summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDmitrii Kuznetsov <torgeek@gmail.com>2021-02-22 18:42:33 +0300
committerDmitrii Kuznetsov <torgeek@gmail.com>2021-02-22 18:42:33 +0300
commite09fefaa3e78c645c720c86391e3f96d257be8a9 (patch)
tree0ff8b235e3e707125e2b11d5268ad085832355cb
parentf4c740839d78f797e9cbcfa1eb0483ac0ea45501 (diff)
parentbc8bd2646f068cfb402850f7c0f9b1dbfe81e5a0 (diff)
Merge branch 'master' of https://github.com/torgeek/learnxinyminutes-docs
-rw-r--r--.gitattributes2
-rw-r--r--.github/CODEOWNERS5
-rw-r--r--.github/ISSUE_TEMPLATE.md15
-rw-r--r--.github/PULL_REQUEST_TEMPLATE.md (renamed from PULL_REQUEST_TEMPLATE.md)3
-rw-r--r--.mailmap1
-rw-r--r--CHICKEN.html.markdown12
-rw-r--r--CONTRIBUTING.markdown32
-rw-r--r--Gemfile.lock15
-rw-r--r--LOLCODE.html.markdown185
-rw-r--r--angularjs.html.markdown19
-rw-r--r--ansible.html.markdown755
-rw-r--r--ar-ar/html-ar.html.markdown121
-rw-r--r--ar-ar/python-ar.html.markdown1019
-rw-r--r--asciidoc.html.markdown18
-rw-r--r--asymptotic-notation.html.markdown86
-rw-r--r--awk.html.markdown386
-rw-r--r--bash.html.markdown225
-rw-r--r--bc.html.markdown98
-rw-r--r--bf.html.markdown3
-rw-r--r--bg-bg/logtalk-bg.html.markdown593
-rw-r--r--bg-bg/perl-bg.html.markdown9
-rw-r--r--c++.html.markdown319
-rw-r--r--c.html.markdown104
-rw-r--r--ca-es/asciidoc-ca.html.markdown134
-rw-r--r--ca-es/go-ca.html.markdown464
-rw-r--r--ca-es/groovy-ca.html.markdown439
-rw-r--r--ca-es/html-ca.html.markdown176
-rw-r--r--ca-es/kotlin-ca.html.markdown389
-rw-r--r--chapel.html.markdown1227
-rw-r--r--citron.html.markdown212
-rw-r--r--clojure-macros.html.markdown15
-rw-r--r--clojure.html.markdown11
-rw-r--r--cmake.html.markdown56
-rw-r--r--cobol.html.markdown198
-rw-r--r--coffeescript.html.markdown12
-rw-r--r--coldfusion.html.markdown5
-rw-r--r--common-lisp.html.markdown665
-rw-r--r--coq.html.markdown510
-rw-r--r--crystal.html.markdown554
-rw-r--r--cs-cz/elm.html.markdown28
-rw-r--r--cs-cz/javascript.html.markdown378
-rw-r--r--cs-cz/markdown.html.markdown2
-rw-r--r--cs-cz/python.html.markdown (renamed from cs-cz/python3.html.markdown)60
-rw-r--r--csharp.html.markdown353
-rw-r--r--css.html.markdown23
-rw-r--r--cypher.html.markdown249
-rw-r--r--d.html.markdown15
-rw-r--r--dart.html.markdown577
-rw-r--r--de-de/LOLCODE-de.html.markdown188
-rw-r--r--de-de/asciidoc-de.html.markdown10
-rw-r--r--de-de/bash-de.html.markdown6
-rw-r--r--de-de/bc.html.markdown102
-rw-r--r--de-de/c++-de.html.markdown1158
-rw-r--r--de-de/c-de.html.markdown869
-rw-r--r--de-de/clojure-macros-de.html.markdown161
-rw-r--r--de-de/css-de.html.markdown6
-rw-r--r--de-de/d-de.html.markdown64
-rw-r--r--de-de/dhall-de.html.markdown380
-rw-r--r--de-de/dynamic-programming-de.html.markdown77
-rw-r--r--de-de/edn-de.html.markdown112
-rw-r--r--de-de/elm-de.html.markdown376
-rw-r--r--de-de/git-de.html.markdown20
-rw-r--r--de-de/go-de.html.markdown2
-rw-r--r--de-de/hq9+-de.html.markdown43
-rw-r--r--de-de/html-de.html.markdown20
-rw-r--r--de-de/java-de.html.markdown6
-rw-r--r--de-de/javascript-de.html.markdown4
-rw-r--r--de-de/latex-de.html.markdown8
-rw-r--r--de-de/make-de.html.markdown53
-rw-r--r--de-de/markdown-de.html.markdown6
-rw-r--r--de-de/nix-de.html.markdown358
-rw-r--r--de-de/opencv-de.html.markdown153
-rw-r--r--de-de/paren-de.html.markdown200
-rw-r--r--de-de/perl-de.html.markdown4
-rw-r--r--de-de/processing-de.html.markdown498
-rw-r--r--de-de/pug-de.html.markdown208
-rw-r--r--de-de/pyqt-de.html.markdown89
-rw-r--r--de-de/python-de.html.markdown306
-rw-r--r--de-de/python3-de.html.markdown655
-rw-r--r--de-de/pythonlegacy-de.html.markdown766
-rw-r--r--de-de/qt-de.html.markdown175
-rw-r--r--de-de/rst-de.html.markdown119
-rw-r--r--de-de/ruby-de.html.markdown782
-rw-r--r--de-de/scala-de.html.markdown582
-rw-r--r--de-de/shutit-de.html.markdown330
-rw-r--r--de-de/swift-de.html.markdown32
-rw-r--r--de-de/vim-de.html.markdown282
-rw-r--r--de-de/yaml-de.html.markdown6
-rw-r--r--dhall.html.markdown362
-rw-r--r--directx9.html.markdown827
-rw-r--r--docker.html.markdown146
-rw-r--r--dynamic-programming.html.markdown26
-rw-r--r--edn.html.markdown45
-rw-r--r--el-gr/bash-gr.html.markdown528
-rw-r--r--el-gr/html-gr.html.markdown193
-rw-r--r--el-gr/json-gr.html.markdown60
-rw-r--r--el-gr/python-gr.html.markdown1031
-rw-r--r--el-gr/rust-gr.html.markdown339
-rw-r--r--el-gr/vim-gr.html.markdown267
-rw-r--r--elisp.html.markdown23
-rw-r--r--elixir.html.markdown25
-rw-r--r--elm.html.markdown26
-rw-r--r--emacs.html.markdown320
-rw-r--r--erlang.html.markdown7
-rw-r--r--es-es/amd-es.html.markdown2
-rw-r--r--es-es/asciidoc-es.html.markdown134
-rw-r--r--es-es/awk-es.html.markdown363
-rw-r--r--es-es/bf-es.html.markdown1
-rw-r--r--es-es/c++-es.html.markdown133
-rw-r--r--es-es/c-es.html.markdown3
-rw-r--r--es-es/clojure-es.html.markdown236
-rw-r--r--es-es/coldfusion-es.html.markdown330
-rw-r--r--es-es/common-lisp-es.html.markdown692
-rw-r--r--es-es/csharp-es.html.markdown7
-rw-r--r--es-es/css-es.html327
-rw-r--r--es-es/dart-es.html.markdown529
-rw-r--r--es-es/dynamic-programming-es.html.markdown52
-rw-r--r--es-es/elixir-es.html.markdown457
-rw-r--r--es-es/erlang-es.html.markdown293
-rw-r--r--es-es/factor-es.html.markdown200
-rw-r--r--es-es/fsharp-es.html.markdown629
-rw-r--r--es-es/git-es.html.markdown2
-rw-r--r--es-es/go-es.html.markdown12
-rw-r--r--es-es/groovy-es.html.markdown4
-rw-r--r--es-es/haskell-es.html.markdown2
-rw-r--r--es-es/hq9+-es.html.markdown44
-rw-r--r--es-es/hy-es.html.markdown176
-rw-r--r--es-es/javascript-es.html.markdown6
-rw-r--r--es-es/kotlin-es.html.markdown76
-rw-r--r--es-es/lambda-calculus-es.html.markdown216
-rw-r--r--es-es/learnsmallbasic-es.html.markdown132
-rw-r--r--es-es/markdown-es.html.markdown2
-rw-r--r--es-es/matlab-es.html.markdown568
-rw-r--r--es-es/objective-c-es.html.markdown2
-rw-r--r--es-es/pascal-es.html.markdown205
-rw-r--r--es-es/pcre-es.html.markdown84
-rw-r--r--es-es/perl-es.html.markdown16
-rw-r--r--es-es/pyqt-es.html.markdown82
-rw-r--r--es-es/python-es.html.markdown323
-rw-r--r--es-es/pythonlegacy-es.html.markdown (renamed from es-es/python3-es.html.markdown)302
-rw-r--r--es-es/pythonstatcomp-es.html.markdown3
-rw-r--r--es-es/raku-es.html.markdown1935
-rw-r--r--es-es/ruby-es.html.markdown2
-rw-r--r--es-es/sass-es.html.markdown2
-rw-r--r--es-es/scala-es.html.markdown741
-rw-r--r--es-es/sql-es.html.markdown115
-rw-r--r--es-es/swift-es.html.markdown30
-rw-r--r--es-es/tcl-es.html.markdown600
-rw-r--r--es-es/visualbasic-es.html.markdown4
-rw-r--r--es-es/xml-es.html.markdown2
-rw-r--r--es-es/yaml-es.html.markdown2
-rw-r--r--fa-ir/bf-fa.html.markdown1
-rw-r--r--fa-ir/java-fa.html.markdown902
-rw-r--r--fa-ir/javascript-fa.html.markdown6
-rw-r--r--factor.html.markdown2
-rw-r--r--fi-fi/go-fi.html.markdown2
-rw-r--r--fi-fi/markdown-fi.html.markdown2
-rw-r--r--forth.html.markdown4
-rw-r--r--fortran95.html.markdown6
-rw-r--r--fr-fr/asymptotic-notation-fr.html.markdown152
-rw-r--r--fr-fr/awk-fr.html.markdown377
-rw-r--r--fr-fr/c++-fr.html.markdown915
-rw-r--r--fr-fr/crystal-fr.html.markdown554
-rw-r--r--fr-fr/css-fr.html.markdown1
-rw-r--r--fr-fr/d-fr.html.markdown (renamed from fr-fr/d.html.markdown)34
-rw-r--r--fr-fr/dynamic-programming-fr.html.markdown16
-rw-r--r--fr-fr/elisp-fr.html.markdown372
-rw-r--r--fr-fr/elixir-fr.html.markdown479
-rw-r--r--fr-fr/erlang-fr.html.markdown4
-rw-r--r--fr-fr/fsharp-fr.html.markdown632
-rw-r--r--fr-fr/haml-fr.html.markdown2
-rw-r--r--fr-fr/haskell-fr.html.markdown (renamed from fr-fr/haskell.html.markdown)2
-rw-r--r--fr-fr/java-fr.html.markdown939
-rw-r--r--fr-fr/javascript-fr.html.markdown24
-rw-r--r--fr-fr/jquery-fr.html.markdown3
-rw-r--r--fr-fr/lambda-calculus-fr.html.markdown106
-rw-r--r--fr-fr/make-fr.html.markdown3
-rw-r--r--fr-fr/markdown-fr.html.markdown367
-rw-r--r--fr-fr/markdown.html.markdown289
-rw-r--r--fr-fr/perl-fr.html.markdown4
-rw-r--r--fr-fr/php-fr.html.markdown (renamed from fr-fr/php.html.markdown)85
-rw-r--r--fr-fr/pyqt-fr.html.markdown85
-rw-r--r--fr-fr/python-fr.html.markdown802
-rw-r--r--fr-fr/python3-fr.html.markdown723
-rw-r--r--fr-fr/pythonlegacy-fr.html.markdown488
-rw-r--r--fr-fr/ruby-ecosystem-fr.html.markdown25
-rw-r--r--fr-fr/ruby-fr.html.markdown49
-rw-r--r--fr-fr/rust-fr.html.markdown53
-rw-r--r--fr-fr/scala-fr.html.markdown (renamed from fr-fr/scala.html.markdown)2
-rw-r--r--fr-fr/vim-fr.html.markdown (renamed from fr-fr/vim.html.markdown)4
-rw-r--r--fr-fr/yaml-fr.html.markdown2
-rw-r--r--fsharp.html.markdown15
-rw-r--r--git.html.markdown84
-rw-r--r--go.html.markdown70
-rw-r--r--groovy.html.markdown19
-rw-r--r--hack.html.markdown4
-rw-r--r--haml.html.markdown54
-rw-r--r--haskell.html.markdown211
-rw-r--r--haxe.html.markdown452
-rw-r--r--hdl.html.markdown231
-rw-r--r--hq9+.html.markdown39
-rw-r--r--hre.csv1
-rw-r--r--html.html.markdown116
-rw-r--r--hu-hu/pythonlegacy-hu.html.markdown816
-rw-r--r--hu-hu/yaml-hu.html.markdown2
-rw-r--r--hy.html.markdown2
-rw-r--r--id-id/asciidoc-id.html.markdown4
-rw-r--r--id-id/bf-id.html.markdown86
-rw-r--r--id-id/hq9+-id.html.markdown45
-rw-r--r--id-id/markdown.html.markdown2
-rw-r--r--id-id/rst-id.html.markdown122
-rw-r--r--it-it/asciidoc-it.html.markdown135
-rw-r--r--it-it/bash-it.html.markdown21
-rw-r--r--it-it/bf-it.html.markdown1
-rw-r--r--it-it/c++-it.html.markdown13
-rw-r--r--it-it/dynamic-programming-it.html.markdown55
-rw-r--r--it-it/elixir-it.html.markdown52
-rw-r--r--it-it/go-it.html.markdown49
-rw-r--r--it-it/html-it.html.markdown121
-rw-r--r--it-it/java-it.html.markdown70
-rw-r--r--it-it/javascript-it.html.markdown617
-rw-r--r--it-it/jquery-it.html.markdown131
-rw-r--r--it-it/json-it.html.markdown1
-rw-r--r--it-it/logtalk-it.html.markdown553
-rw-r--r--it-it/markdown.html.markdown198
-rw-r--r--it-it/matlab-it.html.markdown5
-rw-r--r--it-it/pcre-it.html.markdown85
-rw-r--r--it-it/pyqt-it.html.markdown85
-rw-r--r--it-it/python-it.html.markdown954
-rw-r--r--it-it/pythonlegacy-it.html.markdown778
-rw-r--r--it-it/qt-it.html.markdown161
-rw-r--r--it-it/rst-it.html.markdown111
-rw-r--r--it-it/ruby-it.html.markdown653
-rw-r--r--it-it/rust-it.html.markdown4
-rw-r--r--it-it/sql-it.html.markdown112
-rw-r--r--it-it/toml-it.html.markdown276
-rw-r--r--it-it/typescript-it.html.markdown227
-rw-r--r--it-it/zfs-it.html.markdown361
-rw-r--r--ja-jp/asciidoc.html.markdown135
-rw-r--r--ja-jp/php-jp.html.markdown2
-rw-r--r--ja-jp/python-jp.html.markdown1008
-rw-r--r--janet.html.markdown328
-rw-r--r--java.html.markdown340
-rw-r--r--javascript.html.markdown148
-rw-r--r--jquery.html.markdown10
-rw-r--r--json.html.markdown8
-rw-r--r--jsonnet.html.markdown139
-rw-r--r--julia.html.markdown825
-rw-r--r--kdb+.html.markdown60
-rw-r--r--ko-kr/bash-kr.html.markdown382
-rw-r--r--ko-kr/bf-kr.html.markdown1
-rw-r--r--ko-kr/javascript-kr.html.markdown6
-rw-r--r--ko-kr/kotlin-kr.html.markdown376
-rw-r--r--ko-kr/markdown-kr.html.markdown58
-rw-r--r--ko-kr/pythonlegacy-kr.html.markdown (renamed from ko-kr/python-kr.html.markdown)6
-rw-r--r--ko-kr/vim-kr.html.markdown269
-rw-r--r--ko-kr/yaml-kr.html.markdown2
-rw-r--r--kotlin.html.markdown113
-rw-r--r--lambda-calculus.html.markdown219
-rw-r--r--latex.html.markdown178
-rw-r--r--lbstanza.html.markdown282
-rw-r--r--ldpl.html.markdown170
-rw-r--r--less.html.markdown2
-rw-r--r--lfe.html.markdown459
-rw-r--r--linker.html.markdown9
-rw-r--r--logtalk.html.markdown73
-rw-r--r--lsf/lambda-calculus-lsf.html.markdown91
-rw-r--r--lsf/latex-lsf.html.markdown146
-rw-r--r--lt-lt/tmux-lt.html.markdown255
-rw-r--r--lua.html.markdown168
-rw-r--r--m.html.markdown370
-rw-r--r--make.html.markdown10
-rw-r--r--markdown.html.markdown56
-rw-r--r--matlab.html.markdown18
-rw-r--r--mercurial.html.markdown355
-rw-r--r--mercury.html.markdown263
-rw-r--r--meteor.html.markdown567
-rw-r--r--mips.html.markdown377
-rw-r--r--montilang.html.markdown233
-rw-r--r--moonscript.html.markdown570
-rw-r--r--ms-my/clojure-macros-my.html.markdown151
-rw-r--r--ms-my/clojure-my.html.markdown419
-rw-r--r--ms-my/common-lisp-my.html.markdown692
-rw-r--r--ms-my/elisp-my.html.markdown347
-rw-r--r--ms-my/javascript-my.html.markdown2
-rw-r--r--nim.html.markdown23
-rw-r--r--nix.html.markdown45
-rw-r--r--nl-nl/bash-nl.html.markdown16
-rw-r--r--nl-nl/bf.html.markdown1
-rw-r--r--nl-nl/dynamic-programming-nl.html.markdown55
-rw-r--r--nl-nl/html-nl.html.markdown98
-rw-r--r--nl-nl/json-nl.html.markdown13
-rw-r--r--nl-nl/markdown-nl.html.markdown2
-rw-r--r--nl-nl/vim-nl.html.markdown272
-rw-r--r--nl-nl/yaml-nl.html.markdown2
-rw-r--r--no-nb/bash-no.html.markdown2
-rw-r--r--objective-c.html.markdown7
-rw-r--r--ocaml.html.markdown4
-rw-r--r--opencv.html.markdown144
-rw-r--r--opengl.html.markdown765
-rw-r--r--p5.html.markdown53
-rw-r--r--pascal.html.markdown206
-rw-r--r--pcre.html.markdown47
-rw-r--r--perl.html.markdown57
-rw-r--r--perl6.html.markdown1639
-rw-r--r--php.html.markdown40
-rw-r--r--pl-pl/bf-pl.html.markdown8
-rw-r--r--pl-pl/haskell-pl.html.markdown449
-rw-r--r--pl-pl/java-pl.html.markdown1026
-rw-r--r--pl-pl/json-pl.html.markdown3
-rw-r--r--pl-pl/perl-pl.html.markdown9
-rw-r--r--pl-pl/pythonlegacy-pl.html.markdown (renamed from pl-pl/python-pl.html.markdown)8
-rw-r--r--pl-pl/vim-pl.html.markdown2
-rw-r--r--powershell.html.markdown959
-rw-r--r--processing.html.markdown469
-rw-r--r--prolog.html.markdown339
-rw-r--r--protocol-buffer-3.html.markdown247
-rw-r--r--pt-br/amd-pt.html.markdown (renamed from pt-br/amd.html.markdown)2
-rw-r--r--pt-br/asciidoc-pt.html.markdown6
-rw-r--r--pt-br/asymptotic-notation-pt.html.markdown26
-rw-r--r--pt-br/asymptoticnotation-pt.html.markdown161
-rw-r--r--pt-br/awk-pt.html.markdown377
-rw-r--r--pt-br/bash-pt.html.markdown32
-rw-r--r--pt-br/bf-pt.html.markdown (renamed from pt-br/bf.html.markdown)5
-rw-r--r--pt-br/c++-pt.html.markdown71
-rw-r--r--pt-br/c-pt.html.markdown18
-rw-r--r--pt-br/clojure-macros-pt.html.markdown16
-rw-r--r--pt-br/clojure-pt.html.markdown602
-rw-r--r--pt-br/cmake-pt.html.markdown179
-rw-r--r--pt-br/coffeescript-pt.html.markdown46
-rw-r--r--pt-br/common-lisp-pt.html.markdown2
-rw-r--r--pt-br/csharp-pt.html.markdown (renamed from pt-br/csharp.html.markdown)125
-rw-r--r--pt-br/css-pt.html.markdown75
-rw-r--r--pt-br/cypher-pt.html.markdown250
-rw-r--r--pt-br/dart-pt.html.markdown509
-rw-r--r--pt-br/dynamic-programming-pt.html.markdown20
-rw-r--r--pt-br/elisp-pt.html.markdown2
-rw-r--r--pt-br/elixir-pt.html.markdown (renamed from pt-br/elixir.html.markdown)2
-rw-r--r--pt-br/elm-pt.html.markdown4
-rw-r--r--pt-br/factor-pt.html.markdown184
-rw-r--r--pt-br/fsharp-pt.html.markdown639
-rw-r--r--pt-br/go-pt.html.markdown6
-rw-r--r--pt-br/groovy-pt.html.markdown22
-rw-r--r--pt-br/haskell-pt.html.markdown6
-rw-r--r--pt-br/haxe-pt.html.markdown795
-rw-r--r--pt-br/html-pt.html.markdown125
-rw-r--r--pt-br/hy-pt.html.markdown2
-rw-r--r--pt-br/java-pt.html.markdown28
-rw-r--r--pt-br/javascript-pt.html.markdown15
-rw-r--r--pt-br/json-pt.html.markdown2
-rw-r--r--pt-br/julia-pt.html.markdown4
-rw-r--r--pt-br/kotlin-pt.html.markdown384
-rw-r--r--pt-br/latex-pt.html.markdown291
-rw-r--r--pt-br/less-pt.html.markdown390
-rw-r--r--pt-br/lua-pt.html.markdown423
-rw-r--r--pt-br/make-pt.html.markdown243
-rw-r--r--pt-br/markdown-pt.html.markdown225
-rw-r--r--pt-br/matlab-pt.html.markdown5
-rw-r--r--pt-br/paren-pt.html.markdown8
-rw-r--r--pt-br/pascal-pt.html.markdown254
-rw-r--r--pt-br/perl-pt.html.markdown10
-rw-r--r--pt-br/php-pt.html.markdown2
-rw-r--r--pt-br/pyqt-pt.html.markdown92
-rw-r--r--pt-br/python-pt.html.markdown881
-rw-r--r--pt-br/python3-pt.html.markdown746
-rw-r--r--pt-br/pythonlegacy-pt.html.markdown509
-rw-r--r--pt-br/qt-pt.html.markdown174
-rw-r--r--pt-br/ruby-pt.html.markdown2
-rw-r--r--pt-br/rust-pt.html.markdown (renamed from rust-pt.html.markdown)8
-rw-r--r--pt-br/sass-pt.html.markdown67
-rw-r--r--pt-br/scala-pt.html.markdown668
-rw-r--r--pt-br/self-pt.html.markdown2
-rw-r--r--pt-br/solidity-pt.html.markdown914
-rwxr-xr-xpt-br/stylus-pt.html.markdown228
-rw-r--r--pt-br/swift-pt.html.markdown13
-rw-r--r--pt-br/typescript-pt.html.markdown27
-rw-r--r--pt-br/vim-pt.html.markdown19
-rw-r--r--pt-br/visualbasic-pt.html.markdown14
-rw-r--r--pt-br/whip-pt.html.markdown247
-rw-r--r--pt-br/xml-pt.html.markdown3
-rw-r--r--pt-br/yaml-pt.html.markdown14
-rw-r--r--pt-pt/bf-pt.html.markdown (renamed from pt-pt/bf.html.markdown)1
-rw-r--r--pt-pt/swift-pt.html.markdown (renamed from pt-pt/swift.html.markdown)32
-rw-r--r--pug.html.markdown204
-rw-r--r--purescript.html.markdown8
-rw-r--r--python.html.markdown961
-rw-r--r--python3.html.markdown903
-rw-r--r--pythonlegacy.html.markdown827
-rw-r--r--pythonstatcomp.html.markdown64
-rw-r--r--qsharp.html.markdown204
-rw-r--r--qt.html.markdown6
-rw-r--r--r.html.markdown23
-rw-r--r--racket.html.markdown33
-rw-r--r--raku-pod.html.markdown622
-rw-r--r--raku.html.markdown2411
-rw-r--r--raylib.html.markdown146
-rw-r--r--reason.html.markdown544
-rw-r--r--red.html.markdown32
-rw-r--r--ro-ro/elixir-ro.html.markdown459
-rw-r--r--ro-ro/haskell-ro.html.markdown2
-rw-r--r--ro-ro/pythonlegacy-ro.html.markdown (renamed from ro-ro/python-ro.html.markdown)6
-rw-r--r--rst.html.markdown58
-rw-r--r--ru-ru/.directory4
-rw-r--r--ru-ru/asymptotic-notation-ru.html.markdown225
-rw-r--r--ru-ru/bash-ru.html.markdown346
-rw-r--r--ru-ru/bf.html.markdown1
-rw-r--r--ru-ru/c++-ru.html.markdown40
-rw-r--r--ru-ru/c-ru.html.markdown28
-rw-r--r--ru-ru/clojure-ru.html.markdown54
-rw-r--r--ru-ru/common-lisp-ru.html.markdown704
-rw-r--r--ru-ru/crystal-ru.html.markdown584
-rw-r--r--ru-ru/css-ru.html.markdown6
-rw-r--r--ru-ru/elixir-ru.html.markdown467
-rw-r--r--ru-ru/go-ru.html.markdown4
-rw-r--r--ru-ru/haml-ru.html.markdown233
-rw-r--r--ru-ru/haskell-ru.html.markdown3
-rw-r--r--ru-ru/html-ru.html.markdown3
-rw-r--r--ru-ru/java-ru.html.markdown3
-rw-r--r--ru-ru/javascript-ru.html.markdown4
-rw-r--r--ru-ru/jquery-ru.html.markdown127
-rw-r--r--ru-ru/kotlin-ru.html.markdown375
-rw-r--r--ru-ru/learnvisualbasic-ru.html.markdown284
-rw-r--r--ru-ru/linker-ru.html.markdown203
-rw-r--r--ru-ru/markdown-ru.html.markdown55
-rw-r--r--ru-ru/nim-ru.html.markdown285
-rw-r--r--ru-ru/objective-c-ru.html.markdown2
-rw-r--r--ru-ru/pascal-ru.html.markdown217
-rw-r--r--ru-ru/perl-ru.html.markdown30
-rw-r--r--ru-ru/php-composer-ru.html.markdown197
-rw-r--r--ru-ru/php-ru.html.markdown43
-rw-r--r--ru-ru/pyqt-ru.html.markdown86
-rw-r--r--ru-ru/python-ru.html.markdown1041
-rw-r--r--ru-ru/pythonlegacy-ru.html.markdown (renamed from ru-ru/python3-ru.html.markdown)225
-rw-r--r--ru-ru/ruby-ru.html.markdown192
-rw-r--r--ru-ru/rust-ru.html.markdown313
-rw-r--r--ru-ru/sql-ru.html.markdown120
-rw-r--r--ru-ru/swift-ru.html.markdown38
-rw-r--r--ru-ru/vim-ru.html.markdown2
-rw-r--r--ru-ru/yaml-ru.html.markdown189
-rw-r--r--ruby-ecosystem.html.markdown34
-rw-r--r--ruby.html.markdown384
-rw-r--r--rust.html.markdown34
-rw-r--r--scala.html.markdown77
-rw-r--r--set-theory.html.markdown132
-rw-r--r--shutit.html.markdown318
-rw-r--r--sk-sk/bash-sk.html.markdown (renamed from sk-sk/bash.html.markdown)0
-rw-r--r--sk-sk/coffeescript-sk.html.markdown (renamed from sk-sk/coffeescript.html.markdown)0
-rw-r--r--sk-sk/elixir-sk.html.markdown (renamed from sk-sk/elixir.html.markdown)0
-rw-r--r--sk-sk/git-sk.html.markdown (renamed from sk-sk/git.html.markdown)0
-rw-r--r--sk-sk/json-sk.html.markdown (renamed from sk-sk/json.html.markdown)0
-rw-r--r--sk-sk/latex-sk.html.markdown.tex (renamed from sk-sk/latex.html.markdown.tex)0
-rw-r--r--sk-sk/ruby-sk.html.markdown (renamed from sk-sk/ruby.html.markdown)0
-rw-r--r--sl-si/asciidoc-sl.html.markdown136
-rw-r--r--smalltalk.html.markdown1409
-rw-r--r--solidity.html.markdown246
-rw-r--r--sql.html.markdown110
-rw-r--r--standard-ml.html.markdown52
-rw-r--r--stylus.html.markdown228
-rw-r--r--sv-se/brainfuck-sv.html.markdown1
-rw-r--r--sv-se/haskell-sv.html.markdown461
-rw-r--r--sv-se/nix-sv.html.markdown368
-rw-r--r--swift.html.markdown978
-rw-r--r--ta_in/css-ta.html.markdown42
-rw-r--r--ta_in/javascript-ta.html.markdown6
-rw-r--r--ta_in/json-ta.html.markdown2
-rw-r--r--ta_in/xml-ta.html.markdown52
-rw-r--r--tcl.html.markdown486
-rw-r--r--tcsh.html.markdown791
-rw-r--r--textile.html.markdown505
-rw-r--r--th-th/pascal.th.html.markdown236
-rw-r--r--th-th/typescript.th.html.markdown259
-rw-r--r--tmux.html.markdown1
-rwxr-xr-xtoml.html.markdown52
-rw-r--r--tr-tr/c++-tr.html.markdown1076
-rw-r--r--tr-tr/c-tr.html.markdown4
-rw-r--r--tr-tr/clojure-tr.html.markdown491
-rw-r--r--tr-tr/css-tr.html.markdown304
-rw-r--r--tr-tr/dynamic-programming-tr.html.markdown55
-rw-r--r--tr-tr/edn-tr.html.markdown157
-rw-r--r--tr-tr/git-tr.html.markdown596
-rw-r--r--tr-tr/html-tr.html.markdown157
-rw-r--r--tr-tr/jquery-tr.html.markdown338
-rw-r--r--tr-tr/kotlin-tr.html.markdown474
-rw-r--r--tr-tr/markdown-tr.html.markdown2
-rw-r--r--tr-tr/python-tr.html.markdown812
-rw-r--r--tr-tr/python3-tr.html.markdown640
-rw-r--r--tr-tr/pythonlegacy-tr.html.markdown502
-rw-r--r--tr-tr/ruby-tr.html.markdown1598
-rw-r--r--tr-tr/sql-tr.html.markdown125
-rw-r--r--tr-tr/swift-tr.html.markdown34
-rw-r--r--typescript.html.markdown187
-rw-r--r--uk-ua/bash-ua.html.markdown16
-rw-r--r--uk-ua/cypher-ua.html.markdown254
-rw-r--r--uk-ua/go-ua.html.markdown449
-rw-r--r--uk-ua/java-ua.html.markdown55
-rw-r--r--uk-ua/javascript-ua.html.markdown20
-rw-r--r--uk-ua/kotlin-ua.html.markdown464
-rw-r--r--uk-ua/mips-ua.html.markdown366
-rw-r--r--uk-ua/pythonlegacy-ua.html.markdown818
-rw-r--r--uk-ua/rust-ua.html.markdown331
-rw-r--r--uk-ua/wasm-ua.html.markdown226
-rwxr-xr-xvala.html.markdown503
-rw-r--r--vi-vn/html-vi.html.markdown123
-rw-r--r--vi-vn/less-vi.html.markdown395
-rw-r--r--vi-vn/markdown-vi.html.markdown325
-rw-r--r--vi-vn/python-vi.html.markdown914
-rw-r--r--vi-vn/ruby-vi.html.markdown2
-rw-r--r--vi-vn/sass-vi.html.markdown590
-rw-r--r--vi-vn/typescript-vi.html.markdown193
-rw-r--r--vim.html.markdown80
-rw-r--r--vimscript.html.markdown658
-rw-r--r--visualbasic.html.markdown14
-rw-r--r--vyper.html.markdown872
-rw-r--r--wasm.html.markdown312
-rw-r--r--whip.html.markdown2
-rw-r--r--wolfram.html.markdown4
-rw-r--r--xml.html.markdown13
-rw-r--r--yaml.html.markdown107
-rw-r--r--zfs.html.markdown15
-rw-r--r--zh-cn/angularjs-cn.html.markdown710
-rw-r--r--zh-cn/awk-cn.html.markdown327
-rw-r--r--zh-cn/bf-cn.html.markdown4
-rw-r--r--zh-cn/c++-cn.html.markdown8
-rw-r--r--zh-cn/c-cn.html.markdown6
-rw-r--r--zh-cn/clojure-macro-cn.html.markdown10
-rw-r--r--zh-cn/common-lisp-cn.html.markdown2
-rw-r--r--zh-cn/crystal-cn.html.markdown567
-rw-r--r--zh-cn/css-cn.html.markdown2
-rw-r--r--zh-cn/dart-cn.html.markdown48
-rw-r--r--zh-cn/dynamic-programming-cn.html.markdown57
-rw-r--r--zh-cn/elisp-cn.html.markdown3
-rw-r--r--zh-cn/fortran95-cn.html.markdown435
-rw-r--r--zh-cn/git-cn.html.markdown4
-rw-r--r--zh-cn/go-cn.html.markdown195
-rw-r--r--zh-cn/groovy-cn.html.markdown4
-rw-r--r--zh-cn/haskell-cn.html.markdown4
-rw-r--r--zh-cn/html-cn.html.markdown121
-rw-r--r--zh-cn/java-cn.html.markdown4
-rw-r--r--zh-cn/javascript-cn.html.markdown13
-rw-r--r--zh-cn/jquery-cn.html.markdown131
-rw-r--r--zh-cn/json-cn.html.markdown19
-rw-r--r--zh-cn/julia-cn.html.markdown917
-rw-r--r--zh-cn/kotlin-cn.html.markdown41
-rw-r--r--zh-cn/lambda-calculus-cn.html.markdown223
-rw-r--r--zh-cn/less-cn.html.markdown387
-rw-r--r--zh-cn/livescript-cn.html.markdown2
-rw-r--r--zh-cn/make-cn.html.markdown263
-rw-r--r--zh-cn/markdown-cn.html.markdown286
-rw-r--r--zh-cn/matlab-cn.html.markdown49
-rw-r--r--zh-cn/opencv-cn.html.markdown145
-rw-r--r--zh-cn/perl-cn.html.markdown4
-rw-r--r--zh-cn/powershell-cn.html.markdown325
-rw-r--r--zh-cn/pyqt-cn.html.markdown80
-rw-r--r--zh-cn/python-cn.html.markdown626
-rw-r--r--zh-cn/python3-cn.html.markdown629
-rw-r--r--zh-cn/pythonlegacy-cn.html.markdown476
-rw-r--r--zh-cn/r-cn.html.markdown2
-rw-r--r--zh-cn/racket-cn.html.markdown2
-rw-r--r--zh-cn/red-cn.html.markdown208
-rw-r--r--zh-cn/ruby-cn.html.markdown160
-rw-r--r--zh-cn/sass-cn.html.markdown585
-rw-r--r--zh-cn/solidity-cn.html.markdown825
-rw-r--r--zh-cn/sql.html.markdown105
-rw-r--r--zh-cn/standard-ml-cn.html.markdown438
-rw-r--r--zh-cn/swift-cn.html.markdown48
-rw-r--r--zh-cn/typescript-cn.html.markdown134
-rw-r--r--zh-cn/vim-cn.html.markdown12
-rw-r--r--zh-cn/visualbasic-cn.html.markdown6
-rw-r--r--zh-cn/yaml-cn.html.markdown136
-rw-r--r--zh-tw/dart-tw.html.markdown566
-rw-r--r--zh-tw/pcre-tw.html.markdown84
-rw-r--r--zh-tw/pythonlegacy-tw.html.markdown (renamed from zh-tw/python-tw.html.markdown)8
572 files changed, 110009 insertions, 17736 deletions
diff --git a/.gitattributes b/.gitattributes
index 183b7cdb..96d2bb5a 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -61,5 +61,5 @@ paren*.html.markdown linguist-language=lisp
pcre*.html.markdown linguist-language=Perl
perl.html.markdown linguist-language=Perl
perl-*.html.markdown linguist-language=Perl
-perl6*.html.markdown linguist-language=Perl6
+raku*.html.markdown linguist-language=Perl6
ruby*.html.markdown linguist-language=Ruby
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 00000000..7bc9d01b
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,5 @@
+/fr-fr/ @vendethiel
+/ru-ru/ @Menelion
+/uk-ua/ @Menelion
+/zh-cn/ @geoffliu
+/zh-tw/ @geoffliu
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 00000000..96278da9
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,15 @@
+## Is this a major issue that you cannot fix?
+
+**Being a community driven documents of languages and tools,"YOUR" contributions
+are also important.
+If the issue you're reporting is trivial to report to maintainers why not contribute
+to fix it. In that way, you will have contributed to an awesome open-source project.
+The changes can be typo fix, fixing of data in examples or grammar fix. If you found it,
+why not do it and take full credit for it?**
+
+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/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 6f1f000d..6a496409 100644
--- a/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,4 +1,5 @@
-- [ ] Pull request title is prepended with `[language/lang-code]`
+- [ ] I solemnly swear that this is all original content of which I am the original author
+- [ ] Pull request title is prepended with `[language/lang-code]` (example `[python/fr-fr]` or `[java/en]`)
- [ ] Pull request touches only one file (or a set of logically related files with similar changes made)
- [ ] Content changes are aimed at *intermediate to experienced programmers* (this is a poor format for explaining fundamental programming concepts)
- [ ] If you've changed any part of the YAML Frontmatter, make sure it is formatted according to [CONTRIBUTING.md](https://github.com/adambard/learnxinyminutes-docs/blob/master/CONTRIBUTING.markdown)
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 00000000..b69f76fe
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1 @@
+Leigh Brenecki <l@leigh.net.au> <adam@brenecki.id.au>
diff --git a/CHICKEN.html.markdown b/CHICKEN.html.markdown
index 080527a9..3f7cc2db 100644
--- a/CHICKEN.html.markdown
+++ b/CHICKEN.html.markdown
@@ -8,7 +8,7 @@ contributors:
CHICKEN is an implementation of Scheme programming language that can
compile Scheme programs to C code as well as interpret them. CHICKEN
-supports RSR5 and RSR7 (work in progress) standards and many extensions.
+supports R5RS and R7RS (work in progress) standards and many extensions.
```scheme
@@ -81,7 +81,7 @@ supports RSR5 and RSR7 (work in progress) standards and many extensions.
(string-append "pine" "apple") ;; => "pineapple"
(string-ref "tapioca" 3) ;; => #\i;; character 'i' is at index 3
(string->list "CHICKEN") ;; => (#\C #\H #\I #\C #\K #\E #\N)
-(string->intersperse '("1" "2") ":") ;; => "1:2"
+(string-intersperse '("1" "2") ":") ;; => "1:2"
(string-split "1:2:3" ":") ;; => ("1" "2" "3")
@@ -235,12 +235,12 @@ sqr ;; => #<procedure (sqr x)>
(= 2 1) ;; => #f
;; 'eq?' returns #t if two arguments refer to the same object in memory
-;; In other words, it's a simple pointer comparision.
+;; In other words, it's a simple pointer comparison.
(eq? '() '()) ;; => #t ;; there's only one empty list in memory
(eq? (list 3) (list 3)) ;; => #f ;; not the same object
(eq? 'yes 'yes) ;; => #t
(eq? 3 3) ;; => #t ;; don't do this even if it works in this case
-(eq? 3 3.0) ;; => #f ;; it's better to use '=' for number comparisions
+(eq? 3 3.0) ;; => #f ;; it's better to use '=' for number comparisons
(eq? "Hello" "Hello") ;; => #f
;; 'eqv?' is same as 'eq?' all datatypes except numbers and characters
@@ -255,7 +255,7 @@ sqr ;; => #<procedure (sqr x)>
(equal? '(1 2 3) '(1 2 3)) ;; => #t
(equal? #(a b c) #(a b c)) ;; => #t
(equal? 'a 'a) ;; => #t
-(equal? "abc" "abc") ;; => #f
+(equal? "abc" "abc") ;; => #t
;; In Summary:
;; eq? tests if objects are identical
@@ -510,7 +510,7 @@ sqr ;; => #<procedure (sqr x)>
```
## Further Reading
* [CHICKEN User's Manual](http://wiki.call-cc.org/man/4/The%20User%27s%20Manual).
-* [RSR5 standards](http://www.schemers.org/Documents/Standards/R5RS)
+* [R5RS standards](http://www.schemers.org/Documents/Standards/R5RS)
## Extra Info
diff --git a/CONTRIBUTING.markdown b/CONTRIBUTING.markdown
index 5fa1d03d..3dfd38ce 100644
--- a/CONTRIBUTING.markdown
+++ b/CONTRIBUTING.markdown
@@ -52,6 +52,8 @@ languages:
Other fields:
+- **category**: The category of the article. So far, can be one of *language*,
+ *tool* or *Algorithms & Data Structures*. Defaults to *language* if omitted.
- **filename**: The filename for this article's code. It will be fetched, mashed
together, and made downloadable.
+ For non-English articles, *filename* should have a language-specific
@@ -71,3 +73,33 @@ contributors:
lang: ep-ep
---
```
+
+### Should I add myself as a Contributor?
+
+If you want to add yourself to contributors, keep in mind that contributors get
+equal billing, and the first contributor usually wrote the whole article. Please
+use your judgement when deciding if your contribution constitutes a substantial
+addition or not.
+
+## Building the site locally
+
+You can build the site locally to test your changes. Follow the steps below.
+
+* Install Ruby language runtime and RubyGems. See [here](https://middlemanapp.com/basics/install/) for more details.
+* Clone or zip download the [learnxinyminutes-site](https://github.com/adambard/learnxinyminutes-site) repo.
+ * `git clone https://github.com/adambard/learnxinyminutes-site`
+* Install Middleman and other required dependencies using Bundler.
+ * `cd learnxinyminutes-site/`
+ * `bundle install`
+* Get the source in place
+ * Copy the contents of your clone of the fork of learnxinyminutes-docs repo
+ into the `source/docs` folder. There shouldn't be a `learnxinyminutes-docs`
+ folder inside the `docs` folder, it should just contain all the repo
+ contents.
+ * Checkout your fork of the learnxinyminutes-docs repo as `source/docs`.
+ * `cd source/docs/`
+ * `git clone https://github.com/YOUR-USERNAME/learnxinyminutes-docs ./source/docs/`
+* Build the site or run a development server to test your changes (NOTE: run
+these commands at `learnxinyminutes-site/`).
+ * Build - `bundle exec middleman build`
+ * Dev server - `bundle exec middleman --force-polling --verbose`
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 00000000..ba15ad75
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,15 @@
+GEM
+ remote: http://rubygems.org/
+ specs:
+ charlock_holmes (0.7.3)
+ rake (12.0.0)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ charlock_holmes
+ rake
+
+BUNDLED WITH
+ 1.13.7
diff --git a/LOLCODE.html.markdown b/LOLCODE.html.markdown
new file mode 100644
index 00000000..217b7b7d
--- /dev/null
+++ b/LOLCODE.html.markdown
@@ -0,0 +1,185 @@
+---
+language: LOLCODE
+filename: learnLOLCODE.lol
+contributors:
+ - ["abactel", "https://github.com/abactel"]
+---
+
+LOLCODE is an esoteric programming language designed to resemble the speech of [lolcats](https://upload.wikimedia.org/wikipedia/commons/a/ab/Lolcat_in_folder.jpg?1493656347257).
+
+```
+BTW This is an inline comment
+BTW All code must begin with `HAI <language version>` and end with `KTHXBYE`
+
+HAI 1.3
+CAN HAS STDIO? BTW Importing standard headers
+
+OBTW
+ ==========================================================================
+ ================================= BASICS =================================
+ ==========================================================================
+TLDR
+
+BTW Displaying text:
+VISIBLE "HELLO WORLD"
+
+BTW Declaring variables:
+I HAS A MESSAGE ITZ "CATZ ARE GOOD"
+VISIBLE MESSAGE
+
+OBTW
+ (This is a codeblock.) Variables are dynamically typed so you don't need to
+ declare their type. A variable's type matches its content. These are the
+ types:
+TLDR
+
+I HAS A STRING ITZ "DOGZ ARE GOOOD" BTW type is YARN
+I HAS A INTEGER ITZ 42 BTW type is NUMBR
+I HAS A FLOAT ITZ 3.1415 BTW type is NUMBAR
+I HAS A BOOLEAN ITZ WIN BTW type is TROOF
+I HAS A UNTYPED BTW type is NOOB
+
+BTW Accepting user input:
+I HAS A AGE
+GIMMEH AGE
+BTW The variable is stored as a YARN. To convert it into NUMBR:
+AGE IS NOW A NUMBR
+
+OBTW
+ ==========================================================================
+ ================================== MATH ==================================
+ ==========================================================================
+TLDR
+
+BTW LOLCODE uses polish notation style math.
+
+BTW Basic mathematical notation:
+
+SUM OF 21 AN 33 BTW 21 + 33
+DIFF OF 90 AN 10 BTW 90 - 10
+PRODUKT OF 12 AN 13 BTW 12 * 13
+QUOSHUNT OF 32 AN 43 BTW 32 / 43
+MOD OF 43 AN 64 BTW 43 modulo 64
+BIGGR OF 23 AN 53 BTW max(23, 53)
+SMALLR OF 53 AN 45 BTW min(53, 45)
+
+BTW Binary notation:
+
+BOTH OF WIN AN WIN BTW and: WIN if x=WIN, y=WIN
+EITHER OF FAIL AN WIN BTW or: FAIL if x=FAIL, y=FAIL
+WON OF WIN AN FAIL BTW xor: FAIL if x=y
+NOT FAIL BTW unary negation: WIN if x=FAIL
+ALL OF WIN AN WIN MKAY BTW infinite arity AND
+ANY OF WIN AN FAIL MKAY BTW infinite arity OR
+
+BTW Comparison:
+
+BOTH SAEM "CAT" AN "DOG" BTW WIN if x == y
+DIFFRINT 732 AN 184 BTW WIN if x != y
+BOTH SAEM 12 AN BIGGR OF 12 AN 4 BTW x >= y
+BOTH SAEM 43 AN SMALLR OF 43 AN 56 BTW x <= y
+DIFFRINT 64 AN SMALLR OF 64 AN 2 BTW x > y
+DIFFRINT 75 AN BIGGR OF 75 AN 643 BTW x < y
+
+OBTW
+ ==========================================================================
+ ============================== FLOW CONTROL ==============================
+ ==========================================================================
+TLDR
+
+BTW If/then statement:
+I HAS A ANIMAL
+GIMMEH ANIMAL
+BOTH SAEM ANIMAL AN "CAT", O RLY?
+ YA RLY
+ VISIBLE "YOU HAV A CAT"
+ MEBBE BOTH SAEM ANIMAL AN "MAUS"
+ VISIBLE "NOM NOM NOM. I EATED IT."
+ NO WAI
+ VISIBLE "AHHH IS A WOOF WOOF"
+OIC
+
+BTW Case statement:
+I HAS A COLOR
+GIMMEH COLOR
+COLOR, WTF?
+ OMG "R"
+ VISIBLE "RED FISH"
+ GTFO
+ OMG "Y"
+ VISIBLE "YELLOW FISH"
+ BTW Since there is no `GTFO` the next statements will also be tested
+ OMG "G"
+ OMG "B"
+ VISIBLE "FISH HAS A FLAVOR"
+ GTFO
+ OMGWTF
+ VISIBLE "FISH IS TRANSPARENT OHNO WAT"
+OIC
+
+BTW For loop:
+I HAS A TEMPERATURE
+GIMMEH TEMPERATURE
+TEMPERATURE IS NOW A NUMBR
+IM IN YR LOOP UPPIN YR ITERATOR TIL BOTH SAEM ITERATOR AN TEMPERATURE
+ VISIBLE ITERATOR
+IM OUTTA YR LOOP
+
+BTW While loop:
+IM IN YR LOOP NERFIN YR ITERATOR WILE DIFFRINT ITERATOR AN -10
+ VISIBLE ITERATOR
+IM OUTTA YR LOOP
+
+OBTW
+ =========================================================================
+ ================================ Strings ================================
+ =========================================================================
+TLDR
+
+BTW Linebreaks:
+VISIBLE "FIRST LINE :) SECOND LINE"
+
+BTW Tabs:
+VISIBLE ":>SPACES ARE SUPERIOR"
+
+BTW Bell (goes beep):
+VISIBLE "NXT CUSTOMER PLS :o"
+
+BTW Literal double quote:
+VISIBLE "HE SAID :"I LIKE CAKE:""
+
+BTW Literal colon:
+VISIBLE "WHERE I LIVE:: CYBERSPACE"
+
+OBTW
+ =========================================================================
+ =============================== FUNCTIONS ===============================
+ =========================================================================
+TLDR
+
+BTW Declaring a new function:
+HOW IZ I SELECTMOVE YR MOVE BTW `MOVE` is an argument
+ BOTH SAEM MOVE AN "ROCK", O RLY?
+ YA RLY
+ VISIBLE "YOU HAV A ROCK"
+ NO WAI
+ VISIBLE "OH NO IS A SNIP-SNIP"
+ OIC
+ GTFO BTW This returns NOOB
+IF U SAY SO
+
+BTW Declaring a function and returning a value:
+HOW IZ I IZYELLOW
+ FOUND YR "YELLOW"
+IF U SAY SO
+
+BTW Calling a function:
+I IZ IZYELLOW MKAY
+
+KTHXBYE
+```
+
+## Further reading:
+
+- [LCI compiler](https://github.com/justinmeza/lci)
+- [Official spec](https://github.com/justinmeza/lolcode-spec/blob/master/v1.2/lolcode-spec-v1.2.md)
diff --git a/angularjs.html.markdown b/angularjs.html.markdown
index 89afa291..9156490e 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">
@@ -699,15 +699,10 @@ app.controller('myCtrl', function($scope) {
**Examples**
-- http://www.w3schools.com/angular/angular_examples.asp
+- [http://www.w3schools.com/angular/angular_examples.asp](http://www.w3schools.com/angular/angular_examples.asp)
**References**
-- 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).
-
+- [http://www.w3schools.com/angular/angular_ref_directives.asp](http://www.w3schools.com/angular/angular_ref_directives.asp)
+- [http://www.w3schools.com/angular/default.asp](http://www.w3schools.com/angular/default.asp)
+- [https://teamtreehouse.com/library/angular-basics/](https://teamtreehouse.com/library/angular-basics/)
diff --git a/ansible.html.markdown b/ansible.html.markdown
new file mode 100644
index 00000000..30dfba13
--- /dev/null
+++ b/ansible.html.markdown
@@ -0,0 +1,755 @@
+---
+category: tool
+tool: ansible
+contributors:
+ - ["Jakub Muszynski" , "http://github.com/sirkubax"]
+ - ["Pat Myron" , "https://github.com/patmyron"]
+ - ["Divay Prakash", "https://github.com/divayprakash"]
+filename: LearnAnsible.txt
+---
+
+## Introduction
+
+```yaml
+---
+"{{ Ansible }}" is an orchestration tool written in Python.
+...
+```
+
+Ansible is (one of many) orchestration tools. It allows you to control your
+environment (infrastructure and code) and automate the manual tasks.
+
+Ansible has great integration with multiple operating systems (even Windows)
+and some hardware (switches, Firewalls, etc). It has multiple tools that
+integrate with the cloud providers. Almost every noteworthy cloud provider is
+present in the ecosystem (AWS, Azure, Google, DigitalOcean, OVH, etc...).
+
+But ansible is way more! It provides execution plans, an API, library, and callbacks.
+
+### Main pros and cons
+
+#### Pros
+
+* It is an agent-less tool. In most scenarios, it uses ssh as a transport layer.
+In some way you can use it as 'bash on steroids'.
+* It is very easy to start. If you are familiar with the concept of ssh - you already
+know Ansible (ALMOST).
+* It executes 'as is' - other tools (salt, puppet, chef - might execute in
+different scenario than you would expect)
+* Documentation is at the world-class standard!
+* Writing your own modules and extensions is fairly easy.
+* Ansible AWX is the open source version of Ansible Tower we have been waiting
+for, which provides an excellent UI.
+
+#### Cons
+
+* It is an agent-less tool - every agent consumes up to 16MB ram - in some
+environments, it may be noticable amount.
+* It is agent-less - you have to verify your environment consistency
+'on-demand' - there is no built-in mechanism that would warn you about some
+change automatically (this can be achieved with reasonable effort)
+* Official GUI - Ansible Tower - is great but expensive.
+* There is no 'small enterprise' payment plan, however Ansible AWX is the free
+open source version we were all waiting for.
+
+#### Neutral
+
+Migration - Ansible <-> Salt is fairly easy - so if you would need an
+event-driven agent environment - it would be a good choice to start quick with
+Ansible, and convert to Salt when needed.
+
+#### Some concepts
+
+Ansible uses ssh or paramiko as a transport layer. In a way you can imagine
+that you are using a ssh with API to perform your action. The simplest way is
+to execute remote command in more controlled way (still using ssh).
+On the other hand - in advanced scope - you can wrap Ansible (use python Ansible
+code as a library) with your own Python scripts! It would act a
+bit like Fabric then.
+
+## Example
+
+An example playbook to install apache and configure log level
+
+```yaml
+---
+- hosts: apache
+
+ vars:
+ apache2_log_level: "warn"
+
+ handlers:
+ - name: restart apache
+ service:
+ name: apache2
+ state: restarted
+ enabled: True
+ notify:
+ - Wait for instances to listen on port 80
+ become: True
+
+ - name: reload apache
+ service:
+ name: apache2
+ state: reloaded
+ notify:
+ - Wait for instances to listen on port 80
+ become: True
+
+ - name: Wait for instances to listen on port 80
+ wait_for:
+ state: started
+ host: localhost
+ port: 80
+ timeout: 15
+ delay: 5
+
+ tasks:
+ - name: Update cache
+ apt:
+ update_cache: yes
+ cache_valid_time: 7200
+ become: True
+
+ - name: Install packages
+ apt:
+ name={{ item }}
+ with_items:
+ - apache2
+ - logrotate
+ notify:
+ - restart apache
+ become: True
+
+ - name: Configure apache2 log level
+ lineinfile:
+ dest: /etc/apache2/apache2.conf
+ line: "LogLevel {{ apache2_log_level }}"
+ regexp: "^LogLevel"
+ notify:
+ - reload apache
+ become: True
+...
+```
+
+## Installation
+
+```bash
+# Universal way
+$ pip install ansible
+
+# Debian, Ubuntu
+$ apt-get install ansible
+```
+
+* [Appendix A - How do I install ansible](#infrastructure-as-a-code)
+* [Additional Reading.](http://docs.ansible.com/ansible/latest/intro_installation.html)
+
+### Your first ansible command (shell execution)
+
+```bash
+# Command pings localhost (defined in default inventory: /etc/ansible/hosts)
+$ ansible -m ping localhost
+# You should see this output
+localhost | SUCCESS => {
+ "changed": false,
+ "ping": "pong"
+}
+```
+
+### Shell Commands
+
+There are few commands you should know about
+
+* `ansible` (to run modules in CLI)
+* `ansible-playbook` (to run playbooks)
+* `ansible-vault` (to manage secrets)
+* `ansible-galaxy` (to install roles from github/galaxy)
+
+### Module
+
+A program (usually python) that executes, does some work and returns proper
+JSON output. This program performs specialized task/action (like manage
+instances in the cloud, execute shell command). The simplest module is called
+`ping` - it just returns a JSON with `pong` message.
+
+Example of modules:
+
+* Module: `ping` - the simplest module that is useful to verify host connectivity
+* Module: `shell` - a module that executes a shell command on a specified host(s).
+
+
+```bash
+$ ansible -m ping all
+$ ansible -m shell -a 'date; whoami' localhost #hostname_or_a_group_name
+```
+
+* Module: `command` - executes a single command that will not be processed
+through the shell, so variables like `$HOME` or operands like ``|` `;`` will not
+work. The command module is more secure, because it will not be affected by the
+user’s environment. For more complex commands - use shell module.
+
+```bash
+$ ansible -m command -a 'date; whoami' # FAILURE
+$ ansible -m command -a 'date' all
+$ ansible -m command -a 'whoami' all
+```
+
+* Module: `file` - performs file operations (stat, link, dir, ...)
+* Module: `raw` - executes a low-down and dirty SSH command, not going through
+the module subsystem (useful to install python2.7)
+
+### Task
+
+Execution of a single Ansible **module** is called a **task**. The simplest
+module is called `ping` as you could see above.
+
+Another example of the module that allows you to execute a command remotely on
+multiple resources is called `shell`. See above how you were using them already.
+
+### Playbook
+
+**Execution plan** written in a form of script file(s) is called **playbook**.
+Playbooks consist of multiple elements -
+* a list (or group) of hosts that 'the play' is executed against
+* `task(s)` or `role(s)` that are going to be executed
+* multiple optional settings (like default variables, and way more)
+
+Playbook script language is YAML. You can think that playbook is very advanced
+CLI script that you are executing.
+
+#### Example of the playbook
+
+This example-playbook would execute (on all hosts defined in inventory) two tasks:
+* `ping` that would return message *pong*
+* `shell` that execute three commands and return the output to our terminal
+
+```yaml
+- hosts: all
+
+ tasks:
+ - name: "ping all"
+ ping:
+
+ - name: "execute a shell command"
+ shell: "date; whoami; df -h;"
+```
+
+Run the playbook with the command:
+
+```bash
+$ ansible-playbook path/name_of_the_playbook.yml
+```
+
+Note: Example playbook is explained in the next chapter: 'Roles'
+
+### More on ansible concept
+
+### Inventory
+
+An inventory is a set of objects or hosts, against which we are executing our
+playbooks or single tasks via shell commands. For these few minutes, let's
+assume that we are using the default ansible inventory (which in Debian based
+system is placed in `/etc/ansible/hosts`).
+
+```
+localhost
+
+[some_group]
+hostA.mydomain.com
+hostB.localdomain
+1.2.3.4
+
+[a_group_of_a_groups:children]
+some_group
+some_other_group
+```
+
+* [Additional Reading.](http://docs.ansible.com/ansible/latest/intro_inventory.html)
+
+### ansible-roles (a 'template-playbooks' with right structure)
+
+You already know that the tasks (modules) can be run via CLI. You also know the
+playbooks - the execution plans of multiple tasks (with variables and logic).
+
+A concept called `role` was introduced for parts of the code (playbooks) that
+should be reusable.
+
+**Role** is a structured way to manage your set of tasks, variables, handlers,
+default settings, and way more (meta, files, templates). Roles allow reusing
+the same parts of code in multiple playbooks (you can parametrize the role
+'further' during its execution). Its a great way to introduce `object oriented`
+management for your applications.
+
+Role can be included in your playbook (executed via your playbook).
+
+
+```yaml
+- hosts: all
+
+ tasks:
+ - name: "ping all"
+ ping:
+ - name: "execute a shell command"
+ shell: "date; whoami; df -h;"
+
+ roles:
+ - some_role
+ - { role: another_role, some_variable: 'learnxiny', tags: ['my_tag'] }
+
+ pre_tasks:
+ - name: some pre-task
+ shell: echo 'this task is the last, but would be executed before roles, and before tasks'
+```
+
+#### For remaining examples we would use additional repository
+This example installs ansible in `virtualenv` so it is independent from the system.
+You need to initialize it into your shell-context with the `source environment.sh`
+command.
+
+We are going to use this repository with examples: [https://github.com/sirkubax/ansible-for-learnXinYminutes](https://github.com/sirkubax/ansible-for-learnXinYminutes)
+
+```bash
+$ # The following example contains a shell-prompt to indicate the venv and relative path
+$ git clone git@github.com:sirkubax/ansible-for-learnXinYminutes.git
+user@host:~/$ cd ansible-for-learnXinYminutes
+user@host:~/ansible-for-learnXinYminutes$ source environment.sh
+$
+$ # First lets execute the simple_playbook.yml
+(venv) user@host:~/ansible-for-learnXinYminutes$ ansible-playbook playbooks/simple_playbook.yml
+```
+
+Run the playbook with roles example
+
+```bash
+$ source environment.sh
+$ # Now we would run the above playbook with roles
+(venv) user@host:~/ansible-for-learnXinYminutes$ ansible-playbook playbooks/simple_role.yml
+```
+
+#### Role directory structure
+
+```
+roles/
+ some_role/
+ defaults/ # contains default variables
+ files/ # for static files
+ templates/ # for jinja templates
+ tasks/ # tasks
+ handlers/ # handlers
+ vars/ # more variables (higher priority)
+ meta/ # meta - package (role) info
+```
+
+#### Role Handlers
+Handlers are tasks that can be triggered (notified) during execution of a
+playbook, but they execute at the very end of a playbook. It is the best way to
+restart a service, check if the application port is active (successful
+deployment criteria), etc.
+
+Get familiar with how you can use roles in the simple_apache_role example
+
+```
+playbooks/roles/simple_apache_role/
+├── tasks
+│   └── main.yml
+└── templates
+ └── main.yml
+```
+
+### ansible - variables
+
+Ansible is flexible - it has 21 levels of variable precedence.
+[read more](http://docs.ansible.com/ansible/latest/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable)
+For now you should know that CLI variables have the top priority.
+You should also know, that a nice way to pool some data is a **lookup**
+
+### Lookups
+Awesome tool to query data from various sources!!! Awesome!
+query from:
+* pipe (load shell command output into variable!)
+* file
+* stream
+* etcd
+* password management tools
+* url
+
+```bash
+# read playbooks/lookup.yml
+# then run
+(venv) user@host:~/ansible-for-learnXinYminutes$ ansible-playbook playbooks/lookup.yml
+```
+
+You can use them in CLI too
+
+```yaml
+ansible -m shell -a 'echo "{{ my_variable }}"' -e 'my_variable="{{ lookup("pipe", "date") }}"' localhost
+ansible -m shell -a 'echo "{{ my_variable }}"' -e 'my_variable="{{ lookup("pipe", "hostname") }}"' all
+
+# Or use in playbook
+
+(venv) user@host:~/ansible-for-learnXinYminutes$ ansible-playbook playbooks/lookup.yml
+```
+
+### Register and Conditional
+
+#### Register
+
+Another way to dynamically generate the variable content is the `register` command.
+`Register` is also useful to store an output of a task and use its value
+for executing further tasks.
+
+```
+(venv) user@host:~/ansible-for-learnXinYminutes$ ansible-playbook playbooks/register_and_when.yml
+```
+
+```yaml
+---
+- hosts: localhost
+ tasks:
+ - name: check the system capacity
+ shell: df -h /
+ register: root_size
+
+ - name: debug root_size
+ debug:
+ msg: "{{ root_size }}"
+
+ - name: debug root_size return code
+ debug:
+ msg: "{{ root_size.rc }}"
+
+# when: example
+
+ - name: Print this message when return code of 'check the system capacity' was ok
+ debug:
+ msg: "{{ root_size.rc }}"
+ when: root_size.rc == 0
+...
+```
+
+#### Conditionals - when:
+
+You can define complex logic with Ansible and Jinja functions. Most common is
+usage of `when:`, with some variable (often dynamically generated in previous
+playbook steps with `register` or `lookup`)
+
+```yaml
+---
+- hosts: localhost
+ tasks:
+ - name: check the system capacity
+ shell: df -h /
+ when: some_variable in 'a string'
+ roles:
+ - { role: mid_nagios_probe, when: allow_nagios_probes }
+...
+```
+
+### ansible - tags, limit
+
+You should know about a way to increase efficiency by this simple functionality
+
+#### TAGS
+
+You can tag a task, role (and its tasks), include, etc, and then run only the
+tagged resources
+
+```
+ansible-playbook playbooks/simple_playbook.yml --tags=tagA,tag_other
+ansible-playbook playbooks/simple_playbook.yml -t tagA,tag_other
+
+There are special tags:
+ always
+
+--skip-tags can be used to exclude a block of code
+--list-tags to list available tags
+```
+
+[Read more](http://docs.ansible.com/ansible/latest/playbooks_tags.html)
+
+#### LIMIT
+
+You can limit an execution of your tasks to defined hosts
+
+```
+ansible-playbook playbooks/simple_playbook.yml --limit localhost
+
+--limit my_hostname
+--limit groupname
+--limit some_prefix*
+--limit hostname:group #JM
+```
+
+### Templates
+
+Templates are a powerful way to deliver some (partially) dynamic content.
+Ansible uses **Jinja2** language to describe the template.
+
+```
+Some static content
+
+{{ a_variable }}
+
+{% for item in loop_items %}
+ this line item is {{ item }}
+{% endfor %}
+```
+
+Jinja may have some limitations, but it is a powerful tool that you might like.
+
+Please examine this simple example that installs apache2 and generates
+index.html from the template
+"playbooks/roles/simple_apache_role/templates/index.html"
+
+```bash
+$ source environment.sh
+$ # Now we would run the above playbook with roles
+(venv) user@host:~/ansible-for-learnXinYminutes$ ansible-playbook playbooks/simple_role.yml --tags apache2
+```
+
+#### Jinja2 CLI
+
+You can use the jinja in the CLI too
+
+```bash
+ansible -m shell -a 'echo {{ my_variable }}' -e 'my_variable=something, playbook_parameter=twentytwo' localhost
+```
+
+In fact - jinja is used to template parts of the playbooks too
+
+```yaml
+# check part of this playbook: playbooks/roles/sys_debug/tasks/debug_time.yml
+- local_action: shell date +'%F %T'
+ register: ts
+ become: False
+ changed_when: False
+
+- name: Timestamp
+ debug: msg="{{ ts.stdout }}"
+ when: ts is defined and ts.stdout is defined
+ become: False
+```
+
+#### Jinja2 filters
+
+Jinja is powerful. It has many built-in useful functions.
+
+```
+# get first item of the list
+{{ some_list | first() }}
+# if variable is undefined - use default value
+{{ some_variable | default('default_value') }}
+```
+
+[Read More](http://docs.ansible.com/ansible/latest/playbooks_filters.html)
+
+### ansible-vault
+
+To maintain **infrastructure as code** you need to store secrets. Ansible
+provides a way to encrypt confidential files so you can store them in the
+repository, yet the files are decrypted on-the-fly during ansible execution.
+
+The best way to use it is to store the secret in some secure location, and
+configure ansible to use them during runtime.
+
+```bash
+# Try (this would fail)
+$ ansible-playbook playbooks/vault_example.yml
+
+$ echo some_very_very_long_secret > ~/.ssh/secure_located_file
+
+# in ansible.cfg set the path to your secret file
+$ vi ansible.cfg
+ ansible_vault_password_file = ~/.ssh/secure_located_file
+
+#or use env
+$ export ANSIBLE_VAULT_PASSWORD_FILE=~/.ssh/secure_located_file
+
+$ ansible-playbook playbooks/vault_example.yml
+
+ # encrypt the file
+$ ansible-vault encrypt path/somefile
+
+ # view the file
+$ ansible-vault view path/somefile
+
+ # check the file content:
+$ cat path/somefile
+
+ # decrypt the file
+$ ansible-vault decrypt path/somefile
+```
+
+### dynamic inventory
+
+You might like to know, that you can build your inventory dynamically.
+(For Ansible) inventory is just JSON with proper structure - if you can
+deliver that to ansible - anything is possible.
+
+You do not need to reinvent the wheel - there are plenty of ready to use
+inventory scripts for the most popular Cloud providers and a lot of in-house
+popular usecases.
+
+[AWS example](http://docs.ansible.com/ansible/latest/intro_dynamic_inventory.html#example-aws-ec2-external-inventory-script)
+
+```bash
+$ etc/inv/ec2.py --refresh
+$ ansible -m ping all -i etc/inv/ec2.py
+```
+
+[Read more](http://docs.ansible.com/ansible/latest/intro_dynamic_inventory.html)
+
+### ansible profiling - callback
+
+Playbook execution takes some time. It is OK. First make it run, then you may
+like to speed things up. Since ansible 2.x there is built-in callback for task
+execution profiling.
+
+```
+vi ansible.cfg
+# set this to:
+callback_whitelist = profile_tasks
+```
+
+### facts-cache and ansible-cmdb
+
+You can pull some information about your environment from another host.
+If the information does not change - you may consider using a facts_cache
+to speed things up.
+
+```
+vi ansible.cfg
+
+# if set to a persistent type (not 'memory', for example 'redis') fact values
+# from previous runs in Ansible will be stored. This may be useful when
+# wanting to use, for example, IP information from one group of servers
+# without having to talk to them in the same playbook run to get their
+# current IP information.
+fact_caching = jsonfile
+fact_caching_connection = ~/facts_cache
+fact_caching_timeout = 86400
+```
+
+I like to use `jsonfile` as my backend. It allows to use another project
+`ansible-cmdb` [(project on github)](https://github.com/fboender/ansible-cmdb) that generates a HTML page of your inventory
+resources. A nice 'free' addition!
+
+### Debugging ansible [chapter in progress]
+
+When your job fails - it is good to be effective with debugging.
+
+1. Increase verbosity by using multiple -v **[ -vvvvv]**
+2. If variable is undefined -
+`grep -R path_of_your_inventory -e missing_variable`
+3. If variable (dictionary or a list) is undefined -
+`grep -R path_of_your_inventory -e missing_variable`
+4. Jinja template debug
+5. Strange behaviour - try to run the code 'at the destination'
+
+### Infrastructure as code
+
+You already know, that ansible-vault allows you to store your confidential data
+along with your code. You can go further - and define your
+ansible installation and configuration as code.
+See `environment.sh` to learn how to install the ansible itself inside a
+`virtualenv` that is not attached to your operating system (can be changed by
+non-privileged user), and as additional benefit - upgrading version of ansible
+is as easy as installing new version in new virtualenv. What is more, you can
+have multiple versions of Ansible present at the same time.
+
+```bash
+# recreate ansible 2.x venv
+$ rm -rf venv2
+$ source environment2.sh
+
+# execute playbook
+(venv2)$ ansible-playbook playbooks/ansible1.9_playbook.yml # would fail - deprecated syntax
+
+# now lets install ansible 1.9.x next to ansible 2.x
+(venv2)$ deactivate
+$ source environment.1.9.sh
+
+# execute playbook
+(venv1.9)$ ansible-playbook playbooks/ansible1.9_playbook.yml # works!
+
+# please note that you have both venv1.9 and venv2 present - you need to (de)activate one - that is all
+```
+
+#### become-user, become
+
+In Ansible - to become `sudo` - use the `become` parameter. Use `become_user`
+to specify the username.
+
+```
+- name: Ensure the httpd service is running
+ service:
+ name: httpd
+ state: started
+ become: true
+```
+
+Note: You may like to execute Ansible with `--ask-sudo-pass` or add the user to
+sudoers file in order to allow non-supervised execution if you require 'admin'
+privilages.
+
+[Read more](http://docs.ansible.com/ansible/latest/become.html)
+
+## Tips and tricks
+
+#### --check -C
+
+Always make sure that your playbook can execute in 'dry run' mode (--check),
+and its execution is not declaring 'Changed' objects.
+
+#### --diff -D
+
+Diff is useful to see nice detail of the files changed.
+It compare 'in memory' the files like `diff -BbruN fileA fileB`.
+
+
+#### Execute hosts with 'regex'
+
+```bash
+ansible -m ping web*
+```
+
+#### Host groups can be joined, negated, etc
+
+```bash
+ansible -m ping web*:!backend:monitoring:&allow_change
+```
+
+#### Tagging
+
+You should tag some (not all) objects - a task in a playbook, all tasks
+included form a role, etc. It allows you to execute the chosen parts of the
+playbook.
+
+#### no_logs: True
+
+You may see, that some roles print a lot of output in verbose mode. There is
+also a debug module. This is the place where credentials may leak. Use `no_log`
+to hide the output.
+
+#### Debug module
+
+allows to print a value to the screen - use it!
+
+#### Register the output of a task
+
+You can register the output (stdout), rc (return code), stderr of a task with
+the `register` command.
+
+#### Conditionals: when:
+
+#### Loop: with, with\_items, with\_dict, with\_together
+
+[Read more](http://docs.ansible.com/ansible/latest/playbooks_conditionals.html)
+
+## Additional Resources
+
+* [Servers For Hackers: An Ansible Tutorial](https://serversforhackers.com/c/an-ansible-tutorial)
+* [A system administrator's guide to getting started with Ansible - FAST!](https://www.redhat.com/en/blog/system-administrators-guide-getting-started-ansible-fast)
+* [Ansible Tower](https://www.ansible.com/products/tower) - Ansible Tower provides a web UI, dashboard and rest interface to ansible.
+* [Ansible AWX](https://github.com/ansible/awx) - The Open Source version of Ansible Tower.
diff --git a/ar-ar/html-ar.html.markdown b/ar-ar/html-ar.html.markdown
new file mode 100644
index 00000000..f17164cf
--- /dev/null
+++ b/ar-ar/html-ar.html.markdown
@@ -0,0 +1,121 @@
+---
+language: html
+lang: ar-ar
+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/ar-ar/python-ar.html.markdown b/ar-ar/python-ar.html.markdown
new file mode 100644
index 00000000..f89c2f25
--- /dev/null
+++ b/ar-ar/python-ar.html.markdown
@@ -0,0 +1,1019 @@
+---
+language: Python
+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"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
+ - ["Roberto Fernandez Diaz", "https://github.com/robertofd1995"]
+translators:
+ - ["Ahmad Hegazy", "https://github.com/ahegazy"]
+lang: ar-ar
+filename: learnpython-ar.py
+---
+
+لقد أُنشئت لغة البايثون بواسطة جايدو ڤان روسم في بداية التسعينات. هي الأن أحد أشهر اللغات الموجودة.
+لقد أحببت لغة البايثون بسبب وضوحها. هي في الأساس عبارة عن سودوكود قابل للتنفيذ.
+
+ردود أفعالكم عن المقال مُقدرة بشدة. يمكنكم التواصل مع الكاتب الاساسي من خلال [@louiedinh](http://twitter.com/louiedinh) أو louiedinh [at] [google's email service]
+
+ملحوظة: هذا المقال يُطبق على بايثون 3 فقط. راجع المقال [هنا](http://learnxinyminutes.com/docs/pythonlegacy/) إذا أردت تعلم لغة البايثون نسخة 2.7 الأقدم
+
+```python
+
+# تعليق من سطر واحد يبدأ برمز الرقم.
+
+""" يمكن كتابة تعليق يتكون من أكثر من سطر
+ باستخدام ثلاثة علامات "
+ ، وعادة يُستخدم في كتابة التوثيقات.
+"""
+
+####################################################
+## 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
+
+# الأُس (س ** ص، رفع س لقوى ص)
+2**3 # => 8
+
+# أفرض ترتيب العمليات الحسابية بالأقواس
+(1 + 3) * 2 # => 8
+
+# القيم الثنائية هي المعروفة عموما (ﻻحظ: تكبير أول حرف)
+True
+False
+
+# أنفي بـ (not)
+not True # => False
+not False # => True
+
+# العمليات على القيم الثنائية
+# ﻻحظ ﻻيهم حالة الحرف (كبير أو صغير) في "and" و "or"
+True and False # => False
+False or True # => True
+
+# True و False هما في الواقع 1 و 0 لكن بمسميات مختلفة
+True + True # => 2
+True * 8 # => 8
+False - 5 # => -5
+
+# عمليات المقارنة تنظر الي القيمة الرقمية لل True وال False
+0 == False # => True
+1 == True # => True
+2 == True # => False
+-5 != False # => True
+
+# عند استخدام المنطق الثنائي على القيم الصحيحة يتم تحويلهم الي قيم ثنائية لإجرات العمليات عليهم، لكن قيمهم الأصلية تعود
+# ﻻ تخلط بين bool(قيمة صحيحة) و العمليات المنطقية الثناية and/or (&,|)
+bool(0) # => False
+bool(4) # => True
+bool(-6) # => True
+0 and 2 # => 0
+-5 or 0 # => -5
+
+# مقارنة التساوي ب ==
+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 and 2 < 3 # => True
+2 < 3 and 3 < 2 # => False
+
+# التسلسل يجعلها تبدو أجمل
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# (is مقابل ==) is تتحق من أن المتغيرين يشيران إلي نفس العنصر,
+# لكن == تتحقق من أن العنصرين المُشار اليهما بالمتغيرين لهما نفس القيمة.
+a = [1, 2, 3, 4] # اجعل a تشير إلي قائمة جديدة, [1, 2, 3, 4]
+b = a # اجعل a تُشير الي ما تُشير إليه b
+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 do ﻻ يشيران إلي نفس العنصر
+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"
+
+# إذا كان كود بايثون 3 الخاص بك يحتاج لبايثون 2.5 أو نسخة أقدم
+# يمكنك استخدام أسلوب بناء الجمل القديم:
+"%s can be %s the %s way" % ("Strings", "interpolated", "old") # => "Strings can be interpolated the old way"
+
+# يمكنك أبضا بناء الجمل باستخدام f-strings أو حروف بناء الجمل (في بايثون 3.6 فما فوق)
+name = "Reiko"
+f"She said her name is {name}." # => "She said her name is Reiko"
+# يمكنك ببساطة وضع أي كود بايثون داخل أقواس وستقوم بإخراج الجملة.
+f"{name} is {len(name)} characters long."
+
+
+# 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. المتغيرات والمجموعات
+####################################################
+
+# بايثون لديها دالة عرض "print"
+print("I'm Python. Nice to meet you!") # => I'm Python. Nice to meet you!
+
+# الافتراضي دالة print تطبع سطر جديد في النهاية.
+# استخدم المعامل end لتغيير أخر الجملة المعروضة.
+print("Hello, World", end="!") # => Hello, World!
+
+# طريقة بسيطة لطلب مدخل من الطرفية
+input_string_var = input("Enter some data: ") # يقوم بإعادة البيانات ك "string"
+# لاحظ: في النسخ القديمة من بايثون، دالة input() كان اسمها raw_input()
+
+# ﻻ يوجد تعريفات للمتغيرات، يتم تعيين قيمة المتغير مباشرة.
+# العٌرف تسمية المتغيرات حروف_صغيرة_مع_خطوط_سُفلية
+some_var = 5
+some_var # => 5
+
+# محاولة استخدام متغير غير مُعين يعتبر خطأ
+# إقرأ جزء 3.مسار التحكم لمعرفة المزيد عن التحكم في الأخطاء
+some_unknown_var # يعرض خطأ NameError
+
+# يمكن استخدام if كتعبير واحد
+# مساوِ للتعبير الأتي في لغة السي '?:' عملية ثلاثية
+"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.
+
+# يمكنك الوصول لعناصر القائمة كما تفعل في ال array
+# Access a list like you would any array
+li[0] # => 1
+# للوصول لأخر عنصر
+li[-1] # => 3
+
+# محاولة الوصول لعنصر خارج نطاق القائمة يعتبر خطأ: IndexError
+li[4] # يعرض خطأ IndexError
+
+# يمكنك النظر للنطاقات باستخدام تركيب التقطيع
+# مؤشر/رقم/فهرس البداية مُضمن، مؤشر النهاية ﻻ
+# (لمحبي الرياضيات هو نطاق مفتوح/مغلق)
+li[1:3] # => [2, 4]
+# إحذف أول عنصر ثم إعرض القائمة
+li[2:] # => [4, 3]
+# إحذف أخر عنصر ثم إعرض القائمة
+li[:3] # => [1, 2, 4]
+# حدد عنصر ثم إحذف الذي يليه ثم حدد عنصر وهكذا
+li[::2] # =>[1, 4]
+# اعرض نسخة معكوسة من القائمة
+li[::-1] # => [3, 4, 2, 1]
+# إستخدم أي تجميعة من الطرق المذكورة لعمل تقطيعات متقدمة
+# li[start:end:step]
+
+# عمل نسخة من طبقة واحدة باستخدم التقطيع
+li2 = li[:] # => li2 = [1, 2, 4, 3] لكن عند عمل(li2 is li) سينتج False.
+
+# إمسح أي عنصر من القائمة باستخدام "del"
+del li[2] # li is now [1, 2, 3]
+
+# إمسح أول ظهور لقيمة.
+li.remove(2) # li is now [1, 3]
+li.remove(2) # يعرض خطأ ValueError لأن 2 غير موجود في القائمة
+
+# أضف عنصر في خانة معينة
+li.insert(1, 2) # li is now [1, 2, 3] مرة أخرى
+
+# أحصل على مؤشر/رقم لأول ظهور للقيمة
+li.index(2) # => 1
+li.index(4) # يعرض خطأ ValueError لأن 4 غير موجودة في القائمة
+
+# يمكنك جمع قوائم
+# لاحظ: لا يتم تعديل قيمة li و other_li
+li + other_li # => [1, 2, 3, 4, 5, 6]
+
+# إستخدم دالة "extend()" لربط القوائم
+li.extend(other_li) # Now li is [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
+
+# لاحظ أن صف طوله عنصر واحد يحتاج لإضافة فاصلة "," بعد أخر عنصر
+# لكن الصفوف من أي طول أخر، حتى صفر لا تحتاج.
+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 is now 1, b is now 2 and c is now 3
+# يمكنك أيضا عمل تفريغ واسع
+a, *b, c = (1, 2, 3, 4) # a is now 1, b is now [2, 3] and c is now 4
+# الصفوف تُنشأ تلقائيا إذا تركت الأقواس
+d, e, f = 4, 5, 6 # تم توسعة الصف 4, 5 ,6 في المتغيرات d, e, f
+# بالترتيب حيث d = 4, e = 5 و f = 6
+# الأن إنظر إلي مدى سهولة التبديل بين قيم متغيرين
+e, d = d, e # d is now 5 and e is now 4
+
+
+# القواميس تُخزن خرائط من المفتاح للقيمة
+empty_dict = {}
+# هذا قاموس مملوء
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# لاحظ أن القواميس يجب أن تكون أنواع غير قابلة للتغيير.
+# هذا للتأكد من أن المفتاح يمكن تحويله لقيمة ثابتة للوصول السريع.
+# الأنواع الغير قابلة للتغير تتضمن: الأرقام الصحيحة، الكسور، الكلمات، الصفوف.
+invalid_dict = {[1,2,3]: "123"} # =>يعرض خطأ TypeError: unhashable type: 'list'
+valid_dict = {(1,2,3):[1,2,3]} # القيم يمكن أن تكون من أي نوع.
+
+# يمكنك البحث عن قيمة باستخدام []
+filled_dict["one"] # => 1
+
+# يمكنك الحصول على كل المفاتيح باستخدام "keys()".
+# نحتاج لإرسالها لدالة list() لتحويلها لقائمة. سنتعلم هذا لاحقًا
+# لاحظ - لنسخ بايثون قبل 3.7، ترتيب مفاتيح القاموس غير مضمون. نتائجك
+# يمكن ألا تساوي المثال بالأسفل. مع ذلك، من أول بايثون 3.7،
+# عناصر القاموس تحتفظ بالترتيب الذي تم إضافة المفاتيح به في القاموس.
+list(filled_dict.keys()) # => ["three", "two", "one"] in Python <3.7
+list(filled_dict.keys()) # => ["one", "two", "three"] in Python 3.7+
+
+# يمكنك الحصول على كل القيم باستخدام "values()".
+# مرة أخرى نستخدم list() للحصول عليها كقائمة.
+# نفس الكلام السابق بخصوص ترتيب المفاتيح
+list(filled_dict.values()) # => [3, 2, 1] in Python <3.7
+list(filled_dict.values()) # => [1, 2, 3] in Python 3.7+
+
+# إفحص للتأكد من وجود مغتاح في القاموس باستخدام "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"] is set to 5
+filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5
+
+# إضافة عنصر للقاموس
+filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4}
+filled_dict["four"] = 4 # طريقة أخرى للإضافة
+
+# مسح المفاتيح من القاموس باستخدام del
+del filled_dict["one"] # Removes the key "one" from filled dict
+
+# من بايثون 3.5 فما فوق يمكنك أيضا استخدام خيارات تفريغ إضافية
+{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2}
+{'a': 1, **{'a': 2}} # => {'a': 2}
+
+
+# المجموعات تُخزن .. مجموعات
+empty_set = set()
+# .تهيئة مجموعة بمجموعة قيم. نعم، تشبه قليلا تهيئة القاموس. أسف
+some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4}
+
+# مثل مفتاح القاموس، عناصر المجموعة يجب أن تكون غير قابلة للتغيير.
+invalid_set = {[1], 1} # => يعرض خطأ TypeError: unhashable type: 'list'
+valid_set = {(1,), 1}
+
+# إضافة عنصر أخر للمجموعة
+filled_set = some_set
+filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
+# المجموعات لا يمكن أن تحتوي على عناصر مكررة
+filled_set.add(5) # it remains as before {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. مسار التحكم والعمليات التكرارية #Control Flow and Iterables
+####################################################
+
+# هيا ننشيء متغير
+some_var = 5
+
+# الأن الأمر if. الفجوات (المسافات قبل الأوامر) مهمة في البايثون!
+# العُرف استخدام أربع مسافات. ليس تبويب.
+# هذا السطر البرمجي يطبع "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.
+ print("some_var is smaller than 10.")
+else: # This is optional too.
+ 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(number)" يقوم بإعادة مجموعة من الأرقام يمكن الدوران حولها
+من الصفر إلي رقم معين
+ثم يطبع:
+ 0
+ 1
+ 2
+ 3
+"""
+
+for i in range(4):
+ print(i)
+
+"""
+"range(lower, upper)" يقوم بإعادة مجموعة من الأرقام يمكن الدوران حولها من القيمة السُفلى
+lower حتى القيمة العُليا upper
+ثم يطبع:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print(i)
+
+"""
+"range(lower, upper, step)" يقوم بإعادة مجموعة من الأرقام يمكن الدوران حولها من القيمة السُفلى
+lower حتى القيمة العُليا upper، ثم يقوم بالزيادة قيمة الstep.
+إذا لم تُحدد ال step, القيمة الأفتراضية 1.
+ثم يطبع:
+ 4
+ 6
+"""
+for i in range(4, 8, 2):
+ print(i)
+
+"""
+While هي عبارة عن حلقات تدور حتى عدم تحقق شرط معين.
+وتطبع:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0 for
+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: هو مجرد أمر ﻻ تفعل شيء. عادة تقوم بتصحيح الخطأ هنا.
+except (TypeError, NameError):
+ pass # يمكنك التحكم في أكثر من خطأ في نفس الوقت، إذا أقتضت الضرورة
+else: # فقرة اختيارية في مجموعة try/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)
+
+# يتيح البايثون تجريد أساسي يسمى المُكرَر.
+# المُكرٍَر عبارة عن متغير يمكن التعامل معه كسلسلة.
+# الكائن الذي يعود من دالة نطاق، يسمى المُكرَر.
+
+filled_dict = {"one": 1, "two": 2, "three": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) # => dict_keys(['one', 'two', 'three'])
+# هذا عبارة عن متغير يعرض عناصر مفاتيح المُكرَر.
+
+# يمكننا الدوران حوله.
+for i in our_iterable:
+ print(i) # Prints one, two, three
+
+# مع ذلك ﻻ يمكننا الوصول للعناصر بالمؤشر.
+our_iterable[1] # يرفع خطأ TypeError
+
+# المُكرَر هو عبارة عن عنصر يعلم كيفية إنشاء مُكرِر
+our_iterator = iter(our_iterable)
+
+# المُكرِر هو عبارة عن عنصر يمكنه تذكر الحالة أثناء مرورنا بعناصره.
+# يمكننا الحصول على العنصر التالي عن طريق "next()"
+next(our_iterator) # => "one"
+
+# يحفظ الحالة أثناء الدوران.
+next(our_iterator) # => "two"
+next(our_iterator) # => "three"
+
+# بعد عرض المُكرِر كل عناصره، يرفع استثناء StopIteration
+next(our_iterator) # يرفع StopIteration
+
+# يمكنك الحصول على كل عناصر المُكرر بمناداة دالة list() عليه.
+list(filled_dict.keys()) # => Returns ["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) # => prints out "x is 5 and y is 6" and returns 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 = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # مساوٍ ل all_the_args(1, 2, 3, 4)
+all_the_args(**kwargs) # مساوٍ ل to all_the_args(a=3, b=4)
+all_the_args(*args, **kwargs) # مساوٍ ل to all_the_args(1, 2, 3, 4, a=3, b=4)
+
+# يقوم بإعادة مجموعة من القيم (بتعيين الصفوف)
+def swap(x, y):
+ return y, x # يقوم بإعادة مجموعة من القيم على شكل صفوف بدون الأقواس
+ # (لاحظ: الأقواس حُذفت لكن يمكن إضافتها)
+
+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)
+
+
+# بايثون تدعم دوال الفئة أولية [first class functions] (أي أنه يمكن إرسال الدوال كمعطيات لدوال أخرى)
+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]
+
+# يمكن إشتمال القوائم على خرائط وفلاتر حسنة الشكل
+# هذه القوائم تحفظ المُخرج كقائمة والتي بدورها يمكن أن تكون قائمة مداخلة
+[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 '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. الوحدات البرمجية (الموديولات)
+####################################################
+
+# يمكنك استدعاء موديولات
+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
+
+# يمكنك استدعاء كل الدوال من مديول.
+# تحذير: هذا الفعل غير موصى به
+from math import *
+
+# يمكنك تصغير اسم موديول
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
+
+# موديولات البايثون عبارة عن ملفات بايثون عادية.
+# يمكنك كتابة الموديولات الخاصة بك, واستدعاها.
+# اسم الموديول يكون نفس اسم الملف.
+
+# يمكنك معرفة أي الدوال والصفات مُعرفة في الموديول.
+import math
+dir(math)
+
+# إذا كان لديك سكربت بايثون يسمى math.py
+# في نفس المجلد الموجود به السكربت الخاص بك، الملف الخاص بك math.py
+# سَيُستدعى بدلا من موديول البايثون بنفس الاسم
+# هذا يحدث لأن المجلدات المحلية لديها أولوية عن مكتبات البايثون المُدمجة
+
+
+####################################################
+## 6. الفئات/القوالب (الكلاسات)
+####################################################
+
+# نستخدم السطر البرمجي "class" لإنشاء قالب
+class Human:
+
+ # صفة القالب. مشتركة بين كل نسخ القالب
+ species = "H. sapiens"
+
+ # مُهيئ إبتدائي، يُنادى عليه عندما يتم استدعاء القالب.
+ # لاحظ أن الشرطة السٌفلية المُكررة مرتين __ قبل وبعد الاسم تُعبر عن الكائنات
+ # أو الصفات المُستخدمة عن طريق بايثون لكنها تعيش في مساحة تحكم المُستخدم.
+ # العمليات -الدوال- (أو الكائنات أو الصفات) مثل: __init__, __str__,__repr__ ألخ.
+ # تُسمى عمليات خاصة (أو أحيانا تسمى عمليات سحرية أو dunder methods)
+ # يجب عليك ألا تُسمي مثل هذه الاسماء بنفسك.
+ def __init__(self, name):
+ # ساوِ المُعطى بالصفة name الخاصة بهذه النسخة من القالب.
+ self.name = name
+
+ # هيئ الصفة
+ self._age = 0
+
+ # عملية/دالة خاصة بنسخة القالب. كل العمليات تأخذ "self" كأول مُعطى
+ # An instance method. All methods take "self" as the first argument
+ 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...'
+
+ # عمليات القالب مشتركة بين كل أجزاء القالب
+ # يتم مناداتهم عن طريق جعل القالب المُنادي أول معطى
+ # They are called with the calling class as the first argument
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # تُنادى العملية الثابتة بدون قالب أو نسخة قالب
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+ # الخاصية تشبه تماما إمر الطلب
+ # تُحَوِل العملية 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
+
+
+# عندما يقرأ مُترجم البايثون ملف مصدري يقوم بتنفيذ كل الكود.
+# فحص ال __name__ يجعل هذا الجزء من الكود يُنَفَذ فقط
+# في حالة أن هذا الموديول هو البرنامج الرئيسي
+if __name__ == '__main__':
+ # Instantiate a class
+ 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*"
+
+ # لا يمكن مناداة العملية الثابتة من نسخة الكائن
+ # لأن i.grunt() سيقوم تلقائيا بوضع "self" (الكائن i) كمُعطى للعملية
+ print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
+
+ # حدًث الخاصية لهذه النسخة
+ i.age = 42
+ # أحصل على الخاصية
+ i.say(i.age) # => "Ian: 42"
+ j.say(j.age) # => "Joel: 0"
+ # إحذف الخاصية
+ del i.age
+ # i.age # => سوف يرفع استثناء AttributeError
+
+
+####################################################
+## 6.1 الإرث
+####################################################
+
+# الإرث يتيح لقالب ابن أن يُعَرف ويرث بعض عمليات/دوال ومتغيرات القالب الأب.
+
+# باستخدام القالب Human المُعَرف بالأعلى كأساس أو كقالب أب،
+# يمكننا تعريف قالب ابن،Superhero ، يرث متغيرات القالب مثل "species", "name", و "age"،
+# وأيضا العمليات، مثل "sing", "grunt"
+# من القالب Human، لكنه أيضا لديه خواصه الفريدة
+
+# للاستفادة من التقطيع بالملف يمكنك وضع القوالب بالأعلى في ملفاتهم الخاصة،
+# مثلا، human.py
+
+# لاستيراد دالة من ملف أخر استخدم الطريقة التالية
+# from "اسم الملف بدون مُلحق" import "اسم الدالة أو القالب"
+
+from human import Human
+
+# حدد القالب/ات الأب كمُعطى أثناء تعريف القالب.
+class Superhero(Human):
+
+ # إذا أردت أن يرث القالب الابن كل تعريفات القالب الأب بدون تعديل
+ # يمكنك استخدام الكلمة المفتاحية "pass" (بدون شيء أخر)
+ # لكن في هذه الحالة تم أهمالها لإنشاء قالب ابن فريد:
+ # pass
+
+ # القوالب الابن يمكنها تعديل صفات القوالب الأب
+ species = 'Superhuman'
+
+ # القوالب الابن ترث تلقائيا عمليات الإنشاء الخاصة بالقالب الأب بالإضافة إلي مُعطياتهم
+ # لكن يمكن أيضا تعريف مُعطيات إضافية أو تعريفات
+ # وتعديل العمليات مثل منشيء القالب.
+ # هذا المُنشيء يرث المُعطى "name" من القالب "Human"
+ # ويضيف المعطيات"superpower" و "movies":
+ def __init__(self, name, movie=False,
+ superpowers=["super strength", "bulletproofing"]):
+
+ # إضافة صفة جديدة للقالب
+ self.fictional = True
+ self.movie = movie
+ # كن على علم بالقيم الافتراضية المتغيرة، حيث أن القيم الافتراضية تُشارك
+ self.superpowers = superpowers
+
+ # الدالة "super" تتيح لك الوصول لعمليات القالب الأب
+ # التي تم تغييرها عن طريق الابن، في هذه الحالة، العملية __init__<
+ # هذا السطر يُنادي على منشيء القالب الأب.
+ super().__init__(name)
+
+ # تعديل العملية sing
+ def sing(self):
+ return 'Dun, dun, DUN!'
+
+ # إضافة عملية جديدة للنسخة
+ def boast(self):
+ for power in self.superpowers:
+ print("I wield the power of {pow}!".format(pow=power))
+
+
+if __name__ == '__main__':
+ sup = Superhero(name="Tick")
+
+ # فحص نوع النسخة
+ if isinstance(sup, Human):
+ print('I am human')
+ if type(sup) is Superhero:
+ print('I am a superhero')
+
+ # إحصل على ترتيب قرار البحث للعملية (Method Resolution search Order) المُستخدمة بواسطة العمليات getattr() و super()
+ # هذه الصفة ديناميكية ويمكن أن تُحَدًث.
+ print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
+ # => <class 'human.Human'>, <class 'object'>)
+
+ # نادي العملية الأب لكن استخدم صفات القالب الخاص بها.
+ print(sup.get_species()) # => Superhuman
+
+ # نادي العملية المُعدلة.
+ print(sup.sing()) # => Dun, dun, DUN!
+
+ # نادي العملية من القالب Human
+ sup.say('Spoon') # => Tick: Spoon
+
+ # نادي عملية موجودة فقط في Superhero
+ sup.boast() # => I wield the power of super strength!
+ # => I wield the power of bulletproofing!
+
+ # وَرَثَ صفات القالب
+ sup.age = 31
+ print(sup.age) # => 31
+
+ # صفة موجودة فقط في القالب Superhero
+ print('Am I Oscar eligible? ' + str(sup.movie))
+
+####################################################
+## 6.2 الإرث المُتعدد
+####################################################
+
+# تعريف قالب أخرA
+# bat.py
+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)
+
+# تعريف قالب أخر يرث من Superhero و Bat
+# superhero.py
+from superhero import Superhero
+from bat import Bat
+
+# عَرٍف Batman كقالب ابن يرث من كلا من Superhero و Bat
+class Batman(Superhero, Bat):
+
+ def __init__(self, *args, **kwargs):
+ # عادة لكي ترث صفة يجد أن تنادي على super:
+ # super(Batman, self).__init__(*args, **kwargs)
+ # لكننا في هذه الحالة نتعامل مع إرث متعدد هنا، و super()
+ # تعمل فقط مع القالب التالي في قائمة ال MRO.
+ # لذا بدلا من ذلك ننادي على __init__ صراحة لكل الأباء.
+ # استخدام *args و **kwargs يتيح طريقة نظيفة لتمرير المعطيات.
+ # لكل أب "تقشير طبقة من البصل".
+ Superhero.__init__(self, 'anonymous', movie=True,
+ superpowers=['Wealthy'], *args, **kwargs)
+ Bat.__init__(self, *args, can_fly=False, **kwargs)
+ # تعديل قيمة الصفة name
+ self.name = 'Sad Affleck'
+
+ def sing(self):
+ return 'nan nan nan nan nan batman!'
+
+
+if __name__ == '__main__':
+ sup = Batman()
+
+ # إحصل على ترتيب قرار البحث للعملية (Method Resolution search Order) المُستخدمة بواسطة العمليات getattr() و super()
+ # هذه الصفة ديناميكية ويمكن أن تُحَدًث.
+ print(Batman.__mro__) # => (<class '__main__.Batman'>,
+ # => <class 'superhero.Superhero'>,
+ # => <class 'human.Human'>,
+ # => <class 'bat.Bat'>, <class 'object'>)
+
+ # نادي على العملية الخاصة بالأب لكن استخدم الصفات الخاصة بالقالب الابن
+ print(sup.get_species()) # => Superhuman
+
+ # نادي على العملية المُعدلة
+ print(sup.sing()) # => nan nan nan nan nan batman!
+
+ # نادي على العملية من القالب Human, لأن الترتيب في الأرث مهم.
+ sup.say('I agree') # => Sad Affleck: I agree
+
+ # نادي على العملية الموجودة فقط في القالب الأب الثاني
+ print(sup.sonar()) # => ))) ... (((
+
+ # الصفة الموروثة من القالب الأب
+ sup.age = 100
+ print(sup.age) # => 100
+
+ # الصفة الموروثة من القالب الأب الثاني، الذي تم تعديل قيمته الافتراضية
+ print('Can I fly? ' + str(sup.fly)) # => Can I fly? False
+
+
+
+####################################################
+## 7. مُتَقدم
+####################################################
+
+# المولدات تُساعدك على كتابة كود كسول.
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# المولدات فعالة من حيث الذاكرة، لأنها تُحمٍل الذاكرة بالبيانات التي تحتاج
+# لإجراء العملية عليها في الخطوة التالية في المُكَرِر.
+# هذا يتيح إجراء عمليات على قيم كبيرة ممنوعة في حالات أخرى.
+# ﻻحظ: `range` بديل ل `xrange` في بايثون 3.
+for i in double_numbers(range(1, 900000000)): # `range` is a generator.
+ 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 to console/terminal
+
+# يمكنك أيضا تغيير نوع مولد الاشتمال مباشرة إلي قائمة
+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`.
+# إذا كانت 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 :(
+```
+
+## جاهز للمزيد?
+
+### مجانا عبر الانترنت
+
+* [أتمتتة المهمات المُملة عبر بايثون](https://automatetheboringstuff.com)
+* [أفكار لمشروعات بلغة البايثون](http://pythonpracticeprojects.com)
+* [التوثيقات الرسمية](http://docs.python.org/3/)
+* [دليل المُسافر لبايثون](http://docs.python-guide.org/en/latest/)
+* [دورة بايثون](http://www.python-course.eu/index.php)
+* [أولى الخطوات مع بايثون](https://realpython.com/learn/python-first-steps/)
+* [قائمة مُختارة من إطارات عمل بايثون الرائعة, المكتبات والبرمجيات](https://github.com/vinta/awesome-python)
+* [ثلاثون خاصية وخدعة للغة البايثون ربما لم تعرف بها](http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html)
+* [الدليل الرسمي لنمط البايثون](https://www.python.org/dev/peps/pep-0008/)
+* [بايثون 3 دوائر علوم الحاسب](http://cscircles.cemc.uwaterloo.ca/)
+* [غُص في بايثون 3](http://www.diveintopython3.net/index.html)
+* [دورة سريعة في البايثون للعلماء](http://nbviewer.jupyter.org/gist/anonymous/5924718)
diff --git a/asciidoc.html.markdown b/asciidoc.html.markdown
index 8326c581..51d0d7c9 100644
--- a/asciidoc.html.markdown
+++ b/asciidoc.html.markdown
@@ -2,6 +2,7 @@
language: asciidoc
contributors:
- ["Ryan Mavilia", "http://unoriginality.rocks/"]
+ - ["Abel Salgado Romero", "https://twitter.com/abelsromero"]
filename: asciidoc.md
---
@@ -81,10 +82,6 @@ Section Titles
===== Level 4 <h5>
-====== Level 5 <h6>
-
-======= Level 6 <h7>
-
```
Lists
@@ -120,3 +117,16 @@ You can nest lists by adding extra asterisks or periods up to five times.
.... foo 4
..... foo 5
```
+
+## Further Reading
+
+There are two tools to process AsciiDoc documents:
+
+1. [AsciiDoc](http://asciidoc.org/): original Python implementation available in the main Linux distributions. Stable and currently in maintenance mode.
+2. [Asciidoctor](http://asciidoctor.org/): alternative Ruby implementation, usable also from Java and JavaScript. Under active development, it aims to extend the AsciiDoc syntax with new features and output formats.
+
+Following links are related to `Asciidoctor` implementation:
+
+* [Markdown - AsciiDoc syntax comparison](http://asciidoctor.org/docs/user-manual/#comparison-by-example): side-by-side comparison of common Markdown and AsciiDoc elements.
+* [Getting started](http://asciidoctor.org/docs/#get-started-with-asciidoctor): installation and quick start guides to render simple documents.
+* [Asciidoctor User Manual](http://asciidoctor.org/docs/user-manual/): complete single-document manual with syntax reference, examples, rendering tools, amongst others.
diff --git a/asymptotic-notation.html.markdown b/asymptotic-notation.html.markdown
index a23ef1c8..a6acf54e 100644
--- a/asymptotic-notation.html.markdown
+++ b/asymptotic-notation.html.markdown
@@ -31,24 +31,24 @@ specifications, processing power, etc.
## Types of Asymptotic Notation
-In the first section of this doc we described how an Asymptotic Notation
+In the first section of this doc, we described how an Asymptotic Notation
identifies the behavior of an algorithm as the input size changes. Let us
imagine an algorithm as a function f, n as the input size, and f(n) being
the running time. So for a given algorithm f, with input size n you get
-some resultant run time f(n). This results in a graph where the Y axis is the
-runtime, X axis is the input size, and plot points are the resultants of the
-amount of time for a given input size.
+some resultant run time f(n). This results in a graph where the Y-axis is
+the runtime, the X-axis is the input size, and plot points are the resultants
+of the amount of time for a given input size.
You can label a function, or algorithm, with an Asymptotic Notation in many
different ways. Some examples are, you can describe an algorithm by its best
-case, worse case, or equivalent case. The most common is to analyze an
-algorithm by its worst case. You typically don't evaluate by best case because
-those conditions aren't what you're planning for. A very good example of this
-is sorting algorithms; specifically, adding elements to a tree structure. Best
-case for most algorithms could be as low as a single operation. However, in
-most cases, the element you're adding will need to be sorted appropriately
-through the tree, which could mean examining an entire branch. This is the
-worst case, and this is what we plan for.
+case, worst case, or average case. The most common is to analyze an algorithm
+by its worst case. You typically don’t evaluate by best case because those
+conditions aren’t what you’re planning for. An excellent example of this is
+sorting algorithms; particularly, adding elements to a tree structure. The
+best case for most algorithms could be as low as a single operation. However,
+in most cases, the element you’re adding needs to be sorted appropriately
+through the tree, which could mean examining an entire branch. This is
+the worst case, and this is what we plan for.
### Types of functions, limits, and simplification
@@ -61,20 +61,22 @@ constant
Exponential Function - a^n, where a is some constant
```
-These are some basic function growth classifications used in various
-notations. The list starts at the slowest growing function (logarithmic,
-fastest execution time) and goes on to the fastest growing (exponential,
-slowest execution time). Notice that as 'n', or the input, increases in each
-of those functions, the result clearly increases much quicker in quadratic,
-polynomial, and exponential, compared to logarithmic and linear.
-
-One extremely important note is that for the notations about to be discussed
-you should do your best to use simplest terms. This means to disregard
-constants, and lower order terms, because as the input size (or n in our f(n)
-example) increases to infinity (mathematical limits), the lower order terms
-and constants are of little to no importance. That being said, if you have
-constants that are 2^9001, or some other ridiculous, unimaginable amount,
-realize that simplifying will skew your notation accuracy.
+These are some fundamental function growth classifications used in
+various notations. The list starts at the slowest growing function
+(logarithmic, fastest execution time) and goes on to the fastest
+growing (exponential, slowest execution time). Notice that as ‘n’
+or the input, increases in each of those functions, the result
+increases much quicker in quadratic, polynomial, and exponential,
+compared to logarithmic and linear.
+
+It is worth noting that for the notations about to be discussed,
+you should do your best to use the simplest terms. This means to
+disregard constants, and lower order terms, because as the input
+size (or n in our f(n) example) increases to infinity (mathematical
+limits), the lower order terms and constants are of little to no
+importance. That being said, if you have constants that are 2^9001,
+or some other ridiculous, unimaginable amount, realize that
+simplifying skew your notation accuracy.
Since we want simplest form, lets modify our table a bit...
@@ -89,11 +91,11 @@ Exponential - a^n, where a is some constant
### Big-O
Big-O, commonly written as **O**, is an Asymptotic Notation for the worst
case, or ceiling of growth for a given function. It provides us with an
-_**asymptotic upper bound**_ for the growth rate of runtime of an algorithm.
+_**asymptotic upper bound**_ for the growth rate of the runtime of an algorithm.
Say `f(n)` is your algorithm runtime, and `g(n)` is an arbitrary time
complexity you are trying to relate to your algorithm. `f(n)` is O(g(n)), if
-for some real constant c (c > 0), `f(n)` <= `c g(n)` for every input size
-n (n > 0).
+for some real constants c (c > 0) and n<sub>0</sub>, `f(n)` <= `c g(n)` for every input size
+n (n > n<sub>0</sub>).
*Example 1*
@@ -110,7 +112,7 @@ Let's look to the definition of Big-O.
3log n + 100 <= c * log n
```
-Is there some constant c that satisfies this for all n?
+Is there some pair of constants c, n<sub>0</sub> that satisfies this for all n > n<sub>0</sub>?
```
3log n + 100 <= 150 * log n, n > 2 (undefined at n = 1)
@@ -133,16 +135,16 @@ Let's look at the definition of Big-O.
3 * n^2 <= c * n
```
-Is there some constant c that satisfies this for all n?
+Is there some pair of constants c, n<sub>0</sub> that satisfies this for all n > <sub>0</sub>?
No, there isn't. `f(n)` is NOT O(g(n)).
### Big-Omega
Big-Omega, commonly written as **Ω**, is an Asymptotic Notation for the best
case, or a floor growth rate for a given function. It provides us with an
-_**asymptotic lower bound**_ for the growth rate of runtime of an algorithm.
+_**asymptotic lower bound**_ for the growth rate of the runtime of an algorithm.
-`f(n)` is Ω(g(n)), if for some real constant c (c > 0), `f(n)` is >= `c g(n)`
-for every input size n (n > 0).
+`f(n)` is Ω(g(n)), if for some real constants c (c > 0) and n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` is >= `c g(n)`
+for every input size n (n > n<sub>0</sub>).
### Note
@@ -155,8 +157,8 @@ Small-o, commonly written as **o**, is an Asymptotic Notation to denote the
upper bound (that is not asymptotically tight) on the growth rate of runtime
of an algorithm.
-`f(n)` is o(g(n)), if for any real constant c (c > 0), `f(n)` is < `c g(n)`
-for every input size n (n > 0).
+`f(n)` is o(g(n)), if for all real constants c (c > 0) and n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` is < `c g(n)`
+for every input size n (n > n<sub>0</sub>).
The definitions of O-notation and o-notation are similar. The main difference
is that in f(n) = O(g(n)), the bound f(n) <= g(n) holds for _**some**_
@@ -168,8 +170,8 @@ Small-omega, commonly written as **ω**, is an Asymptotic Notation to denote
the lower bound (that is not asymptotically tight) on the growth rate of
runtime of an algorithm.
-`f(n)` is ω(g(n)), if for any real constant c (c > 0), `f(n)` is > `c g(n)`
-for every input size n (n > 0).
+`f(n)` is ω(g(n)), if for all real constants c (c > 0) and n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` is > `c g(n)`
+for every input size n (n > n<sub>0</sub>).
The definitions of Ω-notation and ω-notation are similar. The main difference
is that in f(n) = Ω(g(n)), the bound f(n) >= g(n) holds for _**some**_
@@ -180,16 +182,16 @@ _**all**_ constants c > 0.
Theta, commonly written as **Θ**, is an Asymptotic Notation to denote the
_**asymptotically tight bound**_ on the growth rate of runtime of an algorithm.
-`f(n)` is Θ(g(n)), if for some real constants c1, c2 (c1 > 0, c2 > 0),
-`c1 g(n)` is < `f(n)` is < `c2 g(n)` for every input size n (n > 0).
+`f(n)` is Θ(g(n)), if for some real constants c1, c2 and n<sub>0</sub> (c1 > 0, c2 > 0, n<sub>0</sub> > 0),
+`c1 g(n)` is < `f(n)` is < `c2 g(n)` for every input size n (n > n<sub>0</sub>).
∴ `f(n)` is Θ(g(n)) implies `f(n)` is O(g(n)) as well as `f(n)` is Ω(g(n)).
Feel free to head over to additional resources for examples on this. Big-O
is the primary notation use for general algorithm time complexity.
-### Ending Notes
-It's hard to keep this kind of topic short, and you should definitely go
+### Endnotes
+It's hard to keep this kind of topic short, and you should go
through the books and online resources listed. They go into much greater depth
with definitions and examples. More where x='Algorithms & Data Structures' is
on its way; we'll have a doc up on analyzing actual code examples soon.
diff --git a/awk.html.markdown b/awk.html.markdown
new file mode 100644
index 00000000..3ff3f937
--- /dev/null
+++ b/awk.html.markdown
@@ -0,0 +1,386 @@
+---
+category: tool
+tool: awk
+filename: learnawk.awk
+contributors:
+ - ["Marshall Mason", "http://github.com/marshallmason"]
+
+---
+
+AWK is a standard tool on every POSIX-compliant UNIX system. It's like
+flex/lex, from the command-line, perfect for text-processing tasks and
+other scripting needs. It has a C-like syntax, but without mandatory
+semicolons (although, you should use them anyway, because they are required
+when you're writing one-liners, something AWK excels at), manual memory
+management, or static typing. It excels at text processing. You can call to
+it from a shell script, or you can use it as a stand-alone scripting language.
+
+Why use AWK instead of Perl? Readability. AWK is easier to read
+than Perl. For simple text-processing scripts, particularly ones that read
+files line by line and split on delimiters, AWK is probably the right tool for
+the job.
+
+```awk
+#!/usr/bin/awk -f
+
+# Comments are like this
+
+
+# AWK programs consist of a collection of patterns and actions.
+pattern1 { action; } # just like lex
+pattern2 { action; }
+
+# There is an implied loop and AWK automatically reads and parses each
+# record of each file supplied. Each record is split by the FS delimiter,
+# which defaults to white-space (multiple spaces,tabs count as one)
+# You can assign FS either on the command line (-F C) or in your BEGIN
+# pattern
+
+# One of the special patterns is BEGIN. The BEGIN pattern is true
+# BEFORE any of the files are read. The END pattern is true after
+# an End-of-file from the last file (or standard-in if no files specified)
+# There is also an output field separator (OFS) that you can assign, which
+# defaults to a single space
+
+BEGIN {
+
+ # BEGIN will run at the beginning of the program. It's where you put all
+ # the preliminary set-up code, before you process any text files. If you
+ # have no text files, then think of BEGIN as the main entry point.
+
+ # Variables are global. Just set them or use them, no need to declare..
+ count = 0;
+
+ # Operators just like in C and friends
+ a = count + 1;
+ b = count - 1;
+ c = count * 1;
+ d = count / 1; # integer division
+ e = count % 1; # modulus
+ f = count ^ 1; # exponentiation
+
+ a += 1;
+ b -= 1;
+ c *= 1;
+ d /= 1;
+ e %= 1;
+ f ^= 1;
+
+ # Incrementing and decrementing by one
+ a++;
+ b--;
+
+ # As a prefix operator, it returns the incremented value
+ ++a;
+ --b;
+
+ # Notice, also, no punctuation such as semicolons to terminate statements
+
+ # Control statements
+ if (count == 0)
+ print "Starting with count of 0";
+ else
+ print "Huh?";
+
+ # Or you could use the ternary operator
+ print (count == 0) ? "Starting with count of 0" : "Huh?";
+
+ # Blocks consisting of multiple lines use braces
+ while (a < 10) {
+ print "String concatenation is done" " with a series" " of"
+ " space-separated strings";
+ print a;
+
+ a++;
+ }
+
+ for (i = 0; i < 10; i++)
+ print "Good ol' for loop";
+
+ # As for comparisons, they're the standards:
+ # a < b # Less than
+ # a <= b # Less than or equal
+ # a != b # Not equal
+ # a == b # Equal
+ # a > b # Greater than
+ # a >= b # Greater than or equal
+
+ # Logical operators as well
+ # a && b # AND
+ # a || b # OR
+
+ # In addition, there's the super useful regular expression match
+ if ("foo" ~ "^fo+$")
+ print "Fooey!";
+ if ("boo" !~ "^fo+$")
+ print "Boo!";
+
+ # Arrays
+ arr[0] = "foo";
+ arr[1] = "bar";
+
+ # You can also initialize an array with the built-in function split()
+
+ n = split("foo:bar:baz", arr, ":");
+
+ # You also have associative arrays (actually, they're all associative arrays)
+ assoc["foo"] = "bar";
+ assoc["bar"] = "baz";
+
+ # And multi-dimensional arrays, with some limitations I won't mention here
+ multidim[0,0] = "foo";
+ multidim[0,1] = "bar";
+ multidim[1,0] = "baz";
+ multidim[1,1] = "boo";
+
+ # You can test for array membership
+ if ("foo" in assoc)
+ print "Fooey!";
+
+ # You can also use the 'in' operator to traverse the keys of an array
+ for (key in assoc)
+ print assoc[key];
+
+ # The command line is in a special array called ARGV
+ for (argnum in ARGV)
+ print ARGV[argnum];
+
+ # You can remove elements of an array
+ # This is particularly useful to prevent AWK from assuming the arguments
+ # are files for it to process
+ delete ARGV[1];
+
+ # The number of command line arguments is in a variable called ARGC
+ print ARGC;
+
+ # AWK has several built-in functions. They fall into three categories. I'll
+ # demonstrate each of them in their own functions, defined later.
+
+ return_value = arithmetic_functions(a, b, c);
+ string_functions();
+ io_functions();
+}
+
+# Here's how you define a function
+function arithmetic_functions(a, b, c, d) {
+
+ # Probably the most annoying part of AWK is that there are no local
+ # variables. Everything is global. For short scripts, this is fine, even
+ # useful, but for longer scripts, this can be a problem.
+
+ # There is a work-around (ahem, hack). Function arguments are local to the
+ # function, and AWK allows you to define more function arguments than it
+ # needs. So just stick local variable in the function declaration, like I
+ # did above. As a convention, stick in some extra whitespace to distinguish
+ # between actual function parameters and local variables. In this example,
+ # a, b, and c are actual parameters, while d is merely a local variable.
+
+ # Now, to demonstrate the arithmetic functions
+
+ # Most AWK implementations have some standard trig functions
+ localvar = sin(a);
+ localvar = cos(a);
+ localvar = atan2(b, a); # arc tangent of b / a
+
+ # And logarithmic stuff
+ localvar = exp(a);
+ localvar = log(a);
+
+ # Square root
+ localvar = sqrt(a);
+
+ # Truncate floating point to integer
+ localvar = int(5.34); # localvar => 5
+
+ # Random numbers
+ srand(); # Supply a seed as an argument. By default, it uses the time of day
+ localvar = rand(); # Random number between 0 and 1.
+
+ # Here's how to return a value
+ return localvar;
+}
+
+function string_functions( localvar, arr) {
+
+ # AWK, being a string-processing language, has several string-related
+ # functions, many of which rely heavily on regular expressions.
+
+ # Search and replace, first instance (sub) or all instances (gsub)
+ # Both return number of matches replaced
+ localvar = "fooooobar";
+ sub("fo+", "Meet me at the ", localvar); # localvar => "Meet me at the bar"
+ gsub("e+", ".", localvar); # localvar => "m..t m. at th. bar"
+
+ # Search for a string that matches a regular expression
+ # index() does the same thing, but doesn't allow a regular expression
+ match(localvar, "t"); # => 4, since the 't' is the fourth character
+
+ # Split on a delimiter
+ n = split("foo-bar-baz", arr, "-"); # a[1] = "foo"; a[2] = "bar"; a[3] = "baz"; n = 3
+
+ # Other useful stuff
+ sprintf("%s %d %d %d", "Testing", 1, 2, 3); # => "Testing 1 2 3"
+ substr("foobar", 2, 3); # => "oob"
+ substr("foobar", 4); # => "bar"
+ length("foo"); # => 3
+ tolower("FOO"); # => "foo"
+ toupper("foo"); # => "FOO"
+}
+
+function io_functions( localvar) {
+
+ # You've already seen print
+ print "Hello world";
+
+ # There's also printf
+ printf("%s %d %d %d\n", "Testing", 1, 2, 3);
+
+ # AWK doesn't have file handles, per se. It will automatically open a file
+ # handle for you when you use something that needs one. The string you used
+ # for this can be treated as a file handle, for purposes of I/O. This makes
+ # it feel sort of like shell scripting, but to get the same output, the string
+ # must match exactly, so use a variable:
+
+ outfile = "/tmp/foobar.txt";
+
+ print "foobar" > outfile;
+
+ # Now the string outfile is a file handle. You can close it:
+ close(outfile);
+
+ # Here's how you run something in the shell
+ system("echo foobar"); # => prints foobar
+
+ # Reads a line from standard input and stores in localvar
+ getline localvar;
+
+ # Reads a line from a pipe (again, use a string so you close it properly)
+ cmd = "echo foobar";
+ cmd | getline localvar; # localvar => "foobar"
+ close(cmd);
+
+ # Reads a line from a file and stores in localvar
+ infile = "/tmp/foobar.txt";
+ getline localvar < infile;
+ close(infile);
+}
+
+# As I said at the beginning, AWK programs consist of a collection of patterns
+# and actions. You've already seen the BEGIN pattern. Other
+# patterns are used only if you're processing lines from files or standard
+# input.
+#
+# When you pass arguments to AWK, they are treated as file names to process.
+# It will process them all, in order. Think of it like an implicit for loop,
+# iterating over the lines in these files. these patterns and actions are like
+# switch statements inside the loop.
+
+/^fo+bar$/ {
+
+ # This action will execute for every line that matches the regular
+ # expression, /^fo+bar$/, and will be skipped for any line that fails to
+ # match it. Let's just print the line:
+
+ print;
+
+ # Whoa, no argument! That's because print has a default argument: $0.
+ # $0 is the name of the current line being processed. It is created
+ # automatically for you.
+
+ # You can probably guess there are other $ variables. Every line is
+ # implicitly split before every action is called, much like the shell
+ # does. And, like the shell, each field can be access with a dollar sign
+
+ # This will print the second and fourth fields in the line
+ print $2, $4;
+
+ # AWK automatically defines many other variables to help you inspect and
+ # process each line. The most important one is NF
+
+ # Prints the number of fields on this line
+ print NF;
+
+ # Print the last field on this line
+ print $NF;
+}
+
+# Every pattern is actually a true/false test. The regular expression in the
+# last pattern is also a true/false test, but part of it was hidden. If you
+# don't give it a string to test, it will assume $0, the line that it's
+# currently processing. Thus, the complete version of it is this:
+
+$0 ~ /^fo+bar$/ {
+ print "Equivalent to the last pattern";
+}
+
+a > 0 {
+ # This will execute once for each line, as long as a is positive
+}
+
+# You get the idea. Processing text files, reading in a line at a time, and
+# doing something with it, particularly splitting on a delimiter, is so common
+# in UNIX that AWK is a scripting language that does all of it for you, without
+# you needing to ask. All you have to do is write the patterns and actions
+# based on what you expect of the input, and what you want to do with it.
+
+# Here's a quick example of a simple script, the sort of thing AWK is perfect
+# for. It will read a name from standard input and then will print the average
+# age of everyone with that first name. Let's say you supply as an argument the
+# name of a this data file:
+#
+# Bob Jones 32
+# Jane Doe 22
+# Steve Stevens 83
+# Bob Smith 29
+# Bob Barker 72
+#
+# Here's the script:
+
+BEGIN {
+
+ # First, ask the user for the name
+ print "What name would you like the average age for?";
+
+ # Get a line from standard input, not from files on the command line
+ getline name < "/dev/stdin";
+}
+
+# Now, match every line whose first field is the given name
+$1 == name {
+
+ # Inside here, we have access to a number of useful variables, already
+ # pre-loaded for us:
+ # $0 is the entire line
+ # $3 is the third field, the age, which is what we're interested in here
+ # NF is the number of fields, which should be 3
+ # NR is the number of records (lines) seen so far
+ # FILENAME is the name of the file being processed
+ # FS is the field separator being used, which is " " here
+ # ...etc. There are plenty more, documented in the man page.
+
+ # Keep track of a running total and how many lines matched
+ sum += $3;
+ nlines++;
+}
+
+# Another special pattern is called END. It will run after processing all the
+# text files. Unlike BEGIN, it will only run if you've given it input to
+# process. It will run after all the files have been read and processed
+# according to the rules and actions you've provided. The purpose of it is
+# usually to output some kind of final report, or do something with the
+# aggregate of the data you've accumulated over the course of the script.
+
+END {
+ if (nlines)
+ print "The average age for " name " is " sum / nlines;
+}
+
+```
+Further Reading:
+
+* [Awk tutorial](http://www.grymoire.com/Unix/Awk.html)
+* [Awk man page](https://linux.die.net/man/1/awk)
+* [The GNU Awk User's Guide](https://www.gnu.org/software/gawk/manual/gawk.html) GNU Awk is found on most Linux systems.
+* [AWK one-liner collection](http://tuxgraphics.org/~guido/scripts/awk-one-liner.html)
+* [Awk alpinelinux wiki](https://wiki.alpinelinux.org/wiki/Awk) a technical summary and list of "gotchas" (places where different implementations may behave in different or unexpected ways).
+* [basic libraries for awk](https://github.com/dubiousjim/awkenough)
diff --git a/bash.html.markdown b/bash.html.markdown
index 271ef62c..11ce4e74 100644
--- a/bash.html.markdown
+++ b/bash.html.markdown
@@ -11,82 +11,121 @@ contributors:
- ["Rahil Momin", "https://github.com/iamrahil"]
- ["Gregrory Kielian", "https://github.com/gskielian"]
- ["Etan Reisner", "https://github.com/deryni"]
- - ["Jonathan Wang", "https://github.com/Jonathansw"]
+ - ["Jonathan Wang", "https://github.com/Jonathansw"]
- ["Leo Rudberg", "https://github.com/LOZORD"]
- ["Betsy Lorton", "https://github.com/schbetsy"]
- ["John Detter", "https://github.com/jdetter"]
+ - ["Harry Mumford-Turner", "https://github.com/harrymt"]
+ - ["Martin Nicholson", "https://github.com/mn113"]
filename: LearnBash.sh
+translators:
+ - ["Dimitri Kokkonis", "https://github.com/kokkonisd"]
---
-Bash is a name of the unix shell, which was also distributed as the shell for the GNU operating system and as default shell on Linux and Mac OS X.
-Nearly all examples below can be a part of a shell script or executed directly in the shell.
+Bash is a name of the unix shell, which was also distributed as the shell
+for the GNU operating system and as the default shell on most Linux distros.
+Nearly all examples below can be a part of a shell script
+or executed directly in the shell.
-[Read more here.](http://www.gnu.org/software/bash/manual/bashref.html)
+[Read more here.](https://www.gnu.org/software/bash/manual/bashref.html)
```bash
-#!/bin/bash
-# First line of the script is shebang which tells the system how to execute
-# the script: http://en.wikipedia.org/wiki/Shebang_(Unix)
+#!/usr/bin/env bash
+# First line of the script is the shebang which tells the system how to execute
+# the script: https://en.wikipedia.org/wiki/Shebang_(Unix)
# As you already figured, comments start with #. Shebang is also a comment.
# Simple hello world example:
-echo Hello world!
+echo Hello world! # => Hello world!
-# Each command starts on a new line, or after semicolon:
+# Each command starts on a new line, or after a semicolon:
echo 'This is the first line'; echo 'This is the second line'
+# => This is the first line
+# => This is the second line
# Declaring a variable looks like this:
Variable="Some string"
# But not like this:
-Variable = "Some string"
+Variable = "Some string" # => returns error "Variable: command not found"
# Bash will decide that Variable is a command it must execute and give an error
# because it can't be found.
-# Or like this:
-Variable= 'Some string'
+# Nor like this:
+Variable= 'Some string' # => returns error: "Some string: command not found"
# Bash will decide that 'Some string' is a command it must execute and give an
# error because it can't be found. (In this case the 'Variable=' part is seen
# as a variable assignment valid only for the scope of the 'Some string'
# command.)
# Using the variable:
-echo $Variable
-echo "$Variable"
-echo '$Variable'
+echo $Variable # => Some string
+echo "$Variable" # => Some string
+echo '$Variable' # => $Variable
# When you use the variable itself — assign it, export it, or else — you write
# its name without $. If you want to use the variable's value, you should use $.
# Note that ' (single quote) won't expand the variables!
# Parameter expansion ${ }:
-echo ${Variable}
+echo ${Variable} # => Some string
# This is a simple usage of parameter expansion
-# Parameter Expansion gets a value from a variable. It "expands" or prints the value
-# During the expansion time the value or parameter are able to be modified
+# Parameter Expansion gets a value from a variable.
+# It "expands" or prints the value
+# During the expansion time the value or parameter can be modified
# Below are other modifications that add onto this expansion
# String substitution in variables
-echo ${Variable/Some/A}
+echo ${Variable/Some/A} # => A string
# This will substitute the first occurrence of "Some" with "A"
# Substring from a variable
Length=7
-echo ${Variable:0:Length}
+echo ${Variable:0:Length} # => Some st
# This will return only the first 7 characters of the value
+echo ${Variable: -5} # => tring
+# This will return the last 5 characters (note the space before -5)
+
+# String length
+echo ${#Variable} # => 11
+
+# Indirect expansion
+OtherVariable="Variable"
+echo ${!OtherVariable} # => Some String
+# This will expand the value of OtherVariable
# Default value for variable
echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"}
+# => DefaultValueIfFooIsMissingOrEmpty
# This works for null (Foo=) and empty string (Foo=""); zero (Foo=0) returns 0.
# Note that it only returns default value and doesn't change variable value.
+# Declare an array with 6 elements
+array0=(one two three four five six)
+# Print first element
+echo $array0 # => "one"
+# Print first element
+echo ${array0[0]} # => "one"
+# Print all elements
+echo ${array0[@]} # => "one two three four five six"
+# Print number of elements
+echo ${#array0[@]} # => "6"
+# Print number of characters in third element
+echo ${#array0[2]} # => "5"
+# Print 2 elements starting from forth
+echo ${array0[@]:3:2} # => "four five"
+# Print all elements. Each of them on new line.
+for i in "${array0[@]}"; do
+ echo "$i"
+done
+
# Brace Expansion { }
# Used to generate arbitrary strings
-echo {1..10}
-echo {a..z}
+echo {1..10} # => 1 2 3 4 5 6 7 8 9 10
+echo {a..z} # => a b c d e f g h i j k l m n o p q r s t u v w x y z
# This will output the range from the start value to the end value
-# Builtin variables:
-# There are some useful builtin variables, like
+# Built-in variables:
+# There are some useful built-in variables, like
echo "Last program's return value: $?"
echo "Script's PID: $$"
echo "Number of arguments passed to script: $#"
@@ -98,7 +137,7 @@ echo "Script's arguments separated into different variables: $1 $2..."
# Our current directory is available through the command `pwd`.
# `pwd` stands for "print working directory".
-# We can also use the builtin variable `$PWD`.
+# We can also use the built-in variable `$PWD`.
# Observe that the following are equivalent:
echo "I'm in $(pwd)" # execs `pwd` and interpolates output
echo "I'm in $PWD" # interpolates the variable
@@ -114,13 +153,14 @@ read Name # Note that we didn't need to declare a new variable
echo Hello, $Name!
# We have the usual if structure:
-# use 'man test' for more info about conditionals
+# use `man test` for more info about conditionals
if [ $Name != $USER ]
then
echo "Your name isn't your username"
else
echo "Your name is your username"
fi
+# True if the value of $Name is not equal to the current user's login username
# NOTE: if $Name is empty, bash sees the above condition as:
if [ != $USER ]
@@ -133,7 +173,11 @@ if [ "" != $USER ] ...
# There is also conditional execution
echo "Always executed" || echo "Only executed if first command fails"
+# => Always executed
echo "Always executed" && echo "Only executed if first command does NOT fail"
+# => Always executed
+# => Only executed if first command does NOT fail
+
# To use && and || with if statements, you need multiple pairs of square brackets:
if [ "$Name" == "Steve" ] && [ "$Age" -eq 15 ]
@@ -146,22 +190,39 @@ then
echo "This will run if $Name is Daniya OR Zach."
fi
+# There is also the `=~` operator, which tests a string against a Regex pattern:
+Email=me@example.com
+if [[ "$Email" =~ [a-z]+@[a-z]{2,}\.(com|net|org) ]]
+then
+ echo "Valid email!"
+fi
+# Note that =~ only works within double [[ ]] square brackets,
+# which are subtly different from single [ ].
+# See https://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs for more on this.
+
+# Redefine command `ping` as alias to send only 5 packets
+alias ping='ping -c 5'
+# Escape the alias and use command with this name instead
+\ping 192.168.1.1
+# Print all aliases
+alias -p
+
# Expressions are denoted with the following format:
-echo $(( 10 + 5 ))
+echo $(( 10 + 5 )) # => 15
# Unlike other programming languages, bash is a shell so it works in the context
# of a current directory. You can list files and directories in the current
# directory with the ls command:
-ls
+ls # Lists the files and subdirectories contained in the current directory
-# These commands have options that control their execution:
+# This command has options that control its execution:
ls -l # Lists every file and directory on a separate line
-ls -t # Sort the directory contents by last-modified date (descending)
+ls -t # Sorts the directory contents by last-modified date (descending)
ls -R # Recursively `ls` this directory and all of its subdirectories
# Results of the previous command can be passed to the next command as input.
-# grep command filters the input with provided patterns. That's how we can list
-# .txt files in the current directory:
+# The `grep` command filters the input with provided patterns.
+# That's how we can list .txt files in the current directory:
ls -l | grep "\.txt"
# Use `cat` to print files to stdout:
@@ -169,7 +230,12 @@ cat file.txt
# We can also read the file using `cat`:
Contents=$(cat file.txt)
-echo "START OF FILE\n$Contents\nEND OF FILE"
+# "\n" prints a new line character
+# "-e" to interpret the newline escape characters as escape characters
+echo -e "START OF FILE\n$Contents\nEND OF FILE"
+# => START OF FILE
+# => [contents of file.txt]
+# => END OF FILE
# Use `cp` to copy files or directories from one place to another.
# `cp` creates NEW versions of the sources,
@@ -187,13 +253,16 @@ cp -r srcDirectory/ dst/ # recursively copy
# `mv` is also useful for renaming files!
mv s0urc3.txt dst.txt # sorry, l33t hackers...
-# Since bash works in the context of a current directory, you might want to
+# Since bash works in the context of a current directory, you might want to
# run your command in some other directory. We have cd for changing location:
cd ~ # change to home directory
+cd # also goes to home directory
cd .. # go up one directory
# (^^say, from /home/username/Downloads to /home/username)
cd /home/username/Documents # change to specified directory
cd ~/Documents/.. # still in home directory..isn't it??
+cd - # change to last directory
+# => /home/username/Documents
# Use subshells to work across directories
(echo "First, I'm here: $PWD") && (cd someDir; echo "Then, I'm here: $PWD")
@@ -203,6 +272,8 @@ pwd # still in first directory
mkdir myNewDir
# The `-p` flag causes new intermediate directories to be created as necessary.
mkdir -p myNewDir/with/intermediate/directories
+# if the intermediate directories didn't already exist, running the above
+# command without the `-p` flag would return an error
# You can redirect command input and output (stdin, stdout, and stderr).
# Read from stdin until ^EOF$ and overwrite hello.py with the lines
@@ -216,13 +287,22 @@ print("#stderr", file=sys.stderr)
for line in sys.stdin:
print(line, file=sys.stdout)
EOF
+# Variables will be expanded if the first "EOF" is not quoted
+
+# Run the hello.py Python script with various stdin, stdout, and
+# stderr redirections:
+python hello.py < "input.in" # pass input.in as input to the script
+
+python hello.py > "output.out" # redirect output from the script to output.out
+
+python hello.py 2> "error.err" # redirect error output to error.err
-# Run hello.py with various stdin, stdout, and stderr redirections:
-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
+# redirect both output and errors to output-and-error.log
+
python hello.py > /dev/null 2>&1
+# redirect all output and errors to the black hole, /dev/null, i.e., no output
+
# The output error will overwrite the file if it exists,
# if you want to append instead, use ">>":
python hello.py >> "output.out" 2>> "error.err"
@@ -245,57 +325,75 @@ echo "#helloworld" | tee output.out >/dev/null
# WARNING: `rm` commands cannot be undone
rm -v output.out error.err output-and-error.log
rm -r tempDir/ # recursively delete
+# You can install the `trash-cli` Python package to have `trash`
+# which puts files in the system trash and doesn't delete them directly
+# see https://pypi.org/project/trash-cli/ if you want to be careful
# Commands can be substituted within other commands using $( ):
# The following command displays the number of files and directories in the
# current directory.
echo "There are $(ls | wc -l) items here."
-# The same can be done using backticks `` but they can't be nested - the preferred way
-# is to use $( ).
+# The same can be done using backticks `` but they can't be nested -
+# the preferred way is to use $( ).
echo "There are `ls | wc -l` items here."
-# Bash uses a case statement that works similarly to switch in Java and C++:
+# Bash uses a `case` statement that works similarly to switch in Java and C++:
case "$Variable" in
- #List patterns for the conditions you want to meet
+ # List patterns for the conditions you want to meet
0) echo "There is a zero.";;
1) echo "There is a one.";;
- *) echo "It is not null.";;
+ *) echo "It is not null.";; # match everything
esac
-# for loops iterate for as many arguments given:
+# `for` loops iterate for as many arguments given:
# The contents of $Variable is printed three times.
for Variable in {1..3}
do
echo "$Variable"
done
+# => 1
+# => 2
+# => 3
+
# Or write it the "traditional for loop" way:
for ((a=1; a <= 3; a++))
do
echo $a
done
+# => 1
+# => 2
+# => 3
# They can also be used to act on files..
-# This will run the command 'cat' on file1 and file2
+# This will run the command `cat` on file1 and file2
for Variable in file1 file2
do
cat "$Variable"
done
# ..or the output from a command
-# This will cat the output from ls.
+# This will `cat` the output from `ls`.
for Output in $(ls)
do
cat "$Output"
done
+# Bash can also accept patterns, like this to `cat`
+# all the Markdown files in current directory
+for Output in ./*.markdown
+do
+ cat "$Output"
+done
+
# while loop:
while [ true ]
do
echo "loop body here..."
break
done
+# => loop body here...
# You can also define functions
# Definition:
@@ -306,6 +404,11 @@ function foo ()
echo "This is a function"
return 0
}
+# Call the function `foo` with two arguments, arg1 and arg2:
+foo arg1 arg2
+# => Arguments work just like script arguments: arg1 arg2
+# => And: arg1 arg2...
+# => This is a function
# or simply
bar ()
@@ -313,6 +416,8 @@ bar ()
echo "Another way to declare functions!"
return 0
}
+# Call the function `bar` with no arguments:
+bar # => Another way to declare functions!
# Calling your function
foo "My name is" $Name
@@ -320,42 +425,56 @@ foo "My name is" $Name
# There are a lot of useful commands you should learn:
# prints last 10 lines of file.txt
tail -n 10 file.txt
+
# prints first 10 lines of file.txt
head -n 10 file.txt
+
# sort file.txt's lines
sort file.txt
+
# report or omit repeated lines, with -d it reports them
uniq -d file.txt
+
# prints only the first column before the ',' character
cut -d ',' -f 1 file.txt
-# replaces every occurrence of 'okay' with 'great' in file.txt, (regex compatible)
+
+# replaces every occurrence of 'okay' with 'great' in file.txt
+# (regex compatible)
sed -i 's/okay/great/g' file.txt
+# be aware that this -i flag means that file.txt will be changed
+# -i or --in-place erase the input file (use --in-place=.backup to keep a back-up)
+
# print to stdout all lines of file.txt which match some regex
# The example prints lines which begin with "foo" and end in "bar"
grep "^foo.*bar$" file.txt
+
# pass the option "-c" to instead print the number of lines matching the regex
grep -c "^foo.*bar$" file.txt
+
# Other useful options are:
grep -r "^foo.*bar$" someDir/ # recursively `grep`
grep -n "^foo.*bar$" file.txt # give line numbers
grep -rI "^foo.*bar$" someDir/ # recursively `grep`, but ignore binary files
+
# perform the same initial search, but filter out the lines containing "baz"
grep "^foo.*bar$" file.txt | grep -v "baz"
# if you literally want to search for the string,
-# and not the regex, use fgrep (or grep -F)
+# and not the regex, use `fgrep` (or `grep -F`)
fgrep "foobar" file.txt
-# trap command allows you to execute a command when a signal is received by your script.
-# Here trap command will execute rm if any one of the three listed signals is received.
+# The `trap` command allows you to execute a command whenever your script
+# receives a signal. Here, `trap` will execute `rm` if it receives any of the
+# three listed signals.
trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM
# `sudo` is used to perform commands as the superuser
+# usually it will ask interactively the password of superuser
NAME1=$(whoami)
NAME2=$(sudo whoami)
echo "Was $NAME1, then became more powerful $NAME2"
-# Read Bash shell builtins documentation with the bash 'help' builtin:
+# Read Bash shell built-ins documentation with the bash `help` built-in:
help
help help
help for
@@ -363,12 +482,12 @@ help return
help source
help .
-# Read Bash manpage documentation with man
+# Read Bash manpage documentation with `man`
apropos bash
man 1 bash
man bash
-# Read info documentation with info (? for help)
+# Read info documentation with `info` (`?` for help)
apropos info | grep '^info.*('
man info
info info
diff --git a/bc.html.markdown b/bc.html.markdown
new file mode 100644
index 00000000..9d63acfb
--- /dev/null
+++ b/bc.html.markdown
@@ -0,0 +1,98 @@
+---
+language: bc
+contributors:
+ - ["Btup"]
+filename: learnbc.bc
+---
+```c
+/*This is a multi-
+line comment.*/
+# This is also a (one-line) comment! (in GNU bc).
+
+ /*1. Variables and control structures*/
+num = 45 /*All variables save only doubles, and you cannot save
+ string constants directly.*/
+num = 45; /*You can choose to add a semicolon after
+ every statement. This is optional.*/
+/*Blocks are denoted using the {} operators(similar to C):*/
+while(num < 50) {
+ num += 1 /*equivalent to num=num+1.
+ a = a op b is equivalent to a op= b.*/
+}
+/*And there are ++(increment) and --(decrement) operators.*/
+/*There are 3 special variables:
+scale: defines the scale of the double numbers.
+ibase: defines the base of input.
+obase: defines the base of output.*/
+/*If clauses:*/
+hour = read() /*Input a number*/
+
+if(hour < 12) { /*Operators are exactly like C.*/
+ print "Good morning\n" /*"print" outputs strings or variables
+ separated by commas.*/
+} else if(hour == 12) {
+ print "Hello\n"
+ /*Escaping sequences start with a \ in a string.
+ In order to make the escaping sequences clearer, here
+ is a simplified list of them that will work in bc:
+ \b: backspace
+ \c: carriage return
+ \n: newline
+ \t: tab
+ \\: backslash*/
+} else {
+ /*Variables are global by default.*/
+ thisIsGlobal = 5
+ /*You can make a variable local. Use the "auto" keyword in a function.*/
+}
+
+/*Every variable is pre-set to 0.*/
+num = blankVariable /*num is set to 0.*/
+
+/*Like C, only 0 is falsy.*/
+if(!num) {print "false\n"}
+
+/*Unlike C, bc does not have the ?: operators. For example,
+ this block of code will cause an error:
+a = (num) ? 1 : 0
+However, you can simulate one:*/
+a = (num) && (1) || (0) /*&& is and, || is or*/
+
+/*For loops*/
+num = 0
+for(i = 1; i <= 100; i++) {/*Similar to the C for loop.*/
+ num += i
+}
+
+ /*2.Functions and Arrays*/
+define fac(n) { /*define a function using define.*/
+ if(n == 1 || n == 0) {
+ return 1 /*return a value*/
+ }
+ return n * fac(n - 1) /*recursion is possible*/
+}
+
+/*Closures and anonymous functions are impossible.*/
+
+num = fac(4) /*24*/
+
+/*This is an example of local variables:*/
+define x(n) {
+ auto x
+ x = 1
+ return n + x
+}
+x(3) /*4*/
+print x /*It turns out that x is not accessible out of the function.*/
+/*Arrays are equivalent to the C array.*/
+for(i = 0; i <= 3; i++) {
+ a[i] = 1
+}
+/*Access it like this:*/
+print a[0], " ", a[1], " ", a[2], " ", a[3], "\n"
+quit /*Add this line of code to make sure
+that your program exits. This line of code is optional.*/
+```
+Enjoy this simple calculator! (Or this programming language, to be exact.)
+
+This whole program is written in GNU bc. To run it, use ```bc learnbc.bc```.
diff --git a/bf.html.markdown b/bf.html.markdown
index c8bbee61..1e415a4d 100644
--- a/bf.html.markdown
+++ b/bf.html.markdown
@@ -1,5 +1,6 @@
---
language: bf
+filename: bf.bf
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
@@ -10,7 +11,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/bg-bg/logtalk-bg.html.markdown b/bg-bg/logtalk-bg.html.markdown
new file mode 100644
index 00000000..e788b17d
--- /dev/null
+++ b/bg-bg/logtalk-bg.html.markdown
@@ -0,0 +1,593 @@
+---
+language: Logtalk
+filename: llearnlogtalk-bg.lgt
+contributors:
+ - ["Paulo Moura", "http://github.com/pmoura"]
+translators:
+ - ["vsraptor", "https://github.com/vsraptor"]
+lang: bg-bg
+
+---
+
+Logtalk е обектно-ориентиран (ОО) модерен логически език за програмиране, които разширява Prolog с възможности за капсулиране (еncapsulation) и многократно използване на кода без да компрометира декларативните възможности на езика. Logtalk е имплементиран така че да може да бъде адапртиран към всеки стандартен Prolog като back-end компилатор, тоест е напълно прозрачен за нормална Prolog програма.
+Допълнително, Logtalk също може да интерпретира Prolog модули, като Logtalk обекти.
+
+Основната структурна единица за изграждане на програмни със Logtalk е чрез използване на обекти.
+Logtalk поддържа както стандартния начин за изграждане на иерархий от класове познати ни от езици като Java, същто така и prototype-OOP познат ни от езици като JavaScript.
+Запомнете че всичко стартира с дефинирането и създаването на обект.
+
+
+## Syntax (Синтакс)
+
+
+Logtalk използва стандартен Prolog синтакс, с минимум допълнителни оператори и директиви.
+Важно последствие от това е че кода лесно се капсулира с много малко промени спрямо оригинален код.
+
+Операторите които Logtalk добавя към Prolog са :
+
+ ::/2 - изпраща саобщение до обект (аналогично на метод в стандартните ООП езици)
+ ::/1 - изпраща саобщение до себе си (self) (тоест до обекта който е получил съобщението което обработваме в момента)
+ ^^/1 - super call (изпраща саобщение до наследен или импортиран предикат(predicate))
+
+
+## Entities and roles (Субекти и роли)
+
+
+Logtalk предоставя обекти, портоколи и категории като първокласни-субекти (first-class entities). Връзката между тях описва ролята която субектите изпалняват.
+Обектите могат да играят различни роли в зависимост от как ги дефинираме тоест какви директиви използваме при дефиницията.
+
+Например когато използваме обект А за да създадем нов обект Б, обект Б играе ролята на "инстанция", а обект А играе ролята на клас.
+Ако използваме "extends"-дефиниция единия от обектите играе ролята на протоип(prototype) за другия.
+
+
+## Defining an object (Дефиниране на обект)
+
+
+Чрез дефинирането на обект ние капсулираме дефиницията на "предикатите".
+Обекти могат да се създадат динамично или дефинират статично във код-файла.
+Ето как дефинираме примерен обект :
+
+```logtalk
+:- object(list).
+
+ :- public(member/2).
+ member(Head, [Head| _]).
+ member(Head, [_| Tail]) :-
+ member(Head, Tail).
+
+:- end_object.
+```
+
+## Compiling source files (Компилиран)
+
+
+Ако предположим че кода е записан във файл с име list.lgt, можем да го компилираме чрез logtalk_load/1 предиката или съкратения вариант {}/1.
+
+
+```logtalk
+?- {list}.
+yes
+```
+
+## Sending a message to an object (Изпращане на събщение до обект)
+
+
+Както казахме ::/2 infix оператор се използва за изпращане на съобщение до обекта. Както в Prolog, ние можем да backtrack-нем за алтернативни решения, понеже метода е просто стандартен предикат :
+
+```logtalk
+?- list::member(X, [1,2,3]).
+X = 1 ;
+X = 2 ;
+X = 3
+yes
+
+?- write_canonical(list::member(X, [1,2,3])).
+::(list,member(_,[1,2,3]))
+```
+
+Кагато декларирме обект автоматично предикатите са капсулирани (еncapsulation), тоест извън обекта те са невидими за останалата част от програмата. Естествено има опции да променим това поведение чрез public, protected, или private предикати.
+
+```logtalk
+:- object(scopes).
+
+ :- private(bar/0).
+ bar.
+
+ local.
+
+:- end_object.
+```
+
+Ако кода е записан в scopes.lgt фаил и се опитаме да изпратим саобщтение до частен(private) или локален предикат ще получим грешка:
+
+```logtalk
+?- {scopes}.
+yes
+
+?- catch(scopes::bar, Error, true).
+Error = error(
+ permission_error(access, private_predicate, bar/0),
+ logtalk(scopes::bar, user)
+)
+yes
+
+?- catch(scopes::local, Error, true).
+Error = error(
+ existence_error(predicate_declaration, local/0),
+ logtalk(scopes::local, user)
+)
+yes
+```
+
+Когато предиката е непознат за обекта това също генерира грешка. Например :
+
+```logtalk
+?- catch(scopes::unknown, Error, true).
+Error = error(
+ existence_error(predicate_declaration, unknown/0),
+ logtalk(scopes::unknown, user)
+)
+yes
+```
+
+## Протоколи (Defining and implementing a protocol)
+
+
+За тези от вас свикнали със стандартно ООП, Protocols наподобяват Interfaces в Java.
+Протоколите съдържат предикати които могат да бъдат в последствие имплементирани в обекти и категории :
+
+```logtalk
+:- protocol(listp).
+
+ :- public(member/2).
+
+:- end_protocol.
+
+:- object(list,
+ implements(listp)).
+
+ member(Head, [Head| _]).
+ member(Head, [_| Tail]) :-
+ member(Head, Tail).
+
+:- end_object.
+```
+
+Обхвата(scope) на предикатите в протокола могат да бъде ограничени чрез protected или private клаузи.
+Например:
+
+```logtalk
+:- object(stack,
+ implements(private::listp)).
+
+:- end_object.
+```
+
+Всички субекти(entity) релации могат да бъдат пре-дефинирани с public, protected или private, подбно на начина показан по горе.
+
+
+## Прототипи (Prototypes)
+
+
+Всеки обект без instantiation или specialization спецификация с друг обект, играе ролята на прототип.
+Прототип-обект може да предефинира и разщири протоипа-родител.
+
+```logtalk
+% clyde, our prototypical elephant
+:- object(clyde).
+
+ :- public(color/1).
+ color(grey).
+
+ :- public(number_of_legs/1).
+ number_of_legs(4).
+
+:- end_object.
+
+% fred, another elephant, is like clyde, except that he's white
+:- object(fred,
+ extends(clyde)).
+
+ color(white).
+
+:- end_object.
+```
+
+Когато системата отговаря на съобщение изпратено до обект който играе ролята на прототип, тя търси отговор първо в прототипа и ако не намери предикат делегира отговора на прототипа-родител-обект :
+
+```logtalk
+?- fred::number_of_legs(N).
+N = 4
+yes
+
+?- fred::color(C).
+C = white
+yes
+```
+
+Съобщението е валидно но няма да генерира грещка, ако предиката е дефиниран но не е деклариран/имплементиран. Това е така наречения closed-world assumption.
+Например :
+
+```logtalk
+:- object(foo).
+
+ :- public(bar/0).
+
+:- end_object.
+```
+
+Ако заредим файла и се опитаме да извикаме bar/0, няма да получим отговор, както може да очакваме. Ако обаче предиката не е дори дефиниран, ще получим гращка :
+
+```logtalk
+?- {foo}.
+yes
+
+?- foo::bar.
+no
+
+?- catch(foo::baz, Error, true).
+Error = error(
+ existence_error(predicate_declaration, baz/0),
+ logtalk(foo::baz, user)
+)
+yes
+```
+
+## Класове и инстанции (Classes and instances)
+
+
+За да саздадем обекти които играят ролята на класове и/или инстанции, трябва да използваме поне instantiation или specialization дефиниция с друг обект. Обектите които играят роля на мета-класове могат да се използват ако е нужно още за саздаване на инстанции на класа.
+Следващия пример ще илюстрира как можем динамично да саздадаваме обекти :
+
+```logtalk
+% a simple, generic, metaclass defining a new/2 predicate for its instances
+:- object(metaclass,
+ instantiates(metaclass)).
+
+ :- public(new/2).
+ new(Instance, Clauses) :-
+ self(Class),
+ create_object(Instance, [instantiates(Class)], [], Clauses).
+
+:- end_object.
+
+% a simple class defining age/1 and name/1 predicate for its instances
+:- object(person,
+ instantiates(metaclass)).
+
+ :- public([
+ age/1, name/1
+ ]).
+
+ % a default value for age/1
+ age(42).
+
+:- end_object.
+
+% a static instance of the class person
+:- object(john,
+ instantiates(person)).
+
+ name(john).
+ age(12).
+
+:- end_object.
+```
+
+Когато отговаряме на съобщение изпратено до обект който играе ролята на инстанция, системата валидира съобщението първо в текущия клас, след това класа-родител ако е необходимо. Ако съобщението е валидно тогава проверяваме инстанцията :
+
+```logtalk
+?- person::new(Instance, [name(paulo)]).
+Instance = o1
+yes
+
+?- o1::name(Name).
+Name = paulo
+yes
+
+?- o1::age(Age).
+Age = 42
+yes
+
+?- john::age(Age).
+Age = 12
+yes
+```
+
+## Категории (Categories)
+
+
+Категорията е капсулран код който може да се рециклира (reuse) в различни обекти. Докато Протокола е само дефиниции Категорията е сащо и декларация/имплементация на предикатите които сме дефинирали.
+В следващия пример ще дефинираме категории представящи автомобилни двигатели след което ще ги импортираме в автомобил-обекти :
+
+
+```logtalk
+% a protocol describing engine characteristics
+:- protocol(carenginep).
+
+ :- public([
+ reference/1,
+ capacity/1,
+ cylinders/1,
+ horsepower_rpm/2,
+ bore_stroke/2,
+ fuel/1
+ ]).
+
+:- end_protocol.
+
+% a typical engine defined as a category
+:- category(classic,
+ implements(carenginep)).
+
+ reference('M180.940').
+ capacity(2195).
+ cylinders(6).
+ horsepower_rpm(94, 4800).
+ bore_stroke(80, 72.8).
+ fuel(gasoline).
+
+:- end_category.
+
+% a souped up version of the previous engine
+:- category(sport,
+ extends(classic)).
+
+ reference('M180.941').
+ horsepower_rpm(HP, RPM) :-
+ ^^horsepower_rpm(ClassicHP, ClassicRPM), % "super" call
+ HP is truncate(ClassicHP*1.23),
+ RPM is truncate(ClassicRPM*0.762).
+
+:- end_category.
+
+% with engines (and other components), we may start "assembling" some cars
+:- object(sedan,
+ imports(classic)).
+
+:- end_object.
+
+:- object(coupe,
+ imports(sport)).
+
+:- end_object.
+```
+
+Категориите се компилират отделно и разрешават импортираните обекти да бъдат обновени като просто обновим категориите без да е необходимо да прекомпилираме обекта:
+
+```logtalk
+?- sedan::current_predicate(Predicate).
+Predicate = reference/1 ;
+Predicate = capacity/1 ;
+Predicate = cylinders/1 ;
+Predicate = horsepower_rpm/2 ;
+Predicate = bore_stroke/2 ;
+Predicate = fuel/1
+yes
+```
+
+## Hot patching
+
+
+Категориите още могат да се използват за промяна на обекти "в движение", след като вече са били инстанциирани.
+Например :
+
+```logtalk
+:- object(buggy).
+
+ :- public(p/0).
+ p :- write(foo).
+
+:- end_object.
+```
+
+Да предположим че обекта изпечатва грешното съобщение p/0 :
+
+```logtalk
+?- {buggy}.
+yes
+
+?- buggy::p.
+foo
+yes
+```
+
+Ако кода който описва този обект не е наличен и трябва да коригираме приложението, ние можем просто да създадем категория която да коригира необходимия предикат :
+
+```logtalk
+:- category(patch,
+ complements(buggy)).
+
+ % fixed p/0 def
+ p :- write(bar).
+
+:- end_category.
+```
+
+След компилиране и зареждане на категорията ще получим :
+
+```logtalk
+?- {patch}.
+yes
+
+?- buggy::p.
+bar
+yes
+```
+
+
+## Parametric objects and categories
+
+
+Обектите и категориите могат да се параметризират ако използваме за индентификатор комплексен-термин вместо атом.
+Параметрите са логически променливи достъпни за всички капсулирани предикати.
+Пример с геометрични кръгове :
+
+```logtalk
+:- object(circle(_Radius, _Color)).
+
+ :- public([
+ area/1, perimeter/1
+ ]).
+
+ area(Area) :-
+ parameter(1, Radius),
+ Area is pi*Radius*Radius.
+
+ perimeter(Perimeter) :-
+ parameter(1, Radius),
+ Perimeter is 2*pi*Radius.
+
+:- end_object.
+```
+
+Параметричните-обекти се използват като всеки друг обект, обикновенно осигуряваики стойности за параметрите когато изпращаме съобщение.
+
+```logtalk
+?- circle(1.23, blue)::area(Area).
+Area = 4.75291
+yes
+```
+
+Параметричните-обекти още осигуряват лесен начин за ассоцииране на различни предикати със нормални Prolog предикати.
+Prolog факти могат да бъдат интерпретирани като посредници (proxies).
+Например следните клаузи на circle/2 предикат :
+
+
+```logtalk
+circle(1.23, blue).
+circle(3.71, yellow).
+circle(0.39, green).
+circle(5.74, black).
+circle(8.32, cyan).
+```
+
+можем лесно да изчислим площа на всички кръгове :
+
+```logtalk
+?- findall(Area, {circle(_, _)}::area(Area), Areas).
+Areas = [4.75291, 43.2412, 0.477836, 103.508, 217.468]
+yes
+```
+
+{Goal}::Message формата доказва(proves) Goal и изпраща съобщение до генерирания термин.
+
+
+## Събития и мониторинг (Events and monitors)
+
+
+Logtalk поддържа event-driven програмиране чрез дефинирането на събития и монитори за тези събития.
+Събитие е просто изпращане на съобщение към обект. При обработването на съобщение системата разпознава before-събитие и after-събитие.
+Мониторите дефинират предикати които ще прихаванат тези събития (before/3 и after/3).
+Нампример следния монитор ще прихаване съобщенията изпратени чрез ::/2 :
+
+```logtalk
+:- object(tracer,
+ implements(monitoring)). % built-in protocol for event handlers
+
+ :- initialization(define_events(_, _, _, _, tracer)).
+
+ before(Object, Message, Sender) :-
+ write('call: '), writeq(Object), write(' <-- '), writeq(Message),
+ write(' from '), writeq(Sender), nl.
+
+ after(Object, Message, Sender) :-
+ write('exit: '), writeq(Object), write(' <-- '), writeq(Message),
+ write(' from '), writeq(Sender), nl.
+
+:- end_object.
+```
+
+Ето как можем да проследим реакцията на изпращане на съобщение :
+
+```logtalk
+?- list::member(X, [1,2,3]).
+
+call: list <-- member(X, [1,2,3]) from user
+exit: list <-- member(1, [1,2,3]) from user
+X = 1 ;
+exit: list <-- member(2, [1,2,3]) from user
+X = 2 ;
+exit: list <-- member(3, [1,2,3]) from user
+X = 3
+yes
+```
+
+Събития могат да се изтрият динамично чрез define_events/5 и abolish_events/5 предикати.
+
+
+## Lambda expressions
+
+
+Logtalk поддържа lambda expressions. Lambda параметрите се предават чрез списък към (>>)/2 infix оператор свързвайки ги с lambda.
+Ето няколко примера :
+
+```logtalk
+?- {library(metapredicates_loader)}.
+yes
+
+?- meta::map([X,Y]>>(Y is 2*X), [1,2,3], Ys).
+Ys = [2,4,6]
+yes
+```
+
+Currying се поддържа :
+
+```logtalk
+?- meta::map([X]>>([Y]>>(Y is 2*X)), [1,2,3], Ys).
+Ys = [2,4,6]
+yes
+```
+
+Lambda free variables can be expressed using the extended syntax {Free1, ...}/[Parameter1, ...]>>Lambda.
+
+
+## Макроси (Macros)
+
+
+Термини и Цели могат да бъдат пре-интерпретирани (expanded) по време на компилация ако специфицираме hook-обект който дефинира прецедурите на пре-интерпретиране.
+Нека следният обект е записан във фаил source.lgt :
+
+```logtalk
+:- object(source).
+
+ :- public(bar/1).
+ bar(X) :- foo(X).
+
+ foo(a). foo(b). foo(c).
+
+:- end_object.
+```
+
+и следния hooк-обект е записан в my_macros.lgt, който пре-интерпретира foo/1 предиката :
+
+```logtalk
+:- object(my_macros,
+ implements(expanding)). % built-in protocol for expanding predicates
+
+ term_expansion(foo(Char), baz(Code)) :-
+ char_code(Char, Code). % standard built-in predicate
+
+ goal_expansion(foo(X), baz(X)).
+
+:- end_object.
+```
+
+След зареждането на файла с макроси ние можем да пре-интерпретираме ползайки hook-флаг за компилатора :
+
+```logtalk
+?- logtalk_load(my_macros), logtalk_load(source, [hook(my_macros)]).
+yes
+
+?- source::bar(X).
+X = 97 ;
+X = 98 ;
+X = 99
+true
+```
+
+## Допълнителна информация (Further information)
+
+
+Посетете сайта на [Logtalk website](http://logtalk.org) за повече информация.
+
diff --git a/bg-bg/perl-bg.html.markdown b/bg-bg/perl-bg.html.markdown
index babd2d4d..e6da8965 100644
--- a/bg-bg/perl-bg.html.markdown
+++ b/bg-bg/perl-bg.html.markdown
@@ -2,7 +2,7 @@
name: perl
category: language
language: perl
-filename: learnperl.pl
+filename: learnperl-bg.pl
contributors:
- ["Korjavin Ivan", "http://github.com/korjavin"]
- ["Dan Book", "http://github.com/Grinnz"]
@@ -11,10 +11,10 @@ translators:
lang: bg-bg
---
-Perl 5 е изключително мощен език за програмиране с широка област на приложение
+Perl е изключително мощен език за програмиране с широка област на приложение
и над 25 годишна история.
-Perl 5 работи на повече от 100 операционни системи от мини до супер-компютри и е
+Perl работи на повече от 100 операционни системи от мини до супер-компютри и е
подходящ както за бърза разработка на скриптове така и за огромни приложения.
```perl
@@ -281,7 +281,7 @@ sub increment {
1;
-# Методите могат да се извикват на клас или на обект като се използва оператора
+# Методите могат да се извикват на клас или на обект като се използва оператора
# стрелка (->).
use MyCounter;
@@ -323,4 +323,3 @@ sub increment {
- [Learn at www.perl.com](http://www.perl.org/learn.html)
- [perldoc](http://perldoc.perl.org/)
- и идващото с perl: `perldoc perlintro`
-
diff --git a/c++.html.markdown b/c++.html.markdown
index 24d38df7..6e94e03e 100644
--- a/c++.html.markdown
+++ b/c++.html.markdown
@@ -2,17 +2,16 @@
language: c++
filename: learncpp.cpp
contributors:
- - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Steven Basart", "https://github.com/xksteven"]
- ["Matt Kline", "https://github.com/mrkline"]
- ["Geoff Liu", "http://geoffliu.me"]
- - ["Connor Waters", "http://github.com/connorwaters"]
- - ["Ankush Goyal", "http://github.com/ankushg07"]
+ - ["Connor Waters", "https://github.com/connorwaters"]
+ - ["Ankush Goyal", "https://github.com/ankushg07"]
- ["Jatin Dhankhar", "https://github.com/jatindhankhar"]
-lang: en
---
C++ is a systems programming language that,
-[according to its inventor Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
+[according to its inventor Bjarne Stroustrup](https://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
was designed to
- be a "better C"
@@ -38,7 +37,7 @@ one of the most widely-used programming languages.
// Just like in C, your program's entry point is a function called
// main with an integer return type.
// This value serves as the program's exit status.
-// See http://en.wikipedia.org/wiki/Exit_status for more information.
+// See https://en.wikipedia.org/wiki/Exit_status for more information.
int main(int argc, char** argv)
{
// Command line arguments are passed in by argc and argv in the same way
@@ -72,10 +71,16 @@ void func(); // function which may accept any number of arguments
// Use nullptr instead of NULL in C++
int* ip = nullptr;
-// C standard headers are available in C++,
-// but are prefixed with "c" and have no .h suffix.
+// C standard headers are available in C++.
+// C headers end in .h, while
+// C++ headers are prefixed with "c" and have no ".h" suffix.
+
+// The C++ standard version:
#include <cstdio>
+// The C standard version:
+#include <stdio.h>
+
int main()
{
printf("Hello, world!\n");
@@ -194,10 +199,10 @@ int main()
cin >> myInt;
// cout can also be formatted
- cout << "Your favorite number is " << myInt << "\n";
+ cout << "Your favorite number is " << myInt << '\n';
// prints "Your favorite number is <myInt>"
- cerr << "Used for error messages";
+ cerr << "Used for error messages";
}
//////////
@@ -217,7 +222,7 @@ cout << myString + myOtherString; // "Hello World"
cout << myString + " You"; // "Hello You"
-// C++ strings are mutable and have value semantics.
+// C++ strings are mutable.
myString.append(" Dog");
cout << myString; // "Hello Dog"
@@ -252,7 +257,7 @@ fooRef = bar;
cout << &fooRef << endl; //Still prints the address of foo
cout << fooRef; // Prints "I am bar"
-//The address of fooRef remains the same, i.e. it is still referring to foo.
+// The address of fooRef remains the same, i.e. it is still referring to foo.
const string& barRef = bar; // Create a const reference to bar.
@@ -456,7 +461,7 @@ void Dog::print() const
Dog::~Dog()
{
- cout << "Goodbye " << name << "\n";
+ std::cout << "Goodbye " << name << '\n';
}
int main() {
@@ -474,10 +479,11 @@ int main() {
// without a public or protected method for doing so
class OwnedDog : public Dog {
+public:
void setOwner(const std::string& dogsOwner);
// Override the behavior of the print function for all OwnedDogs. See
- // http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
+ // https://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
// for a more general introduction if you are unfamiliar with
// subtype polymorphism.
// The override keyword is optional but makes sure you are actually
@@ -498,7 +504,7 @@ void OwnedDog::setOwner(const std::string& dogsOwner)
void OwnedDog::print() const
{
Dog::print(); // Call the print function in the base Dog class
- std::cout << "Dog is owned by " << owner << "\n";
+ std::cout << "Dog is owned by " << owner << '\n';
// Prints "Dog is <name> and weights <weight>"
// "Dog is owned by <owner>"
}
@@ -547,10 +553,14 @@ Point Point::operator+(const Point& rhs) const
return Point(x + rhs.x, y + rhs.y);
}
+// It's good practice to return a reference to the leftmost variable of
+// an assignment. `(a += b) == c` will work this way.
Point& Point::operator+=(const Point& rhs)
{
x += rhs.x;
y += rhs.y;
+
+ // `this` is a pointer to the object, on which a method is called.
return *this;
}
@@ -606,7 +616,7 @@ boxOfBox.insert(intBox);
// template<typename T>
// instead. The 'class' keyword and 'typename' keywords are _mostly_
// interchangeable in this case. For the full explanation, see
-// http://en.wikipedia.org/wiki/Typename
+// https://en.wikipedia.org/wiki/Typename
// (yes, that keyword has its own Wikipedia page).
// Similarly, a template function:
@@ -650,8 +660,8 @@ printMessage<10>(); // Prints "Learn C++ faster in only 10 minutes!"
/////////////////////
// The standard library provides a few exception types
-// (see http://en.cppreference.com/w/cpp/error/exception)
-// but any type can be thrown an as exception
+// (see https://en.cppreference.com/w/cpp/error/exception)
+// but any type can be thrown as an exception
#include <exception>
#include <stdexcept>
@@ -751,7 +761,7 @@ failure:
// things are a little cleaner, but still sub-optimal.
void doSomethingWithAFile(const char* filename)
{
- FILE* fh = fopen(filename, "r"); // Open the file in read mode
+ FILE* fh = fopen(filename, "r"); // Open the file in shared_ptrread mode
if (fh == nullptr)
throw std::runtime_error("Could not open the file.");
@@ -803,7 +813,154 @@ void doSomethingWithAFile(const std::string& filename)
// all automatically destroy their contents when they fall out of scope.
// - Mutexes using lock_guard and unique_lock
-// containers with object keys of non-primitive values (custom classes) require
+
+/////////////////////
+// Smart Pointer
+/////////////////////
+
+// Generally a smart pointer is a class which wraps a "raw pointer" (usage of "new"
+// respectively malloc/calloc in C). The goal is to be able to
+// manage the lifetime of the object being pointed to without ever needing to explicitly delete
+// the object. The term itself simply describes a set of pointers with the
+// mentioned abstraction.
+// Smart pointers should preferred over raw pointers, to prevent
+// risky memory leaks, which happen if you forget to delete an object.
+
+// Usage of a raw pointer:
+Dog* ptr = new Dog();
+ptr->bark();
+delete ptr;
+
+// By using a smart pointer, you don't have to worry about the deletion
+// of the object anymore.
+// A smart pointer describes a policy, to count the references to the
+// pointer. The object gets destroyed when the last
+// reference to the object gets destroyed.
+
+// Usage of "std::shared_ptr":
+void foo()
+{
+// It's no longer necessary to delete the Dog.
+std::shared_ptr<Dog> doggo(new Dog());
+doggo->bark();
+}
+
+// Beware of possible circular references!!!
+// There will be always a reference, so it will be never destroyed!
+std::shared_ptr<Dog> doggo_one(new Dog());
+std::shared_ptr<Dog> doggo_two(new Dog());
+doggo_one = doggo_two; // p1 references p2
+doggo_two = doggo_one; // p2 references p1
+
+// There are several kinds of smart pointers.
+// The way you have to use them is always the same.
+// This leads us to the question: when should we use each kind of smart pointer?
+// std::unique_ptr - use it when you just want to hold one reference to
+// the object.
+// std::shared_ptr - use it when you want to hold multiple references to the
+// same object and want to make sure that it's deallocated
+// when all references are gone.
+// std::weak_ptr - use it when you want to access
+// the underlying object of a std::shared_ptr without causing that object to stay allocated.
+// Weak pointers are used to prevent circular referencing.
+
+
+/////////////////////
+// Containers
+/////////////////////
+
+// Containers or the Standard Template Library are some predefined templates.
+// They manage the storage space for its elements and provide
+// member functions to access and manipulate them.
+
+// Few containers are as follows:
+
+// Vector (Dynamic array)
+// Allow us to Define the Array or list of objects at run time
+#include <vector>
+string val;
+vector<string> my_vector; // initialize the vector
+cin >> val;
+my_vector.push_back(val); // will push the value of 'val' into vector ("array") my_vector
+my_vector.push_back(val); // will push the value into the vector again (now having two elements)
+
+// To iterate through a vector we have 2 choices:
+// Either classic looping (iterating through the vector from index 0 to its last index):
+for (int i = 0; i < my_vector.size(); i++) {
+ cout << my_vector[i] << endl; // for accessing a vector's element we can use the operator []
+}
+
+// or using an iterator:
+vector<string>::iterator it; // initialize the iterator for vector
+for (it = my_vector.begin(); it != my_vector.end(); ++it) {
+ cout << *it << endl;
+}
+
+// Set
+// Sets are containers that store unique elements following a specific order.
+// Set is a very useful container to store unique values in sorted order
+// without any other functions or code.
+
+#include<set>
+set<int> ST; // Will initialize the set of int data type
+ST.insert(30); // Will insert the value 30 in set ST
+ST.insert(10); // Will insert the value 10 in set ST
+ST.insert(20); // Will insert the value 20 in set ST
+ST.insert(30); // Will insert the value 30 in set ST
+// Now elements of sets are as follows
+// 10 20 30
+
+// To erase an element
+ST.erase(20); // Will erase element with value 20
+// Set ST: 10 30
+// To iterate through Set we use iterators
+set<int>::iterator it;
+for(it=ST.begin();it!=ST.end();it++) {
+ cout << *it << endl;
+}
+// Output:
+// 10
+// 30
+
+// To clear the complete container we use Container_name.clear()
+ST.clear();
+cout << ST.size(); // will print the size of set ST
+// Output: 0
+
+// NOTE: for duplicate elements we can use multiset
+// NOTE: For hash sets, use unordered_set. They are more efficient but
+// do not preserve order. unordered_set is available since C++11
+
+// Map
+// Maps store elements formed by a combination of a key value
+// and a mapped value, following a specific order.
+
+#include<map>
+map<char, int> mymap; // Will initialize the map with key as char and value as int
+
+mymap.insert(pair<char,int>('A',1));
+// Will insert value 1 for key A
+mymap.insert(pair<char,int>('Z',26));
+// Will insert value 26 for key Z
+
+// To iterate
+map<char,int>::iterator it;
+for (it=mymap.begin(); it!=mymap.end(); ++it)
+ std::cout << it->first << "->" << it->second << std::cout;
+// Output:
+// A->1
+// Z->26
+
+// To find the value corresponding to a key
+it = mymap.find('Z');
+cout << it->second;
+
+// Output: 26
+
+// NOTE: For hash maps, use unordered_map. They are more efficient but do
+// not preserve order. unordered_map is available since C++11.
+
+// Containers with object keys of non-primitive values (custom classes) require
// compare function in the object itself or as a function pointer. Primitives
// have default comparators, but you can override it.
class Foo {
@@ -816,12 +973,13 @@ struct compareFunction {
return a.j < b.j;
}
};
-//this isn't allowed (although it can vary depending on compiler)
-//std::map<Foo, int> fooMap;
+// this isn't allowed (although it can vary depending on compiler)
+// std::map<Foo, int> fooMap;
std::map<Foo, int, compareFunction> fooMap;
fooMap[Foo(1)] = 1;
fooMap.find(Foo(1)); //true
+
///////////////////////////////////////
// Lambda Expressions (C++11 and above)
///////////////////////////////////////
@@ -872,7 +1030,7 @@ sort(dog_ids.begin(), dog_ids.end(), [&weight](const int &lhs, const int &rhs) {
return weight[lhs] < weight[rhs];
});
// Note we captured "weight" by reference in the above example.
-// More on Lambdas in C++ : http://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11
+// More on Lambdas in C++ : https://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11
///////////////////////////////
// Range For (C++11 and above)
@@ -948,7 +1106,8 @@ f1 = f2;
#include<tuple>
-// Conceptually, Tuples are similar to old data structures (C-like structs) but instead of having named data members,
+// Conceptually, Tuples are similar to old data structures (C-like structs)
+// but instead of having named data members,
// its elements are accessed by their order in the tuple.
// We start with constructing a tuple.
@@ -959,124 +1118,33 @@ const int maxL = 15;
auto second = make_tuple(maxN, maxL);
// Printing elements of 'first' tuple
-cout << get<0>(first) << " " << get<1>(first) << "\n"; //prints : 10 A
+cout << get<0>(first) << " " << get<1>(first) << '\n'; //prints : 10 A
// Printing elements of 'second' tuple
-cout << get<0>(second) << " " << get<1>(second) << "\n"; // prints: 1000000000 15
+cout << get<0>(second) << " " << get<1>(second) << '\n'; // prints: 1000000000 15
// Unpacking tuple into variables
int first_int;
char first_char;
tie(first_int, first_char) = first;
-cout << first_int << " " << first_char << "\n"; // prints : 10 A
+cout << first_int << " " << first_char << '\n'; // prints : 10 A
// We can also create tuple like this.
tuple<int, char, double> third(11, 'A', 3.14141);
// tuple_size returns number of elements in a tuple (as a constexpr)
-cout << tuple_size<decltype(third)>::value << "\n"; // prints: 3
+cout << tuple_size<decltype(third)>::value << '\n'; // prints: 3
// tuple_cat concatenates the elements of all the tuples in the same order.
auto concatenated_tuple = tuple_cat(first, second, third);
// concatenated_tuple becomes = (10, 'A', 1e9, 15, 11, 'A', 3.14141)
-cout << get<0>(concatenated_tuple) << "\n"; // prints: 10
-cout << get<3>(concatenated_tuple) << "\n"; // prints: 15
-cout << get<5>(concatenated_tuple) << "\n"; // prints: 'A'
-
-
-/////////////////////
-// Containers
-/////////////////////
-
-// Containers or the Standard Template Library are some predefined templates.
-// They manage the storage space for its elements and provide
-// member functions to access and manipulate them.
-
-// Few containers are as follows:
-
-// Vector (Dynamic array)
-// Allow us to Define the Array or list of objects at run time
-#include<vector>
-vector<Data_Type> Vector_name; // used to initialize the vector
-cin >> val;
-Vector_name.push_back(val); // will push the value of variable into array
-
-// To iterate through vector, we have 2 choices:
-// Normal looping
-for(int i=0; i<Vector_name.size(); i++)
-// It will iterate through the vector from index '0' till last index
-
-// Iterator
-vector<Data_Type>::iterator it; // initialize the iterator for vector
-for(it=vector_name.begin(); it!=vector_name.end();++it)
-
-// For accessing the element of the vector
-// Operator []
-var = vector_name[index]; // Will assign value at that index to var
-
-
-// Set
-// Sets are containers that store unique elements following a specific order.
-// Set is a very useful container to store unique values in sorted order
-// without any other functions or code.
-
-#include<set>
-set<int> ST; // Will initialize the set of int data type
-ST.insert(30); // Will insert the value 30 in set ST
-ST.insert(10); // Will insert the value 10 in set ST
-ST.insert(20); // Will insert the value 20 in set ST
-ST.insert(30); // Will insert the value 30 in set ST
-// Now elements of sets are as follows
-// 10 20 30
-
-// To erase an element
-ST.erase(20); // Will erase element with value 20
-// Set ST: 10 30
-// To iterate through Set we use iterators
-set<int>::iterator it;
-for(it=ST.begin();it<ST.end();it++) {
- cout << *it << endl;
-}
-// Output:
-// 10
-// 30
-
-// To clear the complete container we use Container_name.clear()
-ST.clear();
-cout << ST.size(); // will print the size of set ST
-// Output: 0
-
-// NOTE: for duplicate elements we can use multiset
-
-// Map
-// Maps store elements formed by a combination of a key value
-// and a mapped value, following a specific order.
-
-#include<map>
-map<char, int> mymap; // Will initialize the map with key as char and value as int
-
-mymap.insert(pair<char,int>('A',1));
-// Will insert value 1 for key A
-mymap.insert(pair<char,int>('Z',26));
-// Will insert value 26 for key Z
-
-// To iterate
-map<char,int>::iterator it;
-for (it=mymap.begin(); it!=mymap.end(); ++it)
- std::cout << it->first << "->" << it->second << '\n';
-// Output:
-// A->1
-// Z->26
-
-// To find the value corresponding to a key
-it = mymap.find('Z');
-cout << it->second;
-
-// Output: 26
+cout << get<0>(concatenated_tuple) << '\n'; // prints: 10
+cout << get<3>(concatenated_tuple) << '\n'; // prints: 15
+cout << get<5>(concatenated_tuple) << '\n'; // prints: 'A'
///////////////////////////////////
@@ -1127,7 +1195,6 @@ compl 4 // Performs a bitwise not
```
Further Reading:
-An up-to-date language reference can be found at
-<http://cppreference.com/w/cpp>
-
-Additional resources may be found at <http://cplusplus.com>
+* An up-to-date language reference can be found at [CPP Reference](http://cppreference.com/w/cpp).
+* Additional resources may be found at [CPlusPlus](http://cplusplus.com).
+* A tutorial covering basics of language and setting up coding environment is available at [TheChernoProject - C++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb).
diff --git a/c.html.markdown b/c.html.markdown
index 57ce72d2..a57be1dc 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -8,6 +8,9 @@ contributors:
- ["Marco Scannadinari", "https://marcoms.github.io"]
- ["Zachary Ferguson", "https://github.io/zfergus2"]
- ["himanshu", "https://github.com/himanshu81494"]
+ - ["Joshua Li", "https://github.com/JoshuaRLi"]
+ - ["Dragos B. Chirila", "https://github.com/dchirila"]
+ - ["Heitor P. de Bittencourt", "https://github.com/heitorPB/"]
---
Ah, C. Still **the** language of modern high-performance computing.
@@ -16,6 +19,16 @@ C is the lowest-level language most programmers will ever use, but
it more than makes up for it with raw speed. Just be aware of its manual
memory management and C will take you as far as you need to go.
+> **About compiler flags**
+>
+> By default, gcc and clang are pretty quiet about compilation warnings and
+> errors, which can be very useful information. Explicitly using stricter
+> compiler flags is recommended. Here are some recommended defaults:
+>
+> `-Wall -Wextra -Werror -O2 -std=c99 -pedantic`
+>
+> For information on what these flags do as well as other flags, consult the man page for your C compiler (e.g. `man 1 gcc`) or just search online.
+
```c
// Single-line comments start with // - only available in C99 and later.
@@ -76,8 +89,12 @@ int main (int argc, char** argv)
// Types
///////////////////////////////////////
- // All variables MUST be declared at the top of the current block scope
- // we declare them dynamically along the code for the sake of the tutorial
+ // Compilers that are not C99-compliant require that variables MUST be
+ // declared at the top of the current block scope.
+ // Compilers that ARE C99-compliant allow declarations near the point where
+ // the value is used.
+ // For the sake of the tutorial, variables are declared dynamically under
+ // C99-compliant standards.
// ints are usually 4 bytes
int x_int = 0;
@@ -90,7 +107,7 @@ int main (int argc, char** argv)
char y_char = 'y'; // Char literals are quoted with ''
// longs are often 4 to 8 bytes; long longs are guaranteed to be at least
- // 64 bits
+ // 8 bytes
long x_long = 0;
long long x_long_long = 0;
@@ -130,6 +147,17 @@ int main (int argc, char** argv)
// You can initialize an array to 0 thusly:
char my_array[20] = {0};
+ // where the "{0}" part is called an "array initializer".
+ // NOTE that you get away without explicitly declaring the size of the array,
+ // IF you initialize the array on the same line. So, the following declaration
+ // is equivalent:
+ char my_array[] = {0};
+ // BUT, then you have to evaluate the size of the array at run-time, like this:
+ size_t my_array_size = sizeof(my_array) / sizeof(my_array[0]);
+ // WARNING If you adopt this approach, you should evaluate the size *before*
+ // you begin passing the array to function (see later discussion), because
+ // arrays get "downgraded" to raw pointers when they are passed to functions
+ // (so the statement above will produce the wrong result inside the function).
// Indexing an array is like other languages -- or,
// rather, other languages are like C
@@ -269,7 +297,7 @@ int main (int argc, char** argv)
// While loops exist
int ii = 0;
- while (ii < 10) { //ANY value not zero is true.
+ while (ii < 10) { //ANY value less than ten is true.
printf("%d, ", ii++); // ii++ increments ii AFTER using its current value.
} // => prints "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
@@ -302,7 +330,7 @@ int main (int argc, char** argv)
// branching with multiple choices: switch()
switch (a) {
- case 0: // labels need to be integral *constant* expressions
+ case 0: // labels need to be integral *constant* expressions (such as enums)
printf("Hey, 'a' equals 0!\n");
break; // if you don't break, control flow falls over labels
case 1:
@@ -324,7 +352,7 @@ int main (int argc, char** argv)
using "goto" in C
*/
typedef enum { false, true } bool;
- // for C don't have bool as data type :(
+ // for C don't have bool as data type before C99 :(
bool disaster = false;
int i, j;
for(i=0;i<100;++i)
@@ -336,10 +364,10 @@ int main (int argc, char** argv)
goto error;
}
error :
- printf("Error occured at i = %d & j = %d.\n", i, j);
+ printf("Error occurred at i = %d & j = %d.\n", i, j);
/*
https://ideone.com/GuPhd6
- this will print out "Error occured at i = 52 & j = 99."
+ this will print out "Error occurred at i = 51 & j = 99."
*/
///////////////////////////////////////
@@ -363,8 +391,8 @@ int main (int argc, char** argv)
// respectively, use the CHAR_MAX, SCHAR_MAX and UCHAR_MAX macros from <limits.h>
// Integral types can be cast to floating-point types, and vice-versa.
- printf("%f\n", (float)100); // %f formats a float
- printf("%lf\n", (double)100); // %lf formats a double
+ printf("%f\n", (double) 100); // %f always formats a double...
+ printf("%f\n", (float) 100); // ...even with a float.
printf("%d\n", (char)100.0);
///////////////////////////////////////
@@ -422,7 +450,7 @@ int main (int argc, char** argv)
// or when it's the argument of the `sizeof` or `alignof` operator:
int arraythethird[10];
int *ptr = arraythethird; // equivalent with int *ptr = &arr[0];
- printf("%zu, %zu\n", sizeof arraythethird, sizeof ptr);
+ printf("%zu, %zu\n", sizeof(arraythethird), sizeof(ptr));
// probably prints "40, 4" or "40, 8"
// Pointers are incremented and decremented based on their type
@@ -439,16 +467,24 @@ int main (int argc, char** argv)
*(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx
} // Initialize memory to 20, 19, 18, 17... 2, 1 (as ints)
+ // Be careful passing user-provided values to malloc! If you want
+ // to be safe, you can use calloc instead (which, unlike malloc, also zeros out the memory)
+ int* my_other_ptr = calloc(20, sizeof(int));
+
// Note that there is no standard way to get the length of a
// dynamically allocated array in C. Because of this, if your arrays are
// going to be passed around your program a lot, you need another variable
// to keep track of the number of elements (size) of an array. See the
// functions section for more info.
- int size = 10;
- int *my_arr = malloc(sizeof(int) * size);
+ size_t size = 10;
+ int *my_arr = calloc(size, sizeof(int));
// Add an element to the array
size++;
my_arr = realloc(my_arr, sizeof(int) * size);
+ if (my_arr == NULL) {
+ //Remember to check for realloc failure!
+ return
+ }
my_arr[10] = 5;
// Dereferencing memory that you haven't allocated gives
@@ -503,9 +539,11 @@ Example: in-place string reversal
void str_reverse(char *str_in)
{
char tmp;
- int ii = 0;
+ size_t ii = 0;
size_t len = strlen(str_in); // `strlen()` is part of the c standard library
- for (ii = 0; ii < len / 2; ii++) {
+ // NOTE: length returned by `strlen` DOESN'T include the
+ // terminating NULL byte ('\0')
+ for (ii = 0; ii < len / 2; ii++) { // in C99 you can directly declare type of `ii` here
tmp = str_in[ii];
str_in[ii] = str_in[len - ii - 1]; // ii-th char from end
str_in[len - ii - 1] = tmp;
@@ -546,7 +584,7 @@ array in C.
*/
// Size must be passed!
// Otherwise, this function has no way of knowing how big the array is.
-void printIntArray(int *arr, int size) {
+void printIntArray(int *arr, size_t size) {
int i;
for (i = 0; i < size; i++) {
printf("arr[%d] is: %d\n", i, arr[i]);
@@ -559,7 +597,7 @@ printIntArray(my_arr, size);
// will print "arr[0] is: 1" etc
*/
-// if referring to external variables outside function, must use extern keyword.
+// if referring to external variables outside function, you should use the extern keyword.
int i = 0;
void testFunc() {
extern int i; //i here is now using external variable i
@@ -570,6 +608,14 @@ static int j = 0; //other files using testFunc2() cannot access variable j
void testFunc2() {
extern int j;
}
+// The static keyword makes a variable inaccessible to code outside the
+// compilation unit. (On almost all systems, a "compilation unit" is a .c
+// file.) static can apply both to global (to the compilation unit) variables,
+// functions, and function-local variables. When using static with
+// function-local variables, the variable is effectively global and retains its
+// value across function calls, but is only accessible within the function it
+// is declared in. Additionally, static variables are initialized to 0 if not
+// declared with some other starting value.
//**You may also declare functions as static to make them private**
///////////////////////////////////////
@@ -656,6 +702,7 @@ typedef void (*my_fnp_type)(char *);
// ...
// my_fnp_type f;
+
//Special characters:
/*
'\a'; // alert (bell) character
@@ -683,7 +730,8 @@ typedef void (*my_fnp_type)(char *);
"%3.2f"; // minimum 3 digits left and 2 digits right decimal float
"%7.4s"; // (can do with strings too)
"%c"; // char
-"%p"; // pointer
+"%p"; // pointer. NOTE: need to (void *)-cast the pointer, before passing
+ // it as an argument to `printf`.
"%x"; // hexadecimal
"%o"; // octal
"%%"; // prints %
@@ -738,14 +786,20 @@ as the C file.
/* Like c source files macros can be defined in headers and used in files */
/* that include this header file. */
#define EXAMPLE_NAME "Dennis Ritchie"
-/* Function macros can also be defined. */
-#define ADD(a, b) (a + b)
+
+/* Function macros can also be defined. */
+#define ADD(a, b) ((a) + (b))
+
+/* Notice the parenthesis surrounding the arguments -- this is important to */
+/* ensure that a and b don't get expanded in an unexpected way (e.g. consider */
+/* MUL(x, y) (x * y); MUL(1 + 2, 3) would expand to (1 + 2 * 3), yielding an */
+/* incorrect result) */
/* Structs and typedefs can be used for consistency between files. */
-typedef struct node
+typedef struct Node
{
int val;
- struct node *next;
+ struct Node *next;
} Node;
/* So can enumerations. */
@@ -769,14 +823,14 @@ Best to find yourself a copy of [K&R, aka "The C Programming Language"](https://
It is *the* book about C, written by Dennis Ritchie, the creator of C, and Brian Kernighan. Be careful, though - it's ancient and it contains some
inaccuracies (well, ideas that are not considered good anymore) or now-changed practices.
-Another good resource is [Learn C The Hard Way](http://c.learncodethehardway.org/book/).
+Another good resource is [Learn C The Hard Way](http://learncodethehardway.org/c/).
If you have a question, read the [compl.lang.c Frequently Asked Questions](http://c-faq.com).
It's very important to use proper spacing, indentation and to be consistent with your coding style in general.
Readable code is better than clever code and fast code. For a good, sane coding style to adopt, see the
-[Linux kernel coding style](https://www.kernel.org/doc/Documentation/CodingStyle).
+[Linux kernel coding style](https://www.kernel.org/doc/Documentation/process/coding-style.rst).
Other than that, Google is your friend.
-[1] http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member
+[1] [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member)
diff --git a/ca-es/asciidoc-ca.html.markdown b/ca-es/asciidoc-ca.html.markdown
new file mode 100644
index 00000000..a88aba52
--- /dev/null
+++ b/ca-es/asciidoc-ca.html.markdown
@@ -0,0 +1,134 @@
+---
+language: asciidoc
+contributors:
+ - ["Ryan Mavilia", "http://unoriginality.rocks/"]
+translators:
+ - ["Abel Salgado Romero", "https://twitter.com/abelsromero"]
+lang: ca-es
+filename: asciidoc-ca.md
+---
+
+AsciiDoc és un llenguatge de marques similar a Markdown i que pot ser usat per qualsevol ús, des de llibres fins a blogs.
+Creat al 2002 per Stuart Rackham, és un llenguatge simple però permet un gran nivell de personalització.
+
+Capçalera de document
+
+La capçalera és opcional i no pot contenir línies buides. Ha d'estar separada del contingut per com a mínim una línia en blanc.
+
+Només títol
+
+```
+= Títol del document
+
+Primer contingut del document.
+```
+
+Títol i autor
+
+```
+= Títol del document
+Nom Cognom(s) <nom.cognom@learnxinyminutes.com>
+
+Inici d'aquest document.
+```
+
+Múltiples autors
+
+```
+= Títol del document
+John Doe <john@go.com>; Jane Doe<jane@yo.com>; Black Beard <beardy@pirate.com>
+
+Inici d'un document amb múltiples autors.
+```
+
+Línia de versió (requereix línia d'autor)
+
+```
+= Títol del document V1
+Potato Man <chip@crunchy.com>
+v1.0, 2016-01-13
+
+Aquest article sobre patates fregides serà genial.
+```
+
+Paràgraf
+
+```
+No necessites res especial per un paràgraf.
+
+Insereix una línia buida entre cada paràgraf per separar-los.
+
+Per inserir un salt de línia, afegeix només un +
+i ja ho tens!
+```
+
+Donant format al text
+
+```
+_guió baix per cursiva_
+*asteriscs per negreta*
+*_combina'ls i veuràs_*
+`usa cometes invertides per monospace`
+`*combina per negreta monospace*`
+```
+
+Títols de secció
+
+```
+= Nivell 0 (usa'l només pel títol del document)
+
+== Nivell 1 <h2>
+
+=== Nivell 2 <h3>
+
+==== Nivell 3 <h4>
+
+===== Nivell 4 <h5>
+```
+
+Llistes
+
+Per crear una llista sense ordre usa asteriscs.
+
+```
+* foo
+* bar
+* baz
+```
+
+Per crear una llista numerada usa punts.
+
+```
+. element 1
+. element 2
+. element 3
+```
+
+Pots crear fins a 5 subnivells de llista afegint asteriscs o punts.
+
+```
+* foo 1
+** foo 2
+*** foo 3
+**** foo 4
+***** foo 5
+
+. foo 1
+.. foo 2
+... foo 3
+.... foo 4
+..... foo 5
+```
+
+## Referències
+
+Existeixen dues eines per processar documentació en AsciiDoc:
+
+1. [AsciiDoc](http://asciidoc.org/): implementació original per Python, disponible a las principals distribucions Linux. Versió estable actualment en mode manteniment.
+2. [Asciidoctor](http://asciidoctor.org/): implementació alternativa per Ruby, usable també des de Java i JavaScript. Implementació completa en evolució, té com a objectiu ampliar AsciiDoc amb noves funcionalitats i conversors de sortida.
+
+Els següents enllaços pertanyen a `Asciidoctor` (documentació en anglès):
+
+* [Comparació de sintaxi Markdown - AsciiDoc](http://asciidoctor.org/docs/user-manual/#comparison-by-example): comparativa d'elements comuns entre Markdown i AsciiDoc.
+* [Primeres pases](http://asciidoctor.org/docs/#get-started-with-asciidoctor): manuals d'instal·lació i inici per convertir documents simples.
+* [Manual d'usuari d'Asciidoctor](http://asciidoctor.org/docs/user-manual/): referència completa en un únic document, conté exemples, guies d'eines, etc.
diff --git a/ca-es/go-ca.html.markdown b/ca-es/go-ca.html.markdown
new file mode 100644
index 00000000..99f0d393
--- /dev/null
+++ b/ca-es/go-ca.html.markdown
@@ -0,0 +1,464 @@
+---
+name: Go
+category: language
+language: Go
+lang: ca-es
+filename: learngo-ca.go
+contributors:
+ - ["Sonia Keys", "https://github.com/soniakeys"]
+ - ["Christopher Bess", "https://github.com/cbess"]
+ - ["Jesse Johnson", "https://github.com/holocronweaver"]
+ - ["Quint Guvernator", "https://github.com/qguv"]
+ - ["Jose Donizetti", "https://github.com/josedonizetti"]
+ - ["Alexej Friesen", "https://github.com/heyalexej"]
+ - ["Clayton Walker", "https://github.com/cwalk"]
+ - ["Leonid Shevtsov", "https://github.com/leonid-shevtsov"]
+translators:
+ - ["Xavier Sala", "http://github.com/utrescu"]
+---
+
+Go es va crear degut a la necessitat de fer la feina ràpidament. No segueix
+la darrera tendència en informàtica, però és la nova forma i la més ràpida de
+resoldre problemes reals.
+
+Té conceptes familiars de llenguatges imperatius amb tipat estàtic. És ràpid
+compilant i ràpid al executar, afegeix una forma fàcil d'entedre de
+concurrència per CPUs de diferents núclis i té característiques que ajuden en
+la programació a gran escala.
+
+Go té una gran llibreria de funcions estàndard i una comunitat d'usuaris
+entusiasta.
+
+```go
+// Comentari d'una sola línia
+/* Comentari
+multilínia */
+
+// La clausula `package` apareix sempre a sobre de cada fitxer de codi font.
+// Quan es desenvolupa un executable en comptes d'una llibreria el nom que
+// s'ha de fer servir de `package` ha de ser 'main'.
+package main
+
+// `import` es fa servir per indicar quins paquets de llibreries fa servir
+// aquest fitxer.
+import (
+ "fmt" // Un paquet de la llibreria estàndard de Go.
+ "io/ioutil" // Les funcions ioutil de io
+ m "math" // La llibreria de matemàtiques que es referenciarà com a m.
+ "net/http" // Si, un servidor web!
+ "os" // funcions per treballar amb el sistema de fitxers
+ "strconv" // Conversions de cadenes
+)
+
+// La definició d'una funció. `main` és especial. És el punt d'entrada per
+// l'executable. Tant si t'agrada com si no, Go fa servir corxets.
+func main() {
+ // Println imprimeix una línia al canal de sortida.
+ // Es qualifica amb el nom del paquet, fmt.
+ fmt.Println("Hola món!")
+
+ // Crida a una altra funció dins d'aquest paquet.
+ mesEnllaDeHola()
+}
+
+// Els paràmetres de les funcions es posen dins de parèntesis.
+// Els parèntesis fan falta encara que no hi hagi cap paràmetre.
+func mesEnllaDeHola() {
+ var x int // Declaració d'una variable.
+ // S'han de declarar abans de fer-les servir.
+ x = 3 // Assignació d'una variable
+ // Hi ha una forma "Curta" amb :=
+ // Descobreix el tipus, declara la variable i li assigna valor.
+ y := 4
+ sum, prod := learnMultiple(x, y) // La funció retorna dos valors.
+ fmt.Println("sum:", sum, "prod:", prod) // Sortida simple.
+ aprenTipus() // < y minuts, aprèn més!
+}
+
+/* <- comentari multilínia
+Les funcions poden tenir paràmetres i (multiples!) valors de retorn.
+Aquí `x`, `y` són els argumens i `sum` i `prod` són els valors retornats.
+Fixa't que `x` i `sum` reben el tipus `int`.
+*/
+func learnMultiple(x, y int) (sum, prod int) {
+ return x + y, x * y // Retorna dos valors.
+}
+
+// Alguns tipus incorporats i literals.
+func aprenTipus() {
+ // Normalment la declaració curta et dóna el que vols.
+ str := "Learn Go!" // tipus string
+
+ s2 := `Un tipus cadena "normal" pot tenir
+salts de línia.` // El mateix tipus
+
+ // literals Non-ASCII literal. El tipus de Go és UTF-8.
+ g := 'Σ' // El tipus rune, és un àlies de int32 conté un caràcter unicode.
+
+ f := 3.14195 // float64, un número de 64 bits amb coma flotant IEEE-754.
+ c := 3 + 4i // complex128, representat internament amb dos float64.
+
+ // Sintaxi amb var i inicialitzadors.
+ var u uint = 7 // Sense signe, però depèn de la mida com els int.
+ var pi float32 = 22. / 7
+
+ // Conversió de tipus amb declaració curta.
+ n := byte('\n') // byte és un àlies de uint8.
+
+ // Les taules tenen mida fixa en temps de compilació.
+ var a4 [4]int // Taula de 4 enters inicialitzats a zero.
+ a3 := [...]int{3, 1, 5} // Taula inicialitzada amb tres elements
+ // amb els valors 3, 1, i 5.
+
+ // Els "Slices" tenen mida dinàmica. Tant les taules com els "slices"
+ // tenen avantatges però és més habitual que es facin servir slices.
+ s3 := []int{4, 5, 9} // Compara amb a3. Aquí no hi ha els tres punts
+ s4 := make([]int, 4) // Crea un slice de 4 enters inicialitzats a zero.
+ var d2 [][]float64 // Només es declara però no hi ha valors.
+ bs := []byte("a slice") // Sintaxi de conversió de tipus.
+
+ // Com que són dinàmics es poden afegir valors nous als slices.
+ // Per afegir-hi elements es fa servir el mètode append().
+ // El primer argument és l'slice en el que s'afegeix.
+ // Sovint ell mateix com aquí sota.
+ s := []int{1, 2, 3} // Un slice amb tres elements.
+ s = append(s, 4, 5, 6) // Ara s tindrà tres elements més
+ fmt.Println(s) // El resultat serà [1 2 3 4 5 6]
+
+ // Per afegir un slice dins d'un altre en comptes de valors atòmics
+ // S'hi pot passar una referència a l'altre slice o un literal acabat
+ // amb tres punts, que vol dir que s'ha de desempaquetar els elements
+ // i afegir-los a "s"
+ s = append(s, []int{7, 8, 9}...) // El segon argument és un slice
+ fmt.Println(s) // El resultat ara és [1 2 3 4 5 6 7 8 9]
+
+ p, q := aprenMemoria() // Declara p i q com a punters de int.
+ fmt.Println(*p, *q) // * segueix el punter fins a trobar els valors
+
+ // Els "Mapes" són taules dinàmiques associatives com els hash o els
+ // diccionaris d'altres llenguatges.
+ m := map[string]int{"tres": 3, "quatre": 4}
+ m["un"] = 1
+
+ // En Go les variables que no es fan servir generen un error.
+ // El subratllat permet fer servir una variable i descartar-ne el valor.
+ _, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs
+ // És útil per descartar algun dels valors retornats per una funció
+ // Per exemple, es pot ignorar l'error retornat per os.Create amb la idea
+ // de que sempre es crearà.
+ file, _ := os.Create("output.txt")
+ fmt.Fprint(file, "Així es pot escriure en un fitxer")
+ file.Close()
+
+ // La sortida compta com a ús d'una variable.
+ fmt.Println(s, c, a4, s3, d2, m)
+
+ aprenControlDeFluxe() // Tornem.
+}
+
+// A diferència d'altres llenguatges les funcions poden retornar valors amb
+// nom. Assignant un nom al valor retornat en la declaració de la funció
+// permet retornar valors des de diferents llocs del programa a més de posar
+// el return sense valors
+func aprenRetornAmbNoms(x, y int) (z int) {
+ z = x * y
+ return // el retorn de z és implícit perquè ja té valor
+}
+
+// Go té un recollidor de basura.
+// Té punters però no té aritmetica de punters
+// Es poden cometre errors amb un punter a nil però no incrementant-lo.
+func aprenMemoria() (p, q *int) {
+ // Els valors retornats p i q són punters a un enter.
+ p = new(int) // Funció per reservar memòria
+ // A la memòria ja hi ha un 0 per defecte, no és nil.
+ s := make([]int, 20) // Reserva un bloc de memòria de 20 enters.
+ s[3] = 7 // Assigna un valor a un d'ells.
+ r := -2 // Declare una altra variable local.
+ return &s[3], &r // & agafa l'adreça d'un objecte.
+}
+
+func expensiveComputation() float64 {
+ return m.Exp(10)
+}
+
+func aprenControlDeFluxe() {
+ // Els "If" necessiten corxets però no parèntesis.
+ if true {
+ fmt.Println("ja ho hem vist")
+ }
+ // El format del codi està estandaritzat amb la comanda "go fmt."
+ if false {
+ // Pout.
+ } else {
+ // Gloat.
+ }
+ // Si cal encadenar ifs és millor fer servir switch.
+ x := 42.0
+ switch x {
+ case 0:
+ case 1:
+ case 42:
+ // Els case no "passen a través" no cal "break" per separar-los.
+ /*
+ Per fer-ho hi ha una comanda `fallthrough`, mireu:
+ https://github.com/golang/go/wiki/Switch#fall-through
+ */
+ case 43:
+ // No hi arriba.
+ default:
+ // La opció "default" és opcional
+ }
+ // El 'for' tampoc necessita parèntesis, com el 'if'.
+ // Les variables dins d'un bloc if o for són local del bloc.
+ for x := 0; x < 3; x++ { // ++ is a statement.
+ fmt.Println("iteració", x)
+ }
+ // x == 42.
+
+ // L'única forma de fer bucles en Go és el 'for' però té moltes variants.
+ for { // bucle infinit.
+ break // És una broma!.
+ continue // No hi arriba mai.
+ }
+
+ // Es fa servir "range" per iterar a una taula, un slice, un mapa
+ // o un canal.
+ // range torna un valor (channel) o dos (array, slice, string o map).
+ for key, value := range map[string]int{"un": 1, "dos": 2, "tres": 3} {
+ // Per cada parell del mapa imprimeix la clau i el valor.
+ fmt.Printf("clau=%s, valor=%d\n", key, value)
+ }
+ // Si només cal el valor es pot fer servir _
+ for _, name := range []string{"Robert", "Bill", "Josep"} {
+ fmt.Printf("Hola, %s\n", name)
+ }
+
+ // Es pot usar := per declarar i assignar valors i després
+ // comprovar-lo y > x.
+ if y := expensiveComputation(); y > x {
+ x = y
+ }
+ // Les funcions literals són closures
+ xBig := func() bool {
+ return x > 10000 // Referencia a x declarada sobre el switch.
+ }
+ x = 99999
+ fmt.Println("xBig:", xBig()) // cert
+ x = 1.3e3 // x val 1300
+ fmt.Println("xBig:", xBig()) // fals.
+
+ // A més les funcions poden ser definides i cridades com a arguments per
+ // una funció sempre que:
+ // a) La funció es cridi inmediatament (),
+ // b) El tipus del resultat sigui del tipus esperat de l'argument.
+ fmt.Println("Suma i duplica dos números: ",
+ func(a, b int) int {
+ return (a + b) * 2
+ }(10, 2)) // Es crida amb els arguments 10 i 2
+ // => Suma i duplica dos números: 24
+
+ // Quan el necessitis t'agradarà que hi sigui
+ goto love
+love:
+
+ aprenFabricaDeFuncions() // func que retorna func és divertit(3)(3)
+ aprenDefer() // Revisió ràpida d'una paraula clau.
+ aprendreInterficies() // Bon material properament!
+}
+
+func aprenFabricaDeFuncions() {
+ // Les dues seguents són equivalents, però la segona és més pràctica
+ fmt.Println(sentenceFactory("dia")("Un bonic", "d'estiu!"))
+
+ d := sentenceFactory("dia")
+ fmt.Println(d("Un bonic", "d'estiu!"))
+ fmt.Println(d("Un tranquil", "de primavera!"))
+}
+
+// Els decoradors són habituals en altres llenguatges.
+// Es pot fer el mateix en Go amb funcions literals que accepten arguments.
+func sentenceFactory(mystring string) func(before, after string) string {
+ return func(before, after string) string {
+ return fmt.Sprintf("%s %s %s", before, mystring, after) // nou string
+ }
+}
+
+func aprenDefer() (ok bool) {
+ // Les comandes marcades amb defer s'executen després de que la funció
+ // hagi acabat.
+ defer fmt.Println("Les comandes defer s'executen en ordre invers (LIFO).")
+ defer fmt.Println("\nAquesta és la primera línia que s'imprimeix")
+ // Defer es fa servir gairebé sempre per tancar un fitxer, en el moment
+ // en que acaba el mètode.
+ return true
+}
+
+// Defineix Stringer com un tipus interfície amb el mètode String().
+type Stringer interface {
+ String() string
+}
+
+// Defineix una estrutura que conté un parell d'enters, x i y.
+type parell struct {
+ x, y int
+}
+
+// Defineix un mètode de l'estructura parell. Ara parell implementa Stringer.
+func (p parell) String() string { // p és anomenat el "receptor"
+ // Sprintf és una funció del paquet fmt.
+ // Fa referència als camps de p.
+ return fmt.Sprintf("(%d, %d)", p.x, p.y)
+}
+
+func aprendreInterficies() {
+ // La sintaxi de claus es pot fer servir per inicialitzar un "struct".
+ // Gràcies a := defineix i inicialitza p com un struct 'parell'.
+ p := parell{3, 4}
+ fmt.Println(p.String()) // Es crida al mètode de p.
+ var i Stringer // Declara i de tipus Stringer.
+ i = p // parell implementa Stringer per tant és vàlid.
+ // Es pot cridar el mètode String() igual que abans.
+ fmt.Println(i.String())
+
+ // Les funcions de fmt criden a String() per aconseguir una representació
+ // imprimible d'un objecte.
+ fmt.Println(p) // Treu el mateix d'abans. Println crida el mètode String.
+ fmt.Println(i) // Idèntic resultat
+
+ aprendreParamentesVariables("Aquí", "estem", "aprenent!")
+}
+
+// Les funcions poden tenir paràmetres variables.
+func aprendreParamentesVariables(myStrings ...interface{}) {
+ // Itera per cada un dels valors dels paràmetres
+ // Ignorant l'índex de la seva posició
+ for _, param := range myStrings {
+ fmt.Println("paràmetre:", param)
+ }
+
+ // Passa el valor de múltipes variables com a paràmetre.
+ fmt.Println("parametres:", fmt.Sprintln(myStrings...))
+
+ aprenControlErrors()
+}
+
+func aprenControlErrors() {
+ // ", ok" Es fa servir per saber si hi és o no.
+ m := map[int]string{3: "tres", 4: "quatre"}
+ if x, ok := m[1]; !ok { // ok serà fals perquè 1 no està en el mapa.
+ fmt.Println("no hi és")
+ } else {
+ fmt.Print(x) // x seria el valor, si no estés en el mapa.
+ }
+ // Un valor d'error donarà més informació sobre l'error.
+ if _, err := strconv.Atoi("no-int"); err != nil { // _ descarta el valor
+ // imprimeix 'strconv.ParseInt: intenta convertir "non-int":
+ // syntaxi invalida'
+ fmt.Println(err)
+ }
+ // Es tornarà a les interfícies més tard. Mentrestant,
+ aprenConcurrencia()
+}
+
+// c és un canal (channel), una forma segura de comunicar objectes.
+func inc(i int, c chan int) {
+ c <- i + 1 // <- és l'operador "envia" quan un canal està a l'esquerra.
+}
+
+// Es pot fer servir inc per incrementar un número de forma concurrent.
+func aprenConcurrencia() {
+ // La funció make es pot fer servir per crear slices, mapes i canals.
+ c := make(chan int)
+ // S'inicien tres goroutines.
+ // Els números s'incrementaran de forma concurrent, En paral·lel
+ // si la màquina on s'executa pot fer-ho i està correctament configurada.
+ // Tots tres envien al mateix canal.
+ go inc(0, c) // go és la comanda que inicia una nova goroutine.
+ go inc(10, c)
+ go inc(-805, c)
+ // Llegeix tres resultats del canal i els imprimeix.
+ // No es pot saber en quin ordre arribaran els resultats!
+ fmt.Println(<-c, <-c, <-c) // Canal a la dreta <- és l'operador "rebre"
+
+ cs := make(chan string) // Un altre canal que processa strings.
+ ccs := make(chan chan string) // Un canal de canals string.
+ go func() { c <- 84 }() // Inicia una goroutine i li envia un valor.
+ go func() { cs <- "paraula" }() // El mateix però amb cs.
+ // Select té una sintaxi semblant a switch però amb canals.
+ // Selecciona un cas aleatòriament dels que poden comunicar-se.
+ select {
+ case i := <-c: // El valor rebit pot ser assignat a una variable,
+ fmt.Printf("és un %T", i)
+ case <-cs: // O es pot descartar
+ fmt.Println("és un string")
+ case <-ccs: // Canal buit, no preparat per la comunicació.
+ fmt.Println("no ha passat.")
+ }
+ // Quan arribi aquí s'haurà agafat un valor de c o bé de cs. Una de les
+ // goroutines iniciades haurà acabat i l'altra romandrà bloquejada.
+
+ aprenProgramacioWeb() // Go ho fa. Tu vols fer-ho.
+}
+
+// Una funció del paquet http inicia un servidor web.
+func aprenProgramacioWeb() {
+
+ // El primer paràmetre de ListenAndServe és l'adreça on escoltar
+ // i el segon és una interfície http.Handler.
+ go func() {
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // no s'han d'ignorar els errors
+ }()
+
+ requestServer()
+}
+
+// Es converteix "parell" en un http.Handler només implementant el
+// mètode ServeHTTP.
+func (p parell) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ // Serveix dades en el http.ResponseWriter.
+ w.Write([]byte("Has après Go en Y minuts!"))
+}
+
+func requestServer() {
+ resp, err := http.Get("http://localhost:8080")
+ fmt.Println(err)
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ fmt.Printf("\nEl servidor diu: `%s`", string(body))
+}
+```
+
+## Més informació
+
+L'arrel de tot en Go és la web oficial [official Go web site]
+(http://golang.org/). Allà es pot seguir el tutorial, jugar interactivament
+i llegir molt més del que hem vist aquí.En el "tour",
+[the docs](https://golang.org/doc/) conté informació sobre com escriure codi
+net i efectiu en Go, comandes per empaquetar i generar documentació, i
+història de les versions.
+
+És altament recomanable llegir La definició del llenguatge. És fàcil de llegir
+i sorprenentment curta (com la definició del llenguatge en aquests dies).
+
+Es pot jugar amb codi a [Go playground](https://play.golang.org/p/tnWMjr16Mm).
+Prova de fer canvis en el codi i executar-lo des del navegador! Es pot fer
+servir [https://play.golang.org](https://play.golang.org) com a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) per provar coses i codi
+en el navegador sense haver d'instal·lar Go.
+
+En la llista de lectures pels estudiants de Go hi ha
+[el codi font de la llibreria estàndard](http://golang.org/src/pkg/).
+Ampliament comentada, que demostra el fàcil que és de llegir i entendre els
+programes en Go, l'estil de programació, i les formes de treballar-hi. O es
+pot clicar en un nom de funció en [la documentació](http://golang.org/pkg/)
+i veure'n el codi!
+
+Un altre gran recurs per aprendre Go és
+[Go by example](https://gobyexample.com/).
+
+Go Mobile afegeix suport per plataformes mòbils (Android i iOS). Es poden
+escriure aplicacions mòbils o escriure llibreries de paquets de Go, que es
+poden cridar des de Java (android) i Objective-C (iOS).
+Comproveu la [Go Mobile page](https://github.com/golang/go/wiki/Mobile) per
+més informació.
diff --git a/ca-es/groovy-ca.html.markdown b/ca-es/groovy-ca.html.markdown
new file mode 100644
index 00000000..f0a9adbe
--- /dev/null
+++ b/ca-es/groovy-ca.html.markdown
@@ -0,0 +1,439 @@
+---
+name: Groovy
+category: language
+language: Groovy
+lang: ca-es
+filename: learngroovy-ca.groovy
+contributors:
+ - ["Roberto Pérez Alcolea", "http://github.com/rpalcolea"]
+translations:
+ - ["Xavier Sala Pujolar", "http://github.com/utrescu"]
+---
+
+Groovy - Un llenguatge dinàmic per la plataforma Java [Llegir-ne més.](http://www.groovy-lang.org/)
+
+```groovy
+
+/*
+ Posa'l en marxa tu mateix:
+
+ 1) Instal.la SDKMAN - http://sdkman.io/
+ 2) Instal.la Groovy: sdk install groovy
+ 3) Inicia la consola groovy escrivint: groovyConsole
+
+*/
+
+// Els comentaris d'una sola línia comencen amb dues barres inverses
+/*
+Els comentaris multilínia són com aquest.
+*/
+
+// Hola món
+println "Hola món!"
+
+/*
+ Variables:
+
+ Es poden assignar valors a les variables per fer-los servir més tard
+*/
+
+def x = 1
+println x
+
+x = new java.util.Date()
+println x
+
+x = -3.1499392
+println x
+
+x = false
+println x
+
+x = "Groovy!"
+println x
+
+/*
+ Col.leccions i mapes
+*/
+
+// Crear una llista buida
+def technologies = []
+
+/*** Afegir elements a la llista ***/
+
+// Com en Java
+technologies.add("Grails")
+
+// El shift a l'esquerra afegeix i retorna la llista
+technologies << "Groovy"
+
+// Afegir múltiples elements
+technologies.addAll(["Gradle","Griffon"])
+
+/*** Eliminar elements de la llista ***/
+
+// Com en Java
+technologies.remove("Griffon")
+
+// La resta també funciona
+technologies = technologies - 'Grails'
+
+/*** Iterar per les llistes ***/
+
+// Iterar per tots els elements de la llista
+technologies.each { println "Technology: $it"}
+technologies.eachWithIndex { it, i -> println "$i: $it"}
+
+/*** Comprovar el contingut de la llista ***/
+
+//Comprovar si la llista conté un o més elements (resultat boolea)
+contained = technologies.contains( 'Groovy' )
+
+// O
+contained = 'Groovy' in technologies
+
+// Comprovar diversos elements
+technologies.containsAll(['Groovy','Grails'])
+
+/*** Ordenar llistes ***/
+
+// Ordenar una llista (canvia la original)
+technologies.sort()
+
+// Per ordenar sense canviar la original es pot fer:
+sortedTechnologies = technologies.sort( false )
+
+/*** Manipular llistes ***/
+
+//Canvia tots els elements de la llista
+Collections.replaceAll(technologies, 'Gradle', 'gradle')
+
+// Desordena la llista
+Collections.shuffle(technologies, new Random())
+
+// Buida la llista
+technologies.clear()
+
+// Crear un mapa buit
+def devMap = [:]
+
+// Afegir valors al mapa
+devMap = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
+devMap.put('lastName','Perez')
+
+// Iterar per tots els elements del mapa
+devMap.each { println "$it.key: $it.value" }
+devMap.eachWithIndex { it, i -> println "$i: $it"}
+
+// Comprovar si la clau hi és
+assert devMap.containsKey('name')
+
+// Comprova si el mapa conté un valor concret
+assert devMap.containsValue('Roberto')
+
+// Obtenir les claus del mapa
+println devMap.keySet()
+
+// Obtenir els valors del mapa
+println devMap.values()
+
+/*
+ Groovy Beans
+
+ Els GroovyBeans són JavaBeans però amb una sintaxi molt més senzilla
+
+ Quan Groovy es compila a bytecode es fan servir les regles següents.
+
+ * Si el nom és declarat amb un modificador (public, private o protected)
+ es genera el camp
+
+ * Un nom declarat sense modificadors genera un camp privat amb un getter
+ i un setter públics (per exemple una propietat)
+
+ * Si la propietat és declarada final el camp privat es crea i no es
+ genera cap setter.
+
+ * Es pot declarar una propietat i també declarar un getter i un setter.
+
+ * Es pot declarar una propietat i un camp amb el mateix nom, la propietat
+ farà servir el camp.
+
+ * Si es vol una propietat private o protected s'ha de definir el getter i
+ el setter que s'han de declarar private o protected.
+
+ * Si s'accedeix a una propietat de la classe que està definida en temps
+ de compilació amb un this implícit o explícit (per exemple this.foo, o
+ bé només foo), Groovy accedirà al camp directament en comptes de fer-ho
+ a través del getter i el setter.
+
+ * Si s'accedeix a una propietat que no existeix tant implícita com
+ explicitament, llavors Groovy accedirà a la propietat a través de la
+ meta classe, que pot fer que falli en temps d'execució.
+
+*/
+
+class Foo {
+ // Propietat només de lectura
+ final String name = "Roberto"
+
+ // Propietat de només lectura amb getter públic i un setter protected
+ String language
+ protected void setLanguage(String language) { this.language = language }
+
+ // Propietat amb el tipus definit dinàmicament
+ def lastName
+}
+
+/*
+ Bucles i estructres de control
+*/
+
+//Groovy té el format tradicional de if -else
+def x = 3
+
+if(x==1) {
+ println "One"
+} else if(x==2) {
+ println "Two"
+} else {
+ println "X greater than Two"
+}
+
+// Groovy també té l'operador ternari
+def y = 10
+def x = (y > 1) ? "worked" : "failed"
+assert x == "worked"
+
+//I també té 'l'Operador Elvis'!
+//En comptes de fer servir l'operador ternari:
+displayName = user.name ? user.name : 'Anonymous'
+
+// Es pot escriure d'aquesta forma:
+displayName = user.name ?: 'Anonymous'
+
+//Bucle for
+//Itera en un rang
+def x = 0
+for (i in 0 .. 30) {
+ x += i
+}
+
+//Itera per una llista
+x = 0
+for( i in [5,3,2,1] ) {
+ x += i
+}
+
+//Itera per un array
+array = (0..20).toArray()
+x = 0
+for (i in array) {
+ x += i
+}
+
+//Itera per un mapa
+def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
+x = ""
+for ( e in map ) {
+ x += e.value
+ x += " "
+}
+assert x.equals("Roberto Grails Groovy ")
+
+/*
+ Operadors
+
+ Hi ha una llista d'operadors que poden ser sobreescrits en Groovy:
+ http://www.groovy-lang.org/operators.html#Operator-Overloading
+
+ Operadors útils de Groovy
+*/
+//Spread operator: Invoca una acció en tots els ítems d'un grup d'objectes.
+def technologies = ['Groovy','Grails','Gradle']
+technologies*.toUpperCase() // = a technologies.collect { it?.toUpperCase() }
+
+//Safe navigation operator: fet servir per evitar el NullPointerException.
+def user = User.get(1)
+def username = user?.username
+
+
+/*
+ Closures
+ Un Closure és com un "bloc de codi" o un punter a un mètode. És un troç de
+ codi que està definit i que s podrà executar més tard.
+
+ Més informació a: http://www.groovy-lang.org/closures.html
+*/
+//Exemple:
+def clos = { println "Hola món!" }
+
+println "Executant el Closure:"
+clos()
+
+// Passar paràmetres a un Closure
+def sum = { a, b -> println a+b }
+sum(2,4)
+
+//Els Closures poden fer referència a variables que no formen part de la
+// llista dels seus paràmetres.
+def x = 5
+def multiplyBy = { num -> num * x }
+println multiplyBy(10)
+
+// Si es té un Closure que agafa un element com a argument, se'n pot ignorar
+// la definició
+def clos = { print it }
+clos( "hi" )
+
+/*
+ Groovy pot recordar els resultats dels Closures [1][2][3]
+*/
+def cl = {a, b ->
+ sleep(3000) // simula un procés llarg
+ a + b
+}
+
+mem = cl.memoize()
+
+def callClosure(a, b) {
+ def start = System.currentTimeMillis()
+ mem(a, b)
+ println "(a = $a, b = $b) - en ${System.currentTimeMillis() - start} ms"
+}
+
+callClosure(1, 2)
+callClosure(1, 2)
+callClosure(2, 3)
+callClosure(2, 3)
+callClosure(3, 4)
+callClosure(3, 4)
+callClosure(1, 2)
+callClosure(2, 3)
+callClosure(3, 4)
+
+/*
+ Expando
+
+ La classe Expando és un bean dinàmic al que se li poden afegir propietats i
+ closures com a mètodes d'una instància d'aquesta classe.
+
+http://mrhaki.blogspot.mx/2009/10/groovy-goodness-expando-as-dynamic-bean.html
+*/
+ def user = new Expando(name:"Roberto")
+ assert 'Roberto' == user.name
+
+ user.lastName = 'Pérez'
+ assert 'Pérez' == user.lastName
+
+ user.showInfo = { out ->
+ out << "Name: $name"
+ out << ", Last name: $lastName"
+ }
+
+ def sw = new StringWriter()
+ println user.showInfo(sw)
+
+
+/*
+ Metaprogrammació (MOP)
+*/
+
+// Fent servir ExpandoMetaClass per afegir comportament
+String.metaClass.testAdd = {
+ println "he afegit això"
+}
+
+String x = "test"
+x?.testAdd()
+
+//Intercepting method calls
+class Test implements GroovyInterceptable {
+ def sum(Integer x, Integer y) { x + y }
+
+ def invokeMethod(String name, args) {
+ System.out.println "Invoca el mètode $name amb arguments: $args"
+ }
+}
+
+def test = new Test()
+test?.sum(2,3)
+test?.multiply(2,3)
+
+//Groovy supporta propertyMissing per gestionar la resolució de propietats
+class Foo {
+ def propertyMissing(String name) { name }
+}
+def f = new Foo()
+
+assertEquals "boo", f.boo
+
+/*
+ TypeChecked i CompileStatic
+ Groovy, by nature, és i sempre serà un llenguatge dinàmic però també té
+ comprovació de tipus i definicions estàtiques
+
+ More info: http://www.infoq.com/articles/new-groovy-20
+*/
+//TypeChecked
+import groovy.transform.TypeChecked
+
+void testMethod() {}
+
+@TypeChecked
+void test() {
+ testMeethod()
+
+ def name = "Roberto"
+
+ println naameee
+
+}
+
+//Un altre exemple:
+import groovy.transform.TypeChecked
+
+@TypeChecked
+Integer test() {
+ Integer num = "1"
+
+ Integer[] numbers = [1,2,3,4]
+
+ Date date = numbers[1]
+
+ return "Test"
+
+}
+
+//exemple de CompileStatic
+import groovy.transform.CompileStatic
+
+@CompileStatic
+int sum(int x, int y) {
+ x + y
+}
+
+assert sum(2,5) == 7
+
+
+```
+
+## Per aprendre'n més
+
+[documentació de Groovy](http://www.groovy-lang.org/documentation.html)
+
+[Cònsola de Groovy](http://groovyconsole.appspot.com/)
+
+Uneix-te a un [grup d'usuaris Groovy]
+(http://www.groovy-lang.org/usergroups.html)
+
+## Llibres
+
+* [Groovy Goodness] (https://leanpub.com/groovy-goodness-notebook)
+
+* [Groovy in Action] (http://manning.com/koenig2/)
+
+* [Programming Groovy 2: Dynamic Productivity for the Java Developer] (http://shop.oreilly.com/product/9781937785307.do)
+
+[1] http://roshandawrani.wordpress.com/2010/10/18/groovy-new-feature-closures-can-now-memorize-their-results/
+[2] http://www.solutionsiq.com/resources/agileiq-blog/bid/72880/Programming-with-Groovy-Trampoline-and-Memoize
+[3] http://mrhaki.blogspot.mx/2011/05/groovy-goodness-cache-closure-results.html
diff --git a/ca-es/html-ca.html.markdown b/ca-es/html-ca.html.markdown
new file mode 100644
index 00000000..351eb722
--- /dev/null
+++ b/ca-es/html-ca.html.markdown
@@ -0,0 +1,176 @@
+---
+language: html
+filename: html-ca.md
+contributors:
+ - ["Christophe THOMAS", "https://github.com/WinChris"]
+translators:
+ - ["Marc Auledas", "https://github.com/Auledas"]
+lang: ca-es
+---
+
+HTML significa llenguatge de marques d'hipertext (HyperText Markup Language).
+
+És un llenguatge que permet escriure pàgines pel sistema web (World Wide Web).
+És un llenguatge de marques que permet escriure pàgines web fent servir codi per indicar
+com s'ha de visualitzar el text i les dades. De fet, els fitxers html són simples
+fitxers de text.
+
+Què són les 'marques'? Són un mètode d'organitzar les dades d'una pàgina mitjançant
+etiquetes d'obertura i tancament. Aquestes marques serveixen per donar
+significat al text que hi ha entre les etiquetes. Com d'altres llenguatges de marques,
+hi ha moltes versions de l'HTML. Aquí es desenvoluparà l'HTML5.
+
+**NOTA:** Pots provar les diferents etiquetes i elements a mesura que progressis a través
+del tutorial a pàgines web com [codepen](http://codepen.io/pen/). D'aquesta manera podràs
+veure'n els efectes, entendre com funcionen i familiaritzar-te amb el llenguatge. Aquest
+article tracta principalment la sintaxi de l'HTML i alguns consells útils.
+
+
+```html
+<!-- Els comentaris s'escriuen com aquesta línia! -->
+
+<!--
+ Els comentaris
+ poden
+ ocupar
+ múltiples
+ línies!
+-->
+
+<!-- #################### Les etiquetes #################### -->
+
+<!-- Aquí hi ha un exemple de fitxer HTML que analitzarem. -->
+
+
+<!doctype html>
+ <html>
+ <head>
+ <title>El meu lloc web</title>
+ </head>
+ <body>
+ <h1>Hola, món!</h1>
+ <a href="http://codepen.io/anon/pen/xwjLbZ">
+ Fes una ullada a com es veu això.
+ </a>
+ <p>Això és un paràgraf.</p>
+ <p>Això és un altre paràgraf.</p>
+ <ul>
+ <li>Això és un element d'una llista no enumerada (llista de punts).</li>
+ <li>Això és un altre element.</li>
+ <li>I aquest és l'últim element de la llista.</li>
+ </ul>
+ </body>
+ </html>
+
+<!--
+ Un fitxer HTML sempre comença indicant al navegador que la pàgina és HTML.
+-->
+<!doctype html>
+
+<!-- Després d'això, es comença obrint l'etiqueta <html>. -->
+<html>
+
+<!-- Aquesta etiqueta s'ha de tancar al final del fitxer amb </html>. -->
+</html>
+
+<!-- No s'ha d'escriure res més després d'aquesta etiqueta final. -->
+
+<!-- Entremig (entre les etiquetes d'obertura i tancament <html></html>), trobem: -->
+
+<!-- Una capçalera definida per <head> (que s'ha de tancar emprant </head>). -->
+<!--
+ La capçalera conté descripcions i informació addicional que no es mostra,
+ això són les metadades.
+-->
+
+<head>
+ <!--
+ L'etiqueta <title> indica al navegador el títol que s'ha de visualitzar
+ a la finestra del buscador, a la barra del títol, i al nom de la pestanya.
+ -->
+ <title>El meu lloc web</title>
+</head>
+
+<!-- Després de la secció <head>, trobem l'etiqueta <body> -->
+<!-- Fins a aquest punt, res del que s'ha fet apareixerà a la finestra del navegador. -->
+<!-- Hem d'emplenar el cos amb el contingut per visualitzar. -->
+
+<body>
+ <!-- L'etiqueta h1 crea el títol. -->
+ <h1>Hola, món!</h1>
+ <!--
+ També es poden fer subtítols per <h1>, que van des del més important <h2>
+ fins al més precís <h6>.
+ -->
+
+ <!-- També es poden crear enllaços fent servir l'atribut href="" -->
+ <a href="http://codepen.io/anon/pen/xwjLbZ">
+ Fes una ullada a com es veu això.
+ </a>
+
+ <!-- L'etiqueta <p> permet incloure text a una pàgina HTML. -->
+ <p>Això és un paràgraf.</p>
+ <p>Això és un altre paràgraf.</p>
+
+ <!-- L'etiqueta <ul> crea una llista de punts. -->
+ <!--
+ Per tenir una llista enumerada s'hauria de fer servir <ol>, en comptes d'<ul>.
+ El primer element seria 1, el segon element 2, etc.
+ -->
+ <ul>
+ <li>Això és un element d'una llista no enumerada (llista de punts).</li>
+ <li>Això és un altre element.</li>
+ <li>I aquest és l'últim element de la llista.</li>
+ </ul>
+</body>
+
+<!-- I això és tot, crear un fitxer HTML pot ser molt simple. -->
+
+<!-- Però és possible afegir molts altres tipus d'etiquetes HTML addicionals. -->
+
+<!-- L'etiqueta <img /> es fa servir per afegir imatges. -->
+<!--
+ L'origen de la imatge s'indica fent servir l'atribut src=""
+ L'origen pot ser una adreça URL o la ruta a un arxiu del teu ordinador.
+-->
+<img src="http://i.imgur.com/XWG0O.gif"/>
+
+<!-- També es poden crear taules. -->
+
+<!-- L'etiqueta <table> obre la taula. -->
+<table>
+
+ <!-- <tr> permet crear files. -->
+ <tr>
+
+ <!-- <th> permet posar títol a la columna d'una taula. -->
+ <th>Primera capçalera</th>
+ <th>Segona capçalera</th>
+ </tr>
+
+ <tr>
+
+ <!-- <td> permet crear cel·les d'una taula. -->
+ <td>Primera fila, primera columna</td>
+ <td>Primera fila, segona columna</td>
+ </tr>
+
+ <tr>
+ <td>Segona fila, primera columna</td>
+ <td>Segona fila, segona columna</td>
+ </tr>
+</table>
+
+```
+
+## Ús
+
+Els arxius HTML acaben amb les extensions `.html` o `.htm`. El tipus MIME és `text/html`.
+
+**HTML NO és un llenguatge de programació**
+
+## Per aprendre'n més
+
+* [Viquipèdia](https://ca.wikipedia.org/wiki/Hyper_Text_Markup_Language)
+* [Tutorial HTML](https://developer.mozilla.org/ca/docs/Web/HTML)
+* [W3School](http://www.w3schools.com/html/html_intro.asp)
diff --git a/ca-es/kotlin-ca.html.markdown b/ca-es/kotlin-ca.html.markdown
new file mode 100644
index 00000000..cd05a808
--- /dev/null
+++ b/ca-es/kotlin-ca.html.markdown
@@ -0,0 +1,389 @@
+---
+language: kotlin
+contributors:
+ - ["S Webber", "https://github.com/s-webber"]
+translators:
+ - ["Xavier Sala", "https://github.com/utrescu"]
+lang: ca-es
+filename: LearnKotlin-ca.kt
+---
+
+Kotlin és un llenguatge estàtic tipat per la JVM, Android i el navegador.
+És interoperable al 100% amb Java.
+[Llegir-ne més aquí.](https://kotlinlang.org/)
+
+```kotlin
+// Els comentaris d'una línia comencen amb //
+/*
+Els comentaris multilínia són com aquest
+*/
+
+// La paraula clau "package" funciona de la mateixa forma que en Java
+
+package com.learnxinyminutes.kotlin
+
+/*
+El punt d'entrada dels programes en Kotlin és una funció anomenada "main".
+La funció rep un array que té els arguments fets servir al executar-lo.
+*/
+fun main(args: Array<String>) {
+ /*
+ La declaració de variables es pot fer tant amb "var" com amb "val".
+ A les declarades amb "val" no se'ls hi pot canviar el valor
+ en canvi a les declarades amb "var" si.
+ */
+ val fooVal = 10 // no es podrà canviar el valor de fooVal
+ var fooVar = 10
+ fooVar = 20 // fooVar si que es pot canviar
+
+ /*
+ Gairebé sempre, Kotlin pot determinar el tipus d'una variable,
+ de manera que no caldrà definir-lo cada vegada.
+ Però es pot definir el tipus d'una variable explícitament d'aquesta forma:
+ */
+ val foo: Int = 7
+
+ /*
+ Els "strings" es poden representar igual que com es fa en Java.
+ Es poden escapar caràcters amb la barra inversa.
+ */
+ val fooString = "Aquí està la meva cadena!"
+ val barString = "Imprimir en dues línies?\nCap problema!"
+ val bazString = "Es poden posar tabuladors?\tI tant!"
+ println(fooString)
+ println(barString)
+ println(bazString)
+
+ /*
+ Es poden definir strings literals envoltant-los amb les triples cometes
+ (""").
+ Dins hi poden haver tant salts de línies com d'altres caràcters.
+ */
+ val fooRawString = """
+fun helloWorld(val name : String) {
+ println("Hola món!")
+}
+"""
+ println(fooRawString)
+
+ /*
+ Els strings poden contenir expressions de plantilla.
+ Les expressions de plantilla comencen amb el símbol ($).
+ */
+ val fooTemplateString = "$fooString té ${fooString.length} caràcters"
+ println(fooTemplateString)
+
+ /*
+ Perquè una variable pugui contenir null ha de ser declarada específicament
+ com a nullable afengint-li ? al seu tipus.
+ Es pot accedir a una variable nulable fent servir l'operador ?.
+ L'operador ?: permet especificar un valor alternatiu en cas de que la
+ variable sigui 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
+
+ /*
+ Les funcions es declaren amb la paraula "fun".
+ Els arguments s'especifiquen entre corxets després del nom de la funció.
+ Els arguments poden tenir un valor per defecte.
+ El retorn de les funcions, si cal, es posa després de l'argument.
+ */
+ fun hello(name: String = "món"): String {
+ return "Hola, $name!"
+ }
+ println(hello("foo")) // => Hola, foo!
+ println(hello(name = "bar")) // => Hola, bar!
+ println(hello()) // => Hola, món!
+
+ /*
+ Un dels paràmetres d'una funció pot ser marcat amb la paraula clau
+ "vararg" que permet que una funció accepti un número variable
+ d'arguments.
+ */
+ fun varargExample(vararg names: Int) {
+ println("S'han rebut ${names.size} arguments")
+ }
+ varargExample() // => S'han rebut 0 elements
+ varargExample(1) // => S'ha rebut 1 element
+ varargExample(1, 2, 3) // => S'han rebut 3 elements
+
+ /*
+ Quan una funció consisteix en una sola expressió no calen els corxets
+ El cos de la funció es posa rere el símbol =.
+ */
+ fun odd(x: Int): Boolean = x % 2 == 1
+ println(odd(6)) // => false
+ println(odd(7)) // => true
+
+ // Si el tipus retornat es pot determinar no cal especificar-lo.
+ fun even(x: Int) = x % 2 == 0
+ println(even(6)) // => true
+ println(even(7)) // => false
+
+ // Les funcions poden tenir altres funcions com arguments i
+ // fins i tot retornar-ne.
+ fun not(f: (Int) -> Boolean): (Int) -> Boolean {
+ return {n -> !f.invoke(n)}
+ }
+ // Les funcions amb nom es poden especificar quan fan d'arguments amb ::
+ val notOdd = not(::odd)
+ val notEven = not(::even)
+ // Les expressions lambda es poden posar com arguments.
+ val notZero = not {n -> n == 0}
+ /*
+ Si la lambda només té un paràmetre es pot ometre la seva declaració.
+ El seu valor serà "it".
+ */
+ val notPositive = not {it > 0}
+ for (i in 0..4) {
+ println("${notOdd(i)} ${notEven(i)} ${notZero(i)} ${notPositive(i)}")
+ }
+
+ // Les classes es defineixen amb "class".
+ class ExampleClass(val x: Int) {
+ fun memberFunction(y: Int): Int {
+ return x + y
+ }
+
+ infix fun infixMemberFunction(y: Int): Int {
+ return x * y
+ }
+ }
+ /*
+ Per crear una nova instància es crida al constructor.
+ Tingueu en compte que Kotlin no té l'operador "new".
+ */
+ val fooExampleClass = ExampleClass(7)
+ // Els mètodes es poden cridar amb la notació .
+ println(fooExampleClass.memberFunction(4)) // => 11
+ /*
+ Si una funció ha estat marcada amb "infix" es pot cridar amb la
+ notació infix.
+ */
+ println(fooExampleClass infixMemberFunction 4) // => 28
+
+ /*
+ Les classes "data" són classes que només contenen dades.
+ Es creen automàticament els mètodes "hashCode","equals" i "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)
+
+ // Les classes data tenen un mètode "copy".
+ val fooCopy = fooData.copy(y = 100)
+ println(fooCopy) // => DataClassExample(x=1, y=100, z=4)
+
+ // Els objectes es poden desestructurar amb múltiples variables
+ val (a, b, c) = fooCopy
+ println("$a $b $c") // => 1 100 4
+
+ // desestructurat en un bucle "for"
+ for ((a, b, c) in listOf(fooData)) {
+ println("$a $b $c") // => 1 100 4
+ }
+
+ val mapData = mapOf("a" to 1, "b" to 2)
+ // Els mapes també
+ for ((key, value) in mapData) {
+ println("$key -> $value")
+ }
+
+ // La funció "with" és similar a la de JavaScript.
+ data class MutableDataClassExample (var x: Int, var y: Int, var z: Int)
+ val fooMutableData = MutableDataClassExample(7, 4, 9)
+ with (fooMutableData) {
+ x -= 2
+ y += 2
+ z--
+ }
+ println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8)
+
+ /*
+ Es pot crear una llista amb la funció "listOf".
+ La llista serà immutable - no s'hi poden afegir o treure elements.
+ */
+ val fooList = listOf("a", "b", "c")
+ println(fooList.size) // => 3
+ println(fooList.first()) // => a
+ println(fooList.last()) // => c
+ // Es pot accedir als elements a partir del seu índex.
+ println(fooList[1]) // => b
+
+ // Es poden crear llistes mutables amb la funció "mutableListOf".
+ val fooMutableList = mutableListOf("a", "b", "c")
+ fooMutableList.add("d")
+ println(fooMutableList.last()) // => d
+ println(fooMutableList.size) // => 4
+
+ // Es poden crear conjunts amb la funció "setOf".
+ val fooSet = setOf("a", "b", "c")
+ println(fooSet.contains("a")) // => true
+ println(fooSet.contains("z")) // => false
+
+ // Es poden crear mapes amb la funció "mapOf".
+ val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9)
+ // S'accedeix als valors del mapa a partir del seu índex.
+ println(fooMap["a"]) // => 8
+
+ /*
+ Les sequències representen col·leccions evaluades quan fan falta.
+ Podem crear una seqüencia amb la funció "generateSequence".
+ */
+ val fooSequence = generateSequence(1, { it + 1 })
+ val x = fooSequence.take(10).toList()
+ println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+
+ // Per exemple amb aquesta seqüència es creen els números de Fibonacci:
+ 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 proporciona funcions de primer ordre per treballar amb
+ // col·leccions.
+ val z = (1..9).map {it * 3}
+ .filter {it < 20}
+ .groupBy {it % 2 == 0}
+ .mapKeys {if (it.key) "parell" else "senar"}
+ println(z) // => {odd=[3, 9, 15], even=[6, 12, 18]}
+
+ // Es pot fer servir el bucle "for" amb qualsevol cosa que proporcioni
+ // un iterador.
+ for (c in "hello") {
+ println(c)
+ }
+
+ // els bucles "while" funcionen com en altres llenguatges.
+ var ctr = 0
+ while (ctr < 5) {
+ println(ctr)
+ ctr++
+ }
+ do {
+ println(ctr)
+ ctr++
+ } while (ctr < 10)
+
+ /*
+ "if" es pot fer servir com una expressió que retorna un valor.
+ Per això no cal l'operador ternari ?: en Kotlin.
+ */
+ val num = 5
+ val message = if (num % 2 == 0) "parell" else "senar"
+ println("$num is $message") // => 5 is odd
+
+ // "when" es pot fer servir com alternativa a les cadenes "if-else if".
+ val i = 10
+ when {
+ i < 7 -> println("primer bloc")
+ fooString.startsWith("hola") -> println("segon bloc")
+ else -> println("bloc else")
+ }
+
+ // "when" es pot fer servir amb un argument.
+ when (i) {
+ 0, 21 -> println("0 o 21")
+ in 1..20 -> println("en el rang 1 a 20")
+ else -> println("cap dels anteriors")
+ }
+
+ // "when" es pot fer servir com una funció que retorna valors.
+ var result = when (i) {
+ 0, 21 -> "0 o 21"
+ in 1..20 -> "en el rang 1 a 20"
+ else -> "cap dels anteriors"
+ }
+ println(result)
+
+ /*
+ Es pot comprovar el tipus d'un objecte fent servir l'operador "is".
+ Si un objecte passa una comprovació es pot fer servir sense posar-hi
+ cap casting.
+ */
+ fun smartCastExample(x: Any) : Boolean {
+ if (x is Boolean) {
+ // x es converteix automàticament a Booleà
+ return x
+ } else if (x is Int) {
+ // x es converteix automàticament a int
+ return x > 0
+ } else if (x is String) {
+ // x es converteix a string automàticament
+ return x.isNotEmpty()
+ } else {
+ return false
+ }
+ }
+ println(smartCastExample("Hola món!")) // => true
+ println(smartCastExample("")) // => false
+ println(smartCastExample(5)) // => true
+ println(smartCastExample(0)) // => false
+ println(smartCastExample(true)) // => true
+
+ // També es pot cridar smarcast en un bloc when
+ fun smartCastWhenExample(x: Any) = when (x) {
+ is Boolean -> x
+ is Int -> x > 0
+ is String -> x.isNotEmpty()
+ else -> false
+ }
+
+ /*
+ Les extensions són una forma d'afegir noves funcionalitats a una classe.
+ És semblant a les extensions de C#.
+ */
+ fun String.remove(c: Char): String {
+ return this.filter {it != c}
+ }
+ println("Hola món!".remove('l')) // => Hoa, món!
+
+ println(EnumExample.A) // => A
+ println(ObjectExample.hello()) // => hola
+}
+
+// Les classes enumerades són semblants a les de Java
+enum class EnumExample {
+ A, B, C
+}
+
+/*
+El paràmetre "object" es pot fer servir per crear objectes singleton.
+No es poden instanciar però es pot fer referència a la seva única instància
+amb el seu nom.
+Són similars als singletons d'Scala.
+*/
+object ObjectExample {
+ fun hello(): String {
+ return "hola"
+ }
+}
+
+fun useObject() {
+ ObjectExample.hello()
+ val someRef: Any = ObjectExample // podem fer servir el nom de l'objecte
+}
+
+```
+
+### Per llegir més
+
+* [tutorials de Kotlin](https://kotlinlang.org/docs/tutorials/)
+* [Provar Kotlin en el navegador](http://try.kotlinlang.org/)
+* [Llista de recursos de Kotlin](http://kotlin.link/)
diff --git a/chapel.html.markdown b/chapel.html.markdown
index 9c1daf40..7e8fc41a 100644
--- a/chapel.html.markdown
+++ b/chapel.html.markdown
@@ -2,90 +2,114 @@
language: chapel
filename: learnchapel.chpl
contributors:
- - ["Ian J. Bertolacci", "http://www.cs.colostate.edu/~ibertola/"]
+ - ["Ian J. Bertolacci", "https://www.cs.arizona.edu/~ianbertolacci/"]
+ - ["Ben Harshbarger", "https://github.com/benharsh/"]
---
-You can read all about Chapel at [Cray's official Chapel website](http://chapel.cray.com).
-In short, Chapel is an open-source, high-productivity, parallel-programming language in development at Cray Inc., and is designed to run on multi-core PCs as well as multi-kilocore supercomputers.
+You can read all about Chapel at [Cray's official Chapel website](https://chapel-lang.org).
+In short, Chapel is an open-source, high-productivity, parallel-programming
+language in development at Cray Inc., and is designed to run on multi-core PCs
+as well as multi-kilocore supercomputers.
More information and support can be found at the bottom of this document.
-```c
+```chapel
// Comments are C-family style
+
// one line comment
/*
- multi-line comment
+ multi-line comment
*/
// Basic printing
-write( "Hello, " );
-writeln( "World!" );
+
+write("Hello, ");
+writeln("World!");
+
// write and writeln can take a list of things to print.
-// each thing is printed right next to each other, so include your spacing!
-writeln( "There are ", 3, " commas (\",\") in this line of code" );
-// Different output channels
-stdout.writeln( "This goes to standard output, just like plain writeln() does");
-stderr.writeln( "This goes to standard error" );
+// Each thing is printed right next to the others, so include your spacing!
+writeln("There are ", 3, " commas (\",\") in this line of code");
+
+// Different output channels:
+stdout.writeln("This goes to standard output, just like plain writeln() does");
+stderr.writeln("This goes to standard error");
+
// Variables don't have to be explicitly typed as long as
// the compiler can figure out the type that it will hold.
-var myVar = 10; // 10 is an int, so myVar is implicitly an int
+// 10 is an int, so myVar is implicitly an int
+var myVar = 10;
myVar = -10;
var mySecondVar = myVar;
-// var anError; // this would be a compile-time error.
+// var anError; would be a compile-time error.
-// We can (and should) explicitly type things
+// We can (and should) explicitly type things.
var myThirdVar: real;
var myFourthVar: real = -1.234;
myThirdVar = myFourthVar;
+// Types
+
// There are a number of basic types.
var myInt: int = -1000; // Signed ints
var myUint: uint = 1234; // Unsigned ints
var myReal: real = 9.876; // Floating point numbers
var myImag: imag = 5.0i; // Imaginary numbers
var myCplx: complex = 10 + 9i; // Complex numbers
-myCplx = myInt + myImag ; // Another way to form complex numbers
+myCplx = myInt + myImag; // Another way to form complex numbers
var myBool: bool = false; // Booleans
var myStr: string = "Some string..."; // Strings
+var singleQuoteStr = 'Another string...'; // String literal with single quotes
-// Some types can have sizes
+// Some types can have sizes.
var my8Int: int(8) = 10; // 8 bit (one byte) sized int;
var my64Real: real(64) = 1.516; // 64 bit (8 bytes) sized real
-// Typecasting
+// Typecasting.
var intFromReal = myReal : int;
var intFromReal2: int = myReal : int;
-// consts are constants, they cannot be changed after set in runtime.
+// Type aliasing.
+type chroma = int; // Type of a single hue
+type RGBColor = 3*chroma; // Type representing a full color
+var black: RGBColor = (0,0,0);
+var white: RGBColor = (255, 255, 255);
+
+// Constants and Parameters
+
+// A const is a constant, and cannot be changed after set in runtime.
const almostPi: real = 22.0/7.0;
-// params are constants whose value must be known statically at compile-time
-// Their value cannot be changed.
+// A param is a constant whose value must be known statically at
+// compile-time.
param compileTimeConst: int = 16;
-// The config modifier allows values to be set at the command line
-// and is much easier than the usual getOpts debacle
-// config vars and consts can be changed through the command line at run time
+// The config modifier allows values to be set at the command line.
+// Set with --varCmdLineArg=Value or --varCmdLineArg Value at runtime.
config var varCmdLineArg: int = -123;
config const constCmdLineArg: int = 777;
-// Set with --VarName=Value or --VarName Value at run time
-// config params can be set/changed at compile-time
+// config param can be set at compile-time.
+// Set with --set paramCmdLineArg=value at compile-time.
config param paramCmdLineArg: bool = false;
-// Set config with --set paramCmdLineArg=value at compile-time
-writeln( varCmdLineArg, ", ", constCmdLineArg, ", ", paramCmdLineArg );
+writeln(varCmdLineArg, ", ", constCmdLineArg, ", ", paramCmdLineArg);
-// refs operate much like a reference in C++
+// References
+
+// ref operates much like a reference in C++. In Chapel, a ref cannot
+// be made to alias a variable other than the variable it is initialized with.
+// Here, refToActual refers to actual.
var actual = 10;
-ref refToActual = actual; // refToActual refers to actual
-writeln( actual, " == ", refToActual ); // prints the same value
+ref refToActual = actual;
+writeln(actual, " == ", refToActual); // prints the same value
actual = -123; // modify actual (which refToActual refers to)
-writeln( actual, " == ", refToActual ); // prints the same value
+writeln(actual, " == ", refToActual); // prints the same value
refToActual = 99999999; // modify what refToActual refers to (which is actual)
-writeln( actual, " == ", refToActual ); // prints the same value
+writeln(actual, " == ", refToActual); // prints the same value
+
+// Operators
-// Math operators
+// Math operators:
var a: int, thisInt = 1234, thatInt = 5678;
a = thisInt + thatInt; // Addition
a = thisInt * thatInt; // Multiplication
@@ -94,252 +118,259 @@ a = thisInt / thatInt; // Division
a = thisInt ** thatInt; // Exponentiation
a = thisInt % thatInt; // Remainder (modulo)
-// Logical Operators
+// Logical operators:
var b: bool, thisBool = false, thatBool = true;
b = thisBool && thatBool; // Logical and
b = thisBool || thatBool; // Logical or
b = !thisBool; // Logical negation
-// Relational Operators
+// Relational operators:
b = thisInt > thatInt; // Greater-than
b = thisInt >= thatInt; // Greater-than-or-equal-to
b = thisInt < a && a <= thatInt; // Less-than, and, less-than-or-equal-to
b = thisInt != thatInt; // Not-equal-to
b = thisInt == thatInt; // Equal-to
-// Bitwise operations
+// Bitwise operators:
a = thisInt << 10; // Left-bit-shift by 10 bits;
a = thatInt >> 5; // Right-bit-shift by 5 bits;
a = ~thisInt; // Bitwise-negation
a = thisInt ^ thatInt; // Bitwise exclusive-or
-// Compound assignment operations
-a += thisInt; // Addition-equals ( a = a + thisInt;)
-a *= thatInt; // Times-equals ( a = a * thatInt; )
-b &&= thatBool; // Logical-and-equals ( b = b && thatBool; )
-a <<= 3; // Left-bit-shift-equals ( a = a << 10; )
-// and many, many more.
-// Unlike other C family languages there are no
-// pre/post-increment/decrement operators like
-// ++j, --j, j++, j--
-
-// Swap operator
+// Compound assignment operators:
+a += thisInt; // Addition-equals (a = a + thisInt;)
+a *= thatInt; // Times-equals (a = a * thatInt;)
+b &&= thatBool; // Logical-and-equals (b = b && thatBool;)
+a <<= 3; // Left-bit-shift-equals (a = a << 10;)
+
+// Unlike other C family languages, there are no
+// pre/post-increment/decrement operators, such as:
+//
+// ++j, --j, j++, j--
+
+// Swap operator:
var old_this = thisInt;
var old_that = thatInt;
thisInt <=> thatInt; // Swap the values of thisInt and thatInt
-writeln( (old_this == thatInt) && (old_that == thisInt) );
+writeln((old_this == thatInt) && (old_that == thisInt));
+
+// Operator overloads can also be defined, as we'll see with procedures.
-// Operator overloads can also be defined, as we'll see with procedures
+// Tuples
-// Tuples can be of the same type
-var sameTup: 2*int = (10,-1);
+// Tuples can be of the same type or different types.
+var sameTup: 2*int = (10, -1);
var sameTup2 = (11, -6);
-// or different types
var diffTup: (int,real,complex) = (5, 1.928, myCplx);
-var diffTupe2 = ( 7, 5.64, 6.0+1.5i );
+var diffTupe2 = (7, 5.64, 6.0+1.5i);
-// Accessed using array bracket notation
-// However, tuples are all 1-indexed
-writeln( "(", sameTup[1], ",", sameTup[2], ")" );
-writeln( diffTup );
+// Tuples can be accessed using square brackets or parentheses, and are
+// 1-indexed.
+writeln("(", sameTup[1], ",", sameTup(2), ")");
+writeln(diffTup);
// Tuples can also be written into.
-diffTup[1] = -1;
+diffTup(1) = -1;
-// Can expand tuple values into their own variables
+// Tuple values can be expanded into their own variables.
var (tupInt, tupReal, tupCplx) = diffTup;
-writeln( diffTup == (tupInt, tupReal, tupCplx) );
+writeln(diffTup == (tupInt, tupReal, tupCplx));
-// Useful for writing a list of variables ( as is common in debugging)
-writeln( (a,b,thisInt,thatInt,thisBool,thatBool) );
+// They are also useful for writing a list of variables, as is common in debugging.
+writeln((a,b,thisInt,thatInt,thisBool,thatBool));
-// Type aliasing
-type chroma = int; // Type of a single hue
-type RGBColor = 3*chroma; // Type representing a full color
-var black: RGBColor = ( 0,0,0 );
-var white: RGBColor = ( 255, 255, 255 );
+// Control Flow
-// If-then-else works just like any other C-family language
+// if - then - else works just like any other C-family language.
if 10 < 100 then
- writeln( "All is well" );
+ writeln("All is well");
if -1 < 1 then
- writeln( "Continuing to believe reality" );
+ writeln("Continuing to believe reality");
else
- writeln( "Send mathematician, something's wrong" );
+ writeln("Send mathematician, something is wrong");
-if ( 10 > 100 ) {
- writeln( "Universe broken. Please reboot universe." );
+// You can use parentheses if you prefer.
+if (10 > 100) {
+ writeln("Universe broken. Please reboot universe.");
}
-if ( a % 2 == 0 ) {
- writeln( a, " is even." );
+if a % 2 == 0 {
+ writeln(a, " is even.");
} else {
- writeln( a, " is odd." );
+ writeln(a, " is odd.");
}
-if ( a % 3 == 0 ) {
- writeln( a, " is even divisible by 3." );
-} else if ( a % 3 == 1 ){
- writeln( a, " is divided by 3 with a remainder of 1." );
+if a % 3 == 0 {
+ writeln(a, " is even divisible by 3.");
+} else if a % 3 == 1 {
+ writeln(a, " is divided by 3 with a remainder of 1.");
} else {
- writeln( b, " is divided by 3 with a remainder of 2." );
+ writeln(b, " is divided by 3 with a remainder of 2.");
}
-// Ternary: if-then-else in a statement
-var maximum = if ( thisInt < thatInt ) then thatInt else thisInt;
+// Ternary: if - then - else in a statement.
+var maximum = if thisInt < thatInt then thatInt else thisInt;
-// Select statements are much like switch statements in other languages
-// However, Select statements don't cascade like in C or Java
+// select statements are much like switch statements in other languages.
+// However, select statements do not cascade like in C or Java.
var inputOption = "anOption";
-select( inputOption ){
- when "anOption" do writeln( "Chose 'anOption'" );
+select inputOption {
+ when "anOption" do writeln("Chose 'anOption'");
when "otherOption" {
- writeln( "Chose 'otherOption'" );
- writeln( "Which has a body" );
+ writeln("Chose 'otherOption'");
+ writeln("Which has a body");
}
otherwise {
- writeln( "Any other Input" );
- writeln( "the otherwise case doesn't need a do if the body is one line" );
+ writeln("Any other Input");
+ writeln("the otherwise case does not need a do if the body is one line");
}
}
-// While and Do-While loops are basically the same in every language.
+// while and do-while loops also behave like their C counterparts.
var j: int = 1;
var jSum: int = 0;
-while( j <= 1000 ){
+while (j <= 1000) {
jSum += j;
j += 1;
}
-writeln( jSum );
+writeln(jSum);
-// Do-While loop
-do{
+do {
jSum += j;
j += 1;
-}while( j <= 10000 );
-writeln( jSum );
+} while (j <= 10000);
+writeln(jSum);
-// For loops are much like those in python in that they iterate over a range.
-// Ranges themselves are types, and can be stuffed into variables
-// (more about that later)
-for i in 1..10 do write( i , ", ") ;
-writeln( );
+// for loops are much like those in Python in that they iterate over a
+// range. Ranges (like the 1..10 expression below) are a first-class object
+// in Chapel, and as such can be stored in variables.
+for i in 1..10 do write(i, ", ");
+writeln();
var iSum: int = 0;
for i in 1..1000 {
iSum += i;
}
-writeln( iSum );
+writeln(iSum);
for x in 1..10 {
for y in 1..10 {
- write( (x,y), "\t" );
+ write((x,y), "\t");
}
- writeln( );
+ writeln();
}
// Ranges and Domains
-// For-loops and arrays both use ranges and domains to
-// define an index set that can be iterated over.
-// Ranges are single dimensional
-// Domains can be multi-dimensional and can
-// represent indices of different types as well.
-// They are first-class citizen types, and can be assigned into variables
+
+// For-loops and arrays both use ranges and domains to define an index set that
+// can be iterated over. Ranges are single dimensional integer indices, while
+// domains can be multi-dimensional and represent indices of different types.
+
+// They are first-class citizen types, and can be assigned into variables.
var range1to10: range = 1..10; // 1, 2, 3, ..., 10
var range2to11 = 2..11; // 2, 3, 4, ..., 11
-var rangeThistoThat: range = thisInt..thatInt; // using variables
-var rangeEmpty: range = 100..-100 ; // this is valid but contains no indices
+var rangeThisToThat: range = thisInt..thatInt; // using variables
+var rangeEmpty: range = 100..-100; // this is valid but contains no indices
-// Ranges can be unbounded
-var range1toInf: range(boundedType=BoundedRangeType.boundedLow) = 1.. ;
-// 1, 2, 3, 4, 5, ...
-// Note: the range(boundedType= ... ) is only
-// necessary if we explicitly type the variable
+// Ranges can be unbounded.
+var range1toInf: range(boundedType=BoundedRangeType.boundedLow) = 1.. ; // 1, 2, 3, 4, 5, ...
+var rangeNegInfTo1 = ..1; // ..., -4, -3, -2, -1, 0, 1
-var rangeNegInfto1 = ..1; // ..., -4, -3, -2, -1, 0, 1
-
-// Ranges can be strided using the 'by' operator.
+// Ranges can be strided (and reversed) using the by operator.
var range2to10by2: range(stridable=true) = 2..10 by 2; // 2, 4, 6, 8, 10
-// Note: the range(stridable=true) is only
-// necessary if we explicitly type the variable
+var reverse2to10by2 = 2..10 by -2; // 10, 8, 6, 4, 2
+
+var trapRange = 10..1 by -1; // Do not be fooled, this is still an empty range
+writeln("Size of range ", trapRange, " = ", trapRange.length);
-// Use by to create a reverse range
-var reverse2to10by2 = 10..2 by -2; // 10, 8, 6, 4, 2
+// Note: range(boundedType= ...) and range(stridable= ...) are only
+// necessary if we explicitly type the variable.
-// The end point of a range can be determined using the count (#) operator
+// The end point of a range can be determined using the count (#) operator.
var rangeCount: range = -5..#12; // range from -5 to 6
-// Can mix operators
+// Operators can be mixed.
var rangeCountBy: range(stridable=true) = -5..#12 by 2; // -5, -3, -1, 1, 3, 5
-writeln( rangeCountBy );
+writeln(rangeCountBy);
-// Can query properties of the range
-// Print the first index, last index, number of indices,
-// stride, and ask if 2 is include in the range
-writeln( ( rangeCountBy.first, rangeCountBy.last, rangeCountBy.length,
- rangeCountBy.stride, rangeCountBy.member( 2 ) ) );
+// Properties of the range can be queried.
+// In this example, printing the first index, last index, number of indices,
+// stride, and if 2 is include in the range.
+writeln((rangeCountBy.first, rangeCountBy.last, rangeCountBy.length,
+ rangeCountBy.stride, rangeCountBy.member(2)));
-for i in rangeCountBy{
- write( i, if i == rangeCountBy.last then "\n" else ", " );
+for i in rangeCountBy {
+ write(i, if i == rangeCountBy.last then "\n" else ", ");
}
-// Rectangular domains are defined using the same range syntax
-// However they are required to be bounded (unlike ranges)
+// Rectangular domains are defined using the same range syntax,
+// but they are required to be bounded (unlike ranges).
var domain1to10: domain(1) = {1..10}; // 1D domain from 1..10;
var twoDimensions: domain(2) = {-2..2,0..2}; // 2D domain over product of ranges
var thirdDim: range = 1..16;
var threeDims: domain(3) = {thirdDim, 1..10, 5..10}; // using a range variable
-// Can iterate over the indices as tuples
+// Domains can also be resized
+var resizedDom = {1..10};
+writeln("before, resizedDom = ", resizedDom);
+resizedDom = {-10..#10};
+writeln("after, resizedDom = ", resizedDom);
+
+// Indices can be iterated over as tuples.
for idx in twoDimensions do
- write( idx , ", ");
-writeln( );
+ write(idx, ", ");
+writeln();
-// or can deconstruct the tuple
+// These tuples can also be deconstructed.
for (x,y) in twoDimensions {
- write( "(", x, ", ", y, ")", ", " );
+ write("(", x, ", ", y, ")", ", ");
}
-writeln( );
+writeln();
-// Associative domains act like sets
+// Associative domains act like sets.
var stringSet: domain(string); // empty set of strings
stringSet += "a";
stringSet += "b";
stringSet += "c";
stringSet += "a"; // Redundant add "a"
stringSet -= "c"; // Remove "c"
-writeln( stringSet );
+writeln(stringSet.sorted());
+
+// Associative domains can also have a literal syntax
+var intSet = {1, 2, 4, 5, 100};
// Both ranges and domains can be sliced to produce a range or domain with the
-// intersection of indices
+// intersection of indices.
var rangeA = 1.. ; // range from 1 to infinity
var rangeB = ..5; // range from negative infinity to 5
var rangeC = rangeA[rangeB]; // resulting range is 1..5
-writeln( (rangeA, rangeB, rangeC ) );
+writeln((rangeA, rangeB, rangeC));
var domainA = {1..10, 5..20};
var domainB = {-5..5, 1..10};
var domainC = domainA[domainB];
-writeln( (domainA, domainB, domainC) );
+writeln((domainA, domainB, domainC));
+
+// Arrays
-// Array are similar to those of other languages.
-// Their sizes are defined using domains that represent their indices
+// Arrays are similar to those of other languages.
+// Their sizes are defined using domains that represent their indices.
var intArray: [1..10] int;
-var intArray2: [{1..10}] int; //equivalent
+var intArray2: [{1..10}] int; // equivalent
-// Accessed using bracket notation
+// They can be accessed using either brackets or parentheses
for i in 1..10 do
intArray[i] = -i;
-writeln( intArray );
+writeln(intArray);
+
// We cannot access intArray[0] because it exists outside
// of the index set, {1..10}, we defined it to have.
// intArray[11] is illegal for the same reason.
-
var realDomain: domain(2) = {1..5,1..7};
var realArray: [realDomain] real;
-var realArray2: [1..5,1..7] real; // Equivalent
-var realArray3: [{1..5,1..7}] real; // Equivalent
+var realArray2: [1..5,1..7] real; // equivalent
+var realArray3: [{1..5,1..7}] real; // equivalent
for i in 1..5 {
for j in realDomain.dim(2) { // Only use the 2nd dimension of the domain
@@ -349,357 +380,390 @@ for i in 1..5 {
}
}
-// Arrays have domains as members that we can iterate over
+// Arrays have domains as members, and can be iterated over as normal.
for idx in realArray.domain { // Again, idx is a 2*int tuple
- realArray[idx] = 1 / realArray[idx[1],idx[2]]; // Access by tuple and list
+ realArray[idx] = 1 / realArray[idx[1], idx[2]]; // Access by tuple and list
}
-writeln( realArray );
+writeln(realArray);
-// Can also iterate over the values of an array
+// The values of an array can also be iterated directly.
var rSum: real = 0;
for value in realArray {
rSum += value; // Read a value
value = rSum; // Write a value
}
-writeln( rSum, "\n", realArray );
+writeln(rSum, "\n", realArray);
-// Using associative domains we can create associative arrays (dictionaries)
+// Associative arrays (dictionaries) can be created using associative domains.
var dictDomain: domain(string) = { "one", "two" };
-var dict: [dictDomain] int = [ "one" => 1, "two" => 2 ];
-dict["three"] = 3;
-for key in dictDomain do writeln( dict[key] );
+var dict: [dictDomain] int = ["one" => 1, "two" => 2];
+dict["three"] = 3; // Adds 'three' to 'dictDomain' implicitly
+for key in dictDomain.sorted() do
+ writeln(dict[key]);
+
+// Arrays can be assigned to each other in a few different ways.
+// These arrays will be used in the example.
+var thisArray : [0..5] int = [0,1,2,3,4,5];
+var thatArray : [0..5] int;
-// Arrays can be assigned to each other in different ways
-var thisArray : [{0..5}] int = [0,1,2,3,4,5];
-var thatArray : [{0..5}] int;
+// First, simply assign one to the other. This copies thisArray into
+// thatArray, instead of just creating a reference. Therefore, modifying
+// thisArray does not also modify thatArray.
-// Simply assign one to the other.
-// This copies thisArray into thatArray, instead of just creating a reference.
-// Modifying thisArray does not also modify thatArray.
thatArray = thisArray;
thatArray[1] = -1;
-writeln( (thisArray, thatArray) );
+writeln((thisArray, thatArray));
-// Assign a slice one array to a slice (of the same size) of the other.
-thatArray[{4..5}] = thisArray[{1..2}];
-writeln( (thisArray, thatArray) );
+// Assign a slice from one array to a slice (of the same size) in the other.
+thatArray[4..5] = thisArray[1..2];
+writeln((thisArray, thatArray));
-// Operation can also be promoted to work on arrays.
+// Operations can also be promoted to work on arrays. 'thisPlusThat' is also
+// an array.
var thisPlusThat = thisArray + thatArray;
-writeln( thisPlusThat );
+writeln(thisPlusThat);
-// Arrays and loops can also be expressions, where loop
-// body's expression is the result of each iteration.
+// Moving on, arrays and loops can also be expressions, where the loop
+// body expression is the result of each iteration.
var arrayFromLoop = for i in 1..10 do i;
-writeln( arrayFromLoop );
+writeln(arrayFromLoop);
-// An expression can result in nothing,
-// such as when filtering with an if-expression
+// An expression can result in nothing, such as when filtering with an if-expression.
var evensOrFives = for i in 1..10 do if (i % 2 == 0 || i % 5 == 0) then i;
-writeln( arrayFromLoop );
+writeln(arrayFromLoop);
-// Or could be written with a bracket notation
-// Note: this syntax uses the 'forall' parallel concept discussed later.
-var evensOrFivesAgain = [ i in 1..10 ] if (i % 2 == 0 || i % 5 == 0) then i;
+// Array expressions can also be written with a bracket notation.
+// Note: this syntax uses the forall parallel concept discussed later.
+var evensOrFivesAgain = [i in 1..10] if (i % 2 == 0 || i % 5 == 0) then i;
-// Or over the values of the array
-arrayFromLoop = [ value in arrayFromLoop ] value + 1;
+// They can also be written over the values of the array.
+arrayFromLoop = [value in arrayFromLoop] value + 1;
-// Note: this notation can get somewhat tricky. For example:
-// evensOrFives = [ i in 1..10 ] if (i % 2 == 0 || i % 5 == 0) then i;
-// would break.
-// The reasons for this are explained in depth when discussing zipped iterators.
-// Chapel procedures have similar syntax to other languages functions.
-proc fibonacci( n : int ) : int {
- if ( n <= 1 ) then return n;
- return fibonacci( n-1 ) + fibonacci( n-2 );
+// Procedures
+
+// Chapel procedures have similar syntax functions in other languages.
+proc fibonacci(n : int) : int {
+ if n <= 1 then return n;
+ return fibonacci(n-1) + fibonacci(n-2);
}
-// Input parameters can be untyped (a generic procedure)
-proc doublePrint( thing ): void {
- write( thing, " ", thing, "\n");
+// Input parameters can be untyped to create a generic procedure.
+proc doublePrint(thing): void {
+ write(thing, " ", thing, "\n");
}
-// Return type can be inferred (as long as the compiler can figure it out)
-proc addThree( n ) {
+// The return type can be inferred, as long as the compiler can figure it out.
+proc addThree(n) {
return n + 3;
}
-doublePrint( addThree( fibonacci( 20 ) ) );
+doublePrint(addThree(fibonacci(20)));
-// Can also take 'unlimited' number of parameters
-proc maxOf( x ...?k ) {
+// It is also possible to take a variable number of parameters.
+proc maxOf(x ...?k) {
// x refers to a tuple of one type, with k elements
var maximum = x[1];
- for i in 2..k do maximum = if (maximum < x[i]) then x[i] else maximum;
+ for i in 2..k do maximum = if maximum < x[i] then x[i] else maximum;
return maximum;
}
-writeln( maxOf( 1, -10, 189, -9071982, 5, 17, 20001, 42 ) );
+writeln(maxOf(1, -10, 189, -9071982, 5, 17, 20001, 42));
-// The ? operator is called the query operator, and is used to take
-// undetermined values (like tuple or array sizes, and generic types).
+// Procedures can have default parameter values, and
+// the parameters can be named in the call, even out of order.
+proc defaultsProc(x: int, y: real = 1.2634): (int,real) {
+ return (x,y);
+}
-// Taking arrays as parameters.
-// The query operator is used to determine the domain of A.
-// This is important to define the return type (if you wanted to)
-proc invertArray( A: [?D] int ): [D] int{
+writeln(defaultsProc(10));
+writeln(defaultsProc(x=11));
+writeln(defaultsProc(x=12, y=5.432));
+writeln(defaultsProc(y=9.876, x=13));
+
+// The ? operator is called the query operator, and is used to take
+// undetermined values like tuple or array sizes and generic types.
+// For example, taking arrays as parameters. The query operator is used to
+// determine the domain of A. This is uesful for defining the return type,
+// though it's not required.
+proc invertArray(A: [?D] int): [D] int{
for a in A do a = -a;
return A;
}
-writeln( invertArray( intArray ) );
+writeln(invertArray(intArray));
-// Procedures can have default parameter values, and
-// the parameters can be named in the call, even out of order
-proc defaultsProc( x: int, y: real = 1.2634 ): (int,real){
- return (x,y);
+// We can query the type of arguments to generic procedures.
+// Here we define a procedure that takes two arguments of
+// the same type, yet we don't define what that type is.
+proc genericProc(arg1 : ?valueType, arg2 : valueType): void {
+ select(valueType) {
+ when int do writeln(arg1, " and ", arg2, " are ints");
+ when real do writeln(arg1, " and ", arg2, " are reals");
+ otherwise writeln(arg1, " and ", arg2, " are somethings!");
+ }
+}
+
+genericProc(1, 2);
+genericProc(1.2, 2.3);
+genericProc(1.0+2.0i, 3.0+4.0i);
+
+// We can also enforce a form of polymorphism with the where clause
+// This allows the compiler to decide which function to use.
+// Note: That means that all information needs to be known at compile-time.
+// The param modifier on the arg is used to enforce this constraint.
+proc whereProc(param N : int): void
+ where (N > 0) {
+ writeln("N is greater than 0");
+}
+
+proc whereProc(param N : int): void
+ where (N < 0) {
+ writeln("N is less than 0");
+}
+
+whereProc(10);
+whereProc(-1);
+
+// whereProc(0) would result in a compiler error because there
+// are no functions that satisfy the where clause's condition.
+// We could have defined a whereProc without a where clause
+// that would then have served as a catch all for all the other cases
+// (of which there is only one).
+
+// where clauses can also be used to constrain based on argument type.
+proc whereType(x: ?t) where t == int {
+ writeln("Inside 'int' version of 'whereType': ", x);
+}
+
+proc whereType(x: ?t) {
+ writeln("Inside general version of 'whereType': ", x);
}
-writeln( defaultsProc( 10 ) );
-writeln( defaultsProc( x=11 ) );
-writeln( defaultsProc( x=12, y=5.432 ) );
-writeln( defaultsProc( y=9.876, x=13 ) );
-
-// Intent modifiers on the arguments convey how
-// those arguments are passed to the procedure
-// in: copy arg in, but not out
-// out: copy arg out, but not in
-// inout: copy arg in, copy arg out
-// ref: pass arg by reference
-proc intentsProc( in inarg, out outarg, inout inoutarg, ref refarg ){
- writeln( "Inside Before: ", (inarg, outarg, inoutarg, refarg) );
+whereType(42);
+whereType("hello");
+
+// Intents
+
+/* Intent modifiers on the arguments convey how those arguments are passed to the procedure.
+
+ * in: copy arg in, but not out
+ * out: copy arg out, but not in
+ * inout: copy arg in, copy arg out
+ * ref: pass arg by reference
+*/
+proc intentsProc(in inarg, out outarg, inout inoutarg, ref refarg) {
+ writeln("Inside Before: ", (inarg, outarg, inoutarg, refarg));
inarg = inarg + 100;
outarg = outarg + 100;
inoutarg = inoutarg + 100;
refarg = refarg + 100;
- writeln( "Inside After: ", (inarg, outarg, inoutarg, refarg) );
+ writeln("Inside After: ", (inarg, outarg, inoutarg, refarg));
}
var inVar: int = 1;
var outVar: int = 2;
var inoutVar: int = 3;
var refVar: int = 4;
-writeln( "Outside Before: ", (inVar, outVar, inoutVar, refVar) );
-intentsProc( inVar, outVar, inoutVar, refVar );
-writeln( "Outside After: ", (inVar, outVar, inoutVar, refVar) );
-
-// Similarly we can define intents on the return type
-// refElement returns a reference to an element of array
-proc refElement( array : [?D] ?T, idx ) ref : T {
- return array[ idx ]; // returns a reference to
-}
+writeln("Outside Before: ", (inVar, outVar, inoutVar, refVar));
+intentsProc(inVar, outVar, inoutVar, refVar);
+writeln("Outside After: ", (inVar, outVar, inoutVar, refVar));
-var myChangingArray : [1..5] int = [1,2,3,4,5];
-writeln( myChangingArray );
-// Store reference to element in ref variable
-ref refToElem = refElement( myChangingArray, 5 );
-writeln( refToElem );
-refToElem = -2; // modify reference which modifies actual value in array
-writeln( refToElem );
-writeln( myChangingArray );
+// Similarly, we can define intents on the return type.
+// refElement returns a reference to an element of array.
// This makes more practical sense for class methods where references to
-// elements in a data-structure are returned via a method or iterator
-
-// We can query the type of arguments to generic procedures
-// Here we define a procedure that takes two arguments of
-// the same type, yet we don't define what that type is.
-proc genericProc( arg1 : ?valueType, arg2 : valueType ): void {
- select( valueType ){
- when int do writeln( arg1, " and ", arg2, " are ints" );
- when real do writeln( arg1, " and ", arg2, " are reals" );
- otherwise writeln( arg1, " and ", arg2, " are somethings!" );
- }
-}
-
-genericProc( 1, 2 );
-genericProc( 1.2, 2.3 );
-genericProc( 1.0+2.0i, 3.0+4.0i );
-
-// We can also enforce a form of polymorphism with the 'where' clause
-// This allows the compiler to decide which function to use.
-// Note: that means that all information needs to be known at compile-time.
-// The param modifier on the arg is used to enforce this constraint.
-proc whereProc( param N : int ): void
- where ( N > 0 ) {
- writeln( "N is greater than 0" );
+// elements in a data-structure are returned via a method or iterator.
+proc refElement(array : [?D] ?T, idx) ref : T {
+ return array[idx];
}
-proc whereProc( param N : int ): void
- where ( N < 0 ) {
- writeln( "N is less than 0" );
-}
+var myChangingArray : [1..5] int = [1,2,3,4,5];
+writeln(myChangingArray);
+ref refToElem = refElement(myChangingArray, 5); // store reference to element in ref variable
+writeln(refToElem);
+refToElem = -2; // modify reference which modifies actual value in array
+writeln(refToElem);
+writeln(myChangingArray);
-whereProc( 10 );
-whereProc( -1 );
-// whereProc( 0 ) would result in a compiler error because there
-// are no functions that satisfy the where clause's condition.
-// We could have defined a whereProc without a where clause that would then have
-// served as a catch all for all the other cases (of which there is only one).
+// Operator Definitions
-// Operator definitions are through procedures as well.
+// Chapel allows for operators to be overloaded.
// We can define the unary operators:
// + - ! ~
// and the binary operators:
// + - * / % ** == <= >= < > << >> & | ˆ by
// += -= *= /= %= **= &= |= ˆ= <<= >>= <=>
-// Boolean exclusive or operator
-proc ^( left : bool, right : bool ): bool {
- return (left || right) && !( left && right );
+// Boolean exclusive or operator.
+proc ^(left : bool, right : bool): bool {
+ return (left || right) && !(left && right);
}
-writeln( true ^ true );
-writeln( false ^ true );
-writeln( true ^ false );
-writeln( false ^ false );
+writeln(true ^ true);
+writeln(false ^ true);
+writeln(true ^ false);
+writeln(false ^ false);
-// Define a * operator on any two types that returns a tuple of those types
-proc *( left : ?ltype, right : ?rtype): ( ltype, rtype ){
- return (left, right );
+// Define a * operator on any two types that returns a tuple of those types.
+proc *(left : ?ltype, right : ?rtype): (ltype, rtype) {
+ writeln("\tIn our '*' overload!");
+ return (left, right);
}
-writeln( 1 * "a" ); // Uses our * operator
-writeln( 1 * 2 ); // Uses the default * operator
+writeln(1 * "a"); // Uses our * operator.
+writeln(1 * 2); // Uses the default * operator.
+
+// Note: You could break everything if you get careless with your overloads.
+// This here will break everything. Don't do it.
/*
-Note: You could break everything if you get careless with your overloads.
-This here will break everything. Don't do it.
-proc +( left: int, right: int ): int{
- return left - right;
-}
+ proc +(left: int, right: int): int {
+ return left - right;
+ }
*/
-// Iterators are a sisters to the procedure, and almost
-// everything about procedures also applies to iterators
-// However, instead of returning a single value,
-// iterators yield many values to a loop.
-// This is useful when a complicated set or order of iterations is needed but
-// allows the code defining the iterations to be separate from the loop body.
-iter oddsThenEvens( N: int ): int {
+// Iterators
+
+// Iterators are sisters to the procedure, and almost everything about
+// procedures also applies to iterators. However, instead of returning a single
+// value, iterators may yield multiple values to a loop.
+//
+// This is useful when a complicated set or order of iterations is needed, as
+// it allows the code defining the iterations to be separate from the loop
+// body.
+iter oddsThenEvens(N: int): int {
for i in 1..N by 2 do
yield i; // yield values instead of returning.
for i in 2..N by 2 do
yield i;
}
-for i in oddsThenEvens( 10 ) do write( i, ", " );
-writeln( );
+for i in oddsThenEvens(10) do write(i, ", ");
+writeln();
// Iterators can also yield conditionally, the result of which can be nothing
-iter absolutelyNothing( N ): int {
+iter absolutelyNothing(N): int {
for i in 1..N {
- if ( N < i ) { // Always false
+ if N < i { // Always false
yield i; // Yield statement never happens
}
}
}
-for i in absolutelyNothing( 10 ){
- writeln( "Woa there! absolutelyNothing yielded ", i );
+for i in absolutelyNothing(10) {
+ writeln("Woa there! absolutelyNothing yielded ", i);
}
// We can zipper together two or more iterators (who have the same number
-// of iterations) using zip() to create a single zipped iterator, where each
+// of iterations) using zip() to create a single zipped iterator, where each
// iteration of the zipped iterator yields a tuple of one value yielded
// from each iterator.
- // Ranges have implicit iterators
-for (positive, negative) in zip( 1..5, -5..-1) do
- writeln( (positive, negative) );
+for (positive, negative) in zip(1..5, -5..-1) do
+ writeln((positive, negative));
// Zipper iteration is quite important in the assignment of arrays,
// slices of arrays, and array/loop expressions.
var fromThatArray : [1..#5] int = [1,2,3,4,5];
var toThisArray : [100..#5] int;
-// The operation
+// Some zipper operations implement other operations.
+// The first statement and the loop are equivalent.
toThisArray = fromThatArray;
-// is produced through
-for (i,j) in zip( toThisArray.domain, fromThatArray.domain) {
- toThisArray[ i ] = fromThatArray[ j ];
+for (i,j) in zip(toThisArray.domain, fromThatArray.domain) {
+ toThisArray[i] = fromThatArray[j];
}
-toThisArray = [ j in -100..#5 ] j;
-writeln( toThisArray );
-// is produced through
-for (i, j) in zip( toThisArray.domain, -100..#5 ){
+// These two chunks are also equivalent.
+toThisArray = [j in -100..#5] j;
+writeln(toThisArray);
+
+for (i, j) in zip(toThisArray.domain, -100..#5) {
toThisArray[i] = j;
}
-writeln( toThisArray );
+writeln(toThisArray);
+
+// This is very important in understanding why this statement exhibits a
+// runtime error.
+
+/*
+ var iterArray : [1..10] int = [i in 1..10] if (i % 2 == 1) then i;
+*/
-// This is all very important in understanding why the statement
-// var iterArray : [1..10] int = [ i in 1..10 ] if ( i % 2 == 1 ) then j;
-// exhibits a runtime error.
// Even though the domain of the array and the loop-expression are
// the same size, the body of the expression can be thought of as an iterator.
// Because iterators can yield nothing, that iterator yields a different number
// of things than the domain of the array or loop, which is not allowed.
-// Classes are similar to those in C++ and Java.
-// They currently lack privatization
+// Classes
+
+// Classes are similar to those in C++ and Java, allocated on the heap.
class MyClass {
- // Member variables
+
+// Member variables
var memberInt : int;
var memberBool : bool = true;
- // Classes have default constructors that don't need to be coded (see below)
- // Our explicitly defined constructor
- proc MyClass( val : real ){
- this.memberInt = ceil( val ): int;
+// Explicitly defined initializer.
+// We also get the compiler-generated initializer, with one argument per field.
+// Note that soon there will be no compiler-generated initializer when we
+// define any initializer(s) explicitly.
+ proc init(val : real) {
+ this.memberInt = ceil(val): int;
}
- // Our explicitly defined destructor
- proc ~MyClass( ){
- writeln( "MyClass Destructor called ", (this.memberInt, this.memberBool) );
+// Explicitly defined deinitializer.
+// If we did not write one, we would get the compiler-generated deinitializer,
+// which has an empty body.
+ proc deinit() {
+ writeln("MyClass deinitializer called ", (this.memberInt, this.memberBool));
}
- // Class methods
- proc setMemberInt( val: int ){
+// Class methods.
+ proc setMemberInt(val: int) {
this.memberInt = val;
}
- proc setMemberBool( val: bool ){
+ proc setMemberBool(val: bool) {
this.memberBool = val;
}
- proc getMemberInt( ): int{
+ proc getMemberInt(): int{
return this.memberInt;
}
- proc getMemberBool( ): bool {
+ proc getMemberBool(): bool {
return this.memberBool;
}
-
-}
-
-// Construct using default constructor, using default values
-var myObject = new MyClass( 10 );
- myObject = new MyClass( memberInt = 10 ); // Equivalent
-writeln( myObject.getMemberInt( ) );
-// ... using our values
-var myDiffObject = new MyClass( -1, true );
- myDiffObject = new MyClass( memberInt = -1,
- memberBool = true ); // Equivalent
-writeln( myDiffObject );
-
-// Construct using written constructor
-var myOtherObject = new MyClass( 1.95 );
- myOtherObject = new MyClass( val = 1.95 ); // Equivalent
-writeln( myOtherObject.getMemberInt( ) );
-
-// We can define an operator on our class as well but
-// the definition has to be outside the class definition
-proc +( A : MyClass, B : MyClass) : MyClass {
- return new MyClass( memberInt = A.getMemberInt( ) + B.getMemberInt( ),
- memberBool = A.getMemberBool( ) || B.getMemberBool( ) );
+} // end MyClass
+
+// Call compiler-generated initializer, using default value for memberBool.
+var myObject = new MyClass(10);
+ myObject = new MyClass(memberInt = 10); // Equivalent
+writeln(myObject.getMemberInt());
+
+// Same, but provide a memberBool value explicitly.
+var myDiffObject = new MyClass(-1, true);
+ myDiffObject = new MyClass(memberInt = -1,
+ memberBool = true); // Equivalent
+writeln(myDiffObject);
+
+// Call the initializer we wrote.
+var myOtherObject = new MyClass(1.95);
+ myOtherObject = new MyClass(val = 1.95); // Equivalent
+writeln(myOtherObject.getMemberInt());
+
+// We can define an operator on our class as well, but
+// the definition has to be outside the class definition.
+proc +(A : MyClass, B : MyClass) : MyClass {
+ return new MyClass(memberInt = A.getMemberInt() + B.getMemberInt(),
+ memberBool = A.getMemberBool() || B.getMemberBool());
}
var plusObject = myObject + myDiffObject;
-writeln( plusObject );
+writeln(plusObject);
-// Destruction
+// Destruction.
delete myObject;
delete myDiffObject;
delete myOtherObject;
@@ -710,350 +774,365 @@ class MyChildClass : MyClass {
var memberComplex: complex;
}
-// Generic Classes
+// Here's an example of generic classes.
class GenericClass {
type classType;
var classDomain: domain(1);
var classArray: [classDomain] classType;
- // Explicit constructor
- proc GenericClass( type classType, elements : int ){
+// Explicit constructor.
+ proc GenericClass(type classType, elements : int) {
this.classDomain = {1..#elements};
}
- // Copy constructor
- // Note: We still have to put the type as an argument, but we can
- // default to the type of the other object using the query (?) operator
- // Further, we can take advantage of this to allow our copy constructor
- // to copy classes of different types and cast on the fly
- proc GenericClass( other : GenericClass(?otherType),
- type classType = otherType ) {
+// Copy constructor.
+// Note: We still have to put the type as an argument, but we can
+// default to the type of the other object using the query (?) operator.
+// Further, we can take advantage of this to allow our copy constructor
+// to copy classes of different types and cast on the fly.
+ proc GenericClass(other : GenericClass(?otherType),
+ type classType = otherType) {
this.classDomain = other.classDomain;
// Copy and cast
- for idx in this.classDomain do this[ idx ] = other[ idx ] : classType;
+ for idx in this.classDomain do this[idx] = other[idx] : classType;
}
- // Define bracket notation on a GenericClass
- // object so it can behave like a normal array
- // i.e. objVar[ i ] or objVar( i )
- proc this( i : int ) ref : classType {
- return this.classArray[ i ];
+// Define bracket notation on a GenericClass
+// object so it can behave like a normal array
+// i.e. objVar[i] or objVar(i)
+ proc this(i : int) ref : classType {
+ return this.classArray[i];
}
- // Define an implicit iterator for the class
- // to yield values from the array to a loop
- // i.e. for i in objVar do ....
- iter these( ) ref : classType {
+// Define an implicit iterator for the class
+// to yield values from the array to a loop
+// i.e. for i in objVar do ...
+ iter these() ref : classType {
for i in this.classDomain do
yield this[i];
}
+} // end GenericClass
-}
-
-var realList = new GenericClass( real, 10 );
// We can assign to the member array of the object using the bracket
-// notation that we defined ( proc this( i: int ){ ... } )
+// notation that we defined.
+var realList = new GenericClass(real, 10);
for i in realList.classDomain do realList[i] = i + 1.0;
+
// We can iterate over the values in our list with the iterator
-// we defined ( iter these( ){ ... } )
-for value in realList do write( value, ", " );
-writeln( );
+// we defined.
+for value in realList do write(value, ", ");
+writeln();
+
+// Make a copy of realList using the copy constructor.
+var copyList = new GenericClass(realList);
+for value in copyList do write(value, ", ");
+writeln();
-// Make a copy of realList using the copy constructor
-var copyList = new GenericClass( realList );
-for value in copyList do write( value, ", " );
-writeln( );
+// Make a copy of realList and change the type, also using the copy constructor.
+var copyNewTypeList = new GenericClass(realList, int);
+for value in copyNewTypeList do write(value, ", ");
+writeln();
-// Make a copy of realList and change the type, also using the copy constructor
-var copyNewTypeList = new GenericClass( realList, int );
-for value in copyNewTypeList do write( value, ", " );
-writeln( );
+
+// Modules
// Modules are Chapel's way of managing name spaces.
// The files containing these modules do not need to be named after the modules
// (as in Java), but files implicitly name modules.
-// In this case, this file implicitly names the 'learnchapel' module
+// For example, this file implicitly names the learnChapelInYMinutes module
module OurModule {
- // We can use modules inside of other modules.
- use Time; // Time is one of the standard modules.
- // We'll use this procedure in the parallelism section.
- proc countdown( seconds: int ){
+// We can use modules inside of other modules.
+// Time is one of the standard modules.
+ use Time;
+
+// We'll use this procedure in the parallelism section.
+ proc countdown(seconds: int) {
for i in 1..seconds by -1 {
- writeln( i );
- sleep( 1 );
+ writeln(i);
+ sleep(1);
}
}
- // Submodules of OurModule
- // It is possible to create arbitrarily deep module nests.
+// It is possible to create arbitrarily deep module nests.
+// i.e. submodules of OurModule
module ChildModule {
- proc foo(){
- writeln( "ChildModule.foo()");
+ proc foo() {
+ writeln("ChildModule.foo()");
}
}
module SiblingModule {
- proc foo(){
- writeln( "SiblingModule.foo()" );
+ proc foo() {
+ writeln("SiblingModule.foo()");
}
}
} // end OurModule
// Using OurModule also uses all the modules it uses.
-// Since OurModule uses Time, we also use time.
+// Since OurModule uses Time, we also use Time.
use OurModule;
-// At this point we have not used ChildModule or SiblingModule so their symbols
-// (i.e. foo ) are not available to us.
-// However, the module names are, and we can explicitly call foo() through them.
-SiblingModule.foo(); // Calls SiblingModule.foo()
-
-// Super explicit naming.
-OurModule.ChildModule.foo(); // Calls ChildModule.foo()
+// At this point we have not used ChildModule or SiblingModule so
+// their symbols (i.e. foo) are not available to us. However, the module
+// names are available, and we can explicitly call foo() through them.
+SiblingModule.foo();
+OurModule.ChildModule.foo();
+// Now we use ChildModule, enabling unqualified calls.
use ChildModule;
-foo(); // Less explicit call on ChildModule.foo()
+foo();
-// We can declare a main procedure
-// Note: all the code above main still gets executed.
-proc main(){
+// Parallelism
- // Parallelism
- // In other languages, parallelism is typically done with
- // complicated libraries and strange class structure hierarchies.
- // Chapel has it baked right into the language.
+// In other languages, parallelism is typically done with
+// complicated libraries and strange class structure hierarchies.
+// Chapel has it baked right into the language.
+
+// We can declare a main procedure, but all the code above main still gets
+// executed.
+proc main() {
+
+// A begin statement will spin the body of that statement off
+// into one new task.
+// A sync statement will ensure that the progress of the main
+// task will not progress until the children have synced back up.
- // A begin statement will spin the body of that statement off
- // into one new task.
- // A sync statement will ensure that the progress of the main
- // task will not progress until the children have synced back up.
sync {
begin { // Start of new task's body
var a = 0;
for i in 1..1000 do a += 1;
- writeln( "Done: ", a);
+ writeln("Done: ", a);
} // End of new tasks body
- writeln( "spun off a task!");
+ writeln("spun off a task!");
}
- writeln( "Back together" );
+ writeln("Back together");
- proc printFibb( n: int ){
- writeln( "fibonacci(",n,") = ", fibonacci( n ) );
+ proc printFibb(n: int) {
+ writeln("fibonacci(",n,") = ", fibonacci(n));
}
- // A cobegin statement will spin each statement of the body into one new task
+// A cobegin statement will spin each statement of the body into one new
+// task. Notice here that the prints from each statement may happen in any
+// order.
cobegin {
- printFibb( 20 ); // new task
- printFibb( 10 ); // new task
- printFibb( 5 ); // new task
+ printFibb(20); // new task
+ printFibb(10); // new task
+ printFibb(5); // new task
{
// This is a nested statement body and thus is a single statement
- // to the parent statement and is executed by a single task
- writeln( "this gets" );
- writeln( "executed as" );
- writeln( "a whole" );
+ // to the parent statement, executed by a single task.
+ writeln("this gets");
+ writeln("executed as");
+ writeln("a whole");
}
}
- // Notice here that the prints from each statement may happen in any order.
- // Coforall loop will create a new task for EACH iteration
+// A coforall loop will create a new task for EACH iteration.
+// Again we see that prints happen in any order.
+// NOTE: coforall should be used only for creating tasks!
+// Using it to iterating over a structure is very a bad idea!
var num_tasks = 10; // Number of tasks we want
coforall taskID in 1..#num_tasks {
- writeln( "Hello from task# ", taskID );
+ writeln("Hello from task# ", taskID);
}
- // Again we see that prints happen in any order.
- // NOTE! coforall should be used only for creating tasks!
- // Using it to iterating over a structure is very a bad idea!
- // forall loops are another parallel loop, but only create a smaller number
- // of tasks, specifically --dataParTasksPerLocale=number of task
+// forall loops are another parallel loop, but only create a smaller number
+// of tasks, specifically --dataParTasksPerLocale= number of tasks.
forall i in 1..100 {
- write( i, ", ");
+ write(i, ", ");
}
- writeln( );
- // Here we see that there are sections that are in order, followed by
- // a section that would not follow ( e.g. 1, 2, 3, 7, 8, 9, 4, 5, 6, ).
- // This is because each task is taking on a chunk of the range 1..10
- // (1..3, 4..6, or 7..9) doing that chunk serially, but each task happens
- // in parallel.
- // Your results may depend on your machine and configuration
-
- // For both the forall and coforall loops, the execution of the
- // parent task will not continue until all the children sync up.
-
- // forall loops are particularly useful for parallel iteration over arrays.
- // Lets run an experiment to see how much faster a parallel loop is
+ writeln();
+
+// Here we see that there are sections that are in order, followed by
+// a section that would not follow (e.g. 1, 2, 3, 7, 8, 9, 4, 5, 6,).
+// This is because each task is taking on a chunk of the range 1..10
+// (1..3, 4..6, or 7..9) doing that chunk serially, but each task happens
+// in parallel. Your results may depend on your machine and configuration
+
+// For both the forall and coforall loops, the execution of the
+// parent task will not continue until all the children sync up.
+
+// forall loops are particularly useful for parallel iteration over arrays.
+// Lets run an experiment to see how much faster a parallel loop is
use Time; // Import the Time module to use Timer objects
var timer: Timer;
var myBigArray: [{1..4000,1..4000}] real; // Large array we will write into
- // Serial Experiment
- timer.start( ); // Start timer
+// Serial Experiment:
+ timer.start(); // Start timer
for (x,y) in myBigArray.domain { // Serial iteration
myBigArray[x,y] = (x:real) / (y:real);
}
- timer.stop( ); // Stop timer
- writeln( "Serial: ", timer.elapsed( ) ); // Print elapsed time
- timer.clear( ); // Clear timer for parallel loop
+ timer.stop(); // Stop timer
+ writeln("Serial: ", timer.elapsed()); // Print elapsed time
+ timer.clear(); // Clear timer for parallel loop
- // Parallel Experiment
- timer.start( ); // start timer
+// Parallel Experiment:
+ timer.start(); // start timer
forall (x,y) in myBigArray.domain { // Parallel iteration
myBigArray[x,y] = (x:real) / (y:real);
}
- timer.stop( ); // Stop timer
- writeln( "Parallel: ", timer.elapsed( ) ); // Print elapsed time
- timer.clear( );
- // You may have noticed that (depending on how many cores you have)
- // that the parallel loop went faster than the serial loop
-
- // The bracket style loop-expression described
- // much earlier implicitly uses a forall loop.
- [ val in myBigArray ] val = 1 / val; // Parallel operation
-
- // Atomic variables, common to many languages, are ones whose operations
- // occur uninterrupted. Multiple threads can both modify atomic variables
- // and can know that their values are safe.
- // Chapel atomic variables can be of type bool, int, uint, and real.
+ timer.stop(); // Stop timer
+ writeln("Parallel: ", timer.elapsed()); // Print elapsed time
+ timer.clear();
+
+// You may have noticed that (depending on how many cores you have)
+// the parallel loop went faster than the serial loop.
+
+// The bracket style loop-expression described
+// much earlier implicitly uses a forall loop.
+ [val in myBigArray] val = 1 / val; // Parallel operation
+
+// Atomic variables, common to many languages, are ones whose operations
+// occur uninterrupted. Multiple threads can therefore modify atomic
+// variables and can know that their values are safe.
+// Chapel atomic variables can be of type bool, int,
+// uint, and real.
var uranium: atomic int;
- uranium.write( 238 ); // atomically write a variable
- writeln( uranium.read() ); // atomically read a variable
+ uranium.write(238); // atomically write a variable
+ writeln(uranium.read()); // atomically read a variable
- // operations are described as functions, you could define your own operators.
- uranium.sub( 3 ); // atomically subtract a variable
- writeln( uranium.read() );
+// Atomic operations are described as functions, so you can define your own.
+ uranium.sub(3); // atomically subtract a variable
+ writeln(uranium.read());
var replaceWith = 239;
- var was = uranium.exchange( replaceWith );
- writeln( "uranium was ", was, " but is now ", replaceWith );
+ var was = uranium.exchange(replaceWith);
+ writeln("uranium was ", was, " but is now ", replaceWith);
var isEqualTo = 235;
- if ( uranium.compareExchange( isEqualTo, replaceWith ) ) {
- writeln( "uranium was equal to ", isEqualTo,
- " so replaced value with ", replaceWith );
+ if uranium.compareExchange(isEqualTo, replaceWith) {
+ writeln("uranium was equal to ", isEqualTo,
+ " so replaced value with ", replaceWith);
} else {
- writeln( "uranium was not equal to ", isEqualTo,
- " so value stays the same... whatever it was" );
+ writeln("uranium was not equal to ", isEqualTo,
+ " so value stays the same... whatever it was");
}
sync {
begin { // Reader task
- writeln( "Reader: waiting for uranium to be ", isEqualTo );
- uranium.waitFor( isEqualTo );
- writeln( "Reader: uranium was set (by someone) to ", isEqualTo );
+ writeln("Reader: waiting for uranium to be ", isEqualTo);
+ uranium.waitFor(isEqualTo);
+ writeln("Reader: uranium was set (by someone) to ", isEqualTo);
}
begin { // Writer task
- writeln( "Writer: will set uranium to the value ", isEqualTo, " in..." );
- countdown( 3 );
- uranium.write( isEqualTo );
+ writeln("Writer: will set uranium to the value ", isEqualTo, " in...");
+ countdown(3);
+ uranium.write(isEqualTo);
}
}
- // sync vars have two states: empty and full.
- // If you read an empty variable or write a full variable, you are waited
- // until the variable is full or empty again
+// sync variables have two states: empty and full.
+// If you read an empty variable or write a full variable, you are waited
+// until the variable is full or empty again.
var someSyncVar$: sync int; // varName$ is a convention not a law.
sync {
begin { // Reader task
- writeln( "Reader: waiting to read." );
+ writeln("Reader: waiting to read.");
var read_sync = someSyncVar$;
- writeln( "Reader: value is ", read_sync );
+ writeln("Reader: value is ", read_sync);
}
begin { // Writer task
- writeln( "Writer: will write in..." );
- countdown( 3 );
+ writeln("Writer: will write in...");
+ countdown(3);
someSyncVar$ = 123;
}
}
- // single vars can only be written once. A read on an unwritten single results
- // in a wait, but when the variable has a value it can be read indefinitely
+// single vars can only be written once. A read on an unwritten single
+// results in a wait, but when the variable has a value it can be read
+// indefinitely.
var someSingleVar$: single int; // varName$ is a convention not a law.
sync {
begin { // Reader task
- writeln( "Reader: waiting to read." );
+ writeln("Reader: waiting to read.");
for i in 1..5 {
var read_single = someSingleVar$;
- writeln( "Reader: iteration ", i,", and the value is ", read_single );
+ writeln("Reader: iteration ", i,", and the value is ", read_single);
}
}
begin { // Writer task
- writeln( "Writer: will write in..." );
- countdown( 3 );
+ writeln("Writer: will write in...");
+ countdown(3);
someSingleVar$ = 5; // first and only write ever.
}
}
- // Heres an example of using atomics and a synch variable to create a
- // count-down mutex (also known as a multiplexer)
+// Here's an example using atomics and a sync variable to create a
+// count-down mutex (also known as a multiplexer).
var count: atomic int; // our counter
var lock$: sync bool; // the mutex lock
- count.write( 2 ); // Only let two tasks in at a time.
- lock$.writeXF( true ); // Set lock$ to full (unlocked)
- // Note: The value doesnt actually matter, just the state
+ count.write(2); // Only let two tasks in at a time.
+ lock$.writeXF(true); // Set lock$ to full (unlocked)
+ // Note: The value doesn't actually matter, just the state
// (full:unlocked / empty:locked)
// Also, writeXF() fills (F) the sync var regardless of its state (X)
coforall task in 1..#5 { // Generate tasks
// Create a barrier
- do{
+ do {
lock$; // Read lock$ (wait)
- }while ( count.read() < 1 ); // Keep waiting until a spot opens up
+ } while (count.read() < 1); // Keep waiting until a spot opens up
count.sub(1); // decrement the counter
- lock$.writeXF( true ); // Set lock$ to full (signal)
+ lock$.writeXF(true); // Set lock$ to full (signal)
// Actual 'work'
- writeln( "Task #", task, " doing work." );
- sleep( 2 );
+ writeln("Task #", task, " doing work.");
+ sleep(2);
- count.add( 1 ); // Increment the counter
- lock$.writeXF( true ); // Set lock$ to full (signal)
+ count.add(1); // Increment the counter
+ lock$.writeXF(true); // Set lock$ to full (signal)
}
- // we can define the operations + * & | ^ && || min max minloc maxloc
- // over an entire array using scans and reductions
- // Reductions apply the operation over the entire array and
- // result in a single value
+// We can define the operations + * & | ^ && || min max minloc maxloc
+// over an entire array using scans and reductions.
+// Reductions apply the operation over the entire array and
+// result in a scalar value.
var listOfValues: [1..10] int = [15,57,354,36,45,15,456,8,678,2];
var sumOfValues = + reduce listOfValues;
var maxValue = max reduce listOfValues; // 'max' give just max value
- // 'maxloc' gives max value and index of the max value
- // Note: We have to zip the array and domain together with the zip iterator
+// maxloc gives max value and index of the max value.
+// Note: We have to zip the array and domain together with the zip iterator.
var (theMaxValue, idxOfMax) = maxloc reduce zip(listOfValues,
listOfValues.domain);
- writeln( (sumOfValues, maxValue, idxOfMax, listOfValues[ idxOfMax ] ) );
+ writeln((sumOfValues, maxValue, idxOfMax, listOfValues[idxOfMax]));
- // Scans apply the operation incrementally and return an array of the
- // value of the operation at that index as it progressed through the
- // array from array.domain.low to array.domain.high
+// Scans apply the operation incrementally and return an array with the
+// values of the operation at that index as it progressed through the
+// array from array.domain.low to array.domain.high.
var runningSumOfValues = + scan listOfValues;
var maxScan = max scan listOfValues;
- writeln( runningSumOfValues );
- writeln( maxScan );
+ writeln(runningSumOfValues);
+ writeln(maxScan);
} // end main()
```
Who is this tutorial for?
-------------------------
-This tutorial is for people who want to learn the ropes of chapel without having to hear about what fiber mixture the ropes are, or how they were braided, or how the braid configurations differ between one another.
-It won't teach you how to develop amazingly performant code, and it's not exhaustive.
-Refer to the [language specification](http://chapel.cray.com/language.html) and the [module documentation](http://chapel.cray.com/docs/latest/) for more details.
+This tutorial is for people who want to learn the ropes of chapel without
+having to hear about what fiber mixture the ropes are, or how they were
+braided, or how the braid configurations differ between one another. It won't
+teach you how to develop amazingly performant code, and it's not exhaustive.
+Refer to the [language specification](https://chapel-lang.org/docs/latest/language/spec.html) and
+the [module documentation](https://chapel-lang.org/docs/latest/) for more
+details.
-Occasionally check back here and on the [Chapel site](http://chapel.cray.com) to see if more topics have been added or more tutorials created.
+Occasionally check back here and on the [Chapel site](https://chapel-lang.org)
+to see if more topics have been added or more tutorials created.
### What this tutorial is lacking:
- * Exposition of the [standard modules](http://chapel.cray.com/docs/latest/modules/modules.html)
+ * Exposition of the [standard modules](https://chapel-lang.org/docs/latest/modules/standard.html)
* Multiple Locales (distributed memory system)
* Records
* Parallel iterators
@@ -1061,27 +1140,36 @@ Occasionally check back here and on the [Chapel site](http://chapel.cray.com) to
Your input, questions, and discoveries are important to the developers!
-----------------------------------------------------------------------
-The Chapel language is still in-development (version 1.12.0), so there are occasional hiccups with performance and language features.
-The more information you give the Chapel development team about issues you encounter or features you would like to see, the better the language becomes.
-Feel free to email the team and other developers through the [sourceforge email lists](https://sourceforge.net/p/chapel/mailman).
+The Chapel language is still in active development, so there are
+occasional hiccups with performance and language features. The more information
+you give the Chapel development team about issues you encounter or features you
+would like to see, the better the language becomes.
+There are several ways to interact with the developers:
++ [Gitter chat](https://gitter.im/chapel-lang/chapel)
++ [sourceforge email lists](https://sourceforge.net/p/chapel/mailman)
-If you're really interested in the development of the compiler or contributing to the project,
-[check out the master GitHub repository](https://github.com/chapel-lang/chapel).
+If you're really interested in the development of the compiler or contributing
+to the project, [check out the master GitHub repository](https://github.com/chapel-lang/chapel).
It is under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0).
Installing the Compiler
-----------------------
+[The Official Chapel documentation details how to download and compile the Chapel compiler.](https://chapel-lang.org/docs/usingchapel/QUICKSTART.html)
+
Chapel can be built and installed on your average 'nix machine (and cygwin).
[Download the latest release version](https://github.com/chapel-lang/chapel/releases/)
and it's as easy as
- 1. `tar -xvf chapel-1.12.0.tar.gz`
- 2. `cd chapel-1.12.0`
- 3. `make`
- 4. `source util/setchplenv.bash # or .sh or .csh or .fish`
+ 1. `tar -xvf chapel-<VERSION>.tar.gz`
+ 2. `cd chapel-<VERSION>`
+ 3. `source util/setchplenv.bash # or .sh or .csh or .fish`
+ 4. `make`
+ 5. `make check # optional`
-You will need to `source util/setchplenv.EXT` from within the Chapel directory (`$CHPL_HOME`) every time your terminal starts so it's suggested that you drop that command in a script that will get executed on startup (like .bashrc).
+You will need to `source util/setchplenv.EXT` from within the Chapel directory
+(`$CHPL_HOME`) every time your terminal starts so it's suggested that you drop
+that command in a script that will get executed on startup (like .bashrc).
Chapel is easily installed with Brew for OS X
@@ -1097,7 +1185,10 @@ Builds like other compilers:
Notable arguments:
- * `--fast`: enables a number of optimizations and disables array bounds checks. Should only enable when application is stable.
- * `--set <Symbol Name>=<Value>`: set config param `<Symbol Name>` to `<Value>` at compile-time.
- * `--main-module <Module Name>`: use the main() procedure found in the module `<Module Name>` as the executable's main.
+ * `--fast`: enables a number of optimizations and disables array bounds
+ checks. Should only enable when application is stable.
+ * `--set <Symbol Name>=<Value>`: set config param `<Symbol Name>` to `<Value>`
+ at compile-time.
+ * `--main-module <Module Name>`: use the main() procedure found in the module
+ `<Module Name>` as the executable's main.
* `--module-dir <Directory>`: includes `<Directory>` in the module search path.
diff --git a/citron.html.markdown b/citron.html.markdown
new file mode 100644
index 00000000..bd3c398c
--- /dev/null
+++ b/citron.html.markdown
@@ -0,0 +1,212 @@
+---
+language: citron
+filename: learncitron.ctr
+contributors:
+ - ["AnotherTest", ""]
+lang: en-us
+---
+```ruby
+# Comments start with a '#'
+# All comments encompass a single line
+
+###########################################
+## 1. Primitive Data types and Operators
+###########################################
+
+# You have numbers
+3. # 3
+
+# Numbers are all doubles in interpreted mode
+
+# Mathematical operator precedence is not respected.
+# binary 'operators' are evaluated in ltr order
+1 + 1. # 2
+8 - 4. # 4
+10 + 2 * 3. # 36
+
+# Division is always floating division
+35 / 2 # 17.5.
+
+# Integer division is non-trivial, you may use floor
+(35 / 2) floor # 17.
+
+# Booleans are primitives
+True.
+False.
+
+# Boolean messages
+True not. # False
+False not. # True
+1 = 1. # True
+1 !=: 1. # False
+1 < 10. # True
+
+# Here, `not` is a unary message to the object `Boolean`
+# Messages are comparable to instance method calls
+# And they have three different forms:
+# 1. Unary messages: Length > 1, and they take no arguments:
+ False not.
+# 2. Binary Messages: Length = 1, and they take a single argument:
+ False & True.
+# 3. Keyword messages: must have at least one ':', they take as many arguments
+# as they have `:` s
+ False either: 1 or: 2. # 2
+
+# Strings
+'This is a string'.
+'There are no character types exposed to the user'.
+# "You cannot use double quotes for strings" <- Error
+
+# Strins can be summed
+'Hello, ' + 'World!'. # 'Hello, World!'
+
+# Strings allow access to their characters
+'This is a beautiful string' at: 0. # 'T'
+
+###########################################
+## intermission: Basic Assignment
+###########################################
+
+# You may assign values to the current scope:
+var name is value. # assignes `value` into `name`
+
+# You may also assign values into the current object's namespace
+my name is value. # assigns `value` into the current object's `name` property
+
+# Please note that these names are checked at compile (read parse if in interpreted mode) time
+# but you may treat them as dynamic assignments anyway
+
+###########################################
+## 2. Lists(Arrays?) and Tuples
+###########################################
+
+# Arrays are allowed to have multiple types
+Array new < 1 ; 2 ; 'string' ; Nil. # Array new < 1 ; 2 ; 'string' ; Nil
+
+# Tuples act like arrays, but are immutable.
+# Any shenanigans degrade them to arrays, however
+[1, 2, 'string']. # [1, 2, 'string']
+
+# They can interoperate with arrays
+[1, 'string'] + (Array new < 'wat'). # Array new < 1 ; 'string' ; 'wat'
+
+# Indexing into them
+[1, 2, 3] at: 1. # 2
+
+# Some array operations
+var arr is Array new < 1 ; 2 ; 3.
+
+arr head. # 1
+arr tail. # Array new < 2 ; 3.
+arr init. # Array new < 1 ; 2.
+arr last. # 3
+arr push: 4. # Array new < 1 ; 2 ; 3 ; 4.
+arr pop. # 4
+arr pop: 1. # 2, `arr` is rebound to Array new < 1 ; 3.
+
+# List comprehensions
+[x * 2 + y,, arr, arr + [4, 5],, x > 1]. # Array ← 7 ; 9 ; 10 ; 11
+# fresh variable names are bound as they are encountered,
+# so `x` is bound to the values in `arr`
+# and `y` is bound to the values in `arr + [4, 5]`
+#
+# The general format is: [expr,, bindings*,, predicates*]
+
+
+####################################
+## 3. Functions
+####################################
+
+# A simple function that takes two variables
+var add is {:a:b ^a + b.}.
+
+# this function will resolve all its names except the formal arguments
+# in the context it is called in.
+
+# Using the function
+add applyTo: 3 and: 5. # 8
+add applyAll: [3, 5]. # 8
+
+# Also a (customizable -- more on this later) pseudo-operator allows for a shorthand
+# of function calls
+# By default it is REF[args]
+
+add[3, 5]. # 8
+
+# To customize this behaviour, you may simply use a compiler pragma:
+#:callShorthand ()
+
+# And then you may use the specified operator.
+# Note that the allowed 'operator' can only be made of any of these: []{}()
+# And you may mix-and-match (why would anyone do that?)
+
+add(3, 5). # 8
+
+# You may also use functions as operators in the following way:
+
+3 `add` 5. # 8
+# This call binds as such: add[(3), 5]
+# because the default fixity is left, and the default precedance is 1
+
+# You may change the precedence/fixity of this operator with a pragma
+#:declare infixr 1 add
+
+3 `add` 5. # 8
+# now this binds as such: add[3, (5)].
+
+# There is another form of functions too
+# So far, the functions were resolved in a dynamic fashion
+# But a lexically scoped block is also possible
+var sillyAdd is {\:x:y add[x,y].}.
+
+# In these blocks, you are not allowed to declare new variables
+# Except with the use of Object::'letEqual:in:`
+# And the last expression is implicitly returned.
+
+# You may also use a shorthand for lambda expressions
+var mul is \:x:y x * y.
+
+# These capture the named bindings that are not present in their
+# formal parameters, and retain them. (by ref)
+
+###########################################
+## 5. Control Flow
+###########################################
+
+# inline conditional-expressions
+var citron is 1 = 1 either: 'awesome' or: 'awful'. # citron is 'awesome'
+
+# multiple lines is fine too
+var citron is 1 = 1
+ either: 'awesome'
+ or: 'awful'.
+
+# looping
+10 times: {:x
+ Pen writeln: x.
+}. # 10. -- side effect: 10 lines in stdout, with numbers 0 through 9 in them
+
+# Citron properly supports tail-call recursion in lexically scoped blocks
+# So use those to your heart's desire
+
+# mapping most data structures is as simple as `fmap:`
+[1, 2, 3, 4] fmap: \:x x + 1. # [2, 3, 4, 5]
+
+# You can use `foldl:accumulator:` to fold a list/tuple
+[1, 2, 3, 4] foldl: (\:acc:x acc * 2 + x) accumulator: 4. # 90
+
+# That expression is the same as
+(2 * (2 * (2 * (2 * 4 + 1) + 2) + 3) + 4)
+
+###################################
+## 6. IO
+###################################
+
+# IO is quite simple
+# With `Pen` being used for console output
+# and Program::'input' and Program::'waitForInput' being used for console input
+
+Pen writeln: 'Hello, ocean!' # prints 'Hello, ocean!\n' to the terminal
+
+Pen writeln: Program waitForInput. # reads a line and prints it back
+```
diff --git a/clojure-macros.html.markdown b/clojure-macros.html.markdown
index d74f77cf..6154d570 100644
--- a/clojure-macros.html.markdown
+++ b/clojure-macros.html.markdown
@@ -99,13 +99,13 @@ You'll want to be familiar with Clojure. Make sure you understand everything in
(list x) ; -> (4)
;; You can use # within ` to produce a gensym for each symbol automatically
-(defmacro define-x-hygenically []
+(defmacro define-x-hygienically []
`(do
(def x# 2)
(list x#)))
(def x 4)
-(define-x-hygenically) ; -> (2)
+(define-x-hygienically) ; -> (2)
(list x) ; -> (4)
;; It's typical to use helper functions with macros. Let's create a few to
@@ -131,7 +131,7 @@ You'll want to be familiar with Clojure. Make sure you understand everything in
; However, we'll need to make it a macro if we want it to be run at compile time
(defmacro inline-2 [form]
- (inline-2-helper form)))
+ (inline-2-helper form))
(macroexpand '(inline-2 (1 + (3 / 2) - (1 / 2) + 1)))
; -> (+ (- (+ 1 (/ 3 2)) (/ 1 2)) 1)
@@ -142,11 +142,8 @@ You'll want to be familiar with Clojure. Make sure you understand everything in
### Further Reading
-Writing Macros from [Clojure for the Brave and True](http://www.braveclojure.com/)
-[http://www.braveclojure.com/writing-macros/](http://www.braveclojure.com/writing-macros/)
+[Writing Macros](http://www.braveclojure.com/writing-macros/)
-Official docs
-[http://clojure.org/macros](http://clojure.org/macros)
+[Official docs](http://clojure.org/macros)
-When to use macros?
-[http://dunsmor.com/lisp/onlisp/onlisp_12.html](http://dunsmor.com/lisp/onlisp/onlisp_12.html)
+[When to use macros?](https://lispcast.com/when-to-use-a-macro/)
diff --git a/clojure.html.markdown b/clojure.html.markdown
index bfe8d79e..20812a9b 100644
--- a/clojure.html.markdown
+++ b/clojure.html.markdown
@@ -150,7 +150,7 @@ x ; => 1
; You can also use this shorthand to create functions:
(def hello2 #(str "Hello " %1))
-(hello2 "Fanny") ; => "Hello Fanny"
+(hello2 "Julie") ; => "Hello Julie"
; You can have multi-variadic functions, too
(defn hello3
@@ -292,14 +292,14 @@ keymap ; => {:a 1, :b 2, :c 3}
; When you are in a situation where you want more freedom as where to
; put the result of previous data transformations in an
; expression, you can use the as-> macro. With it, you can assign a
-; specific name to transformations' output ans use it as a
+; specific name to transformations' output and use it as a
; placeholder in your chained expressions:
(as-> [1 2 3] input
(map inc input);=> You can use last transform's output at the last position
(nth input 2) ;=> and at the second position, in the same expression
- (conj [4 5 6] input [8 9 10])) ;=> or in the middle !
-
+ (conj [4 5 6] input 8 9 10)) ;=> or in the middle !
+ ; Result: [4 5 6 4 8 9 10]
; Modules
@@ -416,3 +416,6 @@ Clojuredocs.org has documentation with examples for most core functions:
Clojure-doc.org (yes, really) has a number of getting started articles:
[http://clojure-doc.org/](http://clojure-doc.org/)
+
+Clojure for the Brave and True has a great introduction to Clojure and a free online version:
+[https://www.braveclojure.com/clojure-for-the-brave-and-true/](https://www.braveclojure.com/clojure-for-the-brave-and-true/)
diff --git a/cmake.html.markdown b/cmake.html.markdown
index 45cf0585..9ea68a42 100644
--- a/cmake.html.markdown
+++ b/cmake.html.markdown
@@ -1,35 +1,36 @@
---
-language: cmake
+category: tool
+tool: cmake
contributors:
- ["Bruno Alano", "https://github.com/brunoalano"]
filename: CMake
---
-CMake is a cross-platform, open-source build system. This tool will allow you
-to test, compile and create packages of your source code.
+CMake is a cross-platform, open-source build system. This tool allows you to test,
+compile, and create packages of your source code.
-The problem that CMake tries to solve is the problem of Makefiles and
-Autoconfigure on cross-platforms (different make interpreters have different
-command) and the ease-of-use on linking 3rd party libraries.
+The problem that CMake tries to solve is the problem of Makefiles and
+Autoconfigure on cross-platforms (different make interpreters have different
+commands) and the ease-of-use on linking 3rd party libraries.
-CMake is an extensible, open-source system that manages the build process in
-an operating system and compiler-independent manner. Unlike many
-cross-platform systems, CMake is designed to be used in conjunction with the
+CMake is an extensible, open-source system that manages the build process in
+an operating system and compiler-agnostic manner. Unlike many
+cross-platform systems, CMake is designed to be used in conjunction with the
native build environment. Simple configuration files placed in each source
-directory (called CMakeLists.txt files) are used to generate standard build
-files (e.g., makefiles on Unix and projects/workspaces in Windows MSVC) which
+directory (called CMakeLists.txt files) are used to generate standard build
+files (e.g., makefiles on Unix and projects/workspaces in Windows MSVC) which
are used in the usual way.
```cmake
# In CMake, this is a comment
-# To run our code, we will use these steps:
+# To run our code, please perform the following commands:
# - mkdir build && cd build
# - cmake ..
# - make
#
-# With those steps, we will follow the best pratice to compile into a subdir
-# and the second line will request to CMake to generate a new OS-dependant
+# With those steps, we will follow the best practice to compile into a subdir
+# and the second line will request to CMake to generate a new OS-dependent
# Makefile. Finally, run the native Make command.
#------------------------------------------------------------------------------
@@ -44,22 +45,22 @@ cmake_minimum_required (VERSION 2.8)
# Raises a FATAL_ERROR if version < 2.8
cmake_minimum_required (VERSION 2.8 FATAL_ERROR)
-# We setup the name for our project. After we do that, this will change some
-# directories naming convention generated by CMake. We can send the LANG of
-# code as second param
+# We define the name of our project, and this changes some directories
+# naming convention generated by CMake. We can send the LANG of code
+# as the second param
project (learncmake C)
# Set the project source dir (just convention)
set( LEARN_CMAKE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
set( LEARN_CMAKE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} )
-# It's useful to setup the current version of our code in the build system
+# It's useful to set up the current version of our code in the build system
# using a `semver` style
set (LEARN_CMAKE_VERSION_MAJOR 1)
set (LEARN_CMAKE_VERSION_MINOR 0)
set (LEARN_CMAKE_VERSION_PATCH 0)
-# Send the variables (version number) to source code header
+# Send the variables (version number) to the source code header
configure_file (
"${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
"${PROJECT_BINARY_DIR}/TutorialConfig.h"
@@ -126,14 +127,14 @@ if(FALSE AND (FALSE OR TRUE))
message("Don't display!")
endif()
-# Set a normal, cache, or environment variable to a given value.
-# If the PARENT_SCOPE option is given the variable will be set in the scope
+# Set a regular, cache, or environment variable to a given value.
+# If the PARENT_SCOPE option is given, the variable will be set in the scope
# above the current scope.
# `set(<variable> <value>... [PARENT_SCOPE])`
-# How to reference variables inside quoted and unquoted arguments
-# A variable reference is replaced by the value of the variable, or by the
-# empty string if the variable is not set
+# How to reference variables inside quoted and unquoted arguments?
+# A variable reference is replaced by either the variable value or by the
+# empty string if the variable is not set.
${variable_name}
# Lists
@@ -171,6 +172,7 @@ endif()
### More Resources
-+ [cmake tutorial](https://cmake.org/cmake-tutorial/)
-+ [cmake documentation](https://cmake.org/documentation/)
-+ [mastering cmake](http://amzn.com/1930934319/)
++ [CMake tutorial](https://cmake.org/cmake-tutorial/)
++ [CMake documentation](https://cmake.org/documentation/)
++ [Mastering CMake](http://amzn.com/1930934319/)
++ [An Introduction to Modern CMake](https://cliutils.gitlab.io/modern-cmake/)
diff --git a/cobol.html.markdown b/cobol.html.markdown
new file mode 100644
index 00000000..1b33f9cc
--- /dev/null
+++ b/cobol.html.markdown
@@ -0,0 +1,198 @@
+---
+language: COBOL
+contributors:
+ - ["Hyphz", "http://github.com/hyphz/"]
+filename: learn.COB
+---
+COBOL is a business-oriented language revised multiple times since its original design in 1960. It is claimed to still be used in over 80% of
+organizations.
+
+```cobol
+ *COBOL. Coding like it's 1985.
+ *Compiles with GnuCOBOL in OpenCobolIDE 4.7.6.
+
+ *COBOL has significant differences between legacy (COBOL-85)
+ *and modern (COBOL-2002 and COBOL-2014) versions.
+ *Legacy versions require columns 1-6 to be blank (they are used
+ *to store the index number of the punched card..)
+ *A '*' in column 7 means a comment.
+ *In legacy COBOL, a comment can only be a full line.
+ *Modern COBOL doesn't require fixed columns and uses *> for
+ *a comment, which can appear in the middle of a line.
+ *Legacy COBOL also imposes a limit on maximum line length.
+ *Keywords have to be in capitals in legacy COBOL,
+ *but are case insensitive in modern.
+ *Although modern COBOL allows you to use mixed-case characters
+ *it is still common to use all caps when writing COBOL code.
+ *This is what most professional COBOL developers do.
+ *COBOL statements end with a period.
+
+ *COBOL code is broken up into 4 divisions.
+ *Those divisions, in order, are:
+ *IDENTIFICATION DIVISION.
+ *ENVIRONMENT DIVISION.
+ *DATA DIVISION.
+ *PROCEDURE DIVISION.
+
+ *First, we must give our program an ID.
+ *Identification division can include other values too,
+ *but they are comments only. Program-id is the only one that is mandatory.
+ IDENTIFICATION DIVISION.
+ PROGRAM-ID. LEARN.
+ AUTHOR. JOHN DOE.
+ DATE-WRITTEN. 05/02/2020.
+
+ *Let's declare some variables.
+ *We do this in the WORKING-STORAGE section within the DATA DIVISION.
+ *Each data item (aka variable) starts with a level number,
+ *then the name of the item, followed by a picture clause
+ *describing the type of data that the variable will contain.
+ *Almost every COBOL programmer will abbreviate PICTURE as PIC.
+ *A is for alphabetic, X is for alphanumeric, and 9 is for numeric.
+
+ *example:
+ 01 MYNAME PIC xxxxxxxxxx. *> A 10 character string.
+
+ *But counting all those x's can lead to errors,
+ *so the above code can, and should
+ *be re-written as:
+ 01 MYNAME PIC X(10).
+
+ *Here are some more examples:
+ 01 AGE PIC 9(3). *> A number up to 3 digits.
+ 01 LAST_NAME PIC X(10). *> A string up to 10 characters.
+
+ *In COBOL, multiple spaces are the same as a single space, so it is common
+ *to use multiple spaces to line up your code so that it is easier for other
+ *coders to read.
+ 01 inyear picture s9(7). *> S makes number signed.
+ *> Brackets indicate 7 repeats of 9,
+ *> ie a 6 digit number (not an array).
+
+ *Now let's write some code. Here is a simple, Hello World program.
+ IDENTIFICATION DIVISION.
+ PROGRAM-ID. HELLO.
+ DATA DIVISION.
+ WORKING-STORAGE SECTION.
+ 01 THE-MESSAGE PIC X(20).
+ PROCEDURE DIVISION.
+ DISPLAY "STARTING PROGRAM".
+ MOVE "HELLO WORLD" TO THE-MESSAGE.
+ DISPLAY THE-MESSAGE.
+ STOP RUN.
+
+ *The above code will output:
+ *STARTING PROGRAM
+ *HELLO WORLD
+
+
+
+ ********COBOL can perform math***************
+ ADD 1 TO AGE GIVING NEW-AGE.
+ SUBTRACT 1 FROM COUNT.
+ DIVIDE VAR-1 INTO VAR-2 GIVING VAR-3.
+ COMPUTE TOTAL-COUNT = COUNT1 PLUS COUNT2.
+
+
+ *********PERFORM********************
+ *The PERFORM keyword allows you to jump to another specified section of the code,
+ *and then to return to the next executable
+ *statement once the specified section of code is completed.
+ *You must write the full word, PERFORM, you cannot abbreviate it.
+
+ IDENTIFICATION DIVISION.
+ PROGRAM-ID. HELLOCOBOL.
+
+ PROCEDURE DIVISION.
+ FIRST-PARA.
+ DISPLAY 'THIS IS IN FIRST-PARA'.
+ PERFORM THIRD-PARA THRU FOURTH-PARA. *>skip second-para and perfrom 3rd & 4th
+ *> then after performing third and fourth,
+ *> return here and continue the program until STOP RUN.
+
+ SECOND-PARA.
+ DISPLAY 'THIS IS IN SECOND-PARA'.
+ STOP RUN.
+
+ THIRD-PARA.
+ DISPLAY 'THIS IS IN THIRD-PARA'.
+
+ FOURTH-PARA.
+ DISPLAY 'THIS IS IN FOURTH-PARA'.
+
+
+ *When you compile and execute the above program, it produces the following result:
+ THIS IS IN FIRST-PARA
+ THIS IS IN THIRD-PARA
+ THIS IS IN FOURTH-PARA
+ THIS IS IN SECOND-PARA
+
+
+ **********Combining variables together using STRING ***********
+
+ *Now it is time to learn about two related COBOL verbs: string and unstring.
+
+ *The string verb is used to concatenate, or put together, two or more stings.
+ *Unstring is used, not surprisingly, to separate a
+ *string into two or more smaller strings.
+ *It is important that you remember to use ‘delimited by’ when you
+ *are using string or unstring in your program.
+
+ IDENTIFICATION DIVISION.
+ PROGRAM-ID. LEARNING.
+ ENVIRONMENT DIVISION.
+ DATA DIVISION.
+ WORKING-STORAGE SECTION.
+ 01 FULL-NAME PIC X(20).
+ 01 FIRST-NAME PIC X(13) VALUE "BOB GIBBERISH".
+ 01 LAST-NAME PIC X(5) VALUE "COBB".
+ PROCEDURE DIVISION.
+ STRING FIRST-NAME DELIMITED BY SPACE
+ " "
+ LAST-NAME DELIMITED BY SIZE
+ INTO FULL-NAME
+ END-STRING.
+ DISPLAY "THE FULL NAME IS: "FULL-NAME.
+ STOP RUN.
+
+
+ *The above code will output:
+ THE FULL NAME IS: BOB COBB
+
+
+ *Let’s examine it to see why.
+
+ *First, we declared all of our variables, including the one that we are creating
+ *by the string command, in the DATA DIVISION.
+
+ *The action takes place down in the PROCEDURE DIVISION.
+ *We start with the STRING keyword and end with END-STRING. In between we
+ *list what we want to combine together into the larger, master variable.
+ *Here, we are combining FIRST-NAME, a space, and LAST-NAME.
+
+ *The DELIMITED BY phrase that follows FIRST-NAME and
+ *LAST-NAME tells the program how much of each variable we want to capture.
+ *DELIMITED BY SPACE tells the program to start at the beginning,
+ *and capture the variable until it runs into a space.
+ *DELIMITED BY SIZE tells the program to capture the full size of the variable.
+ *Since we have DELIMITED BY SPACE after FIRST-NAME, the GIBBERISH part is ignored.
+
+ *To make this clearer, change line 10 in the above code to:
+
+ STRING FIRST-NAME DELIMITED BY SIZE
+
+ *and then re-run the program. This time the output is:
+
+ THE FULL NAME IS: BOB GIBBERISH COBB
+
+
+
+
+
+
+```
+
+##Ready For More?
+
+* [GnuCOBOL](https://sourceforge.net/projects/open-cobol/)
+
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/common-lisp.html.markdown b/common-lisp.html.markdown
index 9a23bc26..1f2bb366 100644
--- a/common-lisp.html.markdown
+++ b/common-lisp.html.markdown
@@ -4,82 +4,91 @@ language: "Common Lisp"
filename: commonlisp.lisp
contributors:
- ["Paul Nathan", "https://github.com/pnathan"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
---
-ANSI Common Lisp is a general purpose, multi-paradigm programming
-language suited for a wide variety of industry applications. It is
-frequently referred to as a programmable programming language.
+Common Lisp is a general-purpose, multi-paradigm programming language suited for a wide variety of
+industry applications. It is frequently referred to as a programmable programming language.
-The classic starting point is [Practical Common Lisp and freely available.](http://www.gigamonkeys.com/book/)
+The classic starting point is [Practical Common Lisp](http://www.gigamonkeys.com/book/). Another
+popular and recent book is [Land of Lisp](http://landoflisp.com/). A new book about best practices,
+[Common Lisp Recipes](http://weitz.de/cl-recipes/), was recently published.
-Another popular and recent book is
-[Land of Lisp](http://landoflisp.com/).
+```lisp
-```common_lisp
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;-----------------------------------------------------------------------------
;;; 0. Syntax
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;-----------------------------------------------------------------------------
-;;; General form.
+;;; General form
-;; Lisp has two fundamental pieces of syntax: the ATOM and the
-;; S-expression. Typically, grouped S-expressions are called `forms`.
+;;; CL has two fundamental pieces of syntax: ATOM and S-EXPRESSION.
+;;; Typically, grouped S-expressions are called `forms`.
-10 ; an atom; it evaluates to itself
+10 ; an atom; it evaluates to itself
+:thing ; another atom; evaluating to the symbol :thing
+t ; another atom, denoting true
+(+ 1 2 3 4) ; an s-expression
+'(4 :foo t) ; another s-expression
-:THING ;Another atom; evaluating to the symbol :thing.
-t ; another atom, denoting true.
+;;; Comments
-(+ 1 2 3 4) ; an s-expression
+;;; Single-line comments start with a semicolon; use four for file-level
+;;; comments, three for section descriptions, two inside definitions, and one
+;;; for single lines. For example,
-'(4 :foo t) ;another one
+;;;; life.lisp
+;;; Foo bar baz, because quu quux. Optimized for maximum krakaboom and umph.
+;;; Needed by the function LINULUKO.
-;;; Comments
+(defun meaning (life)
+ "Return the computed meaning of LIFE"
+ (let ((meh "abc"))
+ ;; Invoke krakaboom
+ (loop :for x :across meh
+ :collect x))) ; store values into x, then return it
-;; Single line comments start with a semicolon; use two for normal
-;; comments, three for section comments, and four for file-level
-;; comments.
+;;; Block comments, on the other hand, allow for free-form comments. They are
+;;; delimited with #| and |#
-#| Block comments
- can span multiple lines and...
+#| This is a block comment which
+ can span multiple lines and
#|
they can be nested!
|#
|#
-;;; Environment.
-;; A variety of implementations exist; most are
-;; standard-conformant. CLISP is a good starting one.
+;;; Environment
-;; Libraries are managed through Quicklisp.org's Quicklisp system.
+;;; A variety of implementations exist; most are standards-conformant. SBCL
+;;; is a good starting point. Third party libraries can be easily installed with
+;;; Quicklisp
-;; Common Lisp is usually developed with a text editor and a REPL
-;; (Read Evaluate Print Loop) running at the same time. The REPL
-;; allows for interactive exploration of the program as it is "live"
-;; in the system.
+;;; CL is usually developed with a text editor and a Read Eval Print
+;;; Loop (REPL) running at the same time. The REPL allows for interactive
+;;; exploration of the program while it is running "live".
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; 1. Primitive Datatypes and Operators
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;-----------------------------------------------------------------------------
+;;; 1. Primitive datatypes and operators
+;;;-----------------------------------------------------------------------------
;;; Symbols
'foo ; => FOO Notice that the symbol is upper-cased automatically.
-;; Intern manually creates a symbol from a string.
+;;; INTERN manually creates a symbol from a string.
-(intern "AAAA") ; => AAAA
-
-(intern "aaa") ; => |aaa|
+(intern "AAAA") ; => AAAA
+(intern "aaa") ; => |aaa|
;;; Numbers
+
9999999999999999999999 ; integers
#b111 ; binary => 7
#o111 ; octal => 73
@@ -89,313 +98,363 @@ t ; another atom, denoting true.
1/2 ; ratios
#C(1 2) ; complex numbers
+;;; Function application are written as (f x y z ...) where f is a function and
+;;; x, y, z, ... are the arguments.
+
+(+ 1 2) ; => 3
+
+;;; If you want to create literal data, use QUOTE to prevent it from being
+;;; evaluated
+
+(quote (+ 1 2)) ; => (+ 1 2)
+(quote a) ; => A
+
+;;; The shorthand for QUOTE is '
+
+'(+ 1 2) ; => (+ 1 2)
+'a ; => A
+
+;;; Basic arithmetic operations
+
+(+ 1 1) ; => 2
+(- 8 1) ; => 7
+(* 10 2) ; => 20
+(expt 2 3) ; => 8
+(mod 5 2) ; => 1
+(/ 35 5) ; => 7
+(/ 1 3) ; => 1/3
+(+ #C(1 2) #C(6 -4)) ; => #C(7 -2)
+
+;;; Booleans
+
+t ; true; any non-NIL value is true
+nil ; false; also, the empty list: ()
+(not nil) ; => T
+(and 0 t) ; => T
+(or 0 nil) ; => 0
+
+;;; Characters
+
+#\A ; => #\A
+#\λ ; => #\GREEK_SMALL_LETTER_LAMDA
+#\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA
+
+;;; Strings are fixed-length arrays of characters
-;; Function application is written (f x y z ...)
-;; where f is a function and x, y, z, ... are operands
-;; If you want to create a literal list of data, use ' to stop it from
-;; being evaluated - literally, "quote" the data.
-'(+ 1 2) ; => (+ 1 2)
-;; You can also call a function manually:
-(funcall #'+ 1 2 3) ; => 6
-;; Some arithmetic operations
-(+ 1 1) ; => 2
-(- 8 1) ; => 7
-(* 10 2) ; => 20
-(expt 2 3) ; => 8
-(mod 5 2) ; => 1
-(/ 35 5) ; => 7
-(/ 1 3) ; => 1/3
-(+ #C(1 2) #C(6 -4)) ; => #C(7 -2)
-
- ;;; Booleans
-t ; for true (any not-nil value is true)
-nil ; for false - and the empty list
-(not nil) ; => t
-(and 0 t) ; => t
-(or 0 nil) ; => 0
-
- ;;; Characters
-#\A ; => #\A
-#\λ ; => #\GREEK_SMALL_LETTER_LAMDA
-#\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA
-
-;;; Strings are fixed-length arrays of characters.
"Hello, world!"
"Benjamin \"Bugsy\" Siegel" ; backslash is an escaping character
-;; Strings can be concatenated too!
-(concatenate 'string "Hello " "world!") ; => "Hello world!"
+;;; Strings can be concatenated
+
+(concatenate 'string "Hello, " "world!") ; => "Hello, world!"
+
+;;; A string can be treated like a sequence of characters
-;; A string can be treated like a sequence of characters
(elt "Apple" 0) ; => #\A
-;; format can be used to format strings:
-(format nil "~a can be ~a" "strings" "formatted")
+;;; FORMAT is used to create formatted output, which ranges from simple string
+;;; interpolation to loops and conditionals. The first argument to FORMAT
+;;; determines where will the formatted string go. If it is NIL, FORMAT
+;;; simply returns the formatted string as a value; if it is T, FORMAT outputs
+;;; to the standard output, usually the screen, then it returns NIL.
+
+(format nil "~A, ~A!" "Hello" "world") ; => "Hello, world!"
+(format t "~A, ~A!" "Hello" "world") ; => NIL
-;; Printing is pretty easy; ~% is the format specifier for newline.
-(format t "Common Lisp is groovy. Dude.~%")
+;;;-----------------------------------------------------------------------------
+;;; 2. Variables
+;;;-----------------------------------------------------------------------------
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 2. Variables
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; You can create a global (dynamically scoped) using defparameter
-;; a variable name can use any character except: ()",'`;#|\
+;;; You can create a global (dynamically scoped) variable using DEFVAR and
+;;; DEFPARAMETER. The variable name can use any character except: ()",'`;#|\
-;; Dynamically scoped variables should have earmuffs in their name!
+;;; The difference between DEFVAR and DEFPARAMETER is that re-evaluating a
+;;; DEFVAR expression doesn't change the value of the variable. DEFPARAMETER,
+;;; on the other hand, does.
+
+;;; By convention, dynamically scoped variables have earmuffs in their name.
(defparameter *some-var* 5)
*some-var* ; => 5
-;; You can also use unicode characters.
+;;; You can also use unicode characters.
(defparameter *AΛB* nil)
+;;; Accessing a previously unbound variable results in an UNBOUND-VARIABLE
+;;; error, however it is defined behavior. Don't do it.
+
+;;; You can create local bindings with LET. In the following snippet, `me` is
+;;; bound to "dance with you" only within the (let ...). LET always returns
+;;; the value of the last `form` in the LET form.
-;; Accessing a previously unbound variable is an
-;; undefined behavior (but possible). Don't do it.
+(let ((me "dance with you")) me) ; => "dance with you"
-;; Local binding: `me` is bound to "dance with you" only within the
-;; (let ...). Let always returns the value of the last `form` in the
-;; let form.
+;;;-----------------------------------------------------------------------------;
+;;; 3. Structs and collections
+;;;-----------------------------------------------------------------------------;
-(let ((me "dance with you"))
- me)
-;; => "dance with you"
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 3. Structs and Collections
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Structs
-;; Structs
(defstruct dog name breed age)
(defparameter *rover*
(make-dog :name "rover"
:breed "collie"
:age 5))
-*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
-
-(dog-p *rover*) ; => true #| -p signifies "predicate". It's used to
- check if *rover* is an instance of dog. |#
+*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
+(dog-p *rover*) ; => T
(dog-name *rover*) ; => "rover"
-;; Dog-p, make-dog, and dog-name are all created by defstruct!
+;;; DOG-P, MAKE-DOG, and DOG-NAME are all automatically created by DEFSTRUCT
+
;;; Pairs
-;; `cons' constructs pairs, `car' and `cdr' extract the first
-;; and second elements
-(cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB)
-(car (cons 'SUBJECT 'VERB)) ; => SUBJECT
-(cdr (cons 'SUBJECT 'VERB)) ; => VERB
+
+;;; CONS constructs pairs. CAR and CDR return the head and tail of a CONS-pair.
+
+(cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB)
+(car (cons 'SUBJECT 'VERB)) ; => SUBJECT
+(cdr (cons 'SUBJECT 'VERB)) ; => VERB
+
;;; Lists
-;; Lists are linked-list data structures, made of `cons' pairs and end
-;; with a `nil' (or '()) to mark the end of the list
-(cons 1 (cons 2 (cons 3 nil))) ; => '(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
-'(1 2 3) ; => '(1 2 3)
+;;; Lists are linked-list data structures, made of CONS pairs and end with a
+;;; NIL (or '()) to mark the end of the list
+
+(cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3)
+
+;;; LIST is a convenience variadic constructor for lists
+
+(list 1 2 3) ; => '(1 2 3)
-;; Can still use `cons' to add an item to the beginning of a list
-(cons 4 '(1 2 3)) ; => '(4 1 2 3)
+;;; When the first argument to CONS is an atom and the second argument is a
+;;; list, CONS returns a new CONS-pair with the first argument as the first
+;;; item and the second argument as the rest of the CONS-pair
-;; Use `append' to - surprisingly - append lists together
-(append '(1 2) '(3 4)) ; => '(1 2 3 4)
+(cons 4 '(1 2 3)) ; => '(4 1 2 3)
-;; Or use concatenate -
+;;; Use APPEND to join lists
-(concatenate 'list '(1 2) '(3 4))
+(append '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;;; Or CONCATENATE
+
+(concatenate 'list '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;;; Lists are a very central type, so there is a wide variety of functionality for
+;;; them, a few examples:
-;; Lists are a very central type, so there is a wide variety of functionality for
-;; them, a few examples:
(mapcar #'1+ '(1 2 3)) ; => '(2 3 4)
(mapcar #'+ '(1 2 3) '(10 20 30)) ; => '(11 22 33)
(remove-if-not #'evenp '(1 2 3 4)) ; => '(2 4)
-(every #'evenp '(1 2 3 4)) ; => nil
+(every #'evenp '(1 2 3 4)) ; => NIL
(some #'oddp '(1 2 3 4)) ; => T
(butlast '(subject verb object)) ; => (SUBJECT VERB)
;;; Vectors
-;; Vector's literals are fixed-length arrays
+;;; Vector's literals are fixed-length arrays
+
#(1 2 3) ; => #(1 2 3)
-;; Use concatenate to add vectors together
+;;; Use CONCATENATE to add vectors together
+
(concatenate 'vector #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
+
;;; Arrays
-;; Both vectors and strings are special-cases of arrays.
+;;; Both vectors and strings are special-cases of arrays.
-;; 2D arrays
+;;; 2D arrays
-(make-array (list 2 2))
+(make-array (list 2 2)) ; => #2A((0 0) (0 0))
+(make-array '(2 2)) ; => #2A((0 0) (0 0))
+(make-array (list 2 2 2)) ; => #3A(((0 0) (0 0)) ((0 0) (0 0)))
-;; (make-array '(2 2)) works as well.
+;;; Caution: the default initial values of MAKE-ARRAY are implementation-defined.
+;;; To explicitly specify them:
-; => #2A((0 0) (0 0))
+(make-array '(2) :initial-element 'unset) ; => #(UNSET UNSET)
-(make-array (list 2 2 2))
+;;; To access the element at 1, 1, 1:
-; => #3A(((0 0) (0 0)) ((0 0) (0 0)))
+(aref (make-array (list 2 2 2)) 1 1 1) ; => 0
+;;; This value is implementation-defined:
+;;; NIL on ECL, 0 on SBCL and CCL.
-;; Caution- the default initial values are
-;; implementation-defined. Here's how to define them:
+;;; Adjustable vectors
-(make-array '(2) :initial-element 'unset)
+;;; Adjustable vectors have the same printed representation as
+;;; fixed-length vector's literals.
-; => #(UNSET UNSET)
+(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3)
+ :adjustable t :fill-pointer t))
+*adjvec* ; => #(1 2 3)
-;; And, to access the element at 1,1,1 -
-(aref (make-array (list 2 2 2)) 1 1 1)
+;;; Adding new elements
-; => 0
+(vector-push-extend 4 *adjvec*) ; => 3
+*adjvec* ; => #(1 2 3 4)
-;;; Adjustable vectors
-;; Adjustable vectors have the same printed representation
-;; as fixed-length vector's literals.
+;;; Sets, naively, are just lists:
-(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3)
- :adjustable t :fill-pointer t))
+(set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1)
+(intersection '(1 2 3 4) '(4 5 6 7)) ; => 4
+(union '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1 4 5 6 7)
+(adjoin 4 '(1 2 3 4)) ; => (1 2 3 4)
-*adjvec* ; => #(1 2 3)
+;;; However, you'll need a better data structure than linked lists when working
+;;; with larger data sets
+
+;;; Dictionaries are implemented as hash tables.
+
+;;; Create a hash table
-;; Adding new element:
-(vector-push-extend 4 *adjvec*) ; => 3
+(defparameter *m* (make-hash-table))
-*adjvec* ; => #(1 2 3 4)
+;;; Set value
+(setf (gethash 'a *m*) 1)
+;;; Retrieve value
-;;; Naively, sets are just lists:
+(gethash 'a *m*) ; => 1, T
-(set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1)
-(intersection '(1 2 3 4) '(4 5 6 7)) ; => 4
-(union '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1 4 5 6 7)
-(adjoin 4 '(1 2 3 4)) ; => (1 2 3 4)
+;;; CL expressions have the ability to return multiple values.
-;; But you'll want to use a better data structure than a linked list
-;; for performant work!
+(values 1 2) ; => 1, 2
-;;; Dictionaries are implemented as hash tables.
+;;; which can be bound with MULTIPLE-VALUE-BIND
-;; Create a hash table
-(defparameter *m* (make-hash-table))
+(multiple-value-bind (x y)
+ (values 1 2)
+ (list y x))
-;; set a value
-(setf (gethash 'a *m*) 1)
+; => '(2 1)
-;; Retrieve a value
-(gethash 'a *m*) ; => 1, t
+;;; GETHASH is an example of a function that returns multiple values. The first
+;;; value it return is the value of the key in the hash table; if the key is
+;;; not found it returns NIL.
-;; Detail - Common Lisp has multiple return values possible. gethash
-;; returns t in the second value if anything was found, and nil if
-;; not.
+;;; The second value determines if that key is indeed present in the hash
+;;; table. If a key is not found in the table it returns NIL. This behavior
+;;; allows us to check if the value of a key is actually NIL.
-;; Retrieving a non-present value returns nil
- (gethash 'd *m*) ;=> nil, nil
+;;; Retrieving a non-present value returns nil
+
+(gethash 'd *m*) ;=> NIL, NIL
+
+;;; You can provide a default value for missing keys
-;; You can provide a default value for missing keys
(gethash 'd *m* :not-found) ; => :NOT-FOUND
-;; Let's handle the multiple return values here in code.
+;;; Let's handle the multiple return values here in code.
-(multiple-value-bind
- (a b)
+(multiple-value-bind (a b)
(gethash 'd *m*)
(list a b))
; => (NIL NIL)
-(multiple-value-bind
- (a b)
+(multiple-value-bind (a b)
(gethash 'a *m*)
(list a b))
; => (1 T)
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 3. Functions
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Use `lambda' to create anonymous functions.
-;; A function always returns the value of its last expression.
-;; The exact printable representation of a function will vary...
+;;;-----------------------------------------------------------------------------
+;;; 3. Functions
+;;;-----------------------------------------------------------------------------
+
+;;; Use LAMBDA to create anonymous functions. Functions always returns the
+;;; value of the last expression. The exact printable representation of a
+;;; function varies between implementations.
(lambda () "Hello World") ; => #<FUNCTION (LAMBDA ()) {1004E7818B}>
-;; Use funcall to call lambda functions
-(funcall (lambda () "Hello World")) ; => "Hello World"
+;;; Use FUNCALL to call anonymous functions
+
+(funcall (lambda () "Hello World")) ; => "Hello World"
+(funcall #'+ 1 2 3) ; => 6
+
+;;; A call to FUNCALL is also implied when the lambda expression is the CAR of
+;;; an unquoted list
-;; Or Apply
+((lambda () "Hello World")) ; => "Hello World"
+((lambda (val) val) "Hello World") ; => "Hello World"
+
+;;; FUNCALL is used when the arguments are known beforehand. Otherwise, use APPLY
+
+(apply #'+ '(1 2 3)) ; => 6
(apply (lambda () "Hello World") nil) ; => "Hello World"
-;; De-anonymize the function
-(defun hello-world ()
- "Hello World")
+;;; To name a function, use DEFUN
+
+(defun hello-world () "Hello World")
(hello-world) ; => "Hello World"
-;; The () in the above is the list of arguments for the function
-(defun hello (name)
- (format nil "Hello, ~a" name))
+;;; The () in the definition above is the list of arguments
+(defun hello (name) (format nil "Hello, ~A" name))
(hello "Steve") ; => "Hello, Steve"
-;; Functions can have optional arguments; they default to nil
+;;; Functions can have optional arguments; they default to NIL
(defun hello (name &optional from)
- (if from
- (format t "Hello, ~a, from ~a" name from)
- (format t "Hello, ~a" name)))
+ (if from
+ (format t "Hello, ~A, from ~A" name from)
+ (format t "Hello, ~A" name)))
- (hello "Jim" "Alpacas") ;; => Hello, Jim, from Alpacas
-
-;; And the defaults can be set...
-(defun hello (name &optional (from "The world"))
- (format t "Hello, ~a, from ~a" name from))
+(hello "Jim" "Alpacas") ; => Hello, Jim, from Alpacas
-(hello "Steve")
-; => Hello, Steve, from The world
+;;; The default values can also be specified
-(hello "Steve" "the alpacas")
-; => Hello, Steve, from the alpacas
+(defun hello (name &optional (from "The world"))
+ (format nil "Hello, ~A, from ~A" name from))
+(hello "Steve") ; => Hello, Steve, from The world
+(hello "Steve" "the alpacas") ; => Hello, Steve, from the alpacas
-;; And of course, keywords are allowed as well... usually more
-;; flexible than &optional.
+;;; Functions also have keyword arguments to allow non-positional arguments
(defun generalized-greeter (name &key (from "the world") (honorific "Mx"))
- (format t "Hello, ~a ~a, from ~a" honorific name from))
+ (format t "Hello, ~A ~A, from ~A" honorific name from))
-(generalized-greeter "Jim") ; => Hello, Mx Jim, from the world
+(generalized-greeter "Jim")
+; => Hello, Mx Jim, from the world
(generalized-greeter "Jim" :from "the alpacas you met last summer" :honorific "Mr")
; => Hello, Mr Jim, from the alpacas you met last summer
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 4. Equality
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Common Lisp has a sophisticated equality system. A couple are covered here.
+;;;-----------------------------------------------------------------------------
+;;; 4. Equality
+;;;-----------------------------------------------------------------------------
+
+;;; CL has a sophisticated equality system. Some are covered here.
+
+;;; For numbers, use `='
+(= 3 3.0) ; => T
+(= 2 1) ; => NIL
-;; for numbers use `='
-(= 3 3.0) ; => t
-(= 2 1) ; => nil
+;;; For object identity (approximately) use EQL
+(eql 3 3) ; => T
+(eql 3 3.0) ; => NIL
+(eql (list 3) (list 3)) ; => NIL
-;; for object identity (approximately) use `eql`
-(eql 3 3) ; => t
-(eql 3 3.0) ; => nil
-(eql (list 3) (list 3)) ; => nil
+;;; for lists, strings, and bit-vectors use EQUAL
+(equal (list 'a 'b) (list 'a 'b)) ; => T
+(equal (list 'a 'b) (list 'b 'a)) ; => NIL
-;; for lists, strings, and bit-vectors use `equal'
-(equal (list 'a 'b) (list 'a 'b)) ; => t
-(equal (list 'a 'b) (list 'b 'a)) ; => nil
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 5. Control Flow
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;-----------------------------------------------------------------------------
+;;; 5. Control Flow
+;;;-----------------------------------------------------------------------------
;;; Conditionals
@@ -404,71 +463,75 @@ nil ; for false - and the empty list
"this is false") ; else expression
; => "this is true"
-;; In conditionals, all non-nil values are treated as true
+;;; In conditionals, all non-NIL values are treated as true
+
(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(GROUCHO ZEPPO)
(if (member 'Groucho '(Harpo Groucho Zeppo))
'yep
'nope)
; => 'YEP
-;; `cond' chains a series of tests to select a result
+;;; COND chains a series of tests to select a result
(cond ((> 2 2) (error "wrong!"))
((< 2 2) (error "wrong again!"))
(t 'ok)) ; => 'OK
-;; Typecase switches on the type of the value
+;;; TYPECASE switches on the type of the value
(typecase 1
(string :string)
(integer :int))
-
; => :int
-;;; Iteration
-;; Of course recursion is supported:
+;;; Looping
-(defun walker (n)
- (if (zerop n)
- :walked
- (walker (- n 1))))
+;;; Recursion
-(walker 5) ; => :walked
+(defun fact (n)
+ (if (< n 2)
+ 1
+ (* n (fact(- n 1)))))
-;; Most of the time, we use DOLIST or LOOP
+(fact 5) ; => 120
+;;; Iteration
-(dolist (i '(1 2 3 4))
- (format t "~a" i))
+(defun fact (n)
+ (loop :for result = 1 :then (* result i)
+ :for i :from 2 :to n
+ :finally (return result)))
-; => 1234
+(fact 5) ; => 120
-(loop for i from 0 below 10
- collect i)
+(loop :for x :across "abcd" :collect x)
+; => (#\a #\b #\c #\d)
-; => (0 1 2 3 4 5 6 7 8 9)
+(dolist (i '(1 2 3 4))
+ (format t "~A" i))
+; => 1234
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 6. Mutation
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;-----------------------------------------------------------------------------
+;;; 6. Mutation
+;;;-----------------------------------------------------------------------------
-;; Use `setf' to assign a new value to an existing variable. This was
-;; demonstrated earlier in the hash table example.
+;;; Use SETF to assign a new value to an existing variable. This was
+;;; demonstrated earlier in the hash table example.
(let ((variable 10))
(setf variable 2))
- ; => 2
+; => 2
+;;; Good Lisp style is to minimize the use of destructive functions and to avoid
+;;; mutation when reasonable.
-;; Good Lisp style is to minimize destructive functions and to avoid
-;; mutation when reasonable.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 7. Classes and Objects
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;-----------------------------------------------------------------------------
+;;; 7. Classes and objects
+;;;-----------------------------------------------------------------------------
-;; No more Animal classes, let's have Human-Powered Mechanical
-;; Conveyances.
+;;; No more animal classes. Let's have Human-Powered Mechanical
+;;; Conveyances.
(defclass human-powered-conveyance ()
((velocity
@@ -479,14 +542,16 @@ nil ; for false - and the empty list
:initarg :average-efficiency))
(:documentation "A human powered conveyance"))
-;; defclass, followed by name, followed by the superclass list,
-;; followed by slot list, followed by optional qualities such as
-;; :documentation.
+;;; The arguments to DEFCLASS, in order are:
+;;; 1. class name
+;;; 2. superclass list
+;;; 3. slot list
+;;; 4. optional specifiers
-;; When no superclass list is set, the empty list defaults to the
-;; standard-object class. This *can* be changed, but not until you
-;; know what you're doing. Look up the Art of the Metaobject Protocol
-;; for more information.
+;;; When no superclass list is set, the empty list defaults to the
+;;; standard-object class. This *can* be changed, but not until you
+;;; know what you're doing. Look up the Art of the Metaobject Protocol
+;;; for more information.
(defclass bicycle (human-powered-conveyance)
((wheel-size
@@ -500,7 +565,7 @@ nil ; for false - and the empty list
(defclass recumbent (bicycle)
((chain-type
:accessor chain-type
- :initarg :chain-type)))
+ :initarg :chain-type)))
(defclass unicycle (human-powered-conveyance) nil)
@@ -509,8 +574,7 @@ nil ; for false - and the empty list
:accessor number-of-rowers
:initarg :number-of-rowers)))
-
-;; Calling DESCRIBE on the human-powered-conveyance class in the REPL gives:
+;;; Calling DESCRIBE on the HUMAN-POWERED-CONVEYANCE class in the REPL gives:
(describe 'human-powered-conveyance)
@@ -532,47 +596,42 @@ nil ; for false - and the empty list
; Readers: AVERAGE-EFFICIENCY
; Writers: (SETF AVERAGE-EFFICIENCY)
-;; Note the reflective behavior available to you! Common Lisp is
-;; designed to be an interactive system
+;;; Note the reflective behavior available. CL was designed to be an
+;;; interactive system
-;; To define a method, let's find out what our circumference of the
-;; bike wheel turns out to be using the equation: C = d * pi
+;;; To define a method, let's find out what our circumference of the
+;;; bike wheel turns out to be using the equation: C = d * pi
(defmethod circumference ((object bicycle))
(* pi (wheel-size object)))
-;; pi is defined in Lisp already for us!
+;;; PI is defined as a built-in in CL
-;; Let's suppose we find out that the efficiency value of the number
-;; of rowers in a canoe is roughly logarithmic. This should probably be set
-;; in the constructor/initializer.
+;;; Let's suppose we find out that the efficiency value of the number
+;;; of rowers in a canoe is roughly logarithmic. This should probably be set
+;;; in the constructor/initializer.
-;; Here's how to initialize your instance after Common Lisp gets done
-;; constructing it:
+;;; To initialize your instance after CL gets done constructing it:
(defmethod initialize-instance :after ((object canoe) &rest args)
(setf (average-efficiency object) (log (1+ (number-of-rowers object)))))
-;; Then to construct an instance and check the average efficiency...
+;;; Then to construct an instance and check the average efficiency...
(average-efficiency (make-instance 'canoe :number-of-rowers 15))
; => 2.7725887
+;;;-----------------------------------------------------------------------------
+;;; 8. Macros
+;;;-----------------------------------------------------------------------------
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 8. Macros
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;; Macros let you extend the syntax of the language
-
-;; Common Lisp doesn't come with a WHILE loop- let's add one.
-;; If we obey our assembler instincts, we wind up with:
+;;; Macros let you extend the syntax of the language. CL doesn't come
+;;; with a WHILE loop, however, it's trivial to write one. If we obey our
+;;; assembler instincts, we wind up with:
(defmacro while (condition &body body)
"While `condition` is true, `body` is executed.
-
`condition` is tested prior to each execution of `body`"
(let ((block-name (gensym)) (done (gensym)))
`(tagbody
@@ -584,47 +643,47 @@ nil ; for false - and the empty list
(go ,block-name)
,done)))
-;; Let's look at the high-level version of this:
-
+;;; Let's look at the high-level version of this:
(defmacro while (condition &body body)
"While `condition` is true, `body` is executed.
-
`condition` is tested prior to each execution of `body`"
`(loop while ,condition
do
(progn
,@body)))
-;; However, with a modern compiler, this is not required; the LOOP
-;; form compiles equally well and is easier to read.
+;;; However, with a modern compiler, this is not required; the LOOP form
+;;; compiles equally well and is easier to read.
-;; Note that ``` is used, as well as `,` and `@`. ``` is a quote-type operator
-;; known as quasiquote; it allows the use of `,` . `,` allows "unquoting"
-;; variables. @ interpolates lists.
+;;; Note that ``` is used, as well as `,` and `@`. ``` is a quote-type operator
+;;; known as quasiquote; it allows the use of `,` . `,` allows "unquoting"
+;;; variables. @ interpolates lists.
-;; Gensym creates a unique symbol guaranteed to not exist elsewhere in
-;; the system. This is because macros are expanded at compile time and
-;; variables declared in the macro can collide with variables used in
-;; regular code.
+;;; GENSYM creates a unique symbol guaranteed to not exist elsewhere in
+;;; the system. This is because macros are expanded at compile time and
+;;; variables declared in the macro can collide with variables used in
+;;; regular code.
-;; See Practical Common Lisp for more information on macros.
+;;; See Practical Common Lisp and On Lisp for more information on macros.
```
-## Further Reading
+## Further reading
+
+- [Practical Common Lisp](http://www.gigamonkeys.com/book/)
+- [Common Lisp: A Gentle Introduction to Symbolic Computation](https://www.cs.cmu.edu/~dst/LispBook/book.pdf)
-* [Keep moving on to the Practical Common Lisp book.](http://www.gigamonkeys.com/book/)
-* [A Gentle Introduction to...](https://www.cs.cmu.edu/~dst/LispBook/book.pdf)
+## Extra information
-## Extra Info
+- [CLiki](http://www.cliki.net/)
+- [common-lisp.net](https://common-lisp.net/)
+- [Awesome Common Lisp](https://github.com/CodyReichert/awesome-cl)
+- [Lisp Lang](http://lisp-lang.org/)
-* [CLiki](http://www.cliki.net/)
-* [common-lisp.net](https://common-lisp.net/)
-* [Awesome Common Lisp](https://github.com/CodyReichert/awesome-cl)
-## Credits.
+## Credits
Lots of thanks to the Scheme people for rolling up a great starting
point which could be easily moved to Common Lisp.
diff --git a/coq.html.markdown b/coq.html.markdown
new file mode 100644
index 00000000..4c1ad690
--- /dev/null
+++ b/coq.html.markdown
@@ -0,0 +1,510 @@
+---
+language: Coq
+filename: learncoq.v
+contributors:
+ - ["Philip Zucker", "http://www.philipzucker.com/"]
+---
+
+The Coq system is a proof assistant. It is designed to build and verify mathematical proofs. The Coq system contains the functional programming language Gallina and is capable of proving properties about programs written in this language.
+
+Coq is a dependently typed language. This means that the types of the language may depend on the values of variables. In this respect, it is similar to other related languages such as Agda, Idris, F*, Lean, and others. Via the Curry-Howard correspondence, programs, properties and proofs are formalized in the same language.
+
+Coq is developed in OCaml and shares some syntactic and conceptual similarity with it. Coq is a language containing many fascinating but difficult topics. This tutorial will focus on the programming aspects of Coq, rather than the proving. It may be helpful, but not necessary to learn some OCaml first, especially if you are unfamiliar with functional programming. This tutorial is based upon its OCaml equivalent
+
+The standard usage model of Coq is to write it with interactive tool assistance, which operates like a high powered REPL. Two common such editors are the CoqIDE and Proof General Emacs mode.
+
+Inside Proof General `Ctrl+C Ctrl+<Enter>` will evaluate up to your cursor.
+
+
+```coq
+(*** Comments ***)
+
+(* Comments are enclosed in (* and *). It's fine to nest comments. *)
+
+(* There are no single-line comments. *)
+
+(*** Variables and functions ***)
+
+(* The Coq proof assistant can be controlled and queried by a command
+ language called the vernacular. Vernacular keywords are capitalized and
+ the commands end with a period. Variable and function declarations are
+ formed with the Definition vernacular. *)
+
+Definition x := 10.
+
+(* Coq can sometimes infer the types of arguments, but it is common practice
+ to annotate with types. *)
+
+Definition inc_nat (x : nat) : nat := x + 1.
+
+(* There exists a large number of vernacular commands for querying
+ information. These can be very useful. *)
+
+Compute (1 + 1). (* 2 : nat *) (* Compute a result. *)
+
+Check tt. (* tt : unit *) (* Check the type of an expressions *)
+
+About plus. (* Prints information about an object *)
+
+(* Print information including the definition *)
+Print true. (* Inductive bool : Set := true : Bool | false : Bool *)
+
+Search nat. (* Returns a large list of nat related values *)
+Search "_ + _". (* You can also search on patterns *)
+Search (?a -> ?a -> bool). (* Patterns can have named parameters *)
+Search (?a * ?a).
+
+(* Locate tells you where notation is coming from. Very helpful when you
+ encounter new notation. *)
+
+Locate "+".
+
+(* Calling a function with insufficient number of arguments does not cause
+ an error, it produces a new function. *)
+Definition make_inc x y := x + y. (* make_inc is int -> int -> int *)
+Definition inc_2 := make_inc 2. (* inc_2 is int -> int *)
+Compute inc_2 3. (* Evaluates to 5 *)
+
+
+(* Definitions can be chained with "let ... in" construct. This is roughly
+ the same to assigning values to multiple variables before using them in
+ expressions in imperative languages. *)
+
+Definition add_xy : nat := let x := 10 in
+ let y := 20 in
+ x + y.
+
+(* Pattern matching is somewhat similar to switch statement in imperative
+ languages, but offers a lot more expressive power. *)
+
+Definition is_zero (x : nat) :=
+ match x with
+ | 0 => true
+ | _ => false (* The "_" pattern means "anything else". *)
+ end.
+
+(* You can define recursive function definition using the Fixpoint
+ vernacular.*)
+
+Fixpoint factorial n := match n with
+ | 0 => 1
+ | (S n') => n * factorial n'
+ end.
+
+(* Function application usually doesn't need parentheses around arguments *)
+Compute factorial 5. (* 120 : nat *)
+
+(* ...unless the argument is an expression. *)
+Compute factorial (5-1). (* 24 : nat *)
+
+(* You can define mutually recursive functions using "with" *)
+Fixpoint is_even (n : nat) : bool := match n with
+ | 0 => true
+ | (S n) => is_odd n
+end with
+ is_odd n := match n with
+ | 0 => false
+ | (S n) => is_even n
+ end.
+
+(* As Coq is a total programming language, it will only accept programs when
+ it can understand they terminate. It can be most easily seen when the
+ recursive call is on a pattern matched out subpiece of the input, as then
+ the input is always decreasing in size. Getting Coq to understand that
+ functions terminate is not always easy. See the references at the end of
+ the article for more on this topic. *)
+
+(* Anonymous functions use the following syntax: *)
+
+Definition my_square : nat -> nat := fun x => x * x.
+
+Definition my_id (A : Type) (x : A) : A := x.
+Definition my_id2 : forall A : Type, A -> A := fun A x => x.
+Compute my_id nat 3. (* 3 : nat *)
+
+(* You can ask Coq to infer terms with an underscore *)
+Compute my_id _ 3.
+
+(* An implicit argument of a function is an argument which can be inferred
+ from contextual knowledge. Parameters enclosed in {} are implicit by
+ default *)
+
+Definition my_id3 {A : Type} (x : A) : A := x.
+Compute my_id3 3. (* 3 : nat *)
+
+(* Sometimes it may be necessary to turn this off. You can make all
+ arguments explicit again with @ *)
+
+Compute @my_id3 nat 3.
+
+(* Or give arguments by name *)
+Compute my_id3 (A:=nat) 3.
+
+(* Coq has the ability to extract code to OCaml, Haskell, and Scheme *)
+Require Extraction.
+Extraction Language OCaml.
+Extraction "factorial.ml" factorial.
+(* The above produces a file factorial.ml and factorial.mli that holds:
+
+type nat =
+| O
+| S of nat
+
+(** val add : nat -> nat -> nat **)
+
+let rec add n m =
+ match n with
+ | O -> m
+ | S p -> S (add p m)
+
+(** val mul : nat -> nat -> nat **)
+
+let rec mul n m =
+ match n with
+ | O -> O
+ | S p -> add m (mul p m)
+
+(** val factorial : nat -> nat **)
+
+let rec factorial n = match n with
+| O -> S O
+| S n' -> mul n (factorial n')
+*)
+
+
+(*** Notation ***)
+
+(* Coq has a very powerful Notation system that can be used to write
+ expressions in more natural forms. *)
+
+Compute Nat.add 3 4. (* 7 : nat *)
+Compute 3 + 4. (* 7 : nat *)
+
+(* Notation is a syntactic transformation applied to the text of the program
+ before being evaluated. Notation is organized into notation scopes. Using
+ different notation scopes allows for a weak notion of overloading. *)
+
+(* Imports the Zarith module holding definitions related to the integers Z *)
+
+Require Import ZArith.
+
+(* Notation scopes can be opened *)
+Open Scope Z_scope.
+
+(* Now numerals and addition are defined on the integers. *)
+Compute 1 + 7. (* 8 : Z *)
+
+(* Integer equality checking *)
+Compute 1 =? 2. (* false : bool *)
+
+(* Locate is useful for finding the origin and definition of notations *)
+Locate "_ =? _". (* Z.eqb x y : Z_scope *)
+Close Scope Z_scope.
+
+(* We're back to nat being the default interpretation of "+" *)
+Compute 1 + 7. (* 8 : nat *)
+
+(* Scopes can also be opened inline with the shorthand % *)
+Compute (3 * -7)%Z. (* -21%Z : Z *)
+
+(* Coq declares by default the following interpretation scopes: core_scope,
+ type_scope, function_scope, nat_scope, bool_scope, list_scope, int_scope,
+ uint_scope. You may also want the numerical scopes Z_scope (integers) and
+ Q_scope (fractions) held in the ZArith and QArith module respectively. *)
+
+(* You can print the contents of scopes *)
+Print Scope nat_scope.
+(*
+Scope nat_scope
+Delimiting key is nat
+Bound to classes nat Nat.t
+"x 'mod' y" := Nat.modulo x y
+"x ^ y" := Nat.pow x y
+"x ?= y" := Nat.compare x y
+"x >= y" := ge x y
+"x > y" := gt x y
+"x =? y" := Nat.eqb x y
+"x <? y" := Nat.ltb x y
+"x <=? y" := Nat.leb x y
+"x <= y <= z" := and (le x y) (le y z)
+"x <= y < z" := and (le x y) (lt y z)
+"n <= m" := le n m
+"x < y <= z" := and (lt x y) (le y z)
+"x < y < z" := and (lt x y) (lt y z)
+"x < y" := lt x y
+"x / y" := Nat.div x y
+"x - y" := Init.Nat.sub x y
+"x + y" := Init.Nat.add x y
+"x * y" := Init.Nat.mul x y
+*)
+
+(* Coq has exact fractions available as the type Q in the QArith module.
+ Floating point numbers and real numbers are also available but are a more
+ advanced topic, as proving properties about them is rather tricky. *)
+
+Require Import QArith.
+
+Open Scope Q_scope.
+Compute 1. (* 1 : Q *)
+
+(* Only 1 and 0 are interpreted as fractions by Q_scope *)
+Compute 2. (* 2 : nat *)
+Compute (2 # 3). (* The fraction 2/3 *)
+Compute (1 # 3) ?= (2 # 6). (* Eq : comparison *)
+Close Scope Q_scope.
+
+Compute ( (2 # 3) / (1 # 5) )%Q. (* 10 # 3 : Q *)
+
+
+(*** Common data structures ***)
+
+(* Many common data types are included in the standard library *)
+
+(* The unit type has exactly one value, tt *)
+Check tt. (* tt : unit *)
+
+(* The option type is useful for expressing computations that might fail *)
+Compute None. (* None : option ?A *)
+Check Some 3. (* Some 3 : option nat *)
+
+(* The type sum A B allows for values of either type A or type B *)
+Print sum.
+Check inl 3. (* inl 3 : nat + ?B *)
+Check inr true. (* inr true : ?A + bool *)
+Check sum bool nat. (* (bool + nat)%type : Set *)
+Check (bool + nat)%type. (* Notation for sum *)
+
+(* Tuples are (optionally) enclosed in parentheses, items are separated
+ by commas. *)
+Check (1, true). (* (1, true) : nat * bool *)
+Compute prod nat bool. (* (nat * bool)%type : Set *)
+
+Definition my_fst {A B : Type} (x : A * B) : A := match x with
+ | (a,b) => a
+ end.
+
+(* A destructuring let is available if a pattern match is irrefutable *)
+Definition my_fst2 {A B : Type} (x : A * B) : A := let (a,b) := x in
+ a.
+
+(*** Lists ***)
+
+(* Lists are built by using cons and nil or by using notation available in
+ list_scope. *)
+Compute cons 1 (cons 2 (cons 3 nil)). (* (1 :: 2 :: 3 :: nil)%list : list nat *)
+Compute (1 :: 2 :: 3 :: nil)%list.
+
+(* There is also list notation available in the ListNotations modules *)
+Require Import List.
+Import ListNotations.
+Compute [1 ; 2 ; 3]. (* [1; 2; 3] : list nat *)
+
+
+(* There is a large number of list manipulation functions available,
+ including:
+
+• length
+• head : first element (with default)
+• tail : all but first element
+• app : appending
+• rev : reverse
+• nth : accessing n-th element (with default)
+• map : applying a function
+• flat_map : applying a function returning lists
+• fold_left : iterator (from head to tail)
+• fold_right : iterator (from tail to head)
+
+ *)
+
+Definition my_list : list nat := [47; 18; 34].
+
+Compute List.length my_list. (* 3 : nat *)
+
+(* All functions in coq must be total, so indexing requires a default value *)
+Compute List.nth 1 my_list 0. (* 18 : nat *)
+Compute List.map (fun x => x * 2) my_list. (* [94; 36; 68] : list nat *)
+Compute List.filter (fun x => Nat.eqb (Nat.modulo x 2) 0) my_list.
+ (* [18; 34] : list nat *)
+Compute (my_list ++ my_list)%list. (* [47; 18; 34; 47; 18; 34] : list nat *)
+
+(*** Strings ***)
+
+Require Import Strings.String.
+
+(* Use double quotes for string literals. *)
+Compute "hi"%string.
+
+Open Scope string_scope.
+
+(* Strings can be concatenated with the "++" operator. *)
+Compute String.append "Hello " "World". (* "Hello World" : string *)
+Compute "Hello " ++ "World". (* "Hello World" : string *)
+
+(* Strings can be compared for equality *)
+Compute String.eqb "Coq is fun!" "Coq is fun!". (* true : bool *)
+Compute "no" =? "way". (* false : bool *)
+
+Close Scope string_scope.
+
+(*** Other Modules ***)
+
+(* Other Modules in the standard library that may be of interest:
+
+• Logic : Classical logic and dependent equality
+• Arith : Basic Peano arithmetic
+• PArith : Basic positive integer arithmetic
+• NArith : Basic binary natural number arithmetic
+• ZArith : Basic relative integer arithmetic
+
+• Numbers : Various approaches to natural, integer and cyclic numbers
+ (currently axiomatically and on top of 2^31 binary words)
+• Bool : Booleans (basic functions and results)
+
+• Lists : Monomorphic and polymorphic lists (basic functions and results),
+ Streams (infinite sequences defined with co-inductive types)
+• Sets : Sets (classical, constructive, finite, infinite, power set, etc.)
+• FSets : Specification and implementations of finite sets and finite maps
+ (by lists and by AVL trees)
+• Reals : Axiomatization of real numbers (classical, basic functions,
+ integer part, fractional part, limit, derivative, Cauchy series,
+ power series and results,...)
+• Relations : Relations (definitions and basic results)
+• Sorting : Sorted list (basic definitions and heapsort correctness)
+• Strings : 8-bits characters and strings
+• Wellfounded : Well-founded relations (basic results)
+ *)
+
+(*** User-defined data types ***)
+
+(* Because Coq is dependently typed, defining type aliases is no different
+ than defining an alias for a value. *)
+
+Definition my_three : nat := 3.
+Definition my_nat : Type := nat.
+
+(* More interesting types can be defined using the Inductive vernacular.
+ Simple enumeration can be defined like so *)
+
+Inductive ml := OCaml | StandardML | Coq.
+Definition lang := Coq. (* Has type "ml". *)
+
+(* For more complicated types, you will need to specify the types of the
+ constructors. *)
+
+(* Type constructors don't need to be empty. *)
+Inductive my_number := plus_infinity
+ | nat_value : nat -> my_number.
+Compute nat_value 3. (* nat_value 3 : my_number *)
+
+
+(* Record syntax is sugar for tuple-like types. It defines named accessor
+ functions for the components. Record types are defined with the notation
+ {...} *)
+
+Record Point2d (A : Set) := mkPoint2d { x2 : A ; y2 : A }.
+(* Record values are constructed with the notation {|...|} *)
+Definition mypoint : Point2d nat := {| x2 := 2 ; y2 := 3 |}.
+Compute x2 nat mypoint. (* 2 : nat *)
+Compute mypoint.(x2 nat). (* 2 : nat *)
+
+(* Types can be parameterized, like in this type for "list of lists of
+ anything". 'a can be substituted with any type. *)
+
+Definition list_of_lists a := list (list a).
+Definition list_list_nat := list_of_lists nat.
+
+(* Types can also be recursive. Like in this type analogous to
+ built-in list of naturals. *)
+
+Inductive my_nat_list :=
+ EmptyList | NatList : nat -> my_nat_list -> my_nat_list.
+
+Compute NatList 1 EmptyList. (* NatList 1 EmptyList : my_nat_list *)
+
+(** Matching type constructors **)
+
+Inductive animal := Dog : string -> animal | Cat : string -> animal.
+
+Definition say x :=
+ match x with
+ | Dog x => (x ++ " says woof")%string
+ | Cat x => (x ++ " says meow")%string
+ end.
+
+Compute say (Cat "Fluffy"). (* "Fluffy says meow". *)
+
+(** Traversing data structures with pattern matching **)
+
+(* Recursive types can be traversed with pattern matching easily.
+ Let's see how we can traverse a data structure of the built-in list type.
+ Even though the built-in cons ("::") looks like an infix operator,
+ it's actually a type constructor and can be matched like any other. *)
+Fixpoint sum_list l :=
+ match l with
+ | [] => 0
+ | head :: tail => head + (sum_list tail)
+ end.
+
+Compute sum_list [1; 2; 3]. (* Evaluates to 6 *)
+
+
+(*** A Taste of Proving ***)
+
+(* Explaining the proof language is out of scope for this tutorial, but here
+ is a taste to whet your appetite. Check the resources below for more. *)
+
+(* A fascinating feature of dependently type based theorem provers is that
+ the same primitive constructs underly the proof language as the
+ programming features. For example, we can write and prove the
+ proposition A and B implies A in raw Gallina *)
+
+Definition my_theorem : forall A B, A /\ B -> A :=
+ fun A B ab => match ab with
+ | (conj a b) => a
+ end.
+
+(* Or we can prove it using tactics. Tactics are a macro language to help
+ build proof terms in a more natural style and automate away some
+ drudgery. *)
+
+Theorem my_theorem2 : forall A B, A /\ B -> A.
+Proof.
+ intros A B ab. destruct ab as [ a b ]. apply a.
+Qed.
+
+(* We can prove easily prove simple polynomial equalities using the
+ automated tactic ring. *)
+
+Require Import Ring.
+Require Import Arith.
+Theorem simple_poly : forall (x : nat), (x + 1) * (x + 2) = x * x + 3 * x + 2.
+ Proof. intros. ring. Qed.
+
+(* Here we prove the closed form for the sum of all numbers 1 to n using
+ induction *)
+
+Fixpoint sumn (n : nat) : nat :=
+ match n with
+ | 0 => 0
+ | (S n') => n + (sumn n')
+ end.
+
+Theorem sum_formula : forall n, 2 * (sumn n) = (n + 1) * n.
+Proof. intros n. induction n.
+ - reflexivity. (* 0 = 0 base case *)
+ - simpl. ring [IHn]. (* induction step *)
+Qed.
+```
+
+With this we have only scratched the surface of Coq. It is a massive
+ecosystem with many interesting and peculiar topics leading all the way up
+to modern research.
+
+## Further reading
+
+* [The Coq reference manual](https://coq.inria.fr/refman/)
+* [Software Foundations](https://softwarefoundations.cis.upenn.edu/)
+* [Certified Programming with Dependent Types](http://adam.chlipala.net/cpdt/)
+* [Mathematical Components](https://math-comp.github.io/mcb/)
+* [Coq'Art: The Calculus of Inductive Constructions](http://www.cse.chalmers.se/research/group/logic/TypesSS05/resources/coq/CoqArt/)
+* [FRAP](http://adam.chlipala.net/frap/)
diff --git a/crystal.html.markdown b/crystal.html.markdown
new file mode 100644
index 00000000..ae027a8d
--- /dev/null
+++ b/crystal.html.markdown
@@ -0,0 +1,554 @@
+---
+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
+
+# Five signed integer types
+1_i8.class #=> Int8
+1_i16.class #=> Int16
+1_i32.class #=> Int32
+1_i64.class #=> Int64
+1_i128.class #=> Int128
+
+# Five unsigned integer types
+1_u8.class #=> UInt8
+1_u16.class #=> UInt16
+1_u32.class #=> UInt32
+1_u64.class #=> UInt64
+1_u128.class #=> UInt128
+
+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)
+
+# Access 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 literal
+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: 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 propery 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](https://crystal-lang.org/)
diff --git a/cs-cz/elm.html.markdown b/cs-cz/elm.html.markdown
index babd46a2..42ec89e5 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.
@@ -75,14 +75,14 @@ List.head [] -- Nothing
-- K získání hodnot z dvojice použijte funkce first a second.
-- (Toto je pouze zkratka. Brzy si ukážeme, jak na to "správně".)
-fst ("elm", 42) -- "elm"
-snd ("elm", 42) -- 42
+Tuple.first ("elm", 42) -- "elm"
+Tuple.second ("elm", 42) -- 42
-- Prázná n-tice, neboli "unit", se občas používá jako zástupný symbol.
-- 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/cs-cz/javascript.html.markdown b/cs-cz/javascript.html.markdown
index cbf7687e..408ddde0 100644
--- a/cs-cz/javascript.html.markdown
+++ b/cs-cz/javascript.html.markdown
@@ -1,7 +1,7 @@
---
language: javascript
contributors:
- - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Leigh Brenecki", "https://leigh.net.au"]
- ["Ariel Krakowski", "http://www.learneroo.com"]
translators:
- ["Michal Martinek", "https://github.com/MichalMartinek"]
@@ -9,33 +9,28 @@ lang: cs-cz
filename: javascript-cz.js
---
-JavaScript byl vytvořen Brendan Eichem v roce 1995 pro Netscape. Byl původně
-zamýšlen jako jednoduchý skriptovací jazyk pro webové stránky, jako doplněk Javy,
-která byla zamýšlena pro více komplexní webové aplikace, ale jeho úzké propojení
-s webovými stránkami a vestavěná podpora v prohlížečích způsobila, že se stala
-více běžná ve webovém frontendu než Java.
+JavaScript byl vytvořen Brendanem Eichem v roce 1995 pro Netscape. Původně byl
+zamýšlen jako jednoduchý skriptovací jazyk pro webové stránky, jako doplněk
+Javy, která byla zamýšlena pro komplexnější webové aplikace. Úzké propojení
+JavaScriptu s webovými stránkami a vestavěná podpora v prohlížečích způsobila,
+že se stal ve webovém frontendu běžnějším než Java.
-
-JavaScript není omezen pouze na webové prohlížeče, např. projekt Node.js,
-který zprostředkovává samostatně běžící prostředí V8 JavaScriptového enginu z
-Google Chrome se stává více a více oblíbený pro serverovou část webových aplikací.
-
-Zpětná vazba je velmi ceněná. Autora článku můžete kontaktovat (anglicky) na
-[@adambrenecki](https://twitter.com/adambrenecki), nebo
-[adam@brenecki.id.au](mailto:adam@brenecki.id.au), nebo mě, jakožto překladatele,
-na [martinek@ludis.me](mailto:martinek@ludis.me).
+JavaScript není omezen pouze na webové prohlížeče. Např. projekt Node.js,
+který zprostředkovává samostatně běžící prostředí V8 JavaScriptového jádra z
+Google Chrome se stává stále oblíbenější i pro serverovou část webových
+aplikací.
```js
-// Komentáře jsou jako v zayku C. Jednořádkové komentáře začínájí dvojitým lomítkem,
+// Jednořádkové komentáře začínají dvojitým lomítkem,
/* a víceřádkové komentáře začínají lomítkem s hvězdičkou
a končí hvězdičkou s lomítkem */
-// Vyrazu můžou být spuštěny pomocí ;
+// Příkazy mohou být ukončeny středníkem ;
delejNeco();
-// ... ale nemusí, středníky jsou automaticky vloženy kdekoliv,
-// kde končí řádka, kromě pár speciálních případů
-delejNeco()
+// ... ale nemusí, protože středníky jsou automaticky vloženy kdekoliv,
+// kde končí řádka, kromě pár speciálních případů.
+delejNeco();
// Protože tyto případy můžou způsobit neočekávané výsledky, budeme
// středníky v našem návodu používat.
@@ -44,12 +39,12 @@ delejNeco()
// 1. Čísla, řetězce a operátory
// JavaScript má jeden číselný typ (čímž je 64-bitový IEEE 754 double).
-// Double má 52-bit přesnost, což je dostatečně přesné pro ukládání celých čísel
-// do 9✕10¹⁵.
+// Double má 52-bitovou přesnost, což je dostatečně přesné pro ukládání celých
+// čísel až do 9✕10¹⁵.
3; // = 3
1.5; // = 1.5
-// Základní matematické operace fungují, jak byste očekávali
+// Základní matematické operace fungují tak, jak byste očekávali
1 + 1; // = 2
0.1 + 0.2; // = 0.30000000000000004
8 - 1; // = 7
@@ -65,30 +60,30 @@ delejNeco()
18.5 % 7; // = 4.5
// Bitové operace také fungují; když provádíte bitové operace, desetinné číslo
-// (float) se převede na celé číslo (int) se znaménkem *do* 32 bitů
+// (float) se převede na celé číslo (int) se znaménkem *až do* 32 bitů
1 << 2; // = 4
// Přednost se vynucuje závorkami.
(1 + 3) * 2; // = 8
-// Existují 3 hodnoty mimo obor reálných čísel
+// Existují 3 hodnoty mimo obor reálných čísel:
Infinity; // + nekonečno; výsledek např. 1/0
-Infinity; // - nekonečno; výsledek např. -1/0
NaN; // výsledek např. 0/0, znamená, že výsledek není číslo ('Not a Number')
-// Také existují hodnoty typu bool
+// Také existují hodnoty typu boolean.
true; // pravda
false; // nepravda
-// Řetězce znaků jsou obaleny ' nebo ".
+// Řetězce znaků jsou obaleny ' nebo ".
'abc';
-"Ahoj světe!";
+"Hello, world";
-// Negace se tvoří pomocí !
+// Negace se tvoří pomocí znaku !
!true; // = false
!false; // = true
-// Rovnost se porovnává ===
+// Rovnost se porovnává pomocí ===
1 === 1; // = true
2 === 1; // = false
@@ -103,16 +98,16 @@ false; // nepravda
2 >= 2; // = true
// Řetězce znaků se spojují pomocí +
-"Ahoj " + "světe!"; // = "Ahoj světe!"
+"Hello " + "world!"; // = "Hello world!"
-// ... což funguje nejenom s řetězci
+// ... což funguje nejen s řetězci
"1, 2, " + 3; // = "1, 2, 3"
-"Ahoj " + ["světe", "!"] // = "Ahoj světe,!"
+"Hello " + ["world", "!"]; // = "Hello world,!"
// a porovnávají se pomocí < nebo >
"a" < "b"; // = true
-// Rovnost s převodem typů se dělá pomocí == ...
+// Rovnost s převodem typů se dělá za pomoci dvojitého rovnítka...
"5" == 5; // = true
null == undefined; // = true
@@ -124,24 +119,24 @@ null === undefined; // = false
13 + !0; // 14
"13" + !0; // '13true'
-// Můžeme přistupovat k jednotlivým znakům v řetězci pomocí charAt`
+// Můžeme přistupovat k jednotlivým znakům v řetězci pomocí `charAt`
"Toto je řetězec".charAt(0); // = 'T'
-// ...nebo použít `substring` k získání podřetězce
-"Ahoj světe".substring(0, 4); // = "Ahoj"
+// ...nebo použít `substring` k získání podřetězce.
+"Hello world".substring(0, 5); // = "Hello"
-// `length` znamená délka a je to vlastnost, takže nepoužívejte ()
-"Ahoj".length; // = 4
+// `length` znamená délka a je to vlastnost, takže nepoužívejte ().
+"Hello".length; // = 5
// Existují také typy `null` a `undefined`.
-null; // značí, že žádnou hodnotu
-undefined; // značí, že hodnota nebyla definovaná (ikdyž
+null; // obvykle označuje něco záměrně bez hodnoty
+undefined; // obvykle označuje, že hodnota není momentálně definovaná (ačkoli
// `undefined` je hodnota sama o sobě)
-// false, null, undefined, NaN, 0 and "" vrací nepravdu (false). Všechno ostatní
-// vrací pravdu (true)..
-// Všimněte si, že 0 vrací nepravdu, ale "0" vrací pravdu, ikdyž 0 == "0"
-// vrací pravdu
+// false, null, undefined, NaN, 0 a "" vrací nepravdu (false). Všechno ostatní
+// vrací pravdu (true).
+// Všimněte si, že 0 vrací nepravdu, ale "0" vrací pravdu, i když 0 == "0"
+// vrací pravdu.
///////////////////////////////////
// 2. Proměnné, pole a objekty
@@ -151,11 +146,11 @@ undefined; // značí, že hodnota nebyla definovaná (ikdyž
// znak `=`.
var promenna = 5;
-// když vynecháte slůvko 'var' nedostanete chybovou hlášku...
+// Když vynecháte slůvko 'var', nedostanete chybovou hlášku...
jinaPromenna = 10;
-// ...ale vaše proměnná bude vytvořena globálně, bude vytvořena v globálním
-// oblasti působnosti, ne jenom v lokálním tam, kde jste ji vytvořili
+// ...ale vaše proměnná bude vytvořena globálně. Bude vytvořena v globální
+// oblasti působnosti, tedy nejenom v lokální tam, kde jste ji vytvořili.
// Proměnné vytvořené bez přiřazení obsahují hodnotu undefined.
var dalsiPromenna; // = undefined
@@ -163,114 +158,136 @@ var dalsiPromenna; // = undefined
// Pokud chcete vytvořit několik proměnných najednou, můžete je oddělit čárkou
var someFourthVar = 2, someFifthVar = 4;
-// Existuje kratší forma pro matematické operace na proměnné
+// Existuje kratší forma pro matematické operace nad proměnnými
promenna += 5; // se provede stejně jako promenna = promenna + 5;
-// promenna je ted 10
+// promenna je teď 10
promenna *= 10; // teď je promenna rovna 100
// a tohle je způsob, jak přičítat a odečítat 1
promenna++; // teď je promenna 101
promenna--; // zpět na 100
-// Pole jsou uspořádané seznamy hodnot jakéhokoliv typu
-var mojePole = ["Ahoj", 45, true];
+// Pole jsou uspořádané seznamy hodnot jakéhokoliv typu.
+var myArray = ["Ahoj", 45, true];
// Jednotlivé hodnoty jsou přístupné přes hranaté závorky.
// Členové pole se začínají počítat na nule.
myArray[1]; // = 45
-// Pole je proměnlivé délky a členové se můžou měnit
-myArray.push("Světe");
+// Pole je proměnlivé délky a členové se můžou měnit.
+myArray.push("World");
myArray.length; // = 4
// Přidání/změna na specifickém indexu
myArray[3] = "Hello";
-// JavaScriptové objekty jsou stejné jako asociativní pole v jinných programovacích
+// Přidání nebo odebrání člena ze začátku nebo konce pole
+myArray.unshift(3); // Přidej jako první člen
+someVar = myArray.shift(); // Odstraň prvního člena a vrať jeho hodnotu
+myArray.push(3); // Přidej jako poslední člen
+someVar = myArray.pop(); // Odstraň posledního člena a vrať jeho hodnotu
+
+// Spoj všechny členy pole středníkem
+var myArray0 = [32,false,"js",12,56,90];
+myArray0.join(";") // = "32;false;js;12;56;90"
+
+// Vrať část pole s elementy od pozice 1 (včetně) do pozice 4 (nepočítaje)
+myArray0.slice(1,4); // = [false,"js",12]
+
+// Odstraň čtyři členy od pozice 2, vlož následující
+// "hi","wr" and "ld"; vrať odstraněné členy
+myArray0.splice(2,4,"hi","wr","ld"); // = ["js",12,56,90]
+// myArray0 === [32,false,"hi","wr","ld"]
+
+// JavaScriptové objekty jsou stejné jako asociativní pole v jiných programovacích
// jazycích: je to neuspořádaná množina páru hodnot - klíč:hodnota.
-var mujObjekt = {klic1: "Ahoj", klic2: "světe"};
+var mujObjekt = {klic1: "Hello", klic2: "World"};
-// Klíče jsou řetězce, ale nejsou povinné uvozovky, pokud jsou validní
-// JavaScriptové identifikátory. Hodnoty můžou být jakéhokoliv typu-
+// Klíče jsou řetězce, ale nemusí mít povinné uvozovky, pokud jsou validními
+// JavaScriptovými identifikátory. Hodnoty můžou být jakéhokoliv typu.
var mujObjekt = {klic: "mojeHodnota", "muj jiny klic": 4};
// K hodnotám můžeme přistupovat opět pomocí hranatých závorek
-myObj["muj jiny klic"]; // = 4
+mujObjekt["muj jiny klic"]; // = 4
// ... nebo pokud je klíč platným identifikátorem, můžeme přistupovat k
// hodnotám i přes tečku
mujObjekt.klic; // = "mojeHodnota"
// Objekty jsou měnitelné, můžeme upravit hodnoty, nebo přidat nové klíče.
-myObj.mujDalsiKlic = true;
+mujObjekt.mujDalsiKlic = true;
-// Pokud se snažíte přistoupit ke klíči, který není nastaven, dostanete undefined
-myObj.dalsiKlic; // = undefined
+// Pokud se snažíte přistoupit ke klíči, který neexistuje, dostanete undefined.
+mujObjekt.dalsiKlic; // = undefined
///////////////////////////////////
// 3. Řízení toku programu
-// Syntaxe pro tuto sekci je prakticky stejná jako pro Javu
-
-// `if` (když) funguje, jak byste čekali.
+// Funkce `if` funguje, jak byste čekali.
var pocet = 1;
if (pocet == 3){
// provede, když se pocet rovná 3
} else if (pocet == 4){
// provede, když se pocet rovná 4
} else {
- // provede, když je pocet cokoliv jinného
+ // provede, když je pocet cokoliv jiného
}
-// Stejně tak cyklus while
+// Stejně tak cyklus `while`.
while (true){
- // nekonečný cyklus
+ // nekonečný cyklus!
}
-// Do-while cyklus je stejný jako while, akorát se vždy provede aspoň jednou
+// Do-while cyklus je stejný jako while, akorát se vždy provede aspoň jednou.
var vstup;
do {
vstup = nactiVstup();
} while (!jeValidni(vstup))
-// Cyklus for je stejný jako v Javě nebo jazyku C
+// Cyklus `for` je stejný jako v Javě nebo jazyku C:
// inicializace; podmínka pro pokračování; iterace.
-for (var i = 0; i < 3; i++){
- // provede třikrát
+for (var i = 0; i < 5; i++){
+ // provede se pětkrát
}
-// Cyklus For-in iteruje přes každo vlastnost prototypu
-var popis = "";
-var osoba = {prijmeni:"Paul", jmeno:"Ken", vek:18};
-for (var x in osoba){
- popis += osoba[x] + " ";
+// Opuštění cyklu s návěštím je podobné jako v Javě
+outer:
+for (var i = 0; i < 10; i++) {
+ for (var j = 0; j < 10; j++) {
+ if (i == 5 && j ==5) {
+ break outer;
+ // opustí vnější (outer) cyklus místo pouze vnitřního (inner) cyklu
+ }
+ }
}
-//Když chcete iterovat přes vlastnosti, které jsou přímo na objektu a nejsou
-//zděněné z prototypů, kontrolujte vlastnosti přes hasOwnProperty()
+// Cyklus For-in iteruje přes každou vlastnost prototypu
var popis = "";
-var osoba = {prijmeni:"Jan", jmeno:"Novák", vek:18};
+var osoba = {prijmeni:"Paul", jmeno:"Ken", vek:18};
for (var x in osoba){
- if (osoba.hasOwnProperty(x)){
- popis += osoba[x] + " ";
- }
-}
+ popis += osoba[x] + " ";
+} // popis = 'Paul Ken 18 '
-// for-in by neměl být použit pro pole, pokud záleží na pořadí indexů.
-// Neexistuje jistota, že for-in je vrátí ve správném pořadí.
+// Příkaz for/of umožňuje iterovat iterovatelné objekty (včetně vestavěných typů
+// String, Array, například polím podobným argumentům nebo NodeList objektům,
+// TypeArray, Map a Set, či uživatelsky definované iterovatelné objekty).
+var myPets = "";
+var pets = ["cat", "dog", "hamster", "hedgehog"];
+for (var pet of pets){
+ myPets += pet + " ";
+} // myPets = 'cat dog hamster hedgehog '
// && je logické a, || je logické nebo
if (dum.velikost == "velký" && dum.barva == "modrá"){
dum.obsahuje = "medvěd";
}
if (barva == "červená" || barva == "modrá"){
- // barva je červená nebo modtrá
+ // barva je červená nebo modrá
}
// && a || jsou praktické i pro nastavení základních hodnot
var jmeno = nejakeJmeno || "default";
-
// `switch` zkoumá přesnou rovnost (===)
// Používejte 'break;' po každé možnosti, jinak se provede i možnost za ní.
znamka = 'B';
@@ -289,8 +306,9 @@ switch (znamka) {
break;
}
+
////////////////////////////////////////////////////////
-// 4. Funckce, Oblast platnosti (scope) a Vnitřní funkce
+// 4. Funkce, Oblast platnosti (scope) a Vnitřní funkce
// JavaScriptové funkce jsou definovány slůvkem `function`.
function funkce(text){
@@ -302,12 +320,9 @@ funkce("něco"); // = "NĚCO"
// jako slůvko return, jinak se vrátí 'undefined', kvůli automatickému vkládání
// středníků. Platí to zejména pro Allmanův styl zápisu.
-function funkce()
-{
+function funkce(){
return // <- zde je automaticky vložen středník
- {
- tohleJe: "vlastnost objektu"
- }
+ { tohleJe: "vlastnost objektu"};
}
funkce(); // = undefined
@@ -327,9 +342,9 @@ function myFunction(){
setInterval(myFunction, 5000);
// Objekty funkcí nemusíme ani deklarovat pomocí jména, můžeme je napsat jako
-// ananymní funkci přímo vloženou jako argument
+// anonymní funkci přímo vloženou jako argument
setTimeout(function(){
- // tento kód bude zavolán za 5 vteřin
+ // tento kód bude zavolán za 5 vteřin
}, 5000);
// JavaScript má oblast platnosti funkce, funkce ho mají, ale jiné bloky ne
@@ -339,21 +354,21 @@ if (true){
i; // = 5 - ne undefined, jak byste očekávali v jazyku, kde mají bloky svůj
// rámec působnosti
-// Toto je běžný model,který chrání před únikem dočasných proměnných do
+// Toto je běžný model, který chrání před únikem dočasných proměnných do
//globální oblasti
(function(){
var docasna = 5;
- // Můžeme přistupovat k globálního oblasti přes přiřazování globalním
+ // Můžeme přistupovat ke globálního oblasti přes přiřazování globálním
// objektům. Ve webovém prohlížeči je to vždy 'window`. Globální objekt
- // může mít v jiných prostředích jako Node.js jinné jméno.
+ // může mít v jiných prostředích jako Node.js jiné jméno.
window.trvala = 10;
})();
docasna; // způsobí ReferenceError
trvala; // = 10
-// Jedna z nejvice mocných vlastnosti JavaScriptu je vnitřní funkce. Je to funkce
-// definovaná v jinné funkci, vnitřní funkce má přístup ke všem proměnným ve
-// vnější funkci, dokonce i poté, co funkce skončí
+// Jedna z nejmocnějších vlastností JavaScriptu je vnitřní funkce. Je to funkce
+// definovaná v jiné funkci. Vnitřní funkce má přístup ke všem proměnným ve
+// vnější funkci, dokonce i poté, co vnější funkce skončí.
function ahojPoPetiVterinach(jmeno){
var prompt = "Ahoj, " + jmeno + "!";
// Vnitřní funkce je dána do lokální oblasti platnosti, jako kdyby byla
@@ -362,33 +377,33 @@ function ahojPoPetiVterinach(jmeno){
alert(prompt);
}
setTimeout(vnitrni, 5000);
- // setTimeout je asynchronní, takže funkce ahojPoPetiVterinach se ukončí
- // okamžitě, ale setTimeout zavolá funkci vnitrni až poté. Avšak protože
- // vnitrni je definována přes ahojPoPetiVterinach, má pořád přístup k
+ // setTimeout je asynchronní, takže se funkce ahojPoPetiVterinach ukončí
+ // okamžitě, ale setTimeout zavolá funkci vnitrni až poté. Avšak
+ // vnitrni je definována přes ahojPoPetiVterinach a má pořád přístup k
// proměnné prompt, když je konečně zavolána.
}
ahojPoPetiVterinach("Adam"); // otevře popup s "Ahoj, Adam!" za 5s
///////////////////////////////////////////////////
-// 5. Více o objektech, konstuktorech a prototypech
+// 5. Více o objektech, konstruktorech a prototypech
-// Objekty můžou obsahovat funkce
+// Objekty můžou obsahovat funkce.
var mujObjekt = {
mojeFunkce: function(){
- return "Ahoj světe!";
+ return "Hello world!";
}
};
-mujObjekt.mojeFunkce(); // = "Ahoj světe!"
+mujObjekt.mojeFunkce(); // = "Hello world!"
// Když jsou funkce z objektu zavolány, můžou přistupovat k objektu přes slůvko
// 'this''
var mujObjekt = {
- text: "Ahoj světe!",
+ text: "Hello world!",
mojeFunkce: function(){
return this.text;
}
};
-mujObjekt.mojeFunkce(); // = "Ahoj světe!"
+mujObjekt.mojeFunkce(); // = "Hello world!"
// Slůvko this je nastaveno k tomu, kde je voláno, ne k tomu, kde je definováno
// Takže naše funkce nebude fungovat, když nebude v kontextu objektu.
@@ -396,23 +411,23 @@ var mojeFunkce = mujObjekt.mojeFunkce;
mojeFunkce(); // = undefined
// Opačně, funkce může být přiřazena objektu a může přistupovat k objektu přes
-// this, i když nebyla přímo v definici-
+// this, i když nebyla přímo v definici.
var mojeDalsiFunkce = function(){
return this.text.toUpperCase();
}
mujObjekt.mojeDalsiFunkce = mojeDalsiFunkce;
-mujObjekt.mojeDalsiFunkce(); // = "AHOJ SVĚTE!"
+mujObjekt.mojeDalsiFunkce(); // = "HELLO WORLD!"
// Můžeme také specifikovat, v jakém kontextu má být funkce volána pomocí
// `call` nebo `apply`.
var dalsiFunkce = function(s){
return this.text + s;
-}
-dalsiFunkce.call(mujObjekt, " A ahoj měsíci!"); // = "Ahoj světe! A ahoj měsíci!"
+};
+dalsiFunkce.call(mujObjekt, " A ahoj měsíci!"); // = "Hello world! A ahoj měsíci!"
-// Funkce `apply`je velmi podobná, akorát bere jako druhý argument pole argumentů
-dalsiFunkce.apply(mujObjekt, [" A ahoj slunce!"]); // = "Ahoj světe! A ahoj slunce!"
+// Funkce `apply`je velmi podobná, pouze bere jako druhý argument pole argumentů
+dalsiFunkce.apply(mujObjekt, [" A ahoj slunce!"]); // = "Hello world! A ahoj slunce!"
// To je praktické, když pracujete s funkcí, která bere sekvenci argumentů a
// chcete předat pole.
@@ -425,38 +440,42 @@ Math.min.apply(Math, [42, 6, 27]); // = 6
// použijte `bind`.
var pripojenaFunkce = dalsiFunkce.bind(mujObjekt);
-pripojenaFunkce(" A ahoj Saturne!"); // = "Ahoj světe! A ahoj Saturne!"
+pripojenaFunkce(" A ahoj Saturne!"); // = "Hello world! A ahoj Saturne!"
-// `bind` může být použito čatečně částečně i k používání
+// `bind` může být použito částečně k provázání funkcí
-var nasobeni = function(a, b){ return a * b; }
+var nasobeni = function(a, b){ return a * b; };
var zdvojeni = nasobeni.bind(this, 2);
zdvojeni(8); // = 16
// Když zavoláte funkci se slůvkem 'new', vytvoří se nový objekt a
// a udělá se dostupný funkcím skrz slůvko 'this'. Funkcím volaným takto se říká
-// konstruktory
+// konstruktory.
var MujKonstruktor = function(){
this.mojeCislo = 5;
-}
+};
mujObjekt = new MujKonstruktor(); // = {mojeCislo: 5}
mujObjekt.mojeCislo; // = 5
-// Každý JsavaScriptový objekt má prototyp. Když budete přistupovat k vlasnosti
-// objektu, který neexistuje na objektu, tak se JS koukne do prototypu.
+// Na rozdíl od nejznámějších objektově orientovaných jazyků, JavaScript nezná
+// koncept instancí vytvořených z tříd. Místo toho Javascript kombinuje
+// vytváření instancí a dědění do konceptu zvaného 'prototyp'.
+
+// Každý JavaScriptový objekt má prototyp. Když budete přistupovat k vlastnosti
+// objektu, který neexistuje na objektu, tak se JS podívá do prototypu.
// Některé JS implementace vám umožní přistupovat k prototypu přes magickou
// vlastnost '__proto__'. I když je toto užitečné k vysvětlování prototypů, není
-// to součást standardu, ke standartní způsobu k používání prototypu se dostaneme
-// později.
+// to součást standardu. Ke standardnímu způsobu používání prototypu se
+// dostaneme později.
var mujObjekt = {
- mujText: "Ahoj svete!"
+ mujText: "Hello world!"
};
var mujPrototyp = {
smyslZivota: 42,
mojeFunkce: function(){
- return this.mujText.toLowerCase()
+ return this.mujText.toLowerCase();
}
};
@@ -464,7 +483,7 @@ mujObjekt.__proto__ = mujPrototyp;
mujObjekt.smyslZivota; // = 42
// Toto funguje i pro funkce
-mujObjekt.mojeFunkce(); // = "Ahoj světe!"
+mujObjekt.mojeFunkce(); // = "Hello world!"
// Samozřejmě, pokud není vlastnost na vašem prototypu, tak se hledá na
// prototypu od prototypu atd.
@@ -474,21 +493,41 @@ mujPrototyp.__proto__ = {
mujObjekt.mujBoolean; // = true
-// Zde neni žádné kopírování; každý objekt ukládá referenci na svůj prototyp
-// Toto znamená, že můžeme měnit prototyp a změny se projeví všude
+// Zde není žádné kopírování; každý objekt ukládá referenci na svůj prototyp
+// Toto znamená, že můžeme měnit prototyp a změny se projeví všude.
mujPrototyp.smyslZivota = 43;
-mujObjekt.smyslZivota // = 43
+mujObjekt.smyslZivota; // = 43
+
+// Příkaz for/in umožňuje iterovat vlastnosti objektu až do úrovně null
+// prototypu.
+for (var x in myObj){
+ console.log(myObj[x]);
+}
+///Vypíše:
+// Hello world!
+// 43
+// [Function: myFunc]
+
+// Pro výpis pouze vlastností patřících danému objektu a nikoli jeho prototypu,
+// použijte kontrolu pomocí `hasOwnProperty()`.
+for (var x in myObj){
+ if (myObj.hasOwnProperty(x)){
+ console.log(myObj[x]);
+ }
+}
+///Vypíše:
+// Hello world!
// Zmínili jsme již předtím, že '__proto__' není ve standardu a není cesta, jak
// měnit prototyp existujícího objektu. Avšak existují možnosti, jak vytvořit
-// nový objekt s daným prototypem
+// nový objekt s daným prototypem.
// První je Object.create, což je nedávný přídavek do JS a není dostupný zatím
// ve všech implementacích.
var mujObjekt = Object.create(mujPrototyp);
-mujObjekt.smyslZivota // = 43
+mujObjekt.smyslZivota; // = 43
-// Druhý způsob, který funguje všude je pomocí konstuktoru. Konstruktor má
+// Druhý způsob, který funguje všude, je pomocí konstruktoru. Konstruktor má
// vlastnost jménem prototype. Toto *není* prototyp samotného konstruktoru, ale
// prototyp nového objektu.
MujKonstruktor.prototype = {
@@ -499,10 +538,10 @@ MujKonstruktor.prototype = {
};
var mujObjekt2 = new MujKonstruktor();
mujObjekt2.ziskejMojeCislo(); // = 5
-mujObjekt2.mojeCislo = 6
+mujObjekt2.mojeCislo = 6;
mujObjekt2.ziskejMojeCislo(); // = 6
-// Vestavěnné typy jako čísla nebo řetězce mají také konstruktory, které vytváří
+// Vestavěné typy jako čísla nebo řetězce mají také konstruktory, které vytváří
// ekvivalentní obalovací objekty (wrappery).
var mojeCislo = 12;
var mojeCisloObj = new Number(12);
@@ -521,7 +560,7 @@ if (new Number(0)){
// a objekty jsou vždy pravdivé
}
-// Avšak, obalovací objekty a normální vestavěnné typy sdílejí prototyp, takže
+// Avšak, obalovací objekty a normální vestavěné typy sdílejí prototyp, takže
// můžete přidat funkcionalitu k řetězci
String.prototype.prvniZnak = function(){
return this.charAt(0);
@@ -530,45 +569,60 @@ String.prototype.prvniZnak = function(){
// Tento fakt je často používán v polyfillech, což je implementace novějších
// vlastností JavaScriptu do starších variant, takže je můžete používat třeba
-// ve starých prohlížečích
+// ve starých prohlížečích.
-// Pro příkklad, zmínili jsme, že Object.create není dostupný ve všech
-// implementacích, můžeme si avšak přidat pomocí polyfillu
+// Na příklad jsme zmínili, že Object.create není dostupný ve všech
+// implementacích, ale můžeme si ho přidat pomocí polyfillu:
if (Object.create === undefined){ // nebudeme ho přepisovat, když existuje
Object.create = function(proto){
// vytvoříme dočasný konstruktor
var Constructor = function(){};
Constructor.prototype = proto;
- // ten použijeme k vytvoření nového s prototypem
+ // ten použijeme k vytvoření nového objektu s prototypem
return new Constructor();
- }
+ };
}
```
## Kam dál
-[Mozilla Developer
-Network](https://developer.mozilla.org/en-US/docs/Web/JavaScript) obsahuje
-perfektní dokumentaci pro JavaScript, který je používaný v prohlížečích. Navíc
-je to i wiki, takže jakmile se naučíte více, můžete pomoci ostatním, tím, že
-přispějete svými znalostmi.
+[Mozilla Developer Network][1] obsahuje perfektní dokumentaci pro JavaScript,
+který je používaný v prohlížečích. Navíc je to i wiki, takže jakmile se naučíte
+více, můžete pomoci ostatním tím, že přispějete svými znalostmi.
-MDN's [A re-introduction to
-JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
+MDN's [A re-introduction to JavaScript][2]
pojednává o konceptech vysvětlených zde v mnohem větší hloubce. Tento návod
-pokrývá hlavně JavaScript sám o sobě. Pokud se chcete naučit více, jak se používá
-na webových stránkách, začněte tím, že se kouknete na [DOM](https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core)
+pokrývá hlavně JavaScript sám o sobě. Pokud se chcete naučit, jak se používá
+na webových stránkách, začněte tím, že se podíváte na [DOM][3]
+
+[Learn Javascript by Example and with Challenges][4]
+je varianta tohoto návodu i s úkoly.
+
+[JavaScript Garden][5] je sbírka příkladů těch nejnepředvídatelnějších částí
+tohoto jazyka.
+
+[JavaScript: The Definitive Guide][6] je klasická výuková kniha.
+
+[Eloquent Javascript][8] od Marijn Haverbeke je výbornou JS knihou/e-knihou.
-[Learn Javascript by Example and with Challenges](http://www.learneroo.com/modules/64/nodes/350) je varianta tohoto
-návodu i s úkoly-
+[Javascript: The Right Way][10] je průvodcem JavaScriptem pro začínající
+vývojáře i pomocníkem pro zkušené vývojáře, kteří si chtějí prohloubit své
+znalosti.
-[JavaScript Garden](http://bonsaiden.github.io/JavaScript-Garden/) je sbírka
-příkladů těch nejvíce nepředvídatelných částí tohoto jazyka.
+[Javascript:Info][11] je moderním JavaScriptovým průvodcem, který pokrývá
+základní i pokročilé témata velice výstižným výkladem.
-[JavaScript: The Definitive Guide](http://www.amazon.com/gp/product/0596805527/)
-je klasická výuková kniha.
+Jako dodatek k přímým autorům tohoto článku byly na těchto stránkách části
+obsahu převzaty z Pythonního tutoriálu Louiho Dinha, a tak0 z [JS Tutorial][7]
+na stránkách Mozilla Developer Network.
-Jako dodatek k přímým autorům tohoto článku, některý obsah byl přizpůsoben z
-Pythoního tutoriálu od Louie Dinh na této stráce, a z [JS
-Tutorial](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
-z Mozilla Developer Network.
+[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript
+[2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
+[3]: https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core
+[4]: http://www.learneroo.com/modules/64/nodes/350
+[5]: http://bonsaiden.github.io/JavaScript-Garden/
+[6]: http://www.amazon.com/gp/product/0596805527/
+[7]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
+[8]: http://eloquentjavascript.net/
+[10]: http://jstherightway.org/
+[11]: https://javascript.info/
diff --git a/cs-cz/markdown.html.markdown b/cs-cz/markdown.html.markdown
index 568e4343..35becf94 100644
--- a/cs-cz/markdown.html.markdown
+++ b/cs-cz/markdown.html.markdown
@@ -13,7 +13,7 @@ Markdown byl vytvořen Johnem Gruberem v roce 2004. Je zamýšlen jako lehce či
a psatelná syntaxe, která je jednoduše převeditelná do HTML (a dnes i do mnoha
dalších formátů)
-```markdown
+```md
<!-- Markdown je nadstavba nad HTML, takže jakýkoliv kód HTML je validní
Markdown, to znamená, že můžeme používat HTML elementy, třeba jako komentář, a
nebudou ovlivněny parserem Markdownu. Avšak, pokud vytvoříte HTML element v
diff --git a/cs-cz/python3.html.markdown b/cs-cz/python.html.markdown
index 581ed3a3..71509460 100644
--- a/cs-cz/python3.html.markdown
+++ b/cs-cz/python.html.markdown
@@ -1,5 +1,5 @@
---
-language: python3
+language: Python
contributors:
- ["Louie Dinh", "http://pythonpracticeprojects.com"]
- ["Steven Basart", "http://github.com/xksteven"]
@@ -7,7 +7,7 @@ contributors:
- ["Tomáš Bedřich", "http://tbedrich.cz"]
translators:
- ["Tomáš Bedřich", "http://tbedrich.cz"]
-filename: learnpython3-cz.py
+filename: learnpython-cz.py
lang: cs-cz
---
@@ -17,7 +17,7 @@ Zamiloval jsem si Python pro jeho syntaktickou čistotu - je to vlastně spustit
Vaše zpětná vazba je vítána! Můžete mě zastihnout na [@louiedinh](http://twitter.com/louiedinh) nebo louiedinh [at] [email od googlu] anglicky,
autora českého překladu pak na [@tbedrich](http://twitter.com/tbedrich) nebo ja [at] tbedrich.cz
-Poznámka: Tento článek je zaměřen na Python 3. Zde se můžete [naučit starší Python 2.7](http://learnxinyminutes.com/docs/python/).
+Poznámka: Tento článek je zaměřen na Python 3. Zde se můžete [naučit starší Python 2.7](http://learnxinyminutes.com/docs/pythonlegacy/).
```python
@@ -42,7 +42,8 @@ Poznámka: Tento článek je zaměřen na Python 3. Zde se můžete [naučit sta
# Až na dělení, které vrací desetinné číslo
35 / 5 # => 7.0
-# Při celočíselném dělení je desetinná část oříznuta (pro kladná i záporná čísla)
+# Při celočíselném dělení je na výsledek aplikována funkce floor(),
+# což znamená zaokrouhlení směrem k mínus nekonečnu (pro kladná i záporná čísla).
5 // 3 # => 1
5.0 // 3.0 # => 1.0 # celočíselně dělit lze i desetinným číslem
-5 // 3 # => -2
@@ -76,9 +77,13 @@ False or True # => True
# Používání logických operátorů s čísly
0 and 2 # => 0
-5 or 0 # => -5
-0 == False # => True
-2 == True # => False
-1 == True # => True
+
+# Při porovnání s boolean hodnotou nepoužívejte operátor rovnosti "==".
+# Stejně jako u hodnoty None.
+# Viz PEP8: https://www.python.org/dev/peps/pep-0008/
+0 is False # => True
+2 is True # => False
+1 is True # => True
# Rovnost je ==
1 == 1 # => True
@@ -99,11 +104,11 @@ False or True # => True
2 < 3 < 2 # => False
-# Řetězce používají " nebo ' a mohou obsahovat UTF8 znaky
+# Řetězce používají " nebo ' a mohou obsahovat unicode znaky
"Toto je řetězec."
'Toto je také řetězec.'
-# Řetězce se také dají sčítat, ale nepoužívejte to
+# Řetězce se také dají slučovat
"Hello " + "world!" # => "Hello world!"
# Dají se spojovat i bez '+'
"Hello " "world!" # => "Hello world!"
@@ -133,12 +138,14 @@ None # => None
"něco" is None # => False
None is None # => True
-# None, 0, a prázdný řetězec/seznam/slovník se vyhodnotí jako False
+# None, 0, a prázdný řetězec/seznam/N-tice/slovník/množina se vyhodnotí jako False
# Vše ostatní se vyhodnotí jako True
-bool(0) # => False
-bool("") # => False
-bool([]) # => False
-bool({}) # => False
+bool(0) # => False
+bool("") # => False
+bool([]) # => False
+bool(tuple()) # => False
+bool({}) # => False
+bool(set()) # => False
####################################################
@@ -152,10 +159,12 @@ print("Jsem 3. Python 3.")
# Konvence je používat male_pismo_s_podtrzitky
nazev_promenne = 5
nazev_promenne # => 5
-# Názvy proměnných mohou obsahovat i UTF8 znaky
+# Názvy proměnných mohou obsahovat i unicode znaky, ale nedělejte to.
+# Viz PEP 3131 -- Supporting Non-ASCII Identifiers:
+# https://www.python.org/dev/peps/pep-3131/
název_proměnné = 5
-# Přístup k předtím nepoužité proměnné vyvolá výjimku
+# Přístup k předtím nedefinované proměnné vyvolá výjimku
# Odchytávání vyjímek - viz další kapitola
neznama_promenna # Vyhodí NameError
@@ -199,7 +208,7 @@ sez[::-1] # => [3, 4, 2, 1]
# Odebírat prvky ze seznamu lze pomocí del
del sez[2] # sez je nyní [1, 2, 3]
-# Seznamy můžete sčítat
+# Seznamy můžete slučovat
# Hodnoty sez a jiny_seznam přitom nejsou změněny
sez + jiny_seznam # => [1, 2, 3, 4, 5, 6]
@@ -566,7 +575,7 @@ Clovek.odkaslej_si() # => "*ehm*"
# Lze importovat moduly
import math
-print(math.sqrt(16.0)) # => 4
+print(math.sqrt(16.0)) # => 4.0
# Lze také importovat pouze vybrané funkce z modulu
from math import ceil, floor
@@ -596,18 +605,21 @@ dir(math)
# Generátory jsou funkce, které místo return obsahují yield
def nasobicka_2(sekvence):
for i in sekvence:
+ print("Zpracovávám číslo {}".format(i))
yield 2 * i
# Generátor generuje hodnoty postupně, jak jsou potřeba. Místo toho, aby vrátil
# celou sekvenci s prvky vynásobenými dvěma, provádí jeden výpočet v každé iteraci.
-# To znamená, že čísla větší než 15 se v metodě nasobicka_2 vůbec nezpracují.
+for nasobek in nasobicka_2([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]):
+ # Vypíše postupně: "Zpracovávám číslo 1", ..., "Zpracovávám číslo 5"
+ if nasobek >= 10:
+ break
# Funkce range() je také generátor - vytváření seznamu 900000000 prvků by zabralo
# hodně času i paměti, proto se místo toho čísla generují postupně.
-
-for i in nasobicka_2(range(900000000)):
- print(i) # Vypíše čísla 0, 2, 4, 6, 8, ... 30
- if i >= 30:
+for nasobek in nasobicka_2(range(900000000)):
+ # Vypíše postupně: "Zpracovávám číslo 1", ..., "Zpracovávám číslo 5"
+ if nasobek >= 10:
break
@@ -627,7 +639,7 @@ def nekolikrat(puvodni_funkce):
def pozdrav(jmeno):
print("Měj se {}!".format(jmeno))
-pozdrav("Pepo") # Vypíše 3x: Měj se Pepo!
+pozdrav("Pepo") # Vypíše 3x: "Měj se Pepo!"
```
## Co dál?
diff --git a/csharp.html.markdown b/csharp.html.markdown
index 442700a6..b965c2d4 100644
--- a/csharp.html.markdown
+++ b/csharp.html.markdown
@@ -14,20 +14,22 @@ filename: LearnCSharp.cs
C# is an elegant and type-safe object-oriented language that enables developers to build a variety of secure and robust applications that run on the .NET Framework.
-[Read more here.](http://msdn.microsoft.com/en-us/library/vstudio/z1zx9t92.aspx)
+[Read more here.](https://docs.microsoft.com/dotnet/csharp/getting-started/introduction-to-the-csharp-language-and-the-net-framework)
```c#
// Single-line comments start with //
+
/*
Multi-line comments look like this
*/
+
/// <summary>
/// This is an XML documentation comment which can be used to generate external
/// documentation or provide context help within an IDE
/// </summary>
/// <param name="firstParam">This is some parameter documentation for firstParam</param>
/// <returns>Information on the returned value of a function</returns>
-//public void MethodOrClassOrOtherWithParsableHelp(string firstParam) {}
+public void MethodOrClassOrOtherWithParsableHelp(string firstParam) {}
// Specify the namespaces this source code will be using
// The namespaces below are all part of the standard .NET Framework Class Library
@@ -132,6 +134,12 @@ namespace Learning.CSharp
DateTime fooDate = DateTime.Now;
Console.WriteLine(fooDate.ToString("hh:mm, dd MMM yyyy"));
+ // Verbatim String
+ // You can use the @ symbol before a string literal to escape all characters in the string
+ string path = "C:\\Users\\User\\Desktop";
+ string verbatimPath = @"C:\Users\User\Desktop";
+ Console.WriteLine(path == verbatimPath); // => true
+
// You can split a string over two lines with the @ symbol. To escape " use ""
string bazString = @"Here's some stuff
on a new line! ""Wow!"", the masses cried";
@@ -248,7 +256,7 @@ on a new line! ""Wow!"", the masses cried";
int fooWhile = 0;
while (fooWhile < 100)
{
- //Iterated 100 times, fooWhile 0->99
+ // Iterated 100 times, fooWhile 0->99
fooWhile++;
}
@@ -267,10 +275,10 @@ on a new line! ""Wow!"", the masses cried";
} while (fooDoWhile < 100);
- //for loop structure => for(<start_statement>; <conditional>; <step>)
+ // for loop structure => for(<start_statement>; <conditional>; <step>)
for (int fooFor = 0; fooFor < 10; fooFor++)
{
- //Iterated 10 times, fooFor 0->9
+ // Iterated 10 times, fooFor 0->9
}
// For Each Loop
@@ -281,7 +289,7 @@ on a new line! ""Wow!"", the masses cried";
// (The ToCharArray() could be removed, because a string also implements IEnumerable)
foreach (char character in "Hello World".ToCharArray())
{
- //Iterated over all the characters in the string
+ // Iterated over all the characters in the string
}
// Switch Case
@@ -323,7 +331,7 @@ on a new line! ""Wow!"", the masses cried";
// Convert String To Integer
// this will throw a FormatException on failure
- int.Parse("123");//returns an integer version of "123"
+ int.Parse("123"); // returns an integer version of "123"
// try parse will default to type default on failure
// in this case: 0
@@ -338,7 +346,7 @@ on a new line! ""Wow!"", the masses cried";
tryInt.ToString();
// Casting
- // Cast decimal 15 to a int
+ // Cast decimal 15 to an int
// and then implicitly cast to long
long x = (int) 15M;
}
@@ -367,7 +375,7 @@ on a new line! ""Wow!"", the masses cried";
Console.Read();
} // End main method
- // CONSOLE ENTRY A console application must have a main method as an entry point
+ // CONSOLE ENTRY - A console application must have a main method as an entry point
public static void Main(string[] args)
{
OtherInterestingFeatures();
@@ -398,7 +406,7 @@ on a new line! ""Wow!"", the masses cried";
ref int maxCount, // Pass by reference
out int count)
{
- //the argument passed in as 'count' will hold the value of 15 outside of this function
+ // the argument passed in as 'count' will hold the value of 15 outside of this function
count = 15; // out param must be assigned before control leaves the method
}
@@ -546,7 +554,7 @@ on a new line! ""Wow!"", the masses cried";
}
// PARALLEL FRAMEWORK
- // http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx
+ // https://devblogs.microsoft.com/csharpfaq/parallel-programming-in-net-framework-4-getting-started/
var words = new List<string> {"dog", "cat", "horse", "pony"};
@@ -558,11 +566,11 @@ on a new line! ""Wow!"", the masses cried";
}
);
- //Running this will produce different outputs
- //since each thread finishes at different times.
- //Some example outputs are:
- //cat dog horse pony
- //dog horse pony cat
+ // Running this will produce different outputs
+ // since each thread finishes at different times.
+ // Some example outputs are:
+ // cat dog horse pony
+ // dog horse pony cat
// DYNAMIC OBJECTS (great for working with other languages)
dynamic student = new ExpandoObject();
@@ -593,7 +601,7 @@ on a new line! ""Wow!"", the masses cried";
Console.WriteLine(bikeSummary.Name);
// ASPARALLEL
- // And this is where things get wicked - combines linq and parallel operations
+ // And this is where things get wicked - combine linq and parallel operations
var threeWheelers = bikes.AsParallel().Where(b => b.Wheels == 3).Select(b => b.Name);
// this will happen in parallel! Threads will automagically be spun up and the
// results divvied amongst them! Amazing for large datasets when you have lots of
@@ -613,7 +621,7 @@ on a new line! ""Wow!"", the masses cried";
.ThenBy(b => b.Name)
.Select(b => b.Name); // still no query run
- // Now the query runs, but opens a reader, so only populates are you iterate through
+ // Now the query runs, but opens a reader, so only populates as you iterate through
foreach (string bike in query)
Console.WriteLine(result);
@@ -634,6 +642,54 @@ on a new line! ""Wow!"", the masses cried";
}
}
+
+ // DELEGATES AND EVENTS
+ public class DelegateTest
+ {
+ public static int count = 0;
+ public static int Increment()
+ {
+ // increment count then return it
+ return ++count;
+ }
+
+ // A delegate is a reference to a method.
+ // To reference the Increment method,
+ // first declare a delegate with the same signature,
+ // i.e. takes no arguments and returns an int
+ public delegate int IncrementDelegate();
+
+ // An event can also be used to trigger delegates
+ // Create an event with the delegate type
+ public static event IncrementDelegate MyEvent;
+
+ static void Main(string[] args)
+ {
+ // Refer to the Increment method by instantiating the delegate
+ // and passing the method itself in as an argument
+ IncrementDelegate inc = new IncrementDelegate(Increment);
+ Console.WriteLine(inc()); // => 1
+
+ // Delegates can be composed with the + operator
+ IncrementDelegate composedInc = inc;
+ composedInc += inc;
+ composedInc += inc;
+
+ // composedInc will run Increment 3 times
+ Console.WriteLine(composedInc()); // => 4
+
+
+ // Subscribe to the event with the delegate
+ MyEvent += new IncrementDelegate(Increment);
+ MyEvent += new IncrementDelegate(Increment);
+
+ // Trigger the event
+ // ie. run all delegates subscribed to this event
+ Console.WriteLine(MyEvent()); // => 6
+ }
+ }
+
+
// Class Declaration Syntax:
// <public/private/protected/internal> class <class name>{
// //data fields, constructors, functions all inside.
@@ -671,10 +727,10 @@ on a new line! ""Wow!"", the masses cried";
int _speed; // Everything is private by default: Only accessible from within this class.
// can also use keyword private
public string Name { get; set; }
-
+
// Properties also have a special syntax for when you want a readonly property
// that simply returns the result of an expression
- public string LongName => Name + " " + _speed + " speed";
+ public string LongName => Name + " " + _speed + " speed";
// Enum is a value type that consists of a set of named constants
// It is really just mapping a name to a value (an int, unless specified otherwise).
@@ -711,7 +767,7 @@ on a new line! ""Wow!"", the masses cried";
// Before .NET 4: (aBike.Accessories & Bicycle.BikeAccessories.Bell) == Bicycle.BikeAccessories.Bell
public BikeAccessories Accessories { get; set; }
- // Static members belong to the type itself rather then specific object.
+ // Static members belong to the type itself rather than specific object.
// You can access them without a reference to any object:
// Console.WriteLine("Bicycles created: " + Bicycle.bicyclesCreated);
public static int BicyclesCreated { get; set; }
@@ -811,7 +867,7 @@ on a new line! ""Wow!"", the masses cried";
}
}
- //Method to display the attribute values of this Object.
+ // Method to display the attribute values of this Object.
public virtual string Info()
{
return "Gear: " + Gear +
@@ -906,7 +962,7 @@ on a new line! ""Wow!"", the masses cried";
/// <summary>
/// Used to connect to DB for LinqToSql example.
/// EntityFramework Code First is awesome (similar to Ruby's ActiveRecord, but bidirectional)
- /// http://msdn.microsoft.com/en-us/data/jj193542.aspx
+ /// https://docs.microsoft.com/ef/ef6/modeling/code-first/workflows/new-database
/// </summary>
public class BikeRepository : DbContext
{
@@ -949,6 +1005,7 @@ on a new line! ""Wow!"", the masses cried";
// String interpolation by prefixing the string with $
// and wrapping the expression you want to interpolate with { braces }
+ // You can also combine both interpolated and verbatim strings with $@
public class Rectangle
{
public int Length { get; set; }
@@ -961,6 +1018,9 @@ on a new line! ""Wow!"", the masses cried";
{
Rectangle rect = new Rectangle { Length = 5, Width = 3 };
Console.WriteLine($"The length is {rect.Length} and the width is {rect.Width}");
+
+ string username = "User";
+ Console.WriteLine($@"C:\Users\{username}\Desktop");
}
}
@@ -1006,15 +1066,242 @@ on a new line! ""Wow!"", the masses cried";
// x?.y will return null immediately if x is null; y is not evaluated
=> GenieName?.ToUpper();
}
+
+ static class MagicService
+ {
+ private static bool LogException(Exception ex)
+ {
+ // log exception somewhere
+ return false;
+ }
+
+ public static bool CastSpell(string spell)
+ {
+ try
+ {
+ // Pretend we call API here
+ throw new MagicServiceException("Spell failed", 42);
+
+ // Spell succeeded
+ return true;
+ }
+ // Only catch if Code is 42 i.e. spell failed
+ catch(MagicServiceException ex) when (ex.Code == 42)
+ {
+ // Spell failed
+ return false;
+ }
+ // Other exceptions, or MagicServiceException where Code is not 42
+ catch(Exception ex) when (LogException(ex))
+ {
+ // Execution never reaches this block
+ // The stack is not unwound
+ }
+ return false;
+ // Note that catching a MagicServiceException and rethrowing if Code
+ // is not 42 or 117 is different, as then the final catch-all block
+ // will not catch the rethrown exception
+ }
+ }
+
+ public class MagicServiceException : Exception
+ {
+ public int Code { get; }
+
+ public MagicServiceException(string message, int code) : base(message)
+ {
+ Code = code;
+ }
+ }
+
+ public static class PragmaWarning {
+ // Obsolete attribute
+ [Obsolete("Use NewMethod instead", false)]
+ public static void ObsoleteMethod()
+ {
+ // obsolete code
+ }
+
+ public static void NewMethod()
+ {
+ // new code
+ }
+
+ public static void Main()
+ {
+ ObsoleteMethod(); // CS0618: 'ObsoleteMethod is obsolete: Use NewMethod instead'
+#pragma warning disable CS0618
+ ObsoleteMethod(); // no warning
+#pragma warning restore CS0618
+ ObsoleteMethod(); // CS0618: 'ObsoleteMethod is obsolete: Use NewMethod instead'
+ }
+ }
} // End Namespace
+
+using System;
+// C# 6, static using
+using static System.Math;
+
+namespace Learning.More.CSharp
+{
+ class StaticUsing
+ {
+ static void Main()
+ {
+ // Without a static using statement..
+ Console.WriteLine("The square root of 4 is {}.", Math.Sqrt(4));
+ // With one
+ Console.WriteLine("The square root of 4 is {}.", Sqrt(4));
+ }
+ }
+}
+
+// New C# 7 Feature
+// Install Microsoft.Net.Compilers Latest from Nuget
+// Install System.ValueTuple Latest from Nuget
+using System;
+namespace Csharp7
+{
+ // TUPLES, DECONSTRUCTION AND DISCARDS
+ class TuplesTest
+ {
+ public (string, string) GetName()
+ {
+ // Fields in tuples are by default named Item1, Item2...
+ var names1 = ("Peter", "Parker");
+ Console.WriteLine(names1.Item2); // => Parker
+
+ // Fields can instead be explicitly named
+ // Type 1 Declaration
+ (string FirstName, string LastName) names2 = ("Peter", "Parker");
+
+ // Type 2 Declaration
+ var names3 = (First:"Peter", Last:"Parker");
+
+ Console.WriteLine(names2.FirstName); // => Peter
+ Console.WriteLine(names3.Last); // => Parker
+
+ return names3;
+ }
+
+ public string GetLastName() {
+ var fullName = GetName();
+
+ // Tuples can be deconstructed
+ (string firstName, string lastName) = fullName;
+
+ // Fields in a deconstructed tuple can be discarded by using _
+ var (_, last) = fullName;
+ return last;
+ }
+
+ // Any type can be deconstructed in the same way by
+ // specifying a Deconstruct method
+ public int randomNumber = 4;
+ public int anotherRandomNumber = 10;
+
+ public void Deconstruct(out int randomNumber, out int anotherRandomNumber)
+ {
+ randomNumber = this.randomNumber;
+ anotherRandomNumber = this.anotherRandomNumber;
+ }
+
+ static void Main(string[] args)
+ {
+ var tt = new TuplesTest();
+ (int num1, int num2) = tt;
+ Console.WriteLine($"num1: {num1}, num2: {num2}"); // => num1: 4, num2: 10
+
+ Console.WriteLine(tt.GetLastName());
+ }
+ }
+
+ // PATTERN MATCHING
+ class PatternMatchingTest
+ {
+ public static (string, int)? CreateLogMessage(object data)
+ {
+ switch(data)
+ {
+ // Additional filtering using when
+ case System.Net.Http.HttpRequestException h when h.Message.Contains("404"):
+ return (h.Message, 404);
+ case System.Net.Http.HttpRequestException h when h.Message.Contains("400"):
+ return (h.Message, 400);
+ case Exception e:
+ return (e.Message, 500);
+ case string s:
+ return (s, s.Contains("Error") ? 500 : 200);
+ case null:
+ return null;
+ default:
+ return (data.ToString(), 500);
+ }
+ }
+ }
+
+ // REFERENCE LOCALS
+ // Allow you to return a reference to an object instead of just its value
+ class RefLocalsTest
+ {
+ // note ref in return
+ public static ref string FindItem(string[] arr, string el)
+ {
+ for(int i=0; i<arr.Length; i++)
+ {
+ if(arr[i] == el) {
+ // return the reference
+ return ref arr[i];
+ }
+ }
+ throw new Exception("Item not found");
+ }
+
+ public static void SomeMethod()
+ {
+ string[] arr = {"this", "is", "an", "array"};
+
+ // note refs everywhere
+ ref string item = ref FindItem(arr, "array");
+ item = "apple";
+ Console.WriteLine(arr[3]); // => apple
+ }
+ }
+
+ // LOCAL FUNCTIONS
+ class LocalFunctionTest
+ {
+ private static int _id = 0;
+ public int id;
+ public LocalFunctionTest()
+ {
+ id = generateId();
+
+ // This local function can only be accessed in this scope
+ int generateId()
+ {
+ return _id++;
+ }
+ }
+
+ public static void AnotherMethod()
+ {
+ var lf1 = new LocalFunctionTest();
+ var lf2 = new LocalFunctionTest();
+ Console.WriteLine($"{lf1.id}, {lf2.id}"); // => 0, 1
+
+ int id = generateId();
+ // error CS0103: The name 'generateId' does not exist in the current context
+ }
+ }
+}
+
```
## Topics Not Covered
* Attributes
- * async/await, pragma directives
- * Exception filters
- * `using static`
+ * async/await
* Web Development
* ASP.NET MVC & WebApi (new)
* ASP.NET Web Forms (old)
@@ -1025,13 +1312,13 @@ on a new line! ""Wow!"", the masses cried";
## Further Reading
+ * [C# language reference](https://docs.microsoft.com/dotnet/csharp/language-reference/)
+ * [Learn .NET](https://dotnet.microsoft.com/learn)
+ * [C# Coding Conventions](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions)
* [DotNetPerls](http://www.dotnetperls.com)
* [C# in Depth](http://manning.com/skeet2)
- * [Programming C#](http://shop.oreilly.com/product/0636920024064.do)
- * [LINQ](http://shop.oreilly.com/product/9780596519254.do)
- * [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx)
- * [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials)
- * [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials)
- * [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials)
+ * [Programming C# 5.0](http://shop.oreilly.com/product/0636920024064.do)
+ * [LINQ Pocket Reference](http://shop.oreilly.com/product/9780596519254.do)
* [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
- * [C# Coding Conventions](http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx)
+ * [freeCodeCamp - C# Tutorial for Beginners](https://www.youtube.com/watch?v=GhQdlIFylQ8)
+ \ No newline at end of file
diff --git a/css.html.markdown b/css.html.markdown
index 3b378d44..b8adc886 100644
--- a/css.html.markdown
+++ b/css.html.markdown
@@ -135,6 +135,10 @@ selector::after {}
.parent * { } /* all descendants */
.parent > * { } /* all children */
+/* Group any number of selectors to define styles that affect all selectors
+ in the group */
+selector1, selector2 { }
+
/* ####################
## PROPERTIES
#################### */
@@ -160,14 +164,14 @@ selector {
max-width: 5in; /* inches */
/* Colors */
- color: #F6E; /* short hex format */
- color: #FF66EE; /* long hex format */
- color: tomato; /* a named color */
- color: rgb(255, 255, 255); /* as rgb values */
- color: rgb(10%, 20%, 50%); /* as rgb percentages */
- color: rgba(255, 0, 0, 0.3); /* as rgba values (CSS 3) Note: 0 <= a <= 1 */
- color: transparent; /* equivalent to setting the alpha to 0 */
- color: hsl(0, 100%, 50%); /* as hsl percentages (CSS 3) */
+ color: #F6E; /* short hex format */
+ color: #FF66EE; /* long hex format */
+ color: tomato; /* a named color */
+ color: rgb(255, 255, 255); /* as rgb values */
+ color: rgb(10%, 20%, 50%); /* as rgb percentages */
+ color: rgba(255, 0, 0, 0.3); /* as rgba values (CSS 3) Note: 0 <= a <= 1 */
+ color: transparent; /* equivalent to setting the alpha to 0 */
+ color: hsl(0, 100%, 50%); /* as hsl percentages (CSS 3) */
color: hsla(0, 100%, 50%, 0.3); /* as hsl percentages with alpha */
/* Borders */
@@ -175,7 +179,7 @@ selector {
border-style:solid;
border-color:red; /* similar to how background-color is set */
border: 5px solid red; /* this is a short hand approach for the same */
- border-radius:20px; /* this is a CSS3 property */
+ border-radius:20px; /* this is a CSS3 property */
/* Images as backgrounds of elements */
background-image: url(/img-path/img.jpg); /* quotes inside url() optional */
@@ -313,6 +317,7 @@ a new feature.
* [Dabblet](http://dabblet.com/) (CSS playground)
* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS) (Tutorials and reference)
* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/) (Reference)
+* [DevTips' CSS Basics](https://www.youtube.com/playlist?list=PLqGj3iMvMa4IOmy04kDxh_hqODMqoeeCy) (Tutorials)
## Further Reading
diff --git a/cypher.html.markdown b/cypher.html.markdown
new file mode 100644
index 00000000..32868354
--- /dev/null
+++ b/cypher.html.markdown
@@ -0,0 +1,249 @@
+---
+language: cypher
+filename: LearnCypher.cql
+contributors:
+ - ["Théo Gauchoux", "https://github.com/TheoGauchoux"]
+---
+
+Cypher is the Neo4j’s query language to manipulate graphs easily. It reuses syntax from SQL and mixes it with kind of ascii-art to represent graphs.
+This tutorial assumes that you already know graph concepts like nodes and relationships.
+
+[Read more here.](https://neo4j.com/developer/cypher-query-language/)
+
+
+Nodes
+---
+
+**Represents a record in a graph.**
+
+`()`
+It's an empty *node*, to indicate that there is a *node*, but it's not relevant for the query.
+
+`(n)`
+It's a *node* referred by the variable **n**, reusable in the query. It begins with lowercase and uses camelCase.
+
+`(p:Person)`
+You can add a *label* to your node, here **Person**. It's like a type / a class / a category. It begins with uppercase and uses camelCase.
+
+`(p:Person:Manager)`
+A node can have many *labels*.
+
+`(p:Person {name : 'Théo Gauchoux', age : 22})`
+A node can have some *properties*, here **name** and **age**. It begins with lowercase and uses camelCase.
+
+The types allowed in properties :
+
+ - Numeric
+ - Boolean
+ - String
+ - List of previous primitive types
+
+*Warning : there isn't datetime property in Cypher ! You can use String with a specific pattern or a Numeric from a specific date.*
+
+`p.name`
+You can access to a property with the dot style.
+
+
+Relationships (or Edges)
+---
+
+**Connects two nodes**
+
+`[:KNOWS]`
+It's a *relationship* with the *label* **KNOWS**. It's a *label* as the node's label. It begins with uppercase and use UPPER\_SNAKE\_CASE.
+
+`[k:KNOWS]`
+The same *relationship*, referred by the variable **k**, reusable in the query, but it's not necessary.
+
+`[k:KNOWS {since:2017}]`
+The same *relationship*, with *properties* (like *node*), here **since**.
+
+`[k:KNOWS*..4]`
+It's a structural information to use in a *path* (seen later). Here, **\*..4** says "Match the pattern, with the relationship **k** which be repeated between 1 and 4 times.
+
+
+Paths
+---
+
+**The way to mix nodes and relationships.**
+
+`(a:Person)-[:KNOWS]-(b:Person)`
+A path describing that **a** and **b** know each other.
+
+`(a:Person)-[:MANAGES]->(b:Person)`
+A path can be directed. This path describes that **a** is the manager of **b**.
+
+`(a:Person)-[:KNOWS]-(b:Person)-[:KNOWS]-(c:Person)`
+You can chain multiple relationships. This path describes the friend of a friend.
+
+`(a:Person)-[:MANAGES]->(b:Person)-[:MANAGES]->(c:Person)`
+A chain can also be directed. This path describes that **a** is the boss of **b** and the big boss of **c**.
+
+Patterns often used (from Neo4j doc) :
+
+```
+// Friend-of-a-friend
+(user)-[:KNOWS]-(friend)-[:KNOWS]-(foaf)
+
+// Shortest path
+path = shortestPath( (user)-[:KNOWS*..5]-(other) )
+
+// Collaborative filtering
+(user)-[:PURCHASED]->(product)<-[:PURCHASED]-()-[:PURCHASED]->(otherProduct)
+
+// Tree navigation
+(root)<-[:PARENT*]-(leaf:Category)-[:ITEM]->(data:Product)
+
+```
+
+
+Create queries
+---
+
+Create a new node
+```
+CREATE (a:Person {name:"Théo Gauchoux"})
+RETURN a
+```
+*`RETURN` allows to have a result after the query. It can be multiple, as `RETURN a, b`.*
+
+Create a new relationship (with 2 new nodes)
+```
+CREATE (a:Person)-[k:KNOWS]-(b:Person)
+RETURN a,k,b
+```
+
+Match queries
+---
+
+Match all nodes
+```
+MATCH (n)
+RETURN n
+```
+
+Match nodes by label
+```
+MATCH (a:Person)
+RETURN a
+```
+
+Match nodes by label and property
+```
+MATCH (a:Person {name:"Théo Gauchoux"})
+RETURN a
+```
+
+Match nodes according to relationships (undirected)
+```
+MATCH (a)-[:KNOWS]-(b)
+RETURN a,b
+```
+
+Match nodes according to relationships (directed)
+```
+MATCH (a)-[:MANAGES]->(b)
+RETURN a,b
+```
+
+Match nodes with a `WHERE` clause
+```
+MATCH (p:Person {name:"Théo Gauchoux"})-[s:LIVES_IN]->(city:City)
+WHERE s.since = 2015
+RETURN p,state
+```
+
+You can use `MATCH WHERE` clause with `CREATE` clause
+```
+MATCH (a), (b)
+WHERE a.name = "Jacquie" AND b.name = "Michel"
+CREATE (a)-[:KNOWS]-(b)
+```
+
+
+Update queries
+---
+
+Update a specific property of a node
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+SET p.age = 23
+```
+
+Replace all properties of a node
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+SET p = {name: "Michel", age: 23}
+```
+
+Add new property to a node
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+SET p + = {studies: "IT Engineering"}
+```
+
+Add a label to a node
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+SET p:Internship
+```
+
+
+Delete queries
+---
+
+Delete a specific node (linked relationships must be deleted before)
+```
+MATCH (p:Person)-[relationship]-()
+WHERE p.name = "Théo Gauchoux"
+DELETE relationship, p
+```
+
+Remove a property in a specific node
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+REMOVE p.age
+```
+*Pay attention to the `REMOVE`keyword, it's not `DELETE` !*
+
+Remove a label from a specific node
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+DELETE p:Person
+```
+
+Delete entire database
+```
+MATCH (n)
+OPTIONAL MATCH (n)-[r]-()
+DELETE n, r
+```
+*Seriously, it's the `rm -rf /` of Cypher !*
+
+
+Other useful clauses
+---
+
+`PROFILE`
+Before a query, show the execution plan of it.
+
+`COUNT(e)`
+Count entities (nodes or relationships) matching **e**.
+
+`LIMIT x`
+Limit the result to the x first results.
+
+
+Special hints
+---
+
+- There is just single-line comments in Cypher, with double-slash : // Comments
+- You can execute a Cypher script stored in a **.cql** file directly in Neo4j (it's an import). However, you can't have multiple statements in this file (separated by **;**).
+- Use the Neo4j shell to write Cypher, it's really awesome.
+- The Cypher will be the standard query language for all graph databases (known as **OpenCypher**).
diff --git a/d.html.markdown b/d.html.markdown
index edb3bff5..93c08da2 100644
--- a/d.html.markdown
+++ b/d.html.markdown
@@ -3,10 +3,10 @@ language: D
filename: learnd.d
contributors:
- ["Nick Papanastasiou", "www.nickpapanastasiou.github.io"]
-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,9 +209,10 @@ 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
+import std.stdio;
void main() {
// We want to print the sum of a list of squares of even ints
@@ -237,7 +238,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..b215474a 100644
--- a/dart.html.markdown
+++ b/dart.html.markdown
@@ -2,159 +2,285 @@
language: dart
filename: learndart.dart
contributors:
- - ["Joao Pedrosa", "https://github.com/jpedrosa/"]
+ - ["Joao Pedrosa", "https://github.com/jpedrosa/"]
+ - ["Vince Ramces Oliveros", "https://github.com/ram231"]
---
-Dart is a newcomer into the realm of programming languages.
-It borrows a lot from other mainstream languages, having as a goal not to deviate too much from
-its JavaScript sibling. Like JavaScript, Dart aims for great browser integration.
+**Dart** is a single threaded, general purpose programming language.
+It borrows a lot from other mainstream languages.
+It supports Streams, Futures(known as Promises in JavaScript), Generics, First-class functions(closures) and static type checking.
+Dart can run in any platform such as Web, CLI, Desktop, Mobile and IoT devices.
-Dart's most controversial feature must be its Optional Typing.
+Dart's most controversial feature is its ~~Optional Typing~~ Static Type safety and [Sound Type checks](https://dart.dev/guides/language/sound-dart).
-```javascript
+```dart
import "dart:collection";
-import "dart:math" as DM;
-
-// Welcome to Learn Dart in 15 minutes. http://www.dartlang.org/
-// This is an executable tutorial. You can run it with Dart or on
-// the Try Dart! site if you copy/paste it there. http://try.dartlang.org/
-
-// Function declaration and method declaration look the same. Function
-// declarations can be nested. The declaration takes the form of
-// name() {} or name() => singleLineExpression;
-// The fat arrow function declaration has an implicit return for the result of
-// the expression.
+import "dart:math" as math;
+
+/// Welcome to Learn Dart in 15 minutes. http://dart.dev/
+/// This is an executable tutorial. You can run it with Dart or on
+/// the Try Dart! site if you copy/paste it there. http://dartpad.dev/
+/// You can also run Flutter in DartPad by click the `< > New Pad ` and choose Flutter
+
+
+/// In Dart, Everything is an Object.
+/// Every declaration of an object is an instance of Null and
+/// Null is also an object.
+
+
+/// 3 Types of comments in dart
+// Single line comment
+/**
+* Multi-line comment
+* Can comment more than 2 lines
+*/
+/// Code doc comment
+/// It uses markdown syntax to generate code docs when making an API.
+/// Code doc comment is the recommended choice when documenting your APIs, classes and methods.
+
+/// 4 types of variable declaration.
+/// Constants are variables that are immutable cannot be change or altered.
+/// `const` in dart should practice SCREAMING_SNAKE_CASE name declaration.
+const CONSTANT_VALUE = "I CANNOT CHANGE";
+CONSTANT_VALUE = "DID I?"; //Error
+/// Final is another variable declaration that cannot be change once it has been instantiated. Commonly used in classes and functions
+/// `final` can be declared in pascalCase.
+final finalValue = "value cannot be change once instantiated";
+finalValue = "Seems not"; //Error
+
+/// `var` is another variable declaration that is mutable and can change its value. Dart will infer types and will not change its data type
+var mutableValue = "Variable string";
+mutableValue = "this is valid";
+mutableValue = false; // Error.
+
+/// `dynamic` is another variable declaration in which the type is not evaluated by the dart static type checking.
+/// It can change its value and data type.
+/// Some dartisans uses dynamic cautiously as it cannot keep track of its data type. so use it at your own risk
+dynamic dynamicValue = "I'm a string";
+dynamicValue = false; // false
+
+
+/// Functions can be declared in a global space
+/// Function declaration and method declaration look the same. Function
+/// declarations can be nested. The declaration takes the form of
+/// name() {} or name() => singleLineExpression;
+/// The fat arrow function declaration can be an implicit or
+/// explicit return for the result of the expression.
+/// Dart will execute a function called `main()` anywhere in the dart project.
+///
example1() {
- example1nested1() {
- example1nested2() => print("Example1 nested 1 nested 2");
- example1nested2();
+ nested1() {
+ nested2() => print("Example1 nested 1 nested 2");
+ nested2();
}
- example1nested1();
+
+ nested1();
}
-// Anonymous functions don't include a name.
+/// Anonymous functions don't include a name but can take number of arguments
example2() {
- example2nested1(fn) {
+ //// Explicit return type.
+ nested1(Function<void> fn) {
fn();
}
- example2nested1(() => print("Example2 nested 1"));
+
+ nested1(() => print("Example2 nested 1"));
}
-// When a function parameter is declared, the declaration can include the
-// number of parameters the function takes by specifying the names of the
-// parameters it takes.
+/// When a function parameter is declared, the declaration can include the
+/// number of parameters the function takes by explicitly specifying the names of the
+/// parameters it takes.
example3() {
- example3nested1(fn(informSomething)) {
- fn("Example3 nested 1");
+ planA(fn(String informSomething)) {
+ fn("Example3 plan A");
}
- example3planB(fn) { // Or don't declare number of parameters.
+ planB(fn) {
+ // Or don't declare number of parameters.
fn("Example3 plan B");
}
- example3nested1((s) => print(s));
- example3planB((s) => print(s));
+
+ planA((s) => print(s));
+ planB((s) => print(s));
}
-// Functions have closure access to outer variables.
+/// Functions have closure access to outer variables.
+/// Dart will infer types when the variable has a value of something.
+/// In this example dart knows that this variable is a String.
var example4Something = "Example4 nested 1";
example4() {
- example4nested1(fn(informSomething)) {
+ nested1(fn(informSomething)) {
fn(example4Something);
}
- example4nested1((s) => print(s));
+
+ nested1((s) => print(s));
}
-// Class declaration with a sayIt method, which also has closure access
-// to the outer variable as though it were a function as seen before.
+/// Class declaration with a sayIt method, which also has closure access
+/// to the outer variable as though it were a function as seen before.
var example5method = "Example5 sayIt";
+
class Example5Class {
sayIt() {
print(example5method);
}
}
+
example5() {
- // Create an anonymous instance of the Example5Class and call the sayIt
- // method on it.
+ /// Create an anonymous instance of the Example5Class and call the sayIt
+ /// method on it.
+ /// the `new` keyword is optional in Dart.
new Example5Class().sayIt();
}
-// Class declaration takes the form of class name { [classBody] }.
-// Where classBody can include instance methods and variables, but also
-// class methods and variables.
+/// Class declaration takes the form of class name { [classBody] }.
+/// Where classBody can include instance methods and variables, but also
+/// class methods and variables.
class Example6Class {
- var example6InstanceVariable = "Example6 instance variable";
+ var instanceVariable = "Example6 instance variable";
sayIt() {
- print(example6InstanceVariable);
+ print(instanceVariable);
}
}
+
example6() {
- new Example6Class().sayIt();
+ Example6Class().sayIt();
}
-// Class methods and variables are declared with "static" terms.
+/// Class methods and variables are declared with "static" terms.
class Example7Class {
- static var example7ClassVariable = "Example7 class variable";
+ static var classVariable = "Example7 class variable";
static sayItFromClass() {
- print(example7ClassVariable);
+ print(classVariable);
}
+
sayItFromInstance() {
- print(example7ClassVariable);
+ print(classVariable);
}
}
+
example7() {
Example7Class.sayItFromClass();
new Example7Class().sayItFromInstance();
}
-// Literals are great, but there's a restriction for what literals can be
-// outside of function/method bodies. Literals on the outer scope of class
-// or outside of class have to be constant. Strings and numbers are constant
-// by default. But arrays and maps are not. They can be made constant by
-// declaring them "const".
-var example8A = const ["Example8 const array"],
- example8M = const {"someKey": "Example8 const map"};
-example8() {
- print(example8A[0]);
- print(example8M["someKey"]);
+/// Dart supports Generics.
+/// Generics refers to the technique of writing the code for a class
+/// without specifying the data type(s) that the class works on.
+/// Source: https://stackoverflow.com/questions/4560890/what-are-generics-in-c
+
+/// Type `T` refers to any type that has been instantiated
+/// you can call whatever you want
+/// Programmers uses the convention in the following
+/// T - Type(used for class and primitype types)
+/// E - Element(used for List, Set, or Iterable)
+/// K,V - Key Value(used for Map)
+class GenericExample<T>{
+ void printType(){
+ print("$T")
+ }
+ // methods can also have generics
+ genericMethod<M>(){
+ print("class:$T, method: $M");
+ }
}
-// Loops in Dart take the form of standard for () {} or while () {} loops,
-// slightly more modern for (.. in ..) {}, or functional callbacks with many
-// supported features, starting with forEach.
-var example9A = const ["a", "b"];
+
+/// List are similar to arrays but list is a child of Iterable<E>
+/// Therefore Maps, List, LinkedList are all child of Iterable<E> to be able to loop using the keyword `for`
+/// Important things to remember:
+/// () - Iterable<E>
+/// [] - List<E>
+/// {} - Map<K,V>
+
+
+/// List are great, but there's a restriction for what List can be
+/// outside of function/method bodies. List on the outer scope of class
+/// or outside of class have to be constant. Strings and numbers are constant
+/// by default. But arrays and maps are not. They can be made constant by
+/// declaring them "const". Kind of similar to Javascript's Object.freeze()
+const example8List = ["Example8 const array"];
+const example8Map = {"someKey": "Example8 const map"};
+/// Declare List or Maps as Objects.
+ List<String> explicitList = new List<String>();
+ Map<String,dynamic> explicitMaps = new Map<String,dynamic>();
+
+ explicitList.add("SomeArray");
+example8() {
+ print(example8Map["someKey"]);
+ print(explicitList[0]);
+}
+
+/// Assigning a list from one variable to another will not be the same result.
+/// Because dart is pass-reference-by-value.
+/// So when you assign an existing list to a new variable.
+/// Instead of List, it becomes an Iterable
+var iterableExplicitList = explicitList;
+print(iterableExplicitList) // ("SomeArray"); "[]" becomes "()"
+var newExplicitLists = explicitList.toList() // Converts Iterable<E> to List<E>
+
+/// Loops in Dart take the form of standard for () {} or while () {} loops,
+/// slightly more modern for (.. in ..) {}, or functional callbacks with many
+/// supported features, starting with forEach,map and where.
+var example9Array = const ["a", "b"];
example9() {
- for (var i = 0; i < example9A.length; i++) {
- print("Example9 for loop '${example9A[i]}'");
+ for (int i = 0; i < example9Array.length; i++) {
+ print("Example9 for loop '${example9Array[i]}'");
}
var i = 0;
- while (i < example9A.length) {
- print("Example9 while loop '${example9A[i]}'");
+ while (i < example9Array.length) {
+ print("Example9 while loop '${example9Array[i]}'");
i++;
}
- for (var e in example9A) {
+ for (final e in example9Array) {
print("Example9 for-in loop '${e}'");
}
- example9A.forEach((e) => print("Example9 forEach loop '${e}'"));
+
+ example9Array.forEach((e) => print("Example9 forEach loop '${e}'"));
+
}
-// To loop over the characters of a string or to extract a substring.
-var example10S = "ab";
+/// To loop over the characters of a string or to extract a substring.
+var example10String = "ab";
example10() {
- for (var i = 0; i < example10S.length; i++) {
- print("Example10 String character loop '${example10S[i]}'");
+ for (var i = 0; i < example10String.length; i++) {
+ print("Example10 String character loop '${example10String[i]}'");
}
- for (var i = 0; i < example10S.length; i++) {
- print("Example10 substring loop '${example10S.substring(i, i + 1)}'");
+ for (var i = 0; i < example10String.length; i++) {
+ print("Example10 substring loop '${example10String.substring(i, i + 1)}'");
}
}
-// Int and double are the two supported number formats.
+/// `int`, `double` and `num` are the three supported number formats.
+/// `num` can be either `int` or `double`.
+/// `int` and `double` are children of type `num`
example11() {
var i = 1 + 320, d = 3.2 + 0.01;
+ num myNumDouble = 2.2;
+ num myNumInt = 2;
+ int myInt = 1;
+ double myDouble = 0; // Dart will add decimal prefix, becomes 0.0;
+ myNumDouble = myInt; // valid
+ myNumDouble = myDouble; //valid
+ myNumDouble = myNumInt; //valid
+
+ myNumInt = myInt; // valid
+ myNumInt = myDouble; // valid
+ myNumInt = myNumDouble; // valid
+
+ myInt = myNumDouble; //Error
+ myInt = myDouble; //Error
+ myInt = myNumInt; //valid
+
+ myDouble = myInt; //error
+ myDouble = myNumInt; //valid
+ myDouble = myNumDouble; //valid
+
print("Example11 int ${i}");
print("Example11 double ${d}");
+
}
-// DateTime provides date/time arithmetic.
+/// DateTime provides date/time arithmetic.
example12() {
var now = new DateTime.now();
print("Example12 now '${now}'");
@@ -162,7 +288,7 @@ example12() {
print("Example12 tomorrow '${now}'");
}
-// Regular expressions are supported.
+/// Regular expressions are supported.
example13() {
var s1 = "some string", s2 = "some", re = new RegExp("^s.+?g\$");
match(s) {
@@ -172,38 +298,63 @@ example13() {
print("Example13 regexp doesn't match '${s}'");
}
}
+
match(s1);
match(s2);
}
-// Boolean expressions need to resolve to either true or false, as no
-// implicit conversions are supported.
+/// Boolean expressions support implicit conversions and dynamic type
example14() {
- var v = true;
- if (v) {
- print("Example14 value is true");
+ var a = true;
+ if (a) {
+ print("true, a is $a");
}
- v = null;
+ a = null;
+ if (a) {
+ print("true, a is $a");
+ } else {
+ print("false, a is $a"); /// runs here
+ }
+
+ /// dynamic typed null can be convert to bool
+ var b;/// b is dynamic type
+ b = "abc";
try {
- if (v) {
- // Never runs
+ if (b) {
+ print("true, b is $b");
} else {
- // Never runs
+ print("false, b is $b");
}
} catch (e) {
- print("Example14 null value causes an exception: '${e}'");
+ print("error, b is $b"); /// this could be run but got error
+ }
+ b = null;
+ if (b) {
+ print("true, b is $b");
+ } else {
+ print("false, b is $b"); /// runs here
}
+
+ /// statically typed null can not be convert to bool
+ var c = "abc";
+ c = null;
+ /// complie failed
+ /// if (c) {
+ /// print("true, c is $c");
+ /// } else {
+ /// print("false, c is $c");
+ /// }
}
-// try/catch/finally and throw are used for exception handling.
-// throw takes any object as parameter;
+/// try/catch/finally and throw are used for exception handling.
+/// throw takes any object as parameter;
example15() {
try {
try {
throw "Some unexpected error.";
} catch (e) {
print("Example15 an exception: '${e}'");
- throw e; // Re-throw
+ throw e; /// Re-throw
}
} catch (e) {
print("Example15 catch exception being re-thrown: '${e}'");
@@ -212,18 +363,21 @@ example15() {
}
}
-// To be efficient when creating a long string dynamically, use
-// StringBuffer. Or you could join a string array.
+/// To be efficient when creating a long string dynamically, use
+/// StringBuffer. Or you could join a string array.
example16() {
var sb = new StringBuffer(), a = ["a", "b", "c", "d"], e;
- for (e in a) { sb.write(e); }
+ for (e in a) {
+ sb.write(e);
+ }
print("Example16 dynamic string created with "
- "StringBuffer '${sb.toString()}'");
+ "StringBuffer '${sb.toString()}'");
print("Example16 join string array '${a.join()}'");
}
-// Strings can be concatenated by just having string literals next to
-// one another with no further operator needed.
+/// Strings can be concatenated by just having string List next to
+/// one another with no further operator needed.
+
example17() {
print("Example17 "
"concatenate "
@@ -231,44 +385,44 @@ example17() {
"just like that");
}
-// Strings have single-quote or double-quote for delimiters with no
-// actual difference between the two. The given flexibility can be good
-// to avoid the need to escape content that matches the delimiter being
-// used. For example, double-quotes of HTML attributes if the string
-// contains HTML content.
+/// Strings have single-quote or double-quote for delimiters with no
+/// actual difference between the two. The given flexibility can be good
+/// to avoid the need to escape content that matches the delimiter being
+/// used. For example, double-quotes of HTML attributes if the string
+/// contains HTML content.
example18() {
print('Example18 <a href="etc">'
"Don't can't I'm Etc"
'</a>');
}
-// Strings with triple single-quotes or triple double-quotes span
-// multiple lines and include line delimiters.
+/// Strings with triple single-quotes or triple double-quotes span
+/// multiple lines and include line delimiters.
example19() {
print('''Example19 <a href="etc">
Example19 Don't can't I'm Etc
Example19 </a>''');
}
-// Strings have the nice interpolation feature with the $ character.
-// With $ { [expression] }, the return of the expression is interpolated.
-// $ followed by a variable name interpolates the content of that variable.
-// $ can be escaped like so \$ to just add it to the string instead.
+/// Strings have the nice interpolation feature with the $ character.
+/// With $ { [expression] }, the return of the expression is interpolated.
+/// $ followed by a variable name interpolates the content of that variable.
+/// $ can be escaped like so \$ to just add it to the string instead.
example20() {
var s1 = "'\${s}'", s2 = "'\$s'";
print("Example20 \$ interpolation ${s1} or $s2 works.");
}
-// Optional types allow for the annotation of APIs and come to the aid of
-// IDEs so the IDEs can better refactor, auto-complete and check for
-// errors. So far we haven't declared any types and the programs have
-// worked just fine. In fact, types are disregarded during runtime.
-// Types can even be wrong and the program will still be given the
-// benefit of the doubt and be run as though the types didn't matter.
-// There's a runtime parameter that checks for type errors which is
-// the checked mode, which is said to be useful during development time,
-// but which is also slower because of the extra checking and is thus
-// avoided during deployment runtime.
+/// Optional types allow for the annotation of APIs and come to the aid of
+/// IDEs so the IDEs can better refactor, auto-complete and check for
+/// errors. So far we haven't declared any types and the programs have
+/// worked just fine. In fact, types are disregarded during runtime.
+/// Types can even be wrong and the program will still be given the
+/// benefit of the doubt and be run as though the types didn't matter.
+/// There's a runtime parameter that checks for type errors which is
+/// the checked mode, which is said to be useful during development time,
+/// but which is also slower because of the extra checking and is thus
+/// avoided during deployment runtime.
class Example21 {
List<String> _names;
Example21() {
@@ -278,11 +432,13 @@ class Example21 {
set names(List<String> list) {
_names = list;
}
+
int get length => _names.length;
void add(String name) {
_names.add(name);
}
}
+
void example21() {
Example21 o = new Example21();
o.add("c");
@@ -291,46 +447,50 @@ void example21() {
print("Example21 names '${o.names}' and length '${o.length}'");
}
-// Class inheritance takes the form of class name extends AnotherClassName {}.
+/// Class inheritance takes the form of class name extends AnotherClassName {}.
class Example22A {
var _name = "Some Name!";
get name => _name;
}
+
class Example22B extends Example22A {}
+
example22() {
var o = new Example22B();
print("Example22 class inheritance '${o.name}'");
}
-// Class mixin is also available, and takes the form of
-// class name extends SomeClass with AnotherClassName {}.
-// It's necessary to extend some class to be able to mixin another one.
-// The template class of mixin cannot at the moment have a constructor.
-// Mixin is mostly used to share methods with distant classes, so the
-// single inheritance doesn't get in the way of reusable code.
-// Mixins follow the "with" statement during the class declaration.
+/// Class mixin is also available, and takes the form of
+/// class name extends SomeClass with AnotherClassName {}.
+/// It's necessary to extend some class to be able to mixin another one.
+/// The template class of mixin cannot at the moment have a constructor.
+/// Mixin is mostly used to share methods with distant classes, so the
+/// single inheritance doesn't get in the way of reusable code.
+/// Mixins follow the "with" statement during the class declaration.
class Example23A {}
+
class Example23Utils {
addTwo(n1, n2) {
return n1 + n2;
}
}
+
class Example23B extends Example23A with Example23Utils {
addThree(n1, n2, n3) {
return addTwo(n1, n2) + n3;
}
}
+
example23() {
- var o = new Example23B(), r1 = o.addThree(1, 2, 3),
- r2 = o.addTwo(1, 2);
+ var o = new Example23B(), r1 = o.addThree(1, 2, 3), r2 = o.addTwo(1, 2);
print("Example23 addThree(1, 2, 3) results in '${r1}'");
print("Example23 addTwo(1, 2) results in '${r2}'");
}
-// The Class constructor method uses the same name of the class and
-// takes the form of SomeClass() : super() {}, where the ": super()"
-// part is optional and it's used to delegate constant parameters to the
-// super-parent's constructor.
+/// The Class constructor method uses the same name of the class and
+/// takes the form of SomeClass() : super() {}, where the ": super()"
+/// part is optional and it's used to delegate constant parameters to the
+/// super-parent's constructor.
class Example24A {
var _value;
Example24A({value: "someValue"}) {
@@ -338,71 +498,76 @@ class Example24A {
}
get value => _value;
}
+
class Example24B extends Example24A {
Example24B({value: "someOtherValue"}) : super(value: value);
}
+
example24() {
- var o1 = new Example24B(),
- o2 = new Example24B(value: "evenMore");
+ var o1 = new Example24B(), o2 = new Example24B(value: "evenMore");
print("Example24 calling super during constructor '${o1.value}'");
print("Example24 calling super during constructor '${o2.value}'");
}
-// There's a shortcut to set constructor parameters in case of simpler classes.
-// Just use the this.parameterName prefix and it will set the parameter on
-// an instance variable of same name.
+/// There's a shortcut to set constructor parameters in case of simpler classes.
+/// Just use the this.parameterName prefix and it will set the parameter on
+/// an instance variable of same name.
class Example25 {
var value, anotherValue;
Example25({this.value, this.anotherValue});
}
+
example25() {
var o = new Example25(value: "a", anotherValue: "b");
print("Example25 shortcut for constructor '${o.value}' and "
- "'${o.anotherValue}'");
+ "'${o.anotherValue}'");
}
-// Named parameters are available when declared between {}.
-// Parameter order can be optional when declared between {}.
-// Parameters can be made optional when declared between [].
+/// Named parameters are available when declared between {}.
+/// Parameter order can be optional when declared between {}.
+/// Parameters can be made optional when declared between [].
example26() {
var _name, _surname, _email;
setConfig1({name, surname}) {
_name = name;
_surname = surname;
}
+
setConfig2(name, [surname, email]) {
_name = name;
_surname = surname;
_email = email;
}
+
setConfig1(surname: "Doe", name: "John");
print("Example26 name '${_name}', surname '${_surname}', "
- "email '${_email}'");
+ "email '${_email}'");
setConfig2("Mary", "Jane");
print("Example26 name '${_name}', surname '${_surname}', "
- "email '${_email}'");
+ "email '${_email}'");
}
-// Variables declared with final can only be set once.
-// In case of classes, final instance variables can be set via constant
-// constructor parameter.
+/// Variables declared with final can only be set once.
+/// In case of classes, final instance variables can be set via constant
+/// constructor parameter.
class Example27 {
final color1, color2;
- // A little flexibility to set final instance variables with syntax
- // that follows the :
+ /// A little flexibility to set final instance variables with syntax
+ /// that follows the :
Example27({this.color1, color2}) : color2 = color2;
}
+
example27() {
final color = "orange", o = new Example27(color1: "lilac", color2: "white");
print("Example27 color is '${color}'");
print("Example27 color is '${o.color1}' and '${o.color2}'");
}
-// To import a library, use import "libraryPath" or if it's a core library,
-// import "dart:libraryName". There's also the "pub" package management with
-// its own convention of import "package:packageName".
-// See import "dart:collection"; at the top. Imports must come before
-// other code declarations. IterableBase comes from dart:collection.
+/// To import a library, use import "libraryPath" or if it's a core library,
+/// import "dart:libraryName". There's also the "pub" package management with
+/// its own convention of import "package:packageName".
+/// See import "dart:collection"; at the top. Imports must come before
+/// other code declarations. IterableBase comes from dart:collection.
class Example28 extends IterableBase {
var names;
Example28() {
@@ -410,16 +575,17 @@ class Example28 extends IterableBase {
}
get iterator => names.iterator;
}
+
example28() {
var o = new Example28();
o.forEach((name) => print("Example28 '${name}'"));
}
-// For control flow we have:
-// * standard switch with must break statements
-// * if-else if-else and ternary ..?..:.. operator
-// * closures and anonymous functions
-// * break, continue and return statements
+/// For control flow we have:
+/// * standard switch with must break statements
+/// * if-else if-else and ternary ..?..:.. operator
+/// * closures and anonymous functions
+/// * break, continue and return statements
example29() {
var v = true ? 30 : 60;
switch (v) {
@@ -435,10 +601,12 @@ example29() {
callItForMe(fn()) {
return fn();
}
+
rand() {
v = new DM.Random().nextInt(50);
return v;
}
+
while (true) {
print("Example29 callItForMe(rand) '${callItForMe(rand)}'");
if (v != 30) {
@@ -446,17 +614,21 @@ example29() {
} else {
continue;
}
- // Never gets here.
+ /// Never gets here.
}
}
-// Parse int, convert double to int, or just keep int when dividing numbers
-// by using the ~/ operation. Let's play a guess game too.
+/// Parse int, convert double to int, or just keep int when dividing numbers
+/// by using the ~/ operation. Let's play a guess game too.
example30() {
- var gn, tooHigh = false,
- n, n2 = (2.0).toInt(), top = int.parse("123") ~/ n2, bottom = 0;
+ var gn,
+ tooHigh = false,
+ n,
+ n2 = (2.0).toInt(),
+ top = int.parse("123") ~/ n2,
+ bottom = 0;
top = top ~/ 6;
- gn = new DM.Random().nextInt(top + 1); // +1 because nextInt top is exclusive
+ gn = new DM.Random().nextInt(top + 1); /// +1 because nextInt top is exclusive
print("Example30 Guess a number between 0 and ${top}");
guessNumber(i) {
if (n == gn) {
@@ -464,10 +636,11 @@ example30() {
} else {
tooHigh = n > gn;
print("Example30 Number ${n} is too "
- "${tooHigh ? 'high' : 'low'}. Try again");
+ "${tooHigh ? 'high' : 'low'}. Try again");
}
return n == gn;
}
+
n = (top - bottom) ~/ 2;
while (!guessNumber(n)) {
if (tooHigh) {
@@ -479,19 +652,64 @@ example30() {
}
}
-// Programs have only one entry point in the main function.
-// Nothing is expected to be executed on the outer scope before a program
-// starts running with what's in its main function.
-// This helps with faster loading and even lazily loading of just what
-// the program needs to startup with.
+/// Optional Positional Parameter:
+/// parameter will be disclosed with square bracket [ ] & square bracketed parameter are optional.
+example31() {
+ findVolume31(int length, int breath, [int height]) {
+ print('length = $length, breath = $breath, height = $height');
+ }
+
+ findVolume31(10,20,30); //valid
+ findVolume31(10,20); //also valid
+}
+
+/// Optional Named Parameter:
+/// parameter will be disclosed with curly bracket { }
+/// curly bracketed parameter are optional.
+/// have to use parameter name to assign a value which separated with colan :
+/// in curly bracketed parameter order does not matter
+/// these type parameter help us to avoid confusion while passing value for a function which has many parameter.
+example32() {
+ findVolume32(int length, int breath, {int height}) {
+ print('length = $length, breath = $breath, height = $height');
+ }
+
+ findVolume32(10,20,height:30);//valid & we can see the parameter name is mentioned here.
+ findVolume32(10,20);//also valid
+}
+
+/// Optional Default Parameter:
+/// same like optional named parameter in addition we can assign default value for this parameter.
+/// which means no value is passed this default value will be taken.
+example33() {
+ findVolume33(int length, int breath, {int height=10}) {
+ print('length = $length, breath = $breath, height = $height');
+ }
+
+ findVolume33(10,20,height:30);//valid
+ findVolume33(10,20);//valid
+}
+
+/// Dart has also added feature such as Null aware operators
+var isBool = true;
+var hasString = isBool ?? "default String";
+
+/// Programs have only one entry point in the main function.
+/// Nothing is expected to be executed on the outer scope before a program
+/// starts running with what's in its main function.
+/// This helps with faster loading and even lazily loading of just what
+/// the program needs to startup with.
main() {
print("Learn Dart in 15 minutes!");
- [example1, example2, example3, example4, example5, example6, example7,
- example8, example9, example10, example11, example12, example13, example14,
- example15, example16, example17, example18, example19, example20,
- example21, example22, example23, example24, example25, example26,
- example27, example28, example29, example30
- ].forEach((ef) => ef());
+ [
+ example1, example2, example3, example4, example5,
+ example6, example7, example8, example9, example10,
+ example11, example12, example13, example14, example15,
+ example16, example17, example18, example19, example20,
+ example21, example22, example23, example24, example25,
+ example26, example27, example28, example29,
+ example30 // Adding this comment stops the dart formatter from putting all items on a new line
+ ].forEach((ef) => ef());
}
```
@@ -500,8 +718,5 @@ main() {
Dart has a comprehensive web-site. It covers API reference, tutorials, articles and more, including a
useful Try Dart online.
-http://www.dartlang.org/
-http://try.dartlang.org/
-
-
-
+[https://www.dartlang.org](https://www.dartlang.org)
+[https://try.dartlang.org](https://try.dartlang.org)
diff --git a/de-de/LOLCODE-de.html.markdown b/de-de/LOLCODE-de.html.markdown
new file mode 100644
index 00000000..57eb0ff8
--- /dev/null
+++ b/de-de/LOLCODE-de.html.markdown
@@ -0,0 +1,188 @@
+---
+language: LOLCODE
+filename: learnLOLCODE-de.lol
+contributors:
+ - ["abactel", "https://github.com/abactel"]
+translators:
+ - ["Henrik Jürges", "http://github.com/santifa"]
+lang: de-de
+---
+
+LOLCODE ist eine esoterische Programmiersprache die die Sprache der [lolcats](https://upload.wikimedia.org/wikipedia/commons/a/ab/Lolcat_in_folder.jpg?1493656347257) nachahmt.
+
+```
+BTW Das ist ein Kommentar
+BTW Das Programm muss mit `HAI <language version>` beginnen und mit `KTHXBYE` enden.
+
+HAI 1.3
+CAN HAS STDIO? BTW Standard Header importieren
+
+OBTW
+ ==========================================================================
+ ============================== Grundlegendes =============================
+ ==========================================================================
+TLDR
+
+BTW Texte anzeigen:
+VISIBLE "HELLO WORLD"
+
+BTW Variablen deklarieren:
+I HAS A MESSAGE ITZ "CATZ ARE GOOD"
+VISIBLE MESSAGE
+
+OBTW
+ Variablen sind dynamisch typisiert und der Typ muss nicht explizit
+ angegeben werden. Die möglichen Typen sind:
+TLDR
+
+I HAS A STRING ITZ "DOGZ ARE GOOOD" BTW Typ ist YARN
+I HAS A INTEGER ITZ 42 BTW Typ ist NUMBR
+I HAS A FLOAT ITZ 3.1415 BTW Typ ist NUMBAR
+I HAS A BOOLEAN ITZ WIN BTW Typ ist TROOF
+I HAS A UNTYPED BTW Typ ist NOOB
+
+BTW Eingaben von Nutzern:
+I HAS A AGE
+GIMMEH AGE
+BTW Die Variable wird als YARN gespeichert und kann in eine
+BTW NUMBR konvertiert werden:
+AGE IS NOW A NUMBR
+
+OBTW
+ ==========================================================================
+ ================================== MATHE =================================
+ ==========================================================================
+TLDR
+
+BTW LOLCODE benutzt polnische Notation für Mathe.
+
+BTW grundlegende mathematische Notationen:
+
+SUM OF 21 AN 33 BTW 21 + 33
+DIFF OF 90 AN 10 BTW 90 - 10
+PRODUKT OF 12 AN 13 BTW 12 * 13
+QUOSHUNT OF 32 AN 43 BTW 32 / 43
+MOD OF 43 AN 64 BTW 43 modulo 64
+BIGGR OF 23 AN 53 BTW max(23, 53)
+SMALLR OF 53 AN 45 BTW min(53, 45)
+
+BTW binäre Notation:
+
+BOTH OF WIN AN WIN BTW und: WIN if x=WIN, y=WIN
+EITHER OF FAIL AN WIN BTW oder: FAIL if x=FAIL, y=FAIL
+WON OF WIN AN FAIL BTW exklusives oder: FAIL if x=y
+NOT FAIL BTW unäre Negation: WIN if x=FAIL
+ALL OF WIN AN WIN MKAY BTW beliebige Stelligkeit bei AND
+ANY OF WIN AN FAIL MKAY BTW beliebige Stelligkeit bei OR
+
+BTW Vergleiche:
+
+BOTH SAEM "CAT" AN "DOG" BTW WIN wenn x == y
+DIFFRINT 732 AN 184 BTW WIN wenn x != y
+BOTH SAEM 12 AN BIGGR OF 12 AN 4 BTW x >= y
+BOTH SAEM 43 AN SMALLR OF 43 AN 56 BTW x <= y
+DIFFRINT 64 AN SMALLR OF 64 AN 2 BTW x > y
+DIFFRINT 75 AN BIGGR OF 75 AN 643 BTW x < y
+
+OBTW
+ ==========================================================================
+ ============================= Flusskontrolle =============================
+ ==========================================================================
+TLDR
+
+BTW If/then Statement:
+I HAS A ANIMAL
+GIMMEH ANIMAL
+BOTH SAEM ANIMAL AN "CAT", O RLY?
+ YA RLY
+ VISIBLE "YOU HAV A CAT"
+ MEBBE BOTH SAEM ANIMAL AN "MAUS"
+ VISIBLE "NOM NOM NOM. I EATED IT."
+ NO WAI
+ VISIBLE "AHHH IS A WOOF WOOF"
+OIC
+
+BTW Case Statement:
+I HAS A COLOR
+GIMMEH COLOR
+COLOR, WTF?
+ OMG "R"
+ VISIBLE "RED FISH"
+ GTFO
+ OMG "Y"
+ VISIBLE "YELLOW FISH"
+ BTW Weil hier kein `GTFO` ist wird auch das nächste Statement überprüft
+ OMG "G"
+ OMG "B"
+ VISIBLE "FISH HAS A FLAVOR"
+ GTFO
+ OMGWTF
+ VISIBLE "FISH IS TRANSPARENT OHNO WAT"
+OIC
+
+BTW For Schleife:
+I HAS A TEMPERATURE
+GIMMEH TEMPERATURE
+TEMPERATURE IS NOW A NUMBR
+IM IN YR LOOP UPPIN YR ITERATOR TIL BOTH SAEM ITERATOR AN TEMPERATURE
+ VISIBLE ITERATOR
+IM OUTTA YR LOOP
+
+BTW While Schleife:
+IM IN YR LOOP NERFIN YR ITERATOR WILE DIFFRINT ITERATOR AN -10
+ VISIBLE ITERATOR
+IM OUTTA YR LOOP
+
+OBTW
+ =========================================================================
+ ================================ Strings ================================
+ =========================================================================
+TLDR
+
+BTW Zeilenumbrüche:
+VISIBLE "FIRST LINE :) SECOND LINE"
+
+BTW Tabulatoren:
+VISIBLE ":>SPACES ARE SUPERIOR"
+
+BTW Bell (macht beep):
+VISIBLE "NXT CUSTOMER PLS :o"
+
+BTW Anführungszeichen in Strings:
+VISIBLE "HE SAID :"I LIKE CAKE:""
+
+BTW Doppelpunkte in Strings :
+VISIBLE "WHERE I LIVE:: CYBERSPACE"
+
+OBTW
+ =========================================================================
+ =============================== Funktionen ==============================
+ =========================================================================
+TLDR
+
+BTW Definieren einer neuen Funktion:
+HOW IZ I SELECTMOVE YR MOVE BTW `MOVE` ist ein Argument
+ BOTH SAEM MOVE AN "ROCK", O RLY?
+ YA RLY
+ VISIBLE "YOU HAV A ROCK"
+ NO WAI
+ VISIBLE "OH NO IS A SNIP-SNIP"
+ OIC
+ GTFO BTW Gibt NOOB zurück
+IF U SAY SO
+
+BTW Eine Funktion deklarieren und einen Wert zurückgeben:
+HOW IZ I IZYELLOW
+ FOUND YR "YELLOW"
+IF U SAY SO
+
+BTW Eine Funktion aufrufen:
+I IZ IZYELLOW MKAY
+
+KTHXBYE
+```
+
+## Weiterführende Informationen:
+
+- [LCI compiler](https://github.com/justinmeza/lci)
+- [Official spec](https://github.com/justinmeza/lolcode-spec/blob/master/v1.2/lolcode-spec-v1.2.md)
diff --git a/de-de/asciidoc-de.html.markdown b/de-de/asciidoc-de.html.markdown
index 1a8cdd5a..e3f64a00 100644
--- a/de-de/asciidoc-de.html.markdown
+++ b/de-de/asciidoc-de.html.markdown
@@ -84,15 +84,11 @@ Abteilungstitel
===== Level 4 <h5>
-====== Level 5 <h6>
-
-======= Level 6 <h7>
-
```
Listen
-Um eine Aufzählung zu erstellen verwendest du Sternchen.
+Um eine Aufzählung zu erstellen, verwendest du Sternchen.
```
* foo
@@ -100,7 +96,7 @@ Um eine Aufzählung zu erstellen verwendest du Sternchen.
* baz
```
-Um eine nummerierte Liste zu erstellen verwendest du Punkte.
+Um eine nummerierte Liste zu erstellen, verwendest du Punkte.
```
. item 1
@@ -108,7 +104,7 @@ Um eine nummerierte Liste zu erstellen verwendest du Punkte.
. item 3
```
-Um Listen zu verschachteln musst du zusätzliche Sternchen und Punkte hinzufügen. Dies ist bis zu fünf Mal möglich.
+Um Listen zu verschachteln, musst du zusätzliche Sternchen beziehungsweise Punkte hinzufügen. Dies ist bis zu fünf Mal möglich.
```
* foo 1
diff --git a/de-de/bash-de.html.markdown b/de-de/bash-de.html.markdown
index 7928b136..3a76708a 100644
--- a/de-de/bash-de.html.markdown
+++ b/de-de/bash-de.html.markdown
@@ -157,7 +157,7 @@ echo "#helloworld" | cat > output.out
echo "#helloworld" | tee output.out >/dev/null
# Löschen der Hilfsdateien von oberhalb, mit Anzeige der Dateinamen
-# (mit '-i' für "interactive" erfolgt für jede Date eine Rückfrage)
+# (mit '-i' für "interactive" erfolgt für jede Datei eine Rückfrage)
rm -v output.out error.err output-and-error.log
# Die Ausgabe von Befehlen kann mit Hilfe von $( ) in anderen Befehlen verwendet weden:
@@ -180,7 +180,7 @@ esac
# 'for' Schleifen iterieren über die angegebene Zahl von Argumenten:
# Der Inhalt von $Variable wird dreimal ausgedruckt.
-for $Variable in {1..3}
+for Variable in {1..3}
do
echo "$Variable"
done
@@ -217,7 +217,7 @@ done
function foo ()
{
echo "Argumente funktionieren wie bei skripts: $@"
- echo Und: $1 $2..."
+ echo "Und: $1 $2..."
echo "Dies ist eine Funktion"
return 0
}
diff --git a/de-de/bc.html.markdown b/de-de/bc.html.markdown
new file mode 100644
index 00000000..49a2878d
--- /dev/null
+++ b/de-de/bc.html.markdown
@@ -0,0 +1,102 @@
+---
+language: bc
+contributors:
+ - ["caminsha", "https://github.com/caminsha"]
+filename: learnbc-de.bc
+lang: de-de
+---
+```c
+/* Das is ein mehr-
+zeiliger Kommentar */
+# Das ist ein (einzeiliger) Kommentar (in GNU bc).
+
+ /*1. Variablen und Kontrollstrukturen*/
+num = 45 /* Alle Variablen speichern nur Doubles und es ist
+ nicht möglich String-Konstanten direkt zu speichern */
+num = 45; /* Es kann nach jedem Statement ein optionales Semikolon
+ hinzugefügt werden */
+/* Blöcke werden mit den Operatoren {} (ähnlich wie in C) bezeichnet */
+while(num < 50) {
+ num += 1 /* äquivalent zu num=num+1.
+ a = a Op b ist äquivalent zu a Op= b*/
+}
+/* Ausserdem gibt es ++ (Inkrement) und -- (Dekrement) Operatoren */
+/* Es gibt 3 spezielle Variablen:
+scale: definiert die Anzahl Nachkommastellen
+ibase: definiert die Basis der Eingabe
+obase: definiert die Basis der Ausgabe*/
+/*Wenn-Bedingungen:*/
+hour = read() /*Eingabe einer Zahl*/
+
+if(hour < 12) { /*Operatoren sind genau wie in C*/
+ print "Guten Morgen\n" /*"print" Gibt Strings oder Variablen
+ mit einem Komma separiert aus.*/
+} else if(hour == 12) {
+ print "Hallo\n"
+ /* Escape-Sequenzen starten mite einem \ in einem String.
+ Um Escape-Sequenzen klarer zu machen, ist hier eine vereinfachte
+ Liste, welche in bc funktioneren.:
+ \b: Backspace
+ \c: carriage return
+ \n: Zeilenumbruch
+ \t: Tab
+ \\: Backslash*/
+} else {
+ /* Standardmässig sind Variablen global. */
+ thisIsGlobal = 5
+ /*Variablen können lokal gemacht werden. Benutze das Schlüsselwort "auto"
+ in einer Funktion.*/
+}
+
+/* Jede Variable hat als Voreinstellung den Wert 0. */
+num = blankVariable /*num wurde auf 0 gesetzt.*/
+
+/*Wie in C ist nur 0 falsch.*/
+if(!num) {print "false\n"}
+
+/*Im Gegensatz zu C hat bc den Ternäroperator ?: nicht. Zum Beispiel
+führt dieser Codeblok zu einem Fehler:
+a = (num) ? 1 : 0
+Jedoch kann dies simuliert werden:*/
+a = (num) && (1) || (0) /*&& ist das UND, || ist das ODER*/
+
+/*For-Schleifen*/
+num = 0
+for(i = 1; i <= 100; i++) {/*Gleich wie die For-Schleife in C*/
+ num += i
+}
+
+ /*2.Funktionen und Arrays*/
+define fac(n) { /*Definiere eine Funktion mit define*/
+ if(n == 1 || n == 0) {
+ return 1 /*Gebe einen Wert zurück*/
+ }
+ return n * fac(n - 1) /*Rekursion ist möglich*/
+}
+
+/*Closures und anonyme Funktionen sind nicht möglich */
+
+num = fac(4) /*24*/
+
+/*Dies ist ein Beispiel von lokalen Variabeln.*/
+define x(n) {
+ auto x
+ x = 1
+ return n + x
+}
+x(3) /*4*/
+print x /*Es stellt sich heraus, dass x ausserhalb der Funktion nicht
+ zugänglich ist.*/
+/*Arrays sind äquivalent zu C Arrays.*/
+for(i = 0; i <= 3; i++) {
+ a[i] = 1
+}
+/*Greife wie folgt darauf zu:*/
+print a[0], " ", a[1], " ", a[2], " ", a[3], "\n"
+quit /* Füge diese Codezeile hinzu, um sicherzustellen, dass
+das Programm beendet. Diese Codezeile ist optional.*/
+```
+Viel Spass mit diesem einfachen Rechner! (Oder dieser Programmiersprache, um exakt zu sein.)
+
+Das ganze Programm wurde in GNU bc geschrieben. Um es auszuführen, benutze ```bc learnbc.bc```.
+
diff --git a/de-de/c++-de.html.markdown b/de-de/c++-de.html.markdown
new file mode 100644
index 00000000..87e75ad6
--- /dev/null
+++ b/de-de/c++-de.html.markdown
@@ -0,0 +1,1158 @@
+---
+language: c++
+filename: learncpp-de.cpp
+contributors:
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Matt Kline", "https://github.com/mrkline"]
+ - ["Geoff Liu", "http://geoffliu.me"]
+ - ["Connor Waters", "http://github.com/connorwaters"]
+ - ["Ankush Goyal", "http://github.com/ankushg07"]
+ - ["Jatin Dhankhar", "https://github.com/jatindhankhar"]
+ - ["Maximilian Sonnenburg", "https://github.com/LamdaLamdaLamda"]
+ - ["caminsha", "https://github.com/caminsha"]
+lang: de-de
+---
+
+C++ ist eine Systemprogrammiersprache die,
+
+[laut dem Begründer Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote)
+entworfen wurde um,
+
+- "besseres C" zu sein
+- Datenabstraktion zu unterstützen
+- Objektorientierung zu unterstützen
+- generische Programmierung zu unterstützen
+
+Durch seine Syntax kann sie durchaus schwieriger und komplexer als neuere Sprachen sein.
+
+Sie ist weit verbreitet, weil sie in Maschinen-Code kompiliert, welcher direkt vom Prozessor ausgeführt
+werden kann und somit eine strikte Kontrolle über die Hardware bietet und gleichzeitig
+High-Level-Features wie generics, exceptions und Klassen enthält.
+
+Diese Kombination aus Geschwindigkeit und Funktionalität bildet C++ und ist eine der
+weitverbreitesten Programmiersprachen.
+
+```c++
+//////////////////
+// Vergleich zu C
+//////////////////
+
+// C ist fast eine Untermenge von C++ und teilt sich grundsätzlich die
+// Syntax für Variablen Deklarationen, primitiven Typen und Funktionen.
+
+// Wie in C ist der Programmeinsprungpunkt eine Funktion, welche "main" genannt wird und
+// einen Integer als Rückgabetyp besitzt.
+
+// Dieser Wert fungiert als Beendigungsstatus des Programms.
+// Siehe: https://de.wikipedia.org/wiki/Return_Code für weitere Informationen
+int main(int argc, char** argv)
+{
+ // Kommandozeilen Argumente werden genauso wie in C über argc und argv übergeben
+ // argc entspricht der Anzahl von Argumenten und argv ist ein Array von C-style
+ // strings (char*), welche die Argumente repräsentieren.
+ // Das erste Argument ist der Name des Programms, welches aufgerufen wird.
+ // Argc und argv können, wenn nicht benötigt, weg gelassen werden, indem
+ // die Funktionssignatur "int main()" verwendet wird.
+
+ // Ein Rückgabewert von 0 repräsentiert die erfolgreiche Ausführung.
+ return 0;
+}
+
+// C++ unterscheidet sich in einigen Punkten von C:
+
+// In C++ sind Zeichen-Literale char´s
+sizeof('c') == sizeof(char) == 1
+
+// In C sind Zeichen-Literale int´s
+sizeof('c') == sizeof(int)
+
+// C++ verwendet striktes prototyping
+void func(); // Funktion ohne Argumente
+
+// In C
+void func(); // Funktion mit beliebiger Anzahl von Argumenten
+
+// Verwende nullptr, anstatt von NULL!!!
+int* ip = nullptr;
+
+// C standard header sind in C++ verfügbar.
+// C header enden mit .h, während
+// C++ header das Präfix "c" besitzen und kein ".h" Suffix verwenden.
+
+// Die C++ Standard Version:
+#include <cstdio>
+
+// Die C Standard Version:
+#include <stdio.h>
+
+int main()
+{
+ printf("Hello, world!\n");
+ return 0;
+}
+
+///////////////////////
+// Funktionsüberladung
+///////////////////////
+
+// C++ unterstützt Funktionsüberladung
+// Jede Funktion kann unterschiedliche Parameter erhalten.
+void print(char const* myString)
+{
+ printf("String %s\n", myString);
+}
+
+void print(int myInt)
+{
+ printf("My int is %d", myInt);
+}
+
+int main()
+{
+ print("Hello"); // Wird aufgelöst zu "void print(const char*)"
+ print(15); // Wird aufgelöst zu "void print(int)"
+}
+
+/////////////////////////////
+// Standard Funktionsargumente
+/////////////////////////////
+
+// Argumente können per Standard für eine Funktion gesetzt werden,
+// wenn diese beim Aufruf nicht bereitgestellt werden.
+void doSomethingWithInts(int a = 1, int b = 4)
+{
+ // führe Anweisungen mit "int´s" aus.
+}
+
+int main()
+{
+ doSomethingWithInts(); // a = 1, b = 4
+ doSomethingWithInts(20); // a = 20, b = 4
+ doSomethingWithInts(20, 5); // a = 20, b = 5
+}
+
+// Standard-Argumente müssen am Ende der Liste der Argumente stehen.
+void invalidDeclaration(int a = 1, int b) // Fehler!
+{
+}
+
+
+/////////////
+// Namespaces (Namensräume)
+/////////////
+
+// Namespaces stellen einen getrennten Gültigkeitsbereich für Variablen,
+// Funktionen und andere Deklarationen zur Verfügung.
+// Namespaces können geschachtelt werden.
+namespace First
+{
+ namespace Nested
+ {
+ void foo()
+ {
+ printf("This is First::Nested::foo\n");
+ }
+ } // Ende des Namespace "Nested"
+} // Ende des Namespace "First"
+
+namespace Second
+{
+ void foo()
+ {
+ printf("This is Second::foo\n");
+ }
+}
+
+void foo()
+{
+ printf("This is global foo\n");
+}
+
+int main()
+{
+ // Fügt alle Symbole aus dem namespace Second in den aktuellen Gültigkeitsbereich (scope).
+ // "foo()" wird nun nicht länger funktionieren, da es nun doppeldeutig ist, ob foo aus
+ // dem namespace foo oder darüberliegenden aufgerufen wird.
+ using namespace Second;
+
+ Second::foo(); // Gibt "This is Second::foo" aus.
+ First::Nested::foo(); // Gibt "This is First::Nested::foo" aus.
+ ::foo(); // Gibt "This is global foo" aus.
+}
+
+///////////////
+// Eingabe/Ausgabe
+///////////////
+
+// C++ verwendet für die Eingabe und Ausgabe streams.
+// cin, cout und cerr repräsentieren stdin, stdout und stderr.
+// << ist der Einfügeoperator und >> ist der Extraktionsoperator.
+
+#include <iostream> // Include für Eingabe/Ausgabe (I/O) streams
+
+using namespace std; // Streams befinden sich im std namespace (standard library)
+
+int main()
+{
+ int myInt;
+
+ // Ausgabe auf stdout (oder Terminal/Bildschirm)
+ cout << "Enter your favorite number:\n";
+
+ // Empfängt Eingabe
+ cin >> myInt;
+
+ // cout kann ebenfalls formatiert werden
+ cout << "Your favorite number is " << myInt << "\n";
+ // Gibt "Your favorite number is <myInt>" aus
+
+ cerr << "Used for error messages";
+}
+
+//////////
+// Zeichenketten (Strings)
+//////////
+
+// Strings in C++ sind Objekte und haben diverse member-functions
+#include <string>
+
+using namespace std; // Strings sind ebenfalls im namespace std (Standard Bibliothek)
+
+string myString = "Hello";
+string myOtherString = " World";
+
+// + wird für das Anhängen von strings verwendet.
+cout << myString + myOtherString; // "Hello World"
+
+cout << myString + " You"; // "Hello You"
+
+// C++ strings sind mutable.
+myString.append(" Dog");
+cout << myString; // "Hello Dog"
+
+
+/////////////
+// Referenzen
+/////////////
+
+// Zusätzlich zu Pointern, wie jene in C.
+// C++ besitzt _Referenzen_.
+// Diese sind Pointer-Typen, welche nicht erneut zugewiesen werden können
+// und nicht Null sein können.
+// Sie besitzen den selben Syntax wie Variablen.
+// Für die Dereferenzierung ist kein * notwendig und
+// & (die Adresse) wird nicht für die Zuweisung verwendet.
+
+using namespace std;
+
+string foo = "I am foo";
+string bar = "I am bar";
+
+
+string& fooRef = foo; // Erzeugt eine Referenz auf foo.
+fooRef += ". Hi!"; // Verändert foo durch die Referenz
+cout << fooRef; // Gibt "I am foo. Hi!" aus.
+
+
+// Weist "fooRef" nicht erneut zu. Dies ist dasselbe, wie "foo = bar" und
+// foo == "I am bar"
+// nach dieser Zeile
+cout << &fooRef << endl; // Gibt die Adresse von foo aus
+fooRef = bar;
+cout << &fooRef << endl; // Gibt ebenfalls die Adresse von foo aus
+cout << fooRef; // Gibt "I am bar" aus
+
+// Die Adresse von fooRef verbleibt die selbe, sie verweist immer noch auf foo
+
+const string& barRef = bar; // Erzeugt konstante Referenz auf bar.
+// Wie in C, können konstante Werte ( und Pointer bzw. Referenzen) nicht verändert werden.
+
+barRef += ". Hi!"; // Fehler: konstante Referenzen können nicht verändert werden.
+
+// Hinweis: bevor wir genauer Referenzen besprechen, schauen wir uns zuerst ein Konzept an,
+// welches als "temporäres Objekt" bezeichnet wird. Gehen wir von folgenden Code aus:
+string tempObjectFun() { ... }
+string retVal = tempObjectFun();
+
+// Was passiert nun in der zweiten Zeile:
+// - ein String Objekt wird von "tempObjectFun" zurückgegeben
+// - ein neuer String wird mit dem zurückgegebenen Objekt als Argument für den Konstruktor erzeugt.
+// - das zurückgegebene Objekt wird zerstört
+// Das zurückgegbene Objekt wird temporäres Objekt genannt. Temporäre Objekte werden erzeugt
+// wann immer eine Funktion ein Objekt zurückgibt. Zerstört werden diese am Ende der Auswertung des Ausdrucks
+// (dies schreibt der Standard vor, aber Compiler sind berechtigt dieses Verhalten zu ändern. Siehe "return value optimization"
+// für Details). Wie in diesem Code:
+foo(bar(tempObjectFun()))
+
+// Nehmen wir an, foo und bar existieren. Das Objekt wird von "tempObjectFun" zurückgegeben,
+// wird an bar übergeben und ist zerstört bevor foo aufgerufen wird.
+
+// Zurück zu Referenzen. Die Annahme, dass die "am Ende des Ausdrucks" Regel gültig ist,
+// wenn das temporäre Objekt an eine konstante Referenz gebunden ist, ist der Fall, wenn die Lebensdauer
+// auf den aktuellen Gültigkeitsbereich erweitert wird.
+
+void constReferenceTempObjectFun() {
+ // constRef erhält das temporäre Objekt und ist gültig bis ans Ende der Funktion
+ const string& constRef = tempObjectFun();
+ ...
+}
+
+// Eine andere Art von Referenzen wurde in C++11 eingeführt und ist speziell für
+// temporäre Objekte. Es ist nicht möglich Variablen des Typs zu besitzen, aber
+// Vorrechte bei der Auflösung zu besitzen.
+
+void someFun(string& s) { ... } // Reguläre Referenz
+void someFun(string&& s) { ... } // Referenz auf ein temporäres Objekt
+
+string foo;
+someFun(foo); // Ruft die Funktion mit der regulären Referenz auf
+someFun(tempObjectFun()); // Ruft die Funktion mit der temporären Referenz auf
+
+// Zum Beispiel existieren diese zwei Varianten von Konstruktoren für
+// std::basic_string:
+basic_string(const basic_string& other);
+basic_string(basic_string&& other);
+
+// Nehmen wir an, wir erzeugen einen neuen String eines temporären Objekts (welches später
+// zerstört wird), hierbei existiert ein effizienterer Konstruktor. Dieses Konzept wird
+// als "move semantics" bezeichnet (bewegen eines Objekts in ein anderes in C++).
+
+/////////////////////
+// Enumerations (Aufzählungstypen)
+/////////////////////
+
+// Enums sind eine einfachere Art und Weise einen Wert einer Konstante zu zuweisen.
+// Häufig wird dies verwendet, um den Code lesbarer zu gestalten bzw. zu visualisieren.
+enum ECarTypes
+{
+ Sedan,
+ Hatchback,
+ SUV,
+ Wagon
+};
+
+ECarTypes GetPreferredCarType()
+{
+ return ECarTypes::Hatchback;
+}
+
+// Mit C++11 existiert eine einfache Möglichkeit einem Typ dem Enum zuzuweisen. Dies
+// kann durchaus sinnvoll bei der Serialisierung von Daten sein, oder bei der Konvertierung
+// zwischen Typen bzw. Konstanten.
+enum ECarTypes : uint8_t
+{
+ Sedan, // 0
+ Hatchback, // 1
+ SUV = 254, // 254
+ Hybrid // 255
+};
+
+void WriteByteToFile(uint8_t InputValue)
+{
+ // Serialisierung von "InputValue" in eine Datei
+}
+
+void WritePreferredCarTypeToFile(ECarTypes InputCarType)
+{
+ // Das enum wird implizit zu einem "uint8_t" konvertiert. Bedingt dadurch, dass
+ // es sich um ein "enum" handelt.
+ WriteByteToFile(InputCarType);
+}
+
+// Nicht immer ist es gewünscht, dass enum´s zu einem Integer oder zu einem anderen
+// enum umgewandelt werden. Daher ist es möglich eine enum-Klasse zu erzeugen, welche
+// nicht implizit umgewandelt wird.
+enum class ECarTypes : uint8_t
+{
+ Sedan, // 0
+ Hatchback, // 1
+ SUV = 254, // 254
+ Hybrid // 255
+};
+
+void WriteByteToFile(uint8_t InputValue)
+{
+ // Serialisierung von InputValue in eine Datei
+}
+
+void WritePreferredCarTypeToFile(ECarTypes InputCarType)
+{
+ // Wird nicht kompilieren, da "ECarTypes" ein "uint8_t" ist, da das enum
+ // als "enum class" deklariert wurde!
+ WriteByteToFile(InputCarType);
+}
+
+//////////////////////////////////////////
+// Klassen und objekorientierte Programmierung
+//////////////////////////////////////////
+
+// Erstes Beispiel einer Klasse
+#include <iostream>
+
+// Deklaration einer Klasse.
+// Klassen werden üblicherweise im header (.h oder .hpp) deklariert.
+class Dog
+{
+ // Member Variablen und Funktionen sind private per default (standard).
+ std::string name;
+ int weight;
+
+// Alle nachfolgenden member sind "public" bis
+// "private:" oder "protected:" auftritt.
+public:
+
+ // Standard Konstruktor
+ Dog();
+
+ // Member-Funktionsdeklaration (Implementierung folgt).
+ // Bemerkung: std::string statt der Verwendung von namespace std;
+ // "using namespace" sollte niemals in einem header verwendet werden.
+ void setName(const std::string& dogsName);
+
+ void setWeight(int dogsWeight);
+
+ // Funktionen, die Objekte nicht ändern, sollten mit const deklariert werden.
+ // Funktionen müssen explizit als "virtual" deklariert werden, um in einer
+ // abgeleiteten Klassen überschrieben zu werden.
+ // Aus performance Gründen sind Funktionen nicht per default virtual.
+ virtual void print() const;
+
+ // Funktionen können ebenfalls im class body definiert werden.
+ // Derart definierte Funktionen sind automatisch "inline".
+ void bark() const { std::cout << name << " barks!\n"; }
+
+ // Neben Konstruktoren, bietet C++ Destruktoren.
+ // Diese werden aufgerufen, wenn ein Objekt freigegeben wird oder
+ // seinen Wertebereich verlässt.
+ // Dies ermöglicht mächtige Paradigmen, wie auch RAII.
+ // Destruktoren sollten virtual sein, wenn eine Klasse von ihr
+ // abgeleitet wird. Ist dieser nicht virtual, dann wird der
+ // Destruktor der abgeleiteten Klasse nicht aufgerufen, insofern
+ // das Objekt durch eine Referenz/Pointer der Basisklasse entfernt wird.
+ virtual ~Dog();
+
+}; // Ein Semikolon schließt die Definition der Klasse ab.
+
+// Klassen-Member-Funktionen sind üblicherweise in der .cpp Datei implementiert.
+Dog::Dog()
+{
+ std::cout << "A dog has been constructed\n";
+}
+
+// Objekte sollten als Referenz übergeben werden und wenn diese nicht
+// verändert werden sollen, sollte das Objekt als const Referenz übergeben werden.
+void Dog::setName(const std::string& dogsName)
+{
+ name = dogsName;
+}
+
+void Dog::setWeight(int dogsWeight)
+{
+ weight = dogsWeight;
+}
+
+// "Virtual" wird nur bei der Deklaration benötigt und nicht bei der Definition.
+void Dog::print() const
+{
+ std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
+}
+
+Dog::~Dog()
+{
+ std::cout << "Goodbye " << name << "\n";
+}
+
+int main()
+{
+ Dog myDog; // Ausgabe: "A dog has been constructed"
+ myDog.setName("Barkley");
+ myDog.setWeight(10);
+ myDog.print(); // Ausgabe: "Dog is Barkley and weighs 10 kg"
+ return 0;
+} // Ausgabe: "Goodbye Barkley"
+
+// Diese Klasse erbt alles was public bzw. protected ist von der Dog-Klasse
+// und darüber hinaus auch private Methoden/Attribute, jedoch kann auf diese
+// nicht direkt zugegriffen werden. Lediglich über public/procted getter/setter.
+class OwnedDog : public Dog {
+
+public:
+ void setOwner(const std::string& dogsOwner);
+
+ // Überschreibt das Verhalten der "print" Funktion für alle "OwnedDogs".
+ // Siehe: http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
+ // für eine grundlegende Einführung in "Subtype Polymorphismus".
+ // Das "override" Schlüsselwort ist optional, aber stellt sicher, dass die
+ // Methode der Basisklasse tatsächlich überschrieben wurde.
+ void print() const override;
+
+private:
+ std::string owner;
+};
+
+// Die zugehörige .cpp Datei
+void OwnedDog::setOwner(const std::string& dogsOwner)
+{
+ owner = dogsOwner;
+}
+
+void OwnedDog::print() const
+{
+ Dog::print(); // Ruft die "print" Funktion der Basisklasse auf.
+ std::cout << "Dog is owned by " << owner << "\n";
+ // Ausgaben: "Dog is <name> and weights <weight>"
+ // "Dog is owned by <owner>"
+}
+
+//////////////////////////////////////////
+// Initialisierung und Operatorüberladung
+//////////////////////////////////////////
+
+// In C++ können Operatoren wie: +, -, *, / etc. überladen werden.
+// Dies wird umgesetzt, indem eine entsprechende Funktion definiert wird,
+// welche immer dann aufgerufen wird, sobald der Operator verwendet wird.
+#include <iostream>
+using namespace std;
+
+class Point
+{
+public:
+ // Member Variablen können mit einem default Wert initialisiert werden.
+ double x = 0;
+ double y = 0;
+
+ // Definition des Standard Konstruktor, welcher nichts tut
+ // außer den Punkt auf den default Wert (0,0) zu setzen.
+ Point() { };
+
+ // Die nachfolgende Syntax ist bekannt als "initialization list"
+ // und ist eine gängige Art Klassen-Member zu initialisieren.
+ Point (double a, double b) :
+ x(a),
+ y(b)
+ { /* Außschließliche Initialisierung der Werte */ }
+
+ // Überladung des "+" Operator.
+ Point operator+(const Point& rhs) const;
+
+ // Überladung des "+=" Operator
+ Point& operator+=(const Point& rhs);
+
+ // Sinnhaft wäre es an dieser Stelle den "-" und "-=" Operator
+ // ebenfalls zu überladen.
+};
+
+Point Point::operator+(const Point& rhs) const
+{
+ // Erzeugung eines neuen Punkts, welcher die Summe aus sich
+ // selbst und "rhs" bildet
+ return Point(x + rhs.x, y + rhs.y);
+}
+
+Point& Point::operator+=(const Point& rhs)
+{
+ x += rhs.x;
+ y += rhs.y;
+ return *this;
+}
+
+int main ()
+{
+ Point up (0,1);
+ Point right (1,0);
+
+ // Ruft den + Operator mit den entsprechenden Parametern auf.
+ Point result = up + right;
+ // Ausgabe: "Result is upright (1,1)"
+ cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
+ return 0;
+}
+
+/////////////////////
+// Templates
+/////////////////////
+
+// Templates in C++ werden in erster Linie dafür verwendet generisch zu programmieren.
+// Sie unterstützen explizite und partielle Spezialisierung und darüber hinaus können
+// sie für funktionale Klassen verwendet werden.
+// Tatsächlich bilden Templates die Turing-Vollständigkeit
+// (universelle Programmierbarkeit) ab.
+
+
+// Zu Beginn ein einführendes Beispiel der generischen Programmierung.
+// Die Definition einer Klasse bzw. Funktion, welche mit dem Typ T parametriert wird.
+template<class T>
+class Box
+{
+public:
+ // T repräsentiert an dieser Stelle einen beliebigen Typen.
+ void insert(const T&) { ... }
+};
+
+// Während der Kompilierung generiert der Compiler Kopien für jedes Template, wobei
+// hierbei die Parameter substituiert werden. Somit muss bei jedem Aufruf die gesamte
+// Definition der Klasse zur Verfügung stehen. Aus diesem Grund wird ein Template
+// komplett im header definiert.
+
+// Erzeugung einer Template-Klasse auf dem Stack:
+Box<int> intBox;
+
+// eine der zu erwartenden Verwendungen:
+intBox.insert(123);
+
+// Verschachtelungen von Templates sind möglich.
+Box<Box<int> > boxOfBox;
+boxOfBox.insert(intBox);
+
+// Bis C++11 war es erforderlich ein Leerzeichen zwischen '>' einzufügen,
+// andernfalls wurde es als '>>' geparsed (right shift).
+
+// Manchmal ist folgende Notation anzutreffen:
+// template<typename T>
+// Das 'class' Schlüsselwort und das 'typename' Schlüsselwort
+// sind fast identisch hinsichtlich der Funktionalität. Weitere
+// Informationen auf: http://en.wikipedia.org/wiki/Typename
+
+// Eine Template-Funktion:
+template<class T>
+void barkThreeTimes(const T& input)
+{
+ input.bark();
+ input.bark();
+ input.bark();
+}
+
+// Hierbei ist zu beachten, dass an dieser Stelle nichts über den Typen des Parameters
+// definiert wurde. Der Compiler wird bei jedem Aufruf bzw. jeder Erzeugung den Typen
+// prüfen. Somit funktioniert die zuvor definierte Funktion für jeden Typ 'T', die die
+// const Methode 'bark' implementiert hat.
+
+Dog fluffy;
+fluffy.setName("Fluffy")
+barkThreeTimes(fluffy); // Gibt "Fluffy barks" dreimal aus.
+
+// Template Parameter müssen keine Klassen sein.
+template<int Y>
+void printMessage()
+{
+ cout << "Learn C++ in " << Y << " minutes!" << endl;
+}
+
+// Des Weiteren können Templates aus Effizienzgründen genauer spezifiziert werden.
+// Selbstverständlich sind reale Probleme, welche genauer spezifiziert werden, nicht
+// derart trivial. Auch wenn alle Parameter explizit definiert wurden, muss die
+// Funktion oder Klasse als Template deklariert werden.
+template<>
+void printMessage<10>()
+{
+ cout << "Learn C++ faster in only 10 minutes!" << endl;
+}
+
+printMessage<20>(); // Gibt "Learn C++ in 20 minutes!" aus.
+printMessage<10>(); // Gibt "Learn C++ faster in only 10 minutes!" aus.
+
+
+/////////////////////
+// Ausnahme Behandlungen (Exception-Handling)
+/////////////////////
+
+// Die Standard Bibliothek bietet einige exceptions.
+// Siehe: http://en.cppreference.com/w/cpp/error/exception.
+// Grundsätzlich können alle Typen als exception geworfen werden.
+#include <exception>
+#include <stdexcept>
+
+// Alle exceptions, die in dem "try" Block geworfen werden, können mittels
+// "catch" abgefangen werden.
+try
+{
+ // exceptions sollten nicht auf dem heap mithilfe
+ // von "new" allokiert werden.
+ throw std::runtime_error("A problem occurred");
+}
+
+// Exceptions sollten als const Referenz abgefangen werden
+// insofern diese Objekte sind.
+catch (const std::exception& ex)
+{
+ std::cout << ex.what();
+}
+
+// Abfangen aller Exceptions, welche zuvor nicht abgefangen wurden.
+catch (...)
+{
+ std::cout << "Unknown exception caught";
+ throw; // Erneutes werfen der exception
+}
+
+///////
+// RAII
+///////
+
+// RAII steht für "Resource Acquisition Is Initialization".
+// Oft wird dies als eines der wichtigsten Paradigmen in C++ betrachtet.
+// RAII beschreibt das Konzept, dass der Konstruktor für ein Objekt
+// die Ressourcen akquiriert und der Destruktor diese freigibt.
+
+// Zum Verständnis, warum dies sinnvoll ist, nachfolgend
+// ein einführendes Beispiel:
+void doSomethingWithAFile(const char* filename)
+{
+ // Wir nehmen an, dass nichts schiefgehen wird.
+ FILE* fh = fopen(filename, "r"); // Öffnen der Datei im read-mode.
+
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+
+ fclose(fh); // Schließen des file-handle.
+}
+
+// Unglücklicherweise ist die Fehlerbehandlung äußerst kompliziert.
+// Sollte fopen fehlschlagen und "doSomethingWithTheFile" bzw.
+// "doSomethingElseWithIt", geben diese einen Fehlercode zurück.
+// (Exceptions sind eine bevorzugte Möglichkeit Fehler abzufangen
+// , allerdings bei einigen Programmierern, besonders solchen die einen C
+// background besitzen, ein unbeliebtes Mittel zur Fehlerbehandlung).
+// Nun müssen wir jeden Aufruf auf mögliche auftretende Fehler überprüfen.
+bool doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r"); // Öffnet die Datei im read-mode
+ if (fh == nullptr) // Der Pointer ist bei einem Fehler NULL .
+ return false; // Benachrichtigt den Aufrufer über den Fehler.
+
+ // Wir nehmen an, dass jede Funktion false zurückgibt, in einem Fehlerfall
+ if (!doSomethingWithTheFile(fh))
+ {
+ fclose(fh); // File handle schließen.
+ return false; // Fehler "melden".
+ }
+
+ if (!doSomethingElseWithIt(fh))
+ {
+ fclose(fh); // File handle schließen.
+ return false; // Fehler "melden".
+ }
+
+ fclose(fh); // File handle schließen.
+ return true; // Erfolg "melden".
+}
+
+// C-Programmierer handhaben dies häufig durch goto-Anweisungen:
+bool doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r");
+ if (fh == nullptr)
+ return false;
+
+ if (!doSomethingWithTheFile(fh))
+ goto failure;
+
+ if (!doSomethingElseWithIt(fh))
+ goto failure;
+
+ fclose(fh); // File handle schließen.
+ return true; // Erfolg "melden".
+
+failure:
+ fclose(fh);
+ return false; // Fehler "melden".
+}
+
+// Insofern Funktionen Fehler durch exceptions indizieren,
+// ist dies "sauberer", aber immer noch suboptimal.
+void doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r"); // Öffnet die Datei im read-mode
+ if (fh == nullptr)
+ throw std::runtime_error("Could not open the file.");
+
+ try
+ {
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+ }
+ catch (...)
+ {
+ // Im Fehlerfall sollte sichergestellt sein, dass die
+ // Datei geschlossen wird.
+ fclose(fh);
+ throw; // Erneutes werfen der exception
+ }
+
+ fclose(fh); // Schließen der Datei
+}
+
+// Folgendes ist mit der C++ file stream Klasse (fstream) zu vergleichen.
+// fstream verwendet den Destruktor, um die Datei zu schließen.
+// Der obige Destruktor wird automatisch aufgerufen, sobald das Objekt
+// den Gültigkeitsbereich verlässt.
+void doSomethingWithAFile(const std::string& filename)
+{
+ // ifstream entspricht der Kurzform von "input file stream".
+ std::ifstream fh(filename); // Öffnen der Datei
+
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+
+} // Die Datei wird automatisch vom Destruktor geschlossen.
+
+// Diese Vorgehensweise bietet massive Vorteile:
+// 1. Egal was passiert, die Ressource (das Datei-Handle) wird aufgelöst,
+// insofern der Destruktor korrekt beschrieben wurde. Es ist möglich
+// zu vergessen das Datei-Handle zu schließen, was zu einem "leak" der
+// entsprechenden Ressource führt.
+// 2. Der Code selbst ist wesentlich "sauberer".
+// Der Destruktor wird das Datei-Handle im Hintergrund schließen und der
+// Programmierer muss sich darum keinerlei Sorgen machen.
+// 3. Der Code ist "exception sicher".
+// Egal wo die exception geworfen wird, das Aufräumen wird definitiv vollzogen.
+
+// Der gesamte idiomatische C++ Code verwendet RAII für alle Ressourcen.
+// Weitere Beispiele:
+// - Speicher verwenden "unique_ptr" und "shared_ptr".
+// - Container - verkettete Listen (linked list), vector (selbst organisierende
+// Arrays), hash maps, etc., entfernen deren Inhalt, wenn diese außerhalb des
+// Gültigkeitsbereichs laufen.
+// - Mutex´s verwenden lock_guard und unique_lock.
+
+/////////////////////
+// Container
+/////////////////////
+
+// Die Container der Standard template Bibliothek beinhaltet einige vordefinierte Templates.
+// Diese verwalten die Speicherbereiche für die eigenen Elemente und stellen Member-Funktionen
+// für den Zugriff und die Manipulation bereit.
+
+// Beispielhafte Container:
+
+// Vector (dynamisches array)
+// Erlaubt das Definieren von Arrays oder Listen zur Laufzeit
+#include <vector>
+string val;
+vector<string> my_vector; // Initialisierung des Vectors.
+cin >> val;
+my_vector.push_back(val); // Fügt den Wert "val" zum Vektor "my_vector" hinzu.
+my_vector.push_back(val); // Fügt den Wert "val" zum Vektor "my_vector" hinzu (nun zwei Elemente).
+
+// Für die Iteration über Vektoren stehen zwei Methodiken zu Verfügung:
+// Entweder die klassische Iteration über den Index:
+for (int i = 0; i < my_vector.size(); i++)
+{
+ cout << my_vector[i] << endl; // Zugriff auf die Elemente des Vektors über den [] Operator
+}
+
+// Oder die Verwendung von Iteratoren:
+vector<string>::iterator it; // Initialisierng des Iterators.
+for (it = my_vector.begin(); it != my_vector.end(); ++it)
+{
+ cout << *it << endl;
+}
+
+// Set (Mengen)
+// Sets sind Container, welche einzigartige Elemente beinhalten die einer
+// spezifischen Ordnung folgen.
+
+#include<set>
+set<int> ST; // Initialisierung des Sets mit einem Integer Datentyp.
+ST.insert(30); // Einfügen des Werts 30 in das Set ST
+ST.insert(10); // Einfügen des Werts 10 in das Set ST
+ST.insert(20); // Einfügen des Werts 20 in das Set ST
+ST.insert(30); // Einfügen des Werts 30 in das Set ST
+// Folgende Elemente befinden sich nun in dem Set:
+// 10 20 30
+
+// Entfernen eines Elements:
+ST.erase(20);
+
+// Set ST: 10 30
+// Für das iterieren verwenden wir Iteratoren:
+set<int>::iterator it;
+
+for(it=ST.begin();it<ST.end();it++)
+{
+ cout << *it << endl;
+}
+
+// Ausgabe:
+// 10
+// 30
+
+// Zum leeren des gesamten Containers wird die Methode
+// Container._name.clear() verwendet.
+ST.clear();
+cout << ST.size(); // Ausgabe der Set-Größe
+
+// Ausgabe: 0
+
+// Bemerkung: für mehrdeutige Elemente werden multisets verwendet.
+// Für hash-Sets sollten unordered_set´s verwendet werden, da diese
+// wesentlich effizienter sind, allerdings keiner Ordnung folgen.
+// Verfügbar sind diese Features ab C++11.
+
+// Map
+// Maps speichern Elemente, welche einer Kombination aus "Key"
+// und "Value" folgen.
+
+#include<map>
+map<char, int> mymap; // Initialisierung der Map: char -> Key, int -> Value.
+
+mymap.insert(pair<char,int>('A',1)); // Einfügen des Werts "1" für den Key "A".
+
+mymap.insert(pair<char,int>('Z',26)); // Einfügen des Werts "26" für den Key "Z".
+
+// Das Iterieren über Maps:
+map<char,int>::iterator it;
+for (it=mymap.begin(); it!=mymap.end(); ++it)
+ std::cout << it->first << "->" << it->second << '\n';
+
+// Ausgabe:
+// A->1
+// Z->26
+
+// Für das Finden des dazugehörigen Value des Keys.
+it = mymap.find('Z');
+cout << it->second;
+
+// Ausabe: 26
+
+// Bemerkung: für "hash maps" sollten die "unordered_map´s" verwendet werden. Diese
+// sind effizienter und benötigen keine Reihenfolge. "unordered_maps" sind ab
+// C++11 verfügbar.
+
+// Container für nicht-primitive Datentypen benötigen Vergleichsfunktionen im Objekt selbst,
+// oder als Funktionspointer. Primitive Datentypen besitzen default-Vergleichsfunktionen.
+// Allerdings können diese überschrieben werden.
+class Foo
+{
+public:
+ int j;
+ Foo(int a) : j(a) {}
+};
+
+struct compareFunction
+{
+ bool operator()(const Foo& a, const Foo& b) const
+ {
+ return a.j < b.j;
+ }
+};
+
+// Folgender Code ist nicht valide, könnte aber von einigen Compilern
+// als valide angesehen werden:
+// std::map<Foo, int> fooMap;
+std::map<Foo, int, compareFunction> fooMap;
+fooMap[Foo(1)] = 1;
+fooMap.find(Foo(1)); // Wahr
+
+
+///////////////////////////////////////
+// Lambda Ausdrücke (C++11 und höher)
+///////////////////////////////////////
+
+// Lambdas sind eine gängige Methodik, um anonyme Funktionen an dem
+// Ort der Verwendung zu definieren. Darüber hinaus auch bei der
+// Verwendung von Funktionen als Argument einer Funktion.
+
+// Nehmen wir an, es soll ein Vektor von "pairs" (Paaren) mithilfe
+// des zweiten Werts des "pairs" sortiert werden.
+
+vector<pair<int, int> > tester;
+tester.push_back(make_pair(3, 6));
+tester.push_back(make_pair(1, 9));
+tester.push_back(make_pair(5, 0));
+
+// Übergabe des Lambda-Ausdrucks als drittes Argument für die nachfolgende Sortierfunktion.
+sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs)
+{
+ return lhs.second < rhs.second;
+});
+
+// Beachte die Syntax von Lambda-Ausdrücken.
+// Die [] im Lambda Ausdruck werden für die Variablen verwendet.
+// Diese so genannte "capture list" definiert, was außerhalb des Lambdas,
+// innerhalb der Funktion verfügbar sein soll und in welcher Form.
+// Dies kann folgendes sein:
+// 1. ein Wert [x]
+// 2. eine Referenz [&x]
+// 3. eine beliebige Variable, welche sich im Gültigkeitsbereich durch
+// die Referenz [&] befindet.
+// 4. wie bei 3. aber mithilfe des Werts [=]
+// Beispiel:
+
+vector<int> dog_ids;
+
+for(int i = 0; i < 3; i++)
+{
+ dog_ids.push_back(i);
+}
+
+int weight[3] = {30, 50, 10};
+
+// Nehmen wir an wir möchten die "dog_ids" gemäß des Gewichts des Hundes sortieren.
+// So sollten sich die "dog_ids" wie folgt verhalten: [2, 0, 1]
+
+// Hier werden Lambdas praktisch:
+sort(dog_ids.begin(), dog_ids.end(), [&weight](const int &lhs, const int &rhs)
+{
+ return weight[lhs] < weight[rhs];
+});
+
+
+// Weiterführender Link über Lambda-Ausdrücke:
+// http://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11
+
+///////////////////////////////
+// Range For (C++11 und höher)
+///////////////////////////////
+
+// Range-For Schleifen können verwendet werden, um über Container zu iterieren.
+int arr[] = {1, 10, 3};
+
+for(int elem: arr)
+{
+ cout << elem << endl;
+}
+
+// Insofern "auto" verwendet wird, muss der Typ nicht weiter beachtet werden.
+for(auto elem: arr)
+{
+ // Anweisungen ...
+}
+
+/////////////////////
+// Weiteres:
+/////////////////////
+
+// Einige Aspekte von C++ sind für Neueinsteiger häufig überraschend (aber auch für
+// C++ Veteranen).
+// Der nachfolgende Abschnitt ist leider nicht vollständig:
+// C++ ist eine der Sprachen, bei der es ein Leichtes ist, sich selbst ins Bein zu schießen.
+
+// Private-Methoden können überschrieben werden
+class Foo
+{
+ virtual void bar();
+};
+
+class FooSub : public Foo
+{
+ virtual void bar(); // Überschreibt Foo::bar!
+};
+
+// 0 == false == NULL
+bool* pt = new bool;
+*pt = 0; // Setzt den Wert des Pointers 'pt' auf false.
+pt = 0; // Setzt 'pt' auf den "null-pointer". Keine Compiler-Warnung.
+
+// nullptr sollte dieses Problem nicht lösen:
+int* pt2 = new int;
+*pt2 = nullptr; // Kompiliert nicht.
+pt2 = nullptr; // Setzt pt2 auf null.
+
+// Eine Ausnahme bilden bool´s.
+// Dies erlaubt es "null-pointer" zu testen: if(!ptr)
+// Die Konsequenz ist jedoch, dass dem nullptr ein bool zugewiesen werden kann.
+*pt = nullptr; // Kompiliert auch, wenn '*pt' ein bool ist!
+
+// '=' != '=' != '='!
+// Ruft Foo::Foo(const Foo&) auf, oder den Kopierkonstruktor
+Foo f2;
+Foo f1 = f2;
+
+// Ruft Foo::Foo(const Foo&) auf, aber kopiert lediglich den "Foo" Teil von
+// "fooSub". Alle zusätzlichen Member werden verworfen. Diese eigenartige Verhalten
+// wird auch "object slicing" genannt.
+FooSub fooSub;
+Foo f1 = fooSub;
+
+// Ruft Foo::operator=(Foo&) oder eine andere Variante auf.
+Foo f1;
+f1 = f2;
+
+///////////////////////////////////////
+// Tuple (C++11 und höher)
+///////////////////////////////////////
+
+#include<tuple>
+
+// Konzeptionell sind Tupel alten Datenstrukturen sehr ähnlich, allerdings haben diese keine
+// bezeichneten Daten-Member, sondern werden durch die Reihenfolge angesprochen.
+
+// Erstellen des Tupels und das Einfügen eines Werts.
+auto first = make_tuple(10, 'A');
+const int maxN = 1e9;
+const int maxL = 15;
+auto second = make_tuple(maxN, maxL);
+
+// Ausgabe der Elemente des "first" Tuple.
+cout << get<0>(first) << " " << get<1>(first) << "\n"; // Ausgabe : 10 A
+
+// Ausgabe der Elemente des "second" Tuple.
+cout << get<0>(second) << " " << get<1>(second) << "\n"; // Ausgabe: 1000000000 15
+
+int first_int;
+char first_char;
+tie(first_int, first_char) = first;
+cout << first_int << " " << first_char << "\n"; // Ausgabe : 10 A
+
+// Tuple können auch wie folgt erzeugt werden:
+
+tuple<int, char, double> third(11, 'A', 3.14141);
+// tuple_size gibt die Anzahl der Elemente in einem Tuple zurück.
+// Als "constexpr".
+
+cout << tuple_size<decltype(third)>::value << "\n"; // prints: 3
+
+// tuple_cat fügt die Elemente eines Tupels aneinander (in der selben Reihenfolge).
+
+auto concatenated_tuple = tuple_cat(first, second, third);
+// concatenated_tuple wird zu = (10, 'A', 1e9, 15, 11, 'A', 3.14141)
+
+cout << get<0>(concatenated_tuple) << "\n"; // Ausgabe: 10
+cout << get<3>(concatenated_tuple) << "\n"; // Ausgabe: 15
+cout << get<5>(concatenated_tuple) << "\n"; // Ausgabe: 'A'
+
+
+///////////////////////////////////
+// Logische- und Bitoperatoren
+//////////////////////////////////
+
+// Die meisten Operatoren in C++ entsprechen denen aus anderen Sprachen
+
+// Logische Operatoren.
+// C++ verwendet so genannte "Short-circuit" Evaluierung für Boolean-Ausdrücke.
+// Das zweite Argument wird ausgeführt bzw. evaluiert, wenn das erste Argument genügt,
+// um den Ausdruck zu bestimmen.
+
+true && false // Führt **logisches und** aus.
+true || false // Führt **logisches oder** aus.
+! true // Führt **logisches nicht** aus.
+
+// Anstelle von Symbolen können auch Schlüsselwörter verwendet werden.
+true and false // Führt **logisches und** aus.
+true or false // Führt **logisches oder** aus.
+not true // Führt **logisches nicht** aus.
+
+// Bitoperationen
+
+// **<<** Links-Shift
+// **>>** Rechts-Shift
+
+~4 // Führt bitweises nicht aus.
+4 | 3 // Führt bitweises oder aus.
+4 & 3 // Führt bitweises und aus.
+4 ^ 3 // Führt bitweises xor aus.
+
+// Gleichwertige Schlüsselwörter:
+compl 4 // Führt bitweises nicht aus.
+4 bitor 3 // Führt bitweises oder aus.
+4 bitand 3 // Führt bitweises und aus.
+4 xor 3 // Führt bitweises xor aus.
+
+
+```
+Weiterführende Literatur:
+
+* Aktuelle Sprachen-Referenz [CPP Reference](http://cppreference.com/w/cpp).
+* Zusätzliches: [CPlusPlus](http://cplusplus.com).
+* Grundlagen Tutorial: [TheChernoProject - C++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb).
diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown
new file mode 100644
index 00000000..f9090518
--- /dev/null
+++ b/de-de/c-de.html.markdown
@@ -0,0 +1,869 @@
+---
+language: c
+filename: learnc-de.c
+contributors:
+ - ["caminsha", "https://github.com/caminsha"]
+lang: de-de
+---
+
+Ach, C. Immer noch **die** Sprache für modernes High-Performance Computing.
+
+C ist wahrscheinlich die Programmiersprache mit dem niedrigsten Abstraktionsnvieau,
+welche die meisten Programmierer je brauchen werden.
+Die Geschwindigkeit von C ist enorm, allerdings muss man sich stets der
+manuellen Speicherverwaltung bewusst sein.
+
+
+> **Über Compiler Optionen**
+>
+> Standardmäßig sind `gcc` und `clang` ziemlich ruhig bezüglich Warnungen und
+> Fehlern, obwohl dies sehr nützliche Informationen sein können. Es wird
+> empfohlen, strengere Compiler Optionen zu verwenden. Hier sind einige empfohlene
+> Standards:
+> `-Wall -Wextra -Werror -O2 -std=c99 -pedantic`
+>
+> Da gewisse Optionen (inbesondere der C-Standard) sehr stark vom Projekt
+> abhängen, lohnt es sich, wenn die unterschiedlichen Optionen genauer
+> angeschaut werden. Eine Übersicht über die Compiler-Optionen findet man unter
+> [diesem](https://stackoverflow.com/questions/3375697/useful-gcc-flags-for-c) Stackoverflow-Beitrag.
+>
+> Für weitere Informationen, was diese und weitere Optionen genau machen,
+> sollte die Man-Page des C-Compilers aufgerufen werden (z.B. `man 1 gcc`).
+> Alternativ kann auch online nach den unterschiedlichen Optionen gesucht werden.
+
+```c
+// einzeilige Kommentare starten mit // - nur in C99 und später vorhanden.
+
+/*
+mehrzeilige Kommentare sehen so aus. Diese funktionieren auch in C89
+*/
+
+/*
+mehrzeilige Kommentare können nicht verschachtelt werden /* Sei Vorsichtig! */ // Kommentar endet auf dieser Linie ...
+*/ // ... nicht bei dieser!
+
+// Konstanten: #define <keyword>
+// Konstanten werden laut der Konvention immer in GROSSBUCHSTABEN geschrieben
+#define DAYS_IN_YEAR 365
+
+// Konstanten können auch als Aufzählungskonstanten (Enums) definiert werden.
+// Alle Anweisungen müssen mit einem Semikolon beendet werden.
+enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT};
+// MON wird automatisch zu 2, TUE zu 3 etc.
+
+// Importiere Header-Dateien mit #include
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+// Dateien, welche zwischen <spitzen Klammern> stehen, sind Header-Dateien aus
+// der C-Standard-Bibliothek.
+// Für deine eigenen Header müssen Anführungszeichen verwendet werden, z.B.:
+// #include "mein_header.h"
+
+// Funktionssignaturen werden entweder vorher in einer .h-Datei deklariert oder
+// am Anfang der .c-Datei.
+void function_1();
+int funkcion_2(void);
+
+// Es muss ein Funktionsprototyp deklariert werden vor der `main()` Funktion,
+// wenn die Funktion nach der `main()` Funktion gebraucht wird.
+int add_two_ints(int x1, int x2); // Funktionsprototyp
+// Auch wenn der Ausdrck `int add_two_ints(int, int)` auch valid wäre,
+// ist es empfohlen, dass man die Namen der Argumente hinschreibt für eine
+// einfachere Analyse.
+
+// Der Einstiegspunkt deines Programms ist eine Funktion mit dem Namen main und
+// einem Integer als Rückgabewert.
+int main(void) {
+ // dein Programm
+}
+
+// Die Kommandozeilenargumente, welche gebraucht werden, damit dein Programm
+// läuft, werden als Argumente der `main`-Funktion mitgegeben.
+// argc (argument counter) steht für die Anzahl von Argumenten.
+// Der Programmname ist das erste Argument.
+// argv (argument vector) ist ein Array von Zeichenarrays, welche die
+// Argumente beinhaltet.
+// argv[0] = Name des Programms
+// argv[1] = erstes Argument usw.
+int main (int argc, char** argv) {
+ // Ausgabe mit Hilfe von printf (print formatted)
+ // %d ist ein Integer.
+ // \n steht für eine neue Zeile
+ printf("%d\n",0); // => Gibt 0 aus.
+
+ ////////////////////////////////////////////////
+ // Operatoren
+ ////////////////////////////////////////////////
+
+ // Kurzschreibweise für mehrere Deklarationen
+ int i1 = 1, i2 = 2;
+ flaot f1 = 1.0, f2 = 2.0;
+
+ int b,c;
+ b = c = 0;
+
+ // Arithmetik ist unkompliziert
+ 1 + 2; // => 3
+ 2 - 1; // => 1
+ 2 * 1; // => 2
+ 1 / 2; // 0 (0.5, aber abgeschnitten, da es int sind.)
+
+ // Man muss mindestens ein Integer zu einen float konvertieren, damit man als
+ // Resultat eine Gleitkommazahl erhält.
+ (float)1 / 2; // => 0.5f
+ 1 / (double)2; // => 0.5 // das gleiche mit dem Typ `double`
+ 1.0 / 2.0; // => 0.5, plus oder minus Epsilon
+ // Gleitkommazahlen und deren Berechnungen sind nicht exakt.
+
+ // Es gibt auch die Möglichkeit, Modulo zu rechnen
+ 11 % 3; // => 2
+
+ // Vergleichsoperatoren sind vielleicht schon bekannt, aber in C gibt es
+ // keinen Boolean-Typ. In C verwenden wir `int`. (Oder _Bool oder bool in C99)
+ // 0 ist falsch, alles andere ist wahr (Die Vergleichsoperatoren ergeben
+ // immer 1 oder 0.
+ 3 == 2; // => 0 (falsch)
+ 3 != 2; // => 1 (wahr)
+ 3 > 2; // => 1
+ 3 < 2; // => 0
+ 2 <= 2; // => 1
+ 2 >= 2; // => 1
+
+ // C ist nicht Python - Vergleiche können nicht einfach verkettet werden.
+ // Warnung: die folgende Zeile wird kompilieren, aber es bedeutet `(0 < a) < 2`.
+ // Dieser Ausdruck ist immer wahr, weil (0 < a) kann entweder 1 oder 0 sein.
+ // In diesem Falle ist es 1, weil (0 < 1).
+ int zwischen_0_und_2 = 0 < a < 2;
+ // Benutze stattdessen folgende Schreibweise:
+ int zwischen_0_und_2 = 0 < a && a < 2;
+
+ // Logik funktioniert auch mit ints
+ !3; // => 0 (logisches Nicht)
+ !0; // => 1
+ 1 && 1; // => 1 (logisches Und)
+ 0 && 1; // => 0
+ 0 || 1; // => 1 (logisches Oder)
+ 0 || 0; // => 0
+
+ // Bedingter ternärer Ausdruck ( ? : )
+ int e = 5;
+ int f = 10;
+ int z;
+ z = ( e > f ) ? e : f; // => // => 10 "wenn e > f ist, gib e zurück, sonst f."
+
+ // Inkrementierungs- und Dekrementierungsoperatoren
+ int j = 0;
+ int s = j++; // gib j zurück und erhöhe danach j. (s = 0, j = 1)
+ s = ++j; // erhöhe zuerst j und gib dann j zurück (s = 2, j = 2)
+ // das gleiche gilt für j-- und --j
+
+ // Bitweise Operatoren
+ ~0x0F; // => 0xFFFFFFF0 (Bitweise Negation, "Einer-Komplement",
+ // Beispielresultat für 32-Bit int)
+ 0x0F & 0xF0; // => 0x00 (Bitweises UND)
+ 0x0F | 0xF0; // => 0xFF (Bitweises ODER)
+ 0x04 ^ 0x0F; // => 0x0B (Bitweises XOR)
+ 0x01 << 1; // => 0x02 (Bitweises Linksverschiebung (left shift) (um 1))
+ 0x02 >> 1; // => 0x01 (Bitweises Rechtsverschiebung (right shift) (um 1))
+
+ // Sei vorsichtig beim Shift mit vorzeichenbehafteten Integern
+ // folgende Ausdrücke sind nicht definiert:
+ // - Verschiebung in das Vorzeichenbit (int a = 1 << 31)
+ // - Linksshift einer negativen Zahl (int a = -1 << 2)
+ // - Shift um einen Offset, welcher >= die Breite des linken Ausdrucks ist.
+ // int a = 1 << 32; // undefiniertes Verhalten, wenn int 32-Bit ist.
+
+
+ ////////////////////////////////////////////////
+ // Typen
+ ////////////////////////////////////////////////
+
+ // Compiler, welche nicht C99-kompatibel sind, verlangen, dass sämtliche
+ // Variablen zu Beginn des Blocks deklariert werden.
+ // C99-Konforme Compiler erlauben die Variablendeklaration an dem Punkt, an
+ // welchem die Variable verwendet wird.
+ // Wir deklarieren die Variablen dynamisch im Code um die Lesbarkeit im
+ // Tutorial zu verbessern.
+
+ // integer sind normalerweise 4 Bytes groß
+ int x_int = 0;
+
+ // shorts sind normalerweise 2 Bytes groß
+ short x_short = 0;
+
+ // chars sind garantiert 1 Byte groß
+ char x_char = 0;
+ char y_char = 'y'; // Charakterliterale werden mit '' gekennzeichnet.
+
+ // longs sind oft 4 bis 8 Bytes groß. long long sind garantiert mindestens
+ // 8 Bytes groß.
+ long x_long = 0;
+ long long x_long_long = 0;
+
+ // floats sind normalerweise 32-Bit Gleitkommazahlen
+ float x_float = 0.0f; // 'f'-Suffix beschreibt eine Gleitkommazahl.
+
+ // doubles sind normalerweise 64-Bit Gleitkommazahlen
+ double x_double = 0.0; // echte Zahlen ohne Suffix sind vom Typ double
+
+ // integer-Typen können vorzeichenlos (unsigned) sein
+ // (größer oder kleiner als 0)
+ unsigned short ux_short;
+ unsigned int ux_int;
+ unsigned long long ux_long_long;
+
+ // Zeichen innerhalb von einfachen Anführungszeichen sind Integers im
+ // Maschinenzeichensatz
+ '0'; // => 48 im ASCII-Zeichensatz
+ 'A'; // => 65 im ASCII-Zeichensatz
+
+ // sizeof(T) gibt die Größe einer Variablen des Typen T in Bytes zurück.
+ // sizeof(obj) ergibt die Größe des Ausdrucks (Variable, Literal usw.)
+
+ printf("%zu\n", sizeof(int)); // => 4 (auf den Rechnern mit einem 4-Byte-Wort)
+
+ // Wenn das Argument des `sizeof`-Operator ein Ausdruck ist, dann wird das
+ // Argument nicht ausgewertet (außer Arrays mit variabler Länge)
+ // Der Wert, der in diesem Fall zurückgegeben wird, ist eine Konstante zur
+ // Kompillierzeit.
+
+ int a = 1;
+ //size_t ist ein vorzeichenloser Integer Typ mit mindestens 2 Byte um die
+ // Größe eines Objekts zu repräsentieren.
+ size_t size = sizeof(a++); // a++ wird nicht ausgewertet
+ printf("sizeof(a++) = %zu, wobei a=%d ist\n", size, a);
+ // Gibt "sizeof(a++) = 4, wobei a=1 ist" aus (mit einer 32-Bit-Architektur)
+
+ // Arrays müssen mit einer Größe initialisiert werden.
+ char my_char_array[20]; // Dieses Array beinhaltet 1 * 20 = 20 Bytes
+ int my_int_array[20]; // Dieses Array beinhaltet 4 * 20 = 80 Bytes.
+ // unter der Voraussetzung eines 4-Byte-Worts.
+
+ // Ein Array kann auf diese Weise mit 0 initialisiert werden.
+ char my_array[20] = {0};
+ // Hierbei ist der Teil "{0}" der "Array Initialisierer".
+ // Beachte, dass die Länge des Arrays nicht explizit definiert werden muss,
+ // wenn er auf derselben Linie initialisiert wird.
+ // Folgende Deklaration ist gleichwertig:
+ char my_array[] = {0};
+ // Allerdings muss die Länge des Arrays dann zur Laufzeit ausgewertet werden:
+ size_t my_array_size = sizeof(my_array) / sizeof(my_array[0]);
+ // WARNUNG: Wenn dieser Ansatz gewählt wird, muss man sicherstellen, dass die
+ // Größe des Arrays ermittelt werden *bevor* dieser einer Funktion als
+ // Argument weitergegeben wird (siehe Diskussion weiter unten), weil Arrays
+ // einer Funktion nur als Zeiger übergeben werden. => Das obere Statement
+ // würde innerhalb einer Funktion ein falsches Resultat liefern.
+
+ // Das Indexieren eines Arrays funktioniert wie in anderen Sprache - resp.
+ // in anderen Sprachen funktioniert es gleich wie in C.
+ my_array[0]; // => 0
+
+ // Arrays sind veränderbar; es ist nur Arbeitsspeicher!
+ my_array[1] = 2;
+ printf("%d\n", my_array[1]); // => 2
+
+ // In C99 (und als optionales Feature in C11) können Arrays mit variabler
+ // Länge deklariert werden. Die Größe eines solchen Array muss eine Konstante
+ // zur Kompilierzeit sein.
+ printf("Geben Sie die Arraygröße an: "); //Frag den Benutzer nach
+ // der Arraygröße
+ int array_size;
+ fcsanf(stdin, "%d", &array_size);
+ int var_length_array[array_size]; // deklariere Array mit variabler Länge
+ printf("sizeof array =%zu\n", sizeof var_length_array);
+
+ // Zum Beispiel:
+ // > Geben Sie die Arraygröße an: 10
+ // > sizeof array = 40
+
+ // Strings sind lediglich Arrays von `chars`, welche mit einem Null-Byte
+ // (0x00) beendet werden. In Strings wird das Nullbyte durch das Zeichen \0
+ // repräsentiert. Wir müssen das Null-Byte nicht angeben in String-Literalen;
+ // der Compiler fügt es am Ende des Array automatisch hinzu.
+ char a_string[20] = "Das ist ein String";
+ printf("%s\n", a_string); // %s formattiert einen String
+
+ printf("%d\n", a_string[18]); // => 0
+ // Hier ist das Byte #19 0 (wie auch Byte #20)
+
+ // Wenn wir Zeichen zwischen einfachen Anführungszeichen haben, ist es ein
+ // Zeichenliteral vom Typ int und *nicht* char. (aus historischen Gründen)
+ int cha = 'a'; // Ok
+ char chb = 'a'; // auch ok (implizite Umwandlung von int zu char)
+
+ // Mehrdimensionale Arrays:
+ int multi_array[2][5] = {
+ {1,2,3,4,5},
+ {6,7,8,9,0}
+ };
+ // Auf Elemente zugreifen:
+ int array_int = multi_array[0][2]; // => 3
+
+ ////////////////////////////////////////////////
+ // Kontrollstrukturen
+ ////////////////////////////////////////////////
+ if (0) {
+ printf("Ich werde nie ausgeführt.");
+ }
+ else if (0) {
+ printf("Ich werde auch nie ausgeführt.");
+ }
+ else {
+ printf("Ich gebe etwas aus.");
+ }
+
+ // While-Schleifen existieren auch
+ int ii = 0;
+ while (ii < 10) { // JEDER Wert unter zehn ist wahr
+ printf("%d, " ii++); //i++ inkrementiert ii NACHDEM der Wert gebraucht
+ // wurde.
+ } // => gibt folgendes aus: "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
+
+ printf("\n");
+
+ int kk = 0;
+ do {
+ printf("%d, ", kk);
+ } while(++kk < 10); //++kk inkrementiert kk BEVOR der Wert gebraucht wurde.
+ // => gibt folgendes aus: "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
+
+ printf("\n");
+
+ // In C gibt es auch for-Schleifen
+ int jj;
+ for (jj = 0; jj < 10; jj++) {
+ printf("%d, ", jj);
+ } // => gibt folgendes aus: "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "
+
+ printf("\n");
+
+ // **Merke**
+ // Schleifen und Funktionen müssen einen Rumpf haben. Wenn kein Rumpf gebraucht
+ // wird, kann folgendes gemacht werden:
+ int i;
+ for (i = 0; i <= 5; i++) {
+ ; // Semikolon wird als Rumpf behandelt (Null-Anweisung)
+ }
+ // Alternativ kann auch folgendes geschrieben werden:
+ for (i = 0; i <= 5; i++);
+
+ // Verzweigungen mit mehreren Möglichkeiten: `switch()`
+ switch (a) {
+ case 0: // Labels müssen integrale *konstante* Ausdrücke sein (z.B. Enums)
+ printf("Hey, 'a' ist gleich 0!\n");
+ break; //Wenn du kein break einsetzt, so geht der Kontrollfluss
+ // durch die Labels
+ case 1:
+ printf("Huh, 'a' ist gleich 1!\n");
+ break;
+ // Sei vorsichtig - wenn man das `break` vergisst, werden alle
+ // Anweisungen ausgeführt bis das nächste `break` erscheint.
+ case 3:
+ case 4:
+ printf("Schau mal ... 'a' ist entweder 3 oder 4.\n");
+ break;
+ default:
+ // wenn der Ausdruck `a` auf kein Label zutrifft.
+ fputs("Fehler!\n", stderr);
+ exit(-1);
+ break;
+ }
+
+ ////////////////////////////////////////////////
+ // Typenumwandlung
+ ////////////////////////////////////////////////
+
+ // Jeder Wert in C hat einen bestimmten Typen, aber es ist möglich, ein
+ // Wert in einen anderen Typ umzuwandeln (mit einigen Einschränkungen).
+
+ int x_hex = 0x01; // Es ist möglich, Variablen Hexadezimalwerten zuzuweisen.
+
+ // Bei der Umwandlung zwischen Typen wird versucht, den numerischen Wert
+ // beizubehalten.
+ printf("%d\n", x_hex); // => 1
+ printf("%d\n", (short) x_hex); // => 1
+ printf("%d\n", (char) x_hex); // => 1
+
+ // Typen werden überlaufen (overflow) ohne jegliche Warnung
+ printf("%d\n", (unsigned char) 257); // => 1 (Max char=255 wenn char 8 Bit ist)
+
+ // Um den maximalen Wert eines `char`, `signed char` oder `unsigned char`
+ // herauszufinden, können die Makros `CHAR_MAX`, `SCHAR_MAX` und `UCHAR_MAX`
+ // aus der Header-Datei `<limits.h>` verwendet werden.
+
+ // Integer-Typen können zu Gleitkommazahlen und umgekehrt umgewandelt werden.
+ printf("%f\n", (double) 100); // %f formattiert immer zu einem `double`...
+ printf("%f\n", (flaot) 100); // ... auch mit einem `float`
+ printf("%d\n", (char)100.0);
+
+ ////////////////////////////////////////////////
+ // Zeiger (aka Pointer)
+ ////////////////////////////////////////////////
+
+ // In diesem Tutorial wird das deutsche Wort Zeiger nicht verwendet, da es
+ // bei einer weiteren Recherche einfacher ist, wenn man von Pointern ausgeht.
+ // Außerdem ist der Begriff Pointer auch im deutschen Sprachgebrauch zu finden.
+
+ // Ein Pointer ist eine Variable, welche deklariert wurde, um eine Speicher-
+ // adresse zu speichern. Die Deklaration eines Pointers wird auch zeigen,
+ // auf welche Art von Daten der Pointer zeigt. Man kann die Speicheradresse
+ // von Variablen abrufen und dann mit diesen herumspielen.
+
+ int x = 0;
+ printf("%p\n", (void *)&x); // verwende & um die Adresse der Variable
+ // zu erhalten
+ // %p formattiert einen Objektpointer des Typen void*)
+ // => Gibt eine Adresse im Speicher aus
+
+ // Pointer starten mit einem * zu Beginn der Deklaration.
+ int *px, not_a_pointer; // px ist ein Pointer zu einem int.
+ px = &x; // Speichert die Adresse von x in px
+ printf("%p\n", (void *)px); // => Gibt eine Adresse im Speicher aus
+ printf("%zu, %zu\n", sizeof(px), sizeof(not_a_pointer));
+ // Gibt auf einem typischen 64-Bit-System folgendes aus: "8, 4"
+
+ // Um den Wert einer Adresse, auf welche ein Pointer zeigt, herauszufinden,
+ // muss man vor die Variable ein * setzen, um sie zu dereferenzieren.
+ // Notiz: Ja, es kann verwirrend sein, dass '*' sowohl für das Deklarieren
+ // als auch das Derefenzieren verwendet werden kann.
+ printf("%d\n", *px); // => 0, der Wert von x
+
+ // Man kann den Wert, auf welchen ein Pointer zeigt, auch verändern.
+ // Man muss die Dereferenzierung in Klammern setzen, weil ++ eine höhere
+ // Priorität als * hat.
+ (*px)++; // Inkrementiere den Wert, auf welchen px zeigt, um 1
+ printf("%d\n", *px); // => 1
+ printf("%d\n", x); // => 1
+
+ // Arrays sind eine gute Möglichekit, einen zusammenhängenden Block von
+ // Speicher zu allozieren.
+ int x_array[20]; // deklariert einen Array der Größe 20 (Größe kann
+ // nicht geändert werden.)
+ int xx;
+ for (xx =0; xx < 20; xx++) {
+ x_array[xx] 20 -xx;
+ } // Initialisiere x_array zu 20, 19, 18, ... 2, 1
+
+ // Deklariere ein Pointer des Typs int und initalisiere ihn, um auf `x_array`
+ // zu zeigen.
+ int *x_ptr = x_array;
+ // x_ptr zeigt jetzt auf den ersten Wert innerhalb des Arrays (int 20)
+ // Das funktioniert, weil Arrays oft zu Pointern reduziert werden, welche
+ // auf das erste Element zeigen.
+ // Zum Beispiel: Wenn ein Array einer Funktion mitgegeben wird oder einem
+ // Pointer zugewiesen wird, wird es zu einem Pointer reduziert (implizites Casting)
+ // Ausnahme: Wenn das Array das Argument des Operators `&` ist.
+ int arr[10];
+ int (*ptr_to_arr)[10] = &arr; //`&arr` ist nicht vom Typ `int *`!
+ // Es ist vom Typem "Pointer auf Array" (aus zehn `int`s)
+ // oder wenn das Array ein Stringliteral ist, welches gebraucht wird um ein
+ // `char`-Array zu initialisieren.
+ char other_arr[] = "foobarbazquirk";
+ // oder wenn es das Argument des `sizeof` oder `alignof` Operators ist.
+ int third_array[10];
+ int *ptr = third_array; // gleich wie: `int *ptr = &arr[0]`
+ printf("%zu, %zu\n", sizeof(third_array), sizeof(ptr));
+ // Gibt wahrscheinlich "40, 4" oder "40, 8" aus
+
+ // Pointer werden basierend auf dem Typ in- und dekrementiert
+ // Dies wird Pointer-Arithmetik genannt.
+ printf("%d\n", *(x_ptr + 1)); // => 19
+ printf("%d\n", x_array[1]); // => 19
+
+ // Man kann zusammenhängende Speicherblöcke auch mit der Funktion `malloc`
+ // aus der Standardbibliothek dynamisch allozieren. Der Funktion `malloc`
+ // muss ein Argument des Typs `size_t` übergeben werden, welches bestimmt,
+ // wie viele Bytes alloziert werden sollen. (Normalerweise geschieht dies
+ // aus dem Heap - dies kann auf eingebetteten Systemen unterschiedlichen sein.
+ // Der C Standard sagt nichts darüber.)
+ int *my_ptr = malloc(sizeof(*my_ptr) * 20);
+ for (xx = 0; xx < 20; xx++) {
+ *(my_ptr + xx) = 20 -xx; //my_ptr[xx] = 20-xx
+ } // initialisiere Speicher zu 20, 19, 18, 17, ... 2, 1 (als `int`)
+
+ // Sei vorsichtig beim Übergeben von Benutzerdefinierten Werten an `malloc`.
+ // Wenn du sicher sein willst, kannst du die Funktion `calloc` nutzen, welche
+ // (nicht wie `malloc`) auch den Speicher nullt.
+ int *my_other_ptr = calloc(20, sizeof(int));
+
+ // Merke, dass es in C keinen Standard-Weg gibt, um die Länge eines dynamisch
+ // allozierten Arrays zu bestimmen. Auf Grund dessen sollte eine Variable
+ // erstellt werden, welche sich die Anzahl der Elemente im Array merkt, wenn
+ // die Arrays mehrmals im Programm gebraucht werden.
+ // Weitere Informationen stehen im Abschnitt Funktionen.
+ size_t size = 10;
+ int *my_array = calloc(size, sizeof(int));
+ // Füge dem Array ein Element hinzu
+ size++;
+ my_array = realloc(my_array, sizeof(int) *size);
+ if (my_array == NULL) {
+ // Denke daran, realloc-Fehler zu prüfen
+ return
+ }
+ my_array[10] = 5;
+
+ // Das Dereferenzieren von nicht alloziertem Speicher führt zu einem
+ // Undefinierten Verhalten.
+ printf("%d\n", *(my_ptr + 21)); // Gibt irgendwas aus.
+ // Das Programm kann auch abstürzen
+
+ // Nachdem du fertig mit einem Block bist, welcher `malloc` verwendet hat,
+ // muss der Speicher befreit werden. Ansonsten kann dieser Speicherbereich
+ // niemand nutzen bis dein Programm beendet wird.
+ // Dies wird auch als "Speicherleck" (engl: memory leak) bezeichnet.
+ free(my_ptr);
+
+ // Obwohl Strings normalerweise als Pointer-to-Char (Pointer zum ersten
+ // Zeichen des Arrays) repräsentiert werden, sind Strings Arrays aus `char`s.
+ // Es ist eine gute Praxis, `const char *` zu verwenden, wenn man ein
+ // String-Literal referenziert, da String-Literale nicht modifiziert werden
+ // sollten (z.B. "foo"[0] = 'a' ist ILLEGAL)
+ const char *my_str = "Das ist mein eigener String";
+ printf("%c\n", *my_str); // => D
+
+ // Dies ist nicht der Fall, wenn der String ein Array (möglicherweise mit
+ // einem String-Literal initialisiert) ist, welcher im beschreibbaren Speicher
+ // bleibt, wie zum Beispiel in:
+ char foo[] = "foo";
+ foo[0] = 'a'; // Dies ist legal, foo enthält jetzt "aoo"
+
+ function_1();
+} // Ende der `main`-Funktion
+
+////////////////////////////////////////////////
+// Funktionen
+////////////////////////////////////////////////
+
+// Syntax einer Funktionsdeklaration
+// <rueckgabe_wert> <funktions_name>(<args>)
+
+int add_two_ints(int x1, int x2) {
+ return x1 + x2; // verwendet return, um einen Wert zurückzugeben
+}
+
+/*
+Funktionen werden auf Grund des Wertes aufgerufen (call-by-value). Wenn eine
+Funktion aufgerufen wird, sind die Argumente Kopien der ursprünglichen Werte
+(ausgenommen Arrays). Alles, was man innerhalb einer Funktion mit den Werten
+macht, hat keinen Einfluss auf die Originalwerte als die Funktion aufgerufen
+wurde.
+
+Verwende Pointer, um den Originalinhalt zu bearbeiten.
+
+Beispiel:
+*/
+
+// Eine `void`-Funktion gibt keinen Wert zurück
+void str_reverse(char *str_in) {
+ char tmp;
+ size_t ii = 0;
+ size_t size = strlen(str_in);
+ // `strlen()` ist ein Teil der C Standard-Bibliothek.
+ // Merke: Die Länge, welche von `strlen` zurückgegeben wird, ist ohne den
+ // Null-Byte Terminator.
+ for (ii = 0; i < size /2; ii++) { // in C99 kann man `ii` hier deklarieren.
+ tmp = str_in[ii];
+ str_in[ii] = str_in[size - ii - 1]; //#ii'tes Zeichen vom Ende her
+ str_in[size - ii- 1] = tmp;
+ }
+}
+// Merke: Die `string.h`-Headerdatei muss inkludiert werden, bevor `strlen()`
+// verwendet werden kann.
+
+/*
+char c[] = "Das ist ein Test";
+str_reverse(c);
+printf("%s\n", c), => "tseT nie tsi saD"
+*/
+
+// Weil wir lediglich eine Variable zurückgeben können, kann zum Ändern mehrerer
+// Variablen das Konzept call-by-reference verwendet werden.
+void swap_two_numbers(int *a, int *b) {
+ int temp = *a;
+ *a = *b;
+ *b = temp;
+}
+int first = 10;
+int seconde = 20;
+printf("Erste Zahl: %d\n Zweite Zahl: %d\n", first, second);
+swap_two_numbers(&first, &second);
+printf("Erste Zahl: %d\n Zweite Zahl: %d\n", first, second);
+// Werte sind vertauscht.
+
+/*
+Wenn man Arrays betrachtet, so werden diese immer als Pointer übergeben. Auch
+wenn die Arrays statisch alloziert werden (wie zum Beispiel `arr[10]`), werden
+diese als Pointer zum ersten Element des Arrays übergeben.
+Auch hier soll noch einmal erwähnt werden, dass es keinen Standard gibt, wie die
+Größe eines dynamischen Arrays herausgefunden werden kann.
+*/
+// Die Größe des Arrays muss unbedingt mitgegeben werden.
+// Sonst hat die Funktion keine Ahnung wie groß das Array ist.
+void print_int_arrray(int *arr, size_t size) {
+ int i;
+ for (i = 0; i < size; i++) {
+ printf("arr[%d] ist %d\n", i, arr[i]);
+ }
+}
+
+int my_array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+int size = 10;
+print_int_array(my_array, size);
+// Wird folgendes ausgeben: "arr[0] ist 1" usw.
+
+// Wenn man auf externe Variable (außerhalb der Funktion) referenziert, sollte
+// man das Schlüsselwort `extern` verwenden.
+int i = 0;
+void test_function() {
+ extern int i; // i braucht nun die externe Variable i
+}
+
+// Das Schlüsselwort `static` macht, dass eine Variable außerhalb der Kompilier-
+// einheit nicht zugreifbar ist. (Auf den meisten Systemen ist eine Kompiliereinheit
+// eine `.c`-Datei.) Das Schlüsselwort `static` kann sowohl bei globalen
+// (zur Kompiliereinheit gehörende) Variablen, Funktionen und Funktionslokale
+// Variablen angewendet werden.
+// Wenn man `static` bei lokalen Variablen verwendet, so ist diese Variable global
+// erreichbar und behält dessen Wert über Funktionsaufrufe hinweg, aber sie ist
+// nur innerhalb der deklarierten Funktion verfügbar. Außerdem werden statische
+// Variablen mit 0 initialisiert, wenn sie nicht mit einem anderen Startwert
+// initialisiert werden.
+// Es ist auch möglich, Funktionen als statisch zu deklarieren, damit diese
+// `private` sind. Privat heißt, dass sie nur in diesem Kontekt sichtbar sind.
+
+
+////////////////////////////////////////////////
+// Benutzerdefinierte Typen und Strukturen (Structs)
+////////////////////////////////////////////////
+
+// `typedef`s können verwendet werden, um Typenaliase zu erstellen.
+typedef int my_type;
+my_type my_type_var = 0;
+
+// Structs sind lediglich Sammlungen von Daten, die Inhalte werden
+// (in der Reihenfolge wie sie geschrieben wurden) sequentiell alloziert.
+struct rectangle {
+ int width;
+ int height;
+};
+
+// Allgemein ist es nicht so, dass folgender Ausdruck wahr ist.
+// sizeof(struct rectangle) == sizeof(int) + sizeof(int)
+// Dies ist so, weil potentiell ein Padding zwischen den Struktur-Inhalten
+// möglich ist). (siehe [1, Englisch])
+
+void function_1() {
+ struct rectangle my_rectangle;
+
+ // Greife auf Struct-Inhalte mit `.` zu.
+ my_rectangle.width = 10;
+ my_rectangle.height = 20;
+
+ // Du kannst Pointer zu Structs deklarieren.
+ struct rectangle *my_rectangle_ptr = &my_rectangle;
+
+ // Verwende Dereferenzierung, um Struct-Inhalte zu bearbeiten
+ (*my_rectangle_ptr).width = 30;
+
+ //Noch besser: Verwende die Kurzschreibweise ->, um die Lesbarkeit zu
+ // verbessern.
+ my_rectangle_ptr->height = 10; // Gleich wie: (*my_rectangle_ptr).height = 10;
+}
+
+// Aus Bequemlichkeitsgründen ist es möglich einem `struct` ein `typedef` hinzuzufügen.
+typedef struct rectangle rect;
+
+int area(rect r) {
+ return r.width * r.height;
+}
+
+// Wenn du große Structs hast, kannst du diese mit dem Pointer kopieren,
+// damit große Kopiervorgänge vermieden werden.
+int area_ptr(const rect *r) {
+ return r->width * r->height;
+}
+
+////////////////////////////////////////////////
+// Funktionspointer
+////////////////////////////////////////////////
+
+/*
+Zur Laufzeit sind Funktionen in einer Speicheradresse gespeichert.
+Funktionspointer sind wie normale Pointer (es wird einfach eine Speicheradresse
+gespeichert). Funktionspointer können verwendet werden, um Funktionen und
+Handler (oder Callback-Funktionen) direkt aufzurufen.
+Wie auch immer, die Syntax kann zu Beginn verwirrend wirken.
+
+Zum Beispiel: Verwende str_reverse von einem Pointer
+*/
+void str_reverse_through_pointer(char *str_in) {
+ // Definiere eine Funktionspointer-Variable, welche f genannt wird.
+ void (*f)(char *); // Signatur sollte genau der Funktion entsprechen.
+ f = &str_reverse; // weise die Adresse der wirklichen Funktion zu
+ // (zur Laufzeit bestimmt)
+ // `f = str_reverse;` würde auch funktionieren, da Funktionen zu Pointern
+ // reduziert werden (ähnlich wie Arrays)
+ (*f)(str_in); // Die Funktion einfach mit dem Pointer aufrufen
+ // f(str_in); // Dies ist eine weitere gültige Alternative um eine Funktion
+ // auzurufen.
+}
+
+/*
+Solange die Signaturen der Funktionen übereinstimmen, kann man sämtliche Funktionen
+demselben Pointer zuweisen. Funktionspointer sind auf Grund der Einfacheit und
+Leserlichkeit normalerweise wie folgt `typedef`d
+*/
+typedef void (*my_fnp_type)(char *);
+// Danach werden diese genutzt, um die wirkliche Pointervariable zu deklarieren.
+// ..
+// my_fnp_type f;
+
+// Spezialzeichen
+// Im folgenden sin die englischen Begriffe jeweils in Klammern geschrieben,
+// da diese Begriffe auch im deutschten Sprachgebrauch verwendet werden.
+'\a'; // Alarmzeichen (alert (bell) character)
+'\n'; // Zeichen für neue Linie (newline character)
+'\t'; // Tab (tab character (left justifies text))
+'\v'; // Vertikaler Tab (vertical tab)
+'\f'; // Neue Seite (new page (form feed))
+'\r'; // Wagenrücklauf (carriage return)
+'\b'; // Backspace-Zeichen (backspace character)
+'\0'; // Null-Byte (NULL character). In C wird dieses Zeichen normalerweise am
+// Ende eines Strings gesetzt.
+// Beispiel: Hallo\n\0. "\0" wird per Konvention verwendet, um das Ende
+// eines Strings zu kennzeichnen.
+'\\'; // Backslash (backslash)
+'\?'; // Fragezeichen (question mark)
+'\''; // einfaches Anführungszeichen (single quote)
+'\"'; // doppeltes Anführungszeichen (double quote)
+'\xhh'; // Hexadezimale Zahl (hexadecimal number.) Beispiel:
+ // '\xb' = Zeichen für vertikalen Tab
+'\0oo'; // Oktalzahl (octal number). Beispiel \013 = Zeichen für vertikalen Tab
+
+//Ausgabeformatierung
+"%d"; // Integer
+"%3d"; // Integer mit einer minimalen Länge von drei Zeichen.
+"%s"; // String
+"%f"; // Gleitkommazahl (float)
+"%ld"; // genauere Gleitkommazahl (long)
+"%3.2f"; // Mindestens drei Zeichen vor und drei nach dem Komma.
+"%7.4s"; // (Kann auch mit Strings gemacht werden)
+"%c"; // einzelnes Zeichen (char)
+"%p"; // Pointer. Merke: man muss den Pointer zu void umwandeln,
+ // bevor `printf` funktioniert.
+"%x"; // Hexadezimal
+"%o"; // Oktalzahl
+"%%"; // Gibt % aus
+
+////////////////////////////////////////////////
+// Reihenfolge der Auswertung von Operatoren
+////////////////////////////////////////////////
+
+//-------------------------------------------------------//
+// Operatoren | Assoziativität //
+//-------------------------------------------------------//
+// () [] -> . | linksassoziativ //
+// ! ~ ++ -- + = *(type)sizeof | rechtsassoziativ //
+// * / % | linksassoziativ //
+// + - | linksassoziativ //
+// << >> | linksassoziativ //
+// < <= > >= | linksassoziativ //
+// == != | linksassoziativ //
+// & | linksassoziativ //
+// ^ | linksassoziativ //
+// | | linksassoziativ //
+// && | linksassoziativ //
+// || | linksassoziativ //
+// ?: | rechtsassoziativ //
+// = += -= *= /= %= &= ^= |= <<= >>= | rechtsassoziativ //
+// , | linksassoziativ //
+//-------------------------------------------------------//
+
+
+////////////////////////////////////////////////
+// Header-Dateien
+////////////////////////////////////////////////
+
+/*
+Header-Dateien sind ein wichtiger Teil von C, da sie eine Verbindung zwischen
+unterschiedlichen C-Quelldateien herstellen. Außerdem vereinfachen Header-Dateien
+den Code und Definitionen, da diese in separaten Dateien geschrieben werden können.
+
+Header-Dateien sind von der Syntax her ähnlich zu C-Quelldateien, allerdings haben
+die Header-Dateien die Dateiendung `.h`. Header-Dateien können im Quellcode mit
+der `#include`-Anweisung eingebunden werden z.B. `#include "beispiel.h". Die
+vorherige Anweisung geht davon aus, dass sich die Header-Datei im selben Ordner
+befindet wie die C-Quelldatei.
+*/
+
+// Eine sichere Möglichkeit, einen Header mehrere Male zu definieren bietet, das
+// folgende Statement. Die mehrfache Definition geschieht, wenn Kreisabhängigkeiten
+// bestehen.
+#ifndef EXAMPLE_H /* Wenn EXAMPLE_H noch nicht definiert wurde */
+#define EXAMPLE_H /* definiere das Makro EXAMPLE_H */
+
+// Es könenn weitere Header innerhalb eines Headers eingebunden werden, was dazu
+// führt, dass diese bereits in anderen Dateien eingebunden wurden. So kann eine
+// Header-Datei in mehreren Dateien eingebunden werden. zum Beispiel:
+#include <string.h>
+
+// Wie in den Quelldateien können auch in den Header-Dateien Makros definiert
+// werden und in anderen Dateien verwendet werden, welche diesen Header einbinden.
+#define EXAMPLE_NAME "Dennis Ritchie"
+
+// Funktionsmakros können auch definiert werden.
+#define ADD(a, b) ((a) + (b))
+
+// Beachte die Klammern, welche um die Argumente geschrieben wurden - diese sind
+// wichtig, damit sichergestellt werden kann, dass a und b nicht unerwartet
+// erweitert werden. Zum Beispiel: `MUL (x,y) (x * y)`; Bei der Verwendung von
+// `MUL(1 + 2, 3)` würde dies wie folgt erweitert werden: `(1 + 2 * 3)`, was zu
+// einem falschen Resultat führt.
+
+// Strukturen und Typendefinitionen können verwendet werden, um die Konsistenz
+// zwischen unterschiedlichen Dateien beizubehalten.
+typedef struct Node {
+ int value;
+ struct Node *next;
+}Node;
+
+// Dies kann auch mit Aufzählungen gemacht werden.
+enum traffic_light_state {GREEN, YELLOW, RED};
+
+// Funktionsprototypen könenn auch in Header-Dateien definiert werden, um die
+// Funktion in unterschiedlichen Dateien zu verwenden, aber dies wird als schlechte
+// Praxis angesehen. Definitionen sollten in einer C-Datei erstellt werden.
+Node create_linked_list(int *value, int length);
+
+// Außer den oben genannten Elementen, sollten weitere Definitionen in einer
+// C-Datei gemacht werden. Übermäßige Includes und Definitionen sollten auch
+// nicht einer Header-Datei gemacht werden. Stattdessen wird es empfohlen, diese
+// in eine separate Header-Datei oder in eine C-Quelldatei zu schreiben.
+
+#endif /* Ende der Präprozessordirektive */
+```
+## Weiterführende Literatur
+
+Das Beste wird es sein, wenn man sich ein Exemplar des Buches
+["The C Programming Language"](https://de.wikipedia.org/wiki/The_C_Programming_Language) besorgt.
+Dieses Buch gilt als **das** Buch über die Programmiersprache C und wurde
+von Dennis Ritchie, dem Erfinder der Programmiersprache C, und Brian Kernighan
+geschrieben.
+Sei vorsichtig, da dieses Buch mittlerweile schon etwas älter ist und gewisse
+Unkorrektheiten (d.h. Ideen, welche nicht mehr als gut empfunden werden.) oder
+mittlerweile geänderte Praktiken enthält. [Hinweis: Das Buch wurde auf Englisch
+geschrieben, es gibt aber auch eine Übersetzung davon]
+
+Eine weitere gute Ressource ist [Learn C The Hard Way](http://learncodethehardway.org/c/).
+[Englisch]
+
+Solltest du Fragen zu C haben, so lies die FAQ [compl.lang.c Frequently Asked Questions](http://c-faq.com).[Englisch]
+
+Außerdem ist es wichtig, eine saubere Einrückung zu verwenden. Des weiteren ist
+es wichtig, dass der Codestil möglichst konsistent ist. Es ist wichtiger, lesbaren
+Code zu schreiben als Code, welcher clever und schnell ist. Es lohnt sich ein
+Blick auf den [Codestil des Linuxkernel](https://www.kernel.org/doc/Documentation/process/coding-style.rst) zu werfen. [Englisch]
+
+[1] [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member)
diff --git a/de-de/clojure-macros-de.html.markdown b/de-de/clojure-macros-de.html.markdown
new file mode 100644
index 00000000..088a29a8
--- /dev/null
+++ b/de-de/clojure-macros-de.html.markdown
@@ -0,0 +1,161 @@
+---
+language: "clojure macros"
+filename: learnclojuremacros-de.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+translators:
+ - ["Dennis Keller", "https://github.com/denniskeller"]
+lang: de-de
+---
+
+Wie mit allen Lisps besitzt auch Clojure die inhärente [Homoikonizität](https://en.wikipedia.org/wiki/Homoiconic),
+die dir den vollen Zugang der Sprache gibt, um
+ Code-Generierungsroutinen zu schreiben. Diese werden "Macros" genannt.
+Macros geben dir eine leistungsarke Möglichkeit, die Sprache
+an deine Bedürfnisse anzupassen.
+
+Sei aber vorsichtig, es wird als schlechter Stil angesehen, wenn du
+ein Macro schreibst, obwohl eine Funktion genausogut funktionieren würde.
+Verwende nur dann ein Macro, wenn du Kontrolle darüber brauchst, wann oder ob Argumente in einer Form evaluiert werden.
+
+Wenn du mit Clojure vertraut sein möchtest, stelle sicher, dass du alles in [Clojure in Y Minutes](/docs/clojure/) verstehst.
+
+```clojure
+;; Definiere ein Macro mit defmacro. Dein Macro sollte eine Liste zurückgeben,
+;; die als Clojure Code evaluiert werden kann.
+;;
+;; Dieses Macro ist das Gleiche, als ob du (reverse "Hallo Welt") geschrieben
+;; hättest
+(defmacro my-first-macro []
+ (list reverse "Hallo Welt"))
+
+;; Inspiziere das Ergebnis eines Macros mit macroexpand oder macroexpand-1.
+;;
+;; Beachte, dass der Aufruf zitiert sein muss.
+(macroexpand '(my-first-macro))
+;; -> (#<core$reverse clojure.core$reverse@xxxxxxxx> "Hallo Welt")
+
+;; Du kannst das Ergebnis von macroexpand direkt auswerten.
+(eval (macroexpand '(my-first-macro)))
+; -> (\t \l \e \W \space \o \l \l \a \H)
+
+;; Aber du solltest diese prägnante und funktionsähnliche Syntax verwenden:
+(my-first-macro) ; -> (\t \l \e \W \space \o \l \l \a \H)
+
+;; Du kannst es dir leichter machen, indem du die Zitiersyntax verwendest
+;; um Listen in ihren Makros zu erstellen:
+(defmacro my-first-quoted-macro []
+ '(reverse "Hallo Welt"))
+
+(macroexpand '(my-first-quoted-macro))
+;; -> (reverse "Hallo Welt")
+;; Beachte, dass reverse nicht mehr ein Funktionsobjekt ist, sondern ein Symbol
+
+;; Macros können Argumente haben.
+(defmacro inc2 [arg]
+ (list + 2 arg))
+
+(inc2 2) ; -> 4
+
+;; Aber wenn du versuchst das mit einer zitierten Liste zu machen wirst du
+;; einen Fehler bekommen, weil das Argument auch zitiert sein wird.
+;; Um dies zu umgehen, bietet Clojure einee Art und Weise Macros zu zitieren: `
+;; In ` kannst du ~ verwenden um in den äußeren Bereich zu kommen.
+(defmacro inc2-quoted [arg]
+ `(+ 2 ~arg))
+
+(inc2-quoted 2)
+
+;; Du kannst die normalen destruktuierungs Argumente verwenden. Expandiere
+;; Listenvariablen mit ~@.
+(defmacro unless [arg & body]
+ `(if (not ~arg)
+ (do ~@body))) ; Erinnere dich an das do!
+
+(macroexpand '(unless true (reverse "Hallo Welt")))
+;; ->
+;; (if (clojure.core/not true) (do (reverse "Hallo Welt")))
+
+;; (unless) evaluiert und gibt body zurück, wenn das erste Argument falsch ist.
+;; Andernfalls gibt es nil zurück
+
+(unless true "Hallo") ; -> nil
+(unless false "Hallo") ; -> "Hallo"
+
+;; Die Verwendung Macros ohne Sorgfalt kann viel Böses auslösen, indem es
+;; deine Variablen überschreibt
+(defmacro define-x []
+ '(do
+ (def x 2)
+ (list x)))
+
+(def x 4)
+(define-x) ; -> (2)
+(list x) ; -> (2)
+
+;; Um das zu verhindern kannst du gensym verwenden um einen eindeutigen
+;; Identifikator zu bekommen
+(gensym 'x) ; -> x1281 (oder etwas Ähnliches)
+
+(defmacro define-x-safely []
+ (let [sym (gensym 'x)]
+ `(do
+ (def ~sym 2)
+ (list ~sym))))
+
+(def x 4)
+(define-x-safely) ; -> (2)
+(list x) ; -> (4)
+
+;; Du kannst # innerhalb von ` verwenden um für jedes Symbol automatisch
+;; ein gensym zu erstellen
+(defmacro define-x-hygienically []
+ `(do
+ (def x# 2)
+ (list x#)))
+
+(def x 4)
+(define-x-hygienically) ; -> (2)
+(list x) ; -> (4)
+
+;; Es ist üblich, Hilfsfunktionen mit Macros zu verwenden. Lass uns einige
+;; erstellen, die uns helfen , eine (dumme) arithmetische Syntax
+;; zu unterstützen
+(declare inline-2-helper)
+(defn clean-arg [arg]
+ (if (seq? arg)
+ (inline-2-helper arg)
+ arg))
+
+(defn apply-arg
+ "Bekomme die Argumente [x (+ y)], gebe (+ x y) zurück"
+ [val [op arg]]
+ (list op val (clean-arg arg)))
+
+(defn inline-2-helper
+ [[arg1 & ops-and-args]]
+ (let [ops (partition 2 ops-and-args)]
+ (reduce apply-arg (clean-arg arg1) ops)))
+
+;; Wir können es sofort testen, ohne ein Macro zu erstellen
+(inline-2-helper '(a + (b - 2) - (c * 5))) ; -> (- (+ a (- b 2)) (* c 5))
+
+; Allerdings, brauchen wir ein Macro, wenn wir es zur Kompilierungszeit
+; ausführen wollen
+(defmacro inline-2 [form]
+ (inline-2-helper form))
+
+(macroexpand '(inline-2 (1 + (3 / 2) - (1 / 2) + 1)))
+; -> (+ (- (+ 1 (/ 3 2)) (/ 1 2)) 1)
+
+(inline-2 (1 + (3 / 2) - (1 / 2) + 1))
+; -> 3 (eigentlich, 3N, da die Zahl zu einem rationalen Bruch mit / umgewandelt wird)
+```
+
+### Weiterführende Literatur
+
+[Macros schreiben](http://www.braveclojure.com/writing-macros/)
+
+[Offiziele Docs](http://clojure.org/macros)
+
+[Wann verwendet man Macros?](https://lispcast.com/when-to-use-a-macro/)
diff --git a/de-de/css-de.html.markdown b/de-de/css-de.html.markdown
index c31e73d2..da706e91 100644
--- a/de-de/css-de.html.markdown
+++ b/de-de/css-de.html.markdown
@@ -27,7 +27,7 @@ In diesem Artikel wird am meisten auf generelle Hinweise und die Syntax geachtet
####################*/
/* Eigentlich ist das grundlegende CSS-Statement sehr simpel */
-selektor { eigenschaft: wert; /* mehr eigenschaften...*/ }
+selektor { eigenschaft: wert; /* mehr Eigenschaften...*/ }
/* Der Selektor wird dazu benutzt, ein Element auf der Seite auszuwählen.
@@ -35,7 +35,7 @@ Man kann aber auch alle Elemente auf einer Seite auswählen! */
* { color:red; } /* farbe:rot */
/*
-Angenommen wir haben folgendes Element auf einer Seite:
+Angenommen, wir haben folgendes Element auf einer Seite:
<div class='eine-klasse klasse2' id='eineId' attr='wert' />
*/
@@ -170,7 +170,7 @@ empfohlen ist -->
## Spezifität
Ein Element kann natürlich auch von mehr als einer Regel in einem Stylesheet
-angesprochen werdenm und kann eine Eigenschaft auch öfters als einmal zugewiesen
+angesprochen werden und kann eine Eigenschaft auch öfters als einmal zugewiesen
bekommen. In diesen Fällen gibt es Regeln, die die Spezifität von Selektoren regeln.
Wir haben dieses CSS:
diff --git a/de-de/d-de.html.markdown b/de-de/d-de.html.markdown
index 2b0b38dd..28ecc7ae 100644
--- a/de-de/d-de.html.markdown
+++ b/de-de/d-de.html.markdown
@@ -9,7 +9,7 @@ lang: de-de
---
```c
-// Es war klar dass das kommt...
+// Es war klar, dass das kommt...
module hello;
import std.stdio;
@@ -20,13 +20,13 @@ void main(string[] args) {
}
```
-Wenn du so wie ich bist und viel zeit im Internet verbringst stehen die Chancen gut
-das du schonmal über [D](http://dlang.org/) gehört hast.
-Die D-Sprache ist eine moderne, überall einsetzbare programmiersprache die von Low bis
-High Level verwendet werden kann und dabei viele Stile anbietet.
+Wenn du so wie ich bist und viel Zeit im Internet verbringst, stehen die Chancen
+gut, dass du schonmal über [D](http://dlang.org/) gehört hast.
+Die D-Sprache ist eine moderne, überall einsetzbare programmiersprache die von
+Low bis High Level verwendet werden kann und dabei viele Stile anbietet.
D wird aktiv von Walter Bright und Andrei Alexandrescu entwickelt, zwei super schlaue,
-richtig coole leute. Da das jetzt alles aus dem weg ist - auf zu den Beispielen!
+richtig coole leute. Da das jetzt alles aus dem Weg ist - auf zu den Beispielen!
```c
import std.stdio;
@@ -38,7 +38,7 @@ void main() {
writeln(i);
}
- auto n = 1; // auto um den typ vom Compiler bestimmen zu lassen
+ auto n = 1; // auto um den Typ vom Compiler bestimmen zu lassen
// Zahlenliterale können _ verwenden für lesbarkeit
while(n < 10_000) {
@@ -68,21 +68,22 @@ void main() {
}
```
-Neue Typen können mit `struct`, `class`, `union`, und `enum` definiert werden. Structs und unions
-werden as-value (koppiert) an methoden übergeben wogegen Klassen als Referenz übergeben werden.
-Templates können verwendet werden um alle typen zu parameterisieren.
+Neue Typen können mit `struct`, `class`, `union`, und `enum` definiert werden.
+Structs und unions werden as-value (koppiert) an Methoden übergeben wogegen
+Klassen als Referenz übergeben werden. Templates können verwendet werden um
+alle Typen zu parameterisieren.
```c
// Hier, T ist ein Type-Parameter, Er funktioniert wie Generics in C#/Java/C++
struct LinkedList(T) {
T data = null;
- LinkedList!(T)* next; // Das ! wird verwendet um T zu übergeben. (<T> in C#/Java/C++)
+ LinkedList!(T)* next; // Das ! wird verwendet, um T zu übergeben. (<T> in C#/Java/C++)
}
class BinTree(T) {
T data = null;
- // Wenn es nur einen T parameter gibt können die Klammern um ihn weggelassen werden
+ // Wenn es nur einen T Parameter gibt, können die Klammern um ihn weggelassen werden
BinTree!T left;
BinTree!T right;
}
@@ -97,7 +98,7 @@ enum Day {
Saturday,
}
-// Aliase können verwendet werden um die Entwicklung zu erleichtern
+// Aliase können verwendet werden, um die Entwicklung zu erleichtern
alias IntList = LinkedList!int;
alias NumTree = BinTree!double;
@@ -111,8 +112,8 @@ T max(T)(T a, T b) {
return a;
}
-// Steht ref vor einem Parameter wird sichergestellt das er als Referenz übergeben wird.
-// Selbst bei werten wird es immer eine Referenz sein.
+// Steht ref vor einem Parameter, wird sichergestellt, dass er als Referenz
+übergeben wird. Selbst bei Werten wird es immer eine Referenz sein.
void swap(T)(ref T a, ref T b) {
auto temp = a;
@@ -120,18 +121,18 @@ void swap(T)(ref T a, ref T b) {
b = temp;
}
-// Templates können ebenso werte parameterisieren.
+// Templates können ebenso Werte parameterisieren.
class Matrix(uint m, uint n, T = int) {
T[m] rows;
T[n] columns;
}
-auto mat = new Matrix!(3, 3); // Standardmäßig ist T vom typ Integer
+auto mat = new Matrix!(3, 3); // Standardmäßig ist T vom Typ Integer
```
Wo wir schon bei Klassen sind - Wie wäre es mit Properties! Eine Property
-ist eine Funktion die wie ein Wert agiert. Das gibt uns viel klarere Syntax
+ist eine Funktion, die wie ein Wert agiert. Das gibt uns viel klarere Syntax
im Stil von `structure.x = 7` was gleichgültig wäre zu `structure.setX(7)`
```c
@@ -187,18 +188,17 @@ void main() {
```
Mit properties können wir sehr viel logik hinter unseren gettern
-und settern hinter einer schönen syntax verstecken
+und settern hinter einer schönen Syntax verstecken
-Other object-oriented goodies at our disposal
Andere Objektorientierte features sind beispielsweise
`interface`s, `abstract class` und `override`.
Vererbung funktioniert in D wie in Java:
-Erben von einer Klasse, so viele interfaces wie man will.
+Erben von einer Klasse, so viele Interfaces wie man will.
-Jetzt haben wir Objektorientierung in D gesehen aber schauen
+Jetzt haben wir Objektorientierung in D gesehen, aber schauen
wir uns noch was anderes an.
-D bietet funktionale programmierung mit _first-class functions_
-puren funktionen und unveränderbare daten.
+D bietet funktionale Programmierung mit _first-class functions_
+puren Funktionen und unveränderbaren Daten.
Zusätzlich können viele funktionale Algorithmen wie z.B
map, filter, reduce und friends im `std.algorithm` Modul gefunden werden!
@@ -207,11 +207,11 @@ import std.algorithm : map, filter, reduce;
import std.range : iota; // builds an end-exclusive range
void main() {
- // Wir wollen die summe aller quadratzahlen zwischen
+ // Wir wollen die Summe aller Quadratzahlen zwischen
// 1 und 100 ausgeben. Nichts leichter als das!
- // Einfach eine lambda funktion als template parameter übergeben
- // Es ist genau so gut möglich eine normale funktion hier zu übergeben
+ // Einfach eine Lambda-Funktion als Template Parameter übergeben
+ // Es ist genau so gut möglich eine normale Funktion hier zu übergeben
// Lambdas bieten sich hier aber an.
auto num = iota(1, 101).filter!(x => x % 2 == 0)
.map!(y => y ^^ 2)
@@ -221,13 +221,13 @@ void main() {
}
```
-Ist dir aufgefallen wie wir eine Haskell-Style pipeline gebaut haben
+Ist dir aufgefallen, wie wir eine Haskell-Style Pipeline gebaut haben
um num zu berechnen?
Das war möglich durch die Uniform Function Call Syntax.
-Mit UFCS können wir auswählen ob wir eine Funktion als Methode oder
+Mit UFCS können wir auswählen, ob wir eine Funktion als Methode oder
als freie Funktion aufrufen. Walters artikel dazu findet ihr
[hier.](http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394)
-Kurzgesagt kann man Funktionen deren erster parameter vom typ A ist, als
+Kurzgesagt kann man Funktionen, deren erster Parameter vom typ A ist, als
Methode auf A anwenden.
Parrallel Computing ist eine Tolle sache, findest du nicht auch?
@@ -239,10 +239,10 @@ import std.math : sqrt;
void main() {
// Wir wollen die Wurzel von jeder Zahl in unserem Array berechnen
- // und dabei alle Kerne verwenden die wir zur verfügung haben
+ // und dabei alle Kerne verwenden, die wir zur verfügung haben
auto arr = new double[1_000_000];
- // Wir verwenden den index und das element als referenz
+ // Wir verwenden den Index und das Element als Referenz
// und rufen einfach parallel auf!
foreach(i, ref elem; parallel(arr)) {
ref = sqrt(i + 1.0);
diff --git a/de-de/dhall-de.html.markdown b/de-de/dhall-de.html.markdown
new file mode 100644
index 00000000..385c88be
--- /dev/null
+++ b/de-de/dhall-de.html.markdown
@@ -0,0 +1,380 @@
+---
+language: Dhall
+contributors:
+ - ["Gabriel Gonzalez", "http://www.haskellforall.com/"]
+translators:
+ - ["Profpatsch", "http://profpatsch.de"]
+filename: learndhall-de.py
+lang: de-de
+---
+
+Dhall ist eine programmierbare Konfigurationssprache und bietet eine
+nicht-repetetive Alternative zu YAML.
+
+Man kann Dhall sehen als: JSON + Funktionen + Typen + Importsystem
+
+Obwohl Dhall programmierbar ist, ist die Sprache nicht
+turingvollständig. Viele von Dhalls Features benutzen diese
+Einschränkung, um stärkere Sicherheitsgarantien zu bieten und besseres
+Tooling zu ermöglichen.
+
+```haskell
+-- einzeiliger Kommentar
+
+{- mehrzeiliger Kommentar
+
+ Unicode funktioniert 🙂
+
+ Diese Datei ist eine valide Dhall-Expression und evaluiert zu einem
+ großen Record, welcher die Ergebnisse jedes Schritts beinhaltet.
+
+ Das Ergebnis kann angezeigt werden, indem man die Datei evaluiert:
+
+ $ dhall --file learndhall.dhall
+
+ {- Kommentare können verschachtelt sein -}
+-}
+
+let greeting = "Hallo, Welt!"
+
+let fruits = "🍋🍓🍍🍉🍌"
+
+let interpolation = "Ein paar leckere Früchte: ${fruits}"
+
+let multilineText {- Inline-Kommentare funktionieren ebenfalls -} =
+ ''
+ In Multiline-Text-Literals wird Whitespace am Anfang der Zeile
+ entfernt.
+
+ Das bedeutet Text kann frei eingerückt oder ausgerückt werden,
+ ohne dass sich der Inhalt des Strings ändert.
+
+ Relative Einrückungen bleiben erhalten.
+
+ Ansonsten wird das Text-Literal verbatim erhalten, ähnlich
+ zu “literal”-Multiline-Strings in YAML.
+ ''
+
+let bool = True
+
+-- Typannotationen für Bindings sind optional, aber hilfreich, also
+-- benutzen wir sie hier.
+let annotation : Bool = True
+
+let renderedBool : Text = if bool then "True" else "False"
+
+-- Natürliche Zahlen sind nicht-negativ und vorzeichenlos.
+let naturalNumber : Natural = 42
+
+-- Integer können negativ sein, brauchen aber ein explizites Vorzeichen.
+let positiveInteger : Integer = +1
+
+let negativeInteger : Integer = -12
+
+let pi : Double = 3.14159265359
+
+{- Identifier dürfen eine große Anzahl an verschiedenen Zeichen
+ beinhalten (wie z.B. Anführungszeichen oder Whitespace), wenn man
+ sie mit Backticks umschließt.
+-}
+let `Avogadro's Number` : Double = 6.0221409e+23
+
+let origin : { x : Double, y : Double } = { x = 0.0, y = 0.0 }
+
+let somePrimes : List Natural = [ 2, 3, 5, 7, 11 ]
+
+{- Ein Schema ist das gleiche wie ein Typ.
+
+ Typnamen beginnen konventionell mit einem Großbuchstaben, was
+ jedoch nicht erzwungen wird.
+-}
+let Profile : Type
+ = { person :
+ { name : Text
+ , age : Natural
+ }
+ , address :
+ { country : Text
+ , state : Text
+ , city : Text
+ }
+ }
+
+let bernd : Profile =
+ { person =
+ { name = "Bernd Lauert"
+ , age = 67
+ }
+ , address =
+ { country = "Deutschland"
+ , state = "Bayern"
+ , city = "Augsburg"
+ }
+ }
+
+let augsburg : Text = bernd.address.city
+
+{- Enum-Alternativen beginnen konventionell auch mit einem
+ Großbuchstaben. Das wird ebenfalls nicht erzwungen.
+-}
+let DNA : Type = < Adenine | Cytosine | Guanine | Thymine >
+
+let dnaSequence : List DNA = [ DNA.Thymine, DNA.Guanine, DNA.Guanine ]
+
+let compactDNASequence : List DNA =
+ let a = DNA.Adenine
+ let c = DNA.Cytosine
+ let g = DNA.Guanine
+ let t = DNA.Thymine
+ in [ c, t, t, a, t, c, g, g, c ]
+
+-- Enums werden transformiert, indem man einen Record mit einem Feld
+-- pro Alternative angibt.
+let theLetterG : Text =
+ merge
+ { Adenine = "A"
+ , Cytosine = "C"
+ , Guanine = "G"
+ , Thymine = "T"
+ }
+ DNA.Guanine
+
+let presentOptionalValue : Optional Natural = Some 1
+
+let absentOptionalValue : Optional Natural = None Natural
+
+let points : List { x : Double, y : Double } =
+ [ { x = 1.1, y = -4.2 }
+ , { x = 4.4, y = -3.0 }
+ , { x = 8.2, y = -5.5 }
+ ]
+
+{- `Natural -> List Natural` ist der Funktionstyp mit Eingabetyp
+ `Natural` und Ausgabetyp `List Natural`.
+
+ Alle Funktionen in Dhall sind Anonyme Funktionen (aka. „Lambdas“),
+ denen man optional einen Namen geben kann.
+
+ Die folgende Funktion beispielsweise ist äquivalent zu diesem
+ Python Code:
+
+ lambda n : [ n, n + 1 ]
+
+ ... und diesem Javascript Code:
+
+ function (n) { return [ n, n + 1 ]; }
+-}
+let exampleFunction : Natural -> List Natural =
+ \(n : Natural) -> [ n, n + 1 ]
+
+-- Dhall unterstützt auch Unicode-Syntax, aber dieses Tutorial nutzt
+-- die ASCII-Syntax.
+let unicodeFunction : Natural → List Natural =
+ λ(n : Natural) → [ n, n + 1 ]
+
+-- Funktionsargumente brauchen keine Klammern.
+let exampleFunctionApplication : List Natural =
+ exampleFunction 2
+
+let functionOfMultipleArguments : Natural -> Natural -> List Natural =
+ \(x : Natural) -> \(y : Natural) -> [ x, y ]
+
+let functionAppliedToMultipleArguments : List Natural =
+ functionOfMultipleArguments 2 3
+
+{- Wie `exampleFunction`, aber wir geben dem Eingabetypen
+ einen Namen, `n`.
+-}
+let namedArgumentType : forall (n : Natural) -> List Natural =
+ \(n : Natural) -> [ n, n + 1 ]
+
+{- Bekommt der Eingabetyp einen Namen, kann man ihn weiter hinten in
+ der gleichen Typdefinition wiederverwenden.
+
+ Das ermöglicht Funktionen, die mit mehr als einem Eingabetypen
+ arbeiten können (aka. „polymorphe“ Funktionen).
+-}
+let duplicate : forall (a : Type) -> a -> List a =
+ \(a : Type) -> \(x : a) -> [ x, x ]
+
+let duplicatedNumber : List Natural =
+ duplicate Natural 2
+
+let duplicatedBool : List Bool =
+ duplicate Bool False
+
+{- Die Sprache hat auch eine handvoll eingebauter polymorpher
+ Funktionen, wie zum Beispiel:
+
+ List/head : forall (a : Type) -> List a -> Optional a
+-}
+let firstPrime : Optional Natural = List/head Natural somePrimes
+
+let functionOfARecord : { x : Natural, y : Natural } -> List Natural =
+ \(args : { x : Natural, y : Natural }) -> [ args.x, args.y ]
+
+let functionAppliedToARecord : List Natural =
+ functionOfARecord { x = 2, y = 5 }
+
+{- Alle Typkonversionen sind explizit.
+
+ `Natural/show` ist eine eingebaute Funktion mit dem Typ:
+
+ Natural/show : Natural -> Text
+
+ ... welche `Natural`s in ihre `Text`-Repräsentation konvertiert.
+-}
+let typeConversion : Natural -> Text =
+ \(age : Natural) -> "Ich bin ${Natural/show age} Jahre alt!"
+
+-- Ein „Template“ ist einfach eine Funktion mit Ausgabetyp `Text`.
+let mitLicense : { year : Natural, copyrightHolder : Text } -> Text =
+ \(args : { year : Natural, copyrightHolder : Text }) ->
+''
+Copyright ${Natural/show args.year} ${args.copyrightHolder}
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+''
+
+-- Template-Instanziierung ist das gleiche wie Funktionsanwendung.
+let templatedLicense : Text =
+ mitLicense { year = 2019, copyrightHolder = "Jane Smith" }
+
+{- Expressions können via URL importiert werden.
+
+ Ähnlich wie in Bash kann man Code aus dem lokalen Dateisystem
+ importieren (wird nicht gezeigt).
+
+ Sicherheitsbewusste Nutzer können via URLs importierte Expressions
+ mit einem semantischen Integritätscheck versehen („pinnen“).
+ Für gepinnte Imports wird der Dhall-Interpreter jeden Versuch
+ vereiteln, auf der Remote-Seite die Expression zu manipulieren.
+ Jedoch werden Änderungen, die den Inhalt der importierten
+ Expression nicht verändern trotzdem akzeptiert.
+
+ Auf diese Weise gepinnte Expressions werden auch in einem
+ Content-Adressable Store lokal gecached (standardmäßig in
+ `~/.cache/dhall`).
+-}
+let Natural/sum : List Natural -> Natural =
+ https://prelude.dhall-lang.org/Natural/sum
+ sha256:33f7f4c3aff62e5ecf4848f964363133452d420dcde045784518fb59fa970037
+
+let twentyEight : Natural = Natural/sum somePrimes
+
+-- Ein „Paket“ ist einfach ein (möglicherweise verschachtelter)
+-- Record, den man importiert.
+let Prelude = https://prelude.dhall-lang.org/package.dhall
+
+let false : Bool = Prelude.Bool.not True
+
+-- Durch das Anhängen von `as Text` wird eine Datei verbatim
+-- importiert und nicht als Dhall-Code interpretiert.
+let sourceCode : Text = https://prelude.dhall-lang.org/Bool/not as Text
+
+-- Environment-Variablen können auch imortiert werden.
+let presentWorkingDirectory = env:PWD as Text
+
+-- Mit `?` kann man eine “Fallback-Expression” angeben, für den Fall
+-- dass ein Import fehlschlägt.
+let home : Optional Text = Some env:HOME ? None Text
+
+-- Fallback-Expressions können auch alternative Imports enthalten.
+let possiblyCustomPrelude =
+ env:DHALL_PRELUDE
+ ? https://prelude.dhall-lang.org/package.dhall
+
+{- Ein ausführliches Beispiel, welches mithilfe der
+ `generate`-Funktion eine Konfiguration für 10 Build-User generiert:
+
+ Prelude.List.generate
+ : Natural -> forall (a : Type) -> (Natural -> a) -> List a
+-}
+let buildUsers =
+ let makeUser = \(user : Text) ->
+ let home = "/home/${user}"
+ let privateKey = "${home}/.ssh/id_ed25519"
+ let publicKey = "${privateKey}.pub"
+ in { home = home
+ , privateKey = privateKey
+ , publicKey = publicKey
+ }
+
+ let buildUser =
+ \(index : Natural) -> makeUser "build${Natural/show index}"
+
+ let Config =
+ { home : Text
+ , privateKey : Text
+ , publicKey : Text
+ }
+
+ in Prelude.List.generate 10 Config buildUser
+
+-- Alle Ergebnisse in einem großen Record
+in { greeting = greeting
+ , fruits = fruits
+ , interpolation = interpolation
+ , multilineText = multilineText
+ , bool = bool
+ , annotation = annotation
+ , renderedBool = renderedBool
+ , naturalNumber = naturalNumber
+ , positiveInteger = positiveInteger
+ , negativeInteger = negativeInteger
+ , pi = pi
+ , `Avogadro's Number` = `Avogadro's Number`
+ , origin = origin
+ , somePrimes = somePrimes
+ , bernd = bernd
+ , augsburg = augsburg
+ , dnaSequence = dnaSequence
+ , compactDNASequence = compactDNASequence
+ , theLetterG = theLetterG
+ , presentOptionalValue = presentOptionalValue
+ , absentOptionalValue = absentOptionalValue
+ , points = points
+ , exampleFunction = exampleFunction
+ , unicodeFunction = unicodeFunction
+ , exampleFunctionApplication = exampleFunctionApplication
+ , functionOfMultipleArguments = functionOfMultipleArguments
+ , functionAppliedToMultipleArguments = functionAppliedToMultipleArguments
+ , namedArgumentType = namedArgumentType
+ , duplicate = duplicate
+ , duplicatedNumber = duplicatedNumber
+ , duplicatedBool = duplicatedBool
+ , firstPrime = firstPrime
+ , functionOfARecord = functionOfARecord
+ , functionAppliedToARecord = functionAppliedToARecord
+ , typeConversion = typeConversion
+ , mitLicense = mitLicense
+ , templatedLicense = templatedLicense
+ , twentyEight = twentyEight
+ , false = false
+ , sourceCode = sourceCode
+ , presentWorkingDirectory = presentWorkingDirectory
+ , home = home
+ , buildUsers = buildUsers
+ }
+```
+
+Mehr Infos und Lernmaterialien gibt es auf der offiziellen Website
+(Englisch), auf der man Dhall auf im Browser ausprobieren kann:
+
+* [https://dhall-lang.org](http://dhall-lang.org/)
diff --git a/de-de/dynamic-programming-de.html.markdown b/de-de/dynamic-programming-de.html.markdown
new file mode 100644
index 00000000..58568b3b
--- /dev/null
+++ b/de-de/dynamic-programming-de.html.markdown
@@ -0,0 +1,77 @@
+---
+category: Algorithms & Data Structures
+name: Dynamic Programming
+contributors:
+ - ["Akashdeep Goel", "http://github.com/akashdeepgoel"]
+translators:
+ - ["Henrik Jürges", "http://github.com/santifa"]
+lang: de-de
+---
+
+# Dynamische Programmierung
+
+## Einführung
+Dynamische Programmierung ist eine leistungsfähige Technik, die zur Lösung
+einer bestimmten Klasse von Problemen verwendet wird.
+Die Idee ist sehr einfach, wenn Sie ein Problem mit der gegebenen Eingabe
+gelöst haben, dann speichern Sie das Ergebnis für die spätere Referenz, um zu
+vermeiden, das gleiche Problem noch einmal zu lösen.
+
+Denken Sie immer daran!
+"Diejenigen, die sich nicht an die Vergangenheit erinnern können,
+sind dazu verdammt, sie zu wiederholen."
+
+## Wege zur Lösung solcher Probleme
+
+1. *Top-Down*: Lösen Sie das gegebene Problem, indem Sie es aufteilen.
+Wenn Sie sehen, dass das Problem bereits gelöst ist, geben Sie einfach die
+gespeicherte Antwort zurück. Wenn es nicht gelöst wurde, lösen Sie es und
+speichern Sie die Antwort. Dieser Ansatz ist leicht zu verfolgen und sehr
+intuitiv. Er wird als Memoization bezeichnet.
+
+2. *Bottom-Up*: Analysieren Sie das Problem und beobachten Sie, in welcher
+Reihenfolge die Teilprobleme gelöst werden können. Beginnen Sie mit der
+Lösung vom trivialen Teilproblem bis zum gegebenen Problem. Dabei wird
+sichergestellt, dass die Teilprobleme vor der Problemlösung gelöst werden.
+Dies wird als Dynamische Programmierung bezeichnet.
+
+## Ein Beispiel für Dynamische Programmierung
+
+Das Problem mit der längsten ansteigenden Subsequenz besteht darin,
+die längste ansteigende Subsequenz einer gegebenen Sequenz zu finden.
+Gegeben die Sequenz `S= {a1, a2, a3, a3, a4,..............., an-1, an }`,
+müssen wir die größte Teilmenge finden, so daß für alle `j` und `i`, `j<i`
+in der Teilmenge `aj<ai` gilt.
+Zuerst müssen wir bei jedem Index i den Wert der längsten Subsequenzen (LSi)
+finden, wobei das letzte Element der Sequenz ai ist. Dann wäre die größte LSi
+die längste Subsequenz in der gegebenen Sequenz. Am Anfang wird der LSi mit
+eins belegt, da ai ein Element der Sequenz (Letztes Element) ist.
+Dann ist für alle `j` mit `j<i` und `aj<ai`, so dass wir den größten LSj finden
+und zum LSi hinzufügen. Der Algorithmus hat eine Laufzeit von *O(n2)*.
+
+Pseudocode zur Bestimmung der Länge der am längsten ansteigenden Subsequenz:
+Die Komplexität des Algorithmus könnte durch eine bessere Datenstruktur anstelle
+von Arrays reduziert werden. Das Speichern von Vorgänger-Array's und Variablen
+wie `largest_sequences_so_far` und dessen Index würde eine Menge Zeit sparen.
+
+Ein ähnliches Konzept könnte auch bei der Suche nach dem längsten Weg
+in gerichteten azyklischen Graphen angewandt werden.
+```python
+for i=0 to n-1
+ LS[i]=1
+ for j=0 to i-1
+ if (a[i] > a[j] and LS[i]<LS[j])
+ LS[i] = LS[j]+1
+for i=0 to n-1
+ if (largest < LS[i])
+```
+
+### Einige bekannte DP Probleme
+
+- [Floyd Warshall Algorithm - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code)
+- [Integer Knapsack Problem - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem)
+- [Longest Common Subsequence - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence)
+
+## Online Ressourcen
+
+* [codechef](https://www.codechef.com/wiki/tutorial-dynamic-programming)
diff --git a/de-de/edn-de.html.markdown b/de-de/edn-de.html.markdown
new file mode 100644
index 00000000..2434d1bd
--- /dev/null
+++ b/de-de/edn-de.html.markdown
@@ -0,0 +1,112 @@
+---
+language: edn
+filename: learnedn-de.edn
+contributors:
+ - ["Jason Yeo", "https://github.com/jsyeo"]
+ - ["Jonathan D Johnston", "https://github.com/jdjohnston"]
+translators:
+ - ["Dennis Keller", "https://github.com/denniskeller"]
+lang: de-de
+---
+
+Extensible Data Notation (EDN) ist ein Format für serialisierte Daten.
+
+EDN ist ein Subset der von Clojure verwendeten Syntax. Das Lesen von Daten, die durch EDN definiert werden, ist
+sicherer als das, was durch die vollständige Clojure-Syntax definiert wird, insbesondere von nicht
+vertrauenswürdigen Quellen. EDN ist beschränkt auf Daten, kein Code. Es ist ähnlich in seinen Zielen zu JSON.
+Obwohl es mehr in Clojure verwendet wird, gibt es verschiedene Implementationen von EDN in vielen
+verschiedenen anderen Sprachen.
+
+Der Hauptvorteil von EDN im Gegensatz zu JSON und YAML ist, dass es erweiterbar ist.
+Wir werden später sehen wie es erweitert werden kann.
+
+```clojure
+; Kommentare starten mit einem Semikolon.
+; Alles nach dem Semikolon wird ignoriert.
+
+;;;;;;;;;;;;;;;;;;;
+;;; Basistypen ;;;
+;;;;;;;;;;;;;;;;;;;
+
+nil ; auch bekannt in anderen Sprachen als null
+
+; Booleans
+true
+false
+
+; Strings werden in Gänsefüßchen eingeschlossen.
+"hungarian breakfast"
+"farmer's cheesy omelette"
+
+; Charaktere werden einem Backslash vorangestellt
+\g \r \a \c \e
+
+; Schlüsselwörter beginnen mit einem Doppelpunkt. Sie verhalten sich wie Enums.
+; Ähnlich, wie Symbole in Ruby.
+:eggs
+:cheese
+:olives
+
+; Symbole werden verwendet um Identifier zu repräsentieren. Sie beginnen mit einem #.
+; Du kannst einen Namespace für Symbole nutzen, wenn du / verwendest. Egal was / vorangestellt wird
+; ist der Namespace dieses Namens.
+#spoon
+#kitchen/spoon ; nicht das selbe, wie #spoon
+#kitchen/fork
+#github/fork ; damit kannst du nicht essen
+
+; Integers und Floats
+42
+3.14159
+
+; Listen sind Sequenzen von Werten
+(:bun :beef-patty 9 "yum!")
+
+; Vektoren erlauben zufälligen Zugriff
+[:gelato 1 2 -2]
+
+; Maps sind assoziative Datenstrukturen, die einen Schlüssel mit einem Wert verbinden.
+{:eggs 2
+ :lemon-juice 3.5
+ :butter 1}
+
+; Du bist nicht beschränkt ausschließlich Schlüsselwörter als Schlüssel zu verwenden.
+{[1 2 3 4] "tell the people what she wore",
+ [5 6 7 8] "the more you see the more you hate"}
+
+; Du kannst Kommas für eine bessere Lesbarkeit verwenden. Sie werden wie Leerraum behandelt.
+; Sets sind Sammlungen, die eindeutige Elemente enthalten.
+#{:a :b 88 "huat"}
+
+;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; markierte Elemente ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; EDN kann erweitert werden, indem Elemente mit # Symbolen makiert werden.
+
+#MyYelpClone/MenuItem {:name "eggs-benedict" :rating 10}
+
+; Lass mich das mit einem Clojure Beispiel erklären.
+; Angenommen ich möchte dieses Stück EDM in einen MenuItem record umwandeln.
+(defrecord MenuItem [name rating])
+
+; Um EDN in clojure Werte umzuwandeln, muss ich den eingebauten EDN Leser
+; edn/read-string verwenden
+
+(edn/read-string "{:eggs 2 :butter 1 :flour 5}")
+; -> {:eggs 2 :butter 1 :flour 5}
+
+; Definiere die Leserfunktion, um markierte Elemente zu transformieren
+; und übergebe eine Map, die Tags den Lesefunktionen als edn / read-string zuweisen
+
+(edn/read-string {:readers {'MyYelpClone/MenuItem map->menu-item}}
+ "#MyYelpClone/MenuItem {:name \"eggs-benedict\" :rating 10}")
+; -> #user.MenuItem{:name "eggs-benedict", :rating 10}
+
+```
+
+# Referenzen
+
+- [EDN spec](https://github.com/edn-format/edn)
+- [Implementationen](https://github.com/edn-format/edn/wiki/Implementations)
+- [makierte Elemente](http://www.compoundtheory.com/clojure-edn-walkthrough/)
diff --git a/de-de/elm-de.html.markdown b/de-de/elm-de.html.markdown
new file mode 100644
index 00000000..08832327
--- /dev/null
+++ b/de-de/elm-de.html.markdown
@@ -0,0 +1,376 @@
+---
+language: Elm
+filename: learnelm.elm
+contributors:
+ - ["Max Goldstein", "http://maxgoldste.in/"]
+translators:
+ - ["waynee95", "https://waynee95.me"]
+lang: de-de
+---
+
+Elm ist eine pure funktionale Programmiersprache. Mit Elm werden GUIs
+(grafische Benutzeroberfläche) für Webanwendungen erstellt. Durch die statische
+Typisierung kann Elm viele Fehler schon bei der Kompilierung abfangen. Ein
+Hauptmerkmal von Elm sind die ausführlichen und gut erklärten Fehlermeldungen.
+
+```haskell
+-- Einzeilige Kommentare beginnen mit 2 Bindestrichen.
+{- So wird ein mehrzeiliger Kommentar angelegt.
+{- Diese können auch verschachtelt werden. -}
+-}
+
+{-- Die Grundlagen --}
+
+-- Arithmetik
+1 + 1 -- 2
+8 - 1 -- 7
+10 * 2 -- 20
+
+-- Zahlen ohne Punkt sind entweder vom Typ Int oder Float.
+33 / 2 -- 16.5 mit Division von Gleitkommazahlen
+33 // 2 -- 16 mit ganzzahliger Division
+
+-- Exponenten
+5 ^ 2 -- 25
+
+-- Boolsche Werte
+not True -- False
+not False -- True
+1 == 1 -- True
+1 /= 1 -- False
+1 < 10 -- True
+
+-- Strings (Zeichenketten) und Zeichen
+"Das hier ist ein String."
+'a' -- Zeichen
+
+-- Strings können konkateniert werden.
+"Hello " ++ "world!" -- "Hello world!"
+
+{-- Listen und Tupel --}
+
+-- Jedes Element einer Liste muss vom gleichen Typ sein. Listen sind homogen.
+["the", "quick", "brown", "fox"]
+[1, 2, 3, 4, 5]
+-- Das zweite Beispiel kann man auch mit Hilfe der "range" Funktion schreiben.
+List.range 1 5
+
+-- Listen werden genauso wie Strings konkateniert.
+List.range 1 5 ++ List.range 6 10 == List.range 1 10 -- True
+
+-- Mit dem "cons" Operator lässt sich ein Element an den Anfang einer Liste anfügen.
+0 :: List.range 1 5 -- [0, 1, 2, 3, 4, 5]
+
+-- Die Funktionen "head" und "tail" haben als Rückgabewert den "Maybe" Typ.
+-- Dadurch wird die Fehlerbehandlung von fehlenden Elementen explizit, weil
+-- man immer mit jedem möglichen Fall umgehen muss.
+List.head (List.range 1 5) -- Just 1
+List.tail (List.range 1 5) -- Just [2, 3, 4, 5]
+List.head [] -- Nothing
+-- List.funktionsName bedeutet, dass diese Funktion aus dem "List"-Modul stammt.
+
+-- Tupel sind heterogen, jedes Element kann von einem anderen Typ sein.
+-- Jedoch haben Tupel eine feste Länge.
+("elm", 42)
+
+-- Das Zugreifen auf Elemente eines Tupels geschieht mittels den Funktionen
+-- "first" und "second".
+Tuple.first ("elm", 42) -- "elm"
+Tuple.second ("elm", 42) -- 42
+
+-- Das leere Tupel, genannt "Unit", wird manchmal als Platzhalter verwendet.
+-- Es ist das einzige Element vom Typ "Unit".
+()
+
+{-- Kontrollfluss --}
+
+-- Eine If-Bedingung hat immer einen Else-Zweig und beide Zweige müssen den
+-- gleichen Typ haben.
+if powerLevel > 9000 then
+ "WHOA!"
+else
+ "meh"
+
+-- If-Bedingungen können verkettet werden.
+if n < 0 then
+ "n is negative"
+else if n > 0 then
+ "n is positive"
+else
+ "n is zero"
+
+-- Mit dem Mustervergleich (pattern matching) kann man bestimmte Fälle direkt
+-- behandeln.
+case aList of
+ [] -> "matches the empty list"
+ [x]-> "matches a list of exactly one item, " ++ toString x
+ x::xs -> "matches a list of at least one item whose head is " ++ toString x
+-- Mustervergleich geht immer von oben nach unten. Würde man [x] als letztes
+-- platzieren, dann würde dieser Fall niemals getroffen werden, weil x:xs diesen
+-- Fall schon mit einschließt (xs ist in dem Fall die leere Liste).
+
+-- Mustervergleich an einem Maybe Typ.
+case List.head aList of
+ Just x -> "The head is " ++ toString x
+ Nothing -> "The list was empty."
+
+{-- Funktionen --}
+
+-- Die Syntax für Funktionen in Elm ist minimal. Hier werden Leerzeichen anstelle
+-- von runden oder geschweiften Klammern verwendet. Außerdem gibt es kein "return"
+-- Keyword.
+
+-- Eine Funktion wird durch ihren Namen, einer Liste von Parametern gefolgt von
+-- einem Gleichheitszeichen und dem Funktionskörper angegeben.
+multiply a b =
+ a * b
+
+-- Beim Aufruf der Funktion (auch Applikation genannt) werden die Argumente ohne
+-- Komma übergeben.
+multiply 7 6 -- 42
+
+-- Partielle Applikation einer Funktion (Aufrufen einer Funktion mit fehlenden
+-- Argumenten). Hierbei entsteht eine neue Funktion, der wir einen Namen geben.
+double =
+ multiply 2
+
+-- Konstanten sind Funktionen ohne Parameter.
+answer =
+ 42
+
+-- Funktionen, die Funktionen als Parameter haben, nennt man Funktionen höherer
+-- Ordnung. In funktionalen Programmiersprachen werden Funktionen als "first-class"
+-- behandelt. Man kann sie als Argument übergeben, als Rückgabewert einer Funktion
+-- zurückgeben oder einer Variable zuweisen.
+List.map double (List.range 1 4) -- [2, 4, 6, 8]
+
+-- Funktionen können auch als anonyme Funktion (Lambda-Funktionen) übergeben werden.
+-- Diese werden mit einem Blackslash eingeleitet, gefolgt von allen Argumenten.
+-- Die Funktion "\a -> a * 2" beschreibt die Funktion f(x) = x * 2.
+List.map (\a -> a * 2) (List.range 1 4) -- [2, 4, 6, 8]
+
+-- Mustervergleich kann auch in der Funktionsdefinition verwendet werden.
+-- In diesem Fall hat die Funktion ein Tupel als Parameter. (Beachte: Hier
+-- werden die Werte des Tupels direkt ausgepackt. Dadurch kann man auf die
+-- Verwendung von "first" und "second" verzichten.)
+area (width, height) =
+ width * height
+
+area (6, 7) -- 42
+
+-- Mustervergleich auf Records macht man mit geschweiften Klammern.
+-- Bezeichner (lokale Variablen) werden mittels dem "let" Keyword angelegt.
+-- (Mehr zu Records weiter unten!)
+volume {width, height, depth} =
+ let
+ area = width * height
+ in
+ area * depth
+
+volume { width = 3, height = 2, depth = 7 } -- 42
+
+-- Rekursive Funktion
+fib n =
+ if n < 2 then
+ 1
+ else
+ fib (n - 1) + fib (n - 2)
+
+List.map fib (List.range 0 8) -- [1, 1, 2, 3, 5, 8, 13, 21, 34]
+
+-- Noch eine rekursive Funktion (Nur ein Beispiel, verwende stattdessen immer
+-- List.length!)
+listLength aList =
+ case aList of
+ [] -> 0
+ x::xs -> 1 + listLength xs
+
+-- Funktionsapplikation hat die höchste Präzedenz, sie binden stärker als Operatoren.
+-- Klammern bietet die Möglichkeit der Bevorrangung.
+cos (degrees 30) ^ 2 + sin (degrees 30) ^ 2 -- 1
+-- Als erstes wird die Funktion "degrees" mit dem Wert 30 aufgerufen.
+-- Danach wird das Ergenis davon den Funktionen "cos", bzw. "sin" übergeben.
+-- Dann wird das Ergebnis davon mit 2 quadriert und als letztes werden diese
+-- beiden Werte dann addiert.
+
+{-- Typen und Typ Annotationen --}
+
+-- Durch Typinferenz kann der Compiler jeden Typ genau bestimmen. Man kann diese
+-- aber auch manuell selber angeben (guter Stil!).
+-- Typen beginnen immer mit eine Großbuchstaben. Dabei liest man "x : Typ" als
+-- "x" ist vom Typ "Typ".
+-- Hier ein paar übliche Typen:
+5 : Int
+6.7 : Float
+"hello" : String
+True : Bool
+
+-- Funktionen haben ebenfalls einen Typ. Dabei ist der ganz rechte Typ der
+-- Rückgabetyp der Funktion und alle anderen sind die Typen der Parameter.
+not : Bool -> Bool
+round : Float -> Int
+
+-- Es ist guter Stil immer den Typ anzugeben, da diese eine Form von Dokumentation
+-- sind. Außerdem kann so der Compiler genauere Fehlermeldungen geben.
+double : Int -> Int
+double x = x * 2
+
+-- Funktionen als Parameter werden durch Klammern angegeben. Die folgende Funktion
+-- ist nicht auf einen Typ festgelegt, sondern enthält Typvariablen (beginnend
+-- mit Kleinbuchstaben). Die konkreten Typen werden erst bei Anwendung der
+-- Funktion festgelegt. "List a" bedeutet, dass es sich um eine Liste mit
+-- Elementen vom Typ "a" handelt.
+List.map : (a -> b) -> List a -> List b
+
+-- Es gibt drei spezielle kleingeschriebene Typen: "number", "comparable" und
+-- "appendable".
+add : number -> number -> number
+add x y = x + y -- funktioniert mit Ints und Floats.
+
+max :: comparable -> comparable -> comparable
+max a b = if a > b then a else b -- funktioniert mit Typen, die vergleichbar sind.
+
+append :: appendable -> appendable -> appendable
+append xs ys = xs ++ ys -- funktioniert mit Typen, die konkatenierbar sind.
+
+append "hello" "world" -- "helloworld"
+append [1,1,2] [3,5,8] -- [1,1,2,3,5,8]
+
+{-- Eigene Datentypen erstellen --}
+
+-- Ein "Record" ist ähnlich wie ein Tupel, nur das jedes Feld einen Namne hat.
+-- Dabei spielt die Reihenfolge keine Rolle.
+{ x = 3, y = 7 }
+
+-- Um auf Werte eines Records zuzugreifen, benutzt man einen Punkt gefolgt
+-- von dem Namen des Feldes.
+{ x = 3, y = 7 }.x -- 3
+
+-- Oder mit einer Zugriffsfunktion, welche aus einem Punkt und dem Feldnamen besteht.
+.y { x = 3, y = 7 } -- 7
+
+-- Wert eines Feldes ändern. (Achtung: Das Feld muss aber vorher schon vorhanden sein!)
+{ person |
+ name = "George" }
+
+-- Mehrere Felder aufeinmal ändern unter Verwendung des alten Wertes.
+{ particle |
+ position = particle.position + particle.velocity,
+ velocity = particle.velocity + particle.acceleration }
+
+-- Du kannst ein Record auch als Typ Annotation verwenden.
+-- (Beachte: Ein Record Typ benutzt einen Doppelpunkt und ein Record Wert benutzt
+-- ein Gleichheitszeichen!)
+origin : { x : Float, y : Float, z : Float }
+origin =
+ { x = 0, y = 0, z = 0 }
+
+-- Durch das "type" Keyword kann man einem existierenden Typen einen Namen geben.
+type alias Point3D =
+ { x : Float, y : Float, z : Float }
+
+-- Der Name kann dann als Konstruktor verwendet werden.
+otherOrigin : Point3D
+otherOrigin =
+ Point3D 0 0 0
+
+-- Aber es ist immernoch der selbe Typ, da es nur ein Alias ist!
+origin == otherOrigin -- True
+
+-- Neben den Records gibt es auch noch so genannte Summentypen.
+-- Ein Summentyp hat mehrere Konstruktoren.
+type Direction =
+ North | South | East | West
+
+-- Ein Konstruktor kann außerdem noch andere Typen enthalten. Rekursion ist
+-- auch möglich.
+type IntTree =
+ Leaf | Node Int IntTree IntTree
+
+-- Diese können auch als Typ Annotation verwendet werden.
+root : IntTree
+root =
+ Node 7 Leaf Leaf
+
+-- Außerdem können auch Typvariablen verwendet werden in einem Konstruktor.
+type Tree a =
+ Leaf | Node a (Tree a) (Tree a)
+
+-- Beim Mustervergleich kann man auf die verschiedenen Konstruktoren matchen.
+leftmostElement : Tree a -> Maybe a
+leftmostElement tree =
+ case tree of
+ Leaf -> Nothing
+ Node x Leaf _ -> Just x
+ Node _ subtree _ -> leftmostElement subtree
+
+{-- Module und Imports --}
+
+-- Die Kernbibliotheken und andere Bibliotheken sind in Module aufgeteilt.
+-- Für große Projekte können auch eigene Module erstellt werden.
+
+-- Eine Modul beginnt mit ganz oben. Ohne diese Angabe befindet man sich
+-- automatisch im Modul "Main".
+module Name where
+
+-- Ohne genaue Angabe von Exports wird alles exportiert. Es können aber alle
+-- Exporte explizit angegeben werden.
+module Name (MyType, myValue) where
+
+-- Importiert das Modul "Dict". Jetzt kann man Funktionen mittels "Dict.insert"
+-- aufrufen.
+import Dict
+
+-- Importiert das "Dict" Modul und den "Dict" Typ. Dadurch muss man nicht "Dict.Dict"
+-- verwenden. Man kann trotzdem noch Funktionen des Moduls aufrufen, wie "Dict.insert".
+import Dict exposing (Dict)
+
+-- Abkürzung für den Modulnamen. Aufrufen der Funktionen mittels "C.funktionsName".
+import Graphics.Collage as C
+
+{-- Kommandozeilen Programme --}
+
+-- Eine Elm-Datei kompilieren.
+$ elm make MyFile.elm
+
+-- Beim ersten Aufruf wird Elm die "core" Bibliotheken installieren und eine
+-- "elm-package.json"-Datei anlegen, die alle Informationen des Projektes
+-- speichert.
+
+-- Der Reactor ist ein Server, welche alle Dateinen kompiliert und ausführt.
+$ elm reactor
+
+-- Starte das REPL (read-eval-print-loop).
+$ elm repl
+
+-- Bibliotheken werden durch den Github-Nutzernamen und ein Repository identifiziert.
+-- Installieren einer neuen Bibliothek.
+$ elm package install elm-lang/html
+-- Diese wird der elm-package.json Datei hinzugefügt.
+
+-- Zeigt alle Veränderungen zwischen zwei bestimmten Versionen an.
+$ elm package diff elm-lang/html 1.1.0 2.0.0
+-- Der Paketmanager von Elm erzwingt "semantic versioning"!
+```
+
+Elm ist eine besonders kleine Programmiersprache. Jetzt hast du genug Wissen an
+deiner Seite, um dich in fast jedem Elm Code zurecht zu finden.
+
+Noch ein paar weitere hilfreiche Ressourcen (in Englisch):
+
+- Die [Elm Homepage](http://elm-lang.org/). Dort findest du:
+
+ - [Anleitung zur Installierung von Elm](http://elm-lang.org/install)
+ - [Dokumentation](http://elm-lang.org/docs), sowie eine [Referenz zur Syntax](http://elm-lang.org/docs/syntax)
+ - Viele hilfreiche [Beispiele](http://elm-lang.org/examples)
+
+- Dokumentation der [Elm Kernbibliotheken](http://package.elm-lang.org/packages/elm-lang/core/latest/). Insbesondere:
+
+ - [Basics](http://package.elm-lang.org/packages/elm-lang/core/latest/Basics) (standardmäßig importiert)
+ - [Maybe](http://package.elm-lang.org/packages/elm-lang/core/latest/Maybe) sowie [Result](http://package.elm-lang.org/packages/elm-lang/core/latest/Result) (benutzt für Fehlerbehandlung)
+ - Datenstrukturen, wie [List](http://package.elm-lang.org/packages/elm-lang/core/latest/List), [Array](http://package.elm-lang.org/packages/elm-lang/core/latest/Array), [Dict](http://package.elm-lang.org/packages/elm-lang/core/latest/Dict), und [Set](http://package.elm-lang.org/packages/elm-lang/core/latest/Set)
+ - JSON [encoding](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Encode) und [decoding](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Decode)
+
+- [Die Elm Architektur](https://github.com/evancz/elm-architecture-tutorial#the-elm-architecture).
+
+- Die [Elm mailing list](https://groups.google.com/forum/#!forum/elm-discuss).
diff --git a/de-de/git-de.html.markdown b/de-de/git-de.html.markdown
index 61f7bb67..0896f513 100644
--- a/de-de/git-de.html.markdown
+++ b/de-de/git-de.html.markdown
@@ -10,7 +10,7 @@ lang: de-de
Git ist eine verteilte Versions- und Quellcodeverwaltung.
-Es nimmt Schnappschüsse der Projekte, um mit diesen Schnappschüssen verschiedene Versionen unterscheiden und den Quellcode verwalten zu können.
+Es nimmt Schnappschüsse der Projekte auf, um mit diesen Schnappschüssen verschiedene Versionen unterscheiden und den Quellcode verwalten zu können.
Anmerkung des Übersetzers: Einige englische Begriffe wie *Repository*, *Commit* oder *Head* sind idiomatische Bestandteile im Umgang mit Git. Sie wurden nicht übersetzt.
@@ -20,7 +20,7 @@ Anmerkung des Übersetzers: Einige englische Begriffe wie *Repository*, *Commit*
Eine Versionsverwaltung erfasst die Änderungen einer Datei oder eines Verzeichnisses im Verlauf der Zeit.
-### Zentrale im Vergleich mit verteilter Versionverwaltung
+### Vergleich zwischen Zentraler und verteilter Versionverwaltung
* Zentrale Versionsverwaltung konzentriert sich auf das Synchronisieren, Verfolgen und Sichern von Dateien.
* Verteilte Versionsverwaltung konzentriert sich auf das Teilen der Änderungen. Jede Änderung hat eine eindeutige ID.
@@ -43,13 +43,13 @@ Eine Versionsverwaltung erfasst die Änderungen einer Datei oder eines Verzeichn
### Repository (Repo)
-Ein Satz von Dateien, Verzeichnisen, Historieneinträgen, Commits und Heads. Stell es dir wie eine Quellcode-Datenstruktur vor, unter anderem mit der Eigenschaft, dass alle *Elemente* dir Zugriff auf die Revisionshistorie geben.
+Ein Satz von Dateien, Verzeichnissen, Historieneinträgen, Commits und Heads. Stell es dir wie eine Quellcode-Datenstruktur vor, unter anderem mit der Eigenschaft, dass alle *Elemente* dir Zugriff auf die Revisionshistorie geben.
Ein Repository besteht in Git aus dem .git-Verzeichnis und dem Arbeitsverzeichnis.
### .git-Verzeichnis (Teil des Repositorys)
-Das .git-Verzeichnis enthält alle Einstellung, Logs, Branches, den HEAD und mehr.
+Das .git-Verzeichnis enthält alle Einstellungen, Logs, Branches, den HEAD und mehr.
[Ausführliche Übersicht](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
### Arbeitsverzeichnis (Teil des Repositorys)
@@ -66,7 +66,7 @@ Ein Commit ist ein Schnappschuss von Änderungen in deinem Arbeitsverzeichnis. W
### Branch
-Ein Branch, ein Ast oder Zweig, ist im Kern ein Pointer auf den letzten Commit, den du gemacht hast. Während des Commits wird der Pointer automatisch auf Stand gebracht und zeigt dann auf den neuen letzten Commit.
+Ein Branch, ein Ast oder Zweig, ist im Kern ein Pointer auf den letzten Commit, den du gemacht hast. Während des Commits wird der Pointer automatisch auf diesen Stand gebracht und zeigt dann auf den neuen letzten Commit.
### HEAD und head (Teil des .git-Verzeichnisses)
@@ -205,11 +205,17 @@ Speichert die aktuellen Inhalte des Index in einen neuen *Commit*. Dieser Commit
```bash
# Commit mit Beschreibung erstellen.
$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
+
+# Alle veränderten oder gelöschten Dateien außer neue Dateien werden gestaged und dann wird ein Commit erstellt.
+$ git commit -a -m "Modified foo.php and removed bar.php"
+
+# Ändert den letzten Commit (der letzte Commit wird mit einem neuen Commit ersetzt)
+$ git commit --amend -m "Correct message"
```
### diff
-Zeigt die Unterschiede zwischen Dateien von Arbeitsverzeichnisse, dem Index und Commits an.
+Zeigt die Unterschiede zwischen Dateien vom Arbeitsverzeichnis, dem Index und Commits an.
```bash
# Unterschiede zwischen deinem Arbeitsverzeichnis und dem Index anzeigen
@@ -324,7 +330,7 @@ $ git push origin master
### rebase (mit Vorsicht einsetzen)
-Nimm alle Änderungen, die in einem Branch durch Commits vorgenommen wurden, und übertrage sie auf einen anderen Branch. Achtung: Führe keinen Rebase von Commits durch, die auf ein öffentliches Repo gepusht wurden.
+Nimm alle Änderungen, die in einem Branch durch Commits vorgenommen wurden, und übertrage sie auf einen anderen Branch. Achtung: Führe keinen Rebase von Commits durch, die auf ein öffentliches Repo gepusht wurden!
```bash
# Rebase "experimentBranch" in den "master"-Branch
diff --git a/de-de/go-de.html.markdown b/de-de/go-de.html.markdown
index 817cb4ae..9409e181 100644
--- a/de-de/go-de.html.markdown
+++ b/de-de/go-de.html.markdown
@@ -94,7 +94,7 @@ Zeilenumbrüche beinhalten.` // Selber Zeichenketten-Typ
// Arrays haben bei Kompile-Zeit festgelegte Größen
var a4 [4]int // Ein Array mit 4 ints, alle mit Initialwert 0
- a3 := [...]int{3, 1, 5} // Ein Array mit 4 ints, Initialwerte wie angezeigt
+ a3 := [...]int{3, 1, 5} // Ein Array mit 3 ints, Initialwerte wie angezeigt
// "slices" haben eine dynamische Größe. Arrays und Slices haben beide ihre
// Vorzüge, aber slices werden viel häufiger verwendet
diff --git a/de-de/hq9+-de.html.markdown b/de-de/hq9+-de.html.markdown
new file mode 100644
index 00000000..841de5bb
--- /dev/null
+++ b/de-de/hq9+-de.html.markdown
@@ -0,0 +1,43 @@
+---
+language: HQ9+
+filename: hq9+-de.html
+contributors:
+ - ["Alexey Nazaroff", "https://github.com/rogaven"]
+translators:
+ - ["Dennis Keller", "https://github.com/denniskeller"]
+lang: de-de
+---
+
+HQ9+ ist eine Parodie auf esoterische Programmiersprachen und wurde von Cliff Biffle kreiert.
+Die Sprache hat nur vier Befehle und ist nicht Turing-vollständig.
+
+```
+Es gibt nur vier Befehle, die durch die folgenden vier Zeichen dargestellt werden
+H: druckt "Hello, world!"
+Q: druckt den Quellcode des Programms (ein Quine)
+9: druckt den Liedtext von "99 Bottles of Beer"
++: erhöhe den Akkumulator um Eins (Der Wert des Akkumulators kann nicht gelesen werden)
+Jedes andere Zeichen wird ignoriert.
+
+Ok. Lass uns ein Programm schreiben:
+ HQ
+
+Ergebnis:
+ Hello world!
+ HQ
+
+HQ9+ ist zwar sehr simpel, es erlaubt aber dir Sachen zu machen, die in
+anderen Sprachen sehr schwierig sind. Zum Beispiel druckt das folgende Programm
+drei Mal Kopien von sich selbst auf den Bildschirm:
+ QQQ
+Dies druckt:
+ QQQ
+ QQQ
+ QQQ
+```
+
+Und das ist alles. Es gibt sehr viele Interpreter für HQ9+.
+Unten findest du einen von ihnen.
+
++ [One of online interpreters](https://almnet.de/esolang/hq9plus.php)
++ [HQ9+ official website](http://cliffle.com/esoterica/hq9plus.html)
diff --git a/de-de/html-de.html.markdown b/de-de/html-de.html.markdown
index 2ee18129..8b5597e7 100644
--- a/de-de/html-de.html.markdown
+++ b/de-de/html-de.html.markdown
@@ -9,7 +9,7 @@ lang: de-de
---
HTML steht für HyperText Markup Language (Hypertext-Auszeichnungssprache).
-Sie ist eine Sprache, um Seiten für das World Wide Web zu schreiben..
+Sie ist eine Sprache, um Seiten für das World Wide Web zu schreiben.
Es ist eine Auszeichnugssprache, die es uns ermöglicht Webseiten mithilfe des Codes zu schreiben, der kennzeichnet wie Text und Daten angezeigt werden sollen. Eigentlich sind HTML Dateien nur einfache Textdateien.
Was sind das für Auszeichnungen? Es ist eine Methode, um die Daten der Website zu organisieren mithilfe von Start- und Endtags.
Diese Auszeichnung dient dazu dem Text Bedeutung zu geben, welchen sie umschließt.
@@ -50,10 +50,10 @@ Dieser Artikel ist bedacht darauf, nur HTML Syntax und nützliche Tipps zu geben
<!-- Danach startet sie mit einem Öffnungtag <html>. -->
<html>
-<!-- Dieser wird am Ende der Datei mit</html> geschlossen. -->
+<!-- Dieser wird am Ende der Datei mit </html> geschlossen. -->
</html>
-<!-- Nichts sollte nach diesen finalen Tag erscheinen. -->
+<!-- Nichts sollte nach diesem finalen Tag erscheinen. -->
<!-- Dazwischen (Zwischen dem Öffnungs- und Schließungstag <html></html>) finden wir: -->
@@ -65,13 +65,13 @@ Dieser Artikel ist bedacht darauf, nur HTML Syntax und nützliche Tipps zu geben
</head>
<!-- Nach dem <head> Bereich findet sich der <body> Tag -->
-<!-- Bis zu diesen Punkt wird nichts im Browerfenster angezeigt. -->
-<!-- Wir müssen den Body mit dem Inhalt füllen der angezeigt werden soll. -->
+<!-- Bis zu diesem Punkt wird nichts im Browerfenster angezeigt. -->
+<!-- Wir müssen den Body mit dem Inhalt füllen, der angezeigt werden soll. -->
<body>
<h1>Hallo, Welt!</h1> <!-- Der h1 Tag erstellt einen Titel. -->
<!-- Es gibt auch Untertitel für <h1> von den wichtigsten <h2> zu den Unwichtigsten (h6). -->
- <a href = "http://codepen.io/anon/pen/xwjLbZ">Komm, schaue was das zeigt</a> <!-- Eine URL wird zum Hyperlink, wenn es das Attribut href="" -->
+ <a href = "http://codepen.io/anon/pen/xwjLbZ">Komm, schaue was das zeigt</a> <!-- Eine URL wird zum Hyperlink, wenn es das Attribut href="" hat -->
<p>Das ist ein Absatz.</p> <!-- Der Tag <p> lässt uns Text auf die HTML Seite hinzufügen. -->
<p>Das ist ein anderer Absatz.</p>
<ul> <!-- Der <ul> Tag erstellt eine Aufzählungsliste. -->
@@ -93,12 +93,12 @@ Dieser Artikel ist bedacht darauf, nur HTML Syntax und nützliche Tipps zu geben
<!-- Es ist ebenso möglich eine Tabelle zu erstellen. -->
<table> <!-- Wir öffnen ein <table> Element. -->
- <tr> <!-- <tr> erlaubt es uns Reihe zu erstellen. -->
- <th>Erster Tabellenkopf</th> <!-- <th> erlaubt es uns der Tabelle einen Titel zu geben. -->
+ <tr> <!-- <tr> erlaubt es uns, Reihen zu erstellen. -->
+ <th>Erster Tabellenkopf</th> <!-- <th> erlaubt es uns, der Tabelle einen Titel zu geben. -->
<th>Zweiter Tabllenkopf</th>
</tr>
<tr>
- <td>Erste Zeile, erste Spalte</td> <!-- <td> erlaubt es eine Tabellenzelle zu erstellen. -->
+ <td>Erste Zeile, erste Spalte</td> <!-- <td> erlaubt es, eine Tabellenzelle zu erstellen. -->
<td>Erste Zeile, zweite Spalte</td>
</tr>
<tr>
@@ -111,7 +111,7 @@ Dieser Artikel ist bedacht darauf, nur HTML Syntax und nützliche Tipps zu geben
## Verwendung
-HTML Dateien enden mit `.html`.
+HTML Dateien enden mit `.html` oder mit `.htm`. Der Mime Typ ist meist `text/html`.
## Um mehr zu lernen
diff --git a/de-de/java-de.html.markdown b/de-de/java-de.html.markdown
index 001c6888..e52087ec 100644
--- a/de-de/java-de.html.markdown
+++ b/de-de/java-de.html.markdown
@@ -1,6 +1,6 @@
---
language: java
-filename: LearnJavaDe.java
+filename: LearnJavaDe-de.java
contributors:
- ["Jake Prather", "http://github.com/JakeHP"]
- ["Jakukyo Friel", "http://weakish.github.io"]
@@ -13,7 +13,7 @@ lang: de-de
Java ist eine Programmiersprache für vielfältige Aufgaben. Sie ist imperative und objektorientiert.
Oftmals wird sie für Desktop- Webapplikationen sowie als Programmiersprache im Betriebssystem Android verwendet.
-[Weitere Informationen \(Englisch\](http://docs.oracle.com/javase/tutorial/java/)
+[Weitere Informationen \(Englisch\)](http://docs.oracle.com/javase/tutorial/java/)
```java
// Einzeilige Kommentare starten mit //
@@ -477,7 +477,7 @@ Für tiefergreifende Fragen ist Google der beste Startpunkt.
* [Generics](http://docs.oracle.com/javase/tutorial/java/generics/index.html)
-* [Java Code Conventions](http://www.oracle.com/technetwork/java/codeconv-138413.html)
+* [Java Code Conventions](https://www.oracle.com/technetwork/java/codeconventions-150003.pdf)
**Online Tutorials**
diff --git a/de-de/javascript-de.html.markdown b/de-de/javascript-de.html.markdown
index f3917506..f817ee9f 100644
--- a/de-de/javascript-de.html.markdown
+++ b/de-de/javascript-de.html.markdown
@@ -1,7 +1,7 @@
---
language: javascript
contributors:
- - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Leigh Brenecki", "https://leigh.net.au"]
translators:
- ["ggb", "http://www.ideen-und-soehne.de"]
filename: learnjavascript-de.js
@@ -13,7 +13,7 @@ JavaScript wurde im Jahr 1995 von Brendan Eich bei Netscape entwickelt. Ursprün
Dabei ist JavaScript inzwischen nicht mehr auf Browser beschränkt: Node.js, ein Projekt, das eine eigene Laufzeitumgebung auf Grundlage von Google Chromes V8 mitbringt, wird derzeit immer populärer.
-Feedback ist herzlich Willkommen! Der ursprüngliche Autor ist unter [@adambrenecki](https://twitter.com/adambrenecki) oder [adam@brenecki.id.au](mailto:adam@brenecki.id.au) zu erreichen. Der Übersetzer unter [gregorbg@web.de](mailto:gregorbg@web.de).
+Feedback ist herzlich Willkommen! Der ursprüngliche Autor ist unter [@excitedleigh](https://twitter.com/excitedleigh) oder [l@leigh.net.au](mailto:l@leigh.net.au) zu erreichen. Der Übersetzer unter [gregorbg@web.de](mailto:gregorbg@web.de).
```js
// Kommentare werden wie in C gesetzt: Einzeilige Kommentare starten mit zwei
diff --git a/de-de/latex-de.html.markdown b/de-de/latex-de.html.markdown
index ee9c6e3e..8a952b15 100644
--- a/de-de/latex-de.html.markdown
+++ b/de-de/latex-de.html.markdown
@@ -39,13 +39,13 @@ filename: latex-de.tex
% Dieses Kommando kann man später benutzen.
\newcommand{\comment}[1]{}
-% Es können durchaus noch weitere Optione für das Dokument gesetzt werden!
+% Es können durchaus noch weitere Optionen für das Dokument gesetzt werden!
\author{Chaitanya Krishna Ande, Colton Kohnke \& Sricharan Chiruvolu}
\date{\today}
\title{Learn \LaTeX\ in Y Minutes!}
% Nun kann's losgehen mit unserem Dokument.
-% Alles vor dieser Zeile wird die Preamble genannt.
+% Alles vor dieser Zeile wird die Präambel genannt.
\begin{document}
\comment{
@@ -62,7 +62,7 @@ filename: latex-de.tex
% Inhalt erscheinen.
% Dieser Befehl ist in den Dokumentenklassen article und report verfügbar.
\begin{abstract}
- \LaTeX -Documentation geschrieben in \LaTeX ! Wie ungewöhnlich und garantiert nicht meine Idee!
+ \LaTeX -Dokumentation geschrieben in \LaTeX ! Wie ungewöhnlich und garantiert nicht meine Idee!
\end{abstract}
% Section Befehle sind intuitiv.
@@ -113,7 +113,7 @@ anderen Wissenschaften. Und deswegen müssen wir in der Lage sein, spezielle
Symbole zu unserem Paper hinzuzufügen! \\
Mathe kennt sehr viele Symbole, viel mehr als auf einer Tastatur zu finden sind;
-Symbole für Mengen und relationen, Pfeile, Operatoren und Griechische Buchstaben,
+Symbole für Mengen und Relationen, Pfeile, Operatoren und Griechische Buchstaben,
um nur ein paar zu nennen.\\
Mengen und Relationen spielen eine sehr wichtige Rolle in vielen mathematischen
diff --git a/de-de/make-de.html.markdown b/de-de/make-de.html.markdown
index 22c14a69..1bae332c 100644
--- a/de-de/make-de.html.markdown
+++ b/de-de/make-de.html.markdown
@@ -1,7 +1,9 @@
---
-language: make
+category: tool
+tool: make
contributors:
- ["Robert Steed", "https://github.com/robochat"]
+ - ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
translators:
- ["Martin Schimandl", "https://github.com/Git-Jiro"]
filename: Makefile-de
@@ -9,14 +11,14 @@ lang: de-de
---
Eine Makefile definiert einen Graphen von Regeln um ein Ziel (oder Ziele)
-zu erzeugen. Es dient dazu die geringste Menge an Arbeit zu verrichten um
-ein Ziel in einklang mit dem Quellcode zu bringen. Make wurde berühmterweise
+zu erzeugen. Es dient dazu, die geringste Menge an Arbeit zu verrichten um
+ein Ziel in Einklang mit dem Quellcode zu bringen. Make wurde berühmterweise
von Stuart Feldman 1976 übers Wochenende geschrieben. Make ist noch immer
-sehr verbreitet (vorallem im Unix umfeld) obwohl es bereits sehr viel
+sehr verbreitet (vorallem im Unix Umfeld) obwohl es bereits sehr viel
Konkurrenz und Kritik zu Make gibt.
-Es gibt eine vielzahl an Varianten von Make, dieser Artikel beschäftig sich
-mit der Version GNU Make. Diese Version ist standard auf Linux.
+Es gibt eine Vielzahl an Varianten von Make, dieser Artikel beschäftigt sich
+mit der Version GNU Make. Diese Version ist Standard auf Linux.
```make
@@ -42,14 +44,15 @@ file0.txt:
# die erste Regel ist die Standard-Regel.
-# Diese Regel wird nur abgearbeitet wenn file0.txt aktueller als file1.txt ist.
+# Diese Regel wird nur abgearbeitet, wenn file0.txt aktueller als file1.txt ist.
file1.txt: file0.txt
cat file0.txt > file1.txt
# Verwende die selben Quoting-Regeln wie die Shell
@cat file0.txt >> file1.txt
# @ unterdrückt die Ausgabe des Befehls an stdout.
-@echo 'hello'
- # - bedeutet das Make die Abarbeitung fortsetzt auch wenn Fehler passieren.
+ # - bedeutet, dass Make die Abarbeitung fortsetzt auch wenn Fehler
+ # passieren.
# Versuche `make file1.txt` auf der Kommandozeile.
# Eine Regel kann mehrere Ziele und mehrere Voraussetzungen haben.
@@ -57,16 +60,16 @@ file2.txt file3.txt: file0.txt file1.txt
touch file2.txt
touch file3.txt
-# Make wird sich beschweren wenn es mehrere Rezepte für die gleiche Regel gibt.
-# Leere Rezepte zählen nicht und können dazu verwendet werden weitere
+# Make wird sich beschweren, wenn es mehrere Rezepte für die gleiche Regel gibt.
+# Leere Rezepte zählen nicht und können dazu verwendet werden weitere
# Voraussetzungen hinzuzufügen.
#-----------------------------------------------------------------------
# Phony-Ziele
#-----------------------------------------------------------------------
-# Ein Phony-Ziel ist ein Ziel das keine Datei ist.
-# Es wird nie aktuell sein, daher wird Make immer versuchen es abzuarbeiten
+# Ein Phony-Ziel ist ein Ziel, das keine Datei ist.
+# Es wird nie aktuell sein, daher wird Make immer versuchen, es abzuarbeiten
all: maker process
# Es ist erlaubt Dinge ausserhalb der Reihenfolge zu deklarieren.
@@ -87,14 +90,14 @@ ex0.txt ex1.txt: maker
# Automatische Variablen & Wildcards
#-----------------------------------------------------------------------
-process: file*.txt # Eine Wildcard um Dateinamen zu Vergleichen
+process: file*.txt # Eine Wildcard um Dateinamen zu vergleichen
@echo $^ # $^ ist eine Variable die eine Liste aller
# Voraussetzungen enthält.
@echo $@ # Namen des Ziels ausgeben.
#(Bei mehreren Ziel-Regeln enthält $@ den Verursacher der Abarbeitung
#der Regel.)
@echo $< # Die erste Voraussetzung aus der Liste
- @echo $? # Nur die Voraussetzungen die nicht aktuell sind.
+ @echo $? # Nur die Voraussetzungen, die nicht aktuell sind.
@echo $+ # Alle Voraussetzungen inklusive Duplikate (nicht wie Üblich)
#@echo $| # Alle 'order only' Voraussetzungen
@@ -112,20 +115,20 @@ process: ex1.txt file0.txt
%.png: %.svg
inkscape --export-png $^
-# Muster-Vergleichs-Regeln werden nur abgearbeitet wenn make entscheidet das Ziel zu
-# erzeugen
+# Muster-Vergleichs-Regeln werden nur abgearbeitet, wenn make entscheidet das
+# Ziel zu erzeugen
# Verzeichnis-Pfade werden normalerweise bei Muster-Vergleichs-Regeln ignoriert.
# Aber make wird versuchen die am besten passende Regel zu verwenden.
small/%.png: %.svg
inkscape --export-png --export-dpi 30 $^
-# Make wird die letzte Version einer Muster-Vergleichs-Regel verwenden die es
+# Make wird die letzte Version einer Muster-Vergleichs-Regel verwenden, die es
# findet.
%.png: %.svg
@echo this rule is chosen
-# Allerdings wird make die erste Muster-Vergleicher-Regel verwenden die das
+# Allerdings wird make die erste Muster-Vergleicher-Regel verwenden, die das
# Ziel erzeugen kann.
%.png: %.ps
@echo this rule is not chosen if *.svg and *.ps are both present
@@ -169,7 +172,7 @@ name4 ?= Jean
# nicht gibt.
override name5 = David
-# Verhindert das Kommando-Zeilen Argumente diese Variable ändern können.
+# Verhindert, dass Kommando-Zeilen Argumente diese Variable ändern können.
name4 +=grey
# Werte an eine Variable anhängen (inkludiert Leerzeichen).
@@ -177,14 +180,14 @@ name4 +=grey
# Muster-Spezifische Variablen Werte (GNU Erweiterung).
echo: name2 = Sara # Wahr innerhalb der passenden Regel und auch innerhalb
# rekursiver Voraussetzungen (ausser wenn es den Graphen zerstören
- # kann wenn es zu kompilizert wird!)
+ # kann, wenn es zu kompilizert wird!)
-# Ein paar Variablen die von Make automatisch definiert werden.
+# Ein paar Variablen, die von Make automatisch definiert werden.
echo_inbuilt:
echo $(CC)
- echo ${CXX)}
+ echo ${CXX}
echo $(FC)
- echo ${CFLAGS)}
+ echo ${CFLAGS}
echo $(CPPFLAGS)
echo ${CXXFLAGS}
echo $(LDFLAGS)
@@ -194,7 +197,7 @@ echo_inbuilt:
# Variablen 2
#-----------------------------------------------------------------------
-# Der erste Typ von Variablen wird bei jeder verwendung ausgewertet.
+# Der erste Typ von Variablen wird bei jeder Verwendung ausgewertet.
# Das kann aufwendig sein, daher exisitert ein zweiter Typ von Variablen.
# Diese werden nur einmal ausgewertet. (Das ist eine GNU make Erweiterung)
@@ -213,7 +216,7 @@ var4 ::= good night
# Funktionen
#-----------------------------------------------------------------------
-# Make verfügt über eine vielzahl von Funktionen.
+# Make verfügt über eine Vielzahl von Funktionen.
sourcefiles = $(wildcard *.c */*.c)
objectfiles = $(patsubst %.c,%.o,$(sourcefiles))
diff --git a/de-de/markdown-de.html.markdown b/de-de/markdown-de.html.markdown
index 2c838660..729e883c 100644
--- a/de-de/markdown-de.html.markdown
+++ b/de-de/markdown-de.html.markdown
@@ -14,7 +14,7 @@ Syntax, in der sich Dokumente leicht schreiben *und* lesen lassen. Außerdem
sollte Markdown sich leicht nach HTML (und in andere Formate) konvertieren
lassen.
-```markdown
+```md
<!-- Markdown ist eine Obermenge von HTML - jede valide HTML-Datei ist also
automatisch valides Markdown - was heisst dass wir jedes HTML-Element (also auch
Kommentare) in Markdown benutzen können, ohne dass der Parser sie verändert.
@@ -144,7 +144,7 @@ indem du eine Zeile mit vier Leerzeichen oder einem Tabulator einrückst -->
puts item
end
-<!-- Innerhalb normalen Texts kannst du Code mit Backticks ` auszeichnen -->
+<!-- Innerhalb normalen Texts kannst du Code mit Backticks \` auszeichnen -->
Hermann hatte nicht die leiseste Ahnung, was dieses `go_to()` bedeuten könnte!
@@ -253,4 +253,4 @@ Ganz schön hässlich | vielleicht doch lieber | wieder aufhören
Mehr Informationen gibt es in [John Gruber's offiziellem Blog-Post](http://daringfireball.net/projects/markdown/syntax)
und bei Adam Pritchards [grandiosem Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).
-Infos zu GitHub Flavored Markdown [gibt es hier](https://help.github.com/articles/github-flavored-markdown). \ No newline at end of file
+Infos zu GitHub Flavored Markdown [gibt es hier](https://help.github.com/articles/github-flavored-markdown).
diff --git a/de-de/nix-de.html.markdown b/de-de/nix-de.html.markdown
new file mode 100644
index 00000000..ea02e81d
--- /dev/null
+++ b/de-de/nix-de.html.markdown
@@ -0,0 +1,358 @@
+---
+language: nix
+filename: learnnix-de.nix
+contributors:
+ - ["Chris Martin", "http://chris-martin.org/"]
+translators:
+ - ["Dennis Keller", "https://github.com/denniskeller"]
+lang: de-de
+---
+
+Nix ist eine simple funktionale Programmiersprache, die für den
+[Nix package manager](https://nixos.org/nix/) und
+[NixOS](https://nixos.org/) entwickelt wurde.
+
+Du kannst Nix Ausdrücke evaluieren mithilfe von
+[nix-instantiate](https://nixos.org/nix/manual/#sec-nix-instantiate)
+oder [`nix-repl`](https://github.com/edolstra/nix-repl).
+
+```
+with builtins; [
+
+ # Kommentare
+ #=========================================
+
+ # Inline Kommentare sehen so aus.
+
+ /* Multizeilen Kommentare
+ sehen so aus. */
+
+
+ # Booleans
+ #=========================================
+
+ (true && false) # Und
+ #=> false
+
+ (true || false) # Oder
+ #=> true
+
+ (if 3 < 4 then "a" else "b") # Bedingungen
+ #=> "a"
+
+
+ # Integers
+ #=========================================
+
+ # Integers sind die einzigen numerischen Typen.
+
+ 1 0 42 (-3) # Einige integers
+
+ (4 + 6 + 12 - 2) # Addition
+ #=> 20
+
+ (7 / 2) # Division
+ #=> 3
+
+
+ # Strings
+ #=========================================
+
+ "String Literale sind in Anführungszeichen."
+
+ "
+ String Literale können mehrere
+ Zeilen umspannen.
+ "
+
+ ''
+ Dies wird als Literal mit eingerückten String bezeichnet.
+ Es entfernt intelligent führende Leerzeichen.
+ ''
+
+ ''
+ a
+ b
+ ''
+ #=> "a\n b"
+
+ ("ab" + "cd") # String Konkatenation
+ #=> "abcd"
+
+ # Mit Antiquotation kannst du Werte in Strings einbetten.
+ ("Dein Homeverzeichnis ist ${getEnv "HOME"}")
+ #=> "Dein Homeverzeichnis ist /home/alice"
+
+
+ # Paths
+ #=========================================
+
+ # Nix besitzt einen primitiven Datentyp für Pfade
+ /tmp/tutorials/learn.nix
+
+ # Ein relativer Pfad wird beim Parsing zu einem absoluten Pfad aufgelöst,
+ # relativ zu der Datei in der es auftritt.
+ tutorials/learn.nix
+ #=> /the-base-path/tutorials/learn.nix
+
+ # Ein Pfad muss mindestens einen Schrägstrich enthalten. Ein Pfad für eine
+ # Datei im selben Verzeichnis benötigt ein ./ Präfix.
+ ./learn.nix
+ #=> /the-base-path/learn.nix
+
+ # Der / Operator muss von Leerraum umgeben sein wenn du dividieren möchtest.
+ 7/2 # Das ist ein Pfadliteral
+ (7 / 2) # Das ist ein Integerliteral
+
+
+ # Importe
+ #=========================================
+
+ # Eine nix Datei besitzt einen einzelnen top-level Ausdruck mit keinen freien Variablen.
+ # Ein Import-Ausdruck wird zum Wert der Datei, die importiert wird, ausgewertet.
+ (import /tmp/foo.nix)
+
+ # Importe können ebenso mit Strings spezifiziert werden.
+ (import "/tmp/foo.nix")
+
+ # Import Pfade müssen absolut sein. Pfadliterale
+ # sind automatisch aufgelöst, das ist ein Ordnung.
+ (import ./foo.nix)
+
+ # Jedoch passiert dies nicht mit Strings.
+ (import "./foo.nix")
+ #=> error: string ‘foo.nix’ doesn't represent an absolute path
+
+
+ # Let
+ #=========================================
+
+ # `let` Blöcke erlauben es uns Werte zu Variablen zu binden.
+ (let x = "a"; in
+ x + x + x)
+ #=> "aaa"
+
+ # Bindungen können auf sich gegenseitig verweisen. Die Reihenfolge spielt
+ # keine Rolle.
+ (let y = x + "b";
+ x = "a"; in
+ y + "c")
+ #=> "abc"
+
+ # Innere Bindungen überschatten Äußere.
+ (let a = 1; in
+ let a = 2; in
+ a)
+ #=> 2
+
+
+ # Funktionen
+ #=========================================
+
+ (n: n + 1) # Funktion, die 1 addiert
+
+ ((n: n + 1) 5) # Dieselbe Funktion angewendet auf 5.
+ #=> 6
+
+ # Es gibt keine spezielle Syntax für benannte Funktionen, aber sie
+ # können mit `let` Blöcken, wie jeder andere Wert auch, gebunden werden.
+ (let succ = (n: n + 1); in succ 5)
+ #=> 6
+
+ # Eine Funktion hat genau ein Argument.
+ # Mehrere Argumente können erreicht werden mithilfe von Currying.
+ ((x: y: x + "-" + y) "a" "b")
+ #=> "a-b"
+
+ # Benannte Funktionsargumente gibt es auch. Diese werden wir einführen, nachdem wir uns Sets
+ # angeschaut haben.
+
+ # Listen
+ #=========================================
+
+ # Listen werden durch eckige Klammern gekennzeichnet.
+
+ (length [1 2 3 "x"])
+ #=> 4
+
+ ([1 2 3] ++ [4 5])
+ #=> [1 2 3 4 5]
+
+ (concatLists [[1 2] [3 4] [5]])
+ #=> [1 2 3 4 5]
+
+ (head [1 2 3])
+ #=> 1
+ (tail [1 2 3])
+ #=> [2 3]
+
+ (elemAt ["a" "b" "c" "d"] 2)
+ #=> "c"
+
+ (elem 2 [1 2 3])
+ #=> true
+ (elem 5 [1 2 3])
+ #=> false
+
+ (filter (n: n < 3) [1 2 3 4])
+ #=> [ 1 2 ]
+
+
+ # Sets
+ #=========================================
+
+ # Ein "Set" ist eine ungeordnete Zuordnung mit Stringschlüsseln.
+ { foo = [1 2]; bar = "x"; }
+
+ # Der . Operator nimmt einen Wert aus dem Set.
+ { a = 1; b = 2; }.a
+ #=> 1
+
+ # Der ? Operator testet, ob der Schlüssel in dem Set vorhanden ist.
+ ({ a = 1; b = 2; } ? a)
+ #=> true
+ ({ a = 1; b = 2; } ? c)
+ #=> false
+
+ # Der // Operator mergt zwei Sets.
+ ({ a = 1; } // { b = 2; })
+ #=> { a = 1; b = 2; }
+
+ # Werte auf der rechten Seite überschreiben die Werte auf der linken Seite.
+ ({ a = 1; b = 2; } // { a = 3; c = 4; })
+ #=> { a = 3; b = 2; c = 4; }
+
+ # Das Schlüsselwort rec bezeichenet ein "rekursives Set", in dem sich Attribute
+ # aufeinander beziehen können.
+ (let a = 1; in { a = 2; b = a; }.b)
+ #=> 1
+ (let a = 1; in rec { a = 2; b = a; }.b)
+ #=> 2
+
+ # Verschachtelte Sets können stückweise definiert werden.
+ {
+ a.b = 1;
+ a.c.d = 2;
+ a.c.e = 3;
+ }.a.c
+ #=> { d = 2; e = 3; }
+
+ # Die Nachkommen eines Attributs können in diesem Feld nicht zugeordnet werden, wenn
+ # das Attribut selbst nicht zugewiesen wurde.
+ {
+ a = { b = 1; };
+ a.c = 2;
+ }
+ #=> error: attribute ‘a’ already defined
+
+
+ # With
+ #=========================================
+
+ # Der Körper eines Sets Blocks wird mit der Zuordnung eines Satzes an die Variablen gebunden.
+ (with { a = 1; b = 2; };
+ a + b)
+ # => 3
+
+ # Innere Bindungen überschatten äußere Bindungen.
+ (with { a = 1; b = 2; };
+ (with { a = 5; };
+ a + b))
+ #=> 7
+
+ # Die erste Linie diese Tutorials startet mit "with builtins;",
+ # weil builtins ein Set mit allen eingebauten
+ # Funktionen (length, head, tail, filter, etc.) umfasst.
+ # Das erspart uns beispielsweise "builtins.length" zu schreiben,
+ # anstatt nur "length".
+
+
+ # Set patterns
+ #=========================================
+
+ # Sets sind nützlich, wenn du mehrere Werte einer Funktion
+ # übergeben musst.
+ (args: args.x + "-" + args.y) { x = "a"; y = "b"; }
+ #=> "a-b"
+
+ # Dies kann mit Hilfe von Set patterns deutlicher geschrieben werden.
+ ({x, y}: x + "-" + y) { x = "a"; y = "b"; }
+ #=> "a-b"
+
+ # Standardmäßig schlägt das Muster bei Sets mit zusätzlichen Schlüsseln fehl.
+ ({x, y}: x + "-" + y) { x = "a"; y = "b"; z = "c"; }
+ #=> error: anonymous function called with unexpected argument ‘z’
+
+ # Durch Hinzufügen von ", ..." können zusätzliche Schlüssel ignoriert werden.
+ ({x, y, ...}: x + "-" + y) { x = "a"; y = "b"; z = "c"; }
+ #=> "a-b"
+
+
+ # Errors
+ #=========================================
+
+ # `throw` bewirkt, dass die Auswertung mit einer Fehlermeldung abgebrochen wird.
+ (2 + (throw "foo"))
+ #=> error: foo
+
+ # `tryEval` fängt geworfene Fehler.
+ (tryEval 42)
+ #=> { success = true; value = 42; }
+ (tryEval (2 + (throw "foo")))
+ #=> { success = false; value = false; }
+
+ # `abort` ist ähnlich wie throw, aber es ist fatal. Es kann nicht gefangen werden.
+ (tryEval (abort "foo"))
+ #=> error: evaluation aborted with the following error message: ‘foo’
+
+ # `assert` evaluiert zu dem gegebenen Wert, wenn die Bedingung wahr ist, sonst
+ # löst es eine abfangbare Exception aus.
+ (assert 1 < 2; 42)
+ #=> 42
+ (assert 1 > 2; 42)
+ #=> error: assertion failed at (string):1:1
+ (tryEval (assert 1 > 2; 42))
+ #=> { success = false; value = false; }
+
+
+ # Impurity
+ #=========================================
+
+ # Da die Wiederholbarkeit von Builds für den Nix Packetmanager entscheidend ist,
+ # werden in der Nix Sprache reine funktionale Elemente betont. Es gibt aber ein paar
+ # unreine Elemente.
+ # Du kannst auf Umgebungsvariablen verweisen.
+ (getEnv "HOME")
+ #=> "/home/alice"
+
+ # Die trace Funktion wird zum Debugging verwendet. Sie gibt das erste Argument zu stderr aus
+ # und evaluiert das zweite Argument.
+ (trace 1 2)
+ #=> trace: 1
+ #=> 2
+
+ # Du kannst Dateien in den Nix Store schreiben. Obwohl unrein, kannst du dir relativ sicher sein,
+ # dass es sicher ist, da der Dateiname aus dem Hash des Inhalts abgeleitet wird.
+ # Du kannst Dateien von überall lesen. In diesem Beispiel schreiben wir Dateien in den Store
+ # und lesen wieder davon.
+ (let filename = toFile "foo.txt" "hello!"; in
+ [filename (builtins.readFile filename)])
+ #=> [ "/nix/store/ayh05aay2anx135prqp0cy34h891247x-foo.txt" "hello!" ]
+
+ # Außerdem können wir Dateien in den Nix Store herunterladen.
+ (fetchurl "https://example.com/package-1.2.3.tgz")
+ #=> "/nix/store/2drvlh8r57f19s9il42zg89rdr33m2rm-package-1.2.3.tgz"
+
+]
+```
+
+### Weitere Ressourcen
+
+* [Nix Manual - Nix expression language]
+ (https://nixos.org/nix/manual/#ch-expression-language)
+
+* [James Fisher - Nix by example - Part 1: The Nix expression language]
+ (https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55)
+
+* [Susan Potter - Nix Cookbook - Nix By Example]
+ (https://ops.functionalalgebra.com/nix-by-example/)
diff --git a/de-de/opencv-de.html.markdown b/de-de/opencv-de.html.markdown
new file mode 100644
index 00000000..223e6cd8
--- /dev/null
+++ b/de-de/opencv-de.html.markdown
@@ -0,0 +1,153 @@
+---
+category: tool
+tool: OpenCV
+filename: learnopencv-de.py
+contributors:
+ - ["Yogesh Ojha", "http://github.com/yogeshojha"]
+translators:
+ - ["Dennis Keller", "https://github.com/denniskeller"]
+lang: de-de
+---
+### Opencv
+
+OpenCV (Open Source Computer Vision) ist eine Bibliothek von Programmierfunktionen,
+die hauptsächlich auf maschinelles Sehen in Echtzeit ausgerichtet ist.
+Ursprünglich wurde OpenCV von Intel entwickelt. Später wurde es von von
+Willow Garage und dann Itseez (das später von Intel übernommen wurde) unterstützt.
+OpenCV unterstützt derzeit eine Vielzahl von Sprachen, wie C++, Python, Java uvm.
+
+#### Installation
+
+Bitte lese diese Artikel für die Installation von OpenCV auf deinen Computer.
+
+* Windows Installationsanleitung: [https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.html#install-opencv-python-in-windows]()
+* Mac Installationsanleitung (High Sierra): [https://medium.com/@nuwanprabhath/installing-opencv-in-macos-high-sierra-for-python-3-89c79f0a246a]()
+* Linux Installationsanleitung (Ubuntu 18.04): [https://www.pyimagesearch.com/2018/05/28/ubuntu-18-04-how-to-install-opencv]()
+
+### Hier werden wir uns auf die Pythonimplementierung von OpenCV konzentrieren.
+
+```python
+# Bild in OpenCV lesen
+import cv2
+img = cv2.imread('Katze.jpg')
+
+# Bild darstellen
+# Die imshow() Funktion wird verwendet um das Display darzustellen.
+cv2.imshow('Image',img)
+# Das erste Argument ist der Titel des Fensters und der zweite Parameter ist das Bild
+# Wenn du den Fehler Object Type None bekommst ist eventuell dein Bildpfad falsch.
+# Bitte überprüfe dann den Pfad des Bildes erneut.
+cv2.waitKey(0)
+# waitKey() ist eine Tastaturbindungsfunktion, sie nimmt Argumente in
+# Millisekunden an. Für GUI Ereignisse MUSST du die waitKey() Funktion verwenden.
+
+# Ein Bild schreiben
+cv2.imwrite('graueKatze.png',img)
+# Das erste Arkument ist der Dateiname und das Zweite ist das Bild
+
+# Konveriere das Bild zu Graustufen
+gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+
+# Videoaufnahme von der Webcam
+cap = cv2.VideoCapture(0)
+# 0 ist deine Kamera, wenn du mehrere Kameras hast musst du deren Id eingeben
+while(True):
+ # Erfassen von Einzelbildern
+ _, frame = cap.read()
+ cv2.imshow('Frame',frame)
+ # Wenn der Benutzer q drückt -> beenden
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+# Die Kamera muss wieder freigegeben werden
+cap.release()
+
+# Wiedergabe von Videos aus einer Datei
+cap = cv2.VideoCapture('film.mp4')
+while(cap.isOpened()):
+ _, frame = cap.read()
+ # Das Video in Graustufen abspielen
+ gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
+ cv2.imshow('frame',gray)
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+cap.release()
+
+# Zeichne eine Linie in OpenCV
+# cv2.line(img,(x,y),(x1,y1),(color->r,g,b->0 to 255),thickness)
+cv2.line(img,(0,0),(511,511),(255,0,0),5)
+
+# Zeichne ein Rechteck
+# cv2.rectangle(img,(x,y),(x1,y1),(color->r,g,b->0 to 255),thickness)
+# thickness = -1 wird zum Füllen des Rechtecks verwendet
+cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)
+
+# Zeichne ein Kreis
+cv2.circle(img,(xCenter,yCenter), radius, (color->r,g,b->0 to 255), thickness)
+cv2.circle(img,(200,90), 100, (0,0,255), -1)
+
+# Zeichne eine Ellipse
+cv2.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
+
+# Text auf Bildern hinzufügen
+cv2.putText(img,"Hello World!!!", (x,y), cv2.FONT_HERSHEY_SIMPLEX, 2, 255)
+
+# Bilder zusammenfüggen
+img1 = cv2.imread('Katze.png')
+img2 = cv2.imread('openCV.jpg')
+dst = cv2.addWeighted(img1,0.5,img2,0.5,0)
+
+# Schwellwertbild
+# Binäre Schwellenwerte
+_,thresImg = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
+# Anpassbare Schwellenwerte
+adapThres = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,2)
+
+# Weichzeichnung von einem Bild
+# Gausßscher Weichzeichner
+blur = cv2.GaussianBlur(img,(5,5),0)
+# Rangordnungsfilter
+medianBlur = cv2.medianBlur(img,5)
+
+# Canny-Algorithmus
+img = cv2.imread('Katze.jpg',0)
+edges = cv2.Canny(img,100,200)
+
+# Gesichtserkennung mit Haarkaskaden
+# Lade die Haarkaskaden von https://github.com/opencv/opencv/blob/master/data/haarcascades/ herunter
+import cv2
+import numpy as np
+face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
+eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
+
+img = cv2.imread('Mensch.jpg')
+gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+
+aces = face_cascade.detectMultiScale(gray, 1.3, 5)
+for (x,y,w,h) in faces:
+ cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
+ roi_gray = gray[y:y+h, x:x+w]
+ roi_color = img[y:y+h, x:x+w]
+ eyes = eye_cascade.detectMultiScale(roi_gray)
+ for (ex,ey,ew,eh) in eyes:
+ cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
+
+cv2.imshow('img',img)
+cv2.waitKey(0)
+
+cv2.destroyAllWindows()
+# destroyAllWindows() zerstört alle Fenster
+# Wenn du ein bestimmtes Fenter zerstören möchtest musst du den genauen Namen des
+# von dir erstellten Fensters übergeben.
+```
+
+### Weiterführende Literatur:
+* Lade Kaskade hier herunter [https://github.com/opencv/opencv/blob/master/data/haarcascades]()
+* OpenCV Zeichenfunktionen [https://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html]()
+* Eine aktuelle Sprachenreferenz kann hier gefunden werden [https://opencv.org]()
+* Zusätzliche Ressourcen können hier gefunden werden [https://en.wikipedia.org/wiki/OpenCV]()
+* Gute OpenCV Tutorials
+ * [https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html]()
+ * [https://realpython.com/python-opencv-color-spaces]()
+ * [https://pyimagesearch.com]()
+ * [https://www.learnopencv.com]()
+ * [https://docs.opencv.org/master/]()
diff --git a/de-de/paren-de.html.markdown b/de-de/paren-de.html.markdown
new file mode 100644
index 00000000..641e226e
--- /dev/null
+++ b/de-de/paren-de.html.markdown
@@ -0,0 +1,200 @@
+---
+
+language: Paren
+filename: learnparen-de.paren
+contributors:
+ - ["KIM Taegyoon", "https://github.com/kimtg"]
+ - ["Claudson Martins", "https://github.com/claudsonm"]
+translators:
+ - ["Dennis Keller", "https://github.com/denniskeller"]
+lang: de-de
+---
+
+[Paren](https://bitbucket.org/ktg/paren) ist ein Dialekt von Lisp.
+Es ist als eingebettete Sprache konzipiert.
+
+Manche Beispiele sind von <http://learnxinyminutes.com/docs/racket/>.
+
+```scheme
+;;; Kommentare
+# Kommentare
+
+;; Einzeilige Kommentare starten mit einem Semikolon oder einem Hashtag
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 1. Primitive Datentypen und Operatoren
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Zahlen
+123 ; int
+3.14 ; double
+6.02e+23 ; double
+(int 3.14) ; => 3 : int
+(double 123) ; => 123 : double
+
+;; Funktionsapplikationen werden so geschrieben: (f x y z ...)
+;; Dabei ist f eine Funktion und x, y, z sind die Operatoren.
+;; Wenn du eine Literalliste von Daten erstelllen möchtest,
+;; verwende (quote) um zu verhindern, dass sie ausgewertet zu werden.
+(quote (+ 1 2)) ; => (+ 1 2)
+;; Nun einige arithmetische Operationen
+(+ 1 1) ; => 2
+(- 8 1) ; => 7
+(* 10 2) ; => 20
+(^ 2 3) ; => 8
+(/ 5 2) ; => 2
+(% 5 2) ; => 1
+(/ 5.0 2) ; => 2.5
+
+;;; Wahrheitswerte
+true ; for Wahr
+false ; for Falsch
+(! true) ; => Falsch
+(&& true false (prn "doesn't get here")) ; => Falsch
+(|| false true (prn "doesn't get here")) ; => Wahr
+
+;;; Zeichen sind Ints.
+(char-at "A" 0) ; => 65
+(chr 65) ; => "A"
+
+;;; Zeichenketten sind ein Array von Zahlen mit fester Länge.
+"Hello, world!"
+"Benjamin \"Bugsy\" Siegel" ; Backslash ist ein Escape-Zeichen
+"Foo\tbar\r\n" ; beinhaltet C Escapes: \t \r \n
+
+;; Zeichenketten können auch verbunden werden!
+(strcat "Hello " "world!") ; => "Hello world!"
+
+;; Eine Zeichenketten kann als Liste von Zeichen behandelt werden
+(char-at "Apple" 0) ; => 65
+
+;; Drucken ist ziemlich einfach
+(pr "Ich bin" "Paren. ") (prn "Schön dich zu treffen!")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 2. Variablen
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Du kannst Variablen setzen indem du (set) verwedest
+;; eine Variable kann alle Zeichen besitzen außer: ();#"
+(set some-var 5) ; => 5
+some-var ; => 5
+
+;; Zugriff auf eine zuvor nicht zugewiesene Variable erzeugt eine Ausnahme
+; x ; => Unknown variable: x : nil
+
+;; Lokale Bindung: Verwende das Lambda Calculus! 'a' und 'b'
+;; sind nur zu '1' und '2' innerhalb von (fn ...) gebunden.
+((fn (a b) (+ a b)) 1 2) ; => 3
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. Sammlungen
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Listen
+
+;; Listen sind Vektrorartige Datenstrukturen. (Zufälliger Zugriff ist O(1).
+(cons 1 (cons 2 (cons 3 (list)))) ; => (1 2 3)
+;; 'list' ist ein komfortabler variadischer Konstruktor für Listen
+(list 1 2 3) ; => (1 2 3)
+;; und ein quote kann als literaler Listwert verwendet werden
+(quote (+ 1 2)) ; => (+ 1 2)
+
+;; Du kannst 'cons' verwenden um ein Element an den Anfang einer Liste hinzuzufügen.
+(cons 0 (list 1 2 3)) ; => (0 1 2 3)
+
+;; Listen sind ein sehr einfacher Typ, daher gibt es eine Vielzahl an Funktionen
+;; für Sie. Ein paar Beispiele:
+(map inc (list 1 2 3)) ; => (2 3 4)
+(filter (fn (x) (== 0 (% x 2))) (list 1 2 3 4)) ; => (2 4)
+(length (list 1 2 3 4)) ; => 4
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. Funktionen
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Verwende 'fn' um Funktionen zu erstellen.
+;; eine Funktion gibt immer den Wert ihres letzten Ausdrucks zurück
+(fn () "Hello World") ; => (fn () Hello World) : fn
+
+;; Verwende Klammern um alle Funktionen aufzurufen, inklusive Lambda Ausdrücke
+((fn () "Hello World")) ; => "Hello World"
+
+;; Zuweisung einer Funktion zu einer Variablen
+(set hello-world (fn () "Hello World"))
+(hello-world) ; => "Hello World"
+
+;; Du kannst dies mit syntaktischen Zucker für die Funktionsdefinition verkürzen:
+(defn hello-world2 () "Hello World")
+
+;; Die () von oben ist eine Liste von Argumente für die Funktion.
+(set hello
+ (fn (name)
+ (strcat "Hello " name)))
+(hello "Steve") ; => "Hello Steve"
+
+;; ... oder gleichwertig, unter Verwendung mit syntaktischen Zucker:
+(defn hello2 (name)
+ (strcat "Hello " name))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 4. Gleichheit
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Für Zahlen verwende '=='
+(== 3 3.0) ; => wahr
+(== 2 1) ; => falsch
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 5. Kontrollfluss
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Bedingungen
+
+(if true ; test Ausdruck
+ "this is true" ; then Ausdruck
+ "this is false") ; else Ausdruck
+; => "this is true"
+
+;;; Schleifen
+
+;; for Schleifen ist für Zahlen
+;; (for SYMBOL START ENDE SCHRITT AUSDRUCK ..)
+(for i 0 10 2 (pr i "")) ; => schreibt 0 2 4 6 8 10
+(for i 0.0 10 2.5 (pr i "")) ; => schreibt 0 2.5 5 7.5 10
+
+;; while Schleife
+((fn (i)
+ (while (< i 10)
+ (pr i)
+ (++ i))) 0) ; => schreibt 0123456789
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 6. Mutation
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Verwende 'set' um einer Variablen oder einer Stelle einen neuen Wert zuzuweisen.
+(set n 5) ; => 5
+(set n (inc n)) ; => 6
+n ; => 6
+(set a (list 1 2)) ; => (1 2)
+(set (nth 0 a) 3) ; => 3
+a ; => (3 2)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 7. Makros
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Makros erlauben es dir die Syntax der Sprache zu erweitern.
+;; Parens Makros sind einfach.
+;; Tatsächlich ist (defn) ein Makro.
+(defmacro setfn (name ...) (set name (fn ...)))
+(defmacro defn (name ...) (def name (fn ...)))
+
+;; Lass uns eine Infix Notation hinzufügen
+;; Let's add an infix notation
+(defmacro infix (a op ...) (op a ...))
+(infix 1 + 2 (infix 3 * 4)) ; => 15
+
+;; Makros sind nicht hygenisch, Du kannst bestehende Variablen überschreiben!
+;; Sie sind Codetransformationenen.
+```
diff --git a/de-de/perl-de.html.markdown b/de-de/perl-de.html.markdown
index fd8fb3c4..13c00b01 100644
--- a/de-de/perl-de.html.markdown
+++ b/de-de/perl-de.html.markdown
@@ -8,9 +8,9 @@ translators:
lang: de-de
---
-Perl 5 ist eine sehr mächtige, funktionsreiche Programmiersprache mit über 25 Jahren Entwicklungsgeschichte.
+Perl ist eine sehr mächtige, funktionsreiche Programmiersprache mit über 25 Jahren Entwicklungsgeschichte.
-Perl 5 läuft auf über 100 Platformen von portablen Geräten bis hin zu Mainframes. Perl 5 ist geeignet für Rapid-Prototyping und auch groß angelegte Entwicklungs-Projekte.
+Perl läuft auf über 100 Platformen von portablen Geräten bis hin zu Mainframes. Perl ist geeignet für Rapid-Prototyping und auch groß angelegte Entwicklungs-Projekte.
```perl
# Einzeilige Kommentare beginnen mit dem # Symbol.
diff --git a/de-de/processing-de.html.markdown b/de-de/processing-de.html.markdown
new file mode 100644
index 00000000..42ae2233
--- /dev/null
+++ b/de-de/processing-de.html.markdown
@@ -0,0 +1,498 @@
+---
+language: processing
+filename: learnprocessing.pde
+contributors:
+ - ["Phone Thant Ko", "http://github.com/phonethantko"]
+ - ["Divay Prakash", "https://github.com/divayprakash"]
+translators:
+ - ["caminsha", "https://github.com/caminsha"]
+filename: processing-de.md
+lang: de-de
+---
+
+## Einführung
+
+Processing ist eine Programmiersprache, welche es ermöglicht, digitale Kunst
+und multimediale Inhalte zu erstellen. Mit Processing können Personen ohne
+Programmiererfahrung die Grundlagen der Computerprogrammierung in einem
+visuellen Kontext erlernen.
+
+Obwohl Processing von Java beeinflusst wurde und auf Java basiert, ist die Syntax
+sowohl von Java als auch Javascript beeinflusst worden. Weitere Informationen
+sind [hier](https://processing.org/reference/) zu finden.
+
+Die Programmiersprache wird statisch programmiert und kommt mit einer eigenen
+offiziellen IDE, damit die Programme kompiliert und ausgeführt werden können.
+
+```
+/* ------------
+ Mehrzeilige Kommentare werden so gemacht
+*/
+
+// Einzeilige Kommentare funktionieren so //
+
+/*
+ Da Processing von Java abstammt, ist die Syntax für Kommentare gleich
+ wie bei Java (wie du vielleicht oben bemerkt hast)!
+ Mehrzeilige Kommentare werden wie hier umschloßen.
+*/
+
+/* -------------------------------------------------
+ Schreiben und Ausführen von Processing Programmen
+ -------------------------------------------------
+*/
+
+// In Processing ist der Startpunkt eines Programms die Funktion `setup()`
+// mit dem Rückgabetyp `void`.
+// Beachte: Die Syntax ist derjenigen von C++ ziemlich ähnlich.
+void setup() {
+ // Dies gibt beim Ausführen "Hallo Welt!" auf der Konsole aus.
+ println("Hallo Welt!"); // eine weitere Sprache mit einem Semikolon am Ende.
+}
+
+// Normalerweise wird der Code für statische Elemente innerhalb der Methode
+// `setup()` geschrieben, da diese lediglich einmal ausgeführt wird.
+// Dies kann zum Beispiel das Setzen der Hintergrundfarbe oder das Bestimmen
+// der Canvas-Größe sein.
+background(color); // Setze die Hintergrundfarbe
+size(width, height, [renderer]); // bestimme die Canvasgröße mit dem optionalen
+ // Parameter `renderer`.
+// Du wirst innerhalb dieses Dokuments noch weitere Parameter sehen.
+
+// Wenn du möchstest, dass Code unendlich oft ausgeführt wird, so muss dieser
+// Code innerhalb der `draw()`-Methode stehen.
+// `draw()` muss existieren, wenn du möchtest, dass das Programm durchgehend
+// läuft. Die `draw()`-Methode darf nur einmal vorkommen.
+
+int i = 0;
+void draw() {
+ // Dieser Codeblock wird ausgeführt bis er gestoppt wird.
+ print(i);
+ i++; // Inkrement-Operator
+}
+
+// Da wir nun wissen, wie man ein funktionierendes Skript erstellen kann und wie
+// dieses ausgeführt wird, fahren wir mit den unterschiedlichen Datentypen und
+// Collections weiter, welche in Processing unterstützt werden.
+
+/* -------------------------------------------------
+ Datentypen und Collections
+ -------------------------------------------------
+*/
+
+// Gemäß den Angaben in der Processingreferenz, unterstützt Processing die
+// folgenden acht primitiven Datentypen:
+boolean booleanValue = true; // Boolean
+byte byteValueOfA = 23; // Byte
+char charValueOfA = 'A'; // Char (einzelnes Zeichen)
+color colorValueOfWhiteM = color(255, 255, 255); // Farben (angegeben durch die
+ // `color()`-Methode)
+color colorValueOfWhiteH = #FFFFFF; // Farbe (angegeben mit der Hexadezimal-
+ // schreibweise.)
+int intValue = 5; // Integer (ganze Zahl)
+long longValue = 2147483648L; // "L" wird hinzugefügt, um es als `long` zu
+ // markieren.
+float floatValue = 1.12345; // Float (32-Bit Gleitkommazahl)
+double doubleValue = 1.12345D // Double (64-Bit Gleitkommazahl)
+
+//BEACHTE!
+// Auch wenn es die Datentypen "long" und "double" gibt und auch funktionieren,
+// verwenden Processing-Funktionen diese Datentypen nicht. Das bedeutet, dass
+// diese zu "int" resp. "float" konvertiert werden müssen.
+// Dies geschieht, indem man `(int)` oder `(float)` vor die Variable schreibt,
+// bevor diese einer Funktion übergeben werden.
+
+// Es gibt eine ganze Reiher zusammengesetzter Datentypen, welche in Processing
+// gebraucht werden können. Um Zeit zu sparen, gehen wir in diesem Tutorial
+// lediglich die wichtigsten durch.
+
+// String
+// Während der Datentyp `char` einfache Anzührungszeichen (' ') braucht, haben
+// Strings doppelte Anführungszeichen (" ").
+String sampleString = "Hallo, Processing!";
+// Strings können auch durch ein Array von `char`s erstellt werden.
+// Wir werden Arrays gleich anschauen.
+char source = {'H', 'A', 'L', 'L', 'O'};
+String stringFromSource = new String(source); // HALLO
+// Wie auch in Java können in Processing Strings auch zusammengefügt werden
+// mit dem +-Operator.
+print("Hallo " + "Welt!"); // => Hallo Welt!
+
+
+// Arrays
+// In Processing können Arrays jeden Datentypen beinhalten, sogar Objekte.
+// Da Arrays ähnlich wie Objekte sind, müssen diese mit dem Schlüsselwort `new`
+// erstellt werden.
+int[] intArray = new int[5];
+int[] intArrayWithValues = {1, 2, 3} // Arrays können auch mit Daten gefüllt
+ // werden.
+// ArrayList
+// Die Funktionen einer ArrayList sind ähnlich wie die eines Arrays und können
+// auch jegliche Datentypen beinhalten. Der einzige Unterschied zwischen Arrays
+// und `ArrayList`s ist, dass eine `ArrayList` die Größe dynamisch anpassen kann,
+// da es eine Implementierung des "List" Interface in Java ist.
+ArrayList<Integer> intArrayList = new ArrayList<Integer>();
+
+// Objekte
+// Da Processing auf Java basiert, unterstützt Processing die Objektorientierte
+// Programmierung. Dies bedeutet, dass du grundsätzlich jegliche Datentypen
+// selber erstellen kannst und diese nach deinen Bedürfnissen manipulieren kannst.
+// Selbstverständlich muss eine Klasse definiert werden bevor du ein Objekt
+// davon instanzieren kannst.
+// Format: ClassName InstanceName
+SomeRandomClass myObject // hier musst du das Objekt später instazieren
+// Hier wird das Objekt direkt instanziert:
+SomeRandomClass myObjectInstantiated = new SomeRandomClass();
+
+// Processing hat noch weitere Collections (wie zum Beispiel Dictionaries und
+// Listen). Aus Einfachheitsgründen wird dies in diesem Tutorial weggelassen.
+
+/* -------------------------------------------------
+ Mathematik
+ -------------------------------------------------
+*/
+
+// Arithmetik
+1 + 1 // => 2
+2 -1 // => 1
+2 * 3 // => 6
+3 / 2 // => 1
+3.0 / 2 // => 1.5
+3.0 % 2 // => 1.0 (Modulo)
+
+// Processing beinhaltet auch einige Funktionen, welche mathematische
+// Operationen vereinfachen
+float f = sq(3); // Quadrat => f = 9.0
+float p = pow(3, 3); // Potenz => p = 27.0
+int a = abs(-13); // Absolute Zahl => a = 13
+int r1 = round(3.1); // Runden => r1 = 3
+int r2 = round(3.7); // Runden => r2 = 4
+int sr = sqrt(25); // Quadratwurzel => sr = 5.0
+
+// Vektoren
+// Processing bietet eine einfache Möglichkeit an, mit Vektoren zu arbeiten mit
+// der Klasse PVector. Die Klasse kann zwei- und dreidimensionale Vektoren
+// darstellen und bietet Methoden an, welche nützlich sein können für Matrizen-
+// Operationen. Weitere Informationen findest du hier:
+// (https://processing.org/reference/PVector.html)
+
+// Trigonometrie
+// Processing unterstützt auch trigonometrische Operationen mit Hilfe dieser
+// Funktionen: `sin()`, `cos()`, `tan()`, `asin()`, `atan()`. Für die einfache
+// Konvertierung gibt es außerdem noch die Funktionen `degrees()` und `radians()`.
+// Die trigonometrischen Funktionen rechnen mit dem Winkelmaß Radian, wodurch
+// die Gradzahlen zuerst konvertiert werden müssen.
+float one = sin(PI/2); // => one = 1.0
+// Wie du vielleicht bemerkt hast, existieren einige Konstanten für trigo-
+// metrische Operationen; `PI`, `HALF_PI`, `QUARTER_PI` und so weiter ...
+
+/* -------------------------------------------------
+ Kontrollstrukturen
+ -------------------------------------------------
+*/
+
+// Bedingte Anweisungen
+// Bedinge Anweisungen werden gleich wie in Java geschrieben.
+if (author.getAppearence().equals("hot")) {
+ print("Narzissmus vom Feinsten!")
+} else {
+ // Du kannst hier weitere Bedingungen prüfen.
+ print("Irgendetwas ist falsch hier!");
+}
+// Für die `if`-Anweisungen gibt es auch eine Kurzschreibweise
+// Dies sind sogenannte ternäre Operatoren.
+int i = 3;
+String value = (i > 5) ? "Groß" : "Klein"; // => "Klein"
+
+// Die Switch-Case-Anweisung kann verwendet werden, um mehrere Bedingungen
+// zu prüfen.
+// Wichtig ist, dass nach jeder Bedingung ein `break`-Statement verwendet wird,
+// sonst werden alle folgenden ausgeführt und es wird nicht mehr überprüft, ob
+// die Bedingung wahr ist.
+int value = 2;
+switch(value) {
+ case 0:
+ print("Auf keinen Fall!"); // Dies wird nicht ausgeführt.
+ break; // Geht zum nächsten Statement und prüft dieses
+ case 1:
+ print("Wir kommen näher..."); // Auch dies wird nicht ausgeführt
+ break;
+ case 2:
+ print("Bravo!"); // Dies wird ausgeführt.
+ break;
+ default:
+ print("Nicht gefunden."); // Diese Zeile wird ausgeführt, wenn keine
+ // der anderen Operatoren wahr sind.
+ break;
+}
+
+// Wiederholungen
+// For-Schleifen - Auch hier ist die Syntax wieder gleich wie in Java
+for(int i = 0; i < 5; i++) {
+ print(i); // Gibt die Zahlen 0 bis 4 aus.
+}
+
+// While-Statements
+int j = 3;
+while(j > 0) {
+ print(j);
+ j--; // Dies ist wichtig, dass der Code nicht unendlich lange läuft.
+}
+
+// `loop()` | `noloop()` | `redraw()` | `exit()`
+// Dies sind spezifische Funktionen, welche in Processing verwendet werden
+// können, um den Programmablauf zu steuern.
+loop(); // erlaubt es der `draw()`-Methode immer zu laufen, während
+noloop(); // dies nur für einmal erlaubt.
+redraw(); // führt die `draw()`-Methode noch einmal aus.
+exit(); // Diese Methode stoppt das Programm. Dies kann nützlich sein, wenn die
+ // Methode `draw()` immer läuft.
+```
+
+## Mit Processing zeichnen
+
+Da du nun die Grundsätze der Programmiersprache verstanden hast, schauen wir
+uns nun das Beste an Processing an - Das Zeichnen!
+
+```
+
+/* -------------------------------------------------
+ Figuren
+ -------------------------------------------------
+*/
+
+// 2D-Figuren
+
+// Punkte
+point(x,y); // im zweidimensionalen Raum
+point(x, y, z); // im dreidimensionalen Raum
+// Diese Befehle zeichnen einen Punkt an der Koordinate.
+
+// Linien
+line(x1, y1, x2, y2); // im zweidimensionalen Raum
+// Dies zeichnet eine Linie, welche durch die zwei Punkte (x1, y1) und (x2, y2)
+// definiert wird.
+line(x1, y1, z1, x2, y2, z2); // im dreidimensionalen Raum
+// Analog wird hier eine Linie gezeichnet mit drei Punkten
+
+// Dreieck
+triangle(x1, y1, x2, y2, x3, y3);
+// Zeichnet ein Dreieck, welches als Eckpunkte die drei Koordinaten hat.
+
+// Rechteck
+rect(a, b, c, d, [r]); // Mit dem optionalen Parameter kann der Winkel aller
+ // vier Ecken definiert werden
+rect(a, b, c, d, [tl, tr, br, bl]); // Mit weiteren optionalen Parametern kann
+ // jeder Winkel des Rechtecks definiert werden.
+// Dies zeichnet ein Quadrat mit der Koordinate {a, b} als linke obere Ecke
+// die Parameter c und d sind für die Breite und Höhe.
+
+// Vierecke
+quad(x, y, x2, y2, x3, y3, x4, y4);
+// Dies zeichnet ein Viereck, welches die einzelnen Koordinaten als Eckpunkte hat.
+
+// Ellipse
+ellipse(x, y, width, height);
+// Zeichnet eine Ellipse beim Punkt {x. y}. Die Breite und die Höhe werden durch
+// die Parameter width und height definiert.
+
+// Arc
+arc(x, y, width, height, start, stop, [mode]);
+// Die ersten vier Parameter sollten selbsterklärend sein.
+// start und end definieren die Winkel, bei welchen `arc` starten resp. enden
+// (in Radians)
+// Der optionale Parameter `mode` definiert, ob der Kreisbogen gefüllt wird
+// oder nicht.
+// Die möglichen Optionen für `mode` sind: PIE, CHORD und OPEN.
+
+// Kurven
+// Processing bietet zwei mögliche Kurven an, welche verwendet werden können.
+// Da es hier darum geht, dass es möglichst simpel ist, werden hier keine
+// weiteren Details genannt. Wenn du Kurven in deinem Programm verwenden möchtest,
+// sind die folgenden Links empfehlenswert:
+// https://processing.org/reference/curve_.html
+// https://processing.org/reference/bezier_.html
+
+
+// 3D-Figuren
+
+// Der dreidimensionale Raum kann aktiviert werden, indem man den Renderer-
+// Parameter in der Methode `size()` zu "P3D" setzt.
+size(width, height, P3D);
+// Im dreidimensionalen Raum müssen die Koordinaten übersetzt werden, damit
+// diese korrekt gerendert werden.
+
+// Box
+box(size); // Würfel mit der Seitenlänge `size`
+box(w, h, d); // Quader definiert durch Breite, Höhe und Tiefe
+
+// Kugel
+sphere(radius); // Die Größe wird definiert durch den Parameter `radius`
+// Der Mechanismus hinter dem Rendern von Kugeln wurde durch mosaikartige
+// Dreiecke implementiert.
+// Mit der folgenden Funktion ist es möglich, zu bestimmen wie detailliert die
+// Kugel gerendert wird.
+// spereDetail(res);
+// Weitere Informationen sind hier zu finden: (https://processing.org/reference/sphereDetail_.html)
+
+// Unregelmäßige Figuren
+// Was ist, wenn du etwas zeichnen möchtest, was nicht durch Processing-Funktionen
+// abgedeckt ist?
+// Es ist möglich, die Funktionen `beginShape()`, `endShape()` und `vertex(x,y)
+// zu verwenden.
+// Weitere Informationen findest du hier: (https://processing.org/reference/beginShape_.html)
+// Du kannst selber gemachte Formen auch verwenden mit der PShape-Klasse.
+// Informationen zu PShape gibt es hier: (https://processing.org/reference/PShape.html)
+
+/* -------------------------------------------------
+ Transformationen
+ -------------------------------------------------
+*/
+
+// Tranformationen sind nützlich, um ständig zu wissen, wo die Koordinaten und
+// die Ecken einer Form sind, welche du gezeichnet hast. Grundsätzlich sind dies
+// Matrizenoperationen. `pushMatrix()`, `popMatrix()` und `translate()`.
+pushMatrix(); // Speichert das aktuelle Koordinatensystem auf dem Stack
+ // alle Transformationen werden hier angewendet.
+popMatrix(); // Stellt das gespeicherte Koordinatensystem wieder her.
+// Wenn du diese Funktionen verwendest, kann das Koordinatensystem gespeichert
+// und visualisiert werden, ohne dass es Konflikte gibt.
+
+// Translate
+translate(x,y); // Setzt den Ursprung zu diesem Punkt.
+translate(x, y, z); // Pendant zu der oberen Funktion im dreidimensionalen Raum
+
+// Rotationen
+rotate(angle); // Rotiere, um den Betrag, welcher spezifiert wurde.
+// Es gibt drei Pendants im dreidimensionalen Raum.
+// Namentlich sind dies: `rotateX(angle)`, `rotateY(angle)` und `rotateZ(angle)`
+
+// Skalierung
+scale(s); // Skaliert das Koordinatensystem (entweder erweitern oder verkleinern)
+
+/* -------------------------------------------------
+ Styling und Texturen
+ -------------------------------------------------
+*/
+
+// Farben
+// Wie ich zuvor schon erklärt habe, kann die Hintergrundfarbe mit der Funktion
+// `background()` definiert werden. Außerdem ist es möglich, dass man zuerst
+// eine Farbe definiert und diese erst danach der Funktion übergeben wird.
+color c = color(255, 255, 255); // WEISS!
+// Standardmäßig verwendet Processing das RGB-Farbschema, aber dies kann
+// zu HSB konfiguriert werden, indem die Funktion `colorMode()` verwendet wird.
+// Weitere Informationen findest du hier: (https://processing.org/reference/colorMode_.html)
+background(c); // Ab jetzt ist der Hintergrund in weiß.
+// Du kannst die Funktion `fill()` verwenden, um die Farbe auszuwählen, mit
+// welcher die Formen ausgefüllt werden.
+// Dies muss konfiguriert werden bevor Formen und Figuren gezeichnet werden.
+fill(color(0, 0, 0));
+// Wenn du nur die Farbe der Umrandungen definieren möchtest, kannst du die
+// Funktion `stroke()` verwenden.
+stroke(255, 255, 0, 200); // Linienfarbe wird zu gelb mit einer höheren
+ // Transparenz geändert.
+
+// Bilder
+// Processing kann Bilder rendern und diese unterschiedlich verwenden. Die
+// meisten Bilder sind im Datentyp `PImage` gespeichert.
+filter(shader); // Processing unterstützt mehrere Filter-Funktionen, damit
+ // Bilder verändert werden können.
+texture(image); // PImage kann als Argument, weiteren Funktionen übergeben
+ // werden, um die Figuren zu "Text" zu machen.
+```
+
+Wenn du weitere Dinge mit Processing kennenlernen willst, dann gibt es unzählige
+Dinge, welche du mit Processing machen kannst. Das Rendern von Modellen,
+Schattierungen und viele mehr. Für ein kurzes Tutorial bietet Processing zu viel,
+daher verweise ich dich, falls du interessiert bist, auf die offizielle
+Dokumentaion.
+
+```
+// Bevor wir weiterfahren, werde ich einige Aspekte zum Importieren von
+// Bibliotheken und Paketen sagen, damit du Processing erweitern kannst..
+
+/* -------------------------------------------------
+ Import
+ -------------------------------------------------
+*/
+
+// Die Macht von Processing kann besser veranschaulicht werden, wenn wir
+// Bibliotheken und Pakete importieren.
+// Die Import-Anweisung kann wie unten geschrieben zu Beginn des Quelltextes
+// geschrieben werden.
+import processing.something.*;
+```
+
+## Beispielprogramm
+
+Lass uns ein Beispiel von openprocessing.org ansehen, welches verdeutlicht,
+was man in Processing mit nur wenigen Zeilen Code machen kann.
+
+Kopiere den nachfolgenden Code in deine Processing IDE.
+
+```
+// Disclaimer: Ich habe das Porgramm nicht selbst geschriben. Diese Skizze
+// stammt aus openprocessing, allerdings soll dieses Programm zeigen, wie wenig
+// Zeilen Code notwendig sind, um etwas Cooles zu machen.
+// Abgerufen von: (https://www.openprocessing.org/sketch/559769)
+
+float theta;
+float a;
+float col;
+float num;
+
+void setup() {
+ size(600,600);
+}
+
+void draw() {
+ background(#F2F2F2);
+ translate(width/2, height/2);
+ theta = map(sin(millis()/1000.0), -1, 1, 0, PI/6);
+
+ float num=6;
+ for (int i=0; i<num; i++) {
+ a =350;
+ rotate(TWO_PI/num);
+ branch(a);
+ }
+}
+
+void branch(float len) {
+ col=map(len, 0, 90, 150, 255);
+ fill(col, 0, 74);
+ stroke (col, 0, 74);
+ line(0, 0, 0, -len);
+ ellipse(0, -len, 3, 3);
+ len*=0.7;
+
+ if (len>30) {
+ pushMatrix();
+ translate(0, -30);
+ rotate(theta);
+ branch(len);
+ popMatrix();
+
+ pushMatrix();
+ translate(0, -30);
+ rotate(-theta);
+ branch(len);
+ popMatrix();
+ }
+}
+```
+
+Processing ist einfach zu erlernen und ist vorallem nützlich, um Multimedia-
+Inhalte (auch in 3D) zu erstellen ohne viel Code zu schreiben. Es ist so einfach
+gehalten, dass man den Code durchlesen kann und man versteht den Programmablauf
+bereits.
+
+Wenn du externe Bibliotheken, Pakete oder eigene Klassen einbindest, kann ein
+Programm, welches mit Processing geschrieben wurde, durchaus auch kompliziert
+werden.
+
+## Einige nützliche Links
+
+- [Processing Webseite](http://processing.org)
+- [Processing Sketches](http://openprocessing.org)
diff --git a/de-de/pug-de.html.markdown b/de-de/pug-de.html.markdown
new file mode 100644
index 00000000..c86494ce
--- /dev/null
+++ b/de-de/pug-de.html.markdown
@@ -0,0 +1,208 @@
+---
+language: Pug
+contributors:
+ - ["Michael Warner", "https://github.com/MichaelJGW"]
+filename: lernepug-de.pug
+translators:
+ - ["denniskeller", "https://github.com/denniskeller"]
+lang: de-de
+---
+
+## Erste Schritte mit Pug
+
+Pug ist eine kleine Sprache, die zu HTML kompiliert. Sie hat eine
+saubere Syntax mit zusätzlichen Funktionen wie if Anweisungen und Schleifen.
+Sie kann auch als serverseitige Templatingsprache für Serversprachen
+wie NodeJS verwendet werden.
+
+### Die Sprache
+```pug
+
+//- Einzeilenkommentar
+
+//- Mehrzeiliger
+ Kommentar
+
+//- ---TAGS---
+//- Grundlagen
+div
+//- <div></div>
+h1
+//- <h1></h1>
+mein-benutzerdefiniertesTag
+//- <mein-benutzerdefiniertesTag></mein-benutzerdefiniertesTag>
+
+//- Geschwister
+div
+div
+//- <div></div>
+ <div></div>
+
+//- Kind
+div
+ div
+//- <div>
+ <div></div>
+ </div>
+
+//- Text
+h1 Hallo Welt
+//- <h1>Hallo Welt</h1>
+
+//- Multizeilentext
+div.
+ Hallo
+ Welt
+//- <div>
+ Hallo
+ Welt
+ </div>
+
+//- ---ATTRIBUTE---
+div(class="meine-klasse" id="meine-id" mein-benutzerdefiniertes-attr="data" enabled)
+//- <div class="meine-klasse" id="meine-id" mein-benutzerdefiniertes-attr="data" enabled></div>
+
+//- Kurzhand
+span.meine-klasse
+//- <span class="meine-klasse"></span>
+.meine-klasse
+//- <div class="meine-klasse"></div>
+div#meine-id
+//- <div id="meine-id"></div>
+div#meine-id.meine-klasse
+//- <div class="meine-klasse" id="meine-id"></div>
+
+
+//- ---JS---
+- const sprache = "pug";
+
+//- Multizeilen JS
+-
+ const srache = "pug";
+ const cool = true;
+
+//- JS Klassen
+- const meineKlasse = ['class1', 'class2', 'class3']
+div(class=meineKlasse)
+//- <div class="class1 class2 class3"></div>
+
+//- JS Stil
+- const meineStile = {'color':'white', 'background-color':'blue'}
+div(styles=meineStile)
+//- <div styles="{&quot;color&quot;:&quot;white&quot;,&quot;background-color&quot;:&quot;blue&quot;}"></div>
+
+//- JS Attributte
+- const meineAttribute = {"src": "foto.png", "alt": "meine Bilder"}
+img&attributes(meineAttribute)
+//- <img src="foto.png" alt="meine Bilder">
+- let deaktiviert = false
+input(type="text" disabled=deaktiviert)
+//- <input type="text">
+- deaktiviert = true
+input(type="text" disabled=deaktiviert)
+//- <input type="text" disabled>
+
+//- JS Templating
+- const name = "Bob";
+h1 Hi #{name}
+h1= name
+//- <h1>Hi Bob</h1>
+//- <h1>Bob</h1>
+
+//- ---Schleifen---
+
+//- 'each' und 'for' machen das Selbe. Wir werden nur 'each' verwenden.
+
+each value, i in [1,2,3]
+ p=value
+//-
+ <p>1</p>
+ <p>2</p>
+ <p>3</p>
+
+each value, index in [1,2,3]
+ p=value + '-' + index
+//-
+ <p>1-0</p>
+ <p>2-1</p>
+ <p>3-2</p>
+
+each value in []
+ p=value
+//-
+
+each value in []
+ p=value
+else
+ p Keine Werte sind hier
+
+//- <p>Keine Werte sind hier</p>
+
+//- ---BEDINGUNGEN---
+
+- const zahl = 5
+if zahl < 5
+ p zahl ist kleiner als 5
+else if zahl > 5
+ p zahl ist größer als 5
+else
+ p zahl ist 5
+//- <p>zahl ist 5</p>
+
+- const bestellungsStatus = "Ausstehend";
+case bestellungsStatus
+ when "Ausstehend"
+ p.warn Deine Bestellung steht noch aus
+ when "Abgeschlossen"
+ p.success Bestellung ist abgeschlossen.
+ when -1
+ p.error Ein Fehler ist aufgetreten
+ default
+ p kein Bestellprotokoll gefunden
+//- <p class="warn">Deine Bestellung steht noch aus</p>
+
+//- --INCLUDE--
+//- File path -> "includes/nav.png"
+h1 Firmenname
+nav
+ a(href="index.html") Home
+ a(href="about.html") Über uns
+
+//- Dateipfad -> "index.png"
+html
+ body
+ include includes/nav.pug
+//-
+ <html>
+ <body>
+ <h1>Firmenname</h1>
+ <nav><a href="index.html">Home</a><a href="about.html">Über uns</a></nav>
+ </body>
+ </html>
+
+//- Importiere JS und CSS
+script
+ include scripts/index.js
+style
+ include styles/theme.css
+
+//- ---MIXIN---
+mixin basic()
+ div Hallo
++basic("Bob")
+//- <div>Hallo</div>
+
+mixin comment(name, kommentar)
+ div
+ span.comment-name= name
+ div.comment-text= kommentar
++comment("Bob", "Das ist super")
+//- <div>Hallo</div>
+
+```
+
+
+### Zusätzliche Ressourcen
+- [The Site](https://pugjs.org/)
+- [The Docs](https://pugjs.org/api/getting-started.html)
+- [Github Repo](https://github.com/pugjs/pug)
diff --git a/de-de/pyqt-de.html.markdown b/de-de/pyqt-de.html.markdown
new file mode 100644
index 00000000..93ee20d4
--- /dev/null
+++ b/de-de/pyqt-de.html.markdown
@@ -0,0 +1,89 @@
+---
+category: tool
+tool: PyQT
+filename: learnpyqt-de.py
+contributors:
+ - ["Nathan Hughes", "https://github.com/sirsharpest"]
+translators:
+ - ["Dennis Keller", "https://github.com/denniskeller"]
+lang: de-de
+---
+
+**Qt** ist eine weit bekanntes Framework mit den man plattformunabhängige Programme schreiben kann,
+die auf verschiedenen Sotfware und Hardware Plattformen laufen mit kleinen oder keinen Änderungen im Code.
+Dabei besitzen sie trozdem die Power und Geschwindigkeit von nativen Anwendungen.
+**Qt** wurde ursprünglich in *C++** geschrieben.
+
+Das ist eine Adaption von dem C++ Intro für QT von [Aleksey Kholovchuk](https://github.com/vortexxx192),
+manche der Codebeispiele sollte in der selben Funktionalität resultieren.
+Diese Version wurde in pyqt erstellt.
+
+```python
+import sys
+from PyQt4 import QtGui
+
+def window():
+ # Erschafft ein Anwendungsobjekt.
+ app = QtGui.QApplication(sys.argv)
+ # Erschafft ein Widget, auf dem unser Label platziert wird.
+ w = QtGui.QWidget()
+ # Fügt ein Label zu dem Widget hinzu.
+ b = QtGui.QLabel(w)
+ # Setzt einen Text für das Label.
+ b.setText("Hello World!")
+ # Setzt die Größe und die Platzierungsinfomationen.
+ w.setGeometry(100, 100, 200, 50)
+ b.move(50, 20)
+ # Setzt unserem Fenster einen schönen Titel.
+ w.setWindowTitle("PyQt")
+ # Lässt alles anzeigen.
+ w.show()
+ # Führe alles aus, nachdem wir alles aufgebaut haben.
+ sys.exit(app.exec_())
+
+if __name__ == '__main__':
+ window()
+
+```
+
+Damit wir weitere fortgeschrittene Funktionen in **pyqt** verwenden können,
+müssen wir anfangen zusätzliche Elemente zu bauen.
+Hier zeigen wir wie man eine Dialog Popup Box einführt.
+Diese ist nützlich, um den Benutzer eine Entscheidung zu bestätigen oder um Informationen anzuzeigen.
+
+```Python
+import sys
+from PyQt4.QtGui import *
+from PyQt4.QtCore import *
+
+
+def window():
+ app = QApplication(sys.argv)
+ w = QWidget()
+ # Erschafft einen Knopf und fügt das Widget w hinzu
+ b = QPushButton(w)
+ b.setText("drücke mich")
+ b.move(50, 50)
+ # Wenn b gedrückt wird, wird diese Funktion aufgerufen.
+ # Bemerke das Fehlen von () bei dem Funktionsaufruf.
+ b.clicked.connect(showdialog)
+ w.setWindowTitle("PyQt Dialog")
+ w.show()
+ sys.exit(app.exec_())
+
+# Diese Funktion soll ein Dialogfenster mit einem Knopf erschaffen.
+# Der Knopf wartet bis er geklickt wird und beendet das Programm
+def showdialog():
+ d = QDialog()
+ b1 = QPushButton("ok", d)
+ b1.move(50, 50)
+ d.setWindowTitle("Dialog")
+ # Diese Modalität sagt dem Popup, dass es den Parent blocken soll, solange es aktiv ist.
+ d.setWindowModality(Qt.ApplicationModal)
+ # Beim klicken möchte ich, dass der gesamte Prozess beendet wird.
+ b1.clicked.connect(sys.exit)
+ d.exec_()
+
+if __name__ == '__main__':
+ window()
+```
diff --git a/de-de/python-de.html.markdown b/de-de/python-de.html.markdown
index ae29d6f9..337f1224 100644
--- a/de-de/python-de.html.markdown
+++ b/de-de/python-de.html.markdown
@@ -1,9 +1,10 @@
---
-language: python
+language: Python
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
translators:
- ["kultprok", "http:/www.kulturproktologie.de"]
+ - ["matthiaskern", "https://github.com/matthiaskern"]
filename: learnpython-de.py
lang: de-de
---
@@ -11,13 +12,16 @@ lang: de-de
Anmerkungen des ursprünglichen Autors:
Python wurde in den frühen Neunzigern von Guido van Rossum entworfen. Es ist heute eine der beliebtesten Sprachen. Ich habe mich in Python wegen seiner syntaktischen Übersichtlichkeit verliebt. Eigentlich ist es ausführbarer Pseudocode.
-Feedback ist herzlich willkommen! Ihr erreicht mich unter [@louiedinh](http://twitter.com/louiedinh) oder louiedinh [at] [google's email service]
+Feedback ist herzlich willkommen! Ihr erreicht mich unter [@louiedinh](http://twitter.com/louiedinh) oder louiedinh [at] [google's email service].
-Hinweis: Dieser Beitrag bezieht sich besonders auf Python 2.7, er sollte aber auf Python 2.x anwendbar sein. Haltet Ausschau nach einem Rundgang durch Python 3, der bald erscheinen soll.
+Hinweis: Dieser Beitrag bezieht sich implizit auf Python 3. Falls du lieber Python 2.7 lernen möchtest, schau [hier](http://learnxinyminutes.com/docs/pythonlegacy/) weiter. Beachte hierbei,
+dass Python 2 als veraltet gilt und für neue Projekte nicht mehr verwendet werden sollte.
```python
+
# Einzeilige Kommentare beginnen mit einer Raute (Doppelkreuz)
-""" Mehrzeilige Strings werden mit
+
+""" Mehrzeilige Strings werden mit
drei '-Zeichen geschrieben und werden
oft als Kommentare genutzt.
"""
@@ -33,15 +37,24 @@ Hinweis: Dieser Beitrag bezieht sich besonders auf Python 2.7, er sollte aber au
1 + 1 #=> 2
8 - 1 #=> 7
10 * 2 #=> 20
-35 / 5 #=> 7
-# Division ist ein wenig kniffliger. Ganze Zahlen werden ohne Rest dividiert
-# und das Ergebnis wird automatisch abgerundet.
-5 / 2 #=> 2
+# Außer Division, welche automatisch Gleitkommazahlen zurückgibt
+35 / 5 # => 7.0
+
+# Eine Division kann mit "//" für positive sowie negative Werte abgerundet werden.
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # funktioniert auch mit floats
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
+
+# Benutzt man eine Gleitkommazahl, ist auch das Ergebnis eine solche
+3 * 2.0 # => 6.0
+
+# Der Rest einer Division
+7 % 3 # => 1
-# Um das zu ändern, müssen wir Gleitkommazahlen einführen und benutzen
-2.0 # Das ist eine Gleitkommazahl
-11.0 / 4.0 #=> 2.75 Ahhh...schon besser
+# Potenz
+2**4 # => 16
# Rangfolge wird mit Klammern erzwungen
(1 + 3) * 2 #=> 8
@@ -54,6 +67,18 @@ False
not True #=> False
not False #=> True
+# Boolesche Operatoren
+# Hinweis: "and" und "or" müssen klein geschrieben werden
+True and False #=> False
+False or True #=> True
+
+# Für die Benutzung von Booleschen Operatoren und ganzen Zahlen
+0 and 2 #=> 0
+-5 or 0 #=> -5
+0 == False #=> True
+2 == True #=> False
+1 == True #=> True
+
# Gleichheit ist ==
1 == 1 #=> True
2 == 1 #=> False
@@ -76,58 +101,59 @@ not False #=> True
"Das ist ein String."
'Das ist auch ein String.'
-# Strings können addiert werden!
-"Hello " + "world!" #=> "Hello world!"
+# Strings können auch addiert werden! Vermeide dies aber lieber.
+"Hallo " + "Welt!" #=> "Hallo Welt!"
+# Strings können ohne "+" addiert werden
+"Hallo " "welt!" # => "Hallo Welt!"
# Ein String kann wie eine Liste von Zeichen verwendet werden
"Das ist ein String"[0] #=> 'D'
-# Mit % können Strings formatiert werden, etwa so:
-"%s können %s werden" % ("Strings", "interpoliert")
+# .format kann Strings formatieren
+"{} können {} werden".format("Strings", "formatiert")
+
+# Schneller geht das mit Wiederholungen
+"{0} mag Spagetthi, {0} liebt es zu Schwimmen und ganz besonders mag {0} {1}".format("Hans", "Blattsalat")
+#=> "Hans mag Spagetthi, Hans liebt es zu Schwimmen und ganz besonders mag Hans Blattsalat"
-# Ein modernerer Weg, um Strings zu formatieren, ist die format-Methode.
-# Diese Methode wird bevorzugt
-"{0} können {1} werden".format("Strings", "formatiert")
-# Wir können Schlüsselwörter verwenden, wenn wir nicht abzählen wollen.
-"{name} will {food} essen".format(name="Bob", food="Lasagne")
+# Die Formatierung kann auch mit `f-strings` oder formattierten Strings gemacht
+# werden (ab Python 3.6+)
+name = "Sandra"
+f"Sie hat gesagt, ihr name sei {name}." # => Sie hat gesagt, ihr Name sei Sandra."
+# Es ist möglich, andere Anweisungen innerhalb der geschweiften Klammern zu
+# setzen, welche dann im Output des Strings angezeigt werden.
+f"{name} ist {len(name)} Zeichen lang" # => Sandra ist 6 Zeichen lang.
# None ist ein Objekt
None #=> None
# Verwendet nicht das Symbol für Gleichheit `==`, um Objekte mit None zu vergleichen
-# Benutzt stattdessen `is`
+# Benutzt stattdessen `is`. Dieser Operator testet Objektidentität
"etc" is None #=> False
None is None #=> True
-# Der 'is'-Operator testet Objektidentität. Das ist nicht
-# sehr nützlich, wenn wir mit primitiven Datentypen arbeiten, aber
-# sehr nützlich bei Objekten.
-
# None, 0, und leere Strings/Listen werden alle als False bewertet.
# Alle anderen Werte sind True
-0 == False #=> True
-"" == False #=> True
-
+bool(0) # => False
+bool("") # => False
+bool([]) #=> False
+bool({}) #=> False
####################################################
## 2. Variablen und Collections
####################################################
# Textausgabe ist sehr einfach
-print "Ich bin Python. Schön, dich kennenzulernen!"
-
+print("Ich bin Python. Schön, dich kennenzulernen!")
# Es gibt keinen Grund, Variablen vor der Zuweisung zu deklarieren.
some_var = 5 # kleinschreibung_mit_unterstrichen entspricht der Norm
some_var #=> 5
-# Das Ansprechen einer noch nicht deklarierte Variable löst eine Exception aus.
+# Das Ansprechen einer noch nicht deklarierten Variable löst eine Exception aus.
# Unter "Kontrollstruktur" kann noch mehr über
# Ausnahmebehandlung erfahren werden.
-some_other_var # Löst einen NameError aus
-
-# if kann als Ausdruck verwendet werden
-"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+some_unknown_var # Löst einen NameError aus
# Listen speichern Sequenzen
li = []
@@ -150,7 +176,7 @@ li[0] #=> 1
li[-1] #=> 3
# Bei Zugriffen außerhalb der Liste kommt es jedoch zu einem IndexError
-li[4] # Raises an IndexError
+li[4] # Verursacht einen IndexError
# Wir können uns Ranges mit Slice-Syntax ansehen
li[1:3] #=> [2, 4]
@@ -158,6 +184,12 @@ li[1:3] #=> [2, 4]
li[2:] #=> [4, 3]
# Das Ende auslassen
li[:3] #=> [1, 2, 4]
+# Jeden Zweiten Eintrag auswählen
+li[::2] # =>[1, 4]
+# Eine umgekehrte Kopie zurückgeben
+li[::-1] # => [3, 4, 2, 1]
+# Jegliche Kombination dieser Syntax machen fortgeschrittene Slices möglich
+# li[Start:Ende:Schritt]
# Ein bestimmtes Element mit del aus der Liste entfernen
del li[2] # li ist jetzt [1, 2, 3]
@@ -174,7 +206,6 @@ li.extend(other_li) # Jetzt ist li [1, 2, 3, 4, 5, 6]
# Die Länge der Liste mit len ermitteln
len(li) #=> 6
-
# Tupel sind wie Listen, nur unveränderlich.
tup = (1, 2, 3)
tup[0] #=> 1
@@ -190,11 +221,10 @@ tup[:2] #=> (1, 2)
a, b, c = (1, 2, 3) # a ist jetzt 1, b ist jetzt 2 und c ist jetzt 3
# Tupel werden standardmäßig erstellt, wenn wir uns die Klammern sparen
d, e, f = 4, 5, 6
-# Es ist kinderleicht zwei Werte zu tauschen
-e, d = d, e # d is now 5 and e is now 4
+# Es ist kinderleicht, zwei Werte zu tauschen
+e, d = d, e # d ist nun 5 und e ist nun 4
-
-# Dictionarys (Wörterbucher) speichern Key-Value-Paare
+# Dictionarys (Wörterbucher) speichern Schlüssel-Werte-Paare
empty_dict = {}
# Hier ein gefülltes Wörterbuch
filled_dict = {"one": 1, "two": 2, "three": 3}
@@ -203,15 +233,15 @@ filled_dict = {"one": 1, "two": 2, "three": 3}
filled_dict["one"] #=> 1
# So holen wir alle Keys (Schlüssel) als Liste
-filled_dict.keys() #=> ["three", "two", "one"]
+list(filled_dict.keys()) #=> ["three", "two", "one"]
# Hinweis - Die Reihenfolge von Schlüsseln in der Liste ist nicht garantiert.
# Einzelne Resultate können anders angeordnet sein.
# Alle Values (Werte) als Liste
-filled_dict.values() #=> [3, 2, 1]
+list(filled_dict.values()) #=> [3, 2, 1]
# Hinweis - Hier gelten dieselben Einschränkungen für die Reihenfolge wie bei Schlüsseln.
-# Das Vorhandensein eines Schlüssels im Wörterbuch mit in prüfen
+# Das Vorhandensein eines Schlüssels im Wörterbuch mit "in" prüfen
"one" in filled_dict #=> True
1 in filled_dict #=> False
@@ -229,17 +259,23 @@ filled_dict.get("four", 4) #=> 4
filled_dict.setdefault("five", 5) #filled_dict["five"] wird auf 5 gesetzt
filled_dict.setdefault("five", 6) #filled_dict["five"] ist noch immer 5
+# Einträge zu einem Wörterbuch hinzufügen
+filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4}
+#filled_dict["four"] = 4 # noch ein Weg, Werte hinzuzufügen
+
+# Schlüssel von einem Wörterbuch entfernen
+del filled_dict["one"] # Entfert den Schlüssel "one"
# Sets speichern Mengen
empty_set = set()
# Initialisieren wir ein Set mit ein paar Werten
-some_set = set([1,2,2,3,4]) # some_set ist jetzt set([1, 2, 3, 4])
+some_set = {1, 1, 2, 2, 3, 4} # some_set ist jetzt {1, 2, 3, 4}
-# Seit Python 2.7 kann {} benutzt werden, um ein Set zu erstellen
-filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+# Neue Variablen können einer Menge gleichgesetzt werden
+filled_set = some_set
# Mehr Elemente hinzufügen
-filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
+filled_set.add(5) # filled_set ist jetzt {1, 2, 3, 4, 5}
# Schnittmengen werden mit & gebildet
other_set = {3, 4, 5, 6}
@@ -257,7 +293,7 @@ filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
####################################################
-## 3. Kontrollstruktur
+## 3. Kontrollstruktur und Iteratoren
####################################################
# Erstellen wir mal eine Variable
@@ -266,11 +302,11 @@ some_var = 5
# Hier eine if-Anweisung. Die Einrückung ist in Python wichtig!
# gibt "some_var ist kleiner als 10" aus
if some_var > 10:
- print "some_var ist viel größer als 10."
+ print("some_var ist viel größer als 10.")
elif some_var < 10: # Dieser elif-Absatz ist optional.
- print "some_var ist kleiner als 10."
+ print("some_var ist kleiner als 10.")
else: # Das hier ist auch optional.
- print "some_var ist tatsächlich 10."
+ print("some_var ist tatsächlich 10.")
"""
@@ -281,9 +317,9 @@ Ausgabe:
maus ist ein Säugetier
"""
for animal in ["hund", "katze", "maus"]:
- # Wir können Strings mit % formatieren
- print "%s ist ein Säugetier" % animal
-
+ # Wir können Strings mit format() formatieren
+ print("{} ist ein Säugetier".format(animal))
+
"""
`range(Zahl)` gibt eine null-basierte Liste bis zur angegebenen Zahl wieder
Ausgabe:
@@ -293,7 +329,18 @@ Ausgabe:
3
"""
for i in range(4):
- print i
+ print(i)
+
+"""
+"range(unten, oben)" gibt eine Liste von der unteren Zahl bis zur oberen Zahl aus
+Ausgabe:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print(i)
"""
While-Schleifen laufen, bis eine Bedingung erfüllt ist.
@@ -305,18 +352,59 @@ Ausgabe:
"""
x = 0
while x < 4:
- print x
+ print(x)
x += 1 # Kurzform für x = x + 1
# Ausnahmebehandlung mit einem try/except-Block
-
-# Funktioniert in Python 2.6 und höher:
try:
# Mit raise wird ein Fehler ausgegeben
raise IndexError("Das hier ist ein Index-Fehler")
except IndexError as e:
pass # Pass ist nur eine no-op. Normalerweise würden wir hier den Fehler klären.
+except (TypeError, NameError):
+ pass # Mehrere Fehler können zusammen geklärt werden, falls erforderlich.
+else: # Optional, hinter allen except-Blöcken
+ print("Keine Probleme!") # Wird nur ausgeführt, wenn keine Ausnahmen aufgetreten sind
+finally: # Wird immer ausgeführt
+ print("Hier können wir Ressourcen aufräumen")
+
+# alternativ zu einem try/finally Block um Aufzuräumen:
+with open("meineDatei.txt") as f:
+ for line in f:
+ print(line)
+
+# Python bietet ein fundamentales Konzept der Iteration.
+# Das Objekt, auf das die Iteration, also die Wiederholung einer Methode
+# angewandt wird, heißt auf Englisch "iterable".
+# Die range Methode gibt ein solches Objekt aus.
+
+filled_dict = {"one": 1, "two": 2, "three": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) #=> range(1,10). Dies ist ein "iterable" Objekt.
+
+# Über dieses können wir auch iterieren
+for i in our_iterable:
+ print(i) # Gibt one, two, three aus
+
+# Allerdings können wir die einzelnen Elemente nicht mit ihrem Index ausgeben
+our_iterable[1] # TypeError
+# Ein iterable ist ein Objekt, das weiß wie es einen Iteratoren erschafft.
+our_iterator = iter(our_iterable)
+
+# Unser Iterator ist ein Objekt, das sich merkt, welchen Status es gerade hat
+# während wir durch es gehen. Das jeweils nächste Objekt bekommen wir mit "next()"
+next(our_iterator) #=> "one"
+
+# Es hält den vorherigen Status
+next(our_iterator) #=> "two"
+next(our_iterator) #=> "three"
+
+# Nachdem alle Daten ausgegeben worden sind, kommt eine StopIterator Ausnahme zurück
+next(our_iterator) # Gibt StopIteration aus
+
+# Alle Elemente können mit "list()" ausgegeben werden
+list(filled_dict.keys()) #=> ["one", "two", "three"]
####################################################
## 4. Funktionen
@@ -324,7 +412,7 @@ except IndexError as e:
# Mit def neue Funktionen erstellen
def add(x, y):
- print "x ist %s und y ist %s" % (x, y)
+ print("x ist %s und y ist %s" % (x, y))
return x + y # Werte werden mit return zurückgegeben
# Funktionen mit Parametern aufrufen
@@ -348,10 +436,10 @@ def keyword_args(**kwargs):
# Rufen wir es mal auf, um zu sehen, was passiert
keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
-# Wir können beides gleichzeitig machem, wenn wir wollen
+# Wir können beides gleichzeitig machen, wenn wir wollen
def all_the_args(*args, **kwargs):
- print args
- print kwargs
+ print(args)
+ print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) Ausgabe:
(1, 2)
@@ -366,6 +454,25 @@ all_the_args(*args) # äquivalent zu foo(1, 2, 3, 4)
all_the_args(**kwargs) # äquivalent zu foo(a=3, b=4)
all_the_args(*args, **kwargs) # äquivalent zu foo(1, 2, 3, 4, a=3, b=4)
+
+# Anwendungsbereich von Funktionen
+x = 5
+
+def setX(num):
+ # lokale Variable x ist nicht die globale Variable x
+ x = num # => 43
+ print (x) # => 43
+
+def setGlobalX(num):
+ global x
+ print (x) # => 5
+ x = num # globale Variable x ist jetzt 6
+ print (x) # => 6
+
+setX(43)
+setGlobalX(6)
+
+
# Python hat First-Class-Funktionen
def create_adder(x):
def adder(y):
@@ -403,7 +510,7 @@ class Human(object):
# Eine Instanzmethode. Alle Methoden erhalten self als erstes Argument.
def say(self, msg):
- return "%s: %s" % (self.name, msg)
+ return "{name}: {message}".format(name=self.name, message=msg)
# Eine Klassenmethode wird von allen Instanzen geteilt.
# Sie werden mit der aufrufenden Klasse als erstem Argument aufgerufen
@@ -419,10 +526,10 @@ class Human(object):
# Eine Instanz einer Klasse erstellen
i = Human(name="Ian")
-print i.say("hi") # gibt "Ian: hi" aus
+print(i.say("hi")) # gibt "Ian: hi" aus
j = Human("Joel")
-print j.say("hello") #gibt "Joel: hello" aus
+print(j.say("hello")) #gibt "Joel: hello" aus
# Rufen wir mal unsere Klassenmethode auf
i.get_species() #=> "H. sapiens"
@@ -442,12 +549,12 @@ Human.grunt() #=> "*grunt*"
# Wir können Module importieren
import math
-print math.sqrt(16) #=> 4
+print(math.sqrt(16)) #=> 4.0
# Wir können auch nur spezielle Funktionen eines Moduls importieren
from math import ceil, floor
-print ceil(3.7) #=> 4.0
-print floor(3.7) #=> 3.0
+print(ceil(3.7)) #=> 4.0
+print(floor(3.7)) #=> 3.0
# Wir können auch alle Funktionen eines Moduls importieren
# Warnung: Dies wird nicht empfohlen
@@ -458,7 +565,7 @@ import math as m
math.sqrt(16) == m.sqrt(16) #=> True
# Module sind in Python nur gewöhnliche Dateien. Wir
-# können unsere eigenen schreiben und importieren. Der Name des
+# können unsere eigenen schreiben und importieren. Der Name des
# Moduls ist der Dateiname.
# Wir können auch die Funktionen und Attribute eines
@@ -466,6 +573,56 @@ math.sqrt(16) == m.sqrt(16) #=> True
import math
dir(math)
+####################################################
+## 7. Fortgeschritten
+####################################################
+
+# Generatoren helfen, um Code schnell und einfach zu schreiben
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# Ein Generator erschafft Werte spontan
+# Statt alle Werte auf einmal, wird bei jeder Iteration einer erschaffen.
+# iteration. Das heißt, Werte größer als 15 werden nicht behandelt.
+# Die range-Methode ist auch ein Generator. Im Fall einer Liste von 1-900000000
+# würde das sehr viel Zeit in Anspruch nehmen.
+# Wenn wir eine Variable mit einem Namen erschaffen wollen, das
+# normalerweise mit einem Python - Schlüsselwort kollidieren würde,
+# benutzen wir einen Unterstrich nach dem Wort.
+range_ = range(1, 900000000)
+# Alle Nummern bis zu einem Ergebnis von >=30 werden verdoppelt
+for i in double_numbers(range_):
+ print(i)
+ if i >= 30:
+ break
+
+# Dekoratoren
+# In diesem Beispiel die Methode beg umwickelt say
+# Beim Aufruf von beg, wird say aufgerufen
+# Falls say_please true ist, ändert sich die ausgegebene Nachricht
+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 :(
```
@@ -473,15 +630,18 @@ dir(math)
### Kostenlos online (Englisch)
+* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
* [Dive Into Python](http://www.diveintopython.net/)
-* [The Official Docs](http://docs.python.org/2.6/)
+* [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 Module of the Week](http://pymotw.com/2/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+* [Python Course](http://www.python-course.eu/index.php)
+* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
### Totholz (Englisch)
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
-
diff --git a/de-de/python3-de.html.markdown b/de-de/python3-de.html.markdown
deleted file mode 100644
index ef1786c8..00000000
--- a/de-de/python3-de.html.markdown
+++ /dev/null
@@ -1,655 +0,0 @@
----
-language: python3
-contributors:
- - ["Louie Dinh", "http://ldinh.ca"]
-translators:
- - ["kultprok", "http:/www.kulturproktologie.de"]
- - ["matthiaskern", "https://github.com/matthiaskern"]
-filename: learnpython3-de.py
-lang: de-de
----
-
-Anmerkungen des ursprünglichen Autors:
-Python wurde in den frühen Neunzigern von Guido van Rossum entworfen. Es ist heute eine der beliebtesten Sprachen. Ich habe mich in Python wegen seiner syntaktischen Übersichtlichkeit verliebt. Eigentlich ist es ausführbarer Pseudocode.
-
-Feedback ist herzlich willkommen! Ihr erreicht mich unter [@louiedinh](http://twitter.com/louiedinh) oder louiedinh [at] [google's email service].
-
-Hinweis: Dieser Beitrag bezieht sich insplizit auf Python 3. Falls du lieber Python 2.7 lernen möchtest, schau [hier](http://learnxinyminutes.com/docs/python/) weiter.
-
-```python
-
-# Einzeilige Kommentare beginnen mit einer Raute (Doppelkreuz)
-
-""" Mehrzeilige Strings werden mit
- drei '-Zeichen geschrieben und werden
- oft als Kommentare genutzt.
-"""
-
-####################################################
-## 1. Primitive Datentypen und Operatoren
-####################################################
-
-# Die Zahlen
-3 #=> 3
-
-# Mathematik funktioniert so, wie man das erwartet
-1 + 1 #=> 2
-8 - 1 #=> 7
-10 * 2 #=> 20
-
-# Außer Division, welche automatisch Gleitkommazahlen zurückgibt
-35 / 5 # => 7.0
-
-# Eine Division kann mit "//" für positive sowie negative Werte abgerundet werden.
-5 // 3 # => 1
-5.0 // 3.0 # => 1.0 # works on floats too
--5 // 3 # => -2
--5.0 // 3.0 # => -2.0
-
-# Benutzt man eine Gleitkommazahl, ist auch das Ergebnis eine solche
-3 * 2.0 # => 6.0
-
-# Der Rest einer Division
-7 % 3 # => 1
-
-# Potenz
-2**4 # => 16
-
-# Rangfolge wird mit Klammern erzwungen
-(1 + 3) * 2 #=> 8
-
-# Boolesche Ausdrücke sind primitive Datentypen
-True
-False
-
-# Mit not wird negiert
-not True #=> False
-not False #=> True
-
-# Boolesche Operatoren
-# Hinweis: "and" und "or" müssen klein geschrieben werden
-True and False #=> False
-False or True #=> True
-
-# Für die Benutzung von Booleschen Operatoren und ganzen Zahlen
-0 and 2 #=> 0
--5 or 0 #=> -5
-0 == False #=> True
-2 == True #=> False
-1 == True #=> True
-
-# Gleichheit ist ==
-1 == 1 #=> True
-2 == 1 #=> False
-
-# Ungleichheit ist !=
-1 != 1 #=> False
-2 != 1 #=> True
-
-# Ein paar weitere Vergleiche
-1 < 10 #=> True
-1 > 10 #=> False
-2 <= 2 #=> True
-2 >= 2 #=> True
-
-# Vergleiche können verknüpft werden!
-1 < 2 < 3 #=> True
-2 < 3 < 2 #=> False
-
-# Strings werden mit " oder ' gebildet
-"Das ist ein String."
-'Das ist auch ein String.'
-
-# Strings können auch addiert werden! Vermeide dies aber lieber.
-"Hallo " + "Welt!" #=> "Hallo Welt!"
-# Strings können ohne "+" addiert werden
-"Hallo " "welt!" # => "Hallo Welt!"
-
-# Ein String kann wie eine Liste von Zeichen verwendet werden
-"Das ist ein String"[0] #=> 'D'
-
-# .format kann Strings formatieren
-"{} können {} werden".format("Strings", "formatiert")
-
-# Schneller geht das mit Wiederholungen
-"{0} mag Spagetthi, {0} liebt es zu Schwimmen und ganz besonders mag {0} {1}".format("Hans", "Blattsalat")
-#=> "Hans mag Spagetthi, Hans liebt es zu Schwimmen und ganz besonders mag Hans Blattsalat"
-
-# Wir können Schlüsselwörter verwenden, wenn wir nicht abzählen wollen.
-"{name} will {food} essen".format(name="Bob", food="Lasagne")
-#=> "Bob will Lasagne kochen"
-
-#Falls dein Python 3 Code auch unter Python 2.5 oder darunter laufen soll, kann das alte Format benutzt werden:
-"%s können %s werden" % ("Strings", "interpoliert")
-
-
-# None ist ein Objekt
-None #=> None
-
-# Verwendet nicht das Symbol für Gleichheit `==`, um Objekte mit None zu vergleichen
-# Benutzt stattdessen `is`. Dieser Operator testet Objektidentität
-"etc" is None #=> False
-None is None #=> True
-
-
-
-# None, 0, und leere Strings/Listen werden alle als False bewertet.
-# Alle anderen Werte sind True
-bool(0) # => False
-bool("") # => False
-bool([]) #=> False
-bool({}) #=> False
-
-
-####################################################
-## 2. Variablen und Collections
-####################################################
-
-# Textausgabe ist sehr einfach
-print "Ich bin Python. Schön, dich kennenzulernen!"
-
-# Es gibt keinen Grund, Variablen vor der Zuweisung zu deklarieren.
-some_var = 5 # kleinschreibung_mit_unterstrichen entspricht der Norm
-some_var #=> 5
-
-# Das Ansprechen einer noch nicht deklarierte Variable löst eine Exception aus.
-# Unter "Kontrollstruktur" kann noch mehr über
-# Ausnahmebehandlung erfahren werden.
-some_unknown_var # Löst einen NameError aus
-
-# Listen speichern Sequenzen
-li = []
-# Wir können mit einer bereits gefüllten Liste anfangen
-other_li = [4, 5, 6]
-
-# append fügt Daten am Ende der Liste ein
-li.append(1) #li ist jetzt [1]
-li.append(2) #li ist jetzt [1, 2]
-li.append(4) #li ist jetzt [1, 2, 4]
-li.append(3) #li ist jetzt [1, 2, 4, 3]
-# Vom Ende der Liste mit pop entfernen
-li.pop() #=> 3 und li ist jetzt [1, 2, 4]
-# und dann wieder hinzufügen
-li.append(3) # li ist jetzt wieder [1, 2, 4, 3].
-
-# Greife auf Listen wie auf Arrays zu
-li[0] #=> 1
-# Das letzte Element ansehen
-li[-1] #=> 3
-
-# Bei Zugriffen außerhalb der Liste kommt es jedoch zu einem IndexError
-li[4] # Verursacht einen IndexError
-
-# Wir können uns Ranges mit Slice-Syntax ansehen
-li[1:3] #=> [2, 4]
-# Den Anfang auslassen
-li[2:] #=> [4, 3]
-# Das Ende auslassen
-li[:3] #=> [1, 2, 4]
-# Jeden Zweiten Eintrag auswählen
-li[::2] # =>[1, 4]
-# Eine umgekehrte Kopie zurückgeben
-li[::-1] # => [3, 4, 2, 1]
-# Jegliche Kombination dieser Syntax machen fortgeschrittene Slices möglich
-# li[Start:Ende:Schritt]
-
-# Ein bestimmtes Element mit del aus der Liste entfernen
-del li[2] # li ist jetzt [1, 2, 3]
-
-# Listen können addiert werden
-li + other_li #=> [1, 2, 3, 4, 5, 6] - Hinweis: li und other_li werden in Ruhe gelassen
-
-# Listen mit extend verknüpfen
-li.extend(other_li) # Jetzt ist li [1, 2, 3, 4, 5, 6]
-
-# Mit in auf Existenz eines Elements prüfen
-1 in li #=> True
-
-# Die Länge der Liste mit len ermitteln
-len(li) #=> 6
-
-
-# Tupel sind wie Listen, nur unveränderlich.
-tup = (1, 2, 3)
-tup[0] #=> 1
-tup[0] = 3 # Löst einen TypeError aus
-
-# Wir können all diese Listen-Dinge auch mit Tupeln anstellen
-len(tup) #=> 3
-tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
-tup[:2] #=> (1, 2)
-2 in tup #=> True
-
-# Wir können Tupel (oder Listen) in Variablen entpacken
-a, b, c = (1, 2, 3) # a ist jetzt 1, b ist jetzt 2 und c ist jetzt 3
-# Tupel werden standardmäßig erstellt, wenn wir uns die Klammern sparen
-d, e, f = 4, 5, 6
-# Es ist kinderleicht zwei Werte zu tauschen
-e, d = d, e # d is now 5 and e is now 4
-
-
-# Dictionarys (Wörterbucher) speichern Schlüssel-Werte-Paare
-empty_dict = {}
-# Hier ein gefülltes Wörterbuch
-filled_dict = {"one": 1, "two": 2, "three": 3}
-
-# Wir können Einträge mit [] nachschlagen
-filled_dict["one"] #=> 1
-
-# So holen wir alle Keys (Schlüssel) als Liste
-list(filled_dict.keys()) #=> ["three", "two", "one"]
-# Hinweis - Die Reihenfolge von Schlüsseln in der Liste ist nicht garantiert.
-# Einzelne Resultate können anders angeordnet sein.
-
-# Alle Values (Werte) als Liste
-list(filled_dict.values()) #=> [3, 2, 1]
-# Hinweis - Hier gelten dieselben Einschränkungen für die Reihenfolge wie bei Schlüsseln.
-
-# Das Vorhandensein eines Schlüssels im Wörterbuch mit "in" prüfen
-"one" in filled_dict #=> True
-1 in filled_dict #=> False
-
-# Einen nicht vorhandenenen Schlüssel zu suchen, löst einen KeyError aus
-filled_dict["four"] # KeyError
-
-# Mit der get-Methode verhindern wir das
-filled_dict.get("one") #=> 1
-filled_dict.get("four") #=> None
-# Die get-Methode unterstützt auch ein Standardargument, falls der Wert fehlt
-filled_dict.get("one", 4) #=> 1
-filled_dict.get("four", 4) #=> 4
-
-# Die setdefault-Methode ist ein sicherer Weg, ein neues Schlüssel-Wert-Paar anzulegen
-filled_dict.setdefault("five", 5) #filled_dict["five"] wird auf 5 gesetzt
-filled_dict.setdefault("five", 6) #filled_dict["five"] ist noch immer 5
-
-# Einträge zu einem Wörterbuch hinzufügen
-filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4}
-#filled_dict["four"] = 4 # noch ein Weg, Werte hinzuzufügen
-
-# Schlüssel von einem Wörterbuch entfernen
-del filled_dict["one"] # Entfert den Schlüssel "one"
-
-
-# Sets speichern Mengen
-empty_set = set()
-# Initialisieren wir ein Set mit ein paar Werten
-some_set = {1, 1, 2, 2, 3, 4} # some_set ist jetzt {1, 2, 3, 4}
-
-# Neue Variablen können einer Menge gleichgesetzt werden
-filled_set = some_set
-
-# Mehr Elemente hinzufügen
-filled_set.add(5) # filled_set ist jetzt {1, 2, 3, 4, 5}
-
-# Schnittmengen werden mit & gebildet
-other_set = {3, 4, 5, 6}
-filled_set & other_set #=> {3, 4, 5}
-
-# Mengen werden mit | vereinigt
-filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
-
-# Die Differenz einer Menge mit - bilden
-{1,2,3,4} - {2,3,5} #=> {1, 4}
-
-# Auf Vorhandensein von Elementen mit in prüfen
-2 in filled_set #=> True
-10 in filled_set #=> False
-
-
-####################################################
-## 3. Kontrollstruktur und Iteratoren
-####################################################
-
-# Erstellen wir mal eine Variable
-some_var = 5
-
-# Hier eine if-Anweisung. Die Einrückung ist in Python wichtig!
-# gibt "some_var ist kleiner als 10" aus
-if some_var > 10:
- print "some_var ist viel größer als 10."
-elif some_var < 10: # Dieser elif-Absatz ist optional.
- print "some_var ist kleiner als 10."
-else: # Das hier ist auch optional.
- print "some_var ist tatsächlich 10."
-
-
-"""
-For-Schleifen iterieren über Listen
-Ausgabe:
- hund ist ein Säugetier
- katze ist ein Säugetier
- maus ist ein Säugetier
-"""
-for animal in ["hund", "katze", "maus"]:
- # Wir können Strings mit format() formatieren
- print("{} ist ein Säugetier".format(animal))
-
-"""
-`range(Zahl)` gibt eine null-basierte Liste bis zur angegebenen Zahl wieder
-Ausgabe:
- 0
- 1
- 2
- 3
-"""
-for i in range(4):
- print i
-
-"""
-"range(unten, oben)" gibt eine Liste von der unteren Zahl bis zur oberen Zahl aus
-Ausgabe:
- 4
- 5
- 6
- 7
-"""
-for i in range(4, 8):
- print(i)
-
-"""
-While-Schleifen laufen, bis eine Bedingung erfüllt ist.
-Ausgabe:
- 0
- 1
- 2
- 3
-"""
-x = 0
-while x < 4:
- print x
- x += 1 # Kurzform für x = x + 1
-
-# Ausnahmebehandlung mit einem try/except-Block
-try:
- # Mit raise wird ein Fehler ausgegeben
- raise IndexError("Das hier ist ein Index-Fehler")
-except IndexError as e:
- pass # Pass ist nur eine no-op. Normalerweise würden wir hier den Fehler klären.
-except (TypeError, NameError):
- pass # Mehrere Fehler können zusammen geklärt werden, falls erforderlich.
-else: # Optional, hinter allen except-Blöcken
- print("Keine Probleme!") # Wird nur ausgeführt, wenn keine Ausnahmen aufgetreten sind
-finally: # Wird immer ausgeführt
- print("Hier können wir Ressourcen aufräumen")
-
-# alternativ zu einem try/finally Block um Aufzuräumen:
-with open("meineDatei.txt") as f:
- for line in f:
- print(line)
-
-# Python bietet ein fundamentales Konzept der Iteration.
-# Das Objekt, auf das die Interation, also die Wiederholung einer Methode angewandt wird heißt auf Englisch "iterable".
-# Die range Method gibt ein solches Objekt aus.
-
-filled_dict = {"one": 1, "two": 2, "three": 3}
-our_iterable = filled_dict.keys()
-print(our_iterable) #=> range(1,10). Dies ist ein "iterable" Objekt.
-
-# Über dieses können wir auch iterieren
-for i in our_iterable:
- print(i) # Gibt one, two, three aus
-
-# Allerdings können wir die einzelnen Elemente nicht mit ihrem index ausgeben
-our_iterable[1] # TypeError
-
-# Ein iterable ist ein Objekt, das weiß wie es einen Iteratoren erschafft.
-our_iterator = iter(our_iterable)
-
-# Unser Iterator ist ein Objekt, das sich merkt, welchen Status es geraden hat während wir durch es gehen.
-# Das jeweeils nächste Objekt bekommen wir mit "next()"
-next(our_iterator) #=> "one"
-
-# Es hält den vorherigen Status
-next(our_iterator) #=> "two"
-next(our_iterator) #=> "three"
-
-# Nachdem alle Daten ausgegeben worden sind, kommt eine StopIterator Ausnahme zurück
-next(our_iterator) # Gibt StopIteration aus
-
-# Alle Elemente können mit "list()" ausgegeben werden
-list(filled_dict.keys()) #=> ["one", "two", "three"]
-
-
-
-####################################################
-## 4. Funktionen
-####################################################
-
-# Mit def neue Funktionen erstellen
-def add(x, y):
- print "x ist %s und y ist %s" % (x, y)
- return x + y # Werte werden mit return zurückgegeben
-
-# Funktionen mit Parametern aufrufen
-add(5, 6) #=> Ausgabe ist "x ist 5 und y ist 6" und gibt 11 zurück
-
-# Ein anderer Weg des Funktionsaufrufs sind Schlüsselwort-Argumente
-add(y=6, x=5) # Schlüsselwörter können in beliebiger Reihenfolge übergeben werden.
-
-# Wir können Funktionen mit beliebiger Anzahl von # Positionsargumenten definieren
-def varargs(*args):
- return args
-
-varargs(1, 2, 3) #=> (1,2,3)
-
-
-# Wir können auch Funktionen mit beliebiger Anzahl
-# Schlüsselwort-Argumenten definieren
-def keyword_args(**kwargs):
- return kwargs
-
-# Rufen wir es mal auf, um zu sehen, was passiert
-keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
-
-# Wir können beides gleichzeitig machem, wenn wir wollen
-def all_the_args(*args, **kwargs):
- print args
- print kwargs
-"""
-all_the_args(1, 2, a=3, b=4) Ausgabe:
- (1, 2)
- {"a": 3, "b": 4}
-"""
-
-# Beim Aufruf von Funktionen können wir das Gegenteil von varargs/kwargs machen!
-# Wir benutzen dann *, um Tupel auszuweiten, und ** für kwargs.
-args = (1, 2, 3, 4)
-kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # äquivalent zu foo(1, 2, 3, 4)
-all_the_args(**kwargs) # äquivalent zu foo(a=3, b=4)
-all_the_args(*args, **kwargs) # äquivalent zu foo(1, 2, 3, 4, a=3, b=4)
-
-
-# Anwendungsbereich von Funktionen
-x = 5
-
-def setX(num):
- # lokale Variable x ist nicht die globale Variable x
- x = num # => 43
- print (x) # => 43
-
-def setGlobalX(num):
- global x
- print (x) # => 5
- x = num # globale Variable x ist jetzt 6
- print (x) # => 6
-
-setX(43)
-setGlobalX(6)
-
-
-# Python hat First-Class-Funktionen
-def create_adder(x):
- def adder(y):
- return x + y
- return adder
-
-add_10 = create_adder(10)
-add_10(3) #=> 13
-
-# Es gibt auch anonyme Funktionen
-(lambda x: x > 2)(3) #=> True
-
-# Es gibt auch Funktionen höherer Ordnung als Built-Ins
-map(add_10, [1,2,3]) #=> [11, 12, 13]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
-
-# Wir können bei map- und filter-Funktionen auch List Comprehensions einsetzen
-[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
-[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
-
-####################################################
-## 5. Klassen
-####################################################
-
-# Wir bilden die Unterklasse eines Objekts, um Klassen zu erhalten.
-class Human(object):
-
- # Ein Klassenattribut. Es wird von allen Instanzen einer Klasse geteilt
- species = "H. sapiens"
-
- # Ein simpler Konstruktor
- def __init__(self, name):
- # Wir weisen das Argument name dem name-Attribut der Instanz zu
- self.name = name
-
- # Eine Instanzmethode. Alle Methoden erhalten self als erstes Argument.
- def say(self, msg):
- return "{name}: {message}".format(name=self.name, message=msg)
-
- # Eine Klassenmethode wird von allen Instanzen geteilt.
- # Sie werden mit der aufrufenden Klasse als erstem Argument aufgerufen
- @classmethod
- def get_species(cls):
- return cls.species
-
- # Eine statische Methode wird ohne Klasse oder Instanz aufgerufen
- @staticmethod
- def grunt():
- return "*grunt*"
-
-
-# Eine Instanz einer Klasse erstellen
-i = Human(name="Ian")
-print i.say("hi") # gibt "Ian: hi" aus
-
-j = Human("Joel")
-print j.say("hello") #gibt "Joel: hello" aus
-
-# Rufen wir mal unsere Klassenmethode auf
-i.get_species() #=> "H. sapiens"
-
-# Ändern wir mal das gemeinsame Attribut
-Human.species = "H. neanderthalensis"
-i.get_species() #=> "H. neanderthalensis"
-j.get_species() #=> "H. neanderthalensis"
-
-# Aufruf der statischen Methode
-Human.grunt() #=> "*grunt*"
-
-
-####################################################
-## 6. Module
-####################################################
-
-# Wir können Module importieren
-import math
-print math.sqrt(16) #=> 4
-
-# Wir können auch nur spezielle Funktionen eines Moduls importieren
-from math import ceil, floor
-print ceil(3.7) #=> 4.0
-print floor(3.7) #=> 3.0
-
-# Wir können auch alle Funktionen eines Moduls importieren
-# Warnung: Dies wird nicht empfohlen
-from math import *
-
-# Wir können Modulnamen abkürzen
-import math as m
-math.sqrt(16) == m.sqrt(16) #=> True
-
-# Module sind in Python nur gewöhnliche Dateien. Wir
-# können unsere eigenen schreiben und importieren. Der Name des
-# Moduls ist der Dateiname.
-
-# Wir können auch die Funktionen und Attribute eines
-# Moduls herausfinden.
-import math
-dir(math)
-
-
-####################################################
-## 7. Fortgeschritten
-####################################################
-
-# Generatoren helfen um Code schnell und einfach zu schreiben
-def double_numbers(iterable):
- for i in iterable:
- yield i + i
-
-# Ein Generator erschafft Werte spontan
-# Statt alle Werte auf einmal, wird bei jeder Iteration einer erschaffen.
-# iteration. Das heißt, Werte größer als 15 werden nicht behandelt.
-# Die range-Methode ist auch ein Generator. Im Fall einer Liste von 1-900000000
-# würde das sehr viel Zeit in Anspruch nehmen.
-# Wenn wir eine variable mit einem Namen erschaffen wollen, das
-# normalerweise mit einem Python - Schlüsselwort kollidieren würde,
-# benutzen wir einen Unterstrich nach dem Wort.
-range_ = range(1, 900000000)
-# Alle Nummern bis zu einem Ergebnis von >=30 werden verdoppelt
-for i in double_numbers(range_):
- print(i)
- if i >= 30:
- break
-
-
-# Dekoratoren
-# In diesem Beispiel die Methode beg umwickelt say
-# Beim Aufruf von beg, say wird aufgerufen
-# Falls say_please true ist, ändert sich die ausgegebene Nachricht
-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 :(
-
-```
-
-## Lust auf mehr?
-
-### Kostenlos online (Englisch)
-
-* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
-* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
-* [Dive Into Python](http://www.diveintopython.net/)
-* [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/)
-* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
-* [Python Course](http://www.python-course.eu/index.php)
-* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
-
-### Totholz (Englisch)
-
-* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
-* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
-* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
diff --git a/de-de/pythonlegacy-de.html.markdown b/de-de/pythonlegacy-de.html.markdown
new file mode 100644
index 00000000..d66a8551
--- /dev/null
+++ b/de-de/pythonlegacy-de.html.markdown
@@ -0,0 +1,766 @@
+---
+language: Python 2 (legacy)
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+translators:
+ - ["kultprok", "http:/www.kulturproktologie.de"]
+filename: learnpythonlegacy-de.py
+lang: de-de
+---
+
+Anmerkungen des ursprünglichen Autors:
+Python wurde in den frühen Neunzigern von Guido van Rossum entworfen. Es ist heute eine der beliebtesten Sprachen. Ich habe mich in Python wegen seiner syntaktischen Übersichtlichkeit verliebt. Eigentlich ist es ausführbarer Pseudocode.
+
+Feedback ist herzlich willkommen! Ihr erreicht mich unter [@louiedinh](http://twitter.com/louiedinh) oder louiedinh [at] [google's email service]
+
+Hinweis: Dieser Beitrag bezieht sich besonders auf Python 2.7, er sollte aber auf Python 2.x anwendbar sein. Haltet Ausschau nach einem Rundgang durch Python 3, der bald erscheinen soll.
+
+```python
+# Einzeilige Kommentare beginnen mit einer Raute (Doppelkreuz)
+""" Mehrzeilige Strings werden mit
+ drei '-Zeichen geschrieben und werden
+ oft als Kommentare genutzt.
+"""
+
+####################################################
+## 1. Primitive Datentypen und Operatoren
+####################################################
+
+# Die Zahlen
+3 #=> 3
+
+# Mathematik funktioniert so, wie man das erwartet
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# Division ist ein wenig kniffliger. Ganze Zahlen werden ohne Rest dividiert
+# und das Ergebnis wird automatisch abgerundet.
+5 / 2 #=> 2
+
+# Um das zu ändern, müssen wir Gleitkommazahlen einführen und benutzen
+2.0 # Das ist eine Gleitkommazahl
+11.0 / 4.0 #=> 2.75 Ahhh...schon besser
+
+# Rangfolge wird mit Klammern erzwungen
+(1 + 3) * 2 #=> 8
+
+# Boolesche Ausdrücke sind primitive Datentypen
+True
+False
+
+# Mit not wird negiert
+not True #=> False
+not False #=> True
+
+# Gleichheit ist ==
+1 == 1 #=> True
+2 == 1 #=> False
+
+# Ungleichheit ist !=
+1 != 1 #=> False
+2 != 1 #=> True
+
+# Ein paar weitere Vergleiche
+1 < 10 #=> True
+1 > 10 #=> False
+2 <= 2 #=> True
+2 >= 2 #=> True
+
+# Vergleiche können verknüpft werden!
+1 < 2 < 3 #=> True
+2 < 3 < 2 #=> False
+
+# Strings werden mit " oder ' gebildet
+"Das ist ein String."
+'Das ist auch ein String.'
+
+# Strings können addiert werden!
+"Hello " + "world!" #=> "Hello world!"
+
+# Ein String kann wie eine Liste von Zeichen verwendet werden
+"Das ist ein String"[0] #=> 'D'
+
+# Mit % können Strings formatiert werden, etwa so:
+"%s können %s werden" % ("Strings", "interpoliert")
+
+# Ein modernerer Weg, um Strings zu formatieren, ist die format-Methode.
+# Diese Methode wird bevorzugt
+"{0} können {1} werden".format("Strings", "formatiert")
+# Wir können Schlüsselwörter verwenden, wenn wir nicht abzählen wollen.
+"{name} will {food} essen".format(name="Bob", food="Lasagne")
+
+# None ist ein Objekt
+None #=> None
+
+# Verwendet nicht das Symbol für Gleichheit `==`, um Objekte mit None zu vergleichen
+# Benutzt stattdessen `is`
+"etc" is None #=> False
+None is None #=> True
+
+# Der 'is'-Operator testet Objektidentität. Das ist nicht
+# sehr nützlich, wenn wir mit primitiven Datentypen arbeiten, aber
+# sehr nützlich bei Objekten.
+
+# None, 0, und leere Strings/Listen werden alle als False bewertet.
+# Alle anderen Werte sind True
+0 == False #=> True
+"" == False #=> True
+
+
+####################################################
+## 2. Variablen und Collections
+####################################################
+
+# Textausgabe ist sehr einfach
+print "Ich bin Python. Schön, dich kennenzulernen!"
+
+
+# Es gibt keinen Grund, Variablen vor der Zuweisung zu deklarieren.
+some_var = 5 # kleinschreibung_mit_unterstrichen entspricht der Norm
+some_var #=> 5
+
+# Das Ansprechen einer noch nicht deklarierte Variable löst eine Exception aus.
+# Unter "Kontrollstruktur" kann noch mehr über
+# Ausnahmebehandlung erfahren werden.
+some_other_var # Löst einen NameError aus
+
+# if kann als Ausdruck verwendet werden
+"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+
+# Listen speichern Sequenzen
+li = []
+# Wir können mit einer bereits gefüllten Liste anfangen
+other_li = [4, 5, 6]
+
+# append fügt Daten am Ende der Liste ein
+li.append(1) #li ist jetzt [1]
+li.append(2) #li ist jetzt [1, 2]
+li.append(4) #li ist jetzt [1, 2, 4]
+li.append(3) #li ist jetzt [1, 2, 4, 3]
+# Vom Ende der Liste mit pop entfernen
+li.pop() #=> 3 und li ist jetzt [1, 2, 4]
+# und dann wieder hinzufügen
+li.append(3) # li ist jetzt wieder [1, 2, 4, 3].
+
+# Greife auf Listen wie auf Arrays zu
+li[0] #=> 1
+# Das letzte Element ansehen
+li[-1] #=> 3
+
+# Bei Zugriffen außerhalb der Liste kommt es jedoch zu einem IndexError
+li[4] # Raises an IndexError
+
+# Wir können uns Ranges mit Slice-Syntax ansehen
+li[1:3] #=> [2, 4]
+# Den Anfang auslassen
+li[2:] #=> [4, 3]
+# Das Ende auslassen
+li[:3] #=> [1, 2, 4]
+
+# Ein bestimmtes Element mit del aus der Liste entfernen
+del li[2] # li ist jetzt [1, 2, 3]
+
+# Listen können addiert werden
+li + other_li #=> [1, 2, 3, 4, 5, 6] - Hinweis: li und other_li werden in Ruhe gelassen
+
+# Listen mit extend verknüpfen
+li.extend(other_li) # Jetzt ist li [1, 2, 3, 4, 5, 6]
+
+# Mit in auf Existenz eines Elements prüfen
+1 in li #=> True
+
+# Die Länge der Liste mit len ermitteln
+len(li) #=> 6
+
+
+# Tupel sind wie Listen, nur unveränderlich.
+tup = (1, 2, 3)
+tup[0] #=> 1
+tup[0] = 3 # Löst einen TypeError aus
+
+# Wir können all diese Listen-Dinge auch mit Tupeln anstellen
+len(tup) #=> 3
+tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
+tup[:2] #=> (1, 2)
+2 in tup #=> True
+
+# Wir können Tupel (oder Listen) in Variablen entpacken
+a, b, c = (1, 2, 3) # a ist jetzt 1, b ist jetzt 2 und c ist jetzt 3
+# Tupel werden standardmäßig erstellt, wenn wir uns die Klammern sparen
+d, e, f = 4, 5, 6
+# Es ist kinderleicht zwei Werte zu tauschen
+e, d = d, e # d is now 5 and e is now 4
+
+
+# Dictionarys (Wörterbucher) speichern Key-Value-Paare
+empty_dict = {}
+# Hier ein gefülltes Wörterbuch
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Wir können Einträge mit [] nachschlagen
+filled_dict["one"] #=> 1
+
+# So holen wir alle Keys (Schlüssel) als Liste
+filled_dict.keys() #=> ["three", "two", "one"]
+# Hinweis - Die Reihenfolge von Schlüsseln in der Liste ist nicht garantiert.
+# Einzelne Resultate können anders angeordnet sein.
+
+# Alle Values (Werte) als Liste
+filled_dict.values() #=> [3, 2, 1]
+# Hinweis - Hier gelten dieselben Einschränkungen für die Reihenfolge wie bei Schlüsseln.
+
+# Das Vorhandensein eines Schlüssels im Wörterbuch mit in prüfen
+"one" in filled_dict #=> True
+1 in filled_dict #=> False
+
+# Einen nicht vorhandenenen Schlüssel zu suchen, löst einen KeyError aus
+filled_dict["four"] # KeyError
+
+# Mit der get-Methode verhindern wir das
+filled_dict.get("one") #=> 1
+filled_dict.get("four") #=> None
+# Die get-Methode unterstützt auch ein Standardargument, falls der Wert fehlt
+filled_dict.get("one", 4) #=> 1
+filled_dict.get("four", 4) #=> 4
+
+# Die setdefault-Methode ist ein sicherer Weg, ein neues Schlüssel-Wert-Paar anzulegen
+filled_dict.setdefault("five", 5) #filled_dict["five"] wird auf 5 gesetzt
+filled_dict.setdefault("five", 6) #filled_dict["five"] ist noch immer 5
+
+
+# Sets speichern Mengen
+empty_set = set()
+# Initialisieren wir ein Set mit ein paar Werten
+some_set = set([1,2,2,3,4]) # some_set ist jetzt set([1, 2, 3, 4])
+
+# Seit Python 2.7 kann {} benutzt werden, um ein Set zu erstellen
+filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+
+# Mehr Elemente hinzufügen
+filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
+
+# Schnittmengen werden mit & gebildet
+other_set = {3, 4, 5, 6}
+filled_set & other_set #=> {3, 4, 5}
+
+# Mengen werden mit | vereinigt
+filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+
+# Die Differenz einer Menge mit - bilden
+{1,2,3,4} - {2,3,5} #=> {1, 4}
+
+# Auf Vorhandensein von Elementen mit in prüfen
+2 in filled_set #=> True
+10 in filled_set #=> False
+
+
+####################################################
+## 3. Kontrollstruktur
+####################################################
+
+# Erstellen wir mal eine Variable
+some_var = 5
+
+# Hier eine if-Anweisung. Die Einrückung ist in Python wichtig!
+# gibt "some_var ist kleiner als 10" aus
+if some_var > 10:
+ print "some_var ist viel größer als 10."
+elif some_var < 10: # Dieser elif-Absatz ist optional.
+ print "some_var ist kleiner als 10."
+else: # Das hier ist auch optional.
+ print "some_var ist tatsächlich 10."
+
+
+"""
+For-Schleifen iterieren über Listen
+Ausgabe:
+ hund ist ein Säugetier
+ katze ist ein Säugetier
+ maus ist ein Säugetier
+"""
+for animal in ["hund", "katze", "maus"]:
+ # Wir können Strings mit % formatieren
+ print "%s ist ein Säugetier" % animal
+
+"""
+`range(Zahl)` gibt eine null-basierte Liste bis zur angegebenen Zahl wieder
+Ausgabe:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+While-Schleifen laufen, bis eine Bedingung erfüllt ist.
+Ausgabe:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # Kurzform für x = x + 1
+
+# Ausnahmebehandlung mit einem try/except-Block
+
+# Funktioniert in Python 2.6 und höher:
+try:
+ # Mit raise wird ein Fehler ausgegeben
+ raise IndexError("Das hier ist ein Index-Fehler")
+except IndexError as e:
+ pass # Pass ist nur eine no-op. Normalerweise würden wir hier den Fehler klären.
+
+
+####################################################
+## 4. Funktionen
+####################################################
+
+# Mit def neue Funktionen erstellen
+def add(x, y):
+ print "x ist %s und y ist %s" % (x, y)
+ return x + y # Werte werden mit return zurückgegeben
+
+# Funktionen mit Parametern aufrufen
+add(5, 6) #=> Ausgabe ist "x ist 5 und y ist 6" und gibt 11 zurück
+
+# Ein anderer Weg des Funktionsaufrufs sind Schlüsselwort-Argumente
+add(y=6, x=5) # Schlüsselwörter können in beliebiger Reihenfolge übergeben werden.
+
+# Wir können Funktionen mit beliebiger Anzahl von # Positionsargumenten definieren
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) #=> (1,2,3)
+
+
+# Wir können auch Funktionen mit beliebiger Anzahl
+# Schlüsselwort-Argumenten definieren
+def keyword_args(**kwargs):
+ return kwargs
+
+# Rufen wir es mal auf, um zu sehen, was passiert
+keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+
+# Wir können beides gleichzeitig machem, wenn wir wollen
+def all_the_args(*args, **kwargs):
+ print args
+ print kwargs
+"""
+all_the_args(1, 2, a=3, b=4) Ausgabe:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Beim Aufruf von Funktionen können wir das Gegenteil von varargs/kwargs machen!
+# Wir benutzen dann *, um Tupel auszuweiten, und ** für kwargs.
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # äquivalent zu foo(1, 2, 3, 4)
+all_the_args(**kwargs) # äquivalent zu foo(a=3, b=4)
+all_the_args(*args, **kwargs) # äquivalent zu foo(1, 2, 3, 4, a=3, b=4)
+
+# Python hat First-Class-Funktionen
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) #=> 13
+
+# Es gibt auch anonyme Funktionen
+(lambda x: x > 2)(3) #=> True
+
+# Es gibt auch Funktionen höherer Ordnung als Built-Ins
+map(add_10, [1,2,3]) #=> [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+
+# Wir können bei map- und filter-Funktionen auch List Comprehensions einsetzen
+[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
+
+
+####################################################
+## 5. Module
+####################################################
+
+# Wir können Module importieren
+import math
+print math.sqrt(16) #=> 4.0
+
+# Wir können auch nur spezielle Funktionen eines Moduls importieren
+from math import ceil, floor
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
+
+# Wir können auch alle Funktionen eines Moduls importieren
+# Warnung: Dies wird nicht empfohlen
+from math import *
+
+# Wir können Modulnamen abkürzen
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
+
+# Module sind in Python nur gewöhnliche Dateien. Wir
+# können unsere eigenen schreiben und importieren. Der Name des
+# Moduls ist der Dateiname.
+
+# Wir können herausfinden, welche Funktionen und Attribute in einem
+# Modul definiert sind.
+import math
+dir(math)
+
+# Wenn Sie ein Python-Skript namens math.py im selben Ordner
+# wie Ihr aktuelles Skript haben, wird die Datei math.py
+# anstelle des integrierten Python-Moduls geladen.
+# Dies geschieht, weil der lokale Ordner Vorrang
+# vor den in Python integrierten Bibliotheken hat.
+
+
+####################################################
+## 6. Klassen
+####################################################
+
+# Wir verwenden das Schlüsselwort "class" um eine Klasse zu erzeugen.
+class Human(object):
+
+ # Ein Klassenattribut. Es wird von allen Instanzen einer Klasse geteilt
+ species = "H. sapiens"
+
+ # Ein simpler Konstruktor, wird aufgerufen, wenn diese Klasse instanziiert wird.
+ # Beachten Sie, dass die doppelten vorangestellten und nachgestellten
+ # Unterstriche Objekte oder Attribute bezeichnen, die von Python verwendet werden,
+ # aber in benutzergesteuerten Namespaces leben.
+ # Methoden (oder Objekte oder Attribute) wie: __init__, __str__, __repr__ usw.
+ # werden als Sondermethoden (oder manchmal als Dundermethoden bezeichnet) bezeichnet.
+ # Sie sollten solche Namen nicht selbst erfinden.
+ def __init__(self, name):
+ # Wir weisen das Argument name dem name-Attribut der Instanz zu
+ self.name = name
+
+ # Eine Instanzmethode. Alle Methoden erhalten "self" als erstes Argument.
+ def say(self, msg):
+ return "%s: %s" % (self.name, msg)
+
+ # Eine weitere Instanzmethode
+ def sing(self):
+ return 'yo... yo... microphone check... one two... one two...'
+
+ # Eine Klassenmethode wird von allen Instanzen geteilt.
+ # Sie werden mit der aufrufenden Klasse als erstem Argument aufgerufen
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Eine statische Methode wird ohne Klasse oder Instanz aufgerufen
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+ # Eine Eigenschaft (Property) ist wie ein Getter.
+    # Es verwandelt die Methode age() in ein schreibgeschütztes Attribut mit demselben Namen.
+    # Es ist jedoch nicht nötig, triviale Getter und Setter in Python zu schreiben.
+ @property
+ def age(self):
+ return self._age
+
+    # Damit kann die Eigenschaft festgelegt werden
+ @age.setter
+ def age(self, age):
+ self._age = age
+
+    # Damit kann die Eigenschaft gelöscht werden
+ @age.deleter
+ def age(self):
+ del self._age
+
+# Wenn ein Python-Interpreter eine Quelldatei liest, führt er den gesamten Code aus.
+# Diese __name__-Prüfung stellt sicher, dass dieser Codeblock nur ausgeführt wird,
+# wenn dieses Modul das Hauptprogramm ist.
+if __name__ == '__main__':
+ # Eine Instanz einer Klasse erstellen
+ i = Human(name="Ian")
+ i.say("hi") # "Ian: hi"
+ j = Human("Joel")
+ j.say("hello") # "Joel: hello"
+ # i und j sind Instanzen des Typs Mensch, oder anders ausgedrückt: Sie sind Objekte des Menschen
+
+ # Rufen wir unsere Klassenmethode auf
+ i.say(i.get_species()) # "Ian: H. sapiens"
+
+ # Ändern wir das gemeinsame Attribut
+ Human.species = "H. neanderthalensis"
+ i.say(i.get_species()) # => "Ian: H. neanderthalensis"
+ j.say(j.get_species()) # => "Joel: H. neanderthalensis"
+
+ # Aufruf der statischen Methode
+ print(Human.grunt()) # => "*grunt*"
+
+ # Kann keine statische Methode mit Instanz des Objekts aufrufen,
+ # da i.grunt () automatisch "self" (das Objekt i) als Argument verwendet
+ print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
+
+ # Die Eigenschaft für diese Instanz aktualisieren
+ i.age = 42
+ # die Eigenschaft auslesen
+ i.say(i.age) # => "Ian: 42"
+ j.say(j.age) # => "Joel: 0"
+ # die Eigenschaft löschen
+ del i.age
+ # i.age # => würde einen AttributeError werfen
+
+####################################################
+## 6.1 Inheritance
+####################################################
+
+# Vererbung ermöglicht die Definition neuer untergeordneter Klassen,
+# die Methoden und Variablen von ihrer übergeordneten Klasse erben.
+
+# Wenn Sie die oben definierte Human-Klasse als Basis- oder Elternklasse verwenden,
+# können Sie eine untergeordnete Klasse, Superhero, definieren, die die Klassenvariablen
+# wie "species", "name" und "age" sowie Methoden wie "sing" und "grunzen" aus der Klasse Human erbt.
+# Die Untergeordnete Klasse kann aber auch eigene Eigenschaften haben.
+
+# Um von der Modularisierung per Datei zu profitieren, können Sie die Klassen
+# in ihren eigenen Dateien platzieren, z. B. human.py
+
+# Um Funktionen aus anderen Dateien zu importieren, verwenden Sie das folgende Format
+# from "Dateiname-ohne-Erweiterung" impotr "Funktion-oder-Klasse"
+
+from human import Human
+
+# Geben Sie die übergeordnete(n) Klasse(n) als Parameter für die Klassendefinition an
+class Superhero(Human):
+
+ # Wenn die untergeordnete Klasse alle Definitionen des übergeordneten Elements
+ # ohne Änderungen erben soll, können Sie einfach das Schlüsselwort "pass"
+ # (und nichts anderes) verwenden. In diesem Fall wird jedoch auskommentiert,
+ # um eine eindeutige untergeordnete Klasse zuzulassen:
+ # pass
+
+ # Kindklassen können die Attribute ihrer Eltern überschreiben
+ species = 'Superhuman'
+
+ # Kinder erben automatisch den Konstruktor ihrer übergeordneten Klasse
+ # einschließlich ihrer Argumente, können aber auch zusätzliche Argumente oder
+ # Definitionen definieren und ihre Methoden zB den Klassenkonstruktor überschreiben.
+ # Dieser Konstruktor erbt das Argument "name" von der Klasse "Human" und
+ # fügt die Argumente "superpowers" und "movie" hinzu:
+ def __init__(self, name, movie=False,
+ superpowers=["super strength", "bulletproofing"]):
+
+ # zusätzliche Klassenattribute hinzufügen:
+ self.fictional = True
+ self.movie = movie
+ # Beachten Sie die veränderlichen Standardwerte, da die Standardwerte gemeinsam genutzt werden
+ self.superpowers = superpowers
+
+ # Mit der Funktion "super" können Sie auf die Methoden der übergeordneten Klasse
+ # zugreifen, die vom untergeordneten Objekt überschrieben werden,
+ # in diesem Fall die Methode __init__.
+        # Dies ruft den Konstruktor der übergeordneten Klasse auf:
+ super().__init__(name)
+
+ # überschreiben der "sing" Methode
+ def sing(self):
+ return 'Dun, dun, DUN!'
+
+ # eine zusätzliche Instanzmethode hinzufügen
+ def boast(self):
+ for power in self.superpowers:
+ print("I wield the power of {pow}!".format(pow=power))
+
+if __name__ == '__main__':
+ sup = Superhero(name="Tick")
+
+ # Instanztypprüfungen
+ if isinstance(sup, Human):
+ print('I am human')
+ if type(sup) is Superhero:
+ print('I am a superhero')
+
+ # Die Reihenfolge der Methodenauflösung (MRO = Method Resolution Order) anzeigen, die sowohl von getattr() als auch von super() verwendet wird.
+    # Dieses Attribut ist dynamisch und kann aktualisiert werden.
+ print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
+ # => <class 'human.Human'>, <class 'object'>)
+
+ # Ruft die übergeordnete Methode auf, verwendet jedoch das eigene Klassenattribut
+ print(sup.get_species()) # => Superhuman
+
+ # Ruft die überschriebene Methode auf
+ print(sup.sing()) # => Dun, dun, DUN!
+
+ # Ruft die Methode von Human auf
+ sup.say('Spoon') # => Tick: Spoon
+
+ # Aufruf einer Methode, die nur in Superhero existiert
+ sup.boast() # => I wield the power of super strength!
+ # => I wield the power of bulletproofing!
+
+ # Vererbtes Klassenattribut
+ sup.age = 31
+ print(sup.age) # => 31
+
+ # Attribut, das nur in Superhero existiert
+ print('Am I Oscar eligible? ' + str(sup.movie))
+
+####################################################
+## 6.2 Multiple Inheritance
+####################################################
+
+# Eine weitere Klassendefinition
+# bat.py
+
+class Bat:
+
+ species = 'Baty'
+
+ def __init__(self, can_fly=True):
+ self.fly = can_fly
+
+ # This class also has a say method
+ def say(self, msg):
+ msg = '... ... ...'
+ return msg
+
+ # And its own method as well
+ def sonar(self):
+ return '))) ... ((('
+
+if __name__ == '__main__':
+ b = Bat()
+ print(b.say('hello'))
+ print(b.fly)
+
+# Und noch eine andere Klassendefinition, die von Superhero und Bat erbt
+# superhero.py
+from superhero import Superhero
+from bat import Bat
+
+# Definieren Sie Batman als eine Kindklasse, das von Superheld und Bat erbt
+class Batman(Superhero, Bat):
+
+ def __init__(self, *args, **kwargs):
+ # In der Regel müssen Sie super aufrufen, um Attribute zu erben:
+ # super (Batman, selbst) .__ init__ (* args, ** kwargs)
+ # Allerdings handelt es sich hier um Mehrfachvererbung, und super()
+ # funktioniert nur mit der nächsten Basisklasse in der MRO-Liste.
+ # Stattdessen rufen wir explizit __init__ für alle Vorfahren auf.
+ # Die Verwendung von *args und **kwargs ermöglicht die saubere Übergabe von
+ # Argumenten, wobei jedes übergeordnete Element eine Schicht der Zwiebel "abschält".
+ Superhero.__init__(self, 'anonymous', movie=True,
+ superpowers=['Wealthy'], *args, **kwargs)
+ Bat.__init__(self, *args, can_fly=False, **kwargs)
+ # überschreibt den Wert für das Namensattribut
+ self.name = 'Sad Affleck'
+
+ def sing(self):
+ return 'nan nan nan nan nan batman!'
+
+if __name__ == '__main__':
+ sup = Batman()
+
+ # Die Reihenfolge der Methodenauflösung (MRO = Method Resolution Order) anzeigen,
+ # die sowohl von getattr() als auch von super() verwendet wird.
+ # Dieses Attribut ist dynamisch und kann aktualisiert werden.
+ print(Batman.__mro__) # => (<class '__main__.Batman'>,
+ # => <class 'superhero.Superhero'>,
+ # => <class 'human.Human'>,
+ # => <class 'bat.Bat'>, <class 'object'>)
+
+ # Ruft die übergeordnete Methode auf, verwendet jedoch das eigene Klassenattribut
+ print(sup.get_species()) # => Superhuman
+
+ # Ruft die überschriebene Methode auf
+ print(sup.sing()) # => nan nan nan nan nan batman!
+
+ # Ruft die Methode von Human auf, weil die Reihenfolge der Vererbung wichtig ist
+ sup.say('I agree') # => Sad Affleck: I agree
+
+ # Aufrufmethode, die nur im 2. Vorfahren existiert
+ print(sup.sonar()) # => ))) ... (((
+
+ # Vererbtes Klassenattribut
+ sup.age = 100
+ print(sup.age) # => 100
+
+ # Vererbtes Attribut vom 2. Vorfahren, dessen Standardwert überschrieben wurde.
+ print('Can I fly? ' + str(sup.fly)) # => Can I fly? False
+
+
+####################################################
+## 7. Fortgeschrittenes
+####################################################
+
+# Generatoren helfen Ihnen, lazy Code zu erstellen.
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# Generatoren sind speichereffizient, da sie nur die Daten laden,
+# die zur Verarbeitung des nächsten Werts in der iterierbaren Komponente
+# erforderlich sind. Dadurch können sie ansonsten unzulässig große Wertebereiche ausführen.
+# HINWEIS: `range` ersetzt` xrange` in Python 3.
+for i in double_numbers(range(1, 900000000)): # `range` ist ein Generator.
+ print(i)
+ if i >= 30:
+ break
+
+# Genauso wie Sie ein 'list comprehension' (Listen Abstraktion) erstellen können, können Sie auch 'generator comprehension' (Generator Abstraktion) erstellen.
+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
+
+# Sie können eine Generator Abstraktion auch direkt in eine Liste umwandeln (casten).
+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 diesem Beispiel umschliesst "beg" "say". Wenn say_please True ist, wird die zurückgegebene Nachricht geändert.
+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 :(
+
+```
+
+## Lust auf mehr?
+
+### Kostenlos online (Englisch)
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+
+### Totholz (Englisch)
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+
diff --git a/de-de/qt-de.html.markdown b/de-de/qt-de.html.markdown
new file mode 100644
index 00000000..480030fe
--- /dev/null
+++ b/de-de/qt-de.html.markdown
@@ -0,0 +1,175 @@
+---
+category: tool
+tool: Qt Framework
+language: c++
+filename: learnqt-de.cpp
+contributors:
+ - ["Aleksey Kholovchuk", "https://github.com/vortexxx192"]
+translators:
+ - ["Dennis Keller", "https://github.com/denniskeller"]
+lang: de-de
+---
+
+**Qt** ist ein weithin bekanntes Framework zum Entwickeln von cross-platform Software,
+die auf verschiedenen Hard- und Softwareplatformen mit wenig oder keinen Veränderungen im Code läuft.
+Dabei besitzt man die Power und Geschiwindigkeit von nativen Anwendungen.
+Obwohl **Qt** ursprünglich in *C++* geschrieben wurde,
+gibt es verschiedene Ports für andere Sprachen: *[PyQt](https://learnxinyminutes.com/docs/pyqt/)*, *QtRuby*, *PHP-Qt*, etc.
+
+**Qt** eignet sich hervorragend zum Erstellen von Anwendungen mit grafischer Benutzeroberfläche (GUI).
+Dieses Tutorial zeigt, wie man das in *C++* macht.
+
+```c++
+/*
+ * Lass uns klassisch starten
+ */
+
+// Alle Header vom Qt Framework starten mit dem Großbuchstaben 'Q'.
+#include <QApplication>
+#include <QLineEdit>
+
+int main(int argc, char *argv[]) {
+ // Erstellt ein Objekt um applikationsweit die Resourcen zu managen.
+ QApplication app(argc, argv);
+
+ // Erstellt ein Line edit Widget und zeigt es auf dem Bildschirm
+ QLineEdit lineEdit("Hello world!");
+ lineEdit.show();
+
+ // Startet die Event Loop der Anwendung.
+ return app.exec();
+}
+```
+
+Die GUI bezogene Teile von **Qt** bestehen aus *Widgets* und den *Verbindungen*
+dazwischen.
+
+[Lies mehr über Widgets](http://doc.qt.io/qt-5/qtwidgets-index.html)
+
+```c++
+/*
+ * Lass uns Label und einen Button machen.
+ * Ein Label soll auftauchen, wenn der Button gedrückt wird.
+ *
+ * Der Qt Code spricht für sich selbst.
+ */
+
+#include <QApplication>
+#include <QDialog>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QLabel>
+
+int main(int argc, char *argv[]) {
+ QApplication app(argc, argv);
+
+ QDialog dialogWindow;
+ dialogWindow.show();
+
+ // Füge ein vertikales Layout hinzu
+ QVBoxLayout layout;
+ dialogWindow.setLayout(&layout);
+
+ QLabel textLabel("Danke für das Knopf drücken");
+ layout.addWidget(&textLabel);
+ textLabel.hide();
+
+ QPushButton button("Drück mich");
+ layout.addWidget(&button);
+
+ // Zeigt verstecktes Label, wenn der Button gedrückt wird.
+ QObject::connect(&button, &QPushButton::pressed,
+ &textLabel, &QLabel::show);
+
+ return app.exec();
+}
+```
+
+Beachte den *QObject::connect* Teil. Diese Methode wird verwendet,
+um *Signale* eines Objekts mit den *Slots* eines Objektes zu verbinden.
+
+**Signale** werden ausgegeben, wenn bestimmte Dinge mit Objekten passieren.
+Beispielsweise wird das *pressed* Signal ausgegeben,
+wenn der Benutzer auf das QPushButton Objekt drückt.
+
+**Slots** sind Aktionen, die als Reaktion auf empfangene Signale ausgeführt werden können.
+
+[Lies mehr über Slots und Signale](http://doc.qt.io/qt-5/signalsandslots.html)
+
+
+Als Nächstes lernen wir, dass wir nicht nur Standard Widgets verwenden können,
+sondern auch ihr Verhalten mithilfe von Vererbung verändern können.
+Lass uns einen Button erschaffen, der zählt, wie häufig er gedrückt wird.
+Dafür definieren wir unsere eigene Klasse *CounterLabel*.
+Diese muss wegen der speziellen Qt Architektur in einer seperaten Datei deklariert werden.
+
+```c++
+// counterlabel.hpp
+
+#ifndef COUNTERLABEL
+#define COUNTERLABEL
+
+#include <QLabel>
+
+class CounterLabel : public QLabel {
+ Q_OBJECT // Qt definiertes Makro, welches in jedem modifizierten Widget vorhanden sein muss.
+
+public:
+ CounterLabel() : counter(0) {
+ setText("Zähler wurde noch nicht erhöht."); // Methode von QLabel
+ }
+
+public slots:
+ // Aktion, die ausgeführt wird, wenn der Button gedrückt wird.
+ void increaseCounter() {
+ setText(QString("Zähler Wert: %1").arg(QString::number(++counter)));
+ }
+
+private:
+ int counter;
+};
+
+#endif // Zähllabel
+```
+
+```c++
+// main.cpp
+// Fast das Gleiche, wie das vorherige Beispiel
+
+#include <QApplication>
+#include <QDialog>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QString>
+#include "counterlabel.hpp"
+
+int main(int argc, char *argv[]) {
+ QApplication app(argc, argv);
+
+ QDialog dialogWindow;
+ dialogWindow.show();
+
+ QVBoxLayout layout;
+ dialogWindow.setLayout(&layout);
+
+ CounterLabel counterLabel;
+ layout.addWidget(&counterLabel);
+
+ QPushButton button("Drück mich nochmal.");
+ layout.addWidget(&button);
+ QObject::connect(&button, &QPushButton::pressed,
+ &counterLabel, &CounterLabel::increaseCounter);
+
+ return app.exec();
+}
+```
+
+Das wars! Natürlich ist das Qt Framework erheblich größer, als der der Teil der in diesem Tutorial behandelt wurde.
+Das heißt, es gibt viel zu lesen und zu üben.
+
+## Further reading
+
+- [Qt 4.8 tutorials](http://doc.qt.io/qt-4.8/tutorials.html)
+- [Qt 5 tutorials](http://doc.qt.io/qt-5/qtexamplesandtutorials.html)
+
+Viel Erfolg und viel Spaß!
diff --git a/de-de/rst-de.html.markdown b/de-de/rst-de.html.markdown
new file mode 100644
index 00000000..072299f5
--- /dev/null
+++ b/de-de/rst-de.html.markdown
@@ -0,0 +1,119 @@
+---
+language: restructured text (RST)
+filename: restructuredtext-de.rst
+contributors:
+ - ["DamienVGN", "https://github.com/martin-damien"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+translators:
+ - ["Dennis Keller", "https://github.com/denniskeller"]
+lang: de-de
+---
+
+RST ist ein Dateiformat, das von der Python Community entwickelt wurde,
+
+um Dokumentation zu schreiben (und ist somit Teil von Docutils).
+
+RST-Dateien sind simple Textdateien mit einer leichtgewichtigen Syntax (im Vergleich zu HTML).
+
+
+## Installation
+
+Um Restructured Text zu vewenden musst du [Python](http://www.python.org)
+
+installieren und das `docutils` Packet installieren. `docutils` kann mit dem folgenden
+
+Befehl auf der Kommandozeile installiert werden:
+
+```bash
+$ easy_install docutils
+```
+
+Wenn auf deinem System `pip` installiert kannst du es statdessen auch verwenden:
+
+```bash
+$ pip install docutils
+```
+
+
+## Dateisyntax
+
+Ein einfaches Beispiel für die Dateisyntax:
+
+```
+.. Zeilen, die mit zwei Punkten starten sind spezielle Befehle.
+
+.. Wenn kein Befehl gefunden wird, wird die Zeile als Kommentar gewertet.
+
+============================================================================
+Haupttitel werden mit Gleichheitszeichen darüber und darunter gekennzeichnet
+============================================================================
+
+Beachte das es genau so viele Gleichheitszeichen, wie Hauptitelzeichen
+geben muss.
+
+Titel werden auch mit Gleichheitszeichen unterstrichen
+======================================================
+
+Untertitel werden mit Strichen gekennzeichnet
+---------------------------------------------
+
+Text in *kursiv* oder in **fett**. Du kannst Text als Code "makieren", wenn
+du doppelte Backquotes verwendest ``: ``print()``.
+
+Listen sind so einfach wie in Markdown:
+
+- Erstes Element
+- Zweites Element
+ - Unterelement
+
+oder
+
+* Erstes Element
+* Zweites Element
+ * Unterelement
+
+Tabellen sind einfach zu schreiben:
+
+=========== ==========
+Land Hauptstadt
+=========== ==========
+Frankreich Paris
+Japan Tokyo
+=========== ========
+
+Komplexere Tabellen (zusammengeführte Spalten und Zeilen) können einfach
+erstellt werden, aber ich empfehle dir dafür die komplette Dokumentation zu lesen :)
+
+Es gibt mehrere Möglichkeiten um Links zu machen:
+
+- Wenn man einen Unterstrich hinter einem Wort hinzufügt: Github_ Zusätzlich
+muss man die Zielurl nach dem Text hinzufügen.
+(Dies hat den Vorteil, dass man keine unnötigen Urls in lesbaren Text einfügt.
+- Wenn man die vollständige Url eingibt : https://github.com/
+(Dies wird automatisch in ein Link konvertiert.)
+- Wenn man es mehr Markdown ähnlich eingibt: `Github <https://github.com/>`_ .
+
+.. _Github https://github.com/
+
+```
+
+
+## Wie man es verwendet
+
+RST kommt mit docutils, dort hast du den Befehl `rst2html`, zum Beispiel:
+
+```bash
+$ rst2html myfile.rst output.html
+```
+
+*Anmerkung : Auf manchen Systemen könnte es rst2html.py sein*
+
+Es gibt komplexere Anwendungen, die das RST Format verwenden:
+
+- [Pelican](http://blog.getpelican.com/), ein statischer Websitengenerator
+- [Sphinx](http://sphinx-doc.org/), Ein Dokumentationsgenerator
+- und viele Andere
+
+## Zum Lesen
+
+- [Offizielle Schnellreferenz](http://docutils.sourceforge.net/docs/user/rst/quickref.html)
diff --git a/de-de/ruby-de.html.markdown b/de-de/ruby-de.html.markdown
index e14603cd..8025a8c0 100644
--- a/de-de/ruby-de.html.markdown
+++ b/de-de/ruby-de.html.markdown
@@ -1,5 +1,6 @@
---
language: ruby
+filename: ruby-de.rb
contributors:
- ["David Underwood", "http://theflyingdeveloper.com"]
- ["Joel Walden", "http://joelwalden.net"]
@@ -11,602 +12,677 @@ contributors:
- ["Dzianis Dashkevich", "https://github.com/dskecse"]
- ["Levi Bostian", "https://github.com/levibostian"]
- ["Rahil Momin", "https://github.com/iamrahil"]
+ - ["Gabriel Halley", "https://github.com/ghalley"]
+ - ["Persa Zula", "http://persazula.com"]
+ - ["Jake Faris", "https://github.com/farisj"]
+ - ["Corey Ward", "https://github.com/coreyward"]
+ - ["Jannik Siebert", "https://github.com/janniks"]
+ - ["Keith Miyake", "https://github.com/kaymmm"]
translators:
- ["Christian Albrecht", "https://github.com/coastalchief"]
- ["Dennis Keller", "https://github.com/denniskeller"]
-filename: ruby-de.rb
+ - ["Paul Götze", "https://gitub.com/paulgoetze"]
lang: de-de
---
-# Dies ist ein Kommentar
+```ruby
+# Das ist ein Kommentar
=begin
-Dies sind multi-line
-Kommentare. Niemand benutzt
-die wirklich.
+Das ist ein mehrzeiliger Kommentar.
+Die Anfangszeile muss mit "=begin" beginnen
+und die Endzeile muss mit "=end" beginnen.
+
+Alternativ kannst du jede Zeile in einem
+mehrzeiligen Kommentar mit dem # Zeichen beginnen.
=end
-# Objekte - Alles ist ein Objekt
+# In Ruby ist (fast) alles ein Objekt.
+# Das schließt Zahlen ein...
+3.class #=> Integer
-## Zahlen sind Objekte
-```
-3.class #=> Fixnum
-3.to_s #=> "3"
-```
+# ...und Zeichenketten (Strings)...
+"Hallo".class #=> String
-### Simple Arithmetik
-```
+# ...und sogar Methoden!
+"Hallo".method(:class).class #=> Method
+
+# Simple Arithmetik
1 + 1 #=> 2
8 - 1 #=> 7
10 * 2 #=> 20
35 / 5 #=> 7
-2**5 #=> 32
-```
+2 ** 5 #=> 32
+5 % 3 #=> 2
-// Arithmetik ist aber eigentlich nur syntaktischer Zucker
-// um eine Methode eines Objekt aufzurufen
-```
+# Bitweise Operatoren
+3 & 5 #=> 1
+3 | 5 #=> 7
+3 ^ 5 #=> 6
+
+# Arithmetik ist aber eigentlich nur syntaktischer Zucker
+# um eine Methode eines Objekts aufzurufen
1.+(3) #=> 4
10.* 5 #=> 50
-```
+100.methods.include?(:/) #=> true
-## Special values sind Objekte
-```
-nil # Nothing to see here
-true # truth
-false # falsehood
+## Spezielle Werte sind Objekte
+nil # Equivalent zu null in anderen Sprachen
+true # Wahrheitswert
+false # Falschheitswert
nil.class #=> NilClass
true.class #=> TrueClass
false.class #=> FalseClass
-```
-## Objektvergleiche
-### Gleicheit
-```
+# Gleicheit
1 == 1 #=> true
2 == 1 #=> false
-```
-### Ungleichheit
-```
+
+# Ungleichheit
1 != 1 #=> false
2 != 1 #=> true
-```
-### Neben false selbst, nil ist ein anderer 'falsey' Wert
-```
-!nil #=> true
-!false #=> true
-!0 #=> false
-```
-### Weitere Vergleiche
-```
+
+# Neben false selbst, ist nil der einzige andere
+# zu Falsch evaluierende Wert
+
+!!nil #=> false
+!!false #=> false
+!!0 #=> true
+!!"" #=> true
+
+# Weitere Vergleiche
1 < 10 #=> true
1 > 10 #=> false
2 <= 2 #=> true
2 >= 2 #=> true
-```
+
+# Kombinierter Vergleichsoperator (gibt `1` zurück wenn das erste Argument
+# größer ist, und `-1`, wenn das zweite Argument größer ist, sonst `0`)
+1 <=> 10 #=> -1 (1 < 10)
+10 <=> 1 #=> 1 (10 > 1)
+1 <=> 1 #=> 0 (1 == 1)
+
### Logische Operatoren
-```
true && false #=> false
true || false #=> true
-!true #=> false
-```
-Es gibt alternative Versionen der logischen Operatoren mit niedrigerer
-Wertigkeit. Diese werden meistens bei Flow-Control eingesetzt, um
-verschiedenen Ausdrücke zu verketten bis einer true oder false zurück
-liefert.
+# Es gibt alternative Versionen der logischen Operatoren mit niedrigerer
+# Wertigkeit. Diese werden meistens zur Flusskontrolle eingesetzt, um
+# verschiedenen Ausdrücke zu verketten bis einer true oder false zurück
+# liefert.
-#### and
-##### `do_something_else` wird nur ausgewertet wenn `do_something` true ist.
+# `do_something_else` wird nur ausgewertet wenn `do_something` true ist.
do_something() and do_something_else()
-
-#### or
-#####`log_error` wird nur ausgewertet wenn `do_something` false ist.
+# `log_error` wird nur ausgewertet wenn `do_something` false ist.
do_something() or log_error()
-## Strings sind Objekte
-```
-'I am a string'.class #=> String
-"I am a string too".class #=> String
+# String Interpolation
+placeholder = 'Ruby'
+"Ich kann in #{placeholder} Platzhalter mit doppelten Anführungszeichen füllen."
+#=> "Ich kann in Ruby Platzhalter mit doppelten Anführungszeichen füllen."
-platzhalter = 'Ruby'
-"Ich kann in #{placeholder} Platzhalter mit doppelten Anführungsstrichen füllen."
-```
-Einfache Anführungszeichen sollten bevorzugt werden.
-Doppelte Anführungszeichen führen interne Berechnungen durch.
+# Du kannst Strings mit `+` verbinden, nicht jedoch mit anderen Typen
+'hallo ' + 'Welt' #=> "hallo Welt"
+'Hallo ' + 3 #=> TypeError: no implicit conversion of Integer into String
+'hallo ' + 3.to_s #=> "hallo 3"
+"hallo #{3}" #=> "hallo 3"
+
+# ...oder Strings mit Operatoren kombinieren
+'hallo ' * 3 #=> "hallo hallo hallo "
+
+# ...oder Strings an andere Strings anhängen
+'hallo' << ' Welt' #=> "hallo Welt"
+
+# Du kannst Text mit einer neuen Zeile am Ende ausgeben
+puts "Ich gebe Text aus!"
+#=> Ich gebe Text aus!
+#=> nil
+
+# ...oder Text ohne einen Zeilenumbruch ausgeben
+print "Ich gebe Text aus!"
+#=> "Ich gebe Text aus!" => nil
-### Strings können verbunden werden, aber nicht mit Zahlen
-```
-'hello ' + 'world' #=> "hello world"
-'hello ' + 3 #=> TypeError: can't convert Fixnum into String
-```
-#### Zahl muss in String konvertiert werden
-```
-'hello ' + 3.to_s #=> "hello 3"
-```
-### Text ausgeben
-```
-puts "I'm printing!"
-```
# Variablen
-## Zuweisungen
-### Diese Zuweisung gibt den zugeordneten Wert zurück
-```
x = 25 #=> 25
x #=> 25
-```
-### Damit funktionieren auch mehrfache Zuweisungen
-```
+
+# Beachte, dass Zuweisungen den zugewiesenen Wert zurückgeben.
+# D.h. du kannst mehrfache Zuweisungen machen.
+
x = y = 10 #=> 10
x #=> 10
y #=> 10
-```
-## Benennung
-### Konvention ist snake_case
-```
+
+# Nutze snake_case für Variablennamen.
snake_case = true
-```
-### Benutze verständliche Variablennamen
-```
-path_to_project_root = '/good/name/'
-path = '/bad/name/'
-```
-# Symbols (sind auch Objekte)
-Symbols sind unveränderliche, wiederverwendbare Konstanten, welche intern
-als integer repräsentiert werden. Sie werden häufig anstelle von Strings
-verwendet, um sinnvoll Werte zu übermitteln.
-Symbols werden mit dem Doppelpunkt gekennzeichnet.
-```
+# Nutze verständliche Variablennamen.
+path_to_project_root = '/guter/Name/'
+m = '/schlechter/Name/'
+
+
+# Symbole sind unveränderliche, wiederverwendbare Konstanten, welche intern
+# als Integer repräsentiert werden. Sie werden häufig anstelle von Strings
+# verwendet, um semantisch sinnvoll Werte zu übermitteln.
+# Symbols werden mit dem Doppelpunkt gekennzeichnet.
+
:pending.class #=> Symbol
+
status = :pending
+
status == :pending #=> true
+
status == 'pending' #=> false
+
status == :approved #=> false
-```
+
+# Strings können in Symbole konvertiert werden und umgekehrt.
+status.to_s #=> "pending"
+"argon".to_sym #=> :argon
+
# Arrays
-## Ein Array anlegen
-```
+# Das ist ein Array.
array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
-```
-## Array können verschiedene Typen beinhalten
-```
+# Array können verschiedene Typen beinhalten
[1, 'hello', false] #=> [1, "hello", false]
-```
-## Wie bei arithmetischen Ausdrücken auch wird beim Zugriff auf
-## [0] eigentlich die Methode [] des Array Objekts aufgerufen.
-```
-array.[] 0 #=> 1
-array.[] 12 #=> nil
-```
+## Arrays könnenindiziert werden.
-## Arrays können von vorne indiziert werden
-```
+# Von vorne...
array[0] #=> 1
+array.first #=> 1
array[12] #=> nil
-```
-## Arrays können von hinten indiziert werden
-```
+# ...oder von hinten...
array[-1] #=> 5
-```
+array.last #=> 5
-## Arrays können mit Start Index und Länge indiziert werden
-```
+# ...oder mit einem Startindex und einer Länge...
array[2, 3] #=> [3, 4, 5]
-```
-## Arrays können mit einer Range indiziert werden
-```
+# ...oder mit einem Range...
array[1..3] #=> [2, 3, 4]
-```
-## Einen Wert hinzufügen
-```
+# Du kanns ein Array umkehren.
+# Gib ein neues Array mit umgkehrten Werten zurück
+[1,2,3].reverse #=> [3,2,1]
+
+# Kehre ein Array an Ort und Stelle um, um die Variable mit den
+# umgekehrten Werten zu aktualisieren.
+a = [1,2,3]
+a.reverse! #=> a==[3,2,1] wegen des Aufrufs von reverse mit Ausrufezeichens ('!')
+
+# Wie bei der Arithmetik, ist Zugriff mit [index] nur
+# syntaktischer Zucker für den Aufruf der `[]` Methode auf dem Objekt.
+array.[] 0 #=> 1
+array.[] 12 #=> nil
+
+# Du kannst Werte zu einem Array hinzufügen...
array << 6 #=> [1, 2, 3, 4, 5, 6]
+# Oder so
array.push(6) #=> [1, 2, 3, 4, 5, 6]
-```
-## Testen, ob ein Element schon vorhanden ist
-```
+# ...und testen ob ein Element schon vorhanden ist
array.include?(1) #=> true
-```
-# Hashes
-Hashes sind das Hauptfeature um Key/Values zu speichern
+# Hashes sind Rubys Hauptdatenstruktur for Schlüssel/Wert Paare.
+# Hashes werden durch geschweifte Klammern gekennzeichnet.
+hash = { 'Farbe' => 'grün', 'Nummer' => 5 }
-## Ein Hash anlegen
-```
-hash = { 'color' => 'green', 'number' => 5 }
-hash.keys #=> ['color', 'number']
-```
+hash.keys #=> ['farbe', 'nummer']
-## Wert per key herausfinden
-```
-hash['color'] #=> 'green'
-hash['number'] #=> 5
-hash['nothing here'] #=> nil
-// Fragen an einen Hash nach einem Schlüssel, der nicht existiert, ruft nil hervor:
-```
+# Hashes can be quickly looked up by key.
+hash['Farbe'] #=> "grün"
+hash['Nummer'] #=> 5
-## Symbols können auch keys sein
-```
-new_hash = { defcon: 3, action: true }
-new_hash.keys #=> [:defcon, :action]
-```
+# Abfragen eines nicht vorhandenen Schlüssels, gibt nil zurück.
+hash['nicht vorhanden'] #=> nil
-## Testen ob ein Key oder ein Value existiert
-```
-new_hash.has_key?(:defcon) #=> true
-new_hash.has_value?(3) #=> true
-```
+# Wenn du Symbole als Schlüssel in einem Hash verwendest, kannst du
+# eine alternative Syntax verwenden.
+hash = { :defcon => 3, :action => true }
+hash.keys #=> [:defcon, :action]
-### Tipp: Arrays und Hashes sind Enumerable
-### Und haben gemeinsame, hilfreiche Methoden wie:
-### each, map, count, and more
+hash = { defcon: 3, action: true }
+hash.keys #=> [:defcon, :action]
+
+# Testen ob ein Schlüssel oder Wert im Hash existiert
+hash.key?(:defcon) #=> true
+hash.value?(3) #=> true
+
+# Tipp: Arrays und Hashes sind Enumerables!
+# Sie haben viele nützliche Methoden gemein, wie each, map, count, und andere.
# Kontrolstrukturen
-## if
-```
+
+# Bedingungen
if true
- 'if statement'
+ 'wenn Bedingung'
elsif false
- 'else if, optional'
+ 'sonst wenn, optional'
else
- 'else, also optional'
+ 'sonst, auch optional'
end
-```
-## for - Allerdings werden for Schleifen nicht oft vewendet.
-```
-for counter in 1..5
- puts "iteration #{counter}"
-end
-```
-## Stattdessen: "each" Methode und einen Bloch übergeben
-Ein Block ist ein Codeteil, den man einer Methode übergeben kann
-Ähnelt stark lambdas, anonymen Funktionen oder Closures in anderen
-Programmiersprachen.
-```
+# Wenn eine Kontrollstruktur keinen Code-Block, sondern einen einzigen
+# Ausdruck ausführt, dann kannst du die nachgestellte if-Notation verwenden
+warnings = ['Nachname fehlt', 'Adresse zu kurz']
+puts("Vorhandene Warnungen:\n" + warnings.join("\n")) if !warnings.empty?
+
+# Formuliere die Bedingung um, wenn sich `unless` besser liest als `if`
+puts("Vorhandene Warnungen:\n" + warnings.join("\n")) unless warnings.empty?
+
+# Schleifen
+# Traditionell ist das Benutzen von `for` Schleifen in Ruby eher unüblich.
+# Stattdessen werden diese mit Hilfe von Enumerables implementiert, was mit
+# dem Aufrufen von `each` einhergeht.
(1..5).each do |counter|
- puts "iteration #{counter}"
+ puts "Iteration #{counter}"
+end
+
+# Was in etwa das selbe ist wie Folgendes (selten in Ruby zu sehen).
+for counter in 1..5
+ puts "Iteration #{counter}"
end
-```
-Die each Methode einer Range führt den Block für jedes Element der Range aus.
+# Das `do |variable| ... end` Konstrukt wird `block` genannt.
+# Blocks sind vergleichbar mit Lambdas, anonymen Funktionen
+# oder Closures in anderen Programmiersprachen.
+# Sie können als Objekte übergeben, aufgerufen oder als Methoden
+# zugewiesen werden.
-Dem Block wird ein "counter" parameter übergeben.
+# Die `each` Methode eines Ranges führt den Block einmal für jedes
+# Element des Ranges aus.
+# Dem Block wird eine counter Variable als Parameter übergeben.
-### Den Block kann man auch in geschweiften Klammern schreiben
-```
-(1..5).each { |counter| puts "iteration #{counter}" }
-```
+# Du kannst einen Block auch mit geschweiften Klammern schreiben.
+(1..5).each { |counter| puts "Iteration #{counter}" }
-### Each kann auch über den Inhalt von Datenstrukturen iterieren
-```
+# Each kann auch über den Inhalt von Datenstrukturen iterieren.
array.each do |element|
- puts "#{element} is part of the array"
+ puts "#{element} is Teil des Arrays"
end
+
hash.each do |key, value|
- puts "#{key} is #{value}"
+ puts "#{key} ist #{value}"
+end
+
+# Um auf den Laufindex zuzugreifen kannst du `each_with_index` verwenden
+# und eine index Variable definieren.
+array.each_with_index do |element, index|
+ puts "#{element} ist Nummer #{index} im Array"
end
counter = 1
while counter <= 5 do
- puts "iteration #{counter}"
+ puts "Iteration #{counter}"
counter += 1
end
-```
+#=> Iteration 1
+#=> Iteration 2
+#=> Iteration 3
+#=> Iteration 4
+#=> Iteration 5
+
+# Es gibt einige andere hilfreiche Schleifenfunktionen in Ruby.
+# Wie etwa 'map', 'reduce', 'inject' und viele andere mehr.
+# Map zum Beispiel iteriert über das Array, führt für jedes Element
+# die Anweisungen aus,
+# die im Block definiert sind und gibt ein völlig neues Array zurück.
+array = [1,2,3,4,5]
+doubled = array.map do |element|
+ element * 2
+end
+puts doubled
+#=> [2,4,6,8,10]
+puts array
+#=> [1,2,3,4,5]
-## case
-```
+# Case Konstruct
grade = 'B'
case grade
when 'A'
- puts 'Way to go kiddo'
+ puts 'So wird’s gemacht'
when 'B'
- puts 'Better luck next time'
+ puts 'Viel Glück beim nächsten Mal'
when 'C'
- puts 'You can do better'
+ puts 'Das kannst du besser'
when 'D'
- puts 'Scraping through'
+ puts 'Gerade so durch'
when 'F'
- puts 'You failed!'
+ puts 'Durchgefallen!'
else
- puts 'Alternative grading system, eh?'
+ puts 'Anderes Bewertungssystem, was?'
end
-=> "Better luck next time"
-```
+#=> "Viel Glück beim nächsten Mal"
-### Case können auch ranges
-```
+# Case kann auch Ranges benutzen
grade = 82
case grade
when 90..100
- puts 'Hooray!'
+ puts 'Hurra!'
when 80...90
- puts 'OK job'
+ puts 'OK gemacht'
else
- puts 'You failed!'
+ puts 'Durchgefallen!'
end
-=> "OK job"
-```
+#=> "OK gemacht"
-# Exception handling:
-```
+# Fehlerbehandlung
begin
- # code here that might raise an exception
- raise NoMemoryError, 'You ran out of memory.'
+ # Code der einen Fehler wirft...
+ raise NoMemoryError, 'Dein Speicher ist voll.'
rescue NoMemoryError => exception_variable
- puts 'NoMemoryError was raised', exception_variable
+ puts 'NoMemoryError ist aufgetreten', exception_variable
rescue RuntimeError => other_exception_variable
- puts 'RuntimeError was raised now'
+ puts 'RuntimeError ist aufgetreten'
else
- puts 'This runs if no exceptions were thrown at all'
+ puts 'Das wird ausgeführt, wenn keine Fehler geworfen wurden'
ensure
- puts 'This code always runs no matter what'
+ puts 'Dieser Code wird immer ausgeführt, egal was vorher passiert'
end
-```
-# Funktionen
-```
+
+# Methoden
+
def double(x)
x * 2
end
-```
-## Funktionen (und Blocks)
-## geben implizit den Wert des letzten Statements zurück
-```
+
+# Methoden (und Blocks) geben implizit den Wert des letzten Anweisung zurück.
double(2) #=> 4
-```
-### Klammern sind optional wenn das Ergebnis nicht mehrdeutig ist
-```
+# Klammern sind optional wenn die Anweisung dadurch nicht mehrdeutig wird.
double 3 #=> 6
+
double double 3 #=> 12
+
def sum(x, y)
x + y
end
-```
-### Methoden Parameter werden per Komma getrennt
-```
+# Die Argumente einer Methode werden durch ein Komma getrennt.
sum 3, 4 #=> 7
+
sum sum(3, 4), 5 #=> 12
-```
-## yield
-### Alle Methoden haben einen impliziten, optionalen block Parameter
-### Dieser wird mit dem Schlüsselword "yield" aufgerufen
-```
+# yield
+# Alle Methoden haben implizit einen optionalen block Parameter.
+# Dieser kann durch das Schlüsselwort 'yield' ausgeführt werden.
def surround
puts '{'
yield
puts '}'
end
-surround { puts 'hello world' }
-```
-## Einen Block kann man auch einer Methoden übergeben
-### "&" kennzeichnet die Referenz zum übergebenen Block
-```
+surround { puts 'hallo Welt' }
+
+#=> {
+#=> hallo Welt
+#=> }
+
+# Blocks können in ein 'Proc' Objekt umgewandelt werden.
+# Dieses ist eine Art Container um den Block und erlaubt ihn an eine
+# andere Methode zu übergeben, ihn in einen anderen Gültigkeitsbereicht
+# einzubinden oder ihn andersweitig zu verändern.
+# Am häufigsten findet man dies bei Parameterlisten von Methoden, in Form
+# eines letzten '&block' Parameters, der den Block – wenn es einen gibt –
+# entgegen nimmt und ihn in ein 'Proc' umwandelt. Die Benennung '&block' ist
+# hier nur eine Konvention; es würde genauso mit '&pineapple' funktionieren.
def guests(&block)
- block.call 'some_argument'
+ block.class #=> Proc
+ block.call(4)
end
-```
-### Eine Liste von Parametern kann man auch übergeben,
-### Diese wird in ein Array konvertiert
-### "*" kennzeichnet dies.
-```
+# Die 'call' Methode eines Proc ist ganz ähnlich zum Aufruf von 'yield', wenn
+# ein Block vorhanden ist. Die Argumente, die 'call' übergeben werden, werden
+# als Argumente and den Block weitergereicht.
+
+guests { |n| "Du hast #{n} Gäste." }
+# => "Du hast 4 Gäste."
+
+# Du kannst eine Liste von Argumenten übergeben, die dann in ein Array
+# umgewandelt werden. Dafür gibt es den splat-Operator (`*`).
def guests(*array)
array.each { |guest| puts guest }
end
-```
+
+# Destrukturierung
+
+# Ruby destrukturiert Arrays automatisch beim Zuweisen mehrerer Variablen.
+a, b, c = [1, 2, 3]
+a #=> 1
+b #=> 2
+c #=> 3
+
+# In manchen Fällen will man den splat-Operator (`*`) verwenden um ein Array in
+# eine Liste zu destrukturieren.
+ranked_competitors = ["John", "Sally", "Dingus", "Moe", "Marcy"]
+
+def best(first, second, third)
+ puts "Gewinner sind #{first}, #{second} und #{third}."
+end
+
+best *ranked_competitors.first(3) #=> Gewinner sind John, Sally and Dingus.
+
+# Der splat-Operator kann auch in Parametern verwendet werden.
+def best(first, second, third, *others)
+ puts "Gewinner sind #{first}, #{second} und #{third}."
+ puts "Es gab #{others.count} andere Teilnehmer."
+end
+
+best *ranked_competitors
+#=> Gewinner sind John, Sally und Dingus.
+#=> Es gab 2 andere Teilnehmer.
+
+# Per Konvention enden alle Methoden, die einen Wahrheitswert zurück geben, mit einem
+# Fragezeichen.
+5.even? #=> false
+5.odd? #=> true
+
+# Wenn ein Methodenname mit einem Ausrufezeichen endet, dann tut diese Methode
+# per Konvention etwas Destruktives, wie z.B. das aufrufende Objekt zu
+# verändern.
+# Viele Mehtoden haben eine !-Version um eine direkte Änderung zu machen und
+# eine Nicht-!-Version, die ein neues Objekt mit den Veränderungen zurück gibt.
+company_name = "Dunder Mifflin"
+company_name.upcase #=> "DUNDER MIFFLIN"
+company_name #=> "Dunder Mifflin"
+# Diesmal verändern wir company_name direkt.
+company_name.upcase! #=> "DUNDER MIFFLIN"
+company_name #=> "DUNDER MIFFLIN"
+
# Klassen
-## Werden mit dem class Schlüsselwort definiert
-```
+
+# Du kannst eine Klasse mit dem Schlüsselwort 'class' definieren.
class Human
-```
-### Konstruktor bzw. Initializer
-```
+ # Eine Klassenvariable. Sie wird von allen Instanzen einer Klasse geteilt.
+ @@species = 'H. sapiens'
+
+ # Konstruktor bzw. Initializer
def initialize(name, age = 0)
- # Assign the argument to the "name" instance variable for the instance
+ # Weise das Argument der Instanzvariable 'name' zu.
@name = name
- # If no age given, we will fall back to the default in the arguments list.
+ # Wenn kein 'age' angegeben wurde wird der Standartwert aus der Argumentenlist verwendet.
@age = age
end
-```
-### setter Methode
-```
+ # Setter Methode
def name=(name)
@name = name
end
-```
-### getter Methode
-```
+
+ # Getter Methode
def name
@name
end
-```
-#### getter können mit der attr_accessor Methode vereinfacht definiert werden
-```
+ # Getter & Setter können auch kürzer mit der attr_accessor Methode erstellt werden.
attr_accessor :name
- # Getter/setter methods can also be created individually like this
+
+ # Getter & Setter Methoden können auch einzeln erstellt werden.
attr_reader :name
attr_writer :name
- # A class method uses self to distinguish from instance methods.
- # It can only be called on the class, not an instance.
+
+ # Eine Klassenmethode unterscheidet sich durch ein 'self' von einer
+ # Instanzmethode.
+ # Sie kann nur auf der Klasse und nicht auf einer Instanz der Klasse
+ # aufgerufen werden.
def self.say(msg)
puts msg
end
+
def species
@@species
end
end
-```
-## Eine Klasse instanziieren
-```
+# Instanziieren einer Klasse
jim = Human.new('Jim Halpert')
dwight = Human.new('Dwight K. Schrute')
-```
-## Methodenaufrufe
-```
+# Du kannst die Methoden des erstellten Objekts aufrufen.
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"
-```
-## Eine Klassenmethode aufrufen
-```
+# Aufrufen einer Klassenmethode
Human.say('Hi') #=> "Hi"
-```
-## Variable Gültigkeit
-### Variablen die mit "$" starten, gelten global
-```
-$var = "I'm a global var"
+# Der Gültigkeitsbereich einer Variablen wird durch ihren Namen definiert.
+# Variablen, die mit $ beginnen sind global gültig.
+$var = "Ich bin eine globale Variable"
defined? $var #=> "global-variable"
-```
-### Variablen die mit "@" starten, gelten für die Instanz
-```
-@var = "I'm an instance var"
+# Variablen, die mit @ beginnen, sind innerhalb einer Instanz gültig.
+@var = "Ich bin eine Instanzvariable"
defined? @var #=> "instance-variable"
-```
-### Variablen die mit "@@" starten, gelten für die Klasse
-```
-@@var = "I'm a class var"
+# Variablen, die mit @@ beginnen, sind für die Klasse gültig.
+@@var = "Ich bin eine Klassenvariable"
defined? @@var #=> "class variable"
-```
-### Variablen die mit einem Großbuchstaben anfangen, sind Konstanten
-```
-Var = "I'm a constant"
+# Variablen, die mit einem Großbuchstaben beginnen, sind Konstanten
+Var = "Ich bin eine Konstante"
defined? Var #=> "constant"
-```
-## Class ist auch ein Objekt
-### Hat also auch Instanzvariablen
-### Eine Klassenvariable wird innerhalb der Klasse und Ableitungen geteilt.
+# Class ist in Ruby auch ein Objekt. Deshalb kann eine Klasse Instanzvariablen
+# haben. Eine Klassenvariable wird zwischen der Klasse und all ihren
+# Ableitungen geteilt.
-### Basis Klasse
-```
+# Basis Klasse
class Human
@@foo = 0
+
def self.foo
@@foo
end
+
def self.foo=(value)
@@foo = value
end
end
-```
-### Abgeleitete Klasse
-```
+# Abgeleitete Klasse
class Worker < Human
end
-Human.foo # 0
-Worker.foo # 0
-Human.foo = 2 # 2
-Worker.foo # 2
-```
-### Eine Klasseninstanzvariable wird nicht geteilt
-```
+Human.foo #=> 0
+Worker.foo #=> 0
+
+Human.foo = 2
+Worker.foo #=> 2
+
+# Ableitungen einer Klasse haben keinen Zugriff auf eine Eine Klassen-Instanzvariable.
class Human
@bar = 0
+
def self.bar
@bar
end
+
def self.bar=(value)
@bar = value
end
end
-```
-```
+
class Doctor < Human
end
-```
-```
-Human.bar # 0
-Doctor.bar # nil
-```
-```
+
+Human.bar #=> 0
+Doctor.bar #=> nil
+
module ModuleExample
def foo
'foo'
end
end
-```
-### Module einbinden, heisst ihre Methoden an die Instanzen der Klasse zu binden
-### Module erweitern, heisst ihre Mothden an die Klasse selbst zu binden
-```
+
+# Ein Einbinden (include) eines Moduls bindet seine Methoden an die Instanzen
+# der Klasse.
+# Ein Erweitern (extend) eines Moduls bindet seine Methoden an die Klasse
+# selbst.
class Person
include ModuleExample
end
-```
-```
+
class Book
extend ModuleExample
end
-```
-```
-Person.foo # => NoMethodError: undefined method `foo' for Person:Class
-Person.new.foo # => 'foo'
-Book.foo # => 'foo'
-Book.new.foo # => NoMethodError: undefined method `foo'
-```
-### Callbacks werden ausgeführt, wenn ein Modul eingebunden oder erweitert wird
-```
- module ConcernExample
- def self.included(base)
- base.extend(ClassMethods)
- base.send(:include, InstanceMethods)
- end
- module ClassMethods
- def bar
- 'bar'
- end
- end
- module InstanceMethods
- def qux
- 'qux'
- end
+
+Person.foo #=> NoMethodError: undefined method `foo' for Person:Class
+Person.new.foo #=> "foo"
+Book.foo #=> "foo"
+Book.new.foo #=> NoMethodError: undefined method `foo'
+
+
+# Callbacks werden ausgeführt, wenn ein Modul eingebunden oder erweitert wird.
+module ConcernExample
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.send(:include, InstanceMethods)
+ end
+
+ module ClassMethods
+ def bar
+ 'bar'
end
end
- class Something
- include ConcernExample
+
+ module InstanceMethods
+ def qux
+ 'qux'
+ end
end
-```
-```
-Something.bar # => 'bar'
-Something.qux # => NoMethodError: undefined method `qux'
-Something.new.bar # => NoMethodError: undefined method `bar'
-Something.new.qux # => 'qux'
+end
+
+class Something
+ include ConcernExample
+end
+
+Something.bar #=> "bar"
+Something.qux #=> NoMethodError: undefined method `qux'
+Something.new.bar #=> NoMethodError: undefined method `bar'
+Something.new.qux #=> "qux"
```
-## Weiterführende Hinweise
+## Weitere Links
-//EN
+_(z.T. auf Englisch)_
-- [Learn Ruby by Example with Challenges](http://www.learneroo.com/modules/61/nodes/338) - A variant of this reference with in-browser challenges.
-- [Official Documentation](http://www.ruby-doc.org/core-2.1.1/)
+- [Offizielle Ruby Website](https://www.ruby-lang.org/de/)
+- [Learn Ruby by Example with Challenges](http://www.learneroo.com/modules/61/nodes/338) - Eine Variante dieses Dokuments mit in-Browser Challenges.
+- [RubyMonk](https://rubymonk.com/) - Lerne Ruby mit einer Reihe interaktiver Tutorials.
+- [Offizielle Dokumentation](http://ruby-doc.org/core)
- [Ruby from other languages](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/)
-- [Programming Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - An older [free edition](http://ruby-doc.com/docs/ProgrammingRuby/) is available online.
-- [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) - A community-driven Ruby coding style guide.
+- [Programming Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - Eine ältere [freie Ausgabe](http://ruby-doc.com/docs/ProgrammingRuby/) ist online verfügbar.
+- [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) - Ein von der Community erstellter Ruby coding style guide.
+- [Try Ruby](http://tryruby.org) - Lerne die Grundlagen der Ruby Programmiersprache, interaktiv im Browser.
diff --git a/de-de/scala-de.html.markdown b/de-de/scala-de.html.markdown
index 456403a2..a8344e6a 100644
--- a/de-de/scala-de.html.markdown
+++ b/de-de/scala-de.html.markdown
@@ -8,89 +8,90 @@ contributors:
- ["Dennis Keller", "github.com/denniskeller"]
translators:
- ["Christian Albrecht", "https://github.com/coastalchief"]
+ - ["Jonas Grote", "https://github.com/exic"]
filename: learnscala-de.scala
lang: de-de
---
-Scala ist eine funktionale und objektorientierte Programmiersprache
-für die Java Virtual Machine (JVM), um allgemeine Programmieraufgaben
-zu erledigen. Scala hat einen akademischen Hintergrund und wurde an
+Scala ist eine funktionale und objektorientierte Programmiersprache
+für die Java Virtual Machine (JVM), um allgemeine Programmieraufgaben
+zu erledigen. Scala hat einen akademischen Hintergrund und wurde an
der EPFL (Lausanne / Schweiz) unter der Leitung von Martin Odersky entwickelt.
-```scala
+```scala
/*
-Scala Umgebung einrichten:
+Scala-Umgebung einrichten:
1. Scala binaries herunterladen- http://www.scala-lang.org/downloads
2. Unzip/untar in ein Verzeichnis
-3. das bin Unterverzeichnis der `PATH` Umgebungsvariable hinzufügen
+3. das Unterverzeichnis `bin` der `PATH`-Umgebungsvariable hinzufügen
4. Mit dem Kommando `scala` wird die REPL gestartet und zeigt als Prompt:
scala>
-Die REPL (Read-Eval-Print Loop) ist der interaktive Scala Interpreter.
-Hier kann man jeden Scala Ausdruck verwenden und das Ergebnis wird direkt
-ausgegeben.
-Als nächstes beschäftigen wir uns mit ein paar Scala Basics.
+Die REPL (Read-Eval-Print Loop) ist der interaktive Scala Interpreter.
+Hier kann man jeden Scala Ausdruck verwenden und das Ergebnis wird direkt
+ausgegeben.
+Als nächstes beschäftigen wir uns mit ein paar Scala-Grundlagen.
*/
/////////////////////////////////////////////////
-// 1. Basics
+// 1. Grundlagen
/////////////////////////////////////////////////
-// Einzeilige Kommentare beginnen mit zwei Slashes
+// Einzeilige Kommentare beginnen mit zwei Schrägstrichen.
/*
- Mehrzeilige Kommentare, starten
- mit einem Slash-Stern und enden mit einem Stern-Slash
+ Mehrzeilige Kommentare starten mit Schrägstrich und Stern
+ und enden mit Stern und Schrägstrich.
*/
-// Einen Wert, und eine zusätzliche neue Zeile ausgeben
+// Einen Wert und eine zusätzliche neue Zeile ausgeben:
-println("Hello world!")
+println("Hallo Welt!")
println(10)
-// Einen Wert, ohne eine zusätzliche neue Zeile ausgeben
+// Einen Wert ohne eine zusätzliche neue Zeile ausgeben:
-print("Hello world")
+print("Hallo Welt")
/*
- Variablen werden entweder mit var oder val deklariert.
- Deklarationen mit val sind immutable, also unveränderlich
- Deklarationen mit var sind mutable, also veränderlich
- Immutability ist gut.
+ Variablen werden entweder mit var oder val deklariert.
+ Deklarationen mit val sind immutable, also unveränderlich.
+ Deklarationen mit var sind mutable, also veränderlich.
+ Immutability ist gut.
*/
val x = 10 // x ist 10
-x = 20 // error: reassignment to val
+x = 20 // Error: reassignment to val (Fehler: neue Zuweisung zu einem unveränderlichen Wert)
var y = 10
y = 20 // y ist jetzt 20
/*
-Scala ist eine statisch getypte Sprache, auch wenn wir in dem o.g. Beispiel
-keine Typen an x und y geschrieben haben.
-In Scala ist etwas eingebaut, was sich Type Inference nennt. Das heißt das der
-Scala Compiler in den meisten Fällen erraten kann, von welchen Typ eine Variable ist,
-so dass der Typ nicht jedes mal angegeben werden muss.
-Einen Typ gibt man bei einer Variablendeklaration wie folgt an:
+Scala ist eine statisch getypte Sprache, auch wenn wir in dem o.g. Beispiel
+keine Typen an x und y geschrieben haben.
+In Scala ist etwas eingebaut, was sich Type Inference nennt. Das heißt, dass der
+Scala Compiler in den meisten Fällen erraten kann, von welchem Typ eine Variable ist,
+so dass der Typ nicht jedes mal angegeben werden muss.
+Einen Typ gibt man bei einer Variablendeklaration wie folgt an:
*/
val z: Int = 10
val a: Double = 1.0
-// Bei automatischer Umwandlung von Int auf Double wird aus 10 eine 10.0
+// Bei automatischer Umwandlung von Int auf Double wird aus 10 eine 10.0:
val b: Double = 10
-// Boolean Werte
+// Boolean-Werte:
true
false
-// Boolean Operationen
+// Boolean-Operationen:
!true // false
!false // true
@@ -98,7 +99,7 @@ true == false // false
10 > 5 // true
-// Mathematische Operationen sind wie gewohnt
+// Mathematische Operationen sind wie gewohnt:
1 + 1 // 2
2 - 1 // 1
@@ -108,88 +109,87 @@ true == false // false
6.0 / 4 // 1.5
-// Die Auswertung eines Ausdrucks in der REPL gibt den Typ
-// und das Ergebnis zurück.
+// Die Auswertung eines Ausdrucks in der REPL gibt den Typ
+// und das Ergebnis zurück:
scala> 1 + 7
res29: Int = 8
/*
-Das bedeutet, dass das Resultat der Auswertung von 1 + 7 ein Objekt
-von Typ Int ist und einen Wert 0 hat.
-"res29" ist ein sequentiell generierter name, um das Ergebnis des
-Ausdrucks zu speichern. Dieser Wert kann bei Dir anders sein...
+Das bedeutet, dass das Resultat der Auswertung von 1 + 7 ein Objekt
+von Typ Int ist und einen Wert 8 hat.
+"res29" ist ein sequentiell generierter Name, um das Ergebnis des
+Ausdrucks zu speichern. Dieser Wert kann bei Dir anders sein...
*/
-"Scala strings werden in doppelten Anführungszeichen eingeschlossen"
-'a' // A Scala Char
-// 'Einzeln ge-quotete strings gibt es nicht!' <= This causes an error
-
-// Für Strings gibt es die üblichen Java Methoden
+"Scala strings werden in doppelten Anführungszeichen eingeschlossen"
+'a' // Ein Scala Char
+// 'Einzeln ge-quotete strings gibt es nicht!' <= Das erzeugt einen Fehler!
-"hello world".length
-"hello world".substring(2, 6)
-"hello world".replace("C", "3")
+// Für Strings gibt es die üblichen Java-Methoden:
+"Hallo Welt".length
+"Hallo Welt".substring(2, 6)
+"Hallo Welt".replace("C", "3")
-// Zusätzlich gibt es noch extra Scala Methoden
-// siehe: scala.collection.immutable.StringOps
-"hello world".take(5)
-"hello world".drop(5)
+// Zusätzlich gibt es noch extra Scala-Methoden
+// siehe: scala.collection.immutable.StringOps
+"Hallo Welt".take(5)
+"Hallo Welt".drop(5)
-// String interpolation: prefix "s"
+
+// String-Interpolation: prefix "s":
val n = 45
-s"We have $n apples" // => "We have 45 apples"
+s"Wir haben $n Äpfel" // => "Wir haben 45 Äpfel"
-// Ausdrücke im Innern von interpolierten Strings gibt es auch
+// Ausdrücke im Innern von interpolierten Strings gibt es auch:
val a = Array(11, 9, 6)
-val n = 100
-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"
+s"Meine zweite Tochter ist ${a(0) - a(2)} Jahre alt." // => "Meine zweite Tochter ist 5 Jahre alt."
+s"Wir haben das Doppelte von ${n / 2.0} an Äpfeln." // => "Wir haben das Doppelte von 22.5 an Äpfeln."
+s"2 im Quadrat: ${math.pow(2, 2)}" // => "2 im Quadrat: 4"
-// Formatierung der interpolierten Strings mit dem prefix "f"
+// Formatierung der interpolierten Strings mit dem prefix "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"
+f"5 im Quadrat: ${math.pow(5, 2)}%1.0f" // "5 im Quadrat: 25"
+f"Quadratwurzel von 122: ${math.sqrt(122)}%1.4f" // "Quadratwurzel von 122: 11.0454"
-// Raw Strings, ignorieren Sonderzeichen.
+// Raw Strings ignorieren Sonderzeichen:
raw"New line feed: \n. Carriage return: \r." // => "New line feed: \n. Carriage return: \r."
-// Manche Zeichen müssen "escaped" werden, z.B.
-// ein doppeltes Anführungszeichen in innern eines Strings.
+// Manche Zeichen müssen "escaped" werden, z.B.
+// ein doppeltes Anführungszeichen im Innern eines Strings:
-"They stood outside the \"Rose and Crown\"" // => "They stood outside the "Rose and Crown""
+"Sie standen vor der \"Rose and Crown\"" // => "Sie standen vor der "Rose and Crown""
-// Dreifache Anführungszeichen erlauben es, dass ein String über mehrere Zeilen geht
-// und Anführungszeichen enthalten kann.
+// Dreifache Anführungszeichen erlauben es, dass ein String über mehrere Zeilen geht
+// und Anführungszeichen enthalten kann:
-val html = """<form id="daform">
- <p>Press belo', Joe</p>
+val html = """<form id="dieform">
+ <p>Drück belo', Joe</p>
<input type="submit">
</form>"""
-
+
/////////////////////////////////////////////////
// 2. Funktionen
/////////////////////////////////////////////////
-// Funktionen werden so definiert
-//
-// def functionName(args...): ReturnType = { body... }
-//
-// Beachte: Es gibt kein return Schlüsselwort. In Scala ist der letzte Ausdruck
-// in einer Funktion der Rückgabewert.
+// Funktionen werden so definiert:
+//
+// def functionName(args...): ReturnType = { body... }
+//
+// Beachte: Es wird hier kein Schlüsselwort "return" verwendet.
+// In Scala ist der letzte Ausdruck in einer Funktion der Rückgabewert.
def sumOfSquares(x: Int, y: Int): Int = {
val x2 = x * x
@@ -198,118 +198,118 @@ def sumOfSquares(x: Int, y: Int): Int = {
}
-// Die geschweiften Klammern können weggelassen werden, wenn
-// die Funktion nur aus einem einzigen Ausdruck besteht:
+// Die geschweiften Klammern können weggelassen werden, wenn
+// die Funktion nur aus einem einzigen Ausdruck besteht:
def sumOfSquaresShort(x: Int, y: Int): Int = x * x + y * y
-// Syntax für Funktionsaufrufe:
+// Syntax für Funktionsaufrufe:
sumOfSquares(3, 4) // => 25
-// In den meisten Fällen (mit Ausnahme von rekursiven Funktionen), können
-// Rückgabetypen auch weggelassen werden, da dieselbe Typ Inference, wie bei
-// Variablen, auch bei Funktionen greift:
+// In den meisten Fällen (mit Ausnahme von rekursiven Funktionen) können
+// Rückgabetypen auch weggelassen werden, da dieselbe Typ-Inferenz, wie bei
+// Variablen, auch bei Funktionen greift:
def sq(x: Int) = x * x // Compiler errät, dass der return type Int ist
-// Funktionen können default parameter haben:
+// Funktionen können Default-Parameter haben:
def addWithDefault(x: Int, y: Int = 5) = x + y
addWithDefault(1, 2) // => 3
addWithDefault(1) // => 6
-// Anonyme Funktionen sehen so aus:
+// Anonyme Funktionen sehen so aus:
(x: Int) => x * x
-// Im Gegensatz zu def bei normalen Funktionen, kann bei anonymen Funktionen
-// sogar der Eingabetyp weggelassen werden, wenn der Kontext klar ist.
-// Beachte den Typ "Int => Int", dies beschreibt eine Funktion,
-// welche Int als Parameter erwartet und Int zurückgibt.
+// Im Gegensatz zu def bei normalen Funktionen, kann bei anonymen Funktionen
+// sogar der Eingabetyp weggelassen werden, wenn der Kontext klar ist.
+// Beachte den Typ "Int => Int", dies beschreibt eine Funktion,
+// welche Int als Parameter erwartet und Int zurückgibt.
val sq: Int => Int = x => x * x
-// Anonyme Funktionen benutzt man ganz normal:
+// Anonyme Funktionen benutzt man ganz normal:
sq(10) // => 100
-// Wenn ein Parameter einer anonymen Funktion nur einmal verwendet wird,
-// bietet Scala einen sehr kurzen Weg diesen Parameter zu benutzen,
-// indem die Parameter als Unterstrich "_" in der Parameterreihenfolge
-// verwendet werden. Diese anonymen Funktionen werden sehr häufig
-// verwendet.
+// Wenn ein Parameter einer anonymen Funktion nur einmal verwendet wird,
+// bietet Scala einen sehr kurzen Weg diesen Parameter zu benutzen,
+// indem die Parameter als Unterstrich "_" in der Parameterreihenfolge
+// verwendet werden. Diese anonymen Funktionen werden sehr häufig
+// verwendet.
-val addOne: Int => Int = _ + 1
-val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3)
-addOne(5) // => 6
-weirdSum(2, 4) // => 16
+val addOne: Int => Int = _ + 1
+val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3)
+addOne(5) // => 6
+weirdSum(2, 4) // => 16
-// Es gibt einen keyword return in Scala. Allerdings ist seine Verwendung
-// nicht immer ratsam und kann fehlerbehaftet sein. "return" gibt nur aus
-// dem innersten def, welches den return Ausdruck umgibt, zurück.
-// "return" hat keinen Effekt in anonymen Funktionen:
+// Es gibt ein Schlüsselwort "return" in Scala. Allerdings ist seine Verwendung
+// nicht immer ratsam und kann fehlerbehaftet sein. "return" gibt nur aus
+// dem innersten def, welches den return Ausdruck umgibt, zurück.
+// "return" hat keinen Effekt in anonymen Funktionen:
-def foo(x: Int): Int = {
- val anonFunc: Int => Int = { z =>
- if (z > 5)
- return z // Zeile macht z zum return Wert von foo
- else
- z + 2 // Zeile ist der return Wert von anonFunc
- }
- anonFunc(x) // Zeile ist der return Wert von foo
-}
+def foo(x: Int): Int = {
+ val anonFunc: Int => Int = { z =>
+ if (z > 5)
+ return z // Zeile macht z zum return Wert von foo
+ else
+ z + 2 // Zeile ist der return Wert von anonFunc
+ }
+ anonFunc(x) // Zeile ist der return Wert von foo
+}
/////////////////////////////////////////////////
-// 3. Flow Control
+// 3. Flusskontrolle
/////////////////////////////////////////////////
-// Wertebereiche und Schleifen
+// Wertebereiche und Schleifen:
1 to 5
val r = 1 to 5
r.foreach(println)
r foreach println
(5 to 1 by -1) foreach (println)
-
-// Scala ist syntaktisch sehr großzügig, Semikolons am Zeilenende
-// sind optional, beim Aufruf von Methoden können die Punkte
-// und Klammern entfallen und Operatoren sind im Grunde austauschbare Methoden
-// while Schleife
+// Scala ist syntaktisch sehr großzügig; Semikolons am Zeilenende
+// sind optional, beim Aufruf von Methoden können die Punkte
+// und Klammern entfallen und Operatoren sind im Grunde austauschbare Methoden.
+
+// while Schleife:
var i = 0
while (i < 10) { println("i " + i); i += 1 }
i // i ausgeben, res3: Int = 10
-// Beachte: while ist eine Schleife im klassischen Sinne -
-// Sie läuft sequentiell ab und verändert die loop-Variable.
-// While in Scala läuft schneller ab als in Java und die o.g.
-// Kombinatoren und Zusammenlegungen sind einfacher zu verstehen
-// und zu parellelisieren.
+// Beachte: while ist eine Schleife im klassischen Sinne -
+// Sie läuft sequentiell ab und verändert die loop-Variable.
+// "while" in Scala läuft schneller ab als in Java und die o.g.
+// Kombinatoren und Zusammenlegungen sind einfacher zu verstehen
+// und zu parallelisieren.
-// Ein do while Schleife
+// Ein do while Schleife
do {
- println("x ist immer noch weniger wie 10")
+ println("x ist immer noch weniger als 10")
x += 1
} while (x < 10)
-// Endrekursionen sind ideomatisch um sich wiederholende
-// Dinge in Scala zu lösen. Rekursive Funtionen benötigen explizit einen
-// return Typ, der Compiler kann ihn nicht erraten.
-// Unit, in diesem Beispiel.
+// Endrekursionen sind idiomatisch um sich wiederholende
+// Aufgaben in Scala zu lösen. Rekursive Funtionen benötigen explizit einen
+// Rückgabe-Typ, der Compiler kann ihn nicht erraten.
+// Der Rückgabe-Typ in diesem Beispiel ist Unit:
def showNumbersInRange(a: Int, b: Int): Unit = {
print(a)
@@ -331,7 +331,7 @@ val text = if (x == 10) "yeah" else "nope"
/////////////////////////////////////////////////
-// 4. Daten Strukturen (Array, Map, Set, Tuples)
+// 4. Datenstrukturen (Array, Map, Set, Tupel)
/////////////////////////////////////////////////
// Array
@@ -344,11 +344,11 @@ a(21) // Exception
// Map - Speichert Key-Value-Paare
-val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
+val m = Map("fork" -> "Gabel", "spoon" -> "Löffel", "knife" -> "Messer")
m("fork")
m("spoon")
m("bottle") // Exception
-val safeM = m.withDefaultValue("no lo se")
+val safeM = m.withDefaultValue("unbekannt")
safeM("bottle")
// Set - Speichert Unikate, unsortiert (sortiert -> SortedSet)
@@ -359,8 +359,8 @@ s(1) //true
val s = Set(1,1,3,3,7)
s: scala.collection.immutable.Set[Int] = Set(1, 3, 7)
-// Tuple - Speichert beliebige Daten und "verbindet" sie miteinander
-// Ein Tuple ist keine Collection.
+// Tupel - Speichert beliebige Daten und "verbindet" sie miteinander
+// Ein Tupel ist keine Collection.
(1, 2)
(4, 3, 2)
@@ -368,15 +368,15 @@ s: scala.collection.immutable.Set[Int] = Set(1, 3, 7)
(a, 2, "three")
-// Hier ist der Rückgabewert der Funktion ein Tuple
-// Die Funktion gibt das Ergebnis, so wie den Rest zurück.
+// Hier ist der Rückgabewert der Funktion ein Tupel
+// Die Funktion gibt das Ergebnis sowie den Rest zurück.
val divideInts = (x: Int, y: Int) => (x / y, x % y)
divideInts(10, 3)
-// Um die Elemente eines Tuples anzusprechen, benutzt man diese
-// Notation: _._n wobei n der index des Elements ist (Index startet bei 1)
+// Um die Elemente eines Tupels anzusprechen, benutzt man diese
+// Notation: _._n wobei n der index des Elements ist (Index startet bei 1)
val d = divideInts(10, 3)
d._1
@@ -388,32 +388,32 @@ d._2
/////////////////////////////////////////////////
/*
- Bislang waren alle gezeigten Sprachelemente einfache Ausdrücke, welche zwar
- zum Ausprobieren und Lernen in der REPL gut geeignet sind, jedoch in
- einem Scala file selten alleine zu finden sind.
- Die einzigen Top-Level Konstrukte in Scala sind nämlich:
+ Bislang waren alle gezeigten Sprachelemente einfache Ausdrücke, welche zwar
+ zum Ausprobieren und Lernen in der REPL gut geeignet sind, jedoch in
+ einer Scala-Datei selten alleine zu finden sind.
+ Die einzigen Top-Level-Konstrukte in Scala sind nämlich:
- Klassen (classes)
- Objekte (objects)
- case classes
- traits
- Diesen Sprachelemente wenden wir uns jetzt zu.
+ Diesen Sprachelemente wenden wir uns jetzt zu.
*/
// Klassen
-// Zum Erstellen von Objekten benötigt man eine Klasse, wie in vielen
-// anderen Sprachen auch.
+// Zum Erstellen von Objekten benötigt man eine Klasse, wie in vielen
+// anderen Sprachen auch.
-// erzeugt Klasse mit default Konstruktor
+// erzeugt Klasse mit default Konstruktor:
class Hund
scala> val t = new Hund
t: Hund = Hund@7103745
-// Der Konstruktor wird direkt hinter dem Klassennamen deklariert.
+// Der Konstruktor wird direkt hinter dem Klassennamen deklariert.
class Hund(sorte: String)
scala> val t = new Hund("Dackel")
@@ -421,8 +421,8 @@ t: Hund = Hund@14be750c
scala> t.sorte //error: value sorte is not a member of Hund
-// Per val wird aus dem Attribut ein unveränderliches Feld der Klasse
-// Per var wird aus dem Attribut ein veränderliches Feld der Klasse
+// Per val wird aus dem Attribut ein unveränderliches Feld der Klasse
+// Per var wird aus dem Attribut ein veränderliches Feld der Klasse
class Hund(val sorte: String)
scala> val t = new Hund("Dackel")
@@ -431,14 +431,14 @@ scala> t.sorte
res18: String = Dackel
-// Methoden werden mit def geschrieben
+// Methoden werden mit def geschrieben
-def bark = "Woof, woof!"
+def bark = "Wuff, wuff!"
-// Felder und Methoden können public, protected und private sein
-// default ist public
-// private ist nur innerhalb des deklarierten Bereichs sichtbar
+// Felder und Methoden können public, protected und private sein
+// default ist public
+// private ist nur innerhalb des deklarierten Bereichs sichtbar
class Hund {
private def x = ...
@@ -446,8 +446,8 @@ class Hund {
}
-// protected ist nur innerhalb des deklarierten und aller
-// erbenden Bereiche sichtbar
+// protected ist nur innerhalb des deklarierten und aller
+// erbenden Bereiche sichtbar
class Hund {
protected def x = ...
@@ -457,12 +457,12 @@ class Dackel extends Hund {
}
// Object
-// Wird ein Objekt ohne das Schlüsselwort "new" instanziert, wird das sog.
-// "companion object" aufgerufen. Mit dem "object" Schlüsselwort wird so
-// ein Objekt (Typ UND Singleton) erstellt. Damit kann man dann eine Klasse
-// benutzen ohne ein Objekt instanziieren zu müssen.
-// Ein gültiges companion Objekt einer Klasse ist es aber erst dann, wenn
-// es genauso heisst und in derselben Datei wie die Klasse definiert wurde.
+// Wird ein Objekt ohne das Schlüsselwort "new" instanziert, wird das sog.
+// "companion object" aufgerufen. Mit dem "object" Schlüsselwort wird so
+// ein Objekt (Typ UND Singleton) erstellt. Damit kann man dann eine Klasse
+// verwenden, ohne ein Objekt instanziieren zu müssen.
+// Ein gültiges companion Objekt einer Klasse ist es aber erst dann, wenn
+// es genauso heißt und in derselben Datei wie die Klasse definiert wurde.
object Hund {
def alleSorten = List("Pitbull", "Dackel", "Retriever")
@@ -470,50 +470,51 @@ object Hund {
}
// Case classes
-// Fallklassen bzw. Case classes sind Klassen die normale Klassen um extra
-// Funktionalität erweitern. Mit Case Klassen bekommt man ein paar
-// Dinge einfach dazu, ohne sich darum kümmern zu müssen. Z.B.
-// ein companion object mit den entsprechenden Methoden,
-// Hilfsmethoden wie toString(), equals() und hashCode() und auch noch
-// Getter für unsere Attribute (das Angeben von val entfällt dadurch)
+// Fallklassen bzw. Case classes sind Klassen, die normale Klassen um
+// zusätzliche Funktionalität erweitern.
+// Mit Case-Klassen bekommt man ein paar
+// Dinge einfach dazu, ohne sich darum kümmern zu müssen. Z.B.
+// ein companion object mit den entsprechenden Methoden,
+// Hilfsmethoden wie toString(), equals() und hashCode() und auch noch
+// Getter für unsere Attribute (das Angeben von val entfällt dadurch)
class Person(val name: String)
class Hund(val sorte: String, val farbe: String, val halter: Person)
-// Es genügt das Schlüsselwort case vor die Klasse zu schreiben.
+// Es genügt, das Schlüsselwort case vor die Klasse zu schreiben:
case class Person(name: String)
case class Hund(sorte: String, farbe: String, halter: Person)
-// Für neue Instanzen brauch man kein "new"
+// Für neue Instanzen braucht man kein "new":
val dackel = Hund("dackel", "grau", Person("peter"))
val dogge = Hund("dogge", "grau", Person("peter"))
-
-// getter
+
+// getter
dackel.halter // => Person = Person(peter)
-
-// equals
+
+// equals
dogge == dackel // => false
-
-// copy
-// otherGeorge == Person("george", "9876")
+
+// copy
+// otherGeorge == Person("george", "9876")
val otherGeorge = george.copy(phoneNumber = "9876")
// Traits
-// Ähnlich wie Java interfaces, definiert man mit traits einen Objekttyp
-// und Methodensignaturen. Scala erlaubt allerdings das teilweise
-// implementieren dieser Methoden. Konstruktorparameter sind nicht erlaubt.
-// Traits können von anderen Traits oder Klassen erben, aber nur von
-// parameterlosen.
+// Ähnlich wie Java interfaces, definiert man mit traits einen Objekttyp
+// und Methodensignaturen. Scala erlaubt allerdings das teilweise
+// Implementieren dieser Methoden. Konstruktorparameter sind nicht erlaubt.
+// Traits können von anderen Traits oder Klassen erben, aber nur von
+// parameterlosen.
trait Hund {
def sorte: String
@@ -527,22 +528,23 @@ class Bernhardiner extends Hund{
def beissen = false
}
-
-scala> b
-res0: Bernhardiner = Bernhardiner@3e57cd70
-scala> b.sorte
-res1: String = Bernhardiner
-scala> b.bellen
-res2: Boolean = true
-scala> b.beissen
-res3: Boolean = false
+scala> b
+res0: Bernhardiner = Bernhardiner@3e57cd70
+scala> b.sorte
+res1: String = Bernhardiner
+scala> b.bellen
+res2: Boolean = true
+scala> b.beissen
+res3: Boolean = false
-// Traits können auch via Mixins (Schlüsselwort "with") eingebunden werden
+// Ein Trait kann auch als Mixin eingebunden werden. Die Klasse erbt vom
+// ersten Trait mit dem Schlüsselwort "extends", während weitere Traits
+// mit "with" verwendet werden können.
trait Bellen {
- def bellen: String = "Woof"
+ def bellen: String = "Wuff"
}
trait Hund {
def sorte: String
@@ -555,17 +557,17 @@ class Bernhardiner extends Hund with Bellen{
scala> val b = new Bernhardiner
b: Bernhardiner = Bernhardiner@7b69c6ba
scala> b.bellen
-res0: String = Woof
+res0: String = Wuff
/////////////////////////////////////////////////
-// 6. Pattern Matching
+// 6. Mustervergleich (Pattern Matching)
/////////////////////////////////////////////////
-// Pattern matching in Scala ist ein sehr nützliches und wesentlich
-// mächtigeres Feature als Vergleichsfunktionen in Java. In Scala
-// benötigt ein case Statement kein "break", ein fall-through gibt es nicht.
-// Mehrere Überprüfungen können mit einem Statement gemacht werden.
-// Pattern matching wird mit dem Schlüsselwort "match" gemacht.
+// Pattern matching in Scala ist ein sehr nützliches und wesentlich
+// mächtigeres Feature als Vergleichsfunktionen in Java. In Scala
+// benötigt ein case Statement kein "break", ein fall-through gibt es nicht.
+// Mehrere Überprüfungen können mit einem Statement gemacht werden.
+// Pattern matching wird mit dem Schlüsselwort "match" gemacht.
val x = ...
x match {
@@ -575,19 +577,19 @@ x match {
}
-// Pattern Matching kann auf beliebige Typen prüfen
+// Pattern Matching kann auf beliebige Typen prüfen
val any: Any = ...
val gleicht = any match {
case 2 | 3 | 5 => "Zahl"
- case "woof" => "String"
+ case "wuff" => "String"
case true | false => "Boolean"
case 45.35 => "Double"
case _ => "Unbekannt"
}
-// und auf Objektgleichheit
+// und auf Objektgleichheit
def matchPerson(person: Person): String = person match {
case Person("George", nummer) => "George! Die Nummer ist " + number
@@ -596,31 +598,31 @@ def matchPerson(person: Person): String = person match {
}
-// Und viele mehr...
+// Und viele mehr...
val email = "(.*)@(.*)".r // regex
def matchEverything(obj: Any): String = obj match {
// Werte:
- case "Hello world" => "Got the string Hello world"
+ case "Hallo Welt" => "string Hallo Welt gefunden"
// Typen:
- case x: Double => "Got a Double: " + x
- // Conditions:
- case x: Int if x > 10000 => "Got a pretty big number!"
- // Case Classes:
- case Person(name, number) => s"Got contact info for $name!"
+ case x: Double => "Double gefunden: " + x
+ // Bedingungen:
+ case x: Int if x > 10000 => "Ziemlich große Zahl gefunden!"
+ // Case-Klassen:
+ case Person(name, number) => s"Kontaktinformationen für $name gefunden!"
// RegEx:
- case email(name, domain) => s"Got email address $name@$domain"
- // Tuples:
- case (a: Int, b: Double, c: String) => s"Got a tuple: $a, $b, $c"
+ case email(name, domain) => s"E-Mail-Adresse $name@$domain gefunden"
+ // Tupel:
+ case (a: Int, b: Double, c: String) => s"Tupel gefunden: $a, $b, $c"
// Strukturen:
- case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c"
- // Patterns kann man ineinander schachteln:
- case List(List((1, 2, "YAY"))) => "Got a list of list of tuple"
+ case List(1, b, c) => s"Liste aus drei Elementen gefunden, startend mit 1: 1, $b, $c"
+ // Pattern kann man ineinander schachteln:
+ case List(List((1, 2, "YAY"))) => "Liste von Tupeln gefunden"
}
-// Jedes Objekt mit einer "unapply" Methode kann per Pattern geprüft werden
-// Ganze Funktionen können Patterns sein
+// Jedes Objekt mit einer "unapply" Methode kann per Pattern geprüft werden.
+// Ganze Funktionen können Patterns sein:
val patternFunc: Person => String = {
case Person("George", number) => s"George's number: $number"
@@ -629,58 +631,58 @@ val patternFunc: Person => String = {
/////////////////////////////////////////////////
-// 37. Higher-order functions
+// 7. "Higher-order"-Funktionen
/////////////////////////////////////////////////
-Scala erlaubt, das Methoden und Funktion wiederum Funtionen und Methoden
-als Aufrufparameter oder Return Wert verwenden. Diese Methoden heissen
-higher-order functions
-Es gibt zahlreiche higher-order functions nicht nur für Listen, auch für
-die meisten anderen Collection Typen, sowie andere Klassen in Scala
-Nennenswerte sind:
-"filter", "map", "reduce", "foldLeft"/"foldRight", "exists", "forall"
+// Scala erlaubt, dass Methoden und Funktionen wiederum Funtionen und Methoden
+// als Aufrufparameter oder Rückgabewert verwenden. Diese Methoden heißen
+// higher-order functions.
+// Es gibt zahlreiche higher-order-Funtionen nicht nur für Listen, auch für
+// die meisten anderen Collection-Typen, sowie andere Klassen in Scala.
+// Nennenswerte sind:
+// "filter", "map", "reduce", "foldLeft"/"foldRight", "exists", "forall"
-## List
+// List
-def isGleichVier(a:Int) = a == 4
+def istGleichVier(a:Int) = a == 4
val list = List(1, 2, 3, 4)
val resultExists4 = list.exists(isEqualToFour)
-## map
-// map nimmt eine Funktion und führt sie auf jedem Element aus und erzeugt
-// eine neue Liste
-
-// Funktion erwartet ein Int und returned ein Int
+// map
+// map nimmt eine Funktion und führt sie auf jedem Element aus und erzeugt
+// eine neue Liste
-val add10: Int => Int = _ + 10
+// Funktion erwartet einen Int und gibt einen Int zurück:
+val add10: Int => Int = _ + 10
-// add10 wird auf jedes Element angewendet
+
+// add10 wird auf jedes Element angewendet:
List(1, 2, 3) map add10 // => List(11, 12, 13)
-// Anonyme Funktionen können anstatt definierter Funktionen verwendet werden
+// Anonyme Funktionen können anstatt definierter Funktionen verwendet werden:
List(1, 2, 3) map (x => x + 10)
-// Der Unterstrich wird anstelle eines Parameters einer anonymen Funktion
-// verwendet. Er wird an die Variable gebunden.
+// Der Unterstrich wird anstelle eines Parameters einer anonymen Funktion
+// verwendet. Er wird an die Variable gebunden:
List(1, 2, 3) map (_ + 10)
-// Wenn der anonyme Block und die Funtion beide EIN Argument erwarten,
-// kann sogar der Unterstrich weggelassen werden.
+// Wenn der anonyme Block und die Funktion beide EIN Argument erwarten,
+// kann sogar der Unterstrich weggelassen werden.
List("Dom", "Bob", "Natalia") foreach println
// filter
-// filter nimmt ein Prädikat (eine Funktion von A -> Boolean) und findet
-// alle Elemente die auf das Prädikat passen
+// filter nimmt ein Prädikat (eine Funktion von A -> Boolean) und findet
+// alle Elemente, die auf das Prädikat passen:
List(1, 2, 3) filter (_ > 2) // => List(3)
case class Person(name: String, age: Int)
@@ -691,19 +693,19 @@ List(
// reduce
-// reduce nimmt zwei Elemente und kombiniert sie zu einem Element,
-// und zwar solange bis nur noch ein Element da ist.
+// reduce nimmt zwei Elemente und kombiniert sie zu einem Element,
+// und zwar so lange, bis nur noch ein Element da ist.
// foreach
-// foreach gibt es für einige Collections
+// foreach gibt es für einige Collections
val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100)
aListOfNumbers foreach (x => println(x))
aListOfNumbers foreach println
// For comprehensions
-// Eine for-comprehension definiert eine Beziehung zwischen zwei Datensets.
-// Dies ist keine for-Schleife.
+// Eine for-comprehension definiert eine Beziehung zwischen zwei Datensets.
+// Dies ist keine for-Schleife.
for { n <- s } yield sq(n)
val nSquared2 = for { n <- s } yield sq(n)
@@ -715,108 +717,108 @@ for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
// 8. Implicits
/////////////////////////////////////////////////
-// **ACHTUNG:**
+// **ACHTUNG:**
// Implicits sind ein sehr mächtiges Sprachfeature von Scala.
-// Es sehr einfach
-// sie falsch zu benutzen und Anfänger sollten sie mit Vorsicht oder am
-// besten erst dann benutzen, wenn man versteht wie sie funktionieren.
-// Dieses Tutorial enthält Implicits, da sie in Scala an jeder Stelle
-// vorkommen und man auch mit einer Lib die Implicits benutzt nichts sinnvolles
-// machen kann.
-// Hier soll ein Grundverständnis geschaffen werden, wie sie funktionieren.
+// Es sehr einfach,
+// sie falsch zu benutzen und Anfänger sollten sie mit Vorsicht oder am
+// besten erst dann benutzen, wenn sie verstehen, wie sie funktionieren.
+// Dieses Tutorial enthält Implicits, da sie in Scala an jeder Stelle
+// vorkommen und man auch mit einer Bibliothek, die Implicits benutzt, sonst
+// nichts sinnvolles machen kann.
+// Hier soll ein Grundverständnis geschaffen werden, wie sie funktionieren.
-// Mit dem Schlüsselwort implicit können Methoden, Werte, Funktion, Objekte
-// zu "implicit Methods" werden.
+// Mit dem Schlüsselwort implicit können Methoden, Werte, Funktion, Objekte
+// zu "implicit Methods" werden.
implicit val myImplicitInt = 100
implicit def myImplicitFunction(sorte: String) = new Hund("Golden " + sorte)
-// implicit ändert nicht das Verhalten eines Wertes oder einer Funktion
+// implicit ändert nicht das Verhalten eines Wertes oder einer Funktion
myImplicitInt + 2 // => 102
myImplicitFunction("Pitbull").sorte // => "Golden Pitbull"
-// Der Unterschied ist, dass diese Werte ausgewählt werden können, wenn ein
-// anderer Codeteil einen implicit Wert benötigt, zum Beispiel innerhalb von
-// implicit Funktionsparametern
-
-// Diese Funktion hat zwei Parameter: einen normalen und einen implicit
+// Der Unterschied ist, dass diese Werte ausgewählt werden können, wenn ein
+// anderer Codeteil einen implicit Wert benötigt, zum Beispiel innerhalb von
+// implicit Funktionsparametern
+
+// Diese Funktion hat zwei Parameter: einen normalen und einen implicit
def sendGreetings(toWhom: String)(implicit howMany: Int) =
- s"Hello $toWhom, $howMany blessings to you and yours!"
+ s"Hallo $toWhom, $howMany Segenswünsche für Sie und Ihre Angehörigen!"
+
+// Werden beide Parameter gefüllt, verhält sich die Funktion wie erwartet
-// Werden beide Parameter gefüllt, verhält sich die Funktion wie erwartet
+sendGreetings("John")(1000) // => "Hallo John, 1000 Segenswünsche für Sie und Ihre Angehörigen!"
-sendGreetings("John")(1000) // => "Hello John, 1000 blessings to you and yours!"
+// Wird der implicit-Parameter jedoch weggelassen, wird ein anderer
+// implicit-Wert vom gleichen Typ genommen. Der Compiler sucht im
+// lexikalischen Scope und im companion object nach einem implicit-Wert,
+// der vom Typ passt, oder nach einer implicit-Methode, mit der er in den
+// geforderten Typ konvertieren kann.
-// Wird der implicit Parameter jedoch weggelassen, wird ein anderer
-// implicit Wert vom gleichen Typ genommen. Der Compiler sucht im
-// lexikalischen Scope und im companion object nach einem implicit Wert,
-// der vom Typ passt, oder nach einer implicit Methode mit der er in den
-// geforderten Typ konvertieren kann.
-
-// Hier also: "myImplicitInt", da ein Int gesucht wird
+// Hier also: "myImplicitInt", da ein Int gesucht wird
-sendGreetings("Jane") // => "Hello Jane, 100 blessings to you and yours!"
+sendGreetings("Jane") // => "Hallo Jane, 100 Segenswünsche für Sie und Ihre Angehörigen!"
-// bzw. "myImplicitFunction"
-// Der String wird erst mit Hilfe der Funktion in Hund konvertiert, und
-// dann wird die Methode aufgerufen
+// bzw. "myImplicitFunction"
+// Der String wird erst mit Hilfe der Funktion in Hund konvertiert,
+// dann wird die Methode aufgerufen:
"Retriever".sorte // => "Golden Retriever"
/////////////////////////////////////////////////
-// 19. Misc
+// 9. Sonstiges
/////////////////////////////////////////////////
// Importe
import scala.collection.immutable.List
-// Importiere alle Unterpackages
+// Importiere alle Unterpackages
import scala.collection.immutable._
-// Importiere verschiedene Klassen mit einem Statement
+// Importiere verschiedene Klassen mit einem Statement
import scala.collection.immutable.{List, Map}
-// Einen Import kann man mit '=>' umbenennen
+// Einen Import kann man mit '=>' umbenennen
import scala.collection.immutable.{List => ImmutableList}
-// Importiere alle Klasses, mit Ausnahem von....
-// Hier ohne: Map and Set:
+// Importiere alle Klasses, mit Ausnahem von....
+// Hier ohne: Map and Set:
import scala.collection.immutable.{Map => _, Set => _, _}
-// Main
+// Main
object Application {
def main(args: Array[String]): Unit = {
- // Sachen kommen hierhin
+ // Zeugs hier rein.
}
}
// I/O
-// Eine Datei Zeile für Zeile lesen
+// Eine Datei Zeile für Zeile lesen
import scala.io.Source
for(line <- Source.fromFile("myfile.txt").getLines())
println(line)
-// Eine Datei schreiben
+// Eine Datei schreiben
val writer = new PrintWriter("myfile.txt")
writer.write("Schreibe Zeile" + util.Properties.lineSeparator)
@@ -825,13 +827,13 @@ writer.close()
```
-## Weiterführende Hinweise
+## Weiterführende Hinweise
-// DE
+### DE
* [Scala Tutorial](https://scalatutorial.wordpress.com)
* [Scala Tutorial](http://scalatutorial.de)
-// EN
+### EN
* [Scala for the impatient](http://horstmann.com/scala/)
* [Twitter Scala school](http://twitter.github.io/scala_school/)
* [The scala documentation](http://docs.scala-lang.org/)
diff --git a/de-de/shutit-de.html.markdown b/de-de/shutit-de.html.markdown
new file mode 100644
index 00000000..29ed639e
--- /dev/null
+++ b/de-de/shutit-de.html.markdown
@@ -0,0 +1,330 @@
+---
+category: tool
+filename: learnshutit-de.html
+tool: ShutIt
+contributors:
+ - ["Ian Miell", "http://ian.meirionconsulting.tk"]
+translators:
+ - ["Dennis Keller", "https://github.com/denniskeller"]
+lang: de-de
+---
+
+## ShutIt
+
+ShuIt ist eine Shellautomationsframework, welches für eine einfache
+Handhabung entwickelt wurde.
+
+Er ist ein Wrapper, der auf einem Python expect Klon (pexpect) basiert.
+
+Es ist damit ein 'expect ohne Schmerzen'.
+
+Es ist verfügbar als pip install.
+
+## Hello World
+
+Starten wir mit dem einfachsten Beispiel. Erstelle eine Datei names example.py
+
+```python
+
+import shutit
+session = shutit.create_session('bash')
+session.send('echo Hello World', echo=True)
+```
+
+Führe es hiermit aus:
+
+```bash
+python example.py
+```
+
+gibt aus:
+
+```bash
+$ python example.py
+echo "Hello World"
+echo "Hello World"
+Hello World
+Ians-MacBook-Air.local:ORIGIN_ENV:RhuebR2T#
+```
+
+Das erste Argument zu 'send' ist der Befehl, den du ausführen möchtest.
+Das 'echo' Argument gibt die Terminalinteraktion aus. ShuIt ist standardmäßig leise.
+
+'Send' kümmert sich um die nervige Arbeiten mit den Prompts und macht
+alles was du von 'expect' erwarten würdest.
+
+
+## Logge dich auf einen Server ein
+
+Sagen wir du möchtest dich auf einen Server einloggen und einen Befehl ausführen.
+Ändere dafür example.py folgendermaßen:
+
+```python
+import shutit
+session = shutit.create_session('bash')
+session.login('ssh you@example.com', user='du', password='meinpassword')
+session.send('hostname', echo=True)
+session.logout()
+```
+
+Dies erlaubt dir dich auf deinen Server einzuloggen
+(ersetze die Details mit deinen Eigenen) und das Programm gibt dir deinen Hostnamen aus.
+
+```
+$ python example.py
+hostname
+hostname
+example.com
+example.com:cgoIsdVv:heDa77HB#
+```
+
+
+Es ist klar das das nicht sicher ist. Stattdessen kann man Folgendes machen:
+
+```python
+import shutit
+session = shutit.create_session('bash')
+password = session.get_input('', ispass=True)
+session.login('ssh you@example.com', user='du', password=password)
+session.send('hostname', echo=True)
+session.logout()
+```
+
+Dies zwingt dich dein Passwort einzugeben:
+
+```
+$ python example.py
+Input Secret:
+hostname
+hostname
+example.com
+example.com:cgoIsdVv:heDa77HB#
+```
+
+
+Die 'login' Methode übernimmt wieder das veränderte Prompt für den Login.
+Du übergibst ShutIt den User und das Passwort, falls es benötigt wird,
+mit den du dich einloggen möchtest. ShutIt übernimmt den Rest.
+
+'logout' behandelt das Ende von 'login' und übernimmt alle Veränderungen des
+Prompts für dich.
+
+## Einloggen auf mehrere Server
+
+Sagen wir, dass du eine Serverfarm mit zwei Servern hast und du dich in
+beide Server einloggen möchtest. Dafür musst du nur zwei Session und
+Logins erstellen und kannst dann Befehle schicken:
+
+```python
+import shutit
+session1 = shutit.create_session('bash')
+session2 = shutit.create_session('bash')
+password1 = session1.get_input('Password für server1', ispass=True)
+password2 = session2.get_input('Password für server2', ispass=True)
+session1.login('ssh you@one.example.com', user='du', password=password1)
+session2.login('ssh you@two.example.com', user='du', password=password2)
+session1.send('hostname', echo=True)
+session2.send('hostname', echo=True)
+session1.logout()
+session2.logout()
+```
+
+Gibt aus:
+
+```bash
+$ python example.py
+Password for server1
+Input Secret:
+
+Password for server2
+Input Secret:
+hostname
+hostname
+one.example.com
+one.example.com:Fnh2pyFj:qkrsmUNs# hostname
+hostname
+two.example.com
+two.example.com:Gl2lldEo:D3FavQjA#
+```
+
+## Beispiel: Überwachen mehrerer Server
+
+Wir können das obige Programm in ein einfaches Überwachungstool bringen indem
+wir Logik hinzufügen um die Ausgabe von einem Befehl zu betrachten.
+
+```python
+import shutit
+capacity_command="""df / | awk '{print $5}' | tail -1 | sed s/[^0-9]//"""
+session1 = shutit.create_session('bash')
+session2 = shutit.create_session('bash')
+password1 = session.get_input('Passwort für Server1', ispass=True)
+password2 = session.get_input('Passwort für Server2', ispass=True)
+session1.login('ssh you@one.example.com', user='du', password=password1)
+session2.login('ssh you@two.example.com', user='du', password=password2)
+capacity = session1.send_and_get_output(capacity_command)
+if int(capacity) < 10:
+ print(kein Platz mehr auf Server1!')
+capacity = session2.send_and_get_output(capacity_command)
+if int(capacity) < 10:
+ print(kein Platz mehr auf Server2!')
+session1.logout()
+session2.logout()
+```
+
+Hier kannst du die 'send\_and\_get\_output' Methode verwenden um die Ausgabe von dem
+Kapazitätsbefehl (df) zu erhalten.
+
+Es gibt elegantere Wege als oben (z.B. kannst du ein Dictionary verwenden um über
+die Server zu iterieren), aber es hängt and dir wie clever das Python sein muss.
+
+
+## kompliziertere IO - Expecting
+
+Sagen wir du hast eine Interaktion mit einer interaktiven Kommandozeilenprogramm,
+die du automatisieren möchtest. Hier werden wir Telnet als triviales Beispiel verwenden:
+
+```python
+import shutit
+session = shutit.create_session('bash')
+session.send('telnet', expect='elnet>', echo=True)
+session.send('open google.com 80', expect='scape character', echo=True)
+session.send('GET /', echo=True, check_exit=False)
+session.logout()
+```
+
+Beachte das 'expect' Argument. Du brauchst nur ein Subset von Telnets
+Eingabeaufforderung um es abzugleichen und fortzufahren.
+
+Beachte auch das neue Argument 'check\_exit'. Wir werden nachher nochmal
+darauf zurückkommen. Die Ausgabe von oben ist:
+
+```bash
+$ python example.py
+telnet
+telnet> open google.com 80
+Trying 216.58.214.14...
+Connected to google.com.
+Escape character is '^]'.
+GET /
+HTTP/1.0 302 Found
+Cache-Control: private
+Content-Type: text/html; charset=UTF-8
+Referrer-Policy: no-referrer
+Location: http://www.google.co.uk/?gfe_rd=cr&ei=huczWcj3GfTW8gfq0paQDA
+Content-Length: 261
+Date: Sun, 04 Jun 2017 10:57:10 GMT
+
+<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
+<TITLE>302 Moved</TITLE></HEAD><BODY>
+<H1>302 Moved</H1>
+The document has moved
+<A HREF="http://www.google.co.uk/?gfe_rd=cr&amp;ei=huczWcj3GfTW8gfq0paQDA">
+here
+</A>.
+</BODY></HTML>
+Connection closed by foreign host.
+```
+
+Nun zurück zu 'check\_exit=False'. Da das Telnet Programm einen Fehler mit
+Fehlercode (1) zurückgibt und wir nicht möchten das das Skript fehlschlägt
+kannst du 'check\_exit=False' setzen und damit ShuIt wissen lassen, dass
+der Ausgabecode dich nicht interessiert.
+
+Wenn du das Argument nicht mitgegeben hättest, dann hätte dir ShutIt
+ein interaktives Terminal zurückgegeben, falls es ein Terminal zum
+kommunizieren gibt. Dies nennt sich ein 'Pause point'.
+
+
+## Pause Points
+
+Du kannst jederzeit 'pause point' auslösen, wenn du Folgendes in deinem Skript aufrufst:
+
+```python
+[...]
+session.pause_point('Das ist ein pause point')
+[...]
+```
+
+Danach kannst du das Skript fortführen, wenn du CTRL und ']' zur selben Zeit drückst.
+Dies ist gut für Debugging: Füge ein Pause Point hinzu und schaue dich um.
+Danach kannst du das Programm weiter ausführen. Probiere folgendes aus:
+
+```python
+import shutit
+session = shutit.create_session('bash')
+session.pause_point('Schaue dich um!')
+session.send('echo "Hat dir der Pause point gefallen?"', echo=True)
+```
+
+Dies würde folgendes ausgeben:
+
+```bash
+$ python example.py
+Schaue dich um!
+
+Ians-Air.home:ORIGIN_ENV:I00LA1Mq# bash
+imiell@Ians-Air:/space/git/shutit ⑂ master + 
+CTRL-] caught, continuing with run...
+2017-06-05 15:12:33,577 INFO: Sending: exit
+2017-06-05 15:12:33,633 INFO: Output (squashed): exitexitIans-Air.home:ORIGIN_ENV:I00LA1Mq# [...]
+echo "Hat dir der Pause point gefallen?"
+echo "Hat dir der Pause point gefallen?"
+Hat dir der Pause point gefallen?
+Ians-Air.home:ORIGIN_ENV:I00LA1Mq#
+```
+
+
+## noch kompliziertere IO - Hintergrund
+
+Kehren wir zu unseren Beispiel mit dem Überwachen von mehreren Servern zurück.
+Stellen wir uns vor, dass wir eine langlaufende Aufgabe auf jedem Server durchführen möchten.
+Standardmäßig arbeitet ShutIt seriell, was sehr lange dauern würde.
+Wir können jedoch die Aufgaben im Hintergrund laufen lassen um sie zu beschleunigen.
+
+Hier ist ein Beispiel, welches du ausprobieren kannst.
+Es verwendet den trivialen Befehl: 'sleep'.
+
+
+```python
+import shutit
+import time
+long_command="""sleep 60"""
+session1 = shutit.create_session('bash')
+session2 = shutit.create_session('bash')
+password1 = session1.get_input('Password for server1', ispass=True)
+password2 = session2.get_input('Password for server2', ispass=True)
+session1.login('ssh you@one.example.com', user='du', password=password1)
+session2.login('ssh you@two.example.com', user='du', password=password2)
+start = time.time()
+session1.send(long_command, background=True)
+session2.send(long_command, background=True)
+print('Es hat: ' + str(time.time() - start) + ' Sekunden zum Starten gebraucht')
+session1.wait()
+session2.wait()
+print('Es hat:' + str(time.time() - start) + ' Sekunden zum Vollenden gebraucht')
+```
+
+Mein Computer meint, dass er 0.5 Sekunden gebraucht hat um die Befehle zu starten
+und dann nur etwas über eine Minute gebraucht um sie zu beenden
+(mit Verwendung der 'wait' Methode).
+
+
+Das alles ist trivial, aber stelle dir vor das du hunderte an Servern so managen
+kannst und man kann nun das Potential sehen, die in ein paar Zeilen Code und ein Python
+import liegen können.
+
+
+## Lerne mehr
+
+Es gibt noch viel mehr, was mit ShutIt erreicht werden kann.
+
+Um mehr zu erfahren, siehe:
+
+[ShutIt](https://ianmiell.github.io/shutit/)
+[GitHub](https://github.com/ianmiell/shutit/blob/master/README.md)
+
+Es handelt sich um ein breiteres Automatiesierungsframework, und das oben
+genannte ist der sogennante 'standalone Modus'.
+
+Feedback, feature requests, 'Wie mache ich es' sind herzlich willkommen! Erreiche mit unter
+[@ianmiell](https://twitter.com/ianmiell)
diff --git a/de-de/swift-de.html.markdown b/de-de/swift-de.html.markdown
index b58a72d3..08f72a35 100644
--- a/de-de/swift-de.html.markdown
+++ b/de-de/swift-de.html.markdown
@@ -440,13 +440,13 @@ if let circle = myEmptyCircle {
// Wie Klassen auch können sie Methoden haben
enum Suit {
- case Spades, Hearts, Diamonds, Clubs
+ case spades, hearts, diamonds, clubs
func getIcon() -> String {
switch self {
- case .Spades: return "♤"
- case .Hearts: return "♡"
- case .Diamonds: return "♢"
- case .Clubs: return "♧"
+ case .spades: return "♤"
+ case .hearts: return "♡"
+ case .diamonds: return "♢"
+ case .clubs: return "♧"
}
}
}
@@ -455,35 +455,35 @@ enum Suit {
// Enum-Werte können vereinfacht geschrieben werden, es muss nicht der Enum-Typ
// genannt werden, wenn die Variable explizit deklariert wurde
-var suitValue: Suit = .Hearts
+var suitValue: Suit = .hearts
// Nicht-Integer-Enums brauchen direkt zugewiesene "Rohwerte"
enum BookName: String {
- case John = "John"
- case Luke = "Luke"
+ case john = "John"
+ case luke = "Luke"
}
-print("Name: \(BookName.John.rawValue)")
+print("Name: \(BookName.john.rawValue)")
// Enum mit assoziierten Werten
enum Furniture {
// mit Int assoziiert
- case Desk(height: Int)
+ case desk(height: Int)
// mit String und Int assoziiert
- case Chair(String, Int)
-
+ case chair(String, Int)
+
func description() -> String {
switch self {
- case .Desk(let height):
+ case .desk(let height):
return "Desk with \(height) cm"
- case .Chair(let brand, let height):
+ case .chair(let brand, let height):
return "Chair of \(brand) with \(height) cm"
}
}
}
-var desk: Furniture = .Desk(height: 80)
+var desk: Furniture = .desk(height: 80)
print(desk.description()) // "Desk with 80 cm"
-var chair = Furniture.Chair("Foo", 40)
+var chair = Furniture.chair("Foo", 40)
print(chair.description()) // "Chair of Foo with 40 cm"
diff --git a/de-de/vim-de.html.markdown b/de-de/vim-de.html.markdown
new file mode 100644
index 00000000..8abf9a14
--- /dev/null
+++ b/de-de/vim-de.html.markdown
@@ -0,0 +1,282 @@
+---
+category: tool
+tool: vim
+lang: de-de
+contributors:
+ - ["RadhikaG", "https://github.com/RadhikaG"]
+translators:
+ - ["caminsha", "https://github.com/caminsha"]
+filename: LearnVim-de.txt
+---
+
+
+[Vim](http://www.vim.org)
+(Vi IMproved) ist ein Klon von vi, dem bekannten Editor für Unix. Es ist ein
+Texteditor, welcher mit Fokus auf Geschwindigkeit und Prouktivität entwickelt
+wurde.
+Vim hat viele Keybindings für ein schnelles navigieren und schnelles bearbeiten
+einer Datei.
+
+## Grundlagen, um in Vim zu navigieren
+
+```
+ vim <filename> # Öffne <filename> in Vim
+ :help <topic> # Open up built-in help docs about <topic> if any exists
+ :help <topic> # Öffne die eingebaute Hilfe zum Thema <topic>, wenn
+ # es existiert
+ :q # Schließe vim
+ :w # Speichere diese Datei
+ :wq # Speichere diese Datei und schließe vim
+ ZZ # Speichere diese Datei und schließe vim
+ :q! # Schließe vim ohne die Datei zu speichern
+ # ! *zwingt* die Ausführung von :q,
+ # daher wird die Datei nicht gespeichert.
+ ZQ # Beende vim ohne die Datei zu speichern
+ :x # Speichere die Datei und beende vim
+ # Dies ist eine kürzere Version von :wq
+
+ u # Änderung rückgängig machen
+ CTRL+R # Änderung wiederherstellen
+
+ h # Den Cursor um ein Zeichen nach links bewegen
+ j # Den Cursor eine Zeile nach unten bewegen
+ k # Den Cursor eine Zeile nach oben bewegen
+ l # Den Cursor um ein Zeichen nach rechts bewegen
+
+ Ctrl+B # Gehe eine Bildschirmanzeige zurück
+ Ctrl+F # Gehe eine Bildschirmanzeige vorwärts
+ Ctrl+D # Gehe eine halbe Bildschirmanzeige vorwärts
+ Ctrl+U # Gehe eine halbe Bildschirmanzeige zurück
+
+ # Navigieren innerhalb einer Zeile
+
+ 0 # Navigiere zum Anfang der Zeile
+ $ # Navigiere zum Ende der Zeile
+ ^ # Navigiere zum ersten Zeichen, welches kein Leerzeichen ist
+
+ # Im Text suchen
+
+ /word # Hebt alle Ergebnisse nach dem Cursor hervor
+ ?word # Hebt alle Ergebnisse vor dem Cursor hervor
+ n # Bewegt den Cursor zum nächsten Ergebnis nach der Suche
+ N # Bewegt den Cursor zum vorherigen Ergebnis der Suche
+
+ :%s/foo/bar/g # Ersetze "foo" durch "bar" in allen Zeilen
+ :s/foo/bar/g # Ersetze "foo" durch "bar" in der aktuellen Zeile
+ :%s/\n/\r/g # Ersetze das newline-Zeichen bei allen Zeilen durch
+ # ein carriage return
+
+ # Zu einzelnen Zeichen springen
+
+ f<character> # Springe vorwärts und auf dem Zeichen <character>
+ t<character> # Springe vorwärts und lande vor dem Zeichen <character>
+
+ # Zum Beispiel,
+ f< # Springe vorwärts und lande auf <
+ t< # Springe vorwärts und lande vor <
+
+ # Wortweise navigieren
+
+ w # Springe um ein Wort vorwärts
+ b # Gehe ein Wort zurück
+ e # Springe zum Ende des aktuellen Wortes
+
+ # Weitere Befehle, um zu navigieren
+
+ gg # Gehe an den Start der Datei
+ G # Gehe an das Ende der Datei
+ :NUM # Springe zur Zeile NUM (NUM kann eine beliebige Zahl sein)
+ H # Navigiere zum Start der aktuellen Bildschirmanzeige
+ M # Navigiere in die Mitte der aktuellen Bildschirmanzeige
+ L # Navigiere an das Ende der aktuellen Bildschirmanzeige
+```
+
+## Hilfsdokumente:
+
+Vim hat eine eingebaute Dokumentation, welche mit `:help <topic>` aufgerufen
+werden kann.
+Zum Beispiel öffnet `:help navigation` die Dokumentation über das Navigieren
+
+`:help` kann auch ohne ein Argument verwendet werden. Dies zeigt den Standard-
+Hilfsdialog an, welcher den Start mit vim einfacher macht.
+that aims to make getting started with vim more approachable!
+
+## Modi:
+
+Vim basiert auf dem Konzept von **modes**.
+
+- Command Mode - Vim startet in diesem Modus, hier kann man navigieren und Befehle eingeben
+- Insert Mode - Wird verwendet, um Änderungen in der Datei zu machen.
+- Visual Mode - Wird verwendet, um Text zu markieren und Operationen durchzuführen
+- Ex Mode - Wird verwendet, um im ':'-Prompt Befehle einzugeben
+
+```
+ i # Führt vim in den Insert Mode, vor der Cursorposition
+ a # Führt vim in den Insert Mode, nach der Cursorposition
+ v # Führt vim in den Visual Mode
+ : # Führt vim in den Ex Mode
+ <esc> # Führt zurück in den Command Mode, egal in welchem Mode
+ # man sich gerade befindet.
+
+ # Kopieren und einfügen von Text
+
+ y # Kopiere alles, was im Moment ausgewählt ist
+ yy # Kopiert die aktuelle Zeile
+ d # Löscht alles, was im Moment ausgewählt ist
+ dd # Löscht die aktuelle Zeile
+ p # Fügt den kopierten Text nach dem Cursor ein
+ P # Fügt den kopierten Text vor dem Cursor ein
+ x # Löscht das Zeichen unter dem Cursor
+```
+
+## Die 'Grammatik' von Vim
+
+Vim kann als Satz von Kommandos angesehen werden, welche im Format
+'Verb-Modifier-Noun' sind. Hierbei gilt:
+
+- Verb - die Aktion, du machen willst
+- Modifier - wie die Aktion gemacht wird
+- Noun - das Objekt, auf welchem die Aktion ausgeführt wird.
+
+Einige wichtige Beispiele von 'Verb', 'Modifier' und 'Nouns':
+
+```
+ # 'Verb'
+
+ d # löschen
+ c # ändern
+ y # kopieren
+ v # visuelles auswählen
+
+ # 'Modifiers'
+
+ i # innerhalb
+ a # außerhalb
+ NUM # Nummer (NUM kann irgendeine Zahl sein)
+ f # Sucht nach etwas und landet darauf
+ t # Sucht nach etwas und stoppt davor
+ / # Suche eine Zeichenfolge ab dem Cursor
+ ? # Suche eine Zeichenfolge vor dem Cursor
+
+ # 'Nouns'
+
+ w # Wort
+ s # Satz
+ p # Abschnitt
+ b # Block
+
+ # Beispielsätze resp. Kommandos
+
+ d2w # lösche zwei Wörter
+ cis # Ändere innerhalb des Satzes.
+ yip # Kopiere innerhalb des Abschnitts (kopiere den Abschnitt,
+ # in welchem du bist)
+ ct< # Ändere bis zur spitzen Klammer
+ # Ändere den Text von deiner aktuellen Cursorposition bis
+ # zur nächsten spitzen Klammer
+ d$ # Lösche bis zum Ende der Zeile
+```
+
+## Einige Shortcuts und Tricks
+
+```
+ > # Rücke die Auswahl um einen Block ein
+ < # Lösche eine Einrückung der Auswahl
+ :earlier 15m # Stellt das Dokument so wieder her, wie es vor 15
+ # Minuten war
+ :later 15m # den oberen Befehl rückgängig machen
+ ddp # Vertauschen zweier aufeinanderfolgenden Zeilen
+ # Zuerst dd, dann p
+ . # Wiederhole die vorherige Aktion
+ :w !sudo tee % # Speichere die Datei als Root
+ :set syntax=c # Stelle das Syntax-Highlighting für 'C' ein
+ :sort # Alle Zeilen sortieren
+ :sort! # Alle Zeilen rückwärts sortieren
+ :sort u # Alle Zeilen sortieren und Duplikate entfernen
+ ~ # Umschalten der Groß-/Kleinschreibung des ausgewählten Textes
+ u # Ausgewählten Text zu Kleinschreibung ändern
+ U # Ausgewählten Text zu Großschreibung ändern
+
+ # Text-Folding (Textfaltung)
+ zf # Erstelle eine Faltung des ausgewählten Textes
+ zo # Öffne die aktuelle Faltung
+ zc # Schließe die aktuelle Faltung
+ zR # Öffne alle Faltungen
+ zM # Schließe alle Faltungen
+```
+
+## Makros
+
+Makros sind grundsätzlich einfach aufgezeichnete Aktionen
+Wenn du mit dem Aufnehmen eines Makros beginnst, werden **alle** Aktionen und
+Kommandos, welche du braucht, aufgenommen bis die Aufnahme gestoppt wird.
+Wenn du ein Makro ausführst, werden exakt die gleichen Schritte gemacht.
+
+```
+ qa # Starte das Aufnehmen des Makros 'a'
+ q # Beende das Aufnehmen
+ @a # Führe das Makro 'a' aus
+```
+
+### Konfigurieren mit ~/.vimrc
+
+Die Datei .vimrc kann verwendet werden, um Vim beim Starten zu konfigurieren
+
+Hier ist eine Beispiel ~/.vimrc Datei:
+
+```
+" Beispiel ~/.vimrc
+
+" Erforderlich für vim, dass es iMproved ist.
+set nocompatible
+
+" Bestimme den Dateityp anhand des Namens, um ein intelligentes Einrücken etc.
+" zu ermöglichen
+filetype indent plugin on
+
+" Aktiviere das Syntax-Highlighting
+syntax on
+
+" Bessere Kommandozeilen-Vervollständigung
+set wildmenu
+
+" Verwende die Suche ohne die Berücksichtigung der Groß-/Kleinschreibung, außer
+" wenn mit Großbuchstaben gesucht wird.
+set ignorecase
+set smartcase
+
+" Wenn eine neue Zeile erstellt wird und kein Dateispezifisches Einrücken
+" aktiviert ist, behält die neue Zeile die gleiche Einrückung wie die aktuelle
+" Zeile
+set autoindent
+
+" Zeige links die Zeilennummern an
+set number
+
+" Einrückungsoptionen, ändere diese nach deinen Vorlieben
+
+" Anzahl sichtbarer Leerzeichen bei einem TAB
+set tabstop=4
+
+" Anzahl der Leerzeichen während des Bearbeitens bei einem TAB
+set softtabstop=4
+
+" Anzahl der Einrückungstiefe bei den Operationen (>> und <<)
+set shiftwidth=4
+
+" Konvertiere TABs zu Leerzeichen
+set expandtab
+
+" Enable intelligent tabbing and spacing for indentation and alignment
+" Aktiviere intelligente Tabs und Leerzeichen bei der Einrückung und Ausrichtung
+set smarttab
+```
+
+### Verweise
+
+- [Vim | Homepage](http://www.vim.org/index.php)
+- In der Shell eingeben: `vimtutor`
+- [Ein vim Tutorial und Primer, englisch](https://danielmiessler.com/study/vim/)
+- [Deutsches Arch Linux Wiki](https://wiki.archlinux.de/title/Vim)
+- [Arch Linux Wiki, englisch (dafür ausführlicher)](https://wiki.archlinux.org/index.php/Vim)
+- [What are the dark corners of Vim your mom never told you about? (Stack Overflow thread)](http://stackoverflow.com/questions/726894/what-are-the-dark-corners-of-vim-your-mom-never-told-you-about)
diff --git a/de-de/yaml-de.html.markdown b/de-de/yaml-de.html.markdown
index a46c30f6..0332c912 100644
--- a/de-de/yaml-de.html.markdown
+++ b/de-de/yaml-de.html.markdown
@@ -1,7 +1,7 @@
---
language: yaml
contributors:
- - ["Adam Brenecki", "https://github.com/adambrenecki"]
+ - ["Leigh Brenecki", "https://github.com/adambrenecki"]
translators:
- ["Ruben M.", "https://github.com/switchhax"]
filename: learnyaml-de.yaml
@@ -10,7 +10,7 @@ lang: de-de
YAML ist eine Sprache zur Datenserialisierung, die sofort von Menschenhand geschrieben und gelesen werden kann.
-YAML ist eine Erweiterung von JSON, mit der Erweiterung von syntaktisch wichtigen Zeilenumbrüche und Einrückung sowie in Python. Anders als in Python erlaubt YAML keine Tabulator-Zeichen.
+YAML ist ein Erweiterung von JSON mit der Erweiterung um syntaktisch wichtige Zeilenumbrüche und Einrückungen, ähnlich wie auch in Python geschrieben werden können. Anders als in Python allerdings erlaubt YAML keine Tabulator-Zeichen.
```yaml
# Kommentare in YAML schauen so aus.
@@ -111,7 +111,7 @@ python_komplexe_Zahlen: !!python/komplex 1+2j
# EXTRA YAML TYPEN #
####################
-# Strings and Zahlen sind nicht die einzigen Skalare, welche YAML versteht.
+# Strings und Zahlen sind nicht die einzigen Skalare, welche YAML versteht.
# ISO-formatierte Datumsangaben and Zeiangaben können ebenso geparsed werden.
DatumZeit: 2001-12-15T02:59:43.1Z
DatumZeit_mit_Leerzeichen: 2001-12-14 21:59:43.10 -5
diff --git a/dhall.html.markdown b/dhall.html.markdown
new file mode 100644
index 00000000..704a94ee
--- /dev/null
+++ b/dhall.html.markdown
@@ -0,0 +1,362 @@
+---
+language: Dhall
+filename: learndhall.dhall
+contributors:
+ - ["Gabriel Gonzalez", "http://www.haskellforall.com/"]
+---
+
+Dhall is a programmable configuration language that provides a non-repetitive
+alternative to YAML.
+
+You can think of Dhall as: JSON + functions + types + imports
+
+Note that while Dhall is programmable, Dhall is not Turing-complete. Many
+of Dhall's features take advantage of this restriction to provide stronger
+safety guarantees and more powerful tooling.
+
+```haskell
+-- Single-line comment
+
+{- Multi-line comment
+
+ Unicode is fine 🙂
+
+ This file is a valid Dhall expression that evaluates to a large record
+ collecting the results of each step.
+
+ You can view the results by interpreting the file:
+
+ $ dhall --file learndhall.dhall
+
+ {- Comments can be nested -}
+-}
+
+let greeting = "Hello, world!"
+
+let fruits = "🍋🍓🍍🍉🍌"
+
+let interpolation = "Enjoy some delicious fruit: ${fruits}"
+
+let multilineText {- Inline comments work, too -} =
+ ''
+ Leading whitespace is stripped from multi-line text literals.
+
+ That means you can freely indent or dedent a text literal without
+ changing the result.
+
+ Relative indentation within the literal is still preserved.
+
+ Other than that, the text literal is preserved verbatim, similar to a
+ "literal" YAML multiline string.
+ ''
+
+let bool = True
+
+-- Type annotations on bindings are optional, but helpful, so we'll use them
+let annotation : Bool = True
+
+let renderedBool : Text = if bool then "True" else "False"
+
+-- Natural numbers are non-negative and are unsigned
+let naturalNumber : Natural = 42
+
+-- Integers may be negative, but require an explicit sign, even if positive
+let positiveInteger : Integer = +1
+
+let negativeInteger : Integer = -12
+
+let pi : Double = 3.14159265359
+
+{- You can use a wider character range for identifiers (such as quotation
+ marks and whitespace) if you quote them using backticks
+-}
+let `Avogadro's Number` : Double = 6.0221409e+23
+
+let origin : { x : Double, y : Double } = { x = 0.0, y = 0.0 }
+
+let somePrimes : List Natural = [ 2, 3, 5, 7, 11 ]
+
+{- A schema is the same thing as a type
+
+ Types begin with an uppercase letter by convention, but this convention is
+ not enforced
+-}
+let Profile : Type
+ = { person :
+ { name : Text
+ , age : Natural
+ }
+ , address :
+ { country : Text
+ , state : Text
+ , city : Text
+ }
+ }
+
+let john : Profile =
+ { person =
+ { name = "John Doe"
+ , age = 67
+ }
+ , address =
+ { country = "United States"
+ , state = "Pennsylvania"
+ , city = "Philadelphia"
+ }
+ }
+
+let philadelphia : Text = john.address.city
+
+{- Enum alternatives also begin with an uppercase letter by convention. This
+ convention is not enforced
+-}
+let DNA : Type = < Adenine | Cytosine | Guanine | Thymine >
+
+let dnaSequence : List DNA = [ DNA.Thymine, DNA.Guanine, DNA.Guanine ]
+
+let compactDNASequence : List DNA =
+ let a = DNA.Adenine
+ let c = DNA.Cytosine
+ let g = DNA.Guanine
+ let t = DNA.Thymine
+ in [ c, t, t, a, t, c, g, g, c ]
+
+-- You can transform enums by providing a record with one field per alternative
+let theLetterG : Text =
+ merge
+ { Adenine = "A"
+ , Cytosine = "C"
+ , Guanine = "G"
+ , Thymine = "T"
+ }
+ DNA.Guanine
+
+let presentOptionalValue : Optional Natural = Some 1
+
+let absentOptionalValue : Optional Natural = None Natural
+
+let points : List { x : Double, y : Double } =
+ [ { x = 1.1, y = -4.2 }
+ , { x = 4.4, y = -3.0 }
+ , { x = 8.2, y = -5.5 }
+ ]
+
+{- `Natural -> List Natural` is the type of a function whose input type is a
+ `Natural` and whose output type is a `List Natural`
+
+ All functions in Dhall are anonymous functions (a.k.a. "lambdas"),
+ which you can optionally give a name
+
+ For example, the following function is equivalent to this Python code:
+
+ lambda n : [ n, n + 1 ]
+
+ ... and this JavaScript code:
+
+ function (n) { return [ n, n + 1 ]; }
+-}
+let exampleFunction : Natural -> List Natural =
+ \(n : Natural) -> [ n, n + 1 ]
+
+-- Dhall also supports Unicode syntax, but this tutorial will stick to ASCII
+let unicodeFunction : Natural → List Natural =
+ λ(n : Natural) → [ n, n + 1 ]
+
+-- You don't need to parenthesize function arguments
+let exampleFunctionApplication : List Natural =
+ exampleFunction 2
+
+let functionOfMultipleArguments : Natural -> Natural -> List Natural =
+ \(x : Natural) -> \(y : Natural) -> [ x, y ]
+
+let functionAppliedToMultipleArguments : List Natural =
+ functionOfMultipleArguments 2 3
+
+{- Same as `exampleFunction` except we gave the function's input type a
+ name: "n"
+-}
+let namedArgumentType : forall (n : Natural) -> List Natural =
+ \(n : Natural) -> [ n, n + 1 ]
+
+{- If you name a function's input type, you can use that name later within the
+ same type
+
+ This lets you write a function that works for more than one type of input
+ (a.k.a. a "polymorphic" function)
+-}
+let duplicate : forall (a : Type) -> a -> List a =
+ \(a : Type) -> \(x : a) -> [ x, x ]
+
+let duplicatedNumber : List Natural =
+ duplicate Natural 2
+
+let duplicatedBool : List Bool =
+ duplicate Bool False
+
+{- The language also has some built-in polymorphic functions, such as:
+
+ List/head : forall (a : Type) -> List a -> Optional a
+-}
+let firstPrime : Optional Natural = List/head Natural somePrimes
+
+let functionOfARecord : { x : Natural, y : Natural } -> List Natural =
+ \(args : { x : Natural, y : Natural }) -> [ args.x, args.y ]
+
+let functionAppliedToARecord : List Natural =
+ functionOfARecord { x = 2, y = 5 }
+
+{- All type conversions are explicit
+
+ `Natural/show` is a built-in function of the following type:
+
+ Natural/show : Natural -> Text
+
+ ... that converts `Natural` numbers to their `Text` representation
+-}
+let typeConversion : Natural -> Text =
+ \(age : Natural) -> "I am ${Natural/show age} years old!"
+
+-- A "template" is the same thing as a function whose output type is `Text`
+let mitLicense : { year : Natural, copyrightHolder : Text } -> Text =
+ \(args : { year : Natural, copyrightHolder : Text }) ->
+''
+Copyright ${Natural/show args.year} ${args.copyrightHolder}
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+''
+
+-- Template instantiation is the same thing as function application
+let templatedLicense : Text =
+ mitLicense { year = 2019, copyrightHolder = "Jane Smith" }
+
+{- You can import expressions by URL
+
+ Also, like Bash, you can import code from your local filesystem (not shown)
+
+ Security-conscious users can pin remotely-imported expressions by adding a
+ semantic integrity check. The interpreter rejects any attempt to tamper with
+ an expression pinned in this way. However, behavior-preserving refactors
+ of imported content will not perturb the hash.
+
+ Imported expressions pinned in this way are also locally cached in a
+ content-addressable store (typically underneath `~/.cache/dhall`)
+-}
+let Natural/sum : List Natural -> Natural =
+ https://prelude.dhall-lang.org/Natural/sum
+ sha256:33f7f4c3aff62e5ecf4848f964363133452d420dcde045784518fb59fa970037
+
+let twentyEight : Natural = Natural/sum somePrimes
+
+-- A "package" is the same thing as a (possibly nested) record that you can import
+let Prelude = https://prelude.dhall-lang.org/package.dhall
+
+let false : Bool = Prelude.Bool.not True
+
+-- You can import the raw contents of a file by adding `as Text` to an import
+let sourceCode : Text = https://prelude.dhall-lang.org/Bool/not as Text
+
+-- You can import environment variables, too:
+let presentWorkingDirectory = env:PWD as Text
+
+-- You can provide a fallback expression if an import fails
+let home : Optional Text = Some env:HOME ? None Text
+
+-- Fallback expressions can contain alternative imports of their own
+let possiblyCustomPrelude =
+ env:DHALL_PRELUDE
+ ? https://prelude.dhall-lang.org/package.dhall
+
+{- Tie everything together by auto-generating configurations for 10 build users
+ using the `generate` function:
+
+ Prelude.List.generate
+ : Natural -> forall (a : Type) -> (Natural -> a) -> List a
+-}
+let buildUsers =
+ let makeUser = \(user : Text) ->
+ let home = "/home/${user}"
+ let privateKey = "${home}/.ssh/id_ed25519"
+ let publicKey = "${privateKey}.pub"
+ in { home = home
+ , privateKey = privateKey
+ , publicKey = publicKey
+ }
+
+ let buildUser =
+ \(index : Natural) -> makeUser "build${Natural/show index}"
+
+ let Config =
+ { home : Text
+ , privateKey : Text
+ , publicKey : Text
+ }
+
+ in Prelude.List.generate 10 Config buildUser
+
+-- Present all of the results in a final record
+in { greeting = greeting
+ , fruits = fruits
+ , interpolation = interpolation
+ , multilineText = multilineText
+ , bool = bool
+ , annotation = annotation
+ , renderedBool = renderedBool
+ , naturalNumber = naturalNumber
+ , positiveInteger = positiveInteger
+ , negativeInteger = negativeInteger
+ , pi = pi
+ , `Avogadro's Number` = `Avogadro's Number`
+ , origin = origin
+ , somePrimes = somePrimes
+ , john = john
+ , philadelphia = philadelphia
+ , dnaSequence = dnaSequence
+ , compactDNASequence = compactDNASequence
+ , theLetterG = theLetterG
+ , presentOptionalValue = presentOptionalValue
+ , absentOptionalValue = absentOptionalValue
+ , points = points
+ , exampleFunction = exampleFunction
+ , unicodeFunction = unicodeFunction
+ , exampleFunctionApplication = exampleFunctionApplication
+ , functionOfMultipleArguments = functionOfMultipleArguments
+ , functionAppliedToMultipleArguments = functionAppliedToMultipleArguments
+ , namedArgumentType = namedArgumentType
+ , duplicate = duplicate
+ , duplicatedNumber = duplicatedNumber
+ , duplicatedBool = duplicatedBool
+ , firstPrime = firstPrime
+ , functionOfARecord = functionOfARecord
+ , functionAppliedToARecord = functionAppliedToARecord
+ , typeConversion = typeConversion
+ , mitLicense = mitLicense
+ , templatedLicense = templatedLicense
+ , twentyEight = twentyEight
+ , false = false
+ , sourceCode = sourceCode
+ , presentWorkingDirectory = presentWorkingDirectory
+ , home = home
+ , buildUsers = buildUsers
+ }
+```
+
+To learn more, visit the official website, which also lets you try the
+language live in your browser:
+
+* [https://dhall-lang.org](http://dhall-lang.org/)
diff --git a/directx9.html.markdown b/directx9.html.markdown
new file mode 100644
index 00000000..b51f418d
--- /dev/null
+++ b/directx9.html.markdown
@@ -0,0 +1,827 @@
+---
+category: tool
+tool: DirectX 9
+filename: learndirectx9.cpp
+contributors:
+ - ["Simon Deitermann", "s.f.deitermann@t-online.de"]
+---
+
+**Microsoft DirectX** is a collection of application programming interfaces (APIs) for handling tasks related to
+multimedia, especially game programming and video, on Microsoft platforms. Originally, the names of these APIs
+all began with Direct, such as Direct3D, DirectDraw, DirectMusic, DirectPlay, DirectSound, and so forth. [...]
+Direct3D (the 3D graphics API within DirectX) is widely used in the development of video games for Microsoft
+Windows and the Xbox line of consoles.<sup>[1]</sup>
+
+In this tutorial we will be focusing on DirectX 9, which is not as low-level as it's sucessors, which are aimed at programmers very familiar with how graphics hardware works. It makes a great starting point for learning Direct3D. In this tutorial I will be using the Win32-API for window handling and the DirectX 2010 SDK.
+
+## Window creation
+
+```cpp
+#include <Windows.h>
+
+bool _running{ false };
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+ // Handle incoming message.
+ switch (msg) {
+ // Set running to false if the user tries to close the window.
+ case WM_DESTROY:
+ _running = false;
+ PostQuitMessage(0);
+ break;
+ }
+ // Return the handled event.
+ return DefWindowProc(hWnd, msg, wParam, lParam);
+}
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine, int nCmdShow) {
+ // Set window properties we want to use.
+ WNDCLASSEX wndEx{ };
+ wndEx.cbSize = sizeof(WNDCLASSEX); // structure size
+ wndEx.style = CS_VREDRAW | CS_HREDRAW; // class styles
+ wndEx.lpfnWndProc = WndProc; // window procedure
+ wndEx.cbClsExtra = 0; // extra memory (struct)
+ wndEx.cbWndExtra = 0; // extra memory (window)
+ wndEx.hInstance = hInstance; // module instance
+ wndEx.hIcon = LoadIcon(nullptr, IDI_APPLICATION); // icon
+ wndEx.hCursor = LoadCursor(nullptr, IDC_ARROW); // cursor
+ wndEx.hbrBackground = (HBRUSH) COLOR_WINDOW; // background color
+ wndEx.lpszMenuName = nullptr; // menu name
+ wndEx.lpszClassName = "DirectXClass"; // register class name
+ wndEx.hIconSm = nullptr; // small icon (taskbar)
+ // Register created class for window creation.
+ RegisterClassEx(&wndEx);
+ // Create a new window handle.
+ HWND hWnd{ nullptr };
+ // Create a new window handle using the registered class.
+ hWnd = CreateWindow("DirectXClass", // registered class
+ "directx window", // window title
+ WS_OVERLAPPEDWINDOW, // window style
+ 50, 50, // x, y (position)
+ 1024, 768, // width, height (size)
+ nullptr, // parent window
+ nullptr, // menu
+ hInstance, // module instance
+ nullptr); // struct for infos
+ // Check if a window handle has been created.
+ if (!hWnd)
+ return -1;
+ // Show and update the new window.
+ ShowWindow(hWnd, nCmdShow);
+ UpdateWindow(hWnd);
+ // Start the game loop and send incoming messages to the window procedure.
+ _running = true;
+ MSG msg{ };
+ while (_running) {
+ while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ return 0;
+}
+```
+
+This should create a window, that can the moved, resized and closed.
+
+## Direct3D initialization
+
+```cpp
+// Includes DirectX 9 structures and functions.
+// Remember to link "d3d9.lib" and "d3dx9.lib".
+// For "d3dx9.lib" the DirectX SDK (June 2010) is needed.
+// Don't forget to set your subsystem to Windows.
+#include <d3d9.h>
+#include <d3dx9.h>
+// Includes the ComPtr, a smart pointer automatically releasing COM objects.
+#include <wrl.h>
+using namespace Microsoft::WRL;
+// Next we define some Direct3D9 interface structs we need.
+ComPtr<IDirect3D9> _d3d{ };
+ComPtr<IDirect3DDevice9> _device{ };
+```
+
+With all interfaces declared we can now initialize Direct3D.
+
+```cpp
+bool InitD3D(HWND hWnd) {
+ // Store the size of the window rectangle.
+ RECT clientRect{ };
+ GetClientRect(hWnd, &clientRect);
+ // Initialize Direct3D
+ _d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ // Get the display mode which format will be the window format.
+ D3DDISPLAYMODE displayMode{ };
+ _d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, // use default graphics card
+ &displayMode); // display mode pointer
+ // Next we have to set some presentation parameters.
+ D3DPRESENT_PARAMETERS pp{ };
+ pp.BackBufferWidth = clientRect.right; // width is window width
+ pp.BackBufferHeight = clientRect.bottom; // height is window height
+ pp.BackBufferFormat = displayMode.Format; // use adapter format
+ pp.BackBufferCount = 1; // 1 back buffer (default)
+ pp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard after presentation
+ pp.hDeviceWindow = hWnd; // associated window handle
+ pp.Windowed = true; // display in window mode
+ pp.Flags = 0; // no special flags
+ // Variable to store results of methods to check if everything succeded.
+ HRESULT result{ };
+ result = _d3d->CreateDevice(D3DADAPTER_DEFAULT, // use default graphics card
+ D3DDEVTYPE_HAL, // use hardware acceleration
+ hWnd, // the window handle
+ D3DCREATE_HARDWARE_VERTEXPROCESSING,
+ // vertices are processed by the hardware
+ &pp, // the present parameters
+ &_device); // struct to store the device
+ // Return false if the device creation failed.
+ // It is helpful to set breakpoints at the return line.
+ if (FAILED(result))
+ return false;
+ // Create a viewport which hold information about which region to draw to.
+ D3DVIEWPORT9 viewport{ };
+ viewport.X = 0; // start at top left corner
+ viewport.Y = 0; // ..
+ viewport.Width = clientRect.right; // use the entire window
+ viewport.Height = clientRect.bottom; // ..
+ viewport.MinZ = 0.0f; // minimun view distance
+ viewport.MaxZ = 100.0f; // maximum view distance
+ // Apply the created viewport.
+ result = _device->SetViewport(&viewport);
+ // Always check if something failed.
+ if (FAILED(result))
+ return false;
+ // Everything was successful, return true.
+ return true;
+}
+// ...
+// Back in our WinMain function we call our initialization function.
+// ...
+// Check if Direct3D initialization succeded, else exit the application.
+if (!InitD3D(hWnd))
+ return -1;
+
+MSG msg{ };
+while (_running) {
+ while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ // Clear to render target to a specified color.
+ _device->Clear(0, // number of rects to clear
+ nullptr, // indicates to clear the entire window
+ D3DCLEAR_TARGET, // clear all render targets
+ D3DXCOLOR{ 1.0f, 0.0f, 0.0f, 1.0f }, // color (red)
+ 0.0f, // depth buffer clear value
+ 0); // stencil buffer clear value
+ // ...
+ // Drawing operations go here.
+ // ...
+ // Flip the front- and backbuffer.
+ _device->Present(nullptr, // no source rectangle
+ nullptr, // no destination rectangle
+ nullptr, // don't change the current window handle
+ nullptr); // pretty much always nullptr
+}
+// ...
+```
+
+Now the window should be displayed in a bright red color.
+
+## Vertex Buffer
+
+Let's create a vertex buffer to store the vertices for our triangle
+
+```cpp
+// At the top of the file we need to add a include.
+#include <vector>
+// First we declare a new ComPtr holding a vertex buffer.
+ComPtr<IDirect3DVertexBuffer9> _vertexBuffer{ };
+// Lets define a funtion to calculate the byte size of a std::vector
+template <typename T>
+unsigned int GetByteSize(const std::vector<T>& vec) {
+ return sizeof(vec[0]) * vec.size();
+}
+// Define "flexible vertex format" describing the content of our vertex struct.
+// Use the defined color as diffuse color.
+const unsigned long VertexStructFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
+// Define a struct representing the vertex data the buffer will hold.
+struct VStruct {
+ float x, y, z; // store the 3D position
+ D3DCOLOR color; // store a color
+};
+// Declare a new function to create a vertex buffer.
+IDirect3DVertexBuffer9* CreateBuffer(const std::vector<VStruct>& vertices) {
+ // Declare the buffer to be returned.
+ IDirect3DVertexBuffer9* buffer{ };
+ HRESULT result{ };
+ result = _device->CreateVertexBuffer(
+ GetByteSize(vertices), // vector size in bytes
+ 0, // data usage
+ VertexStructFVF, // FVF of the struct
+ D3DPOOL_DEFAULT, // use default pool for the buffer
+ &buffer, // receiving buffer
+ nullptr); // special shared handle
+ // Check if buffer was created successfully.
+ if (FAILED(result))
+ return nullptr;
+ // Create a data pointer for copying the vertex data
+ void* data{ };
+ // Lock the buffer to get a buffer for data storage.
+ result = buffer->Lock(0, // byte offset
+ GetByteSize(vertices), // size to lock
+ &data, // receiving data pointer
+ 0); // special lock flags
+ // Check if buffer was locked successfully.
+ if (FAILED(result))
+ return nullptr;
+ // Copy the vertex data using C standard libraries memcpy.
+ memcpy(data, vertices.data(), GetByteSize(vertices));
+ buffer->Unlock();
+ // Set the FVF Direct3D uses for rendering.
+ _device->SetFVF(VertexStructFVF);
+ // If everything was successful return the filled vertex buffer.
+ return buffer;
+}
+```
+
+In our **WinMain** we can now call the new function after the Direct3D initialization.
+
+```cpp
+// ...
+if (!InitD3D(hWnd))
+ return -1;
+// Define the vertices we need to draw a triangle.
+// Values are declared in a clockwise direction else Direct3D would cull them.
+// If you want to diable culling just call:
+// _device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+std::vector<VStruct> vertices {
+ // Bottom left
+ VStruct{ -1.0f, -1.0f, 1.0f, D3DXCOLOR{ 1.0f, 0.0f, 0.0f, 1.0f } },
+ // Top left
+ VStruct{ -1.0f, 1.0f, 1.0f, D3DXCOLOR{ 0.0f, 1.0f, 0.0f, 1.0f } },
+ // Top right
+ VStruct{ 1.0f, 1.0f, 1.0f, D3DXCOLOR{ 0.0f, 0.0f, 1.0f, 1.0f } }
+};
+// Try to create the vertex buffer else exit the application.
+if (!(_vertexBuffer = CreateBuffer(vertices)))
+ return -1;
+// ...
+```
+
+## Transformations
+
+Before we can use the vertex buffer to draw our primitives, we first need to set up the matrices.
+
+```cpp
+// Lets create a new funtions for the matrix transformations.
+bool SetupTransform() {
+ // Create a view matrix that transforms world space to
+ // view space.
+ D3DXMATRIX view{ };
+ // Use a left-handed coordinate system.
+ D3DXMatrixLookAtLH(
+ &view, // receiving matrix
+ &D3DXVECTOR3{ 0.0f, 0.0f, -20.0f }, // "camera" position
+ &D3DXVECTOR3{ 0.0f, 0.0f, 0.0f }, // position where to look at
+ &D3DXVECTOR3{ 0.0f, 1.0f, 0.0f }); // positive y-axis is up
+ HRESULT result{ };
+ result = _device->SetTransform(D3DTS_VIEW, &view); // apply the view matrix
+ if (FAILED(result))
+ return false;
+ // Create a projection matrix that defines the view frustrum.
+ // It transforms the view space to projection space.
+ D3DXMATRIX projection{ };
+ // Create a perspective projection using a left-handed coordinate system.
+ D3DXMatrixPerspectiveFovLH(
+ &projection, // receiving matrix
+ D3DXToRadian(60.0f), // field of view in radians
+ 1024.0f / 768.0f, // aspect ratio (width / height)
+ 0.0f, // minimum view distance
+ 100.0f); // maximum view distance
+ result = _device->SetTransform(D3DTS_PROJECTION, &projection);
+ if (FAILED(result))
+ return false;
+ // Disable lighting for now so we can see what we want to render.
+ result = _device->SetRenderState(D3DRS_LIGHTING, false);
+ // View and projection matrix are successfully applied, return true.
+ return true;
+}
+// ...
+// Back in the WinMain function we can now call the transformation function.
+// ...
+if (!(_vertexBuffer = CreateVertexBuffer(vertices)))
+ return -1;
+// Call the transformation setup function.
+if (!SetupTransform())
+ return -1;
+// ...
+```
+
+## Rendering
+
+Now that everything is setup we can start drawing our first 2D triangle in 3D space.
+
+```cpp
+// ...
+if (!SetupTransform())
+ return -1;
+// First we have to bind our vertex buffer to the data stream.
+HRESULT result{ };
+result = _device->SetStreamSource(0, // use the default stream
+ _vertexBuffer.Get(), // pass the vertex buffer
+ 0, // no offset
+ sizeof(VStruct)); // size of vertex struct
+if (FAILED(result))
+ return -1;
+
+// Create a world transformation matrix and set it to an identity matrix.
+D3DXMATRIX world{ };
+D3DXMatrixIdentity(&world);
+// Create a scalation matrix scaling our primitve by 10 in the x,
+// 10 in the y and keeping the z direction.
+D3DXMATRIX scaling{ };
+D3DXMatrixScaling(&scaling, // matrix to scale
+ 10, // x scaling
+ 10, // y scaling
+ 1); // z scaling
+// Create a rotation matrix storing the current rotation of our primitive.
+// We set the current rotation matrix to an identity matrix for now.
+D3DXMATRIX rotation{ };
+D3DXMatrixIdentity(&rotation);
+// Now we multiply the scalation and rotation matrix and store the result
+// in the world matrix.
+D3DXMatrixMultiply(&world, // destination matrix
+ &scaling, // matrix 1
+ &rotation); // matrix 2
+// Apply the current world matrix.
+_device->SetTransform(D3DTS_WORLD, &world);
+// Disable culling so we can see the back of our primitive when it rotates.
+_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+// The default cullmode is D3DCULL_CW.
+// After we used our the rotation matrix for multiplication we can set it
+// to rotate a small amount.
+// D3DXToRadian() function converts degree to radians.
+D3DXMatrixRotationY(&rotation, // matrix to rotate
+ D3DXToRadian(0.5f)); // rotation angle in radians
+
+MSG msg{ };
+ while (_running) {
+ // ...
+ _device->Clear(0, nullptr, D3DCLEAR_TARGET,
+ D3DXCOLOR{ 0.0f, 0.0f, 0.0f, 1.0f }, 0.0f, 0);
+ // With everything setup we can call the draw function.
+ _device->BeginScene();
+ _device->DrawPrimitive(D3DPT_TRIANGLELIST, // primitive type
+ 0, // start vertex
+ 1); // primitive count
+ _device->EndScene();
+
+ _device->Present(nullptr, nullptr, nullptr, nullptr);
+ // We can keep multiplying the world matrix with our rotation matrix
+ // to add it's rotation to the world matrix.
+ D3DXMatrixMultiply(&world, &world, &rotation);
+ // Update the modified world matrix.
+ _device->SetTransform(D3DTS_WORLD, &world);
+ // ...
+```
+
+You should now be viewing a 10x10 units colored triangle from 20 units away, rotating around its origin.<br>
+You can find the complete working code here: [DirectX - 1](https://pastebin.com/YkSF2rkk)
+
+## Indexing
+
+To make it easier to draw primitives sharing a lot of vertices we can use indexing, so we only have to declare the unique vertices and put the order they are called in another array.
+
+```cpp
+// First we declare a new ComPtr for our index buffer.
+ComPtr<IDirect3DIndexBuffer9> _indexBuffer{ };
+// ...
+// Declare a function creating a index buffer from a std::vector
+IDirect3DIndexBuffer9* CreateIBuffer(std::vector<unsigned int>& indices) {
+ IDirect3DIndexBuffer9* buffer{ };
+ HRESULT result{ };
+ result = _device->CreateIndexBuffer(
+ GetByteSize(indices), // vector size in bytes
+ 0, // data usage
+ D3DFMT_INDEX32, // format is 32 bit int
+ D3DPOOL_DEFAULT, // default pool
+ &buffer, // receiving buffer
+ nullptr); // special shared handle
+ if (FAILED(result))
+ return nullptr;
+ // Create a data pointer pointing to the buffer data.
+ void* data{ };
+ result = buffer->Lock(0, // byte offset
+ GetByteSize(indices), // byte size
+ &data, // receiving data pointer
+ 0); // special lock flag
+ if (FAILED(result))
+ return nullptr;
+ // Copy the index data and unlock after copying.
+ memcpy(data, indices.data(), GetByteSize(indices));
+ buffer->Unlock();
+ // Return the filled index buffer.
+ return buffer;
+}
+// ...
+// In our WinMain we can now change the vertex data and create new index data.
+// ...
+std::vector<VStruct> vertices {
+ VStruct{ -1.0f, -1.0f, 1.0f, D3DXCOLOR{ 1.0f, 0.0f, 0.0f, 1.0f } },
+ VStruct{ -1.0f, 1.0f, 1.0f, D3DXCOLOR{ 0.0f, 1.0f, 0.0f, 1.0f } },
+ VStruct{ 1.0f, 1.0f, 1.0f, D3DXCOLOR{ 0.0f, 0.0f, 1.0f, 1.0f } },
+ // Add a vertex for the bottom right.
+ VStruct{ 1.0f, -1.0f, 1.0f, D3DXCOLOR{ 1.0f, 1.0f, 0.0f, 1.0f } }
+};
+// Declare the index data, here we build a rectangle from two triangles.
+std::vector<unsigned int> indices {
+ 0, 1, 2, // the first triangle (b,left -> t,left -> t,right)
+ 0, 2, 3 // the second triangle (b,left -> t,right -> b,right)
+};
+// ...
+// Now we call the "CreateIBuffer" function to create a index buffer.
+// ...
+if (!(_indexBuffer = CreateIBuffer(indices)))
+ return -1;
+// ...
+// After binding the vertex buffer we have to bind the index buffer to
+// use indexed rendering.
+result = _device->SetStreamSource(0, _vertexBuffer.Get(), 0, sizeof(VStruct));
+if (FAILED(result))
+ return -1;
+// Bind the index data to the default data stream.
+result = _device->SetIndices(_indexBuffer.Get())
+if (FAILED(result))
+ return -1;
+// ...
+// Now we replace the "DrawPrimitive" function with an indexed version.
+_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, // primitive type
+ 0, // base vertex index
+ 0, // minimum index
+ indices.size(), // amount of vertices
+ 0, // start in index buffer
+ 2); // primitive count
+// ...
+```
+
+Now you should see a colored rectangle made up of 2 triangles. If you set the primitive count in the "DrawIndexedPrimitive" method to 1 only the first triangle should be rendered and if you set the start of the index buffer to 3 and the primitive count to 1 only the second triangle should be rendered.<br>
+You can find the complete working code here: [DirectX - 2](https://pastebin.com/yWBPWPRG)
+
+## Vertex declaration
+
+Instead of using the old "flexible vertex format" we should use vertex declarations instead, as the FVF declarations get converted to vertex declarations internally anyway.
+
+```cpp
+// First we have to REMOVE the following lines:
+const unsigned long VertexStructFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
+// and
+_device->SetFVF(VertexStructFVF);
+// ...
+// We also have to change the vertex buffer creation FVF-flag.
+result = _device->CreateVertexBuffer(
+ GetByteSize(vertices),
+ 0,
+ 0, // <- 0 indicates we use vertex declarations
+ D3DPOOL_DEFAULT,
+ &buffer,
+ nullptr);
+// Next we have to declare a new ComPtr.
+ComPtr<IDirect3DVertexDeclaration9> _vertexDecl{ };
+// ...
+result = _device->SetIndices(_indexBuffer.Get());
+if (FAILED(result))
+ return -1;
+// Now we have to declare and apply the vertex declaration.
+// Create a vector of vertex elements making up the vertex declaration.
+std::vector<D3DVERTEXELEMENT9> vertexDeclDesc {
+ { 0, // stream index
+ 0, // byte offset from the struct beginning
+ D3DDECLTYPE_FLOAT3, // data type (3d float vector)
+ D3DDECLMETHOD_DEFAULT, // tessellator operation
+ D3DDECLUSAGE_POSTION, // usage of the data
+ 0 }, // index (multiples usage of the same type)
+ { 0,
+ 12, // byte offset (3 * sizeof(float) bytes)
+ D3DDECLTYPE_D3DCOLOR,
+ D3DDECLMETHOD_DEFAULT,
+ D3DDECLUSAGE_COLOR,
+ 0 },
+ D3DDECL_END() // marks the end of the vertex declaration
+};
+// After having defined the vector we can create a vertex declaration from it.
+result = _device->CreateVertexDeclaration(
+ vertexDeclDesc.data(), // the vertex element array
+ &_vertexDecl); // receiving pointer
+if (FAILED(result))
+ return -1;
+// Apply the created vertex declaration.
+_device->SetVertexDeclaration(_vertexDecl.Get());
+// ...
+```
+
+## Shader
+
+The maximum shader model for Direct3D 9 is shader model 3.0. Even though every modern graphics card should support it, it is best to check for capabilities.
+
+```cpp
+// ...
+_device->SetVertexDeclaration(_vertexDecl.Get());
+// First we have to request the device capabilities.
+D3DCAPS9 deviceCaps{ };
+_device->GetDeviceCaps(&deviceCaps);
+// Now we check if shader model 3.0 is supported for the vertex shader.
+if (deviceCaps.VertexShaderVersion < D3DVS_VERSION(3, 0))
+ return -1;
+// And the same for the pixel shader.
+if (deviceCaps.PixelShaderVersion < D3DPS_VERSION(3, 0))
+ return -1;
+```
+
+Now that we are sure shader model 3.0 is supported let's create the vertex and pixel shader files.
+DirectX 9 introduced the HLSL (**High Level Shading Language**), a C-like shader language, which
+simplified the shader programming a lot, as you could only write shaders in shader assembly in DirectX 8.
+Let's create a simple vertex- and pixel shader.
+
+**Vertex Shader**
+
+```cpp
+// 3 4x4 float matrices representing the matrices we set in the fixed-function
+// pipeline by using the SetTransform() method.
+float4x4 projectionMatrix;
+float4x4 viewMatrix;
+float4x4 worldMatrix;
+// The input struct to the vertex shader.
+// It holds a 3d float vector for the position and a 4d float vector
+// for the color.
+struct VS_INPUT {
+ float3 position : POSITION;
+ float4 color : COLOR;
+};
+// The output struct of the vertex shader, that is passed to the pixel shader.
+struct VS_OUTPUT {
+ float4 position : POSITION;
+ float4 color : COLOR;
+};
+// The main function of the vertex shader returns the output it sends to the
+// pixel shader and receives it's input as a parameter.
+VS_OUTPUT main(VS_INPUT input) {
+ // Declare a empty struct, that the vertex shader returns.
+ VS_OUTPUT output;
+ // Set the output position to the input position and set
+ // the w-component to 1, as the input position is a 3d vector and
+ // the output position a 4d vector.
+ output.position = float4(input.position, 1.0f);
+ // Multiply the output position step by step with the world, view and
+ // projection matrices.
+ output.position = mul(output.position, worldMatrix);
+ output.position = mul(output.position, viewMatrix);
+ output.position = mul(output.position, projectionMatrix);
+ // Pass the input color unchanged to the pixel shader.
+ output.color = input.color;
+ // Return the output struct to the pixel shader.
+ // The position value is automatically used as the vertex position.
+ return output;
+}
+```
+
+**Pixel Shader**
+
+```cpp
+// The pixel shader input struct must be the same as the vertex shader output!
+struct PS_INPUT {
+ float4 position : POSITION;
+ float4 color : COLOR;
+};
+// The pixel shader simply returns a 4d vector representing the vertex color.
+// It receives it's input as a parameter just like the vertex shader.
+// We have to declare the output semantic as color to it gets interpreted
+// correctly.
+float4 main(PS_INPUT input) : COLOR {
+ return input.color;
+}
+```
+
+For more on semantics: [DirectX - Semantics](https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics#vertex-shader-semantics)
+
+Now we have to do quite some changes to the code.
+
+```cpp
+ComPtr<IDirect3DDevice9> _device{ };
+ComPtr<IDirect3DVertexBuffer9> _vertexBuffer{ };
+ComPtr<IDirect3DIndexBuffer9> _indexBuffer{ };
+ComPtr<IDirect3DVertexDeclaration9> _vertexDecl{ };
+// We have to add a ComPtr for the vertex- and pixel shader, aswell as one
+// for the constants (matrices) in our vertex shader.
+ComPtr<IDirect3DVertexShader9> _vertexShader{ };
+ComPtr<IDirect3DPixelShader9> _pixelShader{ };
+ComPtr<ID3DXConstantTable> _vertexTable{ };
+// Declare the world and rotation matrix as global, because we use them in
+// WinMain and SetupTransform now.
+D3DXMATRIX _worldMatrix{ };
+D3DXMATRIX _rotationMatrix{ };
+// ...
+bool SetupTransform() {
+ // Set the world and rotation matrix to an identity matrix.
+ D3DXMatrixIdentity(&_worldMatrix);
+ D3DXMatrixIdentity(&_rotationMatrix);
+
+ D3DXMATRIX scaling{ };
+ D3DXMatrixScaling(&scaling, 10, 10, 1);
+ D3DXMatrixMultiply(&_worldMatrix, &scaling, &_rotationMatrix);
+ // After multiplying the scalation and rotation matrix the have to pass
+ // them to the shader, by using a method from the constant table
+ // of the vertex shader.
+ HRESULT result{ };
+ result = _vertexTable->SetMatrix(
+ _device.Get(), // direct3d device
+ "worldMatrix", // matrix name in the shader
+ &_worldMatrix); // pointer to the matrix
+ if (FAILED(result))
+ return false;
+
+ D3DXMATRIX view{ };
+ D3DXMatrixLookAtLH(&view, &D3DXVECTOR3{ 0.0f, 0.0f, -20.0f },
+ &D3DXVECTOR3{ 0.0f, 0.0f, 0.0f }, &D3DXVECTOR3{ 0.0f, 1.0f, 0.0f });
+ // Do the same for the view matrix.
+ result = _vertexTable->SetMatrix(
+ _device.Get(), // direct 3d device
+ "viewMatrix", // matrix name
+ &view); // matrix
+ if (FAILED(result))
+ return false;
+
+ D3DXMATRIX projection{ };
+ D3DXMatrixPerspectiveFovLH(&projection, D3DXToRadian(60.0f),
+ 1024.0f / 768.0f, 0.0f, 100.0f);
+ // And also for the projection matrix.
+ result = _vertexTable->SetMatrix(
+ _device.Get(),
+ "projectionMatrix",
+ &projection);
+ if (FAILED(result))
+ return false;
+
+ D3DXMatrixRotationY(&_rotationMatrix, D3DXToRadian(0.5f));
+ return true;
+}
+// ...
+// Vertex and index buffer creation aswell as initialization stay unchanged.
+// ...
+// After checking that shader model 3.0 is available we have to compile and
+// create the shaders.
+// Declare two temporary buffers storing the compiled shader code.
+ID3DXBuffer* vertexShaderBuffer{ };
+ID3DXBuffer* pixelShaderBuffer{ };
+result = D3DXCompileShaderFromFile("vertex.hlsl", // shader name
+ nullptr, // macro definitions
+ nullptr, // special includes
+ "main", // entry point name
+ "vs_3_0", // shader model version
+ 0, // special flags
+ &vertexShaderBuffer, // code buffer
+ nullptr, // error message
+ &_vertexTable); // constant table
+if (FAILED(result))
+ return -1;
+// After the vertex shader compile the pixel shader.
+result = D3DXCompileShaderFromFile("pixel.hlsl",
+ nullptr,
+ nullptr,
+ "main",
+ "ps_3_0", // pixel shader model 3.0
+ 0,
+ &pixelShaderBuffer,
+ nullptr,
+ nullptr); // no need for a constant table
+if (FAILED(result))
+ return -1;
+// Create the vertex shader from the code buffer.
+result = _device->CreateVertexShader(
+ (DWORD*)vertexShaderBuffer->GetBufferPointer(), // code buffer
+ &_vertexShader); // vertex shader pointer
+if (FAILED(result))
+ return -1;
+
+result = _device->CreatePixelShader(
+ (DWORD*)pixelShaderBuffer->GetBufferPointer(),
+ &_pixelShader);
+if (FAILED(result))
+ return -1;
+// Release the temporary code buffers after the shaders are created.
+vertexShaderBuffer->Release();
+pixelShaderBuffer->Release();
+// Apply the vertex- and pixel shader.
+_device->SetVertexShader(_vertexShader.Get());
+_device->SetPixelShader(_pixelShader.Get());
+// Apply the transform after the shaders have been set.
+if (!SetupTransform())
+ return -1;
+// You can also REMOVE the call so set the lighting render state.
+_device->SetRenderState(D3DRS_LIGHTING, false);
+```
+
+You can find the complete code here: [DirectX - 3](https://pastebin.com/y4NrvawY)
+
+## Texturing
+
+```cpp
+// First we need to declare a ComPtr for the texture.
+ComPtr<IDirect3DTexture9> _texture{ };
+// Then we have to change the vertex struct.
+struct VStruct {
+ float x, y, z;
+ float u, v; // Add texture u and v coordinates
+ D3DCOLOR color;
+};
+// In the vertex declaration we have to add the texture coordinates.
+// the top left of the texture is u: 0, v: 0.
+std::vector<VStruct> vertices {
+ VStruct{ -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, ... }, // bottom left
+ VStruct{ -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, ... }, // top left
+ VStruct{ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, ... }, // top right
+ VStruct{ 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, ... } // bottom right
+};
+// Next is the vertex declaration.
+std::vector<D3DVERTEXELEMENT9> vertexDecl{
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ // Add a 2d float vector used for texture coordinates.
+ {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ // The color offset is not (3 + 2) * sizeof(float) = 20 bytes
+ {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END()
+};
+// Now we have to load the texture and pass its to the shader.
+// ...
+_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+// Create a Direct3D texture from a png file.
+result = D3DXCreateTextureFromFile(_device.Get(), // direct3d device
+ "texture.png", // texture path
+ &_texture); // receiving texture pointer
+if (FAILED(result))
+ return -1;
+// Attach the texture to shader stage 0, which is equal to texture register 0
+// in the pixel shader.
+_device->SetTexture(0, _texture.Get());
+```
+
+With the main code ready we now have to adjust the shaders to these changes.
+
+**Vertex Shader**
+
+```cpp
+float4x4 projectionMatrix;
+float4x4 viewMatrix;
+float4x4 worldMatrix;
+// Add the texture coordinates to the vertex shader in- and output.
+struct VS_INPUT {
+ float3 position : POSITION;
+ float2 texcoord : TEXCOORD;
+ float4 color : COLOR;
+};
+
+struct VS_OUTPUT {
+ float4 position : POSITION;
+ float2 texcoord : TEXCOORD;
+ float4 color : COLOR;
+};
+
+VS_OUTPUT main(VS_INPUT input) {
+ VS_OUTPUT output;
+
+ output.position = float4(input.position, 1.0f);
+ output.position = mul(output.position, worldMatrix);
+ output.position = mul(output.position, viewMatrix);
+ output.position = mul(output.position, projectionMatrix);
+
+ output.color = input.color;
+ // Set the texcoord output to the input.
+ output.texcoord = input.texcoord;
+
+ return output;
+}
+```
+
+**Pixel Shader**
+
+```cpp
+// Create a sampler called "sam0" using sampler register 0, which is equal
+// to the texture stage 0, to which we passed the texture.
+sampler sam0 : register(s0);
+
+struct PS_INPUT {
+ float4 position : POSITION;
+ float2 texcoord : TEXCOORD;
+ float4 color : COLOR;
+};
+
+float4 main(PS_INPUT input) : COLOR{
+ // Do a linear interpolation between the texture color and the input color
+ // using 75% of the input color.
+ // tex2D returns the texture data at the specified texture coordinate.
+ return lerp(tex2D(sam0, input.texcoord), input.color, 0.75f);
+}
+```
+
+## Quotes
+<sup>[1]</sup>[DirectX - Wikipedia](https://en.wikipedia.org/wiki/DirectX)
diff --git a/docker.html.markdown b/docker.html.markdown
new file mode 100644
index 00000000..24f85247
--- /dev/null
+++ b/docker.html.markdown
@@ -0,0 +1,146 @@
+---
+language: docker
+filename: docker.bat
+contributors:
+ - ["Ruslan López", "http://javapro.org/"]
+---
+
+```
+:: download, install and run hello-world image
+docker run hello-world
+
+:: if this is the first time you should be able to see the message
+:: Unable to find image 'hello-world:latest' locally
+:: latest: Pulling from library/hello-world
+:: 1b930d010525: Pull complete
+:: Digest: sha256:4fe721ccc2e8dc7362278a29dc660d833570ec2682f4e4194f4ee23e415e1064
+:: Status: Downloaded newer image for hello-world:latest
+::
+:: Hello from Docker!
+:: This message shows that your installation appears to be working correctly.
+::
+:: To generate this message, Docker took the following steps:
+:: 1. The Docker client contacted the Docker daemon.
+:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
+:: (amd64)
+:: 3. The Docker daemon created a new container from that image which runs the
+:: executable that produces the output you are currently reading.
+:: 4. The Docker daemon streamed that output to the Docker client, which sent it
+:: to your terminal.
+::
+:: To try something more ambitious, you can run an Ubuntu container with:
+:: $ docker run -it ubuntu bash
+::
+:: Share images, automate workflows, and more with a free Docker ID:
+:: https://hub.docker.com/
+::
+:: For more examples and ideas, visit:
+:: https://docs.docker.com/get-started/
+
+:: now lets see currently running images
+docker ps
+:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
+:: NAMES
+
+:: lets see the images we have ran previously
+docker ps -a
+
+:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
+:: NAMES
+:: 4a76281f9c53 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago
+:: happy_poincare
+:: the name part is generated automatically so it probably will be different for you
+
+:: let's remove our previously generated image
+docker rm happy_poincare
+
+:: lets test if it was really deleted
+docker ps -a
+:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
+:: NAMES
+
+:: specify a custom name for the container
+docker run --name test_container hello-world
+:: Hello from Docker!
+:: This message shows that your installation appears to be working correctly.
+::
+:: To generate this message, Docker took the following steps:
+:: 1. The Docker client contacted the Docker daemon.
+:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
+:: (amd64)
+:: 3. The Docker daemon created a new container from that image which runs the
+:: executable that produces the output you are currently reading.
+:: 4. The Docker daemon streamed that output to the Docker client, which sent it
+:: to your terminal.
+::
+:: To try something more ambitious, you can run an Ubuntu container with:
+:: $ docker run -it ubuntu bash
+::
+:: Share images, automate workflows, and more with a free Docker ID:
+:: https://hub.docker.com/
+::
+:: For more examples and ideas, visit:
+:: https://docs.docker.com/get-started/
+
+docker ps -a
+:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
+:: NAMES
+:: d345fe1a4f41 hello-world "/hello" About a minute ago Exited (0) About a minute ago
+:: test_container
+:: as you can see the name is now what we have specified
+
+:: retireve logs from a named container
+docker logs test_container
+:: Hello from Docker!
+:: This message shows that your installation appears to be working correctly.
+::
+:: To generate this message, Docker took the following steps:
+:: 1. The Docker client contacted the Docker daemon.
+:: 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
+:: (amd64)
+:: 3. The Docker daemon created a new container from that image which runs the
+:: executable that produces the output you are currently reading.
+:: 4. The Docker daemon streamed that output to the Docker client, which sent it
+:: to your terminal.
+::
+:: To try something more ambitious, you can run an Ubuntu container with:
+:: $ docker run -it ubuntu bash
+::
+:: Share images, automate workflows, and more with a free Docker ID:
+:: https://hub.docker.com/
+::
+:: For more examples and ideas, visit:
+:: https://docs.docker.com/get-started/
+
+docker rm test_container
+
+docker run ubuntu
+:: Unable to find image 'ubuntu:latest' locally
+:: latest: Pulling from library/ubuntu
+:: 2746a4a261c9: Pull complete
+:: 4c1d20cdee96: Pull complete 0d3160e1d0de: Pull complete c8e37668deea: Pull complete Digest: sha256:250cc6f3f3ffc5cdaa9d8f4946ac79821aafb4d3afc93928f0de9336eba21aa4
+:: Status: Downloaded newer image for ubuntu:latest
+
+docker ps -a
+:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
+:: NAMES
+:: c19e9e5b000a ubuntu "/bin/bash" 5 seconds ago Exited (0) 4 seconds ago
+:: relaxed_nobel
+
+:: running a container in an interactive mode
+docker run -it ubuntu
+:: root@e2cac48323d2:/# uname
+:: Linux
+:: root@e2cac48323d2:/# exit
+:: exit
+
+docker rm relaxed_nobel
+
+docker ps -a
+:: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
+:: NAMES
+:: e2cac48323d2 ubuntu "/bin/bash" 2 minutes ago Exited (0) About a minute ago
+:: nifty_goldwasser
+
+docker rm nifty_goldwasser
+``` \ No newline at end of file
diff --git a/dynamic-programming.html.markdown b/dynamic-programming.html.markdown
index 94be22e9..3e3c0413 100644
--- a/dynamic-programming.html.markdown
+++ b/dynamic-programming.html.markdown
@@ -3,13 +3,14 @@ category: Algorithms & Data Structures
name: Dynamic Programming
contributors:
- ["Akashdeep Goel", "http://github.com/akashdeepgoel"]
+ - ["Miltiadis Stouras", "https://github.com/mstou"]
---
# Dynamic Programming
## 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"
@@ -22,11 +23,11 @@ Always remember!
## Example of Dynamic Programming
-The Longest Increasing Subsequence problem is to find the longest increasing subsequence of a given sequence. Given a sequence `S= {a1 , a2 , a3, a4, ............., an-1, an }` we have to find a longest subset such that for all `j` and `i`, `j<i` in the subset `aj<ai`.
+The Longest Increasing Subsequence problem is to find the longest increasing subsequence of a given sequence. Given a sequence `S={ a1, a2, a3, a4, ............., an-1, an }` we have to find a longest subset such that for all `j` and `i`, `j<i` in the subset `aj<ai`.
First of all we have to find the value of the longest subsequences(LSi) at every index i with last element of sequence being ai. Then largest LSi would be the longest subsequence in the given sequence. To begin LSi is assigned to be one since ai is element of the sequence(Last element). Then for all `j` such that `j<i` and `aj<ai`, we find Largest LSj and add it to LSi. Then algorithm take *O(n2)* time.
Pseudo-code for finding the length of the longest increasing subsequence:
-This algorithms complexity could be reduced by using better data structure rather than array. Storing predecessor array and variable like largest_sequences_so_far and its index would save a lot time.
+This algorithms complexity could be reduced by using better data structure rather than array. Storing predecessor array and variable like `largest_sequences_so_far` and its index would save a lot time.
Similar concept could be applied in finding longest path in Directed acyclic graph.
@@ -42,10 +43,21 @@ for i=0 to n-1
### Some Famous DP Problems
-- Floyd Warshall Algorithm - Tutorial and C Program source code:http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code
-- Integer Knapsack Problem - Tutorial and C Program source code: http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem
-- Longest Common Subsequence - Tutorial and C Program source code : http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence
+- [Floyd Warshall Algorithm - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code)
+- [Integer Knapsack Problem - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem)
+- [Longest Common Subsequence - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence)
## Online Resources
-* [codechef](https://www.codechef.com/wiki/tutorial-dynamic-programming)
+* MIT 6.006: [Lessons 19,20,21,22](https://www.youtube.com/playlist?list=PLUl4u3cNGP61Oq3tWYp6V_F-5jb5L2iHb)
+* TopCoder: [Dynamic Programming from Novice to Advanced](https://www.topcoder.com/community/data-science/data-science-tutorials/dynamic-programming-from-novice-to-advanced/)
+* [CodeChef](https://www.codechef.com/wiki/tutorial-dynamic-programming)
+* [InterviewBit](https://www.interviewbit.com/courses/programming/topics/dynamic-programming/)
+* GeeksForGeeks:
+ * [Overlapping Subproblems](https://www.geeksforgeeks.org/dynamic-programming-set-1/)
+ * [Tabulation vs Memoization](https://www.geeksforgeeks.org/tabulation-vs-memoizatation/)
+ * [Optimal Substructure Property](https://www.geeksforgeeks.org/dynamic-programming-set-2-optimal-substructure-property/)
+ * [How to solve a DP problem](https://www.geeksforgeeks.org/solve-dynamic-programming-problem/)
+* [How to write DP solutions](https://www.quora.com/Are-there-any-good-resources-or-tutorials-for-dynamic-programming-DP-besides-the-TopCoder-tutorial/answer/Michal-Danilák)
+
+And a [quiz](https://www.commonlounge.com/discussion/cdbbfe83bcd64281964b788969247253) to test your knowledge.
diff --git a/edn.html.markdown b/edn.html.markdown
index ca04df89..f47853f0 100644
--- a/edn.html.markdown
+++ b/edn.html.markdown
@@ -3,13 +3,16 @@ language: edn
filename: learnedn.edn
contributors:
- ["Jason Yeo", "https://github.com/jsyeo"]
+ - ["Jonathan D Johnston", "https://github.com/jdjohnston"]
---
Extensible Data Notation (EDN) is a format for serializing data.
-The notation is used internally by Clojure to represent programs. It is also
-used as a data transfer format like JSON. Though it is more commonly used in
-Clojure, there are implementations of EDN for many other languages.
+EDN is a subset of the syntax used by Clojure. Reading data defined by EDN is
+safer than that defined by the full Clojure syntax, especially from untrusted
+sources. EDN is restricted to data, no code. It is similar in intent to JSON.
+Though it is more commonly used in Clojure, there are implementations of EDN
+for many other languages.
The main benefit of EDN over JSON and YAML is that it is extensible. We
will see how it is extended later on.
@@ -32,7 +35,7 @@ false
"hungarian breakfast"
"farmer's cheesy omelette"
-; Characters are preceeded by backslashes
+; Characters are preceded by backslashes
\g \r \a \c \e
; Keywords start with a colon. They behave like enums. Kind of
@@ -41,13 +44,13 @@ false
:cheese
:olives
-; Symbols are used to represent identifiers. They start with #.
-; You can namespace symbols by using /. Whatever preceeds / is
-; the namespace of the name.
-#spoon
-#kitchen/spoon ; not the same as #spoon
-#kitchen/fork
-#github/fork ; you can't eat with this
+; Symbols are used to represent identifiers.
+; You can namespace symbols by using /. Whatever precedes / is
+; the namespace of the symbol.
+spoon
+kitchen/spoon ; not the same as spoon
+kitchen/fork
+github/fork ; you can't eat with this
; Integers and floats
42
@@ -81,22 +84,26 @@ false
#MyYelpClone/MenuItem {:name "eggs-benedict" :rating 10}
-; Let me explain this with a clojure example. Suppose I want to transform that
+; Let me explain this with a Clojure example. Suppose I want to transform that
; piece of EDN into a MenuItem record.
(defrecord MenuItem [name rating])
-; To transform EDN to clojure values, I will need to use the built in EDN
-; reader, edn/read-string
+; defrecord defined, among other things, map->MenuItem which will take a map
+; of field names (as keywords) to values and generate a user.MenuItem record
-(edn/read-string "{:eggs 2 :butter 1 :flour 5}")
+; To transform EDN to Clojure values, I will need to use the built-in EDN
+; reader, clojure.edn/read-string
+
+(clojure.edn/read-string "{:eggs 2 :butter 1 :flour 5}")
; -> {:eggs 2 :butter 1 :flour 5}
-; To transform tagged elements, define the reader function and pass a map
-; that maps tags to reader functions to edn/read-string like so
+; To transform tagged elements, pass to clojure.edn/read-string an option map
+; with a :readers map that maps tag symbols to data-reader functions, like so
-(edn/read-string {:readers {'MyYelpClone/MenuItem map->menu-item}}
- "#MyYelpClone/MenuItem {:name \"eggs-benedict\" :rating 10}")
+(clojure.edn/read-string
+ {:readers {'MyYelpClone/MenuItem map->MenuItem}}
+ "#MyYelpClone/MenuItem {:name \"eggs-benedict\" :rating 10}")
; -> #user.MenuItem{:name "eggs-benedict", :rating 10}
```
diff --git a/el-gr/bash-gr.html.markdown b/el-gr/bash-gr.html.markdown
new file mode 100644
index 00000000..2989969d
--- /dev/null
+++ b/el-gr/bash-gr.html.markdown
@@ -0,0 +1,528 @@
+---
+category: tool
+tool: bash
+contributors:
+ - ["Dimitri Kokkonis", "https://github.com/kokkonisd"]
+filename: LearnBash-gr.sh
+lang: el-gr
+---
+
+Η λέξη «bash» είναι ένα από τα ονόματα του unix shell (τερματικός), το οποίο
+διανέμεται επίσης ως προεπιλεγμένος τερματικός για το λειτουργικό σύστημα GNU, τα Linux και τα Mac OS X.
+Σχεδόν όλα τα παραδείγματα που ακολουθούν μπορούν να αποτελέσουν μέρος ενός
+προγράμματος τερματικού (shell script) ή να εκτελεσθούν απευθείας από τον
+τερματικό.
+
+[Διαβάστε περισσότερα εδώ.](http://www.gnu.org/software/bash/manual/bashref.html)
+
+```bash
+#!/usr/bin/env bash
+# Η πρώτη γραμμή του προγράμματος είναι το shebang που υποδεικνύει στο σύστημα
+# πώς να εκτελέσει το πρόγραμμα: http://en.wikipedia.org/wiki/Shebang_(Unix)
+# Όπως ήδη θα καταλάβατε, τα σχόλια ξεκινούν με τον χαρακτήρα #. Το shebang
+# είναι επίσης ένα σχόλιο.
+# ΣτΜ.: Τα ονόματα των μεταβλητών είναι γραμμένα σε greeklish καθώς η Bash δεν
+# επιτρέπει την χρήση unicode χαρακτήρων.
+
+# Ένα απλό παράδειγμα τύπου «hello world»:
+echo Καλημέρα, Κόσμε! # => Καλημέρα, Κόσμε!
+
+# Κάθε εντολή ξεκινά σε μια νέα γραμμή, ή μετά από ένα ελληνικό ερωτηματικό:
+echo 'Αυτή είναι η πρώτη γραμμή'; echo 'Αυτή είναι η δεύτερη γραμμή'
+# => Αυτή είναι η πρώτη γραμμή
+# => Αυτή είναι η δεύτερη γραμμή
+
+# Ορίζουμε μεταβλητές ως εξής:
+Metavliti="Κάποιο αλφαριθμητικό"
+
+# Αλλά όχι ως εξής:
+Metavliti = "Κάποιο αλφαριθμητικό" # => επιστρέφει το λάθος
+# «Metavliti: command not found»
+# Η Bash θα καταλάβει πως η Metavliti είναι κάποια εντολή που πρέπει να
+# εκτελέσει και θα επιστρέψει ένα λάθος γιατί δεν μπορεί να την βρει.
+
+# Ούτε έτσι μπορούμε να δηλώσουμε μεταβλητές:
+Metavliti= 'Κάποιο αλφαριθμητικό' # => επιστρέφει το λάθος: «Κάποιο
+ # αλφαριθμητικό: command not found»
+# Η Bash θα καταλάβει πως το αλφαριθμητικό «Κάποιο αλφαριθμητικό» είναι μια
+# εντολή που πρέπει να εκτελέσει και θα επιστρέψει ένα λάθος γιατί δεν μπορεί
+# να την βρει. (Σε αυτή την περίπτωση το τμήμα της εντολής «Metavliti=» θα
+# ερμηνευθεί ως ορισμός μεταβλητής ισχύων μόνο στο πλαίσιο της εντολής
+# «Κάποιο αλφαριθμητικό».)
+
+# Ας χρησιμοποιήσουμε την μεταβλητή:
+echo $Metavliti # => Κάποιο αλφαριθμητικό
+echo "$Metavliti" # => Κάποιο αλφαριθμητικό
+echo '$Metavliti' # => $Metavliti
+# Όταν χρησιμοποιούμε την ίδια την μεταβλητή - είτε είναι για να της δώσουμε
+# μια νέα αξία, για να την εξάγουμε ή για οτιδήποτε άλλο - γράφουμε το όνομά
+# της χωρίς τον χαρακτήρα $. Αν θέλουμε να χρησιμοποιήσουμε την αξία της
+# μεταβλητής, πρέπει να χρησιμοποιήσουμε τον χαρατήρα $.
+# Να σημειωθεί πώς ο χαρακτήρας ' δεν θα μετατρέψει τις μεταβλητές στις αξίες
+# τους!
+
+# Επέκταση παραμέτρων ${ }:
+echo ${Metavliti} # => Κάποιο αλφαριθμητικό
+# Αυτή είναι μια απλή χρήση της επέκτασης παραμέτρων.
+# Η επέκταση παραμέτρων εξάγει μια αξία από μια μεταβλητή.
+# Κατά την επέκταση η τιμή ή η παράμετρος μπορεί να τροποποιηθεί.
+# Ακολουθούν άλλες μετατροπές που μπορούν να προστεθούν σε αυτή την επέκταση.
+
+# Αντικατάσταση αλφαριθμητικών μέσα σε μεταβλητές
+echo ${Metavliti/Κάποιο/Ένα} # => Ένα αλφαριθμητικό
+# Αυτή η τροποποίηση θα αντικαταστήσει την πρώτη εμφάνιση της λέξης «Κάποιο»
+# με την λέξη «Ένα».
+
+# Υποαλφαριθμητικό μιας μεταβλητής
+Mikos=7
+echo ${Metavliti:0:Mikos} # => Κάποιο
+# Αυτή η τροποποίηση θα επιστρέψει μόνο τους πρώτους 7 χαρακτήρες της τιμής
+# της μεταβλητής.
+echo ${Metavliti: -5} # => ητικό
+# Αυτή η τροποποίηση θα επιστρέψει τους τελευταίους 5 χαρακτήρες (προσοχή στο
+# κενό πριν το -5).
+
+# Μήκος αλφαριθμητικού
+echo ${#Metavliti} # => 20
+
+# Προεπιλεγμένη αξία για μια μεταβλητή
+echo ${Foo:-"ΠροεπιλεγμένηΑξίαΑνΤοFooΕίναιΑόριστοΉΆδειο"}
+# => ΠροεπιλεγμένηΑξίαΑνΤοFooΕίναιΑόριστοΉΆδειο
+# Αυτό δουλεύει στην περίπτωση που το Foo είναι αόριστο (Foo=) ή άδειο
+# (Foo="")· το μηδέν (Foo=0) επιστρέφει 0.
+# Να σημειωθεί πως αυτή η εντολή απλώς επιστρέφει την προεπιλεγμένη αξία και
+# δεν τροποποιεί την αξία της μεταβλητής.
+
+# Ορισμός ενός πίνακα με 6 στοιχεία
+pinakas0=(ένα δύο τρία τέσσερα πέντε έξι)
+# Εντολή που τυπώνει το πρώτο στοιχείο
+echo $pinakas0 # => "ένα"
+# Εντολή που τυπώνει το πρώτο στοιχείο
+echo ${pinakas0[0]} # => "ένα"
+# Εντολή που τυπώνει όλα τα στοιχεία
+echo ${pinakas0[@]} # => "ένα δύο τρία τέσσερα πέντε έξι"
+# Εντολή που τυπώνει τον αριθμό των στοιχείων
+echo ${#pinakas0[@]} # => "6"
+# Εντολή που τυπώνει τον αριθμό των χαρακτήρων στο τρίτο στοιχείο
+echo ${#pinakas0[2]} # => "4"
+# Εντολή που τυπώνει δύο στοιχεία ξεκινώντας από το τέταρτο
+echo ${pinakas0[@]:3:2} # => "τέσσερα πέντε"
+# Εντολή που τυπώνει όλα τα στοιχεία, το καθένα σε διαφορετική γραμμή
+for i in "${pinakas0[@]}"; do
+ echo "$i"
+done
+
+# Επέκταση αγκίστρων { }
+# Χρησιμοποιείται για την παραγωγή αλφαριθμητικών
+echo {1..10} # => 1 2 3 4 5 6 7 8 9 10
+echo {a..z} # => a b c d e f g h i j k l m n o p q r s t u v w x y z
+# Η εντολή θα τυπώσει όλο το εύρος, από την πρώτη μέχρι την τελευταία αξία
+
+# Ενσωματωμένες μεταβλητές
+# Υπάρχουν κάποιες χρήσιμες ενσωματωμένες μεταβλητές, όπως:
+echo "Η τιμή την οποία επέστρεψε το τελευταίο πρόγραμμα: $?"
+echo "Ο αριθμός PID αυτού του script: $$"
+echo "Ο αριθμός των παραμέτρων που περάστηκαν σε αυτό το script: $#"
+echo "Όλες οι παράμετροι που περάστηκαν σε αυτό το script: $@"
+echo "Οι παράμετροι του script διαχωρισμένες σε μεταβλητές: $1 $2..."
+
+# Τώρα που γνωρίζουμε πως να τυπώνουμε (echo) και να χρησιμοποιούμε μεταβλητές,
+# ας μάθουμε κάποια από τα υπόλοιπα βασικά στοιχεία της Bash!
+
+# Ο τρέχων κατάλογος (ή αλλιώς, φάκελος) μπορεί να βρεθεί μέσω της εντολής
+# `pwd`.
+# `pwd` σημαίνει «print working directory».
+# Μπορούμε επίσης να χρησιμοποιούμε την ενσωματωμένη μεταβλητή `$PWD`.
+# Παρακολουθήστε πως οι δύο εντολές που ακολουθούν είναι ισοδύναμες:
+echo "Είμαι στον κατάλογο $(pwd)" # εκτελεί την εντολή `pwd` και τυπώνει το
+ # αποτέλεσμα
+echo "Είμαι στον κατάλογο $PWD" # τυπώνει την αξία της μεταβλητής
+
+# Αν έχετε πολλά μηνύματα στον τερματικό, η εντολή `clear` μπορεί να
+# «καθαρίσει» την οθόνη σας
+clear
+# Η συντόμευση Ctrl-L δουλεύει επίσης όσον αφορά το «καθάρισμα»
+
+# Ας διαβάσουμε μια αξία από κάποια είσοδο:
+echo "Πώς σε λένε;"
+read Onoma # Προσέξτε πως δεν χρειάστηκε να ορίσουμε μια νέα μεταβλητή
+echo Καλημέρα, $Onoma!
+
+# Η δομή των if statements έχει ως εξής:
+# (μπορείτε να εκτελέσετε την εντολή `man test` για περισσότερες πληροφορίες
+# σχετικά με τα conditionals)
+if [ $Onoma != $USER ]
+then
+ echo "Το όνομά σου δεν είναι το όνομα χρήστη σου"
+else
+ echo "Το όνομά σου είναι το όνομα χρήστη σου"
+fi
+# Η συνθήκη είναι αληθής αν η τιμή του $Onoma δεν είναι ίδια με το τρέχον
+# όνομα χρήστη στον υπολογιστή
+
+# ΣΗΜΕΙΩΣΗ: Αν το $Onoma είναι άδειο, η Bash βλέπει την συνθήκη ως:
+if [ != $USER ]
+# το οποίο αποτελεί συντακτικό λάθος
+# οπότε ο «ασφαλής» τρόπος να χρησιμοποιούμε εν δυνάμει άδειες μεταβλητές στην
+# Bash είναι ο εξής:
+if [ "$Onoma" != $USER ] ...
+# ο οποίος, όταν το $Onoma είναι άδειο, θα ερμηνευθεί από την Bash ως:
+if [ "" != $USER ] ...
+# το οποίο και δουλεύει όπως θα περιμέναμε.
+
+# Υπάρχει επίσης η εκτέλεση εντολών βάσει συνθηκών
+echo "Εκτελείται πάντα" || echo "Εκτελείται μόνο αν η πρώτη εντολή αποτύχει"
+# => Εκτελείται πάντα
+echo "Εκτελείται πάντα" && echo "Εκτελείται μόνο αν η πρώτη εντολή ΔΕΝ αποτύχει"
+# => Εκτελείται πάντα
+# => Εκτελείται μόνο αν η πρώτη εντολή ΔΕΝ αποτύχει
+
+
+# Για να χρησιμοποιήσουμε τους τελεστές && και || με τα if statements,
+# χρειαζόμαστε πολλαπλά ζευγάρια αγκύλων:
+if [ "$Onoma" == "Σταύρος" ] && [ "$Ilikia" -eq 15 ]
+then
+ echo "Αυτό θα εκτελεστεί αν το όνομα ($Onoma) είναι Σταύρος ΚΑΙ η ηλικία ($Ilikia) είναι 15."
+fi
+
+if [ "$Onoma" == "Δανάη" ] || [ "$Onoma" == "Ζαχαρίας" ]
+then
+ echo "Αυτό θα εκτελεστεί αν το όνομα ($Onoma) είναι Δανάη Ή Ζαχαρίας."
+fi
+
+# Υπάρχει επίσης ο τελεστής `=~`, που εκτελεί ένα regex πάνω σε ένα
+# αλφαριθμητικό:
+Email=me@example.com
+if [[ "$Email" =~ [a-z]+@[a-z]{2,}\.(com|net|org) ]]
+then
+ echo "Η διεύθυνση email είναι σωστά διατυπωμένη!"
+fi
+# Να σημειωθεί πως ο τελεστής `=~` δουλεύει μόνο με διπλές αγκύλες [[ ]],
+# που είναι ωστόσο διαφορετικές από τις μονές [ ].
+# Δείτε το http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs
+# για περισσότερες πληροφορίες σχετικά με αυτό.
+
+# Επαναπροσδιορισμός της εντολής `ping` ως alias (ψευδώνυμο) για την αποστολή 5
+# πακέτων
+alias ping='ping -c 5'
+# Ακύρωση του alias και χρήση της εντολής όπως είναι κανονικά ορισμένη
+\ping 192.168.1.1
+# Εκτύπωση όλων των aliases
+alias -p
+
+# Οι μαθηματικές εκφράσεις ορίζονται ως εξής:
+echo $(( 10 + 5 )) # => 15
+
+# Αντίθετα με άλλες γλώσσες προγραμματισμού, η Bash είναι επίσης ένα shell, άρα
+# δουλεύει στο πλαίσιο ενός «τρέχοντος καταλόγου». Μπορούμε να δούμε μια λίστα
+# αρχείων και καταλόγων στον τρέχων κατάλογο με την εντολή ls:
+ls # Τυπώνει μια λίστα των αρχείων και υποκαταλόγων που περιέχονται στον τρέχων
+ # κατάλογο
+
+# Αυτή η εντολή έχει επιλογές που ελέγχουν την εκτέλεσή της:
+ls -l # Τυπώνει κάθε αρχείο και κατάλογο σε διαφορετική γραμμή
+ls -t # Ταξινομεί τα περιεχόμενα του καταλόγου με βάσει την ημερομηνία
+ # τελευταίας τροποποίησης (σε φθίνουσα σειρά)
+ls -R # Εκτελεί την εντολή `ls` αναδρομικά στον τρέχων κατάλογο και σε όλους
+ # τους υποκαταλόγους του.
+
+# Τα αποτελέσματα μιας εντολής μπορούν να μεταβιβαστούν σε μιαν άλλη.
+# Η εντολή `grep` φιλτράρει τα δεδομένα που δέχεται βάσει μοτίβων.
+# Έτσι, μπορούμε να τυπώσουμε μια λίστα αρχείων κειμένου (.txt) στον τρέχων
+# κατάλογο:
+ls -l | grep "\.txt"
+
+# Μπορούμε να χρησιμοποιήσουμε την εντολή `cat` για να τυπώσουμε το περιεχόμενο
+# ενός ή περισσότερων αρχείων στην προεπιλεγμένη έξοδο (stdout):
+cat file.txt
+
+# Μπορούμε επίσης να διαβάσουμε το αρχείο μέσω της `cat`:
+Periexomena=$(cat file.txt)
+echo "ΑΡΧΗ ΤΟΥ ΑΡΧΕΙΟΥ\n$Periexomena\nΤΕΛΟΣ ΤΟΥ ΑΡΧΕΙΟΥ" # Ο χαρακτήρας "\n"
+ # δημιουργεί μια νέα
+ # γραμμή
+# => ΑΡΧΗ ΤΟΥ ΑΡΧΕΙΟΥ
+# => [περιεχόμενα του αρχείου file.txt]
+# => ΤΕΛΟΣ ΤΟΥ ΑΡΧΕΙΟΥ
+
+# Μπορούμε να χρησιμοποιήσουμε την εντολή `cp` για να αντιγράψουμε αρχεία ή
+# καταλόγους από ένα σημείο σε ένα άλλο.
+# Η εντολή `cp` δημιουργεί ΝΕΕΣ εκδοχές των πρωτοτύπων, το οποίο σημαίνει ότι
+# μια τροποποίηση του αντιγράφου δεν θα επηρεάσει το πρωτότυπο (και
+# αντιστρόφως).
+# Να σημειωθεί πως αν υπάρχει ήδη αρχείο ή κατάλογος με το ίδιο όνομα στην ίδια
+# θέση με το αντίγραφο, το αντίγραφο θα αντικαταστήσει το αρχείο/κατάλογο και
+# άρα τα δεδομένα του θα χαθούν.
+cp prototipo.txt antigrafo.txt
+cp -r prototipo/ antigrafo/ # Αναδρομική αντιγραφή (αντιγραφή όλων των
+ # περιεχομένων του καταλόγου prototipo/)
+
+# Ενημερωθείτε σχετικά με τις εντολές `scp` και `sftp` αν σχεδιάζετε να
+# αντιγράψετε αρχεία από έναν υπολογιστή σε έναν άλλο.
+# Η εντολή `scp` μοιάζει πολύ με την `cp`, ενώ η `sftp` είναι πιο διαδραστική.
+
+# Μπορούμε να χρησιμοποιήσουμε την εντολή `mv` για να μετακινήσουμε αρχεία ή
+# καταλόγους από μια θέση σε μια άλλη.
+# Η εντολή `mv` μοιάζει με την `cp`, με τη διαφορά ότι διαγράφει το πρωτότυπο.
+# Η `mv` χρησιμοποιείται επίσης για τη μετονομασία αρχείων!
+mv prototipo.txt prototipo2.txt
+
+# Δεδομένου του ότι η Bash δουλεύει στο πλαίσιο του τρέχοντος καταλόγου,
+# μπορεί να θελήσουμε να τρέξουμε κάποια εντολή σε κάποιον άλλο κατάλογο.
+# Η εντολή `cd` (Change Directory) μας επιτρέπει να αλλάξουμε θέση μέσα στο
+# σύστημα αρχείων:
+cd ~ # Μετατόπιση στον κατάλογο «home»
+cd # Αυτή η εντολή μας μετατοπίζει επίσης στον κατάλογο «home»
+cd .. # Μετατόπιση προς τα πάνω κατά έναν κατάλογο
+ # (για παράδειγμα, μετατόπιση από τη θέση /home/username/Downloads
+ # στη θέση /home/username)
+cd /home/username/Documents # Μετατόπιση προς έναν συγκεκριμένο κατάλογο
+cd ~/Documents/.. # Μετατόπιση προς τον κατάλογο «home»... σωστά;
+cd - # Μετατόπιση προς τον προηγούμενο κατάλογο
+# => /home/username/Documents
+
+# Μπορούμε να χρησιμοποιήσουμε subshells για να δουλέψουμε σε πολλούς
+# διαφορετικούς καταλόγους:
+(echo "Πρώτα, είμαι εδώ: $PWD") && (cd kapoiosKatalogos; echo "Έπειτα, είμαι εδώ: $PWD")
+pwd # Εδώ θα είμαστε στον πρώτο κατάλογο
+
+# Μπορούμε να χρησιμοποιήσουμε την εντολή `mkdir` για να δημιουργήσουμε νέους
+# καταλόγους.
+mkdir neosKatalogos
+# Η επιλογή `-p` επιτρέπει σε ενδιάμεσους καταλόγους να δημιουργηθούν αν
+# χρειάζεται.
+mkdir -p neosKatalogos/me/epipleon/katalogous
+# Αν οι ενδιάμεσοι κατάλογοι δεν υπήρχαν ήδη, η παραπάνω εντολή χωρίς την
+# επιλογή `-p` θα είχε επιστρέψει κάποιο λάθος.
+
+# Μπορούμε να διευθύνουμε τις εισόδους και εξόδους των εντολών (χρησιμοποιώντας
+# τα κανάλια stdin, stdout και stderr).
+# Για παράδειγμα, μπορούμε να «διαβάσουμε» από το stdin μέχρι να βρεθεί ένα
+# ^EOF$ (End Of File) και να αντικαταστήσουμε το περιεχόμενο του αρχείου
+# hello.py με τις γραμμές που διαβάσαμε έως και πριν το "EOF":
+cat > hello.py << EOF
+#!/usr/bin/env python
+from __future__ import print_function
+import sys
+print("#stdout", file=sys.stdout)
+print("#stderr", file=sys.stderr)
+for line in sys.stdin:
+ print(line, file=sys.stdout)
+EOF
+
+# Μπορούμε να τρέξουμε το πρόγραμμα Python «hello.py» με διάφορες
+# ανακατευθύνσεις χρησιμοποιώντας τα stdin, stdout και stderr:
+python hello.py < "eisodos.in" # Περνάμε το eisodos.in ως είσοδο στο πρόγραμμα
+
+python hello.py > "eksodos.out" # Ανακατευθύνουμε την έξοδο του προγράμματος
+ # προς το αρχείο eksodos.out
+
+python hello.py 2> "lathos.err" # ανακατευθύνουμε την έξοδο λάθους (stderr)
+ # προς το αρχείο lathos.err
+
+python hello.py > "eksodos-kai-lathos.log" 2>&1
+# Ανακατευθύνουμε την κανονική έξοδο (stdout) και την έξοδο λάθους (stderr)
+# προς το αρχείο eksodos-kai-lathos.log
+
+python hello.py > /dev/null 2>&1
+# Ανακατευθύνουμε όλες τις εξόδους προς τη «μαύρη τρύπα» που λέγεται /dev/null,
+# δηλαδή τίποτα δεν θα τυπωθεί στον τερματικό
+
+# Αν θέλετε να προσθέσετε την έξοδο σε κάποιο αρχείο αντί να διαγράψετε τα
+# περιεχόμενά του με τη νέα έξοδο, μπορείτε να χρησιμοποιήσετε τον τελεστή
+# `>>` αντί στη θέση του `>`:
+python hello.py >> "eksodos.out" 2>> "lathos.err"
+
+# Αντικατάσταση του αρχείου eksodos.out, προσθήκη στο αρχείο lathos.err, και
+# καταμέτρηση των γραμμών τους:
+info bash 'Basic Shell Features' 'Redirections' > eksodos.out 2>> lathos.err
+wc -l eksodos.out lathos.err
+
+# Μπορούμε να εκτελέσουμε μια εντολή και να τυπώσουμε τον file descriptor της
+# (https://en.wikipedia.org/wiki/File_descriptor)
+# Για παράδειγμα: /dev/fd/123
+# Δείτε επίσης: man fd
+echo <(echo "#καλημέρακόσμε")
+
+# Αντικατάσταση του περιεχομένου του αρχείου eksodos.out με το αλφαριθμητικό
+# «#καλημέρακόσμε»:
+cat > eksodos.out <(echo "#καλημέρακόσμε")
+echo "#καλημέρακόσμε" > eksodos.out
+echo "#καλημέρακόσμε" | cat > eksodos.out
+echo "#καλημέρακόσμε" | tee eksodos.out >/dev/null
+
+# Εκκαθάριση προσωρινών αρχείων με την επιλογή `-v` (verbose) (προσθέστε την
+# επιλογή `-i` για περισσότερη διάδραση)
+# ΠΡΟΣΟΧΗ: τα αποτελέσματα της εντολής `rm` είναι μόνιμα.
+rm -v eksodos.out lathos.err eksodos-kai-lathos.log
+rm -r tempDir/ # Αναδρομική διαγραφή
+
+# Οι εντολές μπορούν να αντικατασταθούν μέσα σε άλλες εντολές χρησιμοποιώντας
+# το μοτίβο $( ).
+# Το παράδειγμα που ακολουθεί τυπώνει τον αριθμό των αρχείων και των καταλόγων
+# στον τρέχων κατάλογο.
+echo "Υπάρχουν $(ls | wc -l) αντικείμενα εδώ."
+
+# Μπορούμε να επιτύχουμε το ίδιο αποτέλεσμα με τους χαρακτήρες ``, αλλά δεν
+# μπορούμε να τους χρησιμοποιήσουμε αναδρομικά (δηλαδή `` μέσα σε ``).
+# Ο προτεινόμενος τρόπος από την Bash είναι το μοτίβο $( ).
+echo "Υπάρχουν `ls | wc -l` αντικείμενα εδώ."
+
+# Η Bash έχει επίσης τη δομή `case` που δουλεύει παρόμοια με τη δομή switch
+# όπως στην Java ή την C++ για παράδειγμα:
+case "$Metavliti" in
+ # Λίστα μοτίβων για τις συνθήκες που θέλετε να ορίσετε:
+ 0) echo "Η μεταβλητή έχει ένα μηδενικό.";;
+ 1) echo "Η μεταβλητή έχει έναν άσσο.";;
+ *) echo "Η μεταβλητή δεν είναι αόριστη (null).";;
+esac
+
+# Οι βρόγχοι `for` εκτελούνται τόσες φορές όσο είναι το πλήθος των παραμέτρων
+# που τους δίνονται:
+# Το περιεχόμενο της μεταβλητής $Metavliti τυπώνεται τρεις φορές.
+for Metavliti in {1..3}
+do
+ echo "$Metavliti"
+done
+# => 1
+# => 2
+# => 3
+
+# Μπορούμε επίσης να το γράψουμε πιο «παραδοσιακά»:
+for ((a=1; a <= 3; a++))
+do
+ echo $a
+done
+# => 1
+# => 2
+# => 3
+
+# Μπορούμε επίσης να περάσουμε αρχεία ως παραμέτρους.
+# Το παράδειγμα που ακολουθεί θα τρέξει την εντολή `cat` με τα αρχεία file1
+# και file2:
+for Metavliti in file1 file2
+do
+ cat "$Metavliti"
+done
+
+# Μπορούμε ακόμα να χρησιμοποιήσουμε την έξοδο μας εντολής.
+# Το παράδειγμα που ακολουθεί θα τρέξει την εντολή `cat` με την έξοδο της
+# εντολής `ls`.
+for Output in $(ls)
+do
+ cat "$Output"
+done
+
+# Ο βρόγχος `while` έχει ως εξής:
+while [ true ]
+do
+ echo "το «σώμα» του βρόγχου μπαίνει εδώ..."
+ break
+done
+# => το «σώμα» του βρόγχου μπαίνει εδώ...
+
+# Μπορούμε επίσης να ορίσουμε συναρτήσεις, ως εξής:
+function synartisi ()
+{
+ echo "Οι παράμετροι συναρτήσεων δουλεύουν όπως αυτές των προγραμμάτων: $@"
+ echo "Και: $1 $2..."
+ echo "Αυτή είναι μια συνάρτηση"
+ return 0
+}
+# Ας καλέσουμε την συνάρτηση `synartisi` με δύο παραμέτρους, param1 και param2
+synartisi param1 param2
+# => Οι παράμετροι συναρτήσεων δουλεύουν όπως αυτές των προγραμμάτων: param1 param2
+# => Και: param1 param2...
+# => Αυτή είναι μια συνάρτηση
+
+# Ή επίσης:
+synartisi2 ()
+{
+ echo "Ένας άλλος τρόπος να ορίσουμε συναρτήσεις!"
+ return 0
+}
+# Ας καλέσουμε την συνάρτηση `synartisi2` χωρίς παραμέτρους:
+synartisi2 # => Ένας άλλος τρόπος να ορίσουμε συναρτήσεις!
+
+# Ας καλέσουμε την πρώτη συνάρτηση:
+synartisi "Το όνομά μου είναι" $Onoma
+
+# Υπάρχουν πολλές χρήσιμες εντολές που μπορείτε να μάθετε.
+# Για παράδειγμα, αυτή που ακολουθεί τυπώνει τις 10 τελευταίες γραμμές του
+# αρχείου file.txt:
+tail -n 10 file.txt
+
+# Ενώ αυτή τυπώνει τις 10 πρώτες:
+head -n 10 file.txt
+
+# Αυτή ταξινομεί τις γραμμές:
+sort file.txt
+
+# Αυτή αναφέρει ή παραλείπει τις γραμμές που επαναλαμβάνονται (η επιλογή
+# -d τις αναφέρει):
+uniq -d file.txt
+
+# Αυτή τυπώνει μόνο ό,τι βρίσκεται πριν τον πρώτο χαρακτήρα «,» σε κάθε γραμμή:
+cut -d ',' -f 1 file.txt
+
+# Αυτή αντικαθιστά κάθε εμφάνιση της λέξης «οκ» με τη λέξη «τέλεια» στο αρχείο
+# file.txt (δέχεται επίσης μοτίβα regex):
+sed -i 's/οκ/τέλεια/g' file.txt
+
+# Αυτή τυπώνει στο stdout όλες τις γραμμές που είναι συμβατές με κάποιο
+# συγκεκριμένο μοτίβο regex.
+# Για παράδειγμα, όλες τις γραμμές που ξεκινούν με «καλημέρα» και τελειώνουν με
+# «καληνύχτα»:
+grep "^καλημέρα.*καληνύχτα$" file.txt
+
+# Η επιλογή `-c` θα τυπώσει τον αριθμό των γραμμών που περιέχουν το μοτίβο:
+grep -c "^καλημέρα.*καληνύχτα$" file.txt
+
+# Άλλες χρήσιμες επιλογές:
+grep -r "^καλημέρα.*καληνύχτα$" someDir/ # Αναδρομική εκτέλεση μέσα σε κάποιο κατάλογο
+grep -n "^καλημέρα.*καληνύχτα$" file.txt # Τυπώνει επίσης τον αριθμό των γραμμών
+grep -rI "^καλημέρα.*καληνύχτα$" someDir/ # Αναδρομική εκτέλεση αγνοώντας τα αρχεία binary
+
+# Η ίδια εντολή, αλλά τώρα αγνοώντας τις γραμμές που περιέχουν «αντίο»
+grep "^καλημέρα.*καληνύχτα$" file.txt | grep -v "αντίο"
+
+# Αν θέλετε να ψάξετε κυριολεκτικά για ένα αλφαριθμητικό, και όχι για κάποιο
+# μοτίβο, μπορείτε να χρησιμοποιήσετε την εντολή `fgrep` (ή `grep -F`):
+fgrep "καλημέρα" file.txt
+
+# Η εντολή `trap` επιτρέπει την εκτέλεση μιας εντολής μόλις το πρόγραμμά μας
+# λάβει κάποιο σήμα. Στο παράδειγμα που ακολουθεί, η εντολή `trap` θα
+# εκτελέσει την εντολή `rm` αν λάβει κάποιο από τα τρία σήματα που ακολουθούν
+# (SIGHUP, SIGINT, SIGTERM):
+trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM
+
+# Η εντολή `sudo` (SuperUser Do) χρησιμοποιείται για να εκτελέσουμε εντολές
+# με προνόμια υπερχρήστη (superuser):
+ONOMA1=$(whoami)
+ONOMA2=$(sudo whoami)
+echo "Ήμουν ο $ONOMA1, και έπειτα έγινα ο πιο ισχυρός $ONOMA2"
+
+# Διαβάστε την ενσωματωμένη documentation της Bash χρησιμοποιώντας την εντολή
+# `help`:
+help
+help help
+help for
+help return
+help source
+help .
+
+# Διαβάστε τα manpages με την εντολή `man`:
+apropos bash
+man 1 bash
+man bash
+
+# Διαβάστε επίσης την info documentation με την εντολή `info`:
+apropos info | grep '^info.*('
+man info
+info info
+info 5 info
+info bash
+info bash 'Bash Features'
+info bash 6
+info --apropos bash
+```
diff --git a/el-gr/html-gr.html.markdown b/el-gr/html-gr.html.markdown
new file mode 100644
index 00000000..0ca6e326
--- /dev/null
+++ b/el-gr/html-gr.html.markdown
@@ -0,0 +1,193 @@
+---
+language: html
+filename: learnhtml-gr.html
+contributors:
+ - ["Dimitri Kokkonis", "https://github.com/kokkonisd"]
+lang: el-gr
+---
+
+Το ακρώνυμο HTML σημαίνει HyperText Markup Language.
+
+Είναι μια γλώσσα που μας επιτρέπει να δημιουργήσουμε σελίδες για το διαδίκτυο.
+Είναι μια γλώσσα σήμανσης (markup), και μας επιτρέπει να γράψουμε ιστοσελίδες
+χρησιμοποιώντας κώδικα για να υποδείξουμε πώς πρέπει να εμφανίζεται το κείμενο
+και τα δεδομένα στη σελίδα. Στην πραγματικότητα, τα αρχεία HTML είναι απλά
+αρχεία κειμένου.
+
+Τι σημαίνει όμως «γλώσσα σήμανσης»; Είναι μια μέθοδος οργάνωσης των δεδομένων
+της σελίδας, που λειτουργεί μέσω ετικετών (tags) που «ανοίγουν» ή «κλείνουν».
+Αυτή η σήμανση έχει ως σκοπό να δώσει κάποια συγκεκριμένη σημασία στο κείμενο
+που περιβάλλει. Όπως και οι περισσότερες γλώσσες υπολογιστών, η HTML έχει
+πολλές διαφορετικές εκδοχές. Εδώ θα μιλήσουμε για την HTML5.
+
+**ΣΗΜΕΙΩΣΗ :** Μπορείτε να δοκιμάσετε τις ετικέτες και τα στοιχεία που
+παρουσιάζονται εδώ σε ένα σάιτ όπως το [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>Αυτό είναι ένα αντικείμενο μέσα σε μια μη-αριθμημένη λίστα
+ (bullet list)</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>
+ <!--
+ Υπάρχουν επίσης υπότιτλοι/υποκεφαλίδες, από την πιο σημαντική (h2)
+ μέχρι την πιο μικρή και ειδική (h6).
+ -->
+
+ <!-- Ένας υπερσύνδεσμος προς την διεύθυνση που δίνεται από την παράμετρο
+ href="": -->
+ <a href="http://codepen.io/anon/pen/xwjLbZ">
+ Δείτε τι κάνει αυτό
+ </a>
+
+ <!-- Η ετικέτα <p> μας επιτρέπει να εισάγουμε κείμενο στην σελίδα μας. -->
+ <p>Αυτή είναι μια παράγραφος.</p>
+ <p>Αυτή είναι μια άλλη παράγραφος.</p>
+
+ <!-- Η ετικέτα <ul> δημιουργεί μια μη-αριθμημένη λίστα. -->
+ <!--
+ Για μια αριθμημένη λίστα χρησιμοποιούμε την ετικέτα <ol>, που θα μας
+ δώσει 1. για το πρώτο στοιχείο, 2. για το δεύτερο κτλ.
+ -->
+ <ul>
+ <li>Αυτό είναι ένα αντικείμενο μέσα σε μια μη-αριθμημένη λίστα (bullet
+ list)</li>
+ <li>Αυτό είναι ένα άλλο αντικείμενο</li>
+ <li>Και αυτό είναι το τελευταίο αντικείμενο της λίστας</li>
+ </ul>
+</body>
+
+<!-- Αυτό ήταν όλο, είναι εύκολο να δημιουργήσουμε αρχεία HTML. -->
+
+<!-- Ωστόσο έχουμε την δυνατότητα να επιλέξουμε ανάμεσα σε πολλές ακόμη
+ετικέτες HTML. -->
+
+<!-- Η ετικέτα <img /> χρησιμοποιείται για να εισάγουμε μια εικόνα. -->
+<!--
+ Η πηγή της εικόνας υποδεικνύεται μέσω της παραμέτρου src="".
+ Η πηγή μπορεί να είναι μια διεύθυνση (URL) ή ακόμα και μια τοπική διεύθυνση
+ ενός αρχείου που βρίσκεται στον υπολογιστή μας.
+-->
+<img src="http://i.imgur.com/XWG0O.gif"/>
+
+<!-- Υπάρχει επίσης η δυνατότητα να δημιουργήσουμε πίνακες. -->
+
+<!-- Ανοίγουμε μια ετικέτα <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` ή `.htm`. Ο τύπος MIME της
+HTML είναι
+`text/html`.
+**H HTML ΔΕΝ είναι γλώσσα προγραμματισμού.**
+## Μάθετε περισσότερα
+
+* [βικιπαίδεια](https://el.wikipedia.org/wiki/HTML)
+* [Μάθημα HTML](https://developer.mozilla.org/en-US/docs/Web/HTML)
+* [W3School](http://www.w3schools.com/html/html_intro.asp)
diff --git a/el-gr/json-gr.html.markdown b/el-gr/json-gr.html.markdown
new file mode 100644
index 00000000..6f30d819
--- /dev/null
+++ b/el-gr/json-gr.html.markdown
@@ -0,0 +1,60 @@
+---
+language: json
+filename: json-gr.html.markdown
+contributors:
+ - ["Anna Harren", "https://github.com/iirelu"]
+ - ["Marco Scannadinari", "https://github.com/marcoms"]
+ - ["himanshu", "https://github.com/himanshu81494"]
+ - ["Michael Neth", "https://github.com/infernocloud"]
+ - ["Athanasios Emmanouilidis", "https://github.com/athanasiosem"]
+translators:
+ - ["Athanasios Emmanouilidis", "https://github.com/athanasiosem"]
+lang: el-gr
+---
+
+Το JSON (JavaScript Object Notation) είναι ένα πολύ απλό και ελαφρύ μορφότυπο ανταλλαγής δεδομένων. Όπως αναφέρεται και στην ιστοσελίδα [json.org](http://json.org), το JSON διαβάζεται και γράφεται εύκολα από τους ανθρώπους όπως επίσης αναλύεται και παράγεται εύκολα από τις μηχανές.
+
+Ένα κομμάτι JSON δηλώνει ένα από τα παρακάτω:
+
+* Μια συλλογή από ζευγάρια ονομάτων/τιμών (collection of name/value pairs) (`{ }`). Σε πολλές γλώσσες προγραμματισμού αυτό αντιστοιχεί σε ένα αντικείμενo (object), μία εγγραφή (record), μία δομή (struct), ένα λεξικό (dictionary), ένα πίνακα κατακερματισμού (hash table), μια λίστα αριθμημένη με κλειδιά (keyed list) ή έναν πίνακα συσχέτισης (associative array).
+
+* Μια ταξινομημένη λίστα τιμών (`[ ]`). Σε πολλές γλώσσες προγραμματισμού αυτό αντιστοιχεί σε ένα πίνακα (array), σε ένα διάνυσμα (vector), μία λίστα (list), ή μια ακολουθία (sequence).
+
+Αν και το JSON στην καθαρότερη του μορφή δεν έχει σχόλια (comments), οι περισσότεροι parsers θα δεχτούν σχόλια (comments) του στύλ της γλώσσας C (`//`, `/* */`). Κάποιοι parsers επίσης ανέχονται ένα εξτρά κόμμα στο τέλος (δηλαδή ένα κόμα μετά το τελευταίο στοιχείο ενός πίνακα ή μετά την τελευταία ιδιότητα ενός αντικειμένου) αλλά καλύτερα θα είναι να αποφεύγεται η χρήση του για χάρη της συμβατότητας.
+
+Υποστηριζόμενοι τύποι δεδομένων (data types):
+
+* Συμβολοσειρές (Strings): `"Γεια"`, `"\"Περικοπή.\""`, `"\u0abe"`, `"Νέα γραμμή.\n"`
+* Αριθμοί (Numbers): `23`, `0.11`, `12e10`, `3.141e-10`, `1.23e+4`
+* Αντικείμενα (Objects): `{ "κλειδί": "τιμή" }`
+* Πίνακες (Arrays): `["Τιμή1","Τιμή2","Τιμή3",]`
+* Διάφορα : `true`, `false`, `null`
+
+```json
+{
+ "κλειδί": "τιμή",
+ "κλειδιά": "πρέπει πάντα να περιβάλονται από διπλά quotes",
+ "νούμερα": 0,
+ "συμβολοσειρές": "Γεια, κόσμε. Οι χαρακτήρες unicode επιτρέπονται, καθώς και το \"escaping\".",
+ "διαδικές τιμές": true,
+ "κενό": null,
+ "μεγάλοι αριθμοί": 1.2e+100,
+ "αντικείμενα": {
+ "σχόλια": "Σήμερα έφαγα ένα μήλο.",
+ "πίνακες": [0, 1, 2, 3, "Οι πίνακες μπορούνε να περιλαμβάνουν διαφορετικούς τύπους δεδομένων", 5],
+ "αντικείμενα μέσα σε αντικείμενα": {
+ "σχόλια": "Τα αντικείμενα μπορούνε να εσωκλύουν αντικείμενα."
+ }
+ },
+
+
+ "κενό διάστημα": "Αναγνωρίζεται χωρίς πρόβλημα αλλά καλύτερα να αποφεύγεται η χρήση του.",
+ "αυτό ήταν": "Πλέον γνωρίζετε πως μπορείτε να χρησιμοποιήσετε το JSON."
+}
+```
+
+## Περαιτέρω διάβασμα
+
+* [JSON.org](http://json.org)
+
+* [JSON Tutorial](https://www.youtube.com/watch?v=wI1CWzNtE-M)
diff --git a/el-gr/python-gr.html.markdown b/el-gr/python-gr.html.markdown
new file mode 100644
index 00000000..203c6e78
--- /dev/null
+++ b/el-gr/python-gr.html.markdown
@@ -0,0 +1,1031 @@
+---
+language: Python
+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"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
+ - ["Roberto Fernandez Diaz", "https://github.com/robertofd1995"]
+filename: learnpython-gr.py
+lang: el-gr
+---
+
+Η Python δημιουργήθηκε από τον Guido van Rossum στις αρχές των 90s. Πλέον είναι μία από τις πιο
+δημοφιλείς γλώσσες. Ερωτευεται κανείς την python για τη συντακτική της απλότητα.
+Βασικά είναι εκτελέσιμος ψευδοκώδικας.
+
+Το Feedback είναι πάντα δεκτό! Μπορείτε να με βρείτε στο [@haritonaras](http://twitter.com/haritonaras)
+ή τον αρχικό συγγραφέα στο [@louiedinh](http://twitter.com/louiedinh) ή στο
+louiedinh [at] [google's email service]
+
+Σημείωση: Το παρόν άρθρο ασχολείται μόνο με την Python 3. Δείτε [εδώ](http://learnxinyminutes.com/docs/pythonlegacy/) αν θέλετε να μάθετε την παλιά Python 2.7
+
+```python
+
+# Τα σχόλια μίας γραμμής ξεκινούν με #
+
+""" Τα σχόλια πολλαπλών γραμμών μπορούν
+ να γραφούν με τρία ", και συχνά χρησιμοποιούνται
+ ως documentation.
+"""
+
+####################################################
+## 1. Primitive (πρωταρχικοί) Τύποι Δεδομένων και Τελεστές
+####################################################
+
+# Αφού έχει αριθμούς
+3 # => 3
+
+# Λογικά θα έχει και Μαθηματικά...
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7.0
+
+# Η διαίρεση ακεραίων κάνει στρογγυλοποίηση προς τα κάτω για θετικούς και αρνητικούς αριθμούς
+5 // 3 # => 1
+-5 // 3 # => -2
+5.0 // 3.0 # => 1.0 # works on floats too
+-5.0 // 3.0 # => -2.0
+
+# Το αποτέλεσμα της διαίρεσης είναι πάντα float
+10.0 / 3 # => 3.3333333333333335
+
+# Modulo τελεστής
+7 % 3 # => 1
+
+# Ύψωση σε δύναμη (x**y, x στην y-οστή δύναμη)
+2**3 # => 8
+
+# Ελέγχουμε την προτεραιότητα πράξεων με παρενθέσεις
+(1 + 3) * 2 # => 8
+
+# Οι Boolean τιμές είναι primitives (Σημ.: τα κεφαλαία)
+True
+False
+
+# άρνηση με το not
+not True # => False
+not False # => True
+
+# Boolean τελεστές
+# Σημ. ότι τα "and" και "or" είναι case-sensitive
+True and False # => False
+False or True # => True
+
+# Τα True και False είναι 1 και 0 αλλά με διαφορετικά keywords
+True + True # => 2
+True * 8 # => 8
+False - 5 # => -5
+
+# Μπορούμε να δούμε τις αριθμητικές τιμές των True και False μέσω των τελεστών σύγκρισης
+0 == False # => True
+1 == True # => True
+2 == True # => False
+-5 != False # => True
+
+# Χρησιμοποιώντας τελεστές boolean σε ακεραίους, οι ακέραιοι γίνονται cast σε
+# boolean ώστε να γίνει η αποτίμηση της έκφρασης.
+# Το αποτέλεσμα όμως είναι non-cast, δηλαδή ίδιου τύπου με τα αρχικά ορίσματα
+# Μην μπερδεύετε τις bool(ints) και bitwise and/or (&,|)
+bool(0) # => False
+bool(4) # => True
+bool(-6) # => True
+0 and 2 # => 0
+-5 or 0 # => -5
+
+# Ισότητα ==
+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 and 2 < 3 # => True
+2 < 3 and 3 < 2 # => False
+# Το Chaining (αλυσίδωση? :P) κάνει το παραπάνω πιο όμορφα
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# (is vs. ==) το is ελέγχει αν δύο μεταβλητές αναφέρονται στο ίδιο αντικείμενο,
+# αλλά το == ελέγχει αν τα αντικείμενα στα οποία αναφέρονται οι μεταβλητές έχουν τις ίδιες τιμές
+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 είναι ίσα
+
+# Τα Strings (συμβολοσειρές) δημιουργούνται με " ή '
+"This is a string."
+'This is also a string.'
+
+# Μπορούμε και να προσθέτουμε Strings, αλλά προσπαθήστε να μην το κάνετε
+"Hello " + "world!" # => "Hello world!"
+# Τα String literals (αλλά όχι οι μεταβλητές) μπορούν να συντμιθούν και χωρίς το '+'
+"Hello " "world!" # => "Hello world!"
+
+# Μπορούμε να φερθούμε σε string σαν να είναι λίστα από χαρακτήρες
+"This is a string"[0] # => 'T'
+
+# Μπορούμε να βρούμε το μήκος ενός string
+len("This is a string") # => 16
+
+# Το .format μπορεί να χρησιμοποιηθεί για να μορφοποιήσουμε strings, όπως εδώ:
+"{} can be {}".format("Strings", "interpolated") # => "Strings can be interpolated"
+
+# Μπορείς να επαναλάβεις τα ορίσματα του formatting για να γλιτώσεις λίγο χρονο
+"{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"
+
+# Μπορείς να χρησιμοποιήσεις keywords αν βαριέσαι το μέτρημα.
+"{name} wants to eat {food}".format(name="Bob", food="lasagna") # => "Bob wants to eat lasagna"
+
+# Αν ο κώδικας Python 3 που γράφεις πρόκειται να τρέξει και με python 2.5 ή παλιότερη
+# μπορείς επίσης να χρησιμοποιήσεις το παλιό τρόπο για formatting:
+"%s can be %s the %s way" % ("Strings", "interpolated", "old") # => "Strings can be interpolated the old way"
+
+# Μπορείς επίσης να μορφοποιήσεις χρησιμοποιώντας τα f-strings / formatted string literals (σε Python 3.6+)
+name = "Reiko"
+f"She said her name is {name}." # => "She said her name is Reiko"
+# Μπορείς βασικά να βάλεις οποιαδήποτε έκφραση Python στα άγκιστρα και θα εμφανιστεί στο string.
+f"{name} is {len(name)} characters long."
+
+
+# το None είναι ένα αντικείμενο (object)
+None # => None
+
+# Μη χρησιμοποιείτε το σύμβολο ισότητας "==" για να συγκρίνετε αντικείμενα με το None
+# Χρησιμοποιείτε το "is". Αυτό ελέγχει για ισότητα της ταυτότητας του αντικειμένου.
+"etc" is None # => False
+None is None # => True
+
+# Τα None, 0, και τα κενά strings/lists/dicts/tuples αποτιμούνται στην τιμή False
+# All other values are True
+bool(0) # => False
+bool("") # => False
+bool([]) # => False
+bool({}) # => False
+bool(()) # => False
+
+####################################################
+## 2. Μεταβλητές (variables) και Συλλογές (collections)
+####################################################
+
+# Η Python έχει μία συνάρτηση print()
+print("I'm Python. Nice to meet you!") # => I'm Python. Nice to meet you!
+
+# By default, η συνάρτηση print() τυπώνει και ένα χαρακτήρα αλλαγής γραμμμής στο τέλος
+# Χρησιμοποιείτε το προαιρετικό όρισμο end για να τυπώνει οτιδήποτε άλλο
+print("Hello, World", end="!") # => Hello, World!
+
+# Απλός τρόπος για να πάρουμε δεδομένα εισόδου από το console
+input_string_var = input("Enter some data: ") # επιστρέφει τα δεδομένα ως string
+# Σημ.: Στις προηγούμενες εκδόσεις της Python, η μέθοδος input() ονομαζόταν raw_input()
+
+# Δεν υπάρχουν δηλώσεις, μόνο αναθέσεις τιμών.
+# Η σύμβαση είναι να χρησιμοποιούμε μικρά γράμματα με κάτω παύλες
+some_var = 5
+some_var # => 5
+
+# Η πρόσβαση σε μεταβλητή που δεν έχει λάβει τιμή είναι εξαίρεση
+# Δες τον Έλεγχο Ροής για να μάθεις περισσότερα για το χειρισμό εξαιρέσεων
+some_unknown_var # Προκαλέι ένα NameError
+
+# Η παρακάτω έκφραση μπορεί να χρησιμποιηθεί ισοδύναμα με τον τελεστή '?' της C
+"yahoo!" if 3 > 2 else 2 # => "yahoo!"
+
+# Οι λίστες κρατούν ακολουθίς
+li = []
+# Μπορείς να αρχίσεις με μία προ-γεμισμένη λίστα
+other_li = [4, 5, 6]
+
+# Και να βάλεις πράγματα στο τέλος με την μέθοδο append
+li.append(1) # η li τώρα είναι [1]
+li.append(2) # η li τώρα είναι [1, 2]
+li.append(4) # η li τώρα είναι [1, 2, 4]
+li.append(3) # η li τώρα είναι [1, 2, 4, 3]
+# Αφαιρούμε από το τέλος με την μέθοδο pop
+li.pop() # => 3 και η li γίνεται [1, 2, 4]
+# Ας βάλουμε το 3 πίσω στη θέση του
+li.append(3) # η li γίνεται πάλι [1, 2, 4, 3].
+
+# Προσπελαύνουμε τις λίστες όπως τους πίνακες σε άλλες γλώσσες
+li[0] # => 1
+# Το τελευταίο στοιχείο...
+li[-1] # => 3
+
+# Όταν βγαίνουμε εκτός ορίων της λίστας προκαλείται IndexError
+li[4] # προκαλεί IndexError
+
+# Μπορείς να δεις ranges μιας λίστας με το slice syntax ':'
+# Ο δείκτης εκίνησης περιλαμβάνεται στο διάστημα, ο δείκτης τερματισμού όχι
+# (είναι ανοικτό/κλειστό διάστημα για τους φίλους των μαθηματικών)
+li[1:3] # => [2, 4]
+# Αγνόησε την αρχή και επίστρεψε τη λίστα
+li[2:] # => [4, 3]
+# Αγνόησε το τέλος και επίστρεψε τη λίστα
+li[:3] # => [1, 2, 4]
+# Διάλεξε κάθε δεύτερο στοιχείο
+li[::2] # =>[1, 4]
+# Επίστρεψε ένα reversed αντίγραφο της λίστας
+li[::-1] # => [3, 4, 2, 1]
+# Χρησιμοποιείστε οποιαδήποτε συνδυασμό αυτών για να φτιάξετε πιο προχωρημένα slices
+# li[start:end:step]
+
+# Φτιάξε ένα αντίγραφο της λίστας χρησιμοποιώντας slices
+li2 = li[:] # => li2 = [1, 2, 4, 3] αλλά το (li2 is li) επιστρέφει False
+
+# Αφαίρεσε οποιοδήποτε στοιχείο από λίστα με την εντολή "del"
+del li[2] # η li γίνεται [1, 2, 3]
+
+# Αφαιρούμε το πρώτο στιγμυότυπο μιας τιμής
+li.remove(2) # η li γίνεται [1, 3]
+li.remove(2) # Προκαλεί ένα ValueError καθώς το 2 δεν βρίσκεται στη λίστα.
+
+# Εισαγωγή ενός στοιχείου σε συγκεκριμένη θέση
+li.insert(1, 2) # η li γίνεται πάλι [1, 2, 3]
+
+# Βρες το index (δείκτη) του πρώτου στοιχείου με τιμή ίση με το όρισμα
+li.index(2) # => 1
+li.index(4) # Προκαλεί ValueError καθώς το 4 δεν βρίσκεται στη λίστα
+
+# Μπορείς να προσθέτεις λίστες
+# Σημ.: οι τιμές των 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
+
+
+# Τα Tuples είναι σαν τις λίστες αλλά είναι αμετάβλητα (immutable).
+tup = (1, 2, 3)
+tup[0] # => 1
+tup[0] = 3 # Προκαλεί TypeError
+
+# Σημειώστε ότι ένα tuple μήκους 1 πρέπει να έχει ένα κόμμα μετά το τελευταίο στοιχείο
+# αλλά τα tuples άλλων μηκών, ακόμα και μηδενικού μήκους, δεν χρειάζονται κόμμα.
+type((1)) # => <class 'int'>
+type((1,)) # => <class 'tuple'>
+type(()) # => <class 'tuple'>
+
+# Μπορείς να εφαρμόσεις τις περισσότερες μεθόδους των λιστών και στα tuples
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# Μπορείς να κάνεις unpack/"ξεπακετάρεις" tuples σε μεταβλητές
+a, b, c = (1, 2, 3) # a == 1, b == 2 και c == 3
+# Μπορείς επίσης να επεκτείνεις το unpacking
+a, *b, c = (1, 2, 3, 4) # a == 1, b == [2, 3] και c == 4
+# Τα Tuples δημιουργούνται by deafult αν δεν βάλεις παρενθέσεις
+d, e, f = 4, 5, 6 # το tuple 4, 5, 6 "ξεπακετάρεται" στις μεταβλητές d, e και f
+# αντίστοιχα έτσι ώστε να γίνεται d = 4, e = 5 and f = 6
+# Δείτε πόσο εύκολα μπορούμε να εναλλάσουμε δύο τιμές
+e, d = d, e # το d παίρνει την τιμή 5 και το e παίρνει την τιμή 4
+
+
+# Τα λεξικά (Dictionaries) αποθηκεύουν απεικονίσεις από κλειδιά σε τιμές
+empty_dict = {}
+# Εδώ έχουμε ένα προ-γεμισμένο dictionary
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Σημ. ότι τα κλειδιά για τα dictionaries πρέπει να είναι αμετάβλητοι τύποι
+# (immutable) αυτό γίνετια για να διασφαλίσουμε ότι τα κλειδιά μπορούν να
+# μετατρέπονται σε σταθερές τιμές κατακερματισμού (hash values) για γρήγορη εύρεση.
+# Μερικοί αμετάβλητοι τύποι είναι τα ints, floats, strings, tuples.
+invalid_dict = {[1,2,3]: "123"} # => Προκαλεί TypeError: unhashable type: 'list'
+valid_dict = {(1,2,3):[1,2,3]} # Οι τιμές όμως μπορούν να έχουν οποιοδήποτε τύπο.
+
+# Βρίσκουμε τιμές με []
+filled_dict["one"] # => 1
+
+# Μπορείς να πάρεις όλα τα κλειδιά με τη μέθοδο "keys()".
+# Πρέπει να "τυλίξουμε" την κλήση με list() για να το μετατρέψουμε σε λίστα
+# Θα μιλήσουμε για αυτά αργότερα. Σημ. - σε εκδόσεις Python < 3.7, η σειρά που
+# εμφανίζονται τα κλειδιά δεν είναι εγγυημένη. Τα αποτελέσματά σας ίσως να μην
+# είναι ακριβώς ίδια με τα παρακάτω. Στην έκδοση 3.7 πάντως, τα αντικείμενα του
+# λεξικού διατηρούν τη σειρά με την οποία εισήχθησαν στο dictionary
+list(filled_dict.keys()) # => ["three", "two", "one"] σε Python <3.7
+list(filled_dict.keys()) # => ["one", "two", "three"] σε Python 3.7+
+
+# Παίρνουμε όλες τις τιμές ενός iterable με τη μέθοδο "values()". Και πάλι
+# χρειάζεται να το περιτυλίξουμε σε list()
+# Σημ. - όπως παραπάνω σχετικά με τη σειρά των keys
+list(filled_dict.values()) # => [3, 2, 1] in Python <3.7
+list(filled_dict.values()) # => [1, 2, 3] in Python 3.7+
+
+# Έλεγχος της ύπαρξης κλειδιών σε ένα dictionary με το "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
+# στο δεύτερο argument της get() μπορούμε να βάλουμε μία τιμή που πρέπει να
+# επιστρέψει αν δεν υπάρχει το key που ψάχνουμε
+filled_dict.get("one", 4) # => 1
+filled_dict.get("four", 4) # => 4
+
+# το "setdefault()" εισάγει στο dictionary μόνο αν δεν υπάρχει το κλειδί
+filled_dict.setdefault("five", 5) # filled_dict["five"] γίνεται 5
+filled_dict.setdefault("five", 6) # filled_dict["five"] μένει 5 (υπαρκτό κλειδί)
+
+# Προσθήκη σε dictionary
+filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4}
+filled_dict["four"] = 4 # β' τρόπος
+
+# Αφαίρεση κλειδιών από dictionary με del
+del filled_dict["one"] # Αφαιρεί το κλειδί "one" από το filled_dict
+
+# Από την Python 3.5 μπορείς να χρησιμοποιήσεις και πρόσθετες επιλογές για unpacking
+{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2}
+{'a': 1, **{'a': 2}} # => {'a': 2}
+
+
+
+# τα Sets -όπως όλοι περιμένουμε- αποθηκεύουν σύνολα
+empty_set = set()
+# Αρχικοποιούμε ένα set με μερικές τιμές. Ναι, μοιάζει λίγο με dictionary, Sorry.
+some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4}
+
+# Παρομοίως με τα κλειδιά του dictionary, τα στοιχεία ενός συνόλου πρέπει να είναι
+# αμετάβλητα (immutable)
+invalid_set = {[1], 1} # => Προκαλεί TypeError: unhashable type: 'list'
+valid_set = {(1,), 1}
+
+# Προσθέτουμε άλλο ένα στοιχείο στο σύνολο
+filled_set = some_set
+filled_set.add(5) # το filled_set είναι τώρα {1, 2, 3, 4, 5}
+# Τα σύνολα δεν έχουν διπλοτυπα αντικείμενα
+filled_set.add(5) # το σύνολο παραμένει ίδιο {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. Έλεγχος Ροής και Iterables
+####################################################
+
+# Φτιάχνουμε μία μεταβλητή
+some_var = 5
+
+# Εδώ έχουμε ένα if statement. Η στοίχιση είναι σημαντική στην Python!
+# Η σύμβαση είναι να χρησιμοποιούμε 4 κενά, όχι tabs.
+# Το παρακάτω τυπώνει "some_var is smaller than 10"
+if some_var > 10:
+ print("some_var is totally bigger than 10.")
+elif some_var < 10: # το (else if) -> elif μέρος είναι προαιρετικό.
+ print("some_var is smaller than 10.")
+else: # και το else είναι προαιρετικό.
+ print("some_var is indeed 10.")
+
+
+"""
+τα for loops τρέχουν πάνω σε lists
+το παρακάτω τυπώνει:
+ dog is a mammal
+ cat is a mammal
+ mouse is a mammal
+"""
+for animal in ["dog", "cat", "mouse"]:
+ # You can use format() to interpolate formatted strings
+ print("{} is a mammal".format(animal))
+
+"""
+το "range(number)" επιστρέφει ένα iterable με αριθμούς
+από το μηδέν μέχρι τον δωσμένο αριθμό number (κλειστό/ανοικτό διάστημα)
+Το παρακάτω τυπώνει:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print(i)
+
+"""
+το "range(lower, upper)" επιστρέφει ένα iterable με αριθμούς
+από το lower εώς το upper (κλειστό/ανοικτό διάστημα)
+το παρακάτω τυπώνει:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print(i)
+
+"""
+το "range(lower, upper, step)" επιστρέφει ένα iterable με αριθμούς
+από το lower μέχρι το upper, με βήμα step
+αν δεν δώσουμε τιμή βήματος, το default βήμα είναι 1.
+το παρακάτω τυπώνει:
+ 4
+ 6
+"""
+for i in range(4, 8, 2):
+ print(i)
+"""
+
+τα While loops τρέχουν μέχρι μία συνθήκη να γίνει ψευδής.
+το παρακάτω τυπώνει:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print(x)
+ x += 1 # Shorthand for x = x + 1
+
+# Χειριζόμαστε εξαιρέσεις με ένα try/except block
+try:
+ # Χρησιμοποιούμε το "raise" για να πετάξουμε ένα error
+ raise IndexError("This is an index error")
+except IndexError as e:
+ pass # το Pass δεν κάνει τίποτα. Συνήθως κάνουμε ανάκτηση.
+except (TypeError, NameError):
+ pass # Μπορούμε να χειριζόμαστε πολλές εξαιρέσεις μαζί, αν χρειαστεί
+else: # Προαιρετικό στο try/except block. Πρέπει να ακολουθεί όλα τα except blocks
+ print("All good!") # τρέχει μόνο αν ο κώδικας στο try δεν προκαλεί εξαιρέσεις
+finally: # Εκτελείται ό,τι και να γίνει
+ print("We can clean up resources here")
+
+# Αντί για try/finally για να καθαρίσουμε τους πόρους, μπορούμε να χρησιμοποιούμε το
+# with expression as target:
+ pass to cleanup resources you can use a with statement
+with open("myfile.txt") as f:
+ for line in f:
+ print(line)
+
+# Η Python προσφέρει μία θεμελιώδη αφαίρεση (abstraction) που λέγεται 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 διεπαφή μας.
+
+# μπορούμε να τρέχουμε loops πάνω του.
+for i in our_iterable:
+ print(i) # Prints one, two, three
+
+# Ωστόσο δεν μπορούμε να προσπελάσουμε τα στοιχεία του με index.
+our_iterable[1] # προκαλεί a TypeError
+
+# Ένα iterable είναι ένα αντικείμενο που ξέρει πώς να δημιουργήσει έναν iterator.
+our_iterator = iter(our_iterable)
+
+# Ο iterator μας είναι ένα αντικείμενο που μπορεί να θυμάται την κατάσταση όπως το διατρέχουμε.
+# Παίρνουμε το επόμενο αντικείμενο με το "next()"
+next(our_iterator) # => "one"
+
+# Διατηρεί την κατάσταση καθώς επαναλαμβάνουμε.
+next(our_iterator) # => "two"
+next(our_iterator) # => "three"
+
+# Όταν ο iterator έχει επιστρέψει όλα τα δεδομένα του, προκαλεί ένα μια εξαίρεση StopIteration.
+next(our_iterator) # προκαλεί StopIteration
+
+# Μπορείς να πάρεις όλα τα αντικείμενα ενός iteratior καλώντας list() πάνω του.
+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
+
+# Ένας άλλος τρόπος να καλέσεις συνάρτησει είναι με keyword arguments (ορίσματα λέξεις-κλειδιά)
+add(y=6, x=5) # τα Keyword arguments μπορούν να δωθούν με οποιαδήποτε σειρά.
+
+# Μπορείς να ορίσεις συναρτήσεις που δέχονται μεταβλητό πλήθος ορισμάτων
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) # => (1, 2, 3)
+
+# Μπορούμε να ορίσουμε και συναρτήσεις που δέχονται μεταβλητό πλήθος keyword arguments
+def keyword_args(**kwargs):
+ return kwargs
+
+# Για να δούμε τι γίνεται αν την καλέσουμε
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
+
+
+# Μπορείς να κάνεις και τα δύο ταυτόχρονα αν θες
+def all_the_args(*args, **kwargs):
+ print(args)
+ print(kwargs)
+"""
+all_the_args(1, 2, a=3, b=4) τυπώνει:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Όταν καλείς συναρτήσεις μπορείς να κάνεις και το αντίστροφο από args/kwargs!
+# Χρησιμοποίησε το * για να επεκτείνεις tuples και χρησιμοποίησε το ** για να επεκτείλεις kwargs
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # ισοδύναμο με all_the_args(1, 2, 3, 4)
+all_the_args(**kwargs) # ισοδύναμο με all_the_args(a=3, b=4)
+all_the_args(*args, **kwargs) # ισοδύναμο με all_the_args(1, 2, 3, 4, a=3, b=4)
+
+# Επιστρέφουμε πλειάδα τιμών (με tuple assignments)
+def swap(x, y):
+ return y, x # Επιστρέφει πολλές τιμές ως tuple χωρίς την παρένθεση
+ # (Σημ.: οι παρενθέσεις έχουν παραλειφθεί αλλά μπορούν να γραφούν)
+
+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 δεν είναι η ίδια με την global μεταβλητή x
+ x = num # => 43
+ print(x) # => 43
+
+def set_global_x(num):
+ global x
+ print(x) # => 5
+ x = num # η global μεταβλητή 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
+
+# Αλλά έχει και anonymous συναρτήσεις.
+(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]
+
+# Μπορούμε να χρησιμοποιήσουμε list comprehensions για ωραία maps και filters
+# το List comprehension αποθηκεύει την έξοδο ως μία λίστα που μπορεί και η ίδια
+# να είναι μια εμφωλευμένη λίστα
+[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 και dict comprehensions.
+{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. Modules
+####################################################
+
+# Μπορείς να κάνεις import modules
+import math
+print(math.sqrt(16)) # => 4.0
+
+# Μπορείς να πάρεις συγκεκριμένες συναρτήσεις από ένα module
+from math import ceil, floor
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
+
+# Μπορείς να κάνεις import όλες τις συναρτήσεις από ένα module.
+# Προσοχή: δεν προτείνεται
+from math import *
+
+# Μπορείς να δημιουργείς συντομογραφίες για τα ονόματα των modules
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
+
+# Τα Python modules είναι απλά αρχεία Python. Μπορείς να δημιουργήσεις τα δικά σου
+# και να τα κάνεις import το όνομα του module είναι ίδιο με το όνομα του αρχείου
+
+# μπορείς να βρεις ποιες συναρτήσεις και γνωρίσματα ορίζονται στο module
+import math
+dir(math)
+
+# Αν έχεις ένα Python script με όνομα math.py στον ίδιο φάκελο με το τρέχον script
+# το αρχείο math.py θα φορτωθεί και όχι το built-in Python module
+# Αυτό συμβαίνει επειδή τα τοπικά αρχεία έχουν προτεραιότητα έναντι των built-in
+# βιβλιοθηκών της Python
+
+
+####################################################
+## 6. Κλάσεις - Classes
+####################################################
+
+# χρησιμοποιούμε το "class" statement για να δημιουργήσουμε μια κλάση
+class Human:
+
+ # Ένα γνώρισμα της κλάσης. Είναι κοινό για όλα τα στιγμιότυπα αυτής.
+ species = "H. sapiens"
+
+ # Βασικός initializer, καλείται όταν δημιουργείται στιγμιότυπο της κλάσης.
+ # Σημ. οι διπλές κάτω παύλες πριν και μετά υποδηλώνουν αντικείμενα
+ # ή γνωρίσματα που χρησιμοποιούνται από την Python αλλά ζουν σε ελεγχόμενα από
+ # το χρήση namespaces.
+ # Μέθοδοι (ή αντικείμενα ή γνωρίσματα) σαν τα __init__, __str__, __repr__ κλπ
+ # είναι ειδικές μέθοδοι (λέγονται και dunder (double underscore) μέθοδοι)
+ # Δεν πρέπει να δηλώνεις δικές σου τέτοιες συναρτήσεις
+ def __init__(self, name):
+ # Εκχώρησε στο attribute name του object το όρισμα
+ self.name = name
+
+ # Αρχικοποίησε την ιδιότητα
+ self._age = 0
+
+ # Μία μέθοδος στιγμιότυπου (instance method). Όλες οι μέθοδοι παίρνουν το
+ # "self" ως πρώτο όρισμα
+ def say(self, msg):
+ print("{name}: {message}".format(name=self.name, message=msg))
+
+ # Ακόμα μία instance method
+ def sing(self):
+ return 'yo... yo... microphone check... one two... one two...'
+
+ # Μία μέθοδος κλάσεις είναι κοινή ανάμεσα σε όλα τα instances.
+ # Καλούνται με calling class ώς πρώτο όρισμα
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Μία στατική μέθοδος καλείται χωρίς αναφορά σε κλάση ή στιγμιότυπο
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+ # Ένα property είναι ακριβώς σαν ένα getter.
+ # Μετατρέπει τη μέθοδο age σε ένα γνώρισμα (attribute) μόνο-για-ανάγνωση
+ # με το ίδιο όνομα.
+ # Δεν χρειάζεται να γράφουμε τετριμένους getters και setters στην Python όμως.
+ @property
+ def age(self):
+ return self._age
+
+ # Αυτό επιτρέπει στο property να γίνει set
+ @age.setter
+ def age(self, age):
+ self._age = age
+
+ # Αυτό επιτρέπει σε ένα property να διαγραφεί
+ @age.deleter
+ def age(self):
+ del self._age
+
+
+# Όταν ο διερμηνέας της Python διαβάζει αρχείο πηγαίου κώδικα τον εκτελεί όλο.
+# Αυτός ο έλεγχος του __name__ σιγουρεύει ότι αυτό το block κώδικα τρέχει μόνο
+# αυτό το module είναι το κύριο πρόγραμμα (και όχι imported)
+if __name__ == '__main__':
+ # Δημιουργούμε στιγμιότυπο κλάσης
+ i = Human(name="Ian")
+ i.say("hi") # "Ian: hi"
+ j = Human("Joel")
+ j.say("hello") # "Joel: hello"
+ # τα i και j είναι στιγμιότυπα του τύπου Human
+
+ # Καλούμε τη μέθοδο της κλάσης
+ i.say(i.get_species()) # "Ian: H. sapiens"
+ # Αλλάζουμε το κοινό attribute των αντικειμένων της κλάσης
+ Human.species = "H. neanderthalensis"
+ i.say(i.get_species()) # => "Ian: H. neanderthalensis"
+ j.say(j.get_species()) # => "Joel: H. neanderthalensis"
+
+ # Καλούμε τη static μέθοδο
+ print(Human.grunt()) # => "*grunt*"
+
+ # Δεν μπορούμε να καλέσουμε τη στατική μέθοδο με ένα στιγμιότυπο
+ # επειδή το i.grunt() θα βάλει αυτόματα το self (δηλαδή το αντικείμενο i) ως όρισμα
+ print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
+
+ # Ενημερώνουμε το property για αυτό το στγμιότυπο
+ i.age = 42
+ # Παίρνουμε το property
+ i.say(i.age) # => "Ian: 42"
+ j.say(j.age) # => "Joel: 0"
+ # Διαγράφουμε το property
+ del i.age
+ # i.age # => αυτό θα προκαλούσε AttributeError
+
+
+####################################################
+## 6.1 Κληρονομικότητα - Inheritance
+####################################################
+
+# Η κληρονομικότητα επιτρέπει σε νέες κλάσεις-παιδιά να οριστούν και να υιοθετήσουν
+# μεθόδους και μεταβλητές από την κλάση-γονέα.
+
+# Χρησιμοποιώντας την κλάση Human που ορίστηκε πριν ως τη βασική κλάση (ή κλάση-γονέα)
+# μπορούμε να ορίσουμε τις κλάσεις-παιδιά Superhero, που κληρονομεί μεταβλητές όπως
+# "species", "name", και "age", καθώς και μεθόδους όπως "sing" και "grunt"
+# από την κλάση Human, αλλά επίσης έχει τις δικές του ξεχωριστές ιδιότητες
+
+# Για να εκμεταλλευτείς το modularization κατά αρχείο, μπορείς να βάλεις την παραπάνω κλάση
+# σε δικό της αρχείο, ας πούμε human.py
+
+# Για να κάνουμε import συναρτήσεις από άλλα αρχεία χρησιμοποιούμε το παρακάτω format
+# from "filename-without-extension" import "function-or-class"
+
+from human import Human
+
+
+# Προσδιόρισε την/τις parent class(es) ως παραμέτρους της κλάσης που ορίζεται
+class Superhero(Human):
+
+ # Αν η κλάση-παιδί πρέπει να κληρονομήσει όλους τους οεισμούς της κλάσης-γονέα
+ # χωρίς καμία αλλαγή, μπορείς απλά να γράψεις pass (και τίποτα άλλο)
+ # αλλά σε αυτή την περίπτωση είναι σχολιασμένο για να επιτρέψει τη δημιουργία
+ # ξεχωριστής κλάσης-παιδιού:
+ # pass
+
+ # Η κλάση παιδί μπορεί να υπερφορτώσει (override) τα attributes της κλάσης από την οποία κληρονομεί
+ species = 'Superhuman'
+
+ # Τα παιδιά αυτόματα, κληρονομούν τον constructo της κλάσης-γονέα
+ # συμπεριλαμβανομένων των ορισμάτων, αλλά μπορείς και να ορίσεις πρόσθετα ορίσματα
+ # ή ορισμούς και να κάνεις override τις μεθόδους, όπως τον constructor.
+ # Αυτός ο constructor κληρονομεί το όρισμα "name" από την κλάση Human και
+ # προσθέτει τα ορίσματα "superpower" και "movie":
+ def __init__(self, name, movie=False,
+ superpowers=["super strength", "bulletproofing"]):
+
+ # πρόσθήκη επιπλέον attributes της κλάσης:
+ self.fictional = True
+ self.movie = movie
+ # έχετε το νου σας τις μεταβλητές (mutable) default τιμές, καθώς είναι κοινές
+ self.superpowers = superpowers
+
+ # Η συνάρτηση "super" επιτρέπει την πρόσβαση στις μεθόδους της κλάσης-γονέα
+ # που είναι υπερφορτωμένες από το παιδί. Σε αυτή την περίπτωση τη μέθοδο __init__
+ # Το παρακάτω καλεί τον constructor της κλάσης-γονέα:
+ super().__init__(name)
+
+ # υπερφόρτωση της μεθόδου sing
+ def sing(self):
+ return 'Dun, dun, DUN!'
+
+ # προσθήκη νέας μεθόδου που εφαρμόζεται σε στιγμιότυπα
+ def boast(self):
+ for power in self.superpowers:
+ print("I wield the power of {pow}!".format(pow=power))
+
+
+if __name__ == '__main__':
+ sup = Superhero(name="Tick")
+
+ # Έλεγχος για το αν το στιγμιότυπο sup ανήκει στην κλάση Human
+ if isinstance(sup, Human):
+ print('I am human')
+ if type(sup) is Superhero:
+ print('I am a superhero')
+# TODO:
+ # Παίρνουμε το Method Resolution search Order που χρησιμοποιούν οι getattr() και super()
+ # Αυτό το attribute είναι δυναμικό και μπορεί να ανανεωθεί
+ print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
+ # => <class 'human.Human'>, <class 'object'>)
+
+ # Καλούμε μέθοδο της κλάσης-γονέα, αλλά χρησιμοποιεί το δικό της attribute
+ print(sup.get_species()) # => Superhuman
+
+ # Καλεί την υπερφορτωμένη μέθοδο
+ print(sup.sing()) # => Dun, dun, DUN!
+
+ # Καλεί μέθοδο από την κλάση Human
+ sup.say('Spoon') # => Tick: Spoon
+
+ # Καλεί μέθοδο που υπάρχει μόνο στην κλάση Superhero
+ sup.boast() # => I wield the power of super strength!
+ # => I wield the power of bulletproofing!
+
+ # Κληρονομημένο class attribute
+ sup.age = 31
+ print(sup.age) # => 31
+
+ # Attribute που υπάρχει μόνο στην μέσα στην κλάση Superhero
+ print('Am I Oscar eligible? ' + str(sup.movie))
+
+####################################################
+## 6.2 Πολλαπλή Κληρονομικότητα - Multiple Inheritance
+####################################################
+
+# Ένας ακόμη ορισμός κλάσης
+# bat.py
+class Bat:
+
+ species = 'Baty'
+
+ def __init__(self, can_fly=True):
+ self.fly = can_fly
+
+ # Αυτή η κλάση έχει επίσης μία μέθοδο say
+ def say(self, msg):
+ msg = '... ... ...'
+ return msg
+
+ # Και τη δική της μέθοδο sonar
+ def sonar(self):
+ return '))) ... ((('
+
+if __name__ == '__main__':
+ b = Bat()
+ print(b.say('hello'))
+ print(b.fly)
+
+
+# Και ορίζουμε μία ακόμα κλάση που κληρονομεί από τις κλάσεις Superhero και Bat
+# superhero.py
+from superhero import Superhero
+from bat import Bat
+
+# Ας πούμε αυτή την κλάση Batman
+class Batman(Superhero, Bat):
+
+ def __init__(self, *args, **kwargs):
+ # Τυπικά γα να κληρονομήουμε attributes πρέπει να καλέσουμε τη super:
+ # super(Batman, self).__init__(*args, **kwargs)
+ # Ωστόσο έχουμε να κάνουμε με πολλαπλή κληρονομικότητα εδώ, και το super()
+ # δουλεύει μόνο με την αμέσως ανώτερη κλάση στην ιεραρχία.
+ # Οπότε, καλούμε ρητά την __init__ για όλους τους πρόγονους
+ # Η χρήση των *args και **kwargs επιτρέπει έναν καθαρό τρόπο για να περνάμε ορίσματα
+ # με κάθε κλάση-γονέα να "βγάζει μία φλούδα από το κρεμμύδι".
+ Superhero.__init__(self, 'anonymous', movie=True,
+ superpowers=['Wealthy'], *args, **kwargs)
+ Bat.__init__(self, *args, can_fly=False, **kwargs)
+ # υπερφορτώνουμε την τιμή του γνωρίσματος name
+ self.name = 'Sad Affleck'
+
+ def sing(self):
+ return 'nan nan nan nan nan batman!'
+
+
+if __name__ == '__main__':
+ sup = Batman()
+
+ #
+ # Λάβε το Method Resolution search Order που χρησιμοποιείται από το getattr() και το super().
+ # Αυτό το attribute είναι δυναμικό και μπορεί να ενημερωθεί
+ print(Batman.__mro__) # => (<class '__main__.Batman'>,
+ # => <class 'superhero.Superhero'>,
+ # => <class 'human.Human'>,
+ # => <class 'bat.Bat'>, <class 'object'>)
+
+ # Καλεί την μέθοδο της κλάσης-πατέρα αλλά χρησιμοποιεί το attribute της δικής του κλάσης
+ print(sup.get_species()) # => Superhuman
+
+ # Καλεί την υπερφορτωμένη μέθοδο
+ print(sup.sing()) # => nan nan nan nan nan batman!
+
+ # Καλεί μέθοδο από την κλάση Human, επειδή μετράει η σειρά της κληρονομιάς
+ sup.say('I agree') # => Sad Affleck: I agree
+
+ # Καλεί μέθοδο που ανήκει μόνο στον δεύτερο πρόγονο
+ print(sup.sonar()) # => ))) ... (((
+
+ # Attribute της κληρονομημένης κλάσης
+ sup.age = 100
+ print(sup.age) # => 100
+
+ # Κληρονομούμενο attribute από τον δεύτερο πρόγονο του οποίου η default τιμή
+ # έχει υπερφορτωθεί.
+ print('Can I fly? ' + str(sup.fly)) # => Can I fly? False
+
+
+
+####################################################
+## 7. Προχωρημένα
+####################################################
+
+# Με τους Generators μπορείς να γράψεις τεμπέλικο κώδικα.
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+# Οι Generators είναι αποδοτικοί από άποψη μνήμης επειδή φορτώνουν μόνο τα δεδομένα
+# που είναι αναγκαία για να επεξεργαστούμε την επόμενη τιμή του iterable.
+# Αυτό μας επιτρέπει να κάνουμε πράξεις σε τιμές που υπό άλλες συνθήκες θα ήταν
+# απαγορευτικά μεγάλες.
+for i in double_numbers(range(1, 900000000)): # το `range` είναι ένας generator.
+ print(i)
+ if i >= 30:
+ break
+
+# Όπως μπορείς να δημιουργήσεις list comprehension, έτσι μπορείς να δημιουργήσεις και
+# generator comprehensions
+values = (-x for x in [1,2,3,4,5])
+for x in values:
+ print(x) # τυπώνει -1 -2 -3 -4 -5 στο console/terminal
+
+# Μπορείς επίσης να μετατρέψεις ένα generator comprehension απευθείας σε λίστα.
+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
+# σε αυτό το παράδειγμα το `beg` τυλίγει το `say`. Αν το say_please είναι True τότε
+# θα αλλάξει το μήνυμα που επιστρέφεται.
+from functools import wraps
+
+
+def beg(target_function):
+ @wraps(target_function)
+ def wrapper(*args, **kwargs):
+ msg, say_please = target_function(*args, **kwargs)
+ if say_please:
+ return "{} {}".format(msg, "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 :(
+```
+
+## Έτοιμοι για περισσότερα?
+
+### Δωρεάν 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/el-gr/rust-gr.html.markdown b/el-gr/rust-gr.html.markdown
new file mode 100644
index 00000000..79f210ac
--- /dev/null
+++ b/el-gr/rust-gr.html.markdown
@@ -0,0 +1,339 @@
+---
+language: Rust
+contributors:
+ - ["P1start", "http://p1start.github.io/"]
+ - ["Dimitri Kokkonis", "https://github.com/kokkonisd"]
+filename: learnrust-gr.rs
+lang: el-gr
+---
+
+_[ΣτΜ.: οι όροι "χαμηλό/υψηλό επίπεδο" αναφέρονται στην εγγύτητα μιας γλώσσας προγραμματισμού ή γενικότερα ενός
+στοιχείου στην "μηχανή", ή το υλικό του υπολογιστή. Για παράδειγμα, η φράση "η C είναι μια γλώσσα χαμηλού επιπέδου"
+αναφέρεται στο γεγονός ότι η C επιτρέπει άμεση και λεπτομερή διαχείρηση μνήμης, και πιο άμεσο έλεγχο του επεξεργαστή·
+σε καμία περίπτωση δεν σημαίνει ότι η C έχει λιγότερες δυνατότητες, και γενικότερα δεν φέρει αρνητική σημασία.]_
+
+Η Rust είναι μια γλώσσα προγραμματισμού ανεπτυγμένη από την Mozilla Research.
+Συνδυάζει τον έλεγχο της απόδοσης χαμηλού επιπέδου με διευκολύνσεις και ασφάλεια υψηλού επιπέδου.
+
+Πετυχαίνει αυτούς τους στόχους χωρίς να χρειάζεται garbage collector ή runtime, το οποίο καθιστά δυνατή τη χρήση
+βιβλιοθηκών της Rust ως αντικατάσταση της C.
+
+Η έκδοση 0.1 (η πρώτη της Rust) δημοσιεύθηκε τον Ιανουάριο του 2012, και για τα επόμενα 3 χρόνια η ανάπτυξή της
+εξελίχθηκε τόσο γρήγορα που, μέχρι πρότινος, προτείνονταν η χρήση μη-σταθερών εκδόσεων (nightly builds) αντί σταθερών
+εκδόσεων.
+
+Τις 15 Μαΐου 2015 δημοσιεύτηκε η εκδοχή 1.0 της Rust, με πλήρη εγγύηση συμβατότητας με προηγούμενες εκδοχές. Οι
+μη-σταθερές εκδόσεις συνήθως περιλαμβάνουν γρηγορότερους χρόνους μεταγλώττισης και γενικότερες βελτιώσεις όσον αφορά
+τον μεταγλωττιστή. Η μέθοδος [train release](https://www.plutora.com/blog/agile-release-train) χρησιμοποιείται, με
+συστηματικές εκδόσεις να δημοσιεύονται κάθε έξι εβδομάδες. Η beta έκδοση της Rust 1.1 δημοσιεύθηκε ταυτοχρόνως με την
+σταθερή έκδοση 1.0.
+
+Αν και η Rust είναι μια γλώσσα σχετικά χαμηλού επιπέδου, ο σχεδιασμός της περιλαμβάνει κάποιες έννοιες που συναντώνται
+συνχότερα σε γλώσσες υψηλού επιπέδου. Αυτό καθιστά την Rust γρήγορη και αποδοτική αλλά επίσης εύκολη και προσβάσιμη.
+
+
+```rust
+// Αυτό είναι ένα σχόλιο. Τα σχόλια μίας γραμμής γράφονται έτσι...
+// Και επεκτείνονται σε περισσότερες από μία γραμμές έτσι.
+
+/// Τα σχόλια documentation γράφονται έτσι, και υποστηρίζουν markdown.
+/// # Παράδειγμα
+///
+/// ```
+/// let five = 5
+/// ```
+
+//////////////////////
+// 1. Βασικές αρχές //
+//////////////////////
+
+#[allow(dead_code)]
+// Συναρτήσεις
+// `i32` είναι ο τύπος που αντιστοιχεί στους 32-bit signed ακέραιους
+fn add2(x: i32, y: i32) -> i32 {
+ // Έμεσα εννοούμενη επιστροφή του αποτελέσματος, χωρίς semicolon (;)
+ x + y
+}
+
+#[allow(unused_variables)]
+#[allow(unused_assignments)]
+#[allow(dead_code)]
+// Συνάρτηση main
+fn main() {
+ // Αριθμοί //
+
+ // Αμετάβλητη σύνδεση
+ let x: i32 = 1;
+
+ // Καταλήξεις integer/float
+ let y: i32 = 13i32;
+ let f: f64 = 1.3f64;
+
+ // Εξακρίβωση τύπου (type inference)
+ // Τις περισσότερες φορες ο μεταγλωττιστής της Rust μπορεί να εξακριβώσει τον τύπο μιας μεταβλητής, επομένως δεν
+ // χρειάζεται ο προγραμματιστής να τον δηλώνει ρητά.
+ // Σε αυτό το tutorial, οι τύποι δηλώνονται ρητά σε διάφορα σημεία, αλλά μόνο προκειμένου να είναι πιο ευανάγνωστος
+ // ο κώδικας. Ο μεταγλωττιστής μπορεί να το διαχειριστεί αυτόματα στις περισσότερες περιπτώσεις.
+ let implicit_x = 1;
+ let implicit_f = 1.3;
+
+ // Πράξεις
+ let sum = x + y + 13;
+
+ // Μη-αμετάβλητη αξία (με την έννοια ότι μπορεί να αλλάξει)
+ let mut mutable = 1;
+ mutable = 4;
+ mutable += 2;
+
+ // Αλφαριθμητικά //
+
+ // Σταθερά αλφαριθμητικά
+ let x: &str = "καλημέρα κόσμε!";
+
+ // Εκτύπωση αλφαριθμητικών
+ println!("{} {}", f, x); // 1.3 καλημέρα κόσμε!
+
+ // A `String` – a heap-allocated string
+ let s: String = "καλημέρα κόσμε".to_string();
+
+ // Ένα κομμάτι αλφαριθμητικού (string slice) – μια μη-μεταβλητή οπτική γωνία προς ένα άλλο αλφαριθμητικό
+ // Το αλφαριθμητικό μπορεί να είναι στατικό όπως τα σταθερά αλφαριθμητικά, ή να περιλαμβάνεται σε ένα άλλο,
+ // δυναμικό αντικείμενο (σε αυτή την περίπτωση τη μεταβλητή `s`)
+ let s_slice: &str = &s;
+
+ println!("{} {}", s, s_slice); // καλημέρα κόσμε καλημέρα κόσμε
+
+ // Διανύσματα/πίνακες //
+
+ // Πίνακας σταθερού μεγέθους
+ let four_ints: [i32; 4] = [1, 2, 3, 4];
+
+ // Δυναμικός πίνακας (διάνυσμα)
+ let mut vector: Vec<i32> = vec![1, 2, 3, 4];
+ vector.push(5);
+
+ // Ένα κομμάτι – μια μη-μεταβλητή οπτική γωνία προς ένα διάνυσμα ή πίνακα
+ // Είναι παρόμοιο με το κομμάτι αλφαριθμητικού που είδαμε προηγουμένως
+ let slice: &[i32] = &vector;
+
+ // Μπορούμε να χρησιμοποιήσουμε το `{:?}` για να εκτυπώσουμε κάτι σε στυλ debug
+ println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
+
+ // Tuples (πλειάδες) //
+
+ // Ένα tuple είναι μια σταθερού μεγέθους σειρά από αξίες (πιθανά διαφορετικού τύπου)
+ let x: (i32, &str, f64) = (1, "καλημέρα", 3.4);
+
+ // Μπορούμε να χρησιμοποιήσουμε το `let` και ένα tuple για να δώσουμε πολλές αξίες σε πολλές μεταβλητές ταυτόχρονα
+ // (destructuring `let`)
+ let (a, b, c) = x;
+ println!("{} {} {}", a, b, c); // 1 καλημέρα 3.4
+
+ // Μπορούμε επίσης να επιλέξουμε ένα συγκεκριμένο στοιχείο από ένα tuple
+ println!("{}", x.1); // καλημέρα
+
+ //////////////
+ // 2. Τύποι //
+ //////////////
+
+ // Δομή
+ struct Point {
+ x: i32,
+ y: i32,
+ }
+
+ let origin: Point = Point { x: 0, y: 0 };
+
+ // Μια δομή με ανώνυμα πεδία, ή αλλιώς μια `δομή tuple` (`tuple struct`)
+ struct Point2(i32, i32);
+
+ let origin2 = Point2(0, 0);
+
+ // Enum, όπως στην C
+ enum Direction {
+ Left,
+ Right,
+ Up,
+ Down,
+ }
+
+ let up = Direction::Up;
+
+ // Enum με πεδία
+ enum OptionalI32 {
+ AnI32(i32),
+ Nothing,
+ }
+
+ let two: OptionalI32 = OptionalI32::AnI32(2);
+ let nothing = OptionalI32::Nothing;
+
+ // Γενικότητα (genericity) //
+
+ struct Foo<T> { bar: T }
+
+ // Αυτό ορίζεται στην standard library ως `Option`
+ enum Optional<T> {
+ SomeVal(T),
+ NoVal,
+ }
+
+ // Μέθοδοι //
+
+ impl<T> Foo<T> {
+ // Οι μέθοδοι παίρνουν πάντα μια ρητή παράμετρο `self`
+ fn bar(&self) -> &T { // Δανειζόμαστε το self
+ &self.bar
+ }
+ fn bar_mut(&mut self) -> &mut T { // Δανειζόμαστε το self ως μη-αμετάβλητη αξία
+ &mut self.bar
+ }
+ fn into_bar(self) -> T { // Εδώ το self καταναλώνεται
+ self.bar
+ }
+ }
+
+ let a_foo = Foo { bar: 1 };
+ println!("{}", a_foo.bar()); // 1
+
+ // Χαρακτηρηστικά (traits) (γνωστά ως interfaces ή typeclasses σε άλλες γλώσσες) //
+
+ trait Frobnicate<T> {
+ fn frobnicate(self) -> Option<T>;
+ }
+
+ impl<T> Frobnicate<T> for Foo<T> {
+ fn frobnicate(self) -> Option<T> {
+ Some(self.bar)
+ }
+ }
+
+ let another_foo = Foo { bar: 1 };
+ println!("{:?}", another_foo.frobnicate()); // Some(1)
+
+ //////////////////////////////////////////////////
+ // 3. Αντιστοιχίσεις Μοτίβων (Pattern Matching) //
+ //////////////////////////////////////////////////
+
+ let foo = OptionalI32::AnI32(1);
+ match foo {
+ OptionalI32::AnI32(n) => println!("Είναι ένα i32: {}", n),
+ OptionalI32::Nothing => println!("Δεν είναι τίποτα!"),
+ }
+
+ // Προχωρημένο pattern matching
+ struct FooBar { x: i32, y: OptionalI32 }
+ let bar = FooBar { x: 15, y: OptionalI32::AnI32(32) };
+
+ match bar {
+ FooBar { x: 0, y: OptionalI32::AnI32(0) } =>
+ println!("Οι αριθμοί είναι μηδέν!"),
+ FooBar { x: n, y: OptionalI32::AnI32(m) } if n == m =>
+ println!("Οι αριθμοί είναι οι ίδιοι"),
+ FooBar { x: n, y: OptionalI32::AnI32(m) } =>
+ println!("Διαφορετικοί αριθμοί: {} {}", n, m),
+ FooBar { x: _, y: OptionalI32::Nothing } =>
+ println!("Ο δεύτερος αριθμός δεν είναι τίποτα!"),
+ }
+
+ /////////////////////
+ // 4. Έλεγχος ροής //
+ /////////////////////
+
+ // Βρόγχοι `for`
+ let array = [1, 2, 3];
+ for i in array.iter() {
+ println!("{}", i);
+ }
+
+ // Διαστήματα
+ for i in 0u32..10 {
+ print!("{} ", i);
+ }
+ println!("");
+ // Τυπώνει `0 1 2 3 4 5 6 7 8 9 `
+
+ // Βρόγχοι `if`
+ if 1 == 1 {
+ println!("Τα μαθηματικά δουλεύουν!");
+ } else {
+ println!("Ωχ όχι...");
+ }
+
+ // `if` ως έκφραση
+ let value = if true {
+ "καλό"
+ } else {
+ "κακό"
+ };
+
+ // Βρόγχοι `while`
+ while 1 == 1 {
+ println!("Το σύμπαν λειτουργεί κανονικά.");
+ // Μπορούμε να βγούμε από το βρόγχο με το `break`
+ break
+ }
+
+ // Ατέρμονος βρόχγος
+ loop {
+ println!("Καλημέρα!");
+ // Μπορούμε να βγούμε από το βρόγχο με το `break`
+ break
+ }
+
+ //////////////////////////////////
+ // 5. Ασφάλεια μνήμης & δείκτες //
+ //////////////////////////////////
+
+ // Δείκτης με ιδιοκτήτη – μόνο ένα αντικείμενο μπορεί να είναι ο "ιδιοκτήτης" αυτού του δείκτη ανά πάσα στιγμή
+ // Αυτό σημαίνει ότι μόλις το `Box` βγει εκτός πλαισίου (out of scope), ο δείκτης μπορεί να ελευθερωθεί με ασφάλεια
+ let mut mine: Box<i32> = Box::new(3);
+ *mine = 5; // Dereference του δείκτη
+ // Εδώ, το `now_its_mine` γίνεται ιδιοκτήτης του `mine`. Δηλαδή, το `mine` μετακινείται.
+ let mut now_its_mine = mine;
+ *now_its_mine += 2;
+
+ println!("{}", now_its_mine); // 7
+ // println!("{}", mine); // Αυτό παράγει λάθος κατά τη μεταγλώττιση διότι τώρα ο δείκτης ανοίκει στο `now_its_mine`
+
+ // Reference (αναφορά) – ένας αμετάβλητος δείκτης που αναφέρεται σε άλλα δεδομένα
+ // Όταν μια αναφορά δίνεται σε μια αξία, λέμε πως η αξία έχει "δανειστεί".
+ // Όταν μια αξία δανείζεται αμετάβλητα, δεν μπορεί να είναι mutated (να μεταβληθεί) ή να μετακινηθεί.
+ // Ένας "δανεισμός" παραμένει ενεργός μέχρι την τελευταία χρήση της μεταβλητής που δανείζεται.
+ let mut var = 4;
+ var = 3;
+ let ref_var: &i32 = &var;
+
+ println!("{}", var); // Αντίθετα με το `mine` προηγουμένως, η μεταβλητή `var` μπορεί ακόμα να χρησιμοποιηθεί
+ println!("{}", *ref_var);
+ // var = 5; // Αυτό παράγει λάθος κατά τη μεταγλώττιση γιατί η μεταβλητή `var` είναι δανεισμένη
+ // *ref_var = 6; // Το ίδιο εδώ, γιατί η `ref_var` αποτελεί αμετάβλητη αναφορά
+ ref_var; // Εντολή no-op (τίποτα δεν εκτελείται από τον επεξεργαστή), η οποία όμως μετράει ως χρήση και κρατά τον
+ // "δανεισμό" ενεργό
+ var = 2; // Η `ref_var` δεν χρησιμοποιείται από εδώ και στο εξής, άρα ο "δανεισμός" τελειώνει
+
+ // Μεταβλητή αναφορά
+ // Όσο μια αξία είναι μεταβλητά δανεισμένη, παραμένει τελείως απροσβάσιμη.
+ let mut var2 = 4;
+ let ref_var2: &mut i32 = &mut var2;
+ *ref_var2 += 2; // Ο αστερίσκος (*) χρησιμοποιείται ως δείκτης προς την μεταβλητά δανεισμένη `var2`
+
+ println!("{}", *ref_var2); // 6 , // Αν είχαμε `var2` εδώ θα προκαλούνταν λάθος μεταγλώττισης.
+ // O τύπος της `ref_var2` είναι &mut i32, άρα αποθηκεύει μια αναφορά προς μια αξία i32, όχι την αξία την ίδια.
+ // var2 = 2; // Λάθος μεταγλώττισης, γιατί η `var2` είναι δανεισμένη.
+ ref_var2; // Εντολή no-op (τίποτα δεν εκτελείται από τον επεξεργαστή), η οποία όμως μετράει ως χρήση και κρατά τον
+ // "δανεισμό" ενεργό
+}
+```
+
+## Μάθετε περισσότερα
+
+Υπάρχουν πολλά ακόμα πράγματα να μάθει κανείς· αυτά είναι μόνο τα βασικά της Rust, που επιτρέπουν να καταλάβουμε το
+βασικό τρόπο λειτουργίας της. Για να μάθετε περισσότερα για τη Rust, διαβάστε το [The Rust Programming
+Language](http://doc.rust-lang.org/book/index.html) και επισκεφθείτε το subreddit [/r/rust](http://reddit.com/r/rust).
+Οι άνθρωποι πίσω από το κανάλι #rust στο irc.mozilla.org είναι επίσης πάντα πρόθυμοι να βοηθήσουν τους αρχάριους.
+
+Μπορείτε επίσης να παίξετε με τη Rust χρησιμοποιώντας τους εξής online μεταγλωττιστές:
+
+- [Rust playpen](http://play.rust-lang.org)
+- [Rust website](http://rust-lang.org)
diff --git a/el-gr/vim-gr.html.markdown b/el-gr/vim-gr.html.markdown
new file mode 100644
index 00000000..679a5488
--- /dev/null
+++ b/el-gr/vim-gr.html.markdown
@@ -0,0 +1,267 @@
+---
+category: tool
+tool: vim
+contributors:
+ - ["RadhikaG", "https://github.com/RadhikaG"]
+filename: LearnVim.txt
+lang: el-gr
+---
+
+
+[Vim](http://www.vim.org)
+To (Vi IMproved) είναι ένας κλώνος του δημοφιλούς vi editor για Unix.
+Είναι ένας text editor σχεδιασμένος για ταχύτητα και αυξημένη παραγωγικότητα,
+και υπάρχει σχεδόν σε όλα τα Unix-based συστήματα. Έχει διάφορα keybindings
+(συντομεύσεις πλήκτρων) για να πλοηγούμαστε γρήγορα σε συγκεκριμένα σημεία ενός αρχείου,
+καθώς και για γρήγορη επεξεργασία.
+
+## Τα βασικά της πλοήγησης στον Vim
+
+```
+ vim <filename> # Άνοιξε το <filename> στον vim
+ :help <topic> # Άνοιξε το built-in βοήθημα για το <topic> αν υπάρχει
+ :q # Βγες από τον vim
+ :w # Αποθήκευσε το τρέχον αρχείο
+ :wq # Αποθήκευσε το τρέχον αρχείο και βγες από τον vim
+ ZZ # Αποθήκευσε το τρέχον αρχείο και βγες από τον vim
+ :q! # Βγες χωρίς αποθήκευση
+ # ! *αναγκάζει* το :q να εκτελεστεί, γι αυτό βγαίνει χωρίς saving
+ :x # Ίδιο με το wq αλλά πιο σύντομο
+
+ u # Undo
+ CTRL+R # Redo
+
+ h # Μετακινήσου κατά ένα χαρακτήρα αριστερά
+ j # Μετακινήσου μια γραμμή κάτω
+ k # Μετακινήσου μια γραμμή πάνω
+ l # Μετακινήσου μια γραμμή δεξιά
+
+ Ctrl+B # Πήγαινε μία οθόνη πίσω
+ Ctrl+F # Πήγαινε μία οθόνη μπροστά
+ Ctrl+U # Πήγαινε μισή οθόνη πίσω
+ Ctrl+D # Πήγαινε μισή οθόνη μπροστά
+
+ # Μετακινήσεις στην ίδια γραμμή
+
+ 0 # Πήγαινε στην αρχή της γραμμής
+ $ # Πήγαινε στο τέλος της γραμμής
+ ^ # Πήγαινε στον πρώτο μη κενό χαρακτήρα της γραμμής
+
+ # Αναζήτηση στο κείμενο
+
+ /word # Υπογραμμίζει όλες τις εμφανίσεις της λέξης μετά τον cursor
+ ?word # Υπογραμμίζει όλες τις εμφανίσεις της λέξης πριν τον cursor
+ n # Μετακινεί τον cursor στην επόμενη εμφάνιση της λέξης
+ N # Μετακινεί τον cursor στην προηγούμενη εμφάνιση της λέξης
+
+ :%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 # Πήγαινε στο κάτω άκρο της σελίδας
+```
+
+## Help docs:
+Το Vim έχει built-in help documentation που μπορείς να δεις με `:help <topic>`.
+Για παράδειγμα το `:help navigation` θα σου εμφανίσει documentation σχετικό με
+το πως να πλοηγείσαι στο αρχείο!
+
+To `:help` μπορεί να χρησιμοποιηθεί και χωρίς option. Αυτό θα εμφανίσει το default
+help dialog που σκοπεύει να κάνει το vim πιο προσιτό σε αρχάριους!
+
+## Modes:
+
+O Vim στηρίζεται στο concept των **modes**.
+
+- Command Mode - ο vim εκκινεί σε αυτό mode, χρησιμοποιείται για πλοήγηση και εντολές
+- Insert Mode - χρησιμοποιείται για να κάνουμε αλλαγές στα αρχεία
+- Visual Mode - χρησιμοποιείται για να υπογραμμίζουμε κείμενα και να κάνουμε διάφορα σε αυτά
+- Ex Mode - χρησιμοποιείται για να πάμε στο κάτω μέρος με το ':' που δίνουμε εντολές
+
+```
+ i # Βάζει το vim σε insert mode, πριν τη θέση cursor
+ a # Βάζει το vim σε insert mode, μετά τη θέση cursor
+ v # βάζει τον vim σε visual mode
+ : # Βάζει τον vim σε ex mode
+ <esc> # φεύγει από όποιο mode είμαστε και πάει σε command mode
+
+ # Αντιγραφή-Επικόληση κειμένου
+
+ y # Yank (κάνε copy) ό,τι είναι επιλεγμένο
+ yy # Yank την γραμμή στην οποία είσαι
+ d # διάγραψε ό,τι είναι επιλεγμένο
+ dd # Διάγραψε τη γραμμή στην οποία είσαι
+ p # Κάνε Paste το αντεγραμένο κείμενο μετά την θέση του cursor
+ P # Κάνε Paste το αντεγραμένο κείμενο πριν την θέση του cursor
+ x # Διάγραψε τον χαρακτήρα που είναι κάτω από τον cursor
+```
+
+## Η 'γραμματική' του Vim
+
+Μπορείς να σκεφτείς τον Vim ως ένα σύνολο εντολών
+σε μορφή 'Verb-Modifier-Noun', όπου
+
+- Verb - η ενέργεια που θες να κάνεις
+- Modifier - πώς κάνεις την ενέργεια
+- Noun - το αντικείμενο που δέχεται την ενέργεια
+
+Μερικά παραδείγματα ''Ρημάτων', 'Modifiers' και 'Ουσιαστικών':
+
+```
+ # 'Ρήματα'
+
+ d # Διάγραψε
+ c # Άλλαξε
+ y # Yank (αντίγραψε)
+ v # Επίλεξε οπτικά
+
+ # 'Modifiers'
+
+ i # Μέσα
+ a # Γύρω
+ NUM # Αριθμός (NUM = οποιοσδήποτε αριθμός)
+ f # Ψάξε κάτι και πήγαινε εκεί που βρίσκεται
+ t # Ψάξε κάτι και πήγαινε πριν από εκεί που βρίσκεται
+ / # Βρες κάποιο string μετά από τον cursor
+ ? # Βρες κάποιο string πριν τον cursor
+
+ # 'Ουσιαστικά'
+
+ w # Λέξη
+ s # Πρόταση
+ p # Παράγραφος
+ b # Block
+
+ # Δείγματα 'προτάσεων' ή εντολών
+
+ d2w # Διάγραψε 2 λέξεις
+ cis # Άλλαξε μέσα στην πρώταση
+ yip # Αντίγραψε την παράγραφο στην οποία βρίσκεσαι
+ ct< # Άλλαξε σε <
+ # Άλλαξε το κείμενο από το οποίο είσαι πριν το επόμενο bracketChange the text from where you are to the next open bracket
+ d$ # Διάγραψε μέχρι το τέλος της γραμμής
+```
+
+## Μερικά shortcuts και κόλπα
+
+ <!--TODO: Βάλτε κι άλλα!-->
+```
+ > # Στοίχισε προς τα δεξιά την επιλογή σου κατά ένα block
+ < # Στοίχισε προς τα αριστερά την επιλογή σου κατά ένα block
+ :earlier 15m # Κάνε το αρχείο όπως ήταν πριν 15 λεπτά
+ :later 15m # Ακύρωση για την παραπάνω εντολή
+ ddp # Αντάλλαξε τις θέσεις διαδοχικών γραμμών
+ . # Επανάλαβε την προηγούμενη ενέργεια
+ :w !sudo tee % # Σώσε το τρέχον αρχείο ως root
+ :set syntax=c # Κάνε syntax highlighting για τη γλώσσα c
+ :sort # Ταξινόμησε όλες τις γραμμές
+ :sort! # Ταξινόμησε ανάποδα όλες τις γραμμές (αύξουσα σειρά)
+ :sort u # Ταξινόμησε όλες τις γραμμές και διάγραψε τις διπλές γραμμές
+ ~ # Άλλαξε τα κεφαλαία σε μικρά στο επιλεγμένο κείμενο
+ u # Το επιλεγμένο κείμενο να γίνει πεζά γράμματα
+ U # Το επιλεγμένο κείμενο να γίνει κεφαλαία γράμματα
+
+ # Fold text
+ zf # Διπλώνει (συμπιέζει τις γραμμές σε μία) το επιλεγμένο κείμενο
+ zo # Ξεδιπλώνει το επιλεγμένο fold
+ zc # Κλείνει το επιλεγμένο fold
+ zR # Ανοίγει όλα τα folds
+ zM # Κλείνει όλα τα folds
+```
+
+## Macros
+
+Τα macros βασικά είναι καταγραφή ενεργειών.
+Όταν ξεικάς να καταγράφεις ένα macro καταγράφονται **όλες** οι ενέργεις και οι
+εντολές που χρησιμοποιείς, μέχρι να σταματήσεις την καταγραφή. Όταν καλείς ένα macro,
+εκτελείται πάλι η ίδια σειρά από ενέργειες και εντολές στο επιλεγμένο κείμενο.
+
+```
+ qa # Ξεκίνα να καταγράφεις ένα macro που θα ονομαστεί 'a'
+ q # Σταμάτα την καταγραφή
+ @a # Τρέξε το macro
+```
+
+### Configuring ~/.vimrc
+
+Το αρχείο .vimrc μπορεί να χρησιμοποιηθεί για να κάνεις configure το Vim στο startup.
+
+Εδώ βλέπουμε δείγμα ενός ~/.vimrc file:
+
+```
+" Example ~/.vimrc
+" 2015.10
+
+" Required for vim to be iMproved
+set nocompatible
+
+" Determines filetype from name to allow intelligent auto-indenting, etc.
+filetype indent plugin on
+
+" Enable syntax highlighting
+syntax on
+
+" Better command-line completion
+set wildmenu
+
+" Use case insensitive search except when using capital letters
+set ignorecase
+set smartcase
+
+" When opening a new line and no file-specific indenting is enabled,
+" keep same indent as the line you're currently on
+set autoindent
+
+" Display line numbers on the left
+set number
+
+" Indentation options, change according to personal preference
+
+" Number of visual spaces per TAB
+set tabstop=4
+
+" Number of spaces in TAB when editing
+set softtabstop=4
+
+" Number of spaces indented when reindent operations (>> and <<) are used
+set shiftwidth=4
+
+" Convert TABs to spaces
+set expandtab
+
+" Enable intelligent tabbing and spacing for indentation and alignment
+set smarttab
+```
+
+### Αναφορές
+
+[Vim | Home](http://www.vim.org/index.php)
+
+`$ vimtutor`
+
+[A vim Tutorial and Primer](https://danielmiessler.com/study/vim/)
+
+[What are the dark corners of Vim your mom never told you about? (Stack Overflow thread)](http://stackoverflow.com/questions/726894/what-are-the-dark-corners-of-vim-your-mom-never-told-you-about)
+
+[Arch Linux Wiki](https://wiki.archlinux.org/index.php/Vim)
diff --git a/elisp.html.markdown b/elisp.html.markdown
index c88d97f0..f839dac0 100644
--- a/elisp.html.markdown
+++ b/elisp.html.markdown
@@ -1,7 +1,7 @@
---
language: elisp
contributors:
- - ["Bastien Guerry", "http://bzg.fr"]
+ - ["Bastien Guerry", "https://bzg.fr"]
- ["Saurabh Sandav", "http://github.com/SaurabhSandav"]
filename: learn-emacs-lisp.el
---
@@ -9,8 +9,6 @@ filename: learn-emacs-lisp.el
```scheme
;; This gives an introduction to Emacs Lisp in 15 minutes (v0.2d)
;;
-;; Author: Bastien / @bzg2 / http://bzg.fr
-;;
;; First make sure you read this text by Peter Norvig:
;; http://norvig.com/21-days.html
;;
@@ -225,6 +223,8 @@ filename: learn-emacs-lisp.el
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Let's store a list of names:
+;; If you want to create a literal list of data, use ' to stop it from
+;; being evaluated - literally, "quote" the data.
(setq list-of-names '("Sarah" "Chloe" "Mathilde"))
;; Get the first element of this list with `car':
@@ -281,7 +281,7 @@ filename: learn-emacs-lisp.el
;; should stop searching at some point in the buffer, and whether it
;; should silently fail when nothing is found:
-;; (search-forward "Hello" nil 't) does the trick:
+;; (search-forward "Hello" nil t) does the trick:
;; The `nil' argument says: the search is not bound to a position.
;; The `'t' argument says: silently fail when nothing is found.
@@ -295,18 +295,18 @@ filename: learn-emacs-lisp.el
(mapcar 'hello list-of-names)
(goto-char (point-min))
;; Replace "Hello" by "Bonjour"
- (while (search-forward "Hello" nil 't)
+ (while (search-forward "Hello" nil t)
(replace-match "Bonjour"))
(other-window 1))
(hello-to-bonjour)
-;; Let's colorize the names:
+;; Let's boldify the names:
(defun boldify-names ()
(switch-to-buffer-other-window "*test*")
(goto-char (point-min))
- (while (re-search-forward "Bonjour \\(.+\\)!" nil 't)
+ (while (re-search-forward "Bonjour \\(.+\\)!" nil t)
(add-text-properties (match-beginning 1)
(match-end 1)
(list 'face 'bold)))
@@ -342,13 +342,4 @@ filename: learn-emacs-lisp.el
;;
;; To read an online introduction to Emacs Lisp:
;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html
-
-;; Thanks to these people for their feedback and suggestions:
-;; - Wes Hardaker
-;; - notbob
-;; - Kevin Montuori
-;; - Arne Babenhauserheide
-;; - Alan Schmitt
-;; - LinXitoW
-;; - Aaron Meurer
```
diff --git a/elixir.html.markdown b/elixir.html.markdown
index 63b7aef2..8b80c582 100644
--- a/elixir.html.markdown
+++ b/elixir.html.markdown
@@ -1,9 +1,10 @@
---
language: elixir
contributors:
- - ["Joao Marques", "http://github.com/mrshankly"]
+ - ["Joao Marques", "https://github.com/mrshankly"]
- ["Dzianis Dashkevich", "https://github.com/dskecse"]
- ["Ryan Plant", "https://github.com/ryanplant-au"]
+ - ["Ev Bogdanov", "https://github.com/evbogdanov"]
filename: learnelixir.ex
---
@@ -127,7 +128,8 @@ rem(10, 3) #=> 1
# These operators expect a boolean as their first argument.
true and true #=> true
false or true #=> true
-# 1 and true #=> ** (ArgumentError) argument error
+# 1 and true
+#=> ** (BadBooleanError) expected a boolean on left-side of "and", got: 1
# Elixir also provides `||`, `&&` and `!` which accept arguments of any type.
# All values except `false` and `nil` will evaluate to true.
@@ -285,7 +287,11 @@ end
PrivateMath.sum(1, 2) #=> 3
# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
-# Function declarations also support guards and multiple clauses:
+# Function declarations also support guards and multiple clauses.
+# When a function with multiple clauses is called, the first function
+# that satisfies the clause will be invoked.
+# Example: invoking area({:circle, 3}) will call the second area
+# function defined below, not the first:
defmodule Geometry do
def area({:rectangle, w, h}) do
w * h
@@ -433,11 +439,11 @@ self() #=> #PID<0.27.0>
# Create an agent with `Agent.start_link`, passing in a function
# The initial state of the agent will be whatever that function returns
-{ok, my_agent} = Agent.start_link(fn -> ["red, green"] end)
+{:ok, my_agent} = Agent.start_link(fn -> ["red", "green"] end)
# `Agent.get` takes an agent name and a `fn` that gets passed the current state
# Whatever that `fn` returns is what you'll get back
-Agent.get(my_agent, fn colors -> colors end) #=> ["red, "green"]
+Agent.get(my_agent, fn colors -> colors end) #=> ["red", "green"]
# Update the agent's state the same way
Agent.update(my_agent, fn colors -> ["blue" | colors] end)
@@ -445,9 +451,10 @@ Agent.update(my_agent, fn colors -> ["blue" | colors] end)
## References
-* [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/)
+* [Getting started guide](https://elixir-lang.org/getting-started/introduction.html) from the [Elixir website](https://elixir-lang.org)
+* [Elixir Documentation](https://elixir-lang.org/docs.html)
* ["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
+* [Elixir Cheat Sheet](https://media.pragprog.com/titles/elixir/ElixirCheat.pdf)
+* ["Learn You Some Erlang for Great Good!"](https://learnyousomeerlang.com/) by Fred Hebert
* ["Programming Erlang: Software for a Concurrent World"](https://pragprog.com/book/jaerlang2/programming-erlang) by Joe Armstrong
+* [Introduction to Elixir](https://learn-elixir.com/)
diff --git a/elm.html.markdown b/elm.html.markdown
index 96554e84..ad80adc9 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.
@@ -72,8 +72,8 @@ List.head [] -- Nothing
-- Access the elements of a pair with the first and second functions.
-- (This is a shortcut; we'll come to the "real way" in a bit.)
-fst ("elm", 42) -- "elm"
-snd ("elm", 42) -- 42
+Tuple.first ("elm", 42) -- "elm"
+Tuple.second ("elm", 42) -- 42
-- The empty tuple, or "unit", is sometimes used as a placeholder.
-- It is the only value of its type, also called "Unit".
@@ -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 =
@@ -286,7 +286,7 @@ leftmostElement tree =
-- Put this at the top of the file. If omitted, you're in Main.
module Name where
--- By default, everything is exported. You can specify exports explicity.
+-- By default, everything is exported. You can specify exports explicitly.
module Name (MyType, myValue) where
-- One common pattern is to export a union type but not its tags. This is known
@@ -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/emacs.html.markdown b/emacs.html.markdown
new file mode 100644
index 00000000..ff4d3c03
--- /dev/null
+++ b/emacs.html.markdown
@@ -0,0 +1,320 @@
+---
+category: tool
+tool: emacs
+filename: emacs.txt
+contributors:
+ - ["Joseph Riad", "https://github.com/Joseph-Riad"]
+---
+
+Emacs started its life as ["the extensible, customizable display
+editor"](https://www.gnu.org/software/emacs/emacs-paper.html) and grew
+over the years into a full-blown ecosystem. Many tasks, usually
+relegated to a diverse set of tools can be accomplished from within
+Emacs in a consistent, familiar interface. Examples include directory
+management, viewing PDF documents, editing files over SSH, managing git
+repos,… (the list is quite long). In short, Emacs is yours to make of it
+what you will: the spectrum of users varies from those who use it to
+edit text files to extreme purists who use it to virtually replace their
+operating system.
+
+Emacs is extensible via a specialized dialect of Lisp known as Emacs
+Lisp (Elisp) which has a lot of macros geared towards editing text and
+managing text buffers. Any key (combination) you use in Emacs is bound
+to an Emacs Lisp function and may be remapped to any other function,
+including ones you write
+yourself.
+
+# Key Notation
+
+``` text
+The Emacs manual and the community in general uses a convention to refer to different key combinations used within Emacs. Specifically, Emacs has the notion of a "modifier key" that is pressed along with another key to modify its action.
+
+An example of this notation is "C-c". In this key combination "C" is the modifier and stands for the "Ctrl" key and "c" is the key whose action is being modified (the literal character "c").
+
+The modifier shorthand:
+"C-" --> The "CTRL" key
+"M-" --> The "Meta" key (usually, the "Alt" key)
+"s-" --> The "Super" key (the "Cmd" key on Macs and the "Windows" key on PCs)
+
+There are other, less commonly used modifiers that I will not get into here.
+
+The key combination "C-x C-s" means you press "Ctrl+x" followed by "Ctrl+s"
+
+In addition to the above modifiers, the special keys "Esc", "Return (Enter)" and "Shift" are denoted by "ESC", "RET" and "S", respectively.
+```
+
+# Basic Emacs Concepts
+
+Here, I discuss some basic Emacs concepts and terminology that may be
+confusing to newcomers (especially to people used to Vim terminology)
+
+ - A bunch of text that Emacs is editing is known as a **buffer**
+ - A buffer does not necessarily correspond to an actual file on disk.
+ It may be just a bunch of text in memory.
+ - When a buffer corresponds to a file on disk, we say that the buffer
+ is **visiting** that file.
+ - Emacs typically has many buffers open at once.
+ - The display of Emacs may be split into different **windows** (not to
+ be confused with your operating system's windows: the operating
+ system window for Emacs can have multiple Emacs windows inside it).
+ - An operating system window for Emacs is called an Emacs **frame**.
+ Thus, when the Emacs manual talks about opening a new frame, this
+ essentially means opening a new OS *window* containing an(other)
+ instance of Emacs.
+ - The concepts conventionally known as cutting and pasting are
+ referred to as **killing** and **yanking**, respectively in Emacs
+ parlance.
+ - The current position of the cursor is called the **point** in Emacs.
+ Technically, **point** is defined as the position right before the
+ character where the cursor currently is.
+ - Finally, each buffer may have several **modes** associated with it:
+ a **major mode** and possibly several **minor modes**.
+ - The **major mode** defines the main behavior of Emacs in the
+ currently selected buffer. This can be roughly thought of as the
+ file type. For example, if you're editing a Python file, the major
+ mode is (by default) `python-mode` which causes Emacs to highlight
+ Python syntax and automatically indent and outdent your code blocks
+ as syntactically required by your Python code.
+ - **Minor modes** define subtle changes in behavior and several minor
+ modes may be active at once in the same buffer. An example minor
+ mode is `flyspell-mode` which automatically highlights spelling
+ errors in your
+buffer.
+
+# Navigation Basics
+
+``` text
+The GUI version of Emacs can be navigated with the mouse like you would expect from a conventional GUI text editor.
+
+The aim here is to focus on navigation solely using the keyboard as this enhances productivity immensely.
+
+
+* Line movement
+
+C-n --> Next line
+C-p --> Previous line
+
+* Character movement
+
+C-f --> Go forward one character
+C-b --> Go backward one character
+
+* Word movement
+
+M-f --> Go forward one word
+M-b --> Go backward one word
+
+* Sentence movement
+
+M-a --> Move to the beginning of the sentence
+M-e --> Move to the end of the sentence
+
+* Beginning and end of line
+
+C-a --> Move to the beginning of the line
+C-e --> Move to the end of the line
+
+* Beginning and end of buffer
+
+M-< ("Meta+Shift+,") --> Go to the beginning of the buffer
+M-> ("Meta+Shift+.") --> Go to the end of the buffer
+
+* Screen movement
+
+C-v --> Scroll down by one screen-full (the last two lines of the previous screen are kept as overlap for a smoother transition)
+M-v --> Scroll up by one screen-full (same as above but with the first two lines)
+
+* Centering the screen
+
+C-l --> Move current line to the screen's center
+
+The above key combination actually cycles through different states depending on how many times it's been pressed.
+
+C-l --> Move current line to the screen's center
+C-l C-l --> Move current line to the top of the screen
+C-l C-l C-l --> Restore the position of the current line to where it was before the first C-l was pressed
+
+If you press "C-l" a 4th time, it cycles back to centering the current line.
+
+* Repeating movement commands
+
+Most movement commands take a numerical prefix argument that says "repeat the following command that many times".
+
+Example:
+
+C-u 3 C-p --> Go up 3 lines
+C-u 5 C-f --> Go forward 5 characters
+
+One notable exception are the screen scrolling commands:
+
+C-u 3 C-v --> Scroll downward 3 lines (maintaining the position of the cursor)
+```
+
+Bonus: many of the above navigation commands are the default navigation
+commands in Bash (e.g. pressing "C-b" while entering a Bash command
+takes you back one
+character).
+
+# File editing basics
+
+``` text
+* Quitting Emacs [ Now you can't say you don't know how to quit Emacs :-) ]
+
+C-x C-c --> Quit Emacs and get prompted to save any unsaved files (buffers not visiting a file will simply be discarded unless you're running in client-server mode)
+
+* Saving a buffer
+
+C-x C-s --> Save the current buffer. If not visiting a file, it will prompt you for a file name to use to save the buffer.
+
+* Searching within a buffer
+
+C-s --> Search forwards within the buffer. Search is incremental and case-insensitive by default.
+ Press C-s to move to the next match.
+ If you press "RET", point is moved to the currently highlighted word and the search ends.
+C-r --> Same as C-s except it searches backward
+
+C-_ or C-/ --> Undo the last action. Keep pressing it to move up the undo tree.
+C-? or M-_ --> Redo the previous change
+
+The "undo" and "redo" commands can take prefix numerical arguments to undo or redo that many actions:
+
+C-u 3 C-_ --> Undo the last 3 changes.
+```
+
+# Executing Elisp Functions
+
+``` text
+You can execute any currently loaded Elisp functions (including ones you have written yourself) via "M-x"
+
+M-x RET --> Prompts you for name of function to execute (Tab completion is available).
+
+Example:
+
+M-x RET search-forward-regexp RET --> Prompts you for a regular expression and searches forward in the buffer for it
+```
+
+# Emacs Configuration
+
+Emacs is configured using Elisp. On startup, it looks for a
+configuration file either in `~/.emacs` or `~/.emacs.d/init.el` where
+`~` refers to your home directory. If you're on Windows, consult [this
+article](https://www.gnu.org/software/emacs/manual/html_node/efaq-w32/Location-of-init-file.html)
+for the appropriate location of your configuration file.
+
+# Vim inside Emacs
+
+If you are considering the transition from Vim to Emacs and you're put
+off by the non-modal nature of Emacs editing, there is an Emacs
+extension known as `evil-mode` which lets you have many Vim concepts
+inside Emacs. Here are some things added to Emacs by `evil-mode`:
+
+ - Modal editing: you get normal, insert, visual and block visual modes
+ like Vim. In addition, you get an "Emacs" mode where movement and
+ navigation follow the Emacs bindings.
+ - Same movement keys as Vim in normal mode
+ - Leader key combinations
+ - Pressing ":" in normal mode allows you to execute commands
+ (including system commands)
+
+In my own experience, `evil-mode` helps make the transition seamless and
+allows you to blend the arguably more intuitive and ergonomic
+keybindings of Vim with the unbridled power of Emacs for a truly
+superior editing experience.
+
+# Discoverable Help
+
+Emacs features a pretty powerful help system that allows you to discover
+new functionality all the
+time.
+
+``` text
+Obtaining help on specific topics. Tab completion is available for function and variable names.
+
+C-h f RET --> Prompts you for the name of an elisp function and
+ displays help text on it along with a clickable link
+ to its source code.
+C-h v RET --> Same as above with variables
+
+C-h k RET --> Allows you to enter a key combination and displays the
+ name of the elisp function bound to it.
+
+Searching for help:
+
+C-h a --> Prompts you for a string to search for a command in the
+ help system. Similar to the 'apropos' or 'man -k'
+ commands in Unix systems.
+
+Starting a tutorial:
+
+C-h C-t --> Starts a tutorial designed to familiarize you with
+ basic Emacs functionality.
+```
+
+# Emacs "Killer Apps"
+
+As I hinted above, Emacs functionality goes way beyond being a mere text
+editor. I will list here a couple of Emacs "apps" that are fairly
+powerful and popular and may interest you in and of themselves.
+
+## Org
+
+Technnically, `org-mode`, a major mode for buffer editing that provides
+organizational tools. It is very difficult to succinctly describe what
+Org can do because it's a behemoth of a tool that has many diverse uses
+to different people. I will attempt to describe the main features I use
+briefly.
+
+ - Divide your file into sections and sub-sections for easy outlining
+ and organizing of concepts.
+ - Different headings in the outline are foldable/expandable so that
+ you can focus on what you need to focus on and eliminate
+ distractions.
+ - You can maintain a TODO list within Org
+ - You can compile TODO lists from many files into an agenda
+ - Track the time you spend on each TODO task
+ - Manage tables in plain text (including spreadsheet-like
+ capabilities)
+ - Using the extension `org-babel`, write and execute code blocks in
+ your file. The results are captured and are re-usable within the
+ file itself. Think Jupyter notebook for any language.
+ - Display inline images and LaTeX formulas as images within your file
+ (makes for a great note-taking system and/or personal wiki)
+ - Export your file into many different formats (LaTeX, PDF, html,…)
+
+Org mode is a very powerful tool to add to your productivity arsenal
+and, on a personal note, was the reason that caused me to start using
+Emacs after years of using Vim.
+
+## Magit
+
+This is a frontend to `git` from within Emacs. It features a very
+intuitive and discoverable interface, yet exposes very powerful
+functionality that allows you to manage commits at the chunk level,
+inspect diffs, rebase, cherry-pick, … all from within the comfort of
+your own editor.
+
+# A Word of Advice
+
+If you are considering using Emacs, a common trap that beginning users
+fall into is to copy someone else's configuration file and use it as is.
+I highly recommend against doing this for several reasons:
+
+ - It will discourage you from learning and finding things out for
+ yourself
+ - Someone else's configuration will probably contain many things
+ relevant to them that you won't need or ever use.
+ - It defeats the purpose of having a customizable text editor that can
+ fit your own needs.
+
+What I encourage you to do is to look at other people's configurations
+and seek to understand them and adapt only what makes sense to you. You
+can find out about new features of Emacs through many YouTube videos,
+screencasts or blog posts and then learn for yourself how to add them to
+your configuration and workflow. This way, you grow your configuration
+incrementally while increasing your knowledge of Emacs along the way.
+
+# Additional Resources
+
+ - [The GNU Emacs Manual](https://www.gnu.org/software/emacs/manual/emacs.html)
+ - [Emacs Stack Exchange](https://emacs.stackexchange.com/)
+ - [Emacs Wiki](https://www.emacswiki.org/emacs/EmacsWiki)
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/amd-es.html.markdown b/es-es/amd-es.html.markdown
index 7a59ddd6..40aa6647 100644
--- a/es-es/amd-es.html.markdown
+++ b/es-es/amd-es.html.markdown
@@ -190,7 +190,7 @@ Para usar el fichero creado en producción, simplemente intercambia `data-main`:
Un increíblemente detallado [resumen de opciones de generación](https://github.com/jrburke/r.js/blob/master/build/example.build.js) está disponible en el repositorio de GitHub.
-### Tópicos no cubiertos en este tutorial
+### Temas no cubiertos en este tutorial
* [Cargador de plugins / transformaciones](http://requirejs.org/docs/plugins.html)
* [Cargando y exportando estilos CommonJS](http://requirejs.org/docs/commonjs.html)
* [Configuración avanzada](http://requirejs.org/docs/api.html#config)
diff --git a/es-es/asciidoc-es.html.markdown b/es-es/asciidoc-es.html.markdown
new file mode 100644
index 00000000..6e357915
--- /dev/null
+++ b/es-es/asciidoc-es.html.markdown
@@ -0,0 +1,134 @@
+---
+language: asciidoc
+contributors:
+ - ["Ryan Mavilia", "http://unoriginality.rocks/"]
+translators:
+ - ["Abel Salgado Romero", "https://twitter.com/abelsromero"]
+lang: es-es
+filename: asciidoc-es.md
+---
+
+AsciiDoc es un lenguaje de marcas similar a Markdown que puede ser usado para cualquier uso, desde libros a blogs.
+Creado en 2002 por Stuart Rackham, el lenguaje es simple pero permite un gran nivel de personalización.
+
+Cabecera de documento
+
+La cabecera es opcional y no puede contener lineas vacías. Debe estar separada del contenido por al menos una línea en blanco.
+
+Solo título
+
+```
+= Título de documento
+
+Primer contenido del documento.
+```
+
+Título y autor
+
+```
+= Título del documento
+Nombre Apellido(s) <nombre.apellido@learnxinyminutes.com>
+
+Inicio de este documento.
+```
+
+Múltiples autores
+
+```
+= Título del documento
+John Doe <john@go.com>; Jane Doe<jane@yo.com>; Black Beard <beardy@pirate.com>
+
+Inicio de un documento con múltiples autores.
+```
+
+Linea de versión (requiere línea de autor)
+
+```
+= Título del documento V1
+Potato Man <chip@crunchy.com>
+v1.0, 2016-01-13
+
+Este artículo sobre patatas fritas será genial.
+```
+
+Párrafo
+
+```
+No necesitas nada especial para un párrafo.
+
+Inserta una línea vacía entre cada párrafo para separarlos.
+
+Para insertar un salto de línea, solo añade un +
+y ya lo tienes!
+```
+
+Dando formato al texto
+
+```
+_guión bajo para cursiva_
+*asteriscos para negrita*
+*_combínalos y verás_*
+`usa comillas invertidas para monospace`
+`*combina para negrita monospace*`
+```
+
+Títulos de sección
+
+```
+= Nivel 0 (úsalo solo para el título del documento)
+
+== Nivel 1 <h2>
+
+=== Nivel 2 <h3>
+
+==== Nivel 3 <h4>
+
+===== Nivel 4 <h5>
+```
+
+Listas
+
+Para crear una lista sin orden usa asteriscos.
+
+```
+* foo
+* bar
+* baz
+```
+
+Para crear una lista numerada usa puntos.
+
+```
+. item 1
+. item 2
+. item 3
+```
+
+Puedes crear hasta 5 subniveles en las listas añadiendo asteriscos o puntos.
+
+```
+* foo 1
+** foo 2
+*** foo 3
+**** foo 4
+***** foo 5
+
+. foo 1
+.. foo 2
+... foo 3
+.... foo 4
+..... foo 5
+```
+
+## Referencias
+
+Existen dos herramientas para procesar documentación en AsciiDoc:
+
+1. [AsciiDoc](http://asciidoc.org/): implementación original para Python, disponible en las principales distribuciones Linux. Versión estable actualmente en modo mantenimiento.
+2. [Asciidoctor](http://asciidoctor.org/): implementación alternativa para Ruby, usable también desde Java y JavaScript. Implementación completa en evolución, su objetivo es ampliar AsciiDoc con nuevas funcionalidades y conversores de salida.
+
+Los siguientes enlaces pertenecen a `Asciidoctor` (documentación en inglés):
+
+* [Comparación de sintaxis Markdown - AsciiDoc](http://asciidoctor.org/docs/user-manual/#comparison-by-example): comparativa de elements comunes entre Markdown y AsciiDoc.
+* [Primeros pasos](http://asciidoctor.org/docs/#get-started-with-asciidoctor): manuales de instalación e inicio para convertir documentos simples.
+* [Manual de usuario de Asciidoctor](http://asciidoctor.org/docs/user-manual/): referencia completa en un único documento, contiene ejemplos, guías de herramientas, etc.
diff --git a/es-es/awk-es.html.markdown b/es-es/awk-es.html.markdown
new file mode 100644
index 00000000..8da8f024
--- /dev/null
+++ b/es-es/awk-es.html.markdown
@@ -0,0 +1,363 @@
+---
+category: tool
+tool: awk
+filename: learnawk-es.awk
+contributors:
+ - ["Marshall Mason", "http://github.com/marshallmason"]
+translators:
+ - ["Hugo Guillén-Ramírez", "http://github.com/HugoGuillen"]
+lang: es-es
+---
+
+AWK es una herramienta estándar en cada sistema UNIX compatible con POSIX.
+Es como un Perl restringido, perfecto para tareas de procesamiento de texto y
+otras necesidades de scripting. Tiene una sintaxis similar a C, pero sin
+puntos y comas, manejo manual de memoria y tipado estático. Puedes llamarlo
+desde un script de shell o usarlo como un lenguaje stand-alone para scripting.
+
+¿Por qué elegir AWK sobre Perl? Principalmente, porque AWK es parte de UNIX.
+Siempre puedes contar con él, mientras que el futuro de Perl está en duda. AWK
+es más fácil de leer que Perl. Para scripts sencillos de procesamiento de texto,
+particularmente si es para leer archivos línea a línea y dividir por
+delimitadores, probablemente AWK es la herramienta correcta para el trabajo.
+
+```awk
+#!/usr/bin/awk -f
+
+# Los comentarios tienen este aspecto.
+
+# Los programas AWK son una colección de patrones y acciones. El patrón más
+# importante es BEGIN. Las acciones van en bloques delimitados por llaves.
+
+BEGIN {
+
+ # BEGIN correrá al inicio del programa. Es donde pones todo el código
+ # preliminar antes de procesar los archivos de texto. Si no tienes archivos
+ # de texto, piensa en BEGIN como el punto de entrada principal del script.
+
+ # Las variables son globales. Asígnalas o úsalas sin declararlas.
+ count = 0
+
+ # Los operadores son justo como en C (y amigos).
+ a = count + 1
+ b = count - 1
+ c = count * 1
+ d = count / 1
+ e = count % 1 # módulo
+ f = count ^ 1 # exponenciación
+
+ a += 1
+ b -= 1
+ c *= 1
+ d /= 1
+ e %= 1
+ f ^= 1
+
+ # Incremento y decremento en uno
+ a++
+ b--
+
+ # Como un operador prefijo, regresa el valor modificado
+ ++a
+ --b
+
+ # Nota que no hay puntación para terminar las instrucciones
+
+ # Instrucciones de control
+ if (count == 0)
+ print "Iniciando count en 0"
+ else
+ print "Eh?"
+
+ # O puedes usar el operador ternario
+ print (count == 0) ? "Iniciando count en 0" : "Eh?"
+
+ # Bloques formados por múltiples líneas usan llaves
+ while (a < 10) {
+ print "La concatenación de strings se hace " " con series "
+ print " de" " strings separados por espacios"
+ print a
+
+ a++
+ }
+
+ for (i = 0; i < 10; i++)
+ print "El viejo confiable ciclo for"
+
+ # Los operaciones de comparación son estándar...
+ a < b # Menor que
+ a <= b # Menor o igual que
+ a != b # No igual
+ a == b # Igual
+ a > b # Mayor que
+ a >= b # Mayor o igual que
+
+ # ...así como los operadores lógicos
+ a && b # AND
+ a || b # OR
+
+ # Además están las expresiones regulares
+ if ("foo" ~ "^fo+$")
+ print "Fooey!"
+ if ("boo" !~ "^fo+$")
+ print "Boo!"
+
+ # Arrays
+ arr[0] = "foo"
+ arr[1] = "bar"
+ # Desafortunadamente no hay otra manera de inicializar un array.
+ # Tienes que inicializar cada posición del array.
+
+ # También hay arrays asociativos
+ assoc["foo"] = "bar"
+ assoc["bar"] = "baz"
+
+ # Y arrays multidimensionales con limitaciones que no mencionaré aquí
+ multidim[0,0] = "foo"
+ multidim[0,1] = "bar"
+ multidim[1,0] = "baz"
+ multidim[1,1] = "boo"
+
+ # Puedes probar pertenencia a un array
+ if ("foo" in assoc)
+ print "Fooey!"
+
+ # También puedes usar el operador 'in' para iterar las claves de un array
+ for (key in assoc)
+ print assoc[key]
+
+ # La terminal es un array especial llamado ARGV
+ for (argnum in ARGV)
+ print ARGV[argnum]
+
+ # Puedes eliminar elementos de un array.
+ # Esto es útil para prevenir que AWK suponga que algunos argumentos
+ # son archivos por procesar.
+ delete ARGV[1]
+
+ # El número de argumentos de la terminal está en la variable ARGC
+ print ARGC
+
+ # AWK tiene tres categorías de funciones incluidas.
+ # Demostraré esas funciones posteriormente.
+
+ return_value = arithmetic_functions(a, b, c)
+ string_functions()
+ io_functions()
+}
+
+# Así se define una función
+function arithmetic_functions(a, b, c, localvar) {
+
+ # Probablemente la parte más molesta de AWK es que no hay variables locales
+ # Todo es global. No es problema en scripts pequeños, pero sí para
+ # scripts más grandes.
+
+ # Hay un work-around (mmm... hack). Los argumentos de las funciones son
+ # locales para la función, y AWK permite definir más argumentos de función
+ # de los que necesita, por lo que define las variables locales en la
+ # declaración como en la función de arriba. Como convención, agrega
+ # espacios en blanco para distinguir los parámetros de la función de las
+ # variables locales. En este ejemplo, a, b y c son parámetros y localvar es una
+ # variable local.
+
+ # Ahora, a demostrar las funciones aritméticas
+
+ # La mayoría de las implementaciones de AWK tienen funciones
+ # trigonométricas estándar
+ localvar = sin(a)
+ localvar = cos(a)
+ localvar = atan2(b, a) # arcotangente de b / a
+
+ # Y cosas logarítmicas
+ localvar = exp(a)
+ localvar = log(a)
+
+ # Raíz cuadrada
+ localvar = sqrt(a)
+
+ # Trucar un flotante a entero
+ localvar = int(5.34) # localvar => 5
+
+ # Números aleatorios
+ srand() # La semilla es el argumento. Por defecto usa el tiempo del sistema
+ localvar = rand() # Número aleatorio entre 0 y 1.
+
+ # Y aquí se regresa el valor
+ return localvar
+}
+
+function string_functions( localvar, arr) {
+
+ # AWK tiene algunas funciones para procesamiento de strings,
+ # y muchas dependen fuertemente en expresiones regulares.
+
+ # Buscar y remplazar, primer instancia (sub) o todas las instancias (gsub)
+ # Ambas regresan el número de matches remplazados.
+ localvar = "fooooobar"
+ sub("fo+", "Meet me at the ", localvar) # localvar => "Meet me at the bar"
+ gsub("e+", ".", localvar) # localvar => "m..t m. at th. bar"
+
+ # Buscar una cadena que haga match con una expresión regular
+ # index() hace lo mismo, pero no permite expresiones regulares
+ match(localvar, "t") # => 4, dado que 't' es el cuarto caracter
+
+ # Separar con base en un delimitador
+ split("foo-bar-baz", arr, "-") # a => ["foo", "bar", "baz"]
+
+ # Otras funciones útiles
+ sprintf("%s %d %d %d", "Testing", 1, 2, 3) # => "Testing 1 2 3"
+ substr("foobar", 2, 3) # => "oob"
+ substr("foobar", 4) # => "bar"
+ length("foo") # => 3
+ tolower("FOO") # => "foo"
+ toupper("foo") # => "FOO"
+}
+
+function io_functions( localvar) {
+
+ # Ya has visto print
+ print "Hello world"
+
+ # También hay printf
+ printf("%s %d %d %d\n", "Testing", 1, 2, 3)
+
+ # AWK no tiene handles de archivos en sí mismo. Automáticamente abrirá un
+ # handle de archivo cuando use algo que necesite uno. El string que usaste
+ # para esto puede ser tratada como un handle de archivo para propósitos de I/O.
+ # Esto lo hace similar al scripting de shell:
+
+ print "foobar" >"/tmp/foobar.txt"
+
+ # Ahora el string "/tmp/foobar.txt" es un handle. Puedes cerrarlo:
+ close("/tmp/foobar.txt")
+
+ # Aquí está como correr algo en el shell
+ system("echo foobar") # => muestra foobar
+
+ # Lee una línea de la entrada estándar (stdin) y lo guarda en localvar
+ getline localvar
+
+ # Lee una línea desde un pipe
+ "echo foobar" | getline localvar # localvar => "foobar"
+ close("echo foobar")
+
+ # Lee una línea desde un archivo y la guarda en localvar
+ getline localvar <"/tmp/foobar.txt"
+ close("/tmp/foobar.txt")
+}
+
+# Como dije al inicio, los programas en AWK son una colección de patrones y
+# acciones. Ya conociste el patrón BEGIN. otros patrones sólo se usan si estás
+# procesando líneas desde archivos o stdin.
+
+# Cuando pasas argumentos a AWK, son tratados como nombres de archivos a
+# procesar. Los va a procesar todos, en orden. Imagínalos como un ciclo for
+# implícito, iterando sobre las líneas de estos archivos. Estos patrones y
+# acciones son como instrucciones switch dentro del ciclo.
+
+/^fo+bar$/ {
+
+ # Esta acción se ejecutará por cada línea que haga match con la expresión
+ # regular /^fo+bar$/, y será saltada por cualquier línea que no haga match.
+ # Vamos a sólo mostrar la línea:
+
+ print
+
+ # ¡Wow, sin argumento! Eso es porque print tiene uno por defecto: $0.
+ # $0 es el nombre de la línea actual que se está procesando.
+ # Se crea automáticamente para ti.
+
+ # Probablemente puedas adivinar que hay otras variables $. Cada línea es
+ # separada implícitamente antes de que se llame cada acción, justo como lo
+ # hace shell. Y, como shell, cada campo puede ser accesado con $.
+
+ # Esto mostrará el segundo y cuarto campos de la línea
+ print $2, $4
+
+ # AWK automáticamente define muchas otras variables que te ayudan a
+ # inspeccionar y procesar cada línea. La más importante es NF
+
+ # Imprime el número de campos de esta línea
+ print NF
+
+ # Imprime el último campo de esta línea
+ print $NF
+}
+
+# Cada patrón es realmente un prueba de verdadero/falso. La expresión regular
+# en el último patrón también es una prueba verdadero/falso, pero parte de eso
+# estaba oculto. Si no le das un string a la prueba, supondrá $0, la línea que
+# se está procesando. La versión completa de esto es:
+
+$0 ~ /^fo+bar$/ {
+ print "Equivalente al último patrón"
+}
+
+a > 0 {
+ # Esto se ejecutará una vez por línea, mientras a sea positivo
+}
+
+# Y ya te das una idea. Procesar archivos de texto, leyendo una línea a la vez,
+# y haciendo algo con ella, particularmente separando en un deliminator, es tan
+# común en UNIX que AWK es un lenguaje de scripting que hace todo eso por ti
+# sin que tengas que pedirlo. Basta con escribir los patrones y acciones
+# basados en lo que esperas de la entrada y lo quieras quieras hacer con ella.
+
+# Aquí está un ejemplo de un script simple, para lo que AWK es perfecto.
+# El script lee un nombre de stdin y muestra el promedio de edad para todos los
+# que tengan ese nombre. Digamos que como argumento pasamos el nombre de un
+# archivo con este contenido:
+#
+# Bob Jones 32
+# Jane Doe 22
+# Steve Stevens 83
+# Bob Smith 29
+# Bob Barker 72
+#
+# Éste es el script:
+
+BEGIN {
+
+ # Primero, pedir al usuario el nombre
+ print "¿Para qué nombre quieres el promedio de edad?"
+
+ # Recuperar una línea de stdin, no de archivos en la línea de comandos
+ getline name <"/dev/stdin"
+}
+
+# Ahora, hacer match con cada línea cuyo primer campo es el nombre dado
+$1 == name {
+
+ # Aquí dentro tenemos acceso a variables útiles precargadas:
+ # $0 es toda la línea
+ # $3 es el tercer campo, la edad, que es lo que nos interesa
+ # NF es el número de campos, que debe ser 3
+ # NR es el número de registros (líneas) vistos hasta ahora
+ # FILENAME es el nombre del archivo que está siendo procesado
+ # FS es el campo separador, " " en este caso
+ # Y muchas más que puedes conocer ejecutando 'man awk' en la terminal.
+
+ # Llevar el registro de la suma y cuantas líneas han hecho match.
+ sum += $3
+ nlines++
+}
+
+# Otro patrón especial es END. Va a ejecutarse después de procesar todos los
+# archivos de texto. A diferencia de BEGIN, sólo se ejecuta si le das dado una
+# entrada a procesar. Se ejecutará después de que todos los archivos hayan sido
+# leídos y procesados según las reglas y acciones que programaste. El propósito
+# es usualmente para mostrar un reporte final, o hacer algo con el agregado de
+# los datos que has acumulado durante la ejecución del script.
+
+END {
+ if (nlines)
+ print "La edad promedio para " name " es " sum / nlines
+}
+
+```
+Más información:
+
+* [Tutorial de AWK](http://www.grymoire.com/Unix/Awk.html)
+* [Página man de AWK](https://linux.die.net/man/1/awk)
+* [La guía del usuario de GNU Awk](https://www.gnu.org/software/gawk/manual/gawk.html): GNU Awk se encuentra en la mayoría de los sistemas Linux.
diff --git a/es-es/bf-es.html.markdown b/es-es/bf-es.html.markdown
index c93b8c3a..df1ae2e7 100644
--- a/es-es/bf-es.html.markdown
+++ b/es-es/bf-es.html.markdown
@@ -1,5 +1,6 @@
---
language: bf
+filename: bf-es.bf
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
diff --git a/es-es/c++-es.html.markdown b/es-es/c++-es.html.markdown
index 07c8bc03..2c3762d5 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>());
@@ -823,7 +823,6 @@ v.swap(vector<Foo>());
```
Otras lecturas:
-Una referencia del lenguaje hasta a la fecha se puede encontrar en
-<http://cppreference.com/w/cpp>
-
-Recursos adicionales se pueden encontrar en <http://cplusplus.com>
+* Una referencia del lenguaje hasta a la fecha se puede encontrar en [CPP Reference](http://cppreference.com/w/cpp).
+* Recursos adicionales se pueden encontrar en [[CPlusPlus]](http://cplusplus.com).
+* Un tutorial que cubre los conceptos básicos del lenguaje y la configuración del entorno de codificación está disponible en [TheChernoProject - C ++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FF).
diff --git a/es-es/c-es.html.markdown b/es-es/c-es.html.markdown
index 8bc1eabb..cae4349e 100644
--- a/es-es/c-es.html.markdown
+++ b/es-es/c-es.html.markdown
@@ -5,6 +5,7 @@ contributors:
- ["Adam Bard", "http://adambard.com/"]
translators:
- ["Francisco García", "http://flaskbreaker.tumblr.com/"]
+ - ["Heitor P. de Bittencourt", "https://github.com/heitorPB/"]
lang: es-es
---
@@ -423,7 +424,7 @@ libro de C, escrito por Dennis Ritchie, creador de C y Brian Kernighan. Aún as
se cuidadoso, es antiguo, contiene algunas inexactitudes, y algunas prácticas
han cambiado.
-Otro buen recurso es [Learn C the hard way](http://c.learncodethehardway.org/book/).
+Otro buen recurso es [Learn C the hard way](http://learncodethehardway.org/c/).
Si tienes una pregunta, lee [compl.lang.c Frequently Asked Questions](http://c-faq.com).
diff --git a/es-es/clojure-es.html.markdown b/es-es/clojure-es.html.markdown
index 150d0bb2..62935ebe 100644
--- a/es-es/clojure-es.html.markdown
+++ b/es-es/clojure-es.html.markdown
@@ -9,28 +9,30 @@ translators:
lang: es-es
---
-Clojure es un lenguaje de la familia Lisp desarrollado sobre la Máquina Virtual
-de Java. Tiene un énfasis mayor en la [programación funcional](https://es.wikipedia.org/wiki/Programación_funcional) pura
-que Common Lisp, pero incluyendo la posibilidad de usar [SMT](https://es.wikipedia.org/wiki/Memoria_transacional) para manipular
+Clojure es un lenguaje de la familia Lisp desarrollado para la Máquina Virtual
+de Java. Tiene un énfasis mayor en la
+[programación funcional](https://es.wikipedia.org/wiki/Programación_funcional)
+pura que Common Lisp, pero incluye varias utilidades de
+[SMT](https://es.wikipedia.org/wiki/Memoria_transacional) para manipular
el estado según se presente.
-Esta combinación le permite gestionar la concurrencia de manera muy sencilla
-y a menudo automáticamente.
+Esta combinación le permite gestionar el procesamiento concurrente de manera
+muy sencilla, y a menudo automáticamente.
-(Necesitas la versión de Clojure 1.2 o posterior)
+(Necesitas la versión de Clojure 1.2 o reciente)
```clojure
-; Los comentatios comienzan con punto y coma.
+; Los comentarios comienzan con punto y coma.
-; Clojure se escribe mediante "forms" (patrones), los cuales son
-; listas de objectos entre paréntesis, separados por espacios en blanco.
+; Clojure se escribe mediante patrones ("forms"), los cuales son
+; listas de cosas entre paréntesis, separados por espacios en blanco.
-; El "reader" (lector) de Clojure asume que el primer objeto es una
-; función o una macro que se va a llamar, y que el resto son argumentos.
+; El lector ("reader") de Clojure asume que la primera cosa es una
+; función o una macro a llamar, y el resto son argumentos.
-; El primer form en un archivo debe ser ns, para establecer el namespace (espacio de
-; nombres)
+; La primera llamada en un archivo debe ser ns, para establecer el espacio de
+; nombres ("namespace")
(ns learnclojure)
; Algunos ejemplos básicos:
@@ -51,69 +53,70 @@ y a menudo automáticamente.
; También es necesaria la negación para las operaciones lógicas
(not true) ; => false
-; Cuando se anidan Los patrones, estos funcionan de la manera esperada
+; Los patrones anidados funcionan como esperas
(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
; Tipos
;;;;;;;;;;;;;
-; Clojure usa los tipos de objetos de Java para booleanos, strings (cadenas de
-; caracteres) y números.
-; Usa class para saber de qué tipo es.
-(class 1); Los enteros son java.lang.Long por defecto
-(class 1.); Los numeros en coma flotante son java.lang.Double
-(class ""); Los strings van entre comillas dobles, y son
-; son java.lang.String
-(class false); Los Booleanos son java.lang.Boolean
+; Clojure usa los tipos de objetos de Java para booleanos, cadenas de
+; caracteres ("strings") y números.
+; Usa class para inspeccionarlos.
+(class 1); Los números enteros literales son java.lang.Long por defecto
+(class 1.); Los números en coma flotante literales son java.lang.Double
+(class ""); Los strings siempre van entre comillas dobles, y son
+ ; java.lang.String
+(class false); Los booleanos son java.lang.Boolean
(class nil); El valor "null" se escribe nil
-; Si quieres crear una lista de datos, precedela con una comilla
-; simple para evitar su evaluación
+; Si quieres crear una lista literal de datos, usa ' para evitar su evaluación
'(+ 1 2) ; => (+ 1 2)
-; (que es una abreviatura de (quote (+ 1 2)) )
+; (que es una abreviatura de (quote (+ 1 2)))
-; Puedes evaluar una lista precedida por comilla con eval
+; Puedes evaluar una lista precedida por una comilla con eval
(eval '(+ 1 2)) ; => 3
; Colecciones & Secuencias
;;;;;;;;;;;;;;;;;;;
-; Las Listas están basadas en las listas enlazadas, mientras que los Vectores en
-; arrays.
+; Las Listas están basadas en listas enlazadas, mientras que los Vectores en
+; arreglos.
; ¡Los Vectores y las Listas también son clases de Java!
(class [1 2 3]); => clojure.lang.PersistentVector
(class '(1 2 3)); => clojure.lang.PersistentList
-; Una lista podría ser escrita como (1 2 3), pero debemos ponerle una
-; comilla simple delante para evitar que el reader piense que es una función.
+; Una lista podría ser escrita como (1 2 3), pero debemos precederle una
+; comilla para evitar que el lector ("reader") piense que es una función.
; Además, (list 1 2 3) es lo mismo que '(1 2 3)
-; Las "Colecciones" son solo grupos de datos
-; Tanto las listas como los vectores son colecciones:
+; Las Colecciones ("collections") son solo grupos de datos
+; Tanto las Listas como los Vectores son colecciones:
(coll? '(1 2 3)) ; => true
(coll? [1 2 3]) ; => true
-; Las "Secuencias" (seqs) son descripciones abstractas de listas de datos.
-; Solo las listas son seqs.
+; Las Secuencias ("seqs") son descripciones abstractas de listas de datos.
+; Solo las listas son secuencias ("seqs").
(seq? '(1 2 3)) ; => true
(seq? [1 2 3]) ; => false
-; Una seq solo necesita proporcionar una entrada cuando es accedida.
-; Así que, las seqs pueden ser perezosas -- pueden establecer series infinitas:
+; Una secuencia solo necesita proporcionar uno de sus elementos cuando es
+; accedido.
+; Así que, las secuencias pueden ser perezosas -- pueden definir series
+; infinitas:
(range 4) ; => (0 1 2 3)
(range) ; => (0 1 2 3 4 ...) (una serie infinita)
(take 4 (range)) ; (0 1 2 3)
-; Usa cons para agregar un elemento al inicio de una lista o vector
+; Usa cons para agregar un elemento al inicio de una Lista o Vector
(cons 4 [1 2 3]) ; => (4 1 2 3)
(cons 4 '(1 2 3)) ; => (4 1 2 3)
; conj agregará un elemento a una colección en la forma más eficiente.
-; Para listas, se añade al inicio. Para vectores, al final.
+; Para Listas, se añade al inicio. Para vectores, al final.
(conj [1 2 3] 4) ; => [1 2 3 4]
(conj '(1 2 3) 4) ; => (4 1 2 3)
-; Usa concat para concatenar listas o vectores
+; Usa concat para concatenar Listas o Vectores
(concat [1 2] '(3 4)) ; => (1 2 3 4)
; Usa filter y map para actuar sobre colecciones
@@ -125,7 +128,7 @@ y a menudo automáticamente.
; = (+ (+ (+ 1 2) 3) 4)
; => 10
-; reduce puede tener un argumento indicando su valor inicial.
+; reduce puede tomar un argumento como su valor inicial también
(reduce conj [] '(3 2 1))
; = (conj (conj (conj [] 3) 2) 1)
; => [3 2 1]
@@ -137,43 +140,42 @@ y a menudo automáticamente.
; su última expresión
(fn [] "Hello World") ; => fn
-; (Necesitas rodearlo con paréntesis para invocarla)
+; (Necesitas rodearlo con paréntesis para llamarla)
((fn [] "Hello World")) ; => "Hello World"
-; Puedes crear una var (variable) mediante def
+; Puedes definir una variable ("var") mediante def
(def x 1)
x ; => 1
-; Asigna una función a una var
+; Asignar una función a una variable ("var")
(def hello-world (fn [] "Hello World"))
(hello-world) ; => "Hello World"
-; Puedes defn como atajo para lo anterior
+; Puedes usar defn como atajo para lo anterior
(defn hello-world [] "Hello World")
-; El [] es el vector de argumentos de la función.
+; El [] es el Vector de argumentos de la función.
(defn hello [name]
(str "Hello " name))
(hello "Steve") ; => "Hello Steve"
-; Otra abreviatura para crear funciones es:
+; Puedes usar esta abreviatura para definir funciones:
(def hello2 #(str "Hello " %1))
(hello2 "Fanny") ; => "Hello Fanny"
-; Puedes tener funciones multi-variadic: funciones con un numero variable de
-; argumentos
+; Puedes tener funciones multi-variables ("multi-variadic") también
(defn hello3
([] "Hello World")
([name] (str "Hello " name)))
(hello3 "Jake") ; => "Hello Jake"
(hello3) ; => "Hello World"
-; Las funciones pueden usar argumentos extras dentro de un seq utilizable en la función
+; Las funciones pueden empaquetar argumentos extras en una secuencia para ti
(defn count-args [& args]
(str "You passed " (count args) " args: " args))
(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
-; Y puedes mezclarlos con el resto de argumentos declarados de la función.
+; Puedes combinar los argumentos regulares y los empaquetados
(defn hello-count [name & args]
(str "Hello " name ", you passed " (count args) " extra args"))
(hello-count "Finn" 1 2 3)
@@ -183,17 +185,18 @@ x ; => 1
; Mapas
;;;;;;;;;;
-; Mapas de Hash y mapas de arrays comparten una misma interfaz. Los mapas de Hash
-; tienen búsquedas más rápidas pero no mantienen el orden de las claves.
+; Los Mapas de Hash ("HashMap") y Mapas de Arreglo ("ArrayMap") comparten una
+; interfaz. Los Mapas de Hash tienen búsquedas más rápidas pero no mantienen el
+; orden de las llaves.
(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
-; Los mapas de arrays se convertidos en mapas de Hash en la mayoría de
-; operaciones si crecen mucho, por lo que no debes preocuparte.
+; Los Mapas de Arreglo se convierten automáticamente en Mapas de Hash en la
+; mayoría de operaciones si crecen mucho, por lo que no debes preocuparte.
-; Los mapas pueden usar cualquier tipo para sus claves, pero generalmente las
-; keywords (palabras clave) son lo habitual.
-; Las keywords son parecidas a cadenas de caracteres con algunas ventajas de eficiencia
+; Los Mapas pueden usar cualquier tipo para sus llaves, pero generalmente las
+; Claves ("keywords") son lo habitual.
+; Las Claves son como strings con algunas ventajas de eficiencia
(class :a) ; => clojure.lang.Keyword
(def stringmap {"a" 1, "b" 2, "c" 3})
@@ -205,28 +208,28 @@ keymap ; => {:a 1, :c 3, :b 2}
; Por cierto, las comas son equivalentes a espacios en blanco y no hacen
; nada.
-; Recupera un valor de un mapa tratandolo como una función
+; Recupera un valor de un Mapa tratándola como una función
(stringmap "a") ; => 1
(keymap :a) ; => 1
-; ¡Las keywords pueden ser usadas para recuperar su valor del mapa, también!
+; ¡Las Claves pueden ser usadas para recuperar su valor del mapa, también!
(:b keymap) ; => 2
; No lo intentes con strings.
;("a" stringmap)
; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
-; Si preguntamos por una clave que no existe nos devuelve nil
+; Recuperando una clave no existente nos devuelve nil
(stringmap "d") ; => nil
-; Usa assoc para añadir nuevas claves a los mapas de Hash
+; Usa assoc para añadir nuevas claves a los Mapas de Hash
(def newkeymap (assoc keymap :d 4))
newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
; Pero recuerda, ¡los tipos de Clojure son inmutables!
keymap ; => {:a 1, :b 2, :c 3}
-; Usa dissoc para eliminar llaves
+; Usa dissoc para eliminar claves
(dissoc keymap :a :b) ; => {:c 3}
; Conjuntos
@@ -238,50 +241,86 @@ keymap ; => {:a 1, :b 2, :c 3}
; Añade un elemento con conj
(conj #{1 2 3} 4) ; => #{1 2 3 4}
-; Elimina elementos con disj
+; Elimina uno con disj
(disj #{1 2 3} 1) ; => #{2 3}
-; Comprueba su existencia usando el conjunto como una función:
+; Comprueba su existencia usando al Conjunto como una función:
(#{1 2 3} 1) ; => 1
(#{1 2 3} 4) ; => nil
-; Hay más funciones en el namespace clojure.sets
+; Hay más funciones en el espacio de nombres clojure.sets
; Patrones útiles
;;;;;;;;;;;;;;;;;
-; Las construcciones lógicas en clojure son macros, y presentan el mismo aspecto
-; que el resto de forms.
+; Los operadores lógicos en clojure son solo macros, y presentan el mismo
+; aspecto que el resto de patrones.
(if false "a" "b") ; => "b"
(if false "a") ; => nil
-; Usa let para crear un binding (asociación) temporal
+; Usa let para definir ("binding") una variable temporal
(let [a 1 b 2]
(> a b)) ; => false
-; Agrupa expresiones mediante do
+; Agrupa sentencias mediante do
(do
(print "Hello")
"World") ; => "World" (prints "Hello")
-; Las funciones tienen implicita la llamada a do
+; Las funciones tienen un do implícito
(defn print-and-say-hello [name]
(print "Saying hello to " name)
(str "Hello " name))
(print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff")
-; Y el let también
+; Y let también
(let [name "Urkel"]
(print "Saying hello to " name)
(str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
+; Usa las macros de tubería ("threading", "arrow", "pipeline" o "chain")
+; (-> y ->>) para expresar la transformación de datos de una manera más clara.
+
+; La macro Tubería-primero ("Thread-first") (->) inserta en cada patrón el
+; resultado de los previos, como el primer argumento (segundo elemento)
+(->
+ {:a 1 :b 2}
+ (assoc :c 3) ;=> (assoc {:a 1 :b 2} :c 3)
+ (dissoc :b)) ;=> (dissoc (assoc {:a 1 :b 2} :c 3) :b)
+
+; Esta expresión podría ser escrita como:
+; (dissoc (assoc {:a 1 :b 2} :c 3) :b)
+; y evalua a {:a 1 :c 3}
+
+; La macro Tubería-último ("Thread-last") hace lo mismo, pero inserta el
+; resultado de cada línea al *final* de cada patrón. Esto es útil para las
+; operaciones de colecciones en particular:
+(->>
+ (range 10)
+ (map inc) ;=> (map inc (range 10)
+ (filter odd?) ;=> (filter odd? (map inc (range 10))
+ (into [])) ;=> (into [] (filter odd? (map inc (range 10)))
+ ; Result: [1 3 5 7 9]
+
+; Cuando estés en una situación donde quieras tener más libertad en donde
+; poner el resultado de transformaciones previas de datos en una expresión,
+; puedes usar la macro as->. Con ella, puedes asignar un nombre especifico
+; a la salida de la transformaciones y usarlo como identificador en tus
+; expresiones encadenadas ("chain").
+
+(as-> [1 2 3] input
+ (map inc input);=> You can use last transform's output at the last position
+ (nth input 2) ;=> and at the second position, in the same expression
+ (conj [4 5 6] input [8 9 10])) ;=> or in the middle !
+
+
; Módulos
;;;;;;;;;;;;;;;
; Usa use para obtener todas las funciones del módulo
(use 'clojure.set)
-; Ahora podemos usar más operaciones de conjuntos
+; Ahora podemos usar más operaciones de Conjuntos
(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
(difference #{1 2 3} #{2 3 4}) ; => #{1}
@@ -291,19 +330,18 @@ keymap ; => {:a 1, :b 2, :c 3}
; Usa require para importar un módulo
(require 'clojure.string)
-; Usa / para llamar a las funciones de un módulo
+; Usa / para llamar las funciones de un módulo
; Aquí, el módulo es clojure.string y la función es blank?
(clojure.string/blank? "") ; => true
-; Puedes asignarle una abreviatura a un modulo al importarlo
+; Puedes asignarle una sobrenombre a un modulo al importarlo
(require '[clojure.string :as str])
(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
-; (#"" es una expresión regular)
+; (#"" es una expresión regular literal)
-; Puedes usar require (y use, pero no lo hagas) desde un espacio de nombre
+; Puedes usar require (y use, pero no lo hagas) desde un espacio de nombres
; usando :require,
-; No necesitas preceder con comilla simple tus módulos si lo haces de esta
-; forma.
+; No necesitas preceder con comilla tus módulos si lo haces de esta manera.
(ns test
(:require
[clojure.string :as str]
@@ -312,8 +350,8 @@ keymap ; => {:a 1, :b 2, :c 3}
; Java
;;;;;;;;;;;;;;;;;
-; Java tiene una enorme librería estándar, por lo que resulta util
-; aprender como interactuar con ella.
+; Java tiene una enorme y útil librería estándar, por lo que querrás
+; aprender como hacer uso de ella.
; Usa import para cargar un módulo de java
(import java.util.Date)
@@ -326,14 +364,15 @@ keymap ; => {:a 1, :b 2, :c 3}
; Usa el nombre de la clase con un "." al final para crear una nueva instancia
(Date.) ; <un objeto Date>
-; Usa "." para llamar a métodos o usa el atajo ".método"
+; Usa "." para llamar métodos. O, usa el atajo ".método"
(. (Date.) getTime) ; <un timestamp>
-(.getTime (Date.)) ; exactamente la misma cosa
+(.getTime (Date.)) ; exactamente lo mismo.
; Usa / para llamar métodos estáticos.
(System/currentTimeMillis) ; <un timestamp> (System siempre está presente)
-; Usa doto para hacer frente al uso de clases (mutables) más tolerable
+; Usa doto para lidiar con el uso de clases (mutables) de una manera más
+; tolerable
(import java.util.Calendar)
(doto (Calendar/getInstance)
(.set 2000 1 1 0 0 0)
@@ -342,9 +381,9 @@ keymap ; => {:a 1, :b 2, :c 3}
; STM
;;;;;;;;;;;;;;;;;
-; Software Transactional Memory es un mecanismo que usa clojure para gestionar
-; el estado persistente. Hay unas cuantas construcciones en clojure que
-; hacen uso de este mecanismo.
+; La Memoria Transaccional ("Software Transactional Memory" / "STM") es un
+; mecanismo que usa clojure para gestionar la persistecia de estado. Hay unas
+; cuantas construcciones en clojure que hacen uso de él.
; Un atom es el más sencillo. Se le da un valor inicial
(def my-atom (atom {}))
@@ -352,14 +391,16 @@ keymap ; => {:a 1, :b 2, :c 3}
; Actualiza un atom con swap!
; swap! toma una función y la llama con el valor actual del atom
; como su primer argumento, y cualquier argumento restante como el segundo
-(swap! my-atom assoc :a 1) ; Establece my-atom al resultado de (assoc {} :a 1)
-(swap! my-atom assoc :b 2) ; Establece my-atom al resultado de (assoc {:a 1} :b 2)
+(swap! my-atom assoc :a 1) ; Establece my-atom al resultado
+ ; de (assoc {} :a 1)
+(swap! my-atom assoc :b 2) ; Establece my-atom al resultado
+ ; de (assoc {:a 1} :b 2)
-; Usa '@' para no referenciar al atom sino para obtener su valor
+; Usa '@' para no referenciar al atom y obtener su valor
my-atom ;=> Atom<#...> (Regresa el objeto Atom)
@my-atom ; => {:a 1 :b 2}
-; Un sencillo contador usando un atom sería
+; Aquí está un sencillo contador usando un atom
(def counter (atom 0))
(defn inc-counter []
(swap! counter inc))
@@ -372,22 +413,25 @@ my-atom ;=> Atom<#...> (Regresa el objeto Atom)
@counter ; => 5
-; Otros forms que utilizan STM son refs y agents.
+; Otras construcciones de STM son refs y agents.
; Refs: http://clojure.org/refs
; Agents: http://clojure.org/agents
+```
+
### Lectura adicional
-Ésto queda lejos de ser exhaustivo, pero espero que sea suficiente para que puedas empezar tu camino.
+Ésto queda lejos de ser exhaustivo, pero ojalá que sea suficiente para que
+puedas empezar tu camino.
Clojure.org tiene muchos artículos:
-[http://clojure.org/](http://clojure.org/)
+[http://clojure.org](http://clojure.org)
Clojuredocs.org contiene documentación con ejemplos para la mayoría de
funciones principales (pertenecientes al core):
-[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
+[http://clojuredocs.org/quickref](http://clojuredocs.org/quickref)
4Clojure es una genial forma de mejorar tus habilidades con clojure/FP:
[http://www.4clojure.com/](http://www.4clojure.com/)
-Clojure-doc.org (sí, de verdad) tiene un buen número de artículos con los que iniciarse en Clojure:
-[http://clojure-doc.org/](http://clojure-doc.org/)
+Clojure-doc.org (sí, de verdad) tiene un buen número de artículos con los que
+iniciarse en Clojure: [http://clojure-doc.org](http://clojure-doc.org)
diff --git a/es-es/coldfusion-es.html.markdown b/es-es/coldfusion-es.html.markdown
new file mode 100644
index 00000000..2e98f910
--- /dev/null
+++ b/es-es/coldfusion-es.html.markdown
@@ -0,0 +1,330 @@
+---
+language: coldfusion
+filename: learncoldfusion-es.cfm
+contributors:
+ - ["Wayne Boka", "http://wboka.github.io"]
+ - ["Kevin Morris", "https://twitter.com/kevinmorris"]
+translators:
+ - ["Ivan Alburquerque", "https://github.com/AlburIvan"]
+lang: es-es
+---
+
+ColdFusion es un lenguaje de scripting para desarrollo web.
+[Lea más aquí](Http://www.adobe.com/products/coldfusion-family.html)
+
+### CFML
+_**C**old**F**usion **M**arkup **L**anguage_
+ColdFusion comenzó como un lenguaje basado en etiquetas. Casi toda la funcionalidad está disponible usando etiquetas.
+
+```cfm
+<em>Se han proporcionado etiquetas HTML para facilitar la lectura.</em>
+
+<!--- Los comentarios comienzan con "<!---" y terminan con "--->" --->
+<!---
+ Los comentarios
+ también
+ pueden ocupar
+ multiples líneas
+--->
+
+<!--- Las etiquetas CFML tienen un formato similar a las etiquetas HTML. --->
+<h1>Variables simples</h1>
+<!--- Declaración de variables: las variables son débilmente tipadas, similar a javascript --->
+<p>Set <b>miVariable</b> to "miValor"</p>
+<cfset miVariable = "miValor" />
+<p>Set <b>miNumero</b> to 3.14</p>
+<cfset miNumero = 3.14 />
+
+<!--- Mostrando datos simples --->
+<!--- Use <cfoutput> para valores simples como cadenas, números y expresiones --->
+<p>Muestra <b>miVariable</b>: <cfoutput>#miVariable#</cfoutput></p><!--- miValor --->
+<p>Muestra <b>miNumero</b>: <cfoutput>#miNumero#</cfoutput></p><!--- 3.14 --->
+
+<hr />
+
+<h1>Variables complejas</h1>
+<!--- Declarar variables complejas. --->
+<!--- Declarar una matriz de 1 dimensión: literal o notación de corchete --->
+<p>Establecer <b>miArreglo1</b> en una matriz de 1 dimensión utilizando la notación literal o de corchete</p>
+<cfset miArreglo1 = [] />
+<!--- Declarar una matriz de 1 dimensión: notación de función --->
+<p>Establecer <b> miArreglo2 </b> en una matriz de 1 dimensión usando la notación de funciones</p>
+<cfset miArreglo2 = ArrayNew(1) />
+
+<!--- Salida de variables complejas. --->
+<p>Contenidos de <b>miArreglo1</b></p>
+<cfdump var="#miArreglo1#" /> <!--- Un objeto de matriz vacío --->
+<p>Contenidos de <b>miArreglo2</b></p>
+<cfdump var="#miArreglo2#" /> <!--- Un objeto de matriz vacío --->
+
+<!--- Los operadores --->
+<!--- Aritméticos --->
+<h1>Operadores</h1>
+<h2>Aritméticos</h2>
+<p>1 + 1 = <cfoutput>#1 + 1#</cfoutput></p>
+<p>10 - 7 = <cfoutput>#10 - 7#<br /></cfoutput></p>
+<p>15 * 10 = <cfoutput>#15 * 10#<br /></cfoutput></p>
+<p>100 / 5 = <cfoutput>#100 / 5#<br /></cfoutput></p>
+<p>120 % 5 = <cfoutput>#120 % 5#<br /></cfoutput></p>
+<p>120 mod 5 = <cfoutput>#120 mod 5#<br /></cfoutput></p>
+
+<hr />
+
+<!--- Comparación --->
+<h2>Comparación</h2>
+<h3>Notación estándar</h3>
+<p>Is 1 eq 1? <cfoutput>#1 eq 1#</cfoutput></p>
+<p>Is 15 neq 1? <cfoutput>#15 neq 1#</cfoutput></p>
+<p>Is 10 gt 8? <cfoutput>#10 gt 8#</cfoutput></p>
+<p>Is 1 lt 2? <cfoutput>#1 lt 2#</cfoutput></p>
+<p>Is 10 gte 5? <cfoutput>#10 gte 5#</cfoutput></p>
+<p>Is 1 lte 5? <cfoutput>#1 lte 5#</cfoutput></p>
+
+<h3>Notación alternativa</h3>
+<p>Is 1 == 1? <cfoutput>#1 eq 1#</cfoutput></p>
+<p>Is 15 != 1? <cfoutput>#15 neq 1#</cfoutput></p>
+<p>Is 10 > 8? <cfoutput>#10 gt 8#</cfoutput></p>
+<p>Is 1 < 2? <cfoutput>#1 lt 2#</cfoutput></p>
+<p>Is 10 >= 5? <cfoutput>#10 gte 5#</cfoutput></p>
+<p>Is 1 <= 5? <cfoutput>#1 lte 5#</cfoutput></p>
+
+<hr />
+
+<!--- Estructuras de Control --->
+<h1>Estructuras de Control</h1>
+
+<cfset miCondicion = "Prueba" />
+
+<p>Condición a probar: "<cfoutput>#miCondicion#</cfoutput>"</p>
+
+<cfif miCondicion eq "Prueba">
+ <cfoutput>#miCondicion#. Estamos probando.</cfoutput>
+<cfelseif miCondicion eq "Producción">
+ <cfoutput>#miCondicion#. Procede con cuidado!!!</cfoutput>
+<cfelse>
+ miCondicion es desconocido
+</cfif>
+
+<hr />
+
+<!--- Bucles --->
+<h1>Bucles</h1>
+<h2>Bucle For</h2>
+<cfloop from="0" to="10" index="i">
+ <p>Index equals <cfoutput>#i#</cfoutput></p>
+</cfloop>
+
+<h2>Bucle For Each (Variables complejas)</h2>
+
+<p>Establecer <b>miArreglo3</b> to [5, 15, 99, 45, 100]</p>
+
+<cfset miArreglo3 = [5, 15, 99, 45, 100] />
+
+<cfloop array="#miArreglo3#" index="i">
+ <p>Index equals <cfoutput>#i#</cfoutput></p>
+</cfloop>
+
+<p>Establecer <b>myArray4</b> to ["Alpha", "Bravo", "Charlie", "Delta", "Echo"]</p>
+
+<cfset myArray4 = ["Alpha", "Bravo", "Charlie", "Delta", "Echo"] />
+
+<cfloop array="#myArray4#" index="s">
+ <p>Index equals <cfoutput>#s#</cfoutput></p>
+</cfloop>
+
+<h2>Declaración Switch</h2>
+
+<p>Establecer <b>miArreglo5</b> to [5, 15, 99, 45, 100]</p>
+
+<cfset miArreglo5 = [5, 15, 99, 45, 100] />
+
+<cfloop array="#miArreglo5#" index="i">
+ <cfswitch expression="#i#">
+ <cfcase value="5,15,45" delimiters=",">
+ <p><cfoutput>#i#</cfoutput> es un múltiplo de 5.</p>
+ </cfcase>
+ <cfcase value="99">
+ <p><cfoutput>#i#</cfoutput> es noventa y nueve.</p>
+ </cfcase>
+ <cfdefaultcase>
+ <p><cfoutput>#i#</cfoutput> no es 5, 15, 45, or 99.</p>
+ </cfdefaultcase>
+ </cfswitch>
+</cfloop>
+
+<hr />
+
+<h1>Conversión de tipos</h1>
+
+<style>
+ table.table th, table.table td {
+ border: 1px solid #000000;
+ padding: 2px;
+ }
+
+ table.table th {
+ background-color: #CCCCCC;
+ }
+</style>
+
+<table class="table" cellspacing="0">
+ <thead>
+ <tr>
+ <th>Valor</th>
+ <th>Como booleano</th>
+ <th>Como número</th>
+ <th>Como fecha</th>
+ <th>Como cadena</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <th>"Si"</th>
+ <td>TRUE</td>
+ <td>1</td>
+ <td>Error</td>
+ <td>"Si"</td>
+ </tr>
+ <tr>
+ <th>"No"</th>
+ <td>FALSE</td>
+ <td>0</td>
+ <td>Error</td>
+ <td>"No"</td>
+ </tr>
+ <tr>
+ <th>TRUE</th>
+ <td>TRUE</td>
+ <td>1</td>
+ <td>Error</td>
+ <td>"Yes"</td>
+ </tr>
+ <tr>
+ <th>FALSE</th>
+ <td>FALSE</td>
+ <td>0</td>
+ <td>Error</td>
+ <td>"No"</td>
+ </tr>
+ <tr>
+ <th>Número</th>
+ <td>True si el número no es 0; False de lo contrario.</td>
+ <td>Número</td>
+ <td>Consulte &#34;Date-time values&#34; anteriormente en este capítulo.</td>
+ <td>Representación de cadena del número (for example, &#34;8&#34;).</td>
+ </tr>
+ <tr>
+ <th>Cadena</th>
+ <td>Si representa una fecha y hora (ver la siguiente columna), se convierte al valor numérico del objeto de fecha y hora correspondiente. <br> Si es una fecha, hora o marca de tiempo ODBC (por ejemplo, "{ts '2001-06-14 11:30:13'}", o si se expresa en un formato de fecha u hora estándar de EE. UU., incluido al usar nombres de mes completos o abreviados, se convierte al valor de fecha y hora correspondiente. <br> Los días de la semana o la puntuación inusual dan como resultado un error. <br> Generalmente se permiten guiones, barras diagonales y espacios. </td>
+ <td>Cadena</td>
+ </tr>
+ <tr>
+ <th>Fecha</th>
+ <td>Error</td>
+ <td>El valor numérico del objeto fecha-hora.</td>
+ <td>Fecha</td>
+ <td>una marca de tiempo de ODBC.</td>
+ </tr>
+ </tbody>
+</table>
+
+<hr />
+
+<h1>Componentes</h1>
+
+<em>Código de referencia (las funciones deben devolver algo para admitir IE)</em>
+```
+```cfs
+<cfcomponent>
+ <cfset this.hola = "Hola" />
+ <cfset this.mundo = "Mundo" />
+
+ <cffunction name="sayHhola">
+ <cfreturn this.hola & ", " & this.mundo & "!" />
+ </cffunction>
+
+ <cffunction name="setHhola">
+ <cfargument name="newHola" type="string" required="true" />
+
+ <cfset this.hola = arguments.newHola />
+
+ <cfreturn true />
+ </cffunction>
+
+ <cffunction name="setMundo">
+ <cfargument name="newMundo" type="string" required="true" />
+
+ <cfset this.mundo = arguments.newMundo />
+
+ <cfreturn true />
+ </cffunction>
+
+ <cffunction name="getHola">
+ <cfreturn this.hola />
+ </cffunction>
+
+ <cffunction name="getMundo">
+ <cfreturn this.mundo />
+ </cffunction>
+</cfcomponent>
+
+<cfset this.hola = "Hola" />
+<cfset this.mundo = "Mundo" />
+
+<cffunction name="sayHola">
+ <cfreturn this.hola & ", " & this.mundo & "!" />
+</cffunction>
+
+<cffunction name="setHola">
+ <cfargument name="newHola" type="string" required="true" />
+
+ <cfset this.hola = arguments.newHola />
+
+ <cfreturn true />
+</cffunction>
+
+<cffunction name="setMundo">
+ <cfargument name="newMundo" type="string" required="true" />
+
+ <cfset this.mundo = arguments.newMundo />
+
+ <cfreturn true />
+</cffunction>
+
+<cffunction name="getHola">
+ <cfreturn this.hola />
+</cffunction>
+
+<cffunction name="getMundo">
+ <cfreturn this.mundo />
+</cffunction>
+
+
+<b>sayHola()</b>
+<cfoutput><p>#sayHola()#</p></cfoutput>
+<b>getHola()</b>
+<cfoutput><p>#getHola()#</p></cfoutput>
+<b>getMundo()</b>
+<cfoutput><p>#getMundo()#</p></cfoutput>
+<b>setHola("Hola")</b>
+<cfoutput><p>#setHola("Hola")#</p></cfoutput>
+<b>setMundo("mundo")</b>
+<cfoutput><p>#setMundo("mundo")#</p></cfoutput>
+<b>sayHola()</b>
+<cfoutput><p>#sayHola()#</p></cfoutput>
+<b>getHola()</b>
+<cfoutput><p>#getHola()#</p></cfoutput>
+<b>getMundo()</b>
+<cfoutput><p>#getMundo()#</p></cfoutput>
+```
+
+### CFScript
+_**C**old**F**usion **S**cript_
+En los últimos años, el lenguaje ColdFusion ha agregado sintaxis de script para simular la funcionalidad de etiquetas. Cuando se utiliza un servidor CF actualizado, casi todas las funciones están disponibles mediante la sintaxis de script.
+
+## Otras lecturas
+
+Los enlaces que se proporcionan a continuación son solo para comprender el tema, siéntase libre de buscar en Google y encuentrar ejemplos específicos.
+
+1. [Coldfusion Reference From Adobe](https://helpx.adobe.com/coldfusion/cfml-reference/topics.html)
+2. [Open Source Documentation](http://cfdocs.org/)
diff --git a/es-es/common-lisp-es.html.markdown b/es-es/common-lisp-es.html.markdown
new file mode 100644
index 00000000..526ea621
--- /dev/null
+++ b/es-es/common-lisp-es.html.markdown
@@ -0,0 +1,692 @@
+---
+
+language: "Common Lisp"
+filename: commonlisp-es.lisp
+contributors:
+ - ["Paul Nathan", "https://github.com/pnathan"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
+translators:
+ - ["ivanchoff", "https://github.com/ivanchoff"]
+ - ["Andre Polykanine", "https://github.com/Menelion"]
+lang: es-es
+---
+
+Common Lisp es un lenguaje de proposito general y multiparadigma adecuado para una amplia variedad
+de aplicaciones en la industria. Es frecuentemente referenciado como un lenguaje de programación
+programable.
+
+EL punto de inicio clásico es [Practical Common Lisp](http://www.gigamonkeys.com/book/). Otro libro
+popular y reciente es [Land of Lisp](http://landoflisp.com/). Un nuevo libro acerca de las mejores
+prácticas, [Common Lisp Recipes](http://weitz.de/cl-recipes/), fue publicado recientemente.
+
+```lisp
+
+;;;-----------------------------------------------------------------------------
+;;; 0. Sintaxis
+;;;-----------------------------------------------------------------------------
+
+;;; Forma general
+
+;;; CL tiene dos piezas fundamentales en su sintaxis: ATOM y S-EXPRESSION.
+;;; Típicamente, S-expressions agrupadas son llamadas `forms`.
+
+10 ; un atom; se evalua a sí mismo
+:thing ; otro atom; evaluando el símbolo :thing
+t ; otro atom, denotando true
+(+ 1 2 3 4) ; una s-expression
+'(4 :foo t) ; otra s-expression
+
+
+;;; Comentarios
+
+;;; comentarios de una sola línea empiezan con punto y coma; usa cuatro para
+;;; comentarios a nivel de archivo, tres para descripciones de sesiones, dos
+;;; adentro de definiciones, y una para líneas simples. Por ejemplo,
+
+;;;; life.lisp
+
+;;; Foo bar baz, porque quu quux. Optimizado para máximo krakaboom y umph.
+;;; Requerido por la función LINULUKO.
+
+(defun sentido (vida)
+ "Retorna el sentido de la vida calculado"
+ (let ((meh "abc"))
+ ;; llama krakaboom
+ (loop :for x :across meh
+ :collect x))) ; guarda valores en x, luego lo retorna
+
+;;; Comentarios de bloques, por otro lado, permiten comentarios de forma libre. estos son
+;;; delimitados con #| y |#
+
+#| Este es un comentario de bloque el cual
+ puede abarcar multiples líneas y
+ #|
+ estos pueden ser anidados
+ |#
+|#
+
+
+;;; Entorno
+
+;;; Existe una variedad de implementaciones; La mayoría son conformes a los estándares. SBCL
+;;; es un buen punto de inicio. Bibliotecas de terceros pueden instalarse fácilmente con
+;;; Quicklisp
+
+;;; CL es usualmente desarrollado y un bucle de Lectura-Evaluación-Impresión (REPL), corriendo
+;;; al mismo tiempo. El REPL permite la exploración interactiva del programa mientras este esta
+;;; corriendo
+
+
+;;;-----------------------------------------------------------------------------
+;;; 1. Operadores y tipos de datos primitivos
+;;;-----------------------------------------------------------------------------
+
+;;; Símbolos
+
+'foo ; => FOO Note que el símbolo es pasado a mayúsculas automáticamente.
+
+;;; INTERN manualmente crea un símbolo a partir de una cadena.
+
+(intern "AAAA") ; => AAAA
+(intern "aaa") ; => |aaa|
+
+;;; Números
+
+9999999999999999999999 ; enteros
+#b111 ; binario=> 7
+#o111 ; octal => 73
+#x111 ; hexadecimal => 273
+3.14159s0 ; simple
+3.14159d0 ; double
+1/2 ; proporciones
+#C(1 2) ; números complejos
+
+;;; las funciones son escritas como (f x y z ...) donde f es una función y
+;;; x, y, z, ... son los argumentos.
+
+(+ 1 2) ; => 3
+
+;;; Si deseas crear datos literales use QUOTE para prevenir que estos sean evaluados
+
+(quote (+ 1 2)) ; => (+ 1 2)
+(quote a) ; => A
+
+;;; La notación abreviada para QUOTE es '
+
+'(+ 1 2) ; => (+ 1 2)
+'a ; => A
+
+;;; Operaciones aritméticas básicas
+
+(+ 1 1) ; => 2
+(- 8 1) ; => 7
+(* 10 2) ; => 20
+(expt 2 3) ; => 8
+(mod 5 2) ; => 1
+(/ 35 5) ; => 7
+(/ 1 3) ; => 1/3
+(+ #C(1 2) #C(6 -4)) ; => #C(7 -2)
+
+;;; Boleanos
+
+t ; true; cualquier valor non-NIL es true
+nil ; false; también, la lista vacia: ()
+(not nil) ; => T
+(and 0 t) ; => T
+(or 0 nil) ; => 0
+
+;;; Caracteres
+
+#\A ; => #\A
+#\λ ; => #\GREEK_SMALL_LETTER_LAMDA
+#\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA
+
+;;; Cadenas son arreglos de caracteres de longitud fija
+
+"Hello, world!"
+"Benjamin \"Bugsy\" Siegel" ; la barra invertida es un carácter de escape
+
+;;; Las cadenas pueden ser concatenadas
+
+(concatenate 'string "Hello, " "world!") ; => "Hello, world!"
+
+;;; Una cadena puede ser tratada como una secuencia de caracteres
+
+(elt "Apple" 0) ; => #\A
+
+;;; FORMAT es usado para crear salidas formateadas, va desde simple interpolación de cadenas
+;;; hasta bucles y condicionales. El primer argumento de FORMAT determina donde irá la cadena
+;;; formateada. Si este es NIL, FORMAT simplemente retorna la cadena formateada como un valor;
+;;; si es T, FORMAT imprime a la salida estándar, usualmente la pantalla, luego este retorna NIL.
+
+(format nil "~A, ~A!" "Hello" "world") ; => "Hello, world!"
+(format t "~A, ~A!" "Hello" "world") ; => NIL
+
+
+;;;-----------------------------------------------------------------------------
+;;; 2. Variables
+;;;-----------------------------------------------------------------------------
+
+;;; Puedes crear una variable global (ámbito dinámico) usando DEFVAR y DEFPARAMETER
+;;; el nombre de la variable puede usar cualquier carácter excepto: ()",'`;#|\
+
+;;; La diferencia entre DEFVAR y DEFPARAMETER es que reevaluando una expresión
+;;; DEFVAR no cambia el valor de la variable. DEFPARAMETER, por otro lado sí lo hace.
+
+;;; Por convención, variables de ámbito dinámico tienen "orejeras" en sus nombres.
+
+(defparameter *some-var* 5)
+*some-var* ; => 5
+
+;;; Puedes usar también caracteres unicode.
+(defparameter *AΛB* nil)
+
+;;; Accediendo a una variable sin asignar tienen como resultado el error
+;;; UNBOUND-VARIABLE, sin embargo este es el comportamiento definido. no lo hagas
+
+;;; puedes crear enlaces locales con LET. en el siguiente código, `me` es asignado
+;;; con "dance with you" solo dentro de (let ...). LET siempre retorna el valor
+;;; del último `form`.
+
+(let ((me "dance with you")) me) ; => "dance with you"
+
+
+;;;-----------------------------------------------------------------------------;
+;;; 3. Estructuras y colecciones
+;;;-----------------------------------------------------------------------------;
+
+
+;;; Estructuras
+
+(defstruct dog name breed age)
+(defparameter *rover*
+ (make-dog :name "rover"
+ :breed "collie"
+ :age 5))
+*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
+(dog-p *rover*) ; => T
+(dog-name *rover*) ; => "rover"
+
+;;; DOG-P, MAKE-DOG, y DOG-NAME son creados automáticamente por DEFSTRUCT
+
+
+;;; Pares
+
+;;; CONS crea pares. CAR y CDR retornan la cabeza y la cola de un CONS-pair
+
+(cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB)
+(car (cons 'SUBJECT 'VERB)) ; => SUBJECT
+(cdr (cons 'SUBJECT 'VERB)) ; => VERB
+
+
+;;; Listas
+
+;;; Listas son estructuras de datos de listas enlazadas, hechas de pares CONS y terminan con un
+;;; NIL (o '()) para marcar el final de la lista
+
+(cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3)
+
+;;; LIST es una forma conveniente de crear listas
+
+(list 1 2 3) ; => '(1 2 3)
+
+;;; Cuando el primer argumento de CONS es un atom y el segundo argumento es una lista,
+;;; CONS retorna un nuevo par CONS con el primer argumento como el primer elemento y el
+;;; segundo argumento como el resto del par CONS
+
+(cons 4 '(1 2 3)) ; => '(4 1 2 3)
+
+;;; Use APPEND para unir listas
+
+(append '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;;; o CONCATENATE
+
+(concatenate 'list '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;;; las listas son un tipo de datos centrales en CL, por lo tanto hay una gran variedad
+;;; de funcionalidades para ellas, algunos ejemplos son:
+
+(mapcar #'1+ '(1 2 3)) ; => '(2 3 4)
+(mapcar #'+ '(1 2 3) '(10 20 30)) ; => '(11 22 33)
+(remove-if-not #'evenp '(1 2 3 4)) ; => '(2 4)
+(every #'evenp '(1 2 3 4)) ; => NIL
+(some #'oddp '(1 2 3 4)) ; => T
+(butlast '(subject verb object)) ; => (SUBJECT VERB)
+
+
+;;; Vectores
+
+;;; Vectores literales son arreglos de longitud fija
+
+#(1 2 3) ; => #(1 2 3)
+
+;;; Use CONCATENATE para juntar vectores
+
+(concatenate 'vector #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
+
+
+;;; Arreglos
+
+;;; Vectores y cadenas son casos especiales de arreglos.
+
+;;; Arreglos bidimensionales
+
+(make-array (list 2 2)) ; => #2A((0 0) (0 0))
+(make-array '(2 2)) ; => #2A((0 0) (0 0))
+(make-array (list 2 2 2)) ; => #3A(((0 0) (0 0)) ((0 0) (0 0)))
+
+;;; Precaución: los valores iniciales por defecto de MAKE-ARRAY son implementaciones definidas
+;;; para definirlos explícitamente:
+
+(make-array '(2) :initial-element 'unset) ; => #(UNSET UNSET)
+
+;;; Para acceder al elemento en 1, 1, 1:
+
+(aref (make-array (list 2 2 2)) 1 1 1) ; => 0
+
+;;; Este valor es definido por implementación:
+;;; NIL en ECL, 0 en SBCL and CCL.
+
+;;; vectores ajustables
+
+;;; los vectores ajustables tienen la misma representación en la impresión como los vectores literales
+;;; de longitud fija.
+
+(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3)
+ :adjustable t :fill-pointer t))
+*adjvec* ; => #(1 2 3)
+
+;;; Agregando nuevos elementos
+
+(vector-push-extend 4 *adjvec*) ; => 3
+*adjvec* ; => #(1 2 3 4)
+
+
+;;; Conjuntos, ingenuamente son listas:
+
+(set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1)
+(intersection '(1 2 3 4) '(4 5 6 7)) ; => 4
+(union '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1 4 5 6 7)
+(adjoin 4 '(1 2 3 4)) ; => (1 2 3 4)
+
+;;; Sin embargo, necesitarás una mejor estructura de datos que listas enlazadas
+;;; cuando trabajes con conjuntos de datos grandes
+
+;;; Los Diccionarios son implementados como tablas hash.
+
+;;; Crear tablas hash
+
+(defparameter *m* (make-hash-table))
+
+;;; definir valor
+
+(setf (gethash 'a *m*) 1)
+
+;;; obtener valor
+
+(gethash 'a *m*) ; => 1, T
+
+;;; las expresiones en CL tienen la facultad de retornar multiples valores.
+
+(values 1 2) ; => 1, 2
+
+;;; los cuales pueden ser asignados con MULTIPLE-VALUE-BIND
+
+(multiple-value-bind (x y)
+ (values 1 2)
+ (list y x))
+
+; => '(2 1)
+
+;;; GETHASH es un ejemplo de una función que retorna multiples valores. El primer
+;;; valor es el valor de la llave en la tabla hash: si la llave no existe retorna NIL.
+
+;;; El segundo valor determina si la llave existe en la tabla hash. si la llave no existe
+;;; en la tabla hash retorna NIL. Este comportamiento permite verificar si el valor de una
+;;; llave es actualmente NIL.
+
+;;; Obteniendo un valor no existente retorna NIL
+
+(gethash 'd *m*) ;=> NIL, NIL
+
+;;; Puedes declarar un valor por defecto para las llaves inexistentes
+
+(gethash 'd *m* :not-found) ; => :NOT-FOUND
+
+;;; Vamos a manejar los multiples valores de retornno en el código.
+
+(multiple-value-bind (a b)
+ (gethash 'd *m*)
+ (list a b))
+; => (NIL NIL)
+
+(multiple-value-bind (a b)
+ (gethash 'a *m*)
+ (list a b))
+; => (1 T)
+
+
+;;;-----------------------------------------------------------------------------
+;;; 3. Funciones
+;;;-----------------------------------------------------------------------------
+
+;;; Use LAMBDA para crear funciones anónimas. las funciones siempre retornan el valor
+;;; de la última expresión. la representación imprimible de una función varia entre
+;;; implementaciones.
+
+(lambda () "Hello World") ; => #<FUNCTION (LAMBDA ()) {1004E7818B}>
+
+;;; Use FUNCALL para llamar funciones anónimas.
+
+(funcall (lambda () "Hello World")) ; => "Hello World"
+(funcall #'+ 1 2 3) ; => 6
+
+;;; Un llamado a FUNCALL es también realizado cuando la expresión lambda es el CAR de
+;;; una lista.
+
+((lambda () "Hello World")) ; => "Hello World"
+((lambda (val) val) "Hello World") ; => "Hello World"
+
+;;; FUNCALL es usado cuando los argumentos son conocidos de antemano.
+;;; de lo contrario use APPLY
+
+(apply #'+ '(1 2 3)) ; => 6
+(apply (lambda () "Hello World") nil) ; => "Hello World"
+
+;;; Para nombrar una funcion use DEFUN
+
+(defun hello-world () "Hello World")
+(hello-world) ; => "Hello World"
+
+;;; Los () en la definición anterior son la lista de argumentos
+
+(defun hello (name) (format nil "Hello, ~A" name))
+(hello "Steve") ; => "Hello, Steve"
+
+;;; las functiones pueden tener argumentos opcionales; por defecto son NIL
+
+(defun hello (name &optional from)
+ (if from
+ (format t "Hello, ~A, from ~A" name from)
+ (format t "Hello, ~A" name)))
+
+(hello "Jim" "Alpacas") ; => Hello, Jim, from Alpacas
+
+;;; Los valores por defecto pueden ser especificados
+
+
+(defun hello (name &optional (from "The world"))
+ (format nil "Hello, ~A, from ~A" name from))
+
+(hello "Steve") ; => Hello, Steve, from The world
+(hello "Steve" "the alpacas") ; => Hello, Steve, from the alpacas
+
+;;; Las funciones también tienen argumentos llaves para permitir argumentos no positionados
+
+(defun generalized-greeter (name &key (from "the world") (honorific "Mx"))
+ (format t "Hello, ~A ~A, from ~A" honorific name from))
+
+(generalized-greeter "Jim")
+; => Hello, Mx Jim, from the world
+
+(generalized-greeter "Jim" :from "the alpacas you met last summer" :honorific "Mr")
+; => Hello, Mr Jim, from the alpacas you met last summer
+
+
+;;;-----------------------------------------------------------------------------
+;;; 4. Igualdad
+;;;-----------------------------------------------------------------------------
+
+;;; CL tiene un sistema sofisticado de igualdad. Una parte es tratada aquí.
+
+;;; Para números use `=`
+(= 3 3.0) ; => T
+(= 2 1) ; => NIL
+
+;;; Para identidad de objetos (aproximadamente) use EQL
+(eql 3 3) ; => T
+(eql 3 3.0) ; => NIL
+(eql (list 3) (list 3)) ; => NIL
+
+;;; para listas, cadenas y bit vectores use EQUAL
+(equal (list 'a 'b) (list 'a 'b)) ; => T
+(equal (list 'a 'b) (list 'b 'a)) ; => NIL
+
+
+;;;-----------------------------------------------------------------------------
+;;; 5. Control de flujo
+;;;-----------------------------------------------------------------------------
+
+;;; Condicionales
+
+(if t ; testar expresión
+ "this is true" ; then expression
+ "this is false") ; else expression
+; => "this is true"
+
+;;; En condicionales, todo valor non-NIL es tratado como true
+
+(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(GROUCHO ZEPPO)
+(if (member 'Groucho '(Harpo Groucho Zeppo))
+ 'yep
+ 'nope)
+; => 'YEP
+
+;;; COND en cadena una serie de pruebas para seleccionar un resultado
+(cond ((> 2 2) (error "wrong!"))
+ ((< 2 2) (error "wrong again!"))
+ (t 'ok)) ; => 'OK
+
+;;; TYPECASE evalua sobre el tipo del valor
+(typecase 1
+ (string :string)
+ (integer :int))
+; => :int
+
+
+;;; Bucles
+
+;;; Recursión
+
+(defun fact (n)
+ (if (< n 2)
+ 1
+ (* n (fact(- n 1)))))
+
+(fact 5) ; => 120
+
+;;; Iteración
+
+(defun fact (n)
+ (loop :for result = 1 :then (* result i)
+ :for i :from 2 :to n
+ :finally (return result)))
+
+(fact 5) ; => 120
+
+(loop :for x :across "abcd" :collect x)
+; => (#\a #\b #\c #\d)
+
+(dolist (i '(1 2 3 4))
+ (format t "~A" i))
+; => 1234
+
+
+;;;-----------------------------------------------------------------------------
+;;; 6. Mutación
+;;;-----------------------------------------------------------------------------
+
+;;; use SETF para asignar un valor nuevo a una variable existente. Esto fue demostrado
+;;; previamente en el ejemplo de la tabla hash.
+
+(let ((variable 10))
+ (setf variable 2))
+; => 2
+
+;;; Un estilo bueno de lisp es minimizar el uso de funciones destructivas y prevenir
+;;; la mutación cuando sea posible.
+
+
+;;;-----------------------------------------------------------------------------
+;;; 7. Clases y objetos
+;;;-----------------------------------------------------------------------------
+
+;;; No más clases de animales, tengamos transportes mecánicos impulsados por el humano
+
+(defclass human-powered-conveyance ()
+ ((velocity
+ :accessor velocity
+ :initarg :velocity)
+ (average-efficiency
+ :accessor average-efficiency
+ :initarg :average-efficiency))
+ (:documentation "A human powered conveyance"))
+
+;;; Los argumentos de DEFCLASS, en orden son:
+;;; 1. nombre de la clase
+;;; 2. lista de superclases
+;;; 3. slot list
+;;; 4. Especificadores opcionales
+
+;;; cuando no hay lista de superclase, la lista vacia indica clase de
+;;; objeto estándar, esto puede ser cambiado, pero no mientras no sepas
+;;; lo que estas haciendo. revisar el arte del protocolo de meta-objetos
+;;; para más información.
+
+(defclass bicycle (human-powered-conveyance)
+ ((wheel-size
+ :accessor wheel-size
+ :initarg :wheel-size
+ :documentation "Diameter of the wheel.")
+ (height
+ :accessor height
+ :initarg :height)))
+
+(defclass recumbent (bicycle)
+ ((chain-type
+ :accessor chain-type
+ :initarg :chain-type)))
+
+(defclass unicycle (human-powered-conveyance) nil)
+
+(defclass canoe (human-powered-conveyance)
+ ((number-of-rowers
+ :accessor number-of-rowers
+ :initarg :number-of-rowers)))
+
+;;; Invocando DESCRIBE en la clase HUMAN-POWERED-CONVEYANCE en REPL obtenemos:
+
+(describe 'human-powered-conveyance)
+
+; COMMON-LISP-USER::HUMAN-POWERED-CONVEYANCE
+; [symbol]
+;
+; HUMAN-POWERED-CONVEYANCE names the standard-class #<STANDARD-CLASS
+; HUMAN-POWERED-CONVEYANCE>:
+; Documentation:
+; A human powered conveyance
+; Direct superclasses: STANDARD-OBJECT
+; Direct subclasses: UNICYCLE, BICYCLE, CANOE
+; Not yet finalized.
+; Direct slots:
+; VELOCITY
+; Readers: VELOCITY
+; Writers: (SETF VELOCITY)
+; AVERAGE-EFFICIENCY
+; Readers: AVERAGE-EFFICIENCY
+; Writers: (SETF AVERAGE-EFFICIENCY)
+
+;;; Tenga en cuenta el comportamiento reflexivo disponible. CL fue diseñado
+;;; para ser un systema interactivo
+
+;;; para definir un método, encontremos la circunferencia de la rueda usando
+;;; la ecuación C = d * pi
+
+(defmethod circumference ((object bicycle))
+ (* pi (wheel-size object)))
+
+;;; PI es definido internamente en CL
+
+;;; Supongamos que descubrimos que el valor de eficiencia del número de remeros
+;;; en una canoa es aproximadamente logarítmico. Esto probablemente debería
+;;; establecerse en el constructor / inicializador.
+
+;;; Para inicializar su instancia después de que CL termine de construirla:
+
+(defmethod initialize-instance :after ((object canoe) &rest args)
+ (setf (average-efficiency object) (log (1+ (number-of-rowers object)))))
+
+;;; luego para construir una instancia y revisar la eficiencia promedio
+
+(average-efficiency (make-instance 'canoe :number-of-rowers 15))
+; => 2.7725887
+
+
+;;;-----------------------------------------------------------------------------
+;;; 8. Macros
+;;;-----------------------------------------------------------------------------
+
+;;; las Macros le permiten extender la sintaxis del lenguaje, CL no viene con
+;;; un bucle WHILE, por lo tanto es facil escribirlo, Si obedecemos nuestros
+;;; instintos de ensamblador, terminamos con:
+
+(defmacro while (condition &body body)
+ "While `condition` is true, `body` is executed.
+`condition` is tested prior to each execution of `body`"
+ (let ((block-name (gensym)) (done (gensym)))
+ `(tagbody
+ ,block-name
+ (unless ,condition
+ (go ,done))
+ (progn
+ ,@body)
+ (go ,block-name)
+ ,done)))
+
+;;; revisemos la versión de alto nivel para esto:
+
+(defmacro while (condition &body body)
+ "While `condition` is true, `body` is executed.
+`condition` is tested prior to each execution of `body`"
+ `(loop while ,condition
+ do
+ (progn
+ ,@body)))
+
+;;; Sin embargo, con un compilador moderno, esto no es necesario; El LOOP se
+;;; compila igualmente bien y es más fácil de leer.
+
+;;; Tenga en cuenta que se utiliza ```, así como `,` y `@`. ``` es un operador
+;;; de tipo de cita conocido como quasiquote; permite el uso de `,` . `,` permite
+;;; variables "entre comillas". @ interpola las listas.
+
+;;; GENSYM crea un símbolo único que garantiza que no existe en ninguna otra parte
+;;; del sistema. Esto se debe a que las macros se expanden en el momento de la compilación
+;;; y las variables declaradas en la macro pueden colisionar con las variables utilizadas
+;;; en un código regular.
+
+;;; Consulte Practical Common Lisp y On Lisp para obtener más información sobre macros.
+```
+
+
+## Otras Lecturas
+
+- [Practical Common Lisp](http://www.gigamonkeys.com/book/)
+- [Common Lisp: A Gentle Introduction to Symbolic Computation](https://www.cs.cmu.edu/~dst/LispBook/book.pdf)
+
+
+## Información extra
+
+- [CLiki](http://www.cliki.net/)
+- [common-lisp.net](https://common-lisp.net/)
+- [Awesome Common Lisp](https://github.com/CodyReichert/awesome-cl)
+- [Lisp Lang](http://lisp-lang.org/)
+
+
+## Creditos
+
+Muchas Gracias a la gente de Scheme por proveer un gran punto de inicio
+el cual puede ser movido fácilmente a Common Lisp
+
+- [Paul Khuong](https://github.com/pkhuong) para un buen repaso.
diff --git a/es-es/csharp-es.html.markdown b/es-es/csharp-es.html.markdown
index ef26d8ce..72a0f90c 100644
--- a/es-es/csharp-es.html.markdown
+++ b/es-es/csharp-es.html.markdown
@@ -1,12 +1,13 @@
---
-language: c#
+language: C#(C Sharp)
+filename: LearnCSharp-es.cs
contributors:
- ["Irfan Charania", "https://github.com/irfancharania"]
- ["Max Yankov", "https://github.com/golergka"]
translators:
- - ["Olfran Jiménez", "https://twitter.com/neslux"]
-filename: LearnCSharp-es.cs
+ - ["Olfran Jiménez", "https://twitter.com/neslux"]
lang: es-es
+
---
C# es un lenguaje orientado a objetos elegante y de tipado seguro que
diff --git a/es-es/css-es.html b/es-es/css-es.html
new file mode 100644
index 00000000..506a9467
--- /dev/null
+++ b/es-es/css-es.html
@@ -0,0 +1,327 @@
+---
+language: css
+contributors:
+ - ["Mohammad Valipour", "https://github.com/mvalipour"]
+ - ["Marco Scannadinari", "https://github.com/marcoms"]
+ - ["Geoffrey Liu", "https://github.com/g-liu"]
+ - ["Connor Shea", "https://github.com/connorshea"]
+ - ["Deepanshu Utkarsh", "https://github.com/duci9y"]
+ - ["Brett Taylor", "https://github.com/glutnix"]
+ - ["Tyler Mumford", "https://tylermumford.com"]
+translators:
+ - ["miky ackerman", "https://github.com/mikyackerman"]
+lang: es-es
+filename: learncss-es.css
+---
+
+Paginas web estan contruidas en HTML, lo cual especifica el contenido de una pagina
+CSS(Hoja de Estilos en Cascada) es un lenguaje separado el cual especifica
+la **apariencia** de una pagina.
+
+codigo CSS esta hecho de *reglas* estaticas. Cada regla toma uno o mas *selectores* y da *valores* especificos a un numero de *propiedades* visuales. Esas propiedades estan entonces aplicadas a los elementos indicados en una pagina por los selectores
+
+Esta guia ha sido escrita con CSS 2 en mente, la cual es extendida por una nueva caracterica de CSS 3.
+
+**NOTA:** Debido a que CSS produce resultados visuales, para aprenderlo, necesitas
+Probar todo en un patio de juegos CSS como [dabblet] (http://dabblet.com/).
+El objetivo principal de este artículo es la sintaxis y algunos consejos generales.
+
+## Sintaxis
+
+```css
+/* Los comentarios aparecen dentro de un diagonal-asterisco, justo como esta linea
+ no hay "comentarios en una linea"; este es el unico estilo de comentario.*/
+
+
+/* ####################
+ ## SELECTORS
+ #################### */
+
+/* el selector es usado para apuntar a un elemento de la pagina. */
+selector { property: value; /* more properties...*/ }
+
+/*
+Here is an example element:
+
+<div class='class1 class2' id='anID' attr='value' otherAttr='en-us foo bar' />
+*/
+
+/* You can target it using one of its CSS classes */
+.class1 { }
+
+/* or both classes! */
+.class1.class2 { }
+
+/* or its name */
+div { }
+
+/* or its id */
+#anID { }
+
+/* or using the fact that it has an attribute! */
+[attr] { font-size:smaller; }
+
+/* or that the attribute has a specific value */
+[attr='value'] { font-size:smaller; }
+
+/* starts with a value (CSS 3) */
+[attr^='val'] { font-size:smaller; }
+
+/* or ends with a value (CSS 3) */
+[attr$='ue'] { font-size:smaller; }
+
+/* or contains a value in a space-separated list */
+[otherAttr~='foo'] { }
+[otherAttr~='bar'] { }
+
+/* or contains a value in a dash-separated list, e.g., "-" (U+002D) */
+[otherAttr|='en'] { font-size:smaller; }
+
+
+/* You can combine different selectors to create a more focused selector. Don't
+ put spaces between them. */
+div.some-class[attr$='ue'] { }
+
+/* You can select an element which is a child of another element */
+div.some-parent > .class-name { }
+
+/* or a descendant of another element. Children are the direct descendants of
+ their parent element, only one level down the tree. Descendants can be any
+ level down the tree. */
+div.some-parent .class-name { }
+
+/* Warning: the same selector without a space has another meaning.
+ Can you guess what? */
+div.some-parent.class-name { }
+
+/* You may also select an element based on its adjacent sibling */
+.i-am-just-before + .this-element { }
+
+/* or any sibling preceding it */
+.i-am-any-element-before ~ .this-element { }
+
+/* There are some selectors called pseudo classes that can be used to select an
+ element only when it is in a particular state */
+
+/* for example, when the cursor hovers over an element */
+selector:hover { }
+
+/* or a link has been visited */
+selector:visited { }
+
+/* or hasn't been visited */
+selected:link { }
+
+/* or an element is in focus */
+selected:focus { }
+
+/* any element that is the first child of its parent */
+selector:first-child {}
+
+/* any element that is the last child of its parent */
+selector:last-child {}
+
+/* Just like pseudo classes, pseudo elements allow you to style certain parts of
+ a document */
+
+/* matches a virtual first child of the selected element */
+selector::before {}
+
+/* matches a virtual last child of the selected element */
+selector::after {}
+
+/* At appropriate places, an asterisk may be used as a wildcard to select every
+ element */
+* { } /* all elements */
+.parent * { } /* all descendants */
+.parent > * { } /* all children */
+
+/* ####################
+ ## PROPERTIES
+ #################### */
+
+selector {
+
+ /* Units of length can be absolute or relative. */
+
+ /* Relative units */
+ width: 50%; /* percentage of parent element width */
+ font-size: 2em; /* multiples of element's original font-size */
+ font-size: 2rem; /* or the root element's font-size */
+ font-size: 2vw; /* multiples of 1% of the viewport's width (CSS 3) */
+ font-size: 2vh; /* or its height */
+ font-size: 2vmin; /* whichever of a vh or a vw is smaller */
+ font-size: 2vmax; /* or greater */
+
+ /* Absolute units */
+ width: 200px; /* pixels */
+ font-size: 20pt; /* points */
+ width: 5cm; /* centimeters */
+ min-width: 50mm; /* millimeters */
+ max-width: 5in; /* inches */
+
+ /* Colors */
+ color: #F6E; /* short hex format */
+ color: #FF66EE; /* long hex format */
+ color: tomato; /* a named color */
+ color: rgb(255, 255, 255); /* as rgb values */
+ color: rgb(10%, 20%, 50%); /* as rgb percentages */
+ color: rgba(255, 0, 0, 0.3); /* as rgba values (CSS 3) Note: 0 <= a <= 1 */
+ color: transparent; /* equivalent to setting the alpha to 0 */
+ color: hsl(0, 100%, 50%); /* as hsl percentages (CSS 3) */
+ color: hsla(0, 100%, 50%, 0.3); /* as hsl percentages with alpha */
+
+ /* Borders */
+ border-width:5px;
+ border-style:solid;
+ border-color:red; /* similar to how background-color is set */
+ border: 5px solid red; /* this is a short hand approach for the same */
+ border-radius:20px; /* this is a CSS3 property */
+
+ /* Images as backgrounds of elements */
+ background-image: url(/img-path/img.jpg); /* quotes inside url() optional */
+
+ /* Fonts */
+ font-family: Arial;
+ /* if the font family name has a space, it must be quoted */
+ font-family: "Courier New";
+ /* if the first one is not found, the browser uses the next, and so on */
+ font-family: "Courier New", Trebuchet, Arial, sans-serif;
+}
+```
+
+## Usage
+
+Save a CSS stylesheet with the extension `.css`.
+
+```html
+<!-- You need to include the css file in your page's <head>. This is the
+ recommended method. Refer to http://stackoverflow.com/questions/8284365 -->
+<link rel='stylesheet' type='text/css' href='path/to/style.css'>
+
+<!-- You can also include some CSS inline in your markup. -->
+<style>
+ a { color: purple; }
+</style>
+
+<!-- Or directly set CSS properties on the element. -->
+<div style="border: 1px solid red;">
+</div>
+```
+
+## Precedence or Cascade
+
+An element may be targeted by multiple selectors and may have a property set on
+it in more than once. In these cases, one of the rules takes precedence over
+others. Rules with a more specific selector take precedence over a less specific
+one, and a rule occurring later in the stylesheet overwrites a previous one
+(which also means that if two different linked stylesheets contain rules for an
+element and if the rules are of the same specificity, then order of linking
+would take precedence and the sheet linked latest would govern styling) .
+
+This process is called cascading, hence the name Cascading Style Sheets.
+
+Given the following CSS:
+
+```css
+/* A */
+p.class1[attr='value']
+
+/* B */
+p.class1 { }
+
+/* C */
+p.class2 { }
+
+/* D */
+p { }
+
+/* E */
+p { property: value !important; }
+```
+
+and the following markup:
+
+```html
+<p style='/*F*/ property:value;' class='class1 class2' attr='value'>
+```
+
+The precedence of style is as follows. Remember, the precedence is for each
+**property**, not for the entire block.
+
+* `E` has the highest precedence because of the keyword `!important`. It is
+recommended that you avoid its usage.
+* `F` is next, because it is an inline style.
+* `A` is next, because it is more "specific" than anything else. It has 3
+ specifiers: The name of the element `p`, its class `class1`, an attribute
+ `attr='value'`.
+* `C` is next, even though it has the same specificity as `B`.
+ This is because it appears after `B`.
+* `B` is next.
+* `D` is the last one.
+
+## Media Queries
+
+CSS Media Queries are a feature in CSS 3 which allows you to specify when certain CSS rules should be applied, such as when printed, or when on a screen with certain dimensions or pixel density. They do not add to the selector's specificity.
+
+```css
+/* A rule that will be used on all devices */
+h1 {
+ font-size: 2em;
+ color: white;
+ background-color: black;
+}
+
+/* change the h1 to use less ink on a printer */
+@media print {
+ h1 {
+ color: black;
+ background-color: white;
+ }
+}
+
+/* make the font bigger when shown on a screen at least 480px wide */
+@media screen and (min-width: 480px) {
+ h1 {
+ font-size: 3em;
+ font-weight: normal;
+ }
+}
+```
+
+Media queries can include these features:
+`width`, `height`, `device-width`, `device-height`, `orientation`, `aspect-ratio`, `device-aspect-ratio`, `color`, `color-index`, `monochrome`, `resolution`, `scan`, `grid`. Most of these features can be prefixed with `min-` or `max-`.
+
+The `resolution` feature is not supported by older devices, instead use `device-pixel-ratio`.
+
+Many smartphones and tablets will attempt to render the page as if it were on a desktop unless you provide a `viewport` meta-tag.
+
+```html
+<head>
+ <meta name="viewport" content="width=device-width; initial-scale=1.0">
+</head>
+```
+
+## Compatibility
+
+Most of the features in CSS 2 (and many in CSS 3) are available across all
+browsers and devices. But it's always good practice to check before using
+a new feature.
+
+## Resources
+
+* [CanIUse](http://caniuse.com) (Detailed compatibility info)
+* [Dabblet](http://dabblet.com/) (CSS playground)
+* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS) (Tutorials and reference)
+* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/) (Reference)
+
+## Further Reading
+
+* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/)
+* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/)
+* [QuirksMode CSS](http://www.quirksmode.org/css/)
+* [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context)
+* [SASS](http://sass-lang.com/) and [LESS](http://lesscss.org/) for CSS pre-processing
+* [CSS-Tricks](https://css-tricks.com)
+
+
diff --git a/es-es/dart-es.html.markdown b/es-es/dart-es.html.markdown
new file mode 100644
index 00000000..d0f57b95
--- /dev/null
+++ b/es-es/dart-es.html.markdown
@@ -0,0 +1,529 @@
+---
+language: dart
+contributors:
+ - ["Joao Pedrosa", "https://github.com/jpedrosa/"]
+translators:
+ - ["Jorge Antonio Atempa", "http://www.twitter.com/atempa09"]
+filename: dart-es.md
+lang: es-es
+---
+
+Dart es un recién llegado al ámbito de los lenguajes de programación.
+Toma prestado mucho de otros lenguajes principales, con el objetivo de no desviarse demasiado de
+su hermano JavaScript. Tal como JavaScript, Dart tiene como objetivo una gran integración en el navegador.
+
+La característica más controvertida de Dart debe ser su escritura opcional.
+
+```dart
+import "dart:collection";
+import "dart:math" as DM;
+
+// Bienvenido a Aprende Dart en 15 minutos. http://www.dartlang.org/
+// Este es un tutorial ejecutable. Puedes ejecutarlo con Dart o en
+// el sitio de ¡Try Dart! solo copiando y pegando en http://try.dartlang.org/
+
+// La declaración de función y de método tienen el mismo aspecto.
+// Las funciones pueden estar anidadas.
+// La declaración toma la forma name() {} o name() => expresionEnUnaLinea;
+// La declaración de la función de flecha gorda, tiene un retorno implícito
+// para el resultado de la expresión.
+example1() {
+ nested1() {
+ nested2() => print("example1 anidado 1 anidado 2");
+ nested2();
+ }
+ nested1();
+}
+
+// Las funciones anónimas no incluyen un nombre.
+example2() {
+ nested1(fn) {
+ fn();
+ }
+ nested1(() => print("example2 anidado 1"));
+}
+
+// Cuando se declara un parámetro de función, la declaración puede incluir el
+// número de parámetros que toma la función especificando los nombres de los
+// parámetros que lleva.
+example3() {
+ planA(fn(informSomething)) {
+ fn("example3 plan A");
+ }
+ planB(fn) { // O no declarar el número de parámetros.
+ fn("example3 plan B");
+ }
+ planA((s) => print(s));
+ planB((s) => print(s));
+}
+
+// Las funciones tienen acceso de cierre a variables externas.
+var example4Something = "Example4 anidado 1";
+example4() {
+ nested1(fn(informSomething)) {
+ fn(example4Something);
+ }
+ nested1((s) => print(s));
+}
+
+// La declaración de la clase con un método sayIt, el cual también tiene acceso de cierre
+// a la variable exterior como si fuera una función como se ha visto antes.
+var example5method = "example5 sayIt";
+class Example5Class {
+ sayIt() {
+ print(example5method);
+ }
+}
+example5() {
+ // Crear una instancia anónima de Example5Class y la llamada del método sayIt
+ new Example5Class().sayIt();
+}
+
+// La declaración de clase toma la forma NombreDeClase { [cuerpoDeClase] }.
+// Donde cuerpoDeClase puede incluir métodos de instancia y variables, pero también
+// métodos y variables de clase.
+class Example6Class {
+ var instanceVariable = "Example6 variable de instancia";
+ sayIt() {
+ print(instanceVariable);
+ }
+}
+example6() {
+ new Example6Class().sayIt();
+}
+
+// Los métodos y variables de clase son declarados con términos "static".
+class Example7Class {
+ static var classVariable = "Example7 variable de clase";
+ static sayItFromClass() {
+ print(classVariable);
+ }
+ sayItFromInstance() {
+ print(classVariable);
+ }
+}
+example7() {
+ Example7Class.sayItFromClass();
+ new Example7Class().sayItFromInstance();
+}
+
+// Las literales son geniales, pero hay una restricción para lo que pueden ser las literales
+// fuera de los cuerpos de función/método. Literales en el ámbito exterior de clase
+// o fuera de clase tienen que ser constantes. Las cadenas de caracteres y los números
+// son constantes por defecto. Pero los arreglos y mapas no lo son.
+// Ellos pueden hacerse constante anteponiendo en la declaración el término "const".
+var example8Array = const ["Example8 arreglo constante"],
+ example8Map = const {"algunaKey": "Example8 mapa constante"};
+example8() {
+ print(example8Array[0]);
+ print(example8Map["algunaKey"]);
+}
+
+// Los bucles en Dart toman la forma estándar para for () {} o ciclos while () {} ,
+// ligeramente más moderno for (.. in ..) {}, o llamadas funcionales con muchas
+// características soportadas, comenzando con forEach.
+var example9Array = const ["a", "b"];
+example9() {
+ for (var i = 0; i < example9Array.length; i++) {
+ print("example9 ciclo for '${example9Array[i]}'");
+ }
+ var i = 0;
+ while (i < example9Array.length) {
+ print("example9 ciclo while '${example9Array[i]}'");
+ i++;
+ }
+ for (var e in example9Array) {
+ print("example9 ciclo for-in '${e}'");
+ }
+ example9Array.forEach((e) => print("example9 ciclo forEach '${e}'"));
+}
+
+// Para recorrer los caracteres de una cadena o para extraer una subcadena.
+var example10String = "ab";
+example10() {
+ for (var i = 0; i < example10String.length; i++) {
+ print("example10 Recorrido de caracteres en la cadena '${example10String[i]}'");
+ }
+ for (var i = 0; i < example10String.length; i++) {
+ print("example10 ciclo de subcadena '${example10String.substring(i, i + 1)}'");
+ }
+}
+
+// Formato de números Int y double son soportados.
+example11() {
+ var i = 1 + 320, d = 3.2 + 0.01;
+ print("example11 int ${i}");
+ print("example11 double ${d}");
+}
+
+// DateTime ofrece aritmética de fecha/hora.
+example12() {
+ var now = new DateTime.now();
+ print("example12 ahora '${now}'");
+ now = now.add(new Duration(days: 1));
+ print("example12 manana '${now}'");
+}
+
+// Expresiones regulares son soportadas.
+example13() {
+ var s1 = "alguna cadena", s2 = "alguna", re = new RegExp("^s.+?g\$");
+ match(s) {
+ if (re.hasMatch(s)) {
+ print("example13 regexp embona '${s}'");
+ } else {
+ print("example13 regexp no embona '${s}'");
+ }
+ }
+ match(s1);
+ match(s2);
+}
+
+// Las expresiones booleanas admiten conversiones implícitas y tipos dinámicos.
+example14() {
+ var a = true;
+ if (a) {
+ print("true, a is $a");
+ }
+ a = null;
+ if (a) {
+ print("true, a es $a");
+ } else {
+ print("false, a es $a"); // corre aquí
+ }
+
+ // el tipado dinámico null puede convertirse a bool
+ var b; // b es de tipo dinámico
+ b = "abc";
+ try {
+ if (b) {
+ print("true, b es $b");
+ } else {
+ print("false, b es $b");
+ }
+ } catch (e) {
+ print("error, b es $b"); // esto podría ser ejecutado pero consiguió error
+ }
+ b = null;
+ if (b) {
+ print("true, b es $b");
+ } else {
+ print("false, b es $b"); // corre aquí
+ }
+
+ // tipado estático null no puede ser convertido a bool
+ var c = "abc";
+ c = null;
+ // compilación fallida
+ // if (c) {
+ // print("true, c is $c");
+ // } else {
+ // print("false, c is $c");
+ // }
+}
+
+// try/catch/finally y throw son utilizados para el manejo de excepciones.
+// throw toma cualquier objeto como parámetro;
+example15() {
+ try {
+ try {
+ throw "Algun error inesperado.";
+ } catch (e) {
+ print("example15 una excepcion: '${e}'");
+ throw e; // Re-throw
+ }
+ } catch (e) {
+ print("example15 atrapa la excepcion que ha sido relanzada: '${e}'");
+ } finally {
+ print("example15 aún ejecuta finally");
+ }
+}
+
+// Para ser eficiente cuando creas una cadena larga dinámicamente, usa
+// StringBuffer. O podrías unir un arreglo de cadena de caracteres.
+example16() {
+ var sb = new StringBuffer(), a = ["a", "b", "c", "d"], e;
+ for (e in a) { sb.write(e); }
+ print("example16 cadena de caracteres dinamica creada con "
+ "StringBuffer '${sb.toString()}'");
+ print("example16 union de arreglo de cadena de caracteres '${a.join()}'");
+}
+
+// Las cadenas de caracteres pueden ser concatenadas contando solo
+// con literales una después de la otra sin algún otro operador necesario.
+example17() {
+ print("example17 "
+ "concatenar "
+ "cadenas "
+ "asi");
+}
+
+// Las cadenas de caracteres utilizan comilla simple o comillas dobles como delimitadores
+// sin ninguna diferencia entre ambas. Esto proporciona flexibilidad que puede ser efectiva
+// para evitar la necesidad de 'escapar' el contenido. Por ejemplo,
+// las dobles comillas de los atributos HTML.
+example18() {
+ print('Example18 <a href="etc">'
+ "Don't can't I'm Etc"
+ '</a>');
+}
+
+// Las cadenas de caracteres con triple comilla simple o triple comillas dobles
+// dividen múltiples lineas e incluyen como delimitador el salto de línea.
+example19() {
+ print('''Example19 <a href="etc">
+Example19 Don't can't I'm Etc
+Example19 </a>''');
+}
+
+// Las cadenas de caracteres cuentan con una extraordinaria característica
+// para la interpolación de caracteres utilizando el operador $
+// Con $ { [expresion] }, devolvemos la expresion interpolada.
+// $ seguido por el nombre de una variable interpola el contenido de dicha variable.
+// $ puede ser escapado con \$ para solo agregarlo a la cadena.
+example20() {
+ var s1 = "'\${s}'", s2 = "'\$s'";
+ print("Example20 \$ interpolation ${s1} or $s2 works.");
+}
+
+// Hasta ahora no hemos declarado ningún tipo de dato y los programas
+// han funcionado bien. De hecho, los tipos no se toman en cuenta durante
+// el tiempo de ejecución.
+// Los tipos incluso pueden estar equivocados y al programa todavía se le dará
+// el beneficio de la duda y se ejecutará como si los tipos no importaran.
+// Hay un parámetro de tiempo de ejecución que comprueba los errores de tipo que es
+// el modo de verificación, el cuál es útil durante el tiempo de desarrollo,
+// pero que también es más lento debido a la comprobación adicional y, por lo tanto
+// se evita durante el tiempo de ejecución de la implementación.
+class Example21 {
+ List<String> _names;
+ Example21() {
+ _names = ["a", "b"];
+ }
+ List<String> get names => _names;
+ set names(List<String> list) {
+ _names = list;
+ }
+ int get length => _names.length;
+ void add(String name) {
+ _names.add(name);
+ }
+}
+void example21() {
+ Example21 o = new Example21();
+ o.add("c");
+ print("example21 nombres '${o.names}' y longitud '${o.length}'");
+ o.names = ["d", "e"];
+ print("example21 nombres '${o.names}' y longitud '${o.length}'");
+}
+
+// La herencia de clases toma la forma NombreDeClase extends OtraClase {}.
+class Example22A {
+ var _name = "¡Algun Nombre!";
+ get name => _name;
+}
+class Example22B extends Example22A {}
+example22() {
+ var o = new Example22B();
+ print("example22 herencia de clase '${o.name}'");
+}
+
+// La mezcla de clases también esta disponible y toman la forma de
+// NombreDeClase extends AlgunaClase with OtraClase {}.
+// Es necesario extender de alguna clase para poder mezclar con otra.
+// La clase de plantilla de mixin no puede en este momento tener un constructor.
+// Mixin se utiliza principalmente para compartir métodos con clases distantes,
+// por lo que la herencia única no interfiere con el código reutilizable.
+// Mixins se colocan despues de la palabra "with" durante la declaración de la clase.
+class Example23A {}
+class Example23Utils {
+ addTwo(n1, n2) {
+ return n1 + n2;
+ }
+}
+class Example23B extends Example23A with Example23Utils {
+ addThree(n1, n2, n3) {
+ return addTwo(n1, n2) + n3;
+ }
+}
+example23() {
+ var o = new Example23B(), r1 = o.addThree(1, 2, 3),
+ r2 = o.addTwo(1, 2);
+ print("Example23 addThree(1, 2, 3) results in '${r1}'");
+ print("Example23 addTwo(1, 2) results in '${r2}'");
+}
+
+// El método constructor de la clase utiliza el mismo nombre de la clase
+// y toma la forma de AlgunaClase() : super() {}, donde la parte ": super()"
+// es opcional y es utilizado para delegar parametros constantes
+// al método constructor de la clase padre o super clase.
+class Example24A {
+ var _value;
+ Example24A({value: "algunValor"}) {
+ _value = value;
+ }
+ get value => _value;
+}
+class Example24B extends Example24A {
+ Example24B({value: "algunOtroValor"}) : super(value: value);
+}
+example24() {
+ var o1 = new Example24B(),
+ o2 = new Example24B(value: "aunMas");
+ print("example24 llama al método super desde el constructor '${o1.value}'");
+ print("example24 llama al método super desde el constructor '${o2.value}'");
+}
+
+// Hay un atajo para configurar los parámetros del constructor en el caso de clases más simples.
+// Simplemente use el prefijo this.nombreParametro y establecerá el parámetro
+// en una variable de instancia del mismo nombre.
+class Example25 {
+ var value, anotherValue;
+ Example25({this.value, this.anotherValue});
+}
+example25() {
+ var o = new Example25(value: "a", anotherValue: "b");
+ print("example25 atajo para el constructor '${o.value}' y "
+ "'${o.anotherValue}'");
+}
+
+// Los parámetros con nombre están disponibles cuando se declaran entre {}.
+// El orden de los parámetros puede ser opcional cuando se declara entre {}.
+// Los parámetros pueden hacerse opcionales cuando se declaran entre [].
+example26() {
+ var _name, _surname, _email;
+ setConfig1({name, surname}) {
+ _name = name;
+ _surname = surname;
+ }
+ setConfig2(name, [surname, email]) {
+ _name = name;
+ _surname = surname;
+ _email = email;
+ }
+ setConfig1(surname: "Doe", name: "John");
+ print("example26 name '${_name}', surname '${_surname}', "
+ "email '${_email}'");
+ setConfig2("Mary", "Jane");
+ print("example26 name '${_name}', surname '${_surname}', "
+ "email '${_email}'");
+}
+
+// Las variables declaradas con final solo se pueden establecer una vez.
+// En el caso de las clases, las variables de instancia final se pueden establecer
+// a través de la constante del parámetro constructor.
+class Example27 {
+ final color1, color2;
+ // Un poco de flexibilidad para establecer variables de instancia finales con la sintaxis
+ // que sigue a :
+ Example27({this.color1, color2}) : color2 = color2;
+}
+example27() {
+ final color = "orange", o = new Example27(color1: "lilac", color2: "white");
+ print("example27 color es '${color}'");
+ print("example27 color es '${o.color1}' y '${o.color2}'");
+}
+
+// Para importar una librería utiliza la palabra reservada import "rutaLibrería" o si es una biblioteca central,
+// import "dart:NombreLibrería". También está el "pub" administrador de paquetes con
+// su propia convensión import "package:NombrePaquete".
+// Ve import "dart:collection"; al inicio. Las importaciones deben venir antes
+// de la delcaración de algún otro código. IterableBase proviene de dart:collection.
+class Example28 extends IterableBase {
+ var names;
+ Example28() {
+ names = ["a", "b"];
+ }
+ get iterator => names.iterator;
+}
+example28() {
+ var o = new Example28();
+ o.forEach((name) => print("example28 '${name}'"));
+}
+
+// Para el control de flujo tenemos:
+// * estandard switch
+// * if-else if-else y el operador ternario ..?..:..
+// * closures y funciones anonimas
+// * sentencias break, continue y return
+example29() {
+ var v = true ? 30 : 60;
+ switch (v) {
+ case 30:
+ print("example29 sentencia switch");
+ break;
+ }
+ if (v < 30) {
+ } else if (v > 30) {
+ } else {
+ print("example29 sentencia if-else");
+ }
+ callItForMe(fn()) {
+ return fn();
+ }
+ rand() {
+ v = new DM.Random().nextInt(50);
+ return v;
+ }
+ while (true) {
+ print("example29 callItForMe(rand) '${callItForMe(rand)}'");
+ if (v != 30) {
+ break;
+ } else {
+ continue;
+ }
+ // Nunca llega aquí.
+ }
+}
+
+// La sentencia int.parse, convierte de tipo double a int, o simplemente mantener int cuando se dividen los números
+// utilizando ~/ como operación. Vamos a jugar un juego de adivinanzas también.
+example30() {
+ var gn, tooHigh = false,
+ n, n2 = (2.0).toInt(), top = int.parse("123") ~/ n2, bottom = 0;
+ top = top ~/ 6;
+ gn = new DM.Random().nextInt(top + 1); // +1 porque nextInt top es exclusivo
+ print("example30 Adivina un número entre 0 y ${top}");
+ guessNumber(i) {
+ if (n == gn) {
+ print("example30 ¡Adivinaste correctamente! El número es ${gn}");
+ } else {
+ tooHigh = n > gn;
+ print("example30 Número ${n} es demasiado "
+ "${tooHigh ? 'high' : 'low'}. Intenta nuevamente");
+ }
+ return n == gn;
+ }
+ n = (top - bottom) ~/ 2;
+ while (!guessNumber(n)) {
+ if (tooHigh) {
+ top = n - 1;
+ } else {
+ bottom = n + 1;
+ }
+ n = bottom + ((top - bottom) ~/ 2);
+ }
+}
+
+// Los programas tienen un solo punto de entrada en la función principal.
+// No se espera que se ejecute nada en el ámbito externo antes de que un programa
+// comience a funcionar con su función principal.
+// Esto ayuda con una carga más rápida e incluso con una carga lenta
+// de lo que necesita el programa para iniciar.
+main() {
+ print("Learn Dart in 15 minutes!");
+ [example1, example2, example3, example4, example5, example6, example7,
+ example8, example9, example10, example11, example12, example13, example14,
+ example15, example16, example17, example18, example19, example20,
+ example21, example22, example23, example24, example25, example26,
+ example27, example28, example29, example30
+ ].forEach((ef) => ef());
+}
+
+```
+
+## Lecturas adicionales
+
+Dart tiene un sitio web muy completo. Cubre referencias de API, tutoriales, artículos y más, incluyendo una
+útil sección en línea Try Dart.
+[https://www.dartlang.org](https://www.dartlang.org)
+[https://try.dartlang.org](https://try.dartlang.org)
diff --git a/es-es/dynamic-programming-es.html.markdown b/es-es/dynamic-programming-es.html.markdown
index 11930653..e613b722 100644
--- a/es-es/dynamic-programming-es.html.markdown
+++ b/es-es/dynamic-programming-es.html.markdown
@@ -8,47 +8,47 @@ translators:
lang: es-es
---
-# programación dinámica
+# Programación Dinámica
## Introducción
-La programación dinámica es una técnica poderosa usada para resolver una clase particular de problemas como veremos más adelante. La idea es muy simple, si usted ha solucionado un problema con la entrada dada, entonces , guardaremos el resultado para una futura referencia, con el fin de evitar la solución del mismo problema de nuevo.
+La programación dinámica es una técnica poderosa usada para resolver una clase particular de problemas como veremos más adelante.
+La idea es muy simple: si has solucionado un problema con la entrada dada, entonces, guardaremos el resultado para una futura referencia, con el fin de evitar la solución del mismo problema de nuevo.
-
-Recuerde siempre!!
+Recuerda siempre:
"Aquellos que no pueden recordar el pasado están condenados a repetirlo"
## Formas de resolver este tipo de problemas
-1.) De arriba hacia abajo : Empezamos resolviendo el problema dado descomponiendolo. Si ves que el problema fue resuelto, entonces retorna la respuesta guardada. si no se ha resuelto, resuélvelo y guarda la respuesta. Esto suele ser fácil pensar y muy intuitivo. Esto se conoce como memorización.
+1. *De arriba hacia abajo (Top-Down)* : Empezamos resolviendo el problema dado descomponiendolo. Si ves que el problema fue resuelto, entonces retorna la respuesta guardada. Si no se ha resuelto, resuélvelo y guarda la respuesta. Esto suele ser fácil de pensar y es muy intuitivo. A esto se le conoce como memoización.
-2.) De abajo hacia arriba : Analiza el problema y mira el orden en que los subproblemas deben ser resueltos y empieza resolviendo el subproblema más trivial, hacia el problema dado.En este proceso, se garantiza que los subproblemas se resuelven antes de resolver el problema. Esto se conoce como programación dinámica.
+2. *De abajo hacia arriba (Bottom-Up)* : Analiza el problema y ve el orden en que los subproblemas deben ser resueltos y empieza resolviendo el subproblema más trivial, hacia el problema dado. En este proceso, se garantiza que los subproblemas se resuelven antes de resolver el problema. Esto se conoce como Programación Dinámica.
## Ejemplo de Programación Dinámica
-El problema de la subsecuencia creciente máxima consiste en encontrar la subsecuencia creciente máxima en una secuencia dada . Dada la secuencia S= {a1 , a2 , a3, a4, ............., an-1, an } tenemos que encontrar un subconjunto más largo tal que para todo j y i, j <i en el subconjunto aj <ai.
-En primer lugar tenemos que encontrar el valor de las subsecuencias más largas (LSI) en cada índice con el último elemento de la secuencia que es ai. El mayor LSi sería la subsecuencia más larga de la secuencia dada. Para empezar LSI es asignado a uno ya que ai es un elemento de la secuencia(El último elemento).Entonces, para todo j tal que j <i aj <ai, nos encontramos con Lsj más grande y lo agregamos a la LSI. A continuación, el algoritmo toma un tiempo de O (n2).
-Pseudocódigo para encontrar la longitud de la más larga subsecuencia creciente:
-La complejidad de este algoritmos podría reducirse mediante el uso de una mejor estructura de datos en lugar de una array. Almacenamiento de una matriz predecesora y una variable como Secuencia_mas_Grande_hasta_ahora y su índice podría ahorrar mucho tiempo.
-concepto similar se podría aplicar en encontrar el camino más largo de grafo acíclico dirigido.
----------------------------------------------------------------------------
- for i=0 to n-1
- LS[i]=1
- for j=0 to i-1
- if (a[i] > a[j] and LS[i]<LS[j])
- LS[i] = LS[j]+1
- for i=0 to n-1
- if (largest < LS[i])
-
-### Algunos problemas famosos de Programación Dinámica (DP).
+El problema de la subsecuencia creciente máxima consiste en encontrar la subsecuencia creciente máxima en una secuencia dada. Dada la secuencia `S= {a1 , a2 , a3, a4, ............., an-1, an }`, tenemos que encontrar un subconjunto más largo tal que para todo `j` y `i`, `j<i` en el subconjunto `aj<ai`.
+En primer lugar tenemos que encontrar el valor de las subsecuencias más largas (LSi) en cada índice `i` con el último elemento de la secuencia que es `ai`. El mayor LSi sería la subsecuencia más larga de la secuencia dada. Para empezar, LSi=1 ya que `ai` es un elemento de la secuencia (el último elemento). Entonces, para todo `j` tal que `j<i` y `aj<ai`, encontramos el LSj más grande y lo agregamos al LSi, por lo que el algoritmo toma un tiempo de *O(n2)*.
+Pseudocódigo para encontrar la longitud de la subsecuencia creciente máxima:
+La complejidad de este algoritmo podría reducirse mediante el uso de una mejor estructura de datos que los arreglos. Guardar un arreglo de predecesores y una variable como `secuencia_mas_grande_hasta_ahora` y su índice podría ahorrar mucho tiempo.
+
+Un concepto similar se podría aplicar para encontrar la trayectoria más larga en un grafo acíclico dirigido (DAG).
+
+```python
+for i=0 to n-1
+ LS[i]=1
+ for j=0 to i-1
+ if (a[i] > a[j] and LS[i]<LS[j])
+ LS[i] = LS[j]+1
+for i=0 to n-1
+ if (largest < LS[i])
```
-Algoritmo Floyd Warshall(EN) - Tutorial y código fuente del programa en C:http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code
-
-Problema de la Mochila(EN) - Tutorial y código fuente del programa en C: http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem
+### Algunos problemas famosos de Programación Dinámica (DP).
-Problema de Subsecuencia Común mas Larga(EN) - Tutorial y código fuente del programa en C : http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence
+- Algoritmo Floyd Warshall(EN) - [Tutorial y código fuente del programa en C](http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code)
+- Problema de la Mochila(EN) - [Tutorial y código fuente del programa en C](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem)
+- Problema de Subsecuencia Común mas Larga(EN) - [Tutorial y código fuente del programa en C](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence)
## Recursos en línea
-* [codechef EN](https://www.codechef.com/wiki/tutorial-dynamic-programming) \ No newline at end of file
+* [codechef EN](https://www.codechef.com/wiki/tutorial-dynamic-programming)
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/es-es/erlang-es.html.markdown b/es-es/erlang-es.html.markdown
new file mode 100644
index 00000000..bc6317a5
--- /dev/null
+++ b/es-es/erlang-es.html.markdown
@@ -0,0 +1,293 @@
+---
+language: erlang
+lang: es-es
+contributors:
+ - ["Giovanni Cappellotto", "http://www.focustheweb.com/"]
+translators:
+ - ["Ernesto Pelayo", "http://github.com/ErnestoPelayo"]
+filename: learnerlang-es.erl
+---
+
+# Erlang
+% Signo de porcentaje inicia un comentario de una línea.
+
+%% Se usarán dos por ciento de caracteres para comentar funciones.
+
+%%% Se usarán tres por ciento de caracteres para comentar los módulos.
+
+### Utilizamos tres tipos de puntuación en Erlang.
+
++ **Comas (`,`)** argumentos separados en llamadas a funciones, constructores de
+datos y patrones.
+
++ **Periodos (`.`)** (seguido de espacios en blanco) separa funciones completas y
+expresiones en el shell.
+
++ **Semicolons (`;`)** cláusulas separadas. Encontramos cláusulas en varios contextos: de definiciones de funciones y en **`case`**,**` if`**, **`try..catch`**, y **` receive`** de expresiones.
+
+ ## 1.-Variables y coincidencia de patrones.
+
+
+- En Erlang, las nuevas variables están vinculadas con una instrucción **`=`**.
+>**Num = 42.**
+
+- Todos los nombres de variables deben comenzar con una letra mayúscula.
+
+- Erlang tiene variables de asignación única; si intentas asignar un diferente de valor a la variable **`Num`**, obtendrá un error.
+Num = 43. **error de excepción**: no coincide con el valor del lado derecho 43
+
+- En la mayoría de los idiomas, **`=`** denota una declaración de asignación. En Erlang, sin embargo,**`=`** denota una operación de coincidencia de patrones.
+
+- Cuando se usa una variable vacía en el del lado izquierdo del operador `=` to está vinculado (asignado), pero cuando está atado variable se usa en el lado izquierdo, se observa el siguiente comportamiento.
+>**`Lhs = Rhs`** realmente significa esto: evaluar el lado derecho (**` Rhs`**), y luego coincide con el resultado contra el patrón en el lado izquierdo (**`Lhs`**).
+>**Num = 7 * 6.**
+
+- Número de punto flotante.
+Pi = 3.14159.
+
+- Los átomos se usan para representar diferentes valores constantes no numéricos.
+
+- Átomos comienza con letras minúsculas, seguido de una secuencia de caracteres
+
+- alfanuméricos de caracteres o el signo de subrayado (**`_`**) o en (**` @ `**).
+>**Hola = hola.**
+ **OtherNode = ejemplo @ nodo.**
+
+- Los átomos con valores no alfanuméricos se pueden escribir al encerrar los átomos con apóstrofes.
+>**AtomWithSpace = 'algún átomo con espacio'.**
+
++ Tuples son similares a las estructuras en C.
+>**Point = {point, 10, 45}.**
+
+- Si queremos extraer algunos valores de una tupla, usamos el patrón de coincidencia
+ operador **`=`**.
+> **{punto, X, Y} = Punto. % X = 10, Y = 45**
+
+- Podemos usar **`_`** como marcador de posición para variables que no nos interesan.
+
+- El símbolo **`_`** se llama una variable anónima. A diferencia de las variables regulares,varias apariciones de `_` en el mismo patrón no tienen que vincularse a mismo valor.
+>**Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.**
+**{_, {_, {_, who }, _}, _} = Persona. % Who = joe**
+
++ Creamos una lista al encerrar los elementos de la lista entre corchetes y separándolos con comas.
+
++ Los elementos individuales de una lista pueden ser de cualquier tipo.
+
+- El primer elemento de una lista es el encabezado de la lista. Si te imaginas eliminar del encabezado de la lista, lo que queda se llama cola de la lista.
+>**ThingsToBuy = [{manzanas, 10}, {peras, 6}, {leche, 3}].**
+
+- Si `T` es una lista, entonces **` [H | T] `** también es una lista, con la cabeza **` H`** y la cola **`T`**.
+
++ La barra vertical (**`|`**) separa el encabezado de una lista de su cola.
+ **`[]`** es la lista vacía.
+
++ Podemos extraer elementos de una lista con una operación de coincidencia de
+ patrones. Si nosotros tiene una lista no vacía **`L`**, luego la expresión **` [X | Y] = L`**, donde **`X`** y **` Y`** son variables independientes, extraerán el encabezado de la lista en **`X`** y la cola de la lista en **`Y`**.
+>**[FirstThing | OtherThingsToBuy] = ThingsToBuy.**
+**FirstThing = {manzanas, 10}**
+**OtherThingsToBuy = [{peras, 6}, {leche, 3}]**
+
++ No hay cadenas en Erlang. Las cadenas son realmente solo listas de enteros.
+
++ Las cadenas están entre comillas dobles (**`" `**).
+>**Nombre = "Hola".
+[72, 101, 108, 108, 111] = "Hola".**
+
+## 2. Programación secuencial.
+
+
+- Los módulos son la unidad básica de código en Erlang. Todas las funciones que escribimos son almacenado en módulos.
+
+- Los módulos se almacenan en archivos con extensiones **`.erl`**.
+- Los módulos deben compilarse antes de poder ejecutar el código. Un módulo compilado tiene el extensión **`.beam`**.
+>**-módulo (geometría).
+-export ([area / 1]). de la lista de funciones exportadas desde el módulo.**
+
++ La función **`área`** consta de dos cláusulas. Las cláusulas están separadas por un punto y coma, y ​​la cláusula final termina con punto-espacio en blanco. Cada cláusula tiene una cabeza y un cuerpo; la cabeza consiste en un nombre de función seguido de un patrón (entre paréntesis), y el cuerpo consiste en una secuencia de expresiones, que se evalúan si el patrón en la cabeza es exitoso coincide con los argumentos de llamada. Los patrones se combinan en el orden aparecen en la definición de la función.
+>**área ({rectángulo, ancho, Ht}) -> ancho * Ht;
+área ({círculo, R}) -> 3.14159 * R * R** .
+
+ ### Compila el código en el archivo geometry.erl.
+c (geometría). {ok, geometría}
+
++ Necesitamos incluir el nombre del módulo junto con el nombre de la función para identifica exactamente qué función queremos llamar.
+>**geometría: área ({rectángulo, 10, 5}). % 50**
+**geometría: área ({círculo, 1.4}). % 6.15752**
+
++ En Erlang, dos funciones con el mismo nombre y arity diferente (número de argumentos) en el mismo módulo representan funciones completamente diferentes.
+>-**module (lib_misc)**.
+-**export ([sum / 1])**.
+
+- función de exportación **`suma`** de arity 1 acepta un argumento:
+>**lista de enteros.
+suma (L) -> suma (L, 0).
+suma ([], N) -> N;
+suma ([H | T], N) -> suma (T, H + N).**
++ Funs son funciones **"anónimas"**. Se llaman así porque tienen sin nombre. Sin embargo, pueden asignarse a variables.
+Doble = diversión (X) -> 2 * X final. **`Doble`** apunta a una función anónima con el controlador: **#Fun <erl_eval.6.17052888>
+Doble (2). % 4**
+
+- Functions acepta funs como sus argumentos y puede devolver funs.
+>**Mult = diversión (Times) -> (fun (X) -> X * Times end) end.
+Triple = Mult (3).
+Triple (5). % 15**
+
+- Las listas de comprensión son expresiones que crean listas sin tener que usar
+ funs, mapas o filtros.
+ - La notación **`[F (X) || X <- L] `** significa" la lista de **`F (X)`** donde se toma **`X`**% de la lista **`L`."**
+>**L = [1,2,3,4,5].
+[2 * X || X <- L]. % [2,4,6,8,10]**
+
+- Una lista de comprensión puede tener generadores y filtros, que seleccionan un subconjunto de los valores generados
+>**EvenNumbers = [N || N <- [1, 2, 3, 4], N rem 2 == 0]. % [2, 4]**
+
+- Los protectores son construcciones que podemos usar para aumentar el poder del patrón coincidencia. Usando guardias, podemos realizar pruebas simples y comparaciones en el de variables en un patrón.
+Puede usar guardias en la cabeza de las definiciones de funciones donde están introducido por la palabra clave **`when`**, o puede usarlos en cualquier lugar del lenguaje donde se permite una expresión.
+>**max (X, Y) cuando X> Y -> X;
+max (X, Y) -> Y.**
+
+- Un guardia es una serie de expresiones de guardia, separadas por comas (**`,`**).
+- La guardia **`GuardExpr1, GuardExpr2, ..., GuardExprN`** es verdadera si todos los guardias expresiones **`GuardExpr1`,` GuardExpr2`, ..., `GuardExprN`** evalúan **`true`**.
+>**is_cat (A) cuando is_atom (A), A =: = cat -> true;
+is_cat (A) -> false.
+is_dog (A) cuando is_atom (A), A =: = dog -> true;
+is_dog (A) -> false.**
+
+No nos detendremos en el operador **`=: =`** aquí; Solo tenga en cuenta que está acostumbrado a comprueba si dos expresiones de Erlang tienen el mismo valor * y * del mismo tipo. Contrasta este comportamiento con el del operador **`==`**:
+
+>**1 + 2 =: = 3.% true
+1 + 2 =: = 3.0. % false
+1 + 2 == 3.0. % true**
+
+ Una secuencia de guardia es una guardia individual o una serie de guardias, separadas por punto y coma (**`;`**). La secuencia de guardia **`G1; G2; ...; Gn`** es verdadero si en menos uno de los guardias **`G1`,` G2`, ..., `Gn`** se evalúa como **` true`**.
+>**is_pet (A) cuando is_atom (A), (A =: = dog); (A =: = cat) -> true;
+is_pet (A) -> false.**
+
+- **Advertencia**: no todas las expresiones de Erlang válidas se pueden usar como expresiones de guarda; en particular, nuestras funciones **`is_cat`** y **`is_dog`** no se pueden usar dentro del secuencia de protección en la definición de **`is_pet`**. Para una descripción de expresiones permitidas en secuencias de guarda, consulte la sección específica en el manual de referencia de Erlang:
+### http://erlang.org/doc/reference_manual/expressions.html#guards
+
+- Los registros proporcionan un método para asociar un nombre con un elemento particular en un de tupla De las definiciones de registros se pueden incluir en los archivos de código fuente de Erlang o poner en archivos con la extensión **`.hrl`**, que luego están incluidos en el código fuente de Erlang de archivos.
+
+>**-record (todo, {
+ status = recordatorio,% valor predeterminado
+ quien = joe,
+ texto
+}).**
+
+- Tenemos que leer las definiciones de registro en el shell antes de que podamos definir un
+ de registro. Usamos la función shell **`rr`** (abreviatura de los registros de lectura) para hacer esto.
+
+>**rr ("records.hrl").** % [que hacer]
+
+- **Creando y actualizando registros:**
+>**X = #todo {}.
+% #todo {status = recordatorio, who = joe, text = undefined}
+X1 = #todo {estado = urgente, texto = "Corregir errata en el libro"}.
+% #todo {status = urgent, who = joe, text = "Corregir errata en el libro"}
+X2 = X1 # todo {estado = hecho}.
+% #todo {status = done, who = joe, text = "Corregir errata en el libro"}
+expresiones `case`**.
+
+**`filter`** devuelve una lista de todos los elementos **` X`** en una lista **`L`** para la cual **` P (X) `** es true.
+>**filter(P, [H|T]) ->
+ case P(H) of
+ true -> [H|filter(P, T)];
+ false -> filter(P, T)
+ end;
+filter(P, []) -> [].
+filter(fun(X) -> X rem 2 == 0 end, [1, 2, 3, 4]). % [2, 4]**
+
+expresiones **`if`**.
+>**max(X, Y) ->
+ if
+ X > Y -> X;
+ X < Y -> Y;
+ true -> nil
+ end.**
+
+**Advertencia:** al menos uno de los guardias en la expresión **`if`** debe evaluar a **`true`**; de lo contrario, se generará una excepción.
+
+## 3. Excepciones.
+
+
+- El sistema genera excepciones cuando se encuentran errores internos o explícitamente en el código llamando **`throw (Exception)`**, **`exit (Exception)`**, o **`erlang: error (Exception)`**.
+>**generate_exception (1) -> a;
+generate_exception (2) -> throw (a);
+generate_exception (3) -> exit (a);
+generate_exception (4) -> {'EXIT', a};
+generate_exception (5) -> erlang: error (a).**
+
+- Erlang tiene dos métodos para atrapar una excepción. Una es encerrar la llamada a de la función que genera la excepción dentro de una expresión **`try ... catch`**.
+>**receptor (N) ->
+ prueba generar_excepción (N) de
+ Val -> {N, normal, Val}
+ captura
+ throw: X -> {N, atrapado, arrojado, X};
+ exit: X -> {N, atrapado, salido, X};
+ error: X -> {N, atrapado, error, X}
+ end.**
+
+- El otro es encerrar la llamada en una expresión **`catch`**. Cuando atrapas un de excepción, se convierte en una tupla que describe el error.
+>**catcher (N) -> catch generate_exception (N).**
+
+## 4. Concurrencia
+
+- Erlang se basa en el modelo de actor para concurrencia. Todo lo que necesitamos para escribir de programas simultáneos en Erlang son tres primitivos: procesos de desove, de envío de mensajes y recepción de mensajes.
+
+- Para comenzar un nuevo proceso, usamos la función **`spawn`**, que toma una función como argumento.
+
+>**F = diversión () -> 2 + 2 final. % #Fun <erl_eval.20.67289768>
+spawn (F). % <0.44.0>**
+
+- **`spawn`** devuelve un pid (identificador de proceso); puedes usar este pid para enviar de mensajes al proceso. Para pasar mensajes, usamos el operador **`!`**.
+
+- Para que todo esto sea útil, debemos poder recibir mensajes. Esto es logrado con el mecanismo **`receive`**:
+
+>**-module (calcular Geometría).
+-compile (export_all).
+calculateArea () ->
+ recibir
+ {rectángulo, W, H} ->
+ W * H;
+ {circle, R} ->
+ 3.14 * R * R;
+ _ ->
+ io: format ("Solo podemos calcular el área de rectángulos o círculos")
+ end.**
+
+- Compile el módulo y cree un proceso que evalúe **`calculateArea`** en cáscara.
+>**c (calcular Geometría).
+CalculateArea = spawn (calcular Geometría, calcular Área, []).
+CalculateArea! {círculo, 2}. % 12.56000000000000049738**
+
+- El shell también es un proceso; puedes usar **`self`** para obtener el pid actual.
+**self(). % <0.41.0>**
+
+## 5. Prueba con EUnit
+
+- Las pruebas unitarias se pueden escribir utilizando los generadores de prueba de EUnits y afirmar macros
+>**-módulo (fib).
+-export ([fib / 1]).
+-include_lib ("eunit / include / eunit.hrl").**
+
+>**fib (0) -> 1;
+fib (1) -> 1;
+fib (N) when N> 1 -> fib (N-1) + fib (N-2).**
+
+>**fib_test_ () ->
+ [? _assert (fib (0) =: = 1),
+ ? _assert (fib (1) =: = 1),
+ ? _assert (fib (2) =: = 2),
+ ? _assert (fib (3) =: = 3),
+ ? _assert (fib (4) =: = 5),
+ ? _assert (fib (5) =: = 8),
+ ? _assertException (error, function_clause, fib (-1)),
+ ? _assert (fib (31) =: = 2178309)
+ ]**
+
+- EUnit exportará automáticamente a una función de prueba () para permitir la ejecución de las pruebas en el shell Erlang
+fib: test ()
+
+- La popular barra de herramientas de construcción de Erlang también es compatible con EUnit
+**`` ` de la unidad de barras de refuerzo
+ ``**
diff --git a/es-es/factor-es.html.markdown b/es-es/factor-es.html.markdown
new file mode 100644
index 00000000..67c60de7
--- /dev/null
+++ b/es-es/factor-es.html.markdown
@@ -0,0 +1,200 @@
+---
+language: factor
+contributors:
+ - ["hyphz", "http://github.com/hyphz/"]
+translators:
+ - ["Roberto R", "https://github.com/rrodriguze"]
+filename: learnfactor-es.factor
+
+lang: es-es
+---
+Factor es un lenguaje moderno basado en la pila, basado en Forth, creado por
+Slava Pestov.
+
+El código de este archivo puede escribirse en Factor, pero no importa
+directamente porque el encabezado del vocabulario de importación haria que el
+comienzo fuera totalmente confuso.
+
+```factor
+! Esto es un comentario
+
+! Como Forth, toda la programación se realiza mediante la manipulación de la
+! pila.
+! La intruducción de un valor literal lo coloca en la pila
+5 2 3 56 76 23 65 ! No hay salida pero la pila se imprime en modo interactivo
+
+! Esos números se agregan a la pila de izquierda a derecha
+! .s imprime la pila de forma no destructiva.
+.s ! 5 2 3 56 76 23 65
+
+! La aritmética funciona manipulando datos en la pila.
+5 4 + ! Sem saída
+
+! `.` muestra el resultado superior de la pila y lo imprime.
+. ! 9
+
+! Más ejemplos de aritmética:
+6 7 * . ! 42
+1360 23 - . ! 1337
+12 12 / . ! 1
+13 2 mod . ! 1
+
+99 neg . ! -99
+-99 abs . ! 99
+52 23 max . ! 52
+52 23 min . ! 23
+
+! Se proporcionan varias palabras para manipular la pila, conocidas
+colectivamente como palabras codificadas.
+
+3 dup - ! duplica el primer item (1st ahora igual a 2nd): 3 - 3
+2 5 swap / ! intercambia el primero con el segundo elemento: 5 / 2
+4 0 drop 2 / ! elimina el primer item (no imprime en pantalla): 4 / 2
+1 2 3 nip .s ! elimina el segundo item (semejante a drop): 1 3
+1 2 clear .s ! acaba con toda la pila
+1 2 3 4 over .s ! duplica el segundo item superior: 1 2 3 4 3
+1 2 3 4 2 pick .s ! duplica el tercer item superior: 1 2 3 4 2 3
+
+! Creando Palabras
+! La palabra `:` factoriza los conjuntos en modo de compilación hasta que vea
+la palabra`;`.
+: square ( n -- n ) dup * ; ! Sin salida
+5 square . ! 25
+
+! Podemos ver lo que las palabra hacen también.
+! \ suprime la evaluación de una palabra y coloca su identificador en la pila.
+\ square see ! : square ( n -- n ) dup * ;
+
+! Después del nombre de la palabra para crear, la declaración entre paréntesis
+da efecto a la pila.
+! Podemos usar los nombres que queramos dentro de la declaración:
+: weirdsquare ( camel -- llama ) dup * ;
+
+! Mientras su recuento coincida con el efecto de pila de palabras:
+: doubledup ( a -- b ) dup dup ; ! Error: Stack effect declaration is wrong
+: doubledup ( a -- a a a ) dup dup ; ! Ok
+: weirddoubledup ( i -- am a fish ) dup dup ; ! Além disso Ok
+
+! Donde Factor difiere de Forth es en el uso de las citaciones.
+! Una citacion es un bloque de código que se coloca en la pila como un valor.
+! [ inicia el modo de citación; ] termina.
+[ 2 + ] ! La cita que suma dos queda en la pila
+4 swap call . ! 6
+
+! Y así, palabras de orden superior. TONOS de palabras de orden superior
+2 3 [ 2 + ] dip .s ! Tomar valor de la parte superior de la pilar, cotizar, retroceder: 4 3
+3 4 [ + ] keep .s ! Copiar el valor desde la parte superior de la pila, cotizar, enviar copia: 7 4
+1 [ 2 + ] [ 3 + ] bi .s ! Ejecute cada cotización en el valor superior, empuje amabos resultados: 3 4
+4 3 1 [ + ] [ + ] bi .s ! Las citas en un bi pueden extraer valores más profundos de la pila: 4 5 ( 1+3 1+4 )
+1 2 [ 2 + ] bi@ .s ! Citar en primer y segundo valor
+2 [ + ] curry ! Inyecta el valor dado al comienzo de la pila: [ 2 + ] se deja en la pila
+
+! Condicionales
+! Cualquier valor es verdadero, excepto el valor interno f.
+! no existe un valor interno, pero su uso no es esencial.
+! Los condicionales son palabras de orden superior, como con los combinadores
+! anteriores
+
+5 [ "Five is true" . ] when ! Cinco es verdadero
+0 [ "Zero is true" . ] when ! Cero es verdadero
+f [ "F is true" . ] when ! Sin salida
+f [ "F is false" . ] unless ! F es falso
+2 [ "Two is true" . ] [ "Two is false" . ] if ! Two es verdadero
+
+! Por defecto, los condicionales consumen el valor bajo prueba, pero las
+! variantes con un
+! asterisco se dejan solo si es verdad:
+
+5 [ . ] when* ! 5
+f [ . ] when* ! Sin salida, pila vacía, se consume porque f es falso
+
+
+! Lazos
+! Lo has adivinado... estas son palabras de orden superior también.
+
+5 [ . ] each-integer ! 0 1 2 3 4
+4 3 2 1 0 5 [ + . ] each-integer ! 0 2 4 6 8
+5 [ "Hello" . ] times ! Hello Hello Hello Hello Hello
+
+! Here's a list:
+{ 2 4 6 8 } ! Goes on the stack as one item
+
+! Aqui está uma lista:
+{ 2 4 6 8 } [ 1 + . ] each ! Exibe 3 5 7 9
+{ 2 4 6 8 } [ 1 + ] map ! Salida { 3 5 7 9 } de la pila
+
+! Reduzir laços ou criar listas:
+{ 1 2 3 4 5 } [ 2 mod 0 = ] filter ! Solo mantenga miembros de la lista para los cuales la cita es verdadera: { 2 4 }
+{ 2 4 6 8 } 0 [ + ] reduce . ! Como "fold" en lenguajes funcinales: exibe 20 (0+2+4+6+8)
+{ 2 4 6 8 } 0 [ + ] accumulate . . ! Como reducir, pero mantiene los valores intermedios en una lista: { 0 2 6 12 } así que 20
+1 5 [ 2 * dup ] replicate . ! Repite la cita 5 veces y recoge los resultados en una lista: { 2 4 8 16 32 }
+1 [ dup 100 < ] [ 2 * dup ] produce ! Repite la segunda cita hasta que la primera devuelva falso y recopile los resultados: { 2 4 8 16 32 64 128 }
+
+! Si todo lo demás falla, un propósito general a repetir.
+1 [ dup 10 < ] [ "Hello" . 1 + ] while ! Escribe "Hello" 10 veces
+ ! Sí, es dificil de leer
+ ! Para eso están los bucles variantes
+
+! Variables
+! Normalmente, se espera que los programas de Factor mantengan todos los datos
+! en la pila.
+! El uso de variables con nombre hace que la refactorización sea más difícil
+! (y se llama Factor por una razón)
+! Variables globales, si las necesitas:
+
+SYMBOL: name ! Crea un nombre como palabra de identificación
+"Bob" name set-global ! Sin salída
+name get-global . ! "Bob"
+
+! Las variables locales nombradas se consideran una extensión, pero están
+! disponibles
+! En una cita ..
+[| m n ! La cita captura los dos valores principales de la pila en m y n
+ | m n + ] ! Leerlos
+
+! Ou em uma palavra..
+:: lword ( -- ) ! Tenga en cuenta los dos puntos dobles para invocar la extensión de variable léxica
+ 2 :> c ! Declara la variable inmutable c para contener 2
+ c . ; ! Imprimirlo
+
+! En una palabra declarada de esta manera, el lado de entrada de la declaración
+! de la pila
+! se vuelve significativo y proporciona los valores de las variables en las que
+! se capturan los valores de pila
+:: double ( a -- result ) a 2 * ;
+
+! Las variables se declaran mutables al terminar su nombre con su signo de
+! exclamación
+:: mword2 ( a! -- x y ) ! Capture la parte superior de la pila en la variable mutable a
+ a ! Empujar a
+ a 2 * a! ! Multiplique por 2 y almacenar el resultado en a
+ a ; ! Empujar el nuevo valor de a
+5 mword2 ! Pila: 5 10
+
+! Listas y Secuencias
+! Vimos arriba cómo empujar una lista a la pila
+
+0 { 1 2 3 4 } nth ! Acceder a un miembro específico de una lista: 1
+10 { 1 2 3 4 } nth ! Error: índice de secuencia fuera de los límites
+1 { 1 2 3 4 } ?nth ! Lo mismo que nth si el índice está dentro de los límites: 2
+10 { 1 2 3 4 } ?nth ! Sin errores si está fuera de los límites: f
+
+{ "at" "the" "beginning" } "Append" prefix ! { "Append" "at" "the" "beginning" }
+{ "Append" "at" "the" } "end" suffix ! { "Append" "at" "the" "end" }
+"in" 1 { "Insert" "the" "middle" } insert-nth ! { "Insert" "in" "the" "middle" }
+"Concat" "enate" append ! "Concatenate" - strings are sequences too
+"Concatenate" "Reverse " prepend ! "Reverse Concatenate"
+{ "Concatenate " "seq " "of " "seqs" } concat ! "Concatenate seq of seqs"
+{ "Connect" "subseqs" "with" "separators" } " " join ! "Connect subseqs with separators"
+
+! Y si desea obtener meta, las citas son secuencias y se pueden desmontar
+0 [ 2 + ] nth ! 2
+1 [ 2 + ] nth ! +
+[ 2 + ] \ - suffix ! Quotation [ 2 + - ]
+
+
+```
+
+##Listo para más?
+
+* [Documentación de Factor](http://docs.factorcode.org/content/article-help.home.html)
diff --git a/es-es/fsharp-es.html.markdown b/es-es/fsharp-es.html.markdown
new file mode 100644
index 00000000..b7f80c44
--- /dev/null
+++ b/es-es/fsharp-es.html.markdown
@@ -0,0 +1,629 @@
+---
+language: F#
+lang: es-es
+contributors:
+ - ['Scott Wlaschin', 'http://fsharpforfunandprofit.com/']
+translators:
+ - ['Angel Arciniega', 'https://github.com/AngelsProjects']
+filename: learnfsharp-es.fs
+---
+
+F# es un lenguaje de programación funcional y orientado a objetos. Es gratis y su código fuente está abierto. Se ejecuta en Linux, Mac, Windows y más.
+
+Tiene un poderoso sistema de tipado que atrapa muchos errores de tiempo de compilación, pero usa inferencias de tipados que le permiten ser leídos como un lenguaje dinámico.
+
+La sintaxis de F# es diferente de los lenguajes que heredan de C.
+
+- Las llaves no se usan para delimitar bloques de código. En cambio, se usa sangría (como en Python).
+- Los espacios se usan para separar parámetros en lugar de comas.
+
+Si quiere probar el siguiente código, puede ir a [tryfsharp.org](http://www.tryfsharp.org/Create) y pegarlo en [REPL](https://es.wikipedia.org/wiki/REPL).
+
+```fsharp
+// Los comentarios de una línea se escibren con una doble diagonal
+(* Los comentarios multilínea usan parentesis (* . . . *)
+
+-final del comentario multilínea- *)
+
+// ================================================
+// Syntaxis básica
+// ================================================
+
+// ------ "Variables" (pero no realmente) ------
+// La palabra reservada "let" define un valor (inmutable)
+let miEntero = 5
+let miFlotante = 3.14
+let miCadena = "hola" // Tenga en cuenta que no es necesario ningún tipado
+
+// ------ Listas ------
+let dosACinco = [2;3;4;5] // Los corchetes crean una lista con
+ // punto y coma para delimitadores.
+let unoACinco = 1 :: dosACinco // :: Crea una lista con un nuevo elemento
+// El resultado es [1;2;3;4;5]
+let ceroACinco = [0;1] @ dosACinco // @ Concatena dos listas
+
+// IMPORTANTE: las comas no se usan para delimitar,
+// solo punto y coma !
+
+// ------ Funciones ------
+// La palabra reservada "let" también define el nombre de una función.
+let cuadrado x = x * x // Tenga en cuenta que no se usa paréntesis.
+cuadrado 3 // Ahora, ejecutemos la función.
+ // De nuevo, sin paréntesis.
+
+let agregar x y = x + y // ¡No use add (x, y)! Eso significa
+ // algo completamente diferente.
+agregar 2 3 // Ahora, ejecutemos la función.
+
+// Para definir una función en varias líneas, usemos la sangría.
+// Los puntos y coma no son necesarios.
+let pares lista =
+ let esPar x = x%2 = 0 // Establece "esPar" como una función anidada
+ List.filter esPar lista // List.filter es una función de la biblioteca
+ // dos parámetros: una función que devuelve un
+ // booleano y una lista en la que trabajar
+
+pares unoACinco // Ahora, ejecutemos la función.
+
+// Puedes usar paréntesis para aclarar.
+// En este ejemplo, "map" se ejecuta primero, con dos argumentos,
+// entonces "sum" se ejecuta en el resultado.
+// Sin los paréntesis, "List.map" se pasará como argumento a List.sum.
+let sumaDeCuadradosHasta100 =
+ List.sum ( List.map cuadrado [1..100] )
+
+// Puedes redirigir la salida de una función a otra con "|>"
+// Redirigir datos es muy común en F#, como con los pipes de UNIX.
+
+// Aquí está la misma función sumOfSquares escrita usando pipes
+let sumaDeCuadradosHasta100piped =
+ [1..100] |> List.map cuadrado |> List.sum // "cuadrado" se declara antes
+
+// Puede definir lambdas (funciones anónimas) gracias a la palabra clave "fun"
+let sumaDeCuadradosHasta100ConFuncion =
+ [1..100] |> List.map (fun x -> x*x) |> List.sum
+
+// En F#, no hay palabra clave "return". Una función siempre regresa
+// el valor de la última expresión utilizada.
+
+// ------ Coincidencia de patrones ------
+// Match..with .. es una sobrecarga de la condición de case/ switch.
+let coincidenciaDePatronSimple =
+ let x = "a"
+ match x with
+ | "a" -> printfn "x es a"
+ | "b" -> printfn "x es b"
+ | _ -> printfn "x es algo mas" // guion bajo corresponde con todos los demás
+
+// F# no permite valores nulos por defecto - debe usar el tipado de Option
+// y luego coincide con el patrón.
+// Some(..) y None son aproximadamente análogos a los envoltorios Nullable
+let valorValido = Some(99)
+let valorInvalido = None
+
+// En este ejemplo, match..with encuentra una coincidencia con "Some" y "None",
+// y muestra el valor de "Some" al mismo tiempo.
+let coincidenciaDePatronDeOpciones entrada =
+ match entrada with
+ | Some i -> printfn "la entrada es un int=%d" i
+ | None -> printfn "entrada faltante"
+
+coincidenciaDePatronDeOpciones validValue
+coincidenciaDePatronDeOpciones invalidValue
+
+// ------ Viendo ------
+// Las funciones printf/printfn son similares a las funciones
+// Console.Write/WriteLine de C#.
+printfn "Imprimiendo un int %i, a float %f, a bool %b" 1 2.0 true
+printfn "Un string %s, y algo generico %A" "hola" [1;2;3;4]
+
+// También hay funciones printf/sprintfn para formatear datos
+// en cadena. Es similar al String.Format de C#.
+
+// ================================================
+// Mas sobre funciones
+// ================================================
+
+// F# es un verdadero lenguaje funcional - las funciones son
+// entidades de primer nivel y se pueden combinar fácilmente
+// para crear construcciones poderosas
+
+// Los módulos se utilizan para agrupar funciones juntas.
+// Se requiere sangría para cada módulo anidado.
+module EjemploDeFuncion =
+
+ // define una función de suma simple
+ let agregar x y = x + y
+
+ // uso básico de una función
+ let a = agregar 1 2
+ printfn "1+2 = %i" a
+
+ // aplicación parcial para "hornear en" los parámetros (?)
+ let agregar42 = agregar 42
+ let b = agregar42 1
+ printfn "42+1 = %i" b
+
+ // composición para combinar funciones
+ let agregar1 = agregar 1
+ let agregar2 = agregar 2
+ let agregar3 = agregar1 >> agregar2
+ let c = agregar3 7
+ printfn "3+7 = %i" c
+
+ // funciones de primer nivel
+ [1..10] |> List.map agregar3 |> printfn "la nueva lista es %A"
+
+ // listas de funciones y más
+ let agregar6 = [agregar1; agregar2; agregar3] |> List.reduce (>>)
+ let d = agregar6 7
+ printfn "1+2+3+7 = %i" d
+
+// ================================================
+// Lista de colecciones
+// ================================================
+
+// Il y a trois types de collection ordonnée :
+// * Les listes sont les collections immutables les plus basiques
+// * Les tableaux sont mutables et plus efficients
+// * Les séquences sont lazy et infinies (e.g. un enumerator)
+//
+// Des autres collections incluent des maps immutables et des sets
+// plus toutes les collections de .NET
+
+module EjemplosDeLista =
+
+ // las listas utilizan corchetes
+ let lista1 = ["a";"b"]
+ let lista2 = "c" :: lista1 // :: para una adición al principio
+ let lista3 = lista1 @ lista2 // @ para la concatenación
+
+ // Lista de comprensión (alias generadores)
+ let cuadrados = [for i in 1..10 do yield i*i]
+
+ // Generador de números primos
+ let rec tamiz = function
+ | (p::xs) -> p :: tamiz [ for x in xs do if x % p > 0 then yield x ]
+ | [] -> []
+ let primos = tamiz [2..50]
+ printfn "%A" primos
+
+ // coincidencia de patrones para listas
+ let listaDeCoincidencias unaLista =
+ match unaLista with
+ | [] -> printfn "la lista esta vacia"
+ | [primero] -> printfn "la lista tiene un elemento %A " primero
+ | [primero; segundo] -> printfn "la lista es %A y %A" primero segundo
+ | _ -> printfn "la lista tiene mas de dos elementos"
+
+ listaDeCoincidencias [1;2;3;4]
+ listaDeCoincidencias [1;2]
+ listaDeCoincidencias [1]
+ listaDeCoincidencias []
+
+ // Récursion en utilisant les listes
+ let rec suma unaLista =
+ match unaLista with
+ | [] -> 0
+ | x::xs -> x + suma xs
+ suma [1..10]
+
+ // -----------------------------------------
+ // Funciones de la biblioteca estándar
+ // -----------------------------------------
+
+ // mapeo
+ let agregar3 x = x + 3
+ [1..10] |> List.map agregar3
+
+ // filtrado
+ let par x = x % 2 = 0
+ [1..10] |> List.filter par
+
+ // mucho más - consulte la documentación
+
+module EjemploDeArreglo =
+
+ // los arreglos usan corchetes con barras.
+ let arreglo1 = [| "a";"b" |]
+ let primero = arreglo1.[0] // se accede al índice usando un punto
+
+ // la coincidencia de patrones de los arreglos es la misma que la de las listas
+ let coincidenciaDeArreglos una Lista =
+ match unaLista with
+ | [| |] -> printfn "la matriz esta vacia"
+ | [| primero |] -> printfn "el arreglo tiene un elemento %A " primero
+ | [| primero; second |] -> printfn "el arreglo es %A y %A" primero segundo
+ | _ -> printfn "el arreglo tiene mas de dos elementos"
+
+ coincidenciaDeArreglos [| 1;2;3;4 |]
+
+ // La biblioteca estándar funciona como listas
+ [| 1..10 |]
+ |> Array.map (fun i -> i+3)
+ |> Array.filter (fun i -> i%2 = 0)
+ |> Array.iter (printfn "el valor es %i. ")
+
+module EjemploDeSecuencia =
+
+ // Las secuencias usan llaves
+ let secuencia1 = seq { yield "a"; yield "b" }
+
+ // Las secuencias pueden usar yield y
+    // puede contener subsecuencias
+ let extranio = seq {
+ // "yield" agrega un elemento
+ yield 1; yield 2;
+
+ // "yield!" agrega una subsecuencia completa
+ yield! [5..10]
+ yield! seq {
+ for i in 1..10 do
+ if i%2 = 0 then yield i }}
+ // prueba
+ extranio |> Seq.toList
+
+ // Las secuencias se pueden crear usando "unfold"
+    // Esta es la secuencia de fibonacci
+ let fib = Seq.unfold (fun (fst,snd) ->
+ Some(fst + snd, (snd, fst + snd))) (0,1)
+
+ // prueba
+ let fib10 = fib |> Seq.take 10 |> Seq.toList
+ printf "Los primeros 10 fib son %A" fib10
+
+// ================================================
+// Tipos de datos
+// ================================================
+
+module EejemploDeTipoDeDatos =
+
+ // Todos los datos son inmutables por defecto
+
+     // las tuplas son tipos anónimos simples y rápidos
+     // - Usamos una coma para crear una tupla
+ let dosTuplas = 1,2
+ let tresTuplas = "a",2,true
+
+ // Combinación de patrones para desempaquetar
+ let x,y = dosTuplas // asignado x=1 y=2
+
+ // ------------------------------------
+ // Los tipos de registro tienen campos con nombre
+ // ------------------------------------
+
+ // Usamos "type" con llaves para definir un tipo de registro
+ type Persona = {Nombre:string; Apellido:string}
+
+ // Usamos "let" con llaves para crear un registro
+ let persona1 = {Nombre="John"; Apellido="Doe"}
+
+ // Combinación de patrones para desempaquetar
+ let {Nombre=nombre} = persona1 // asignado nombre="john"
+
+ // ------------------------------------
+ // Los tipos de unión (o variantes) tienen un conjunto de elección
+     // Solo un caso puede ser válido a la vez.
+ // ------------------------------------
+
+ // Usamos "type" con barra/pipe para definir una unión estándar
+ type Temp =
+ | GradosC of float
+ | GradosF of float
+
+ // Una de estas opciones se usa para crear una
+ let temp1 = GradosF 98.6
+ let temp2 = GradosC 37.0
+
+ // Coincidencia de patrón en todos los casos para desempaquetar (?)
+ let imprimirTemp = function
+ | GradosC t -> printfn "%f gradC" t
+ | GradosF t -> printfn "%f gradF" t
+
+ imprimirTemp temp1
+ imprimirTemp temp2
+
+ // ------------------------------------
+ // Tipos recursivos
+ // ------------------------------------
+
+ // Los tipos se pueden combinar recursivamente de formas complejas
+    // sin tener que crear subclases
+ type Empleado =
+ | Trabajador of Persona
+ | Gerente of Empleado lista
+
+ let jdoe = {Nombre="John";Apellido="Doe"}
+ let trabajador = Trabajador jdoe
+
+ // ------------------------------------
+ // Modelado con tipados (?)
+ // ------------------------------------
+
+ // Los tipos de unión son excelentes para modelar el estado sin usar banderas (?)
+ type DireccionDeCorreo =
+ | DireccionDeCorreoValido of string
+ | DireccionDeCorreoInvalido of string
+
+ let intentarEnviarCorreo correoElectronico =
+ match correoElectronico with // uso de patrones de coincidencia
+ | DireccionDeCorreoValido direccion -> () // enviar
+ | DireccionDeCorreoInvalido direccion -> () // no enviar
+
+ // Combinar juntos, los tipos de unión y tipos de registro
+     // ofrece una base excelente para el diseño impulsado por el dominio.
+     // Puedes crear cientos de pequeños tipos que reflejarán fielmente
+     // el dominio.
+
+ type ArticuloDelCarrito = { CodigoDelProducto: string; Cantidad: int }
+ type Pago = Pago of float
+ type DatosActivosDelCarrito = { ArticulosSinPagar: ArticuloDelCarrito lista }
+ type DatosPagadosDelCarrito = { ArticulosPagados: ArticuloDelCarrito lista; Pago: Pago}
+
+ type CarritoDeCompras =
+ | CarritoVacio // sin datos
+ | CarritoActivo of DatosActivosDelCarrito
+ | CarritoPagado of DatosPagadosDelCarrito
+
+ // ------------------------------------
+ // Comportamiento nativo de los tipos
+ // ------------------------------------
+
+ // Los tipos nativos tienen el comportamiento más útil "listo para usar", sin ningún código para agregar.
+     // * Inmutabilidad
+     // * Bonita depuración de impresión
+     // * Igualdad y comparación
+     // * Serialización
+
+     // La impresión bonita se usa con %A
+ printfn "dosTuplas=%A,\nPersona=%A,\nTemp=%A,\nEmpleado=%A"
+ dosTuplas persona1 temp1 trabajador
+
+ // La igualdad y la comparación son innatas
+     // Aquí hay un ejemplo con tarjetas.
+ type JuegoDeCartas = Trebol | Diamante | Espada | Corazon
+ type Rango = Dos | Tres | Cuatro | Cinco | Seis | Siete | Ocho
+ | Nueve | Diez | Jack | Reina | Rey | As
+
+ let mano = [ Trebol,As; Corazon,Tres; Corazon,As;
+ Espada,Jack; Diamante,Dos; Diamante,As ]
+
+ // orden
+ List.sort mano |> printfn "la mano ordenada es (de menos a mayor) %A"
+ List.max mano |> printfn "la carta más alta es%A"
+ List.min mano |> printfn "la carta más baja es %A"
+
+// ================================================
+// Patrones activos
+// ================================================
+
+module EjemplosDePatronesActivos =
+
+ // F# tiene un tipo particular de coincidencia de patrón llamado "patrones activos"
+    // donde el patrón puede ser analizado o detectado dinámicamente.
+
+    // "clips de banana" es la sintaxis de los patrones activos
+
+    // por ejemplo, definimos un patrón "activo" para que coincida con los tipos de "caracteres" ...
+ let (|Digito|Latra|EspacioEnBlanco|Otros|) ch =
+ if System.Char.IsDigit(ch) then Digito
+ else if System.Char.IsLetter(ch) then Letra
+ else if System.Char.IsWhiteSpace(ch) then EspacioEnBlanco
+ else Otros
+
+ // ... y luego lo usamos para hacer que la lógica de análisis sea más clara
+ let ImprimirCaracter ch =
+ match ch with
+ | Digito -> printfn "%c es un Digito" ch
+ | Letra -> printfn "%c es una Letra" ch
+ | Whitespace -> printfn "%c es un Espacio en blanco" ch
+ | _ -> printfn "%c es algo mas" ch
+
+ // ver una lista
+ ['a';'b';'1';' ';'-';'c'] |> List.iter ImprimirCaracter
+
+ // -----------------------------------------
+ // FizzBuzz usando patrones activos
+ // -----------------------------------------
+
+ // Puede crear un patrón de coincidencia parcial también
+    // Solo usamos un guión bajo en la definición y devolvemos Some si coincide.
+ let (|MultDe3|_|) i = if i % 3 = 0 then Some MultDe3 else None
+ let (|MultDe5|_|) i = if i % 5 = 0 then Some MultDe5 else None
+
+ // la función principal
+ let fizzBuzz i =
+ match i with
+ | MultDe3 & MultDe5 -> printf "FizzBuzz, "
+ | MultDe3 -> printf "Fizz, "
+ | MultDe5 -> printf "Buzz, "
+ | _ -> printf "%i, " i
+
+ // prueba
+ [1..20] |> List.iter fizzBuzz
+
+// ================================================
+// concisión
+// ================================================
+
+module EjemploDeAlgoritmo =
+
+ // F# tiene una alta relación señal / ruido, lo que permite leer el código
+    // casi como un algoritmo real
+
+ // ------ Ejemplo: definir una función sumaDeCuadrados ------
+ let sumaDeCuadrados n =
+ [1..n] // 1) Tome todos los números del 1 al n
+ |> List.map cuadrado // 2) Elevar cada uno de ellos al cuadrado
+ |> List.sum // 3) Realiza su suma
+
+ // prueba
+ sumaDeCuadrados 100 |> printfn "Suma de cuadrados = %A"
+
+ // ------ Ejemplo: definir una función de ordenación ------
+ let rec ordenar lista =
+ match lista with
+ // Si la lista está vacía
+ | [] ->
+ [] // devolvemos una lista vacía
+       // si la lista no está vacía
+ | primerElemento::otrosElementos -> // tomamos el primer elemento
+ let elementosMasPequenios = // extraemos los elementos más pequeños
+ otrosElementos // tomamos el resto
+ |> List.filter (fun e -> e < primerElemento)
+ |> ordenar // y los ordenamos
+ let elementosMasGrandes = // extraemos el mas grande
+ otrosElementos // de los que permanecen
+ |> List.filter (fun e -> e >= primerElemento)
+ |> ordenar // y los ordenamos
+ // Combinamos las 3 piezas en una nueva lista que devolvemos
+ List.concat [elementosMasPequenios; [primerElemento]; elementosMasGrandes]
+
+ // prueba
+ ordenar [1;5;23;18;9;1;3] |> printfn "Ordenado = %A"
+
+// ================================================
+// Código asíncrono
+// ================================================
+
+module AsyncExample =
+
+ // F# incluye características para ayudar con el código asíncrono
+    // sin conocer la "pirámide del destino"
+    //
+    // El siguiente ejemplo descarga una secuencia de página web en paralelo.
+
+ open System.Net
+ open System
+ open System.IO
+ open Microsoft.FSharp.Control.CommonExtensions
+
+ // Recuperar el contenido de una URL de forma asincrónica
+ let extraerUrlAsync url =
+ async { // La palabra clave "async" y llaves
+ // crear un objeto "asincrónico"
+ let solicitud = WebRequest.Create(Uri(url))
+ use! respuesta = solicitud.AsyncGetResponse()
+ // use! es una tarea asincrónica
+ use flujoDeDatos = resp.GetResponseStream()
+ // "use" dispara automáticamente la funcion close()
+ // en los recursos al final de las llaves
+ use lector = new IO.StreamReader(flujoDeDatos)
+ let html = lector.ReadToEnd()
+ printfn "terminó la descarga %s" url
+ }
+
+ // una lista de sitios para informar
+ let sitios = ["http://www.bing.com";
+ "http://www.google.com";
+ "http://www.microsoft.com";
+ "http://www.amazon.com";
+ "http://www.yahoo.com"]
+
+ // ¡Aqui vamos!
+ sitios
+ |> List.map extraerUrlAsync // crear una lista de tareas asíncrona
+ |> Async.Parallel // decirle a las tareas que se desarrollan en paralelo
+ |> Async.RunSynchronously // ¡Empieza!
+
+// ================================================
+// Compatibilidad .NET
+// ================================================
+
+module EjemploCompatibilidadNet =
+
+ // F# puede hacer casi cualquier cosa que C# pueda hacer, y se ajusta
+    // perfectamente con bibliotecas .NET o Mono.
+
+  // ------- Trabaja con las funciones de las bibliotecas existentes -------
+
+ let (i1success,i1) = System.Int32.TryParse("123");
+ if i1success then printfn "convertido como %i" i1 else printfn "conversion fallida"
+
+ // ------- Implementar interfaces sobre la marcha! -------
+
+ // Crea un nuevo objeto que implemente IDisposable
+ let crearRecurso name =
+ { new System.IDisposable
+ with member this.Dispose() = printfn "%s creado" name }
+
+ let utilizarYDisponerDeRecursos =
+ use r1 = crearRecurso "primer recurso"
+ printfn "usando primer recurso"
+ for i in [1..3] do
+ let nombreDelRecurso = sprintf "\tinner resource %d" i
+ use temp = crearRecurso nombreDelRecurso
+ printfn "\thacer algo con %s" nombreDelRecurso
+ use r2 = crearRecurso "segundo recurso"
+ printfn "usando segundo recurso"
+ printfn "hecho."
+
+ // ------- Código orientado a objetos -------
+
+ // F# es también un verdadero lenguaje OO.
+    // Admite clases, herencia, métodos virtuales, etc.
+
+ // interfaz de tipo genérico
+ type IEnumerator<'a> =
+ abstract member Actual : 'a
+ abstract MoverSiguiente : unit -> bool
+
+ // Clase base abstracta con métodos virtuales
+ [<AbstractClass>]
+ type Figura() =
+ // propiedades de solo lectura
+ abstract member Ancho : int with get
+ abstract member Alto : int with get
+ // método no virtual
+ member this.AreaDelimitadora = this.Alto * this.Ancho
+ // método virtual con implementación de la clase base
+ abstract member Imprimir : unit -> unit
+ default this.Imprimir () = printfn "Soy una Figura"
+
+ // clase concreta que hereda de su clase base y sobrecarga
+ type Rectangulo(x:int, y:int) =
+ inherit Figura()
+ override this.Ancho = x
+ override this.Alto = y
+ override this.Imprimir () = printfn "Soy un Rectangulo"
+
+ // prueba
+ let r = Rectangulo(2,3)
+ printfn "La anchura es %i" r.Ancho
+ printfn "El area es %i" r.AreaDelimitadora
+ r.Imprimir()
+
+ // ------- extensión de método -------
+
+ // Al igual que en C#, F# puede extender las clases existentes con extensiones de método.
+ type System.String with
+ member this.EmpiezaConA = this.EmpiezaCon "A"
+
+ // prueba
+ let s = "Alice"
+ printfn "'%s' empieza con una 'A' = %A" s s.EmpiezaConA
+
+ // ------- eventos -------
+
+ type MiBoton() =
+ let eventoClick = new Event<_>()
+
+ [<CLIEvent>]
+ member this.AlHacerClick = eventoClick.Publish
+
+ member this.PruebaEvento(arg) =
+ eventoClick.Trigger(this, arg)
+
+ // prueba
+ let miBoton = new MiBoton()
+ miBoton.AlHacerClick.Add(fun (sender, arg) ->
+ printfn "Haga clic en el evento con arg=%O" arg)
+
+ miBoton.PruebaEvento("Hola Mundo!")
+```
+
+## Más información
+
+Para más demostraciones de F#, visite el sitio [Try F#](http://www.tryfsharp.org/Learn), o sigue la serie [why use F#](http://fsharpforfunandprofit.com/why-use-fsharp/).
+
+Aprenda más sobre F# en [fsharp.org](http://fsharp.org/).
diff --git a/es-es/git-es.html.markdown b/es-es/git-es.html.markdown
index 1a8e275a..749365d1 100644
--- a/es-es/git-es.html.markdown
+++ b/es-es/git-es.html.markdown
@@ -1,11 +1,11 @@
---
category: tool
tool: git
+filename: LearnGit-es.txt
contributors:
- ["Jake Prather", "http://github.com/JakeHP"]
translator:
- ["Raúl Ascencio", "http://rscnt.github.io"]
-filename: LearnGit.txt
lang: es-es
---
diff --git a/es-es/go-es.html.markdown b/es-es/go-es.html.markdown
index c41d693d..78267695 100644
--- a/es-es/go-es.html.markdown
+++ b/es-es/go-es.html.markdown
@@ -26,7 +26,7 @@ Es rápido compilando y rápido al ejecutar, añade una concurrencia fácil de
entender para las CPUs de varios núcleos de hoy día, y tiene
características que ayudan con la programación a gran escala.
-Go viene con una biblioteca estándar muy buena y una entusiasta comunidad.
+Go viene con una biblioteca estándar muy buena y una comunidad entusiasta.
```go
// Comentario de una sola línea
@@ -52,7 +52,7 @@ import (
// para el ejecutable. Te guste o no, Go utiliza llaves.
func main() {
// Println imprime una línea a stdout.
- // Cualificalo con el nombre del paquete, fmt.
+ // Llámalo con el nombre del paquete, fmt.
fmt.Println("¡Hola mundo!")
// Llama a otra función de este paquete.
@@ -90,12 +90,12 @@ saltos de línea.` // mismo tipo cadena
g := 'Σ' // Tipo rune, un alias de int32, alberga un carácter unicode.
f := 3.14195 // float64, el estándar IEEE-754 de coma flotante 64-bit.
c := 3 + 4i // complex128, representado internamente por dos float64.
- // Sintaxis Var con iniciadores.
+ // Sintaxis var con iniciadores.
var u uint = 7 // Sin signo, pero la implementación depende del tamaño
// como en int.
var pi float32 = 22. / 7
- // Sintáxis de conversión con una declaración corta.
+ // Sintaxis de conversión con una declaración corta.
n := byte('\n') // byte es un alias para uint8.
// Los Arreglos tienen un tamaño fijo a la hora de compilar.
@@ -377,8 +377,8 @@ func aprendeConcurrencia() {
go func() { c <- 84 }() // Inicia una nueva rutinago solo para
// enviar un valor.
go func() { cs <- "verboso" }() // Otra vez, para cs en esta ocasión.
- // Select tiene una sintáxis parecida a la instrucción switch pero cada
- // caso involucra una operacion con un canal. Selecciona un caso de
+ // Select tiene una sintaxis parecida a la instrucción switch pero cada
+ // caso involucra una operación con un canal. Selecciona un caso de
// forma aleatoria de los casos que están listos para comunicarse.
select {
case i := <-c: // El valor recibido se puede asignar a una variable,
diff --git a/es-es/groovy-es.html.markdown b/es-es/groovy-es.html.markdown
index 799fc609..262d5e6a 100644
--- a/es-es/groovy-es.html.markdown
+++ b/es-es/groovy-es.html.markdown
@@ -232,10 +232,12 @@ for (i in array) {
// Iterando sobre un mapa
def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
-x = 0
+x = ""
for ( e in map ) {
x += e.value
+ x += " "
}
+assert x.equals("Roberto Grails Groovy ")
/*
Operadores
diff --git a/es-es/haskell-es.html.markdown b/es-es/haskell-es.html.markdown
index babb1060..66ce109d 100644
--- a/es-es/haskell-es.html.markdown
+++ b/es-es/haskell-es.html.markdown
@@ -66,7 +66,7 @@ not False -- True
----------------------------------------------------
--- Listas y Tuplas
+-- 2. Listas y Tuplas
----------------------------------------------------
-- Cada elemento en una lista debe ser del mismo tipo.
diff --git a/es-es/hq9+-es.html.markdown b/es-es/hq9+-es.html.markdown
new file mode 100644
index 00000000..0e1a36e1
--- /dev/null
+++ b/es-es/hq9+-es.html.markdown
@@ -0,0 +1,44 @@
+---
+language: HQ9+
+filename: hq9+-es.html
+contributors:
+ - ["Alexey Nazaroff", "https://github.com/rogaven"]
+translators:
+ - ["Roberto R", "https://github.com/rrodriguze"]
+lang: es-es
+---
+
+HQ9+ es una parodia de los lenguajes de programación esotéricos y fue creado
+por Cliff Biffle.
+El lenguaje tiene solo cuatro comandos y no está completo de Turing.
+
+```
+Solo hay cuatro comandos, representados por los siguientes cuatro caracteres
+H: imprime "Hello, world!"
+Q: imprime el código fuente del programa (ein Quine)
+9: imprime la letra de "99 Bottles of Beer"
++: aumenta el acumulador en uno (el valod del acumulador no se puede leer)
+Cualquier otro caracter es ignorado.
+
+Ok. Escribamos el programa:
+ HQ
+
+Resultado:
+ Hello world!
+ HQ
+
+HQ9+ es muy simple, pero te permite hacer cosas en él. Otros lenguajes son muy
+difíciles.Por ejemplo, el siguiente programa imprime tres copias de sí mismo en
+la pantalla:
+ QQQ
+Esto imprime:
+ QQQ
+ QQQ
+ QQQ
+```
+
+Y esto es todo. Hay muchos intérpretes para HQ9+.
+A continuación encontrarás uno de ellos.
+
++ [One of online interpreters](https://almnet.de/esolang/hq9plus.php)
++ [HQ9+ official website](http://cliffle.com/esoterica/hq9plus.html)
diff --git a/es-es/hy-es.html.markdown b/es-es/hy-es.html.markdown
new file mode 100644
index 00000000..bfad3b6e
--- /dev/null
+++ b/es-es/hy-es.html.markdown
@@ -0,0 +1,176 @@
+---
+language: hy
+filename: learnhy-es.hy
+contributors:
+ - ["Abhishek L", "http://twitter.com/abhishekl"]
+translators:
+ - ["Roberto R", "https://github.com/rrodriguze"]
+lang: es-es
+---
+
+Hy es un lenguaje de Lisp escrito sobre Python. Esto es posible convirtiendo
+código Hy en un árbol abstracto de Python (ast). Por lo que, esto permite a
+Hy llamar a código Pyhton nativo y viceversa.
+
+Este tutorial funciona para hy >= 0.9.12
+
+```clojure
+;; Esto es una intrucción muy básica a Hy, como la del siguiente enlace
+;; http://try-hy.appspot.com
+;;
+; Comentarios usando punto y coma, como en otros LISPS
+
+;; Nociones básicas de expresiones
+; Los programas List están hechos de expresiones simbólicas como la siguiente
+(some-function args)
+; ahora el esencial "Hola Mundo"
+(print "hello world")
+
+;; Tipos de datos simples
+; Todos los tipos de datos simples son exactamente semejantes a sus homólogos
+; en python
+42 ; => 42
+3.14 ; => 3.14
+True ; => True
+4+10j ; => (4+10j) un número complejo
+
+; Vamos a comenzar con un poco de arimética simple
+(+ 4 1) ;=> 5
+; el operador es aplicado a todos los argumentos, como en otros lisps
+(+ 4 1 2 3) ;=> 10
+(- 2 1) ;=> 1
+(* 4 2) ;=> 8
+(/ 4 1) ;=> 4
+(% 4 2) ;=> 0 o operador módulo
+; la exponenciación es representada por el operador ** como python
+(** 3 2) ;=> 9
+; las funciones anidadas funcionan como lo esperado
+(+ 2 (* 4 2)) ;=> 10
+; también los operadores lógicos igual o no igual se comportan como se espera
+(= 5 4) ;=> False
+(not (= 5 4)) ;=> True
+
+;; variables
+; las variables se configuran usando SETV, los nombres de las variables pueden
+; usar utf-8, excepto for ()[]{}",'`;#|
+(setv a 42)
+(setv π 3.14159)
+(def *foo* 42)
+;; otros tipos de datos de almacenamiento
+; strings, lists, tuples & dicts
+; estos son exactamente los mismos tipos de almacenamiento en python
+"hello world" ;=> "hello world"
+; las operaciones de cadena funcionan de manera similar en python
+(+ "hello " "world") ;=> "hello world"
+; Las listas se crean usando [], la indexación comienza en 0
+(setv mylist [1 2 3 4])
+; las tuplas son estructuras de datos inmutables
+(setv mytuple (, 1 2))
+; los diccionarios son pares de valor-clave
+(setv dict1 {"key1" 42 "key2" 21})
+; :nombre se puede usar para definir palabras clave en Hy que se pueden usar para claves
+(setv dict2 {:key1 41 :key2 20})
+; usar 'get' para obtener un elemento en un índice/key
+(get mylist 1) ;=> 2
+(get dict1 "key1") ;=> 42
+; Alternativamente, si se usan palabras clave que podrían llamarse directamente
+(:key1 dict2) ;=> 41
+
+;; funciones y otras estructuras de programa
+; las funciones son definidas usando defn, o el último sexp se devuelve por defecto
+(defn greet [name]
+  "A simple greeting" ; un docstring opcional
+  (print "hello " name))
+
+(greet "bilbo") ;=> "hello bilbo"
+
+; las funciones pueden tener argumentos opcionales, así como argumentos-clave
+(defn foolists [arg1 &optional [arg2 2]]
+  [arg1 arg2])
+
+(foolists 3) ;=> [3 2]
+(foolists 10 3) ;=> [10 3]
+
+; las funciones anonimas son creadas usando constructores 'fn' y 'lambda'
+; que son similares a 'defn'
+(map (fn [x] (* x x)) [1 2 3 4]) ;=> [1 4 9 16]
+
+;; operaciones de secuencia
+; hy tiene algunas utilidades incluidas para operaciones de secuencia, etc.
+; recuperar el primer elemento usando 'first' o 'car'
+(setv mylist [1 2 3 4])
+(setv mydict {"a" 1 "b" 2})
+(first mylist) ;=> 1
+
+; corte listas usando 'slice'
+(slice mylist 1 3) ;=> [2 3]
+
+; obtener elementos de una lista o dict usando 'get'
+(get mylist 1) ;=> 2
+(get mydict "b") ;=> 2
+; la lista de indexación comienza a partir de 0, igual que en python
+; assoc puede definir elementos clave/índice
+(assoc mylist 2 10) ; crear mylist [1 2 10 4]
+(assoc mydict "c" 3) ; crear mydict {"a" 1 "b" 2 "c" 3}
+; hay muchas otras funciones que hacen que trabajar con secuencias sea 
+; entretenido
+
+;; Python interop
+;; los import funcionan exactamente como en python
+(import datetime)
+(import [functools [partial reduce]]) ; importa fun1 e fun2 del module1
+(import [matplotlib.pyplot :as plt]) ; haciendo una importación en foo como en bar
+; todos los métodos de python incluídos etc. son accesibles desde hy
+; a.foo(arg) is called as (.foo a arg)
+(.split (.strip "hello world  ")) ;=> ["hello" "world"]
+
+;; Condicionales
+; (if condition (body-if-true) (body-if-false)
+(if (= passcode "moria")
+  (print "welcome")
+  (print "Speak friend, and Enter!"))
+
+; anidar múltiples cláusulas 'if else if' con condiciones
+(cond
+ [(= someval 42)
+  (print "Life, universe and everything else!")]
+ [(> someval 42)
+  (print "val too large")]
+ [(< someval 42)
+  (print "val too small")])
+
+; declaraciones de grupo con 'do', son ejecutadas secuencialmente
+; formas como defn tienen un 'do' implícito
+(do
+ (setv someval 10)
+ (print "someval is set to " someval)) ;=> 10
+
+; crear enlaces léxicos con 'let', todas las variables definidas de esta manera
+; tienen alcance local
+(let [[nemesis {"superman" "lex luther"
+                "sherlock" "moriarty"
+                "seinfeld" "newman"}]]
+  (for [(, h v) (.items nemesis)]
+    (print (.format "{0}'s nemesis was {1}" h v))))
+
+;; clases
+; las clases son definidas de la siguiente manera
+(defclass Wizard [object]
+  [[--init-- (fn [self spell]
+             (setv self.spell spell) ; init the attr magic
+             None)]
+   [get-spell (fn [self]
+              self.spell)]])
+
+;; acesse hylang.org
+```
+
+### Otras lecturas
+
+Este tutorial apenas es una introducción básica para hy/lisp/python.
+
+Docs Hy: [http://hy.readthedocs.org](http://hy.readthedocs.org)
+
+Repo Hy en GitHub: [http://github.com/hylang/hy](http://github.com/hylang/hy)
+
+Acceso a freenode irc con #hy, hashtag en twitter: #hylang
diff --git a/es-es/javascript-es.html.markdown b/es-es/javascript-es.html.markdown
index 31512dc4..050154c7 100644
--- a/es-es/javascript-es.html.markdown
+++ b/es-es/javascript-es.html.markdown
@@ -1,7 +1,7 @@
---
language: javascript
contributors:
- - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Leigh Brenecki", "https://leigh.net.au"]
- ["Ariel Krakowski", "http://www.learneroo.com"]
translators:
- ["Daniel Zendejas","https://github.com/DanielZendejas"]
@@ -19,8 +19,8 @@ para front-end que Java.
Sin embargo, JavaScript no sólo se limita a los navegadores web: Node.js, un proyecto que proporciona un entorno de ejecución independiente para el motor V8 de Google Chrome, se está volviendo más y más popular.
¡La retroalimentación es bienvenida! Puedes encontrarme en:
-[@adambrenecki](https://twitter.com/adambrenecki), o
-[adam@brenecki.id.au](mailto:adam@brenecki.id.au).
+[@ExcitedLeigh](https://twitter.com/ExcitedLeigh), o
+[l@leigh.net.au](mailto:l@leigh.net.au).
```js
// Los comentarios en JavaScript son los mismos como comentarios en C.
diff --git a/es-es/kotlin-es.html.markdown b/es-es/kotlin-es.html.markdown
index 5d2f165a..80d7a4bb 100644
--- a/es-es/kotlin-es.html.markdown
+++ b/es-es/kotlin-es.html.markdown
@@ -2,6 +2,7 @@
language: kotlin
contributors:
- ["S Webber", "https://github.com/s-webber"]
+- ["Aitor Escolar", "https://github.com/aiescola"]
translators:
- ["Ivan Alburquerque", "https://github.com/AlburIvan"]
lang: es-es
@@ -39,7 +40,13 @@ fun main(args: Array<String>) {
de tal manera que no tenemos que especificarlo explícitamente cada vez.
    Podemos declarar explícitamente el tipo de una variable así:
*/
- val foo : Int = 7
+ val foo: Int = 7
+
+ /*
+ A diferencia de JavaScript, aunque el tipo se infiera, es tipado, por lo que no se puede cambiar el tipo a posteriori
+ */
+ var fooInt = 14 // Se infiere tipo Int
+ fooInt = "Cadena" // ERROR en tiempo de compilación: Type mismatch
/*
Las cadenas pueden ser representadas de la misma manera que Java.
@@ -84,7 +91,6 @@ fun main(args: Array<String>) {
println(fooNullable?.length) // => null
println(fooNullable?.length ?: -1) // => -1
-
/*
Las funciones pueden ser declaras usando la palabra clave "fun".
Los argumentos de las funciones son especificados entre corchetes despues del nombre de la función.
@@ -122,6 +128,40 @@ fun main(args: Array<String>) {
fun even(x: Int) = x % 2 == 0
println(even(6)) // => true
println(even(7)) // => false
+
+ /*
+ Kotlin permite el uso de lambdas, o funciones anónimas
+ */
+
+ // Sin lambda:
+ interface MyListener {
+ fun onClick(foo: Foo)
+ }
+
+ fun listenSomething(listener: MyListener) {
+ listener.onClick(Foo())
+ }
+
+ listenSomething(object: MyListener {
+ override fun onClick(foo: Foo) {
+ //...
+ }
+ })
+
+ // Con lambda:
+ fun listenSomethingLambda(listener: (Foo) -> Unit) {
+ listener(Foo())
+ }
+
+ listenSomethingLambda {
+ //Se recibe foo
+ }
+
+ // el operador typealias permite, entre otras cosas, simplificar las expresiones con lambdas
+ typealias MyLambdaListener = (Foo) -> Unit
+ fun listenSomethingLambda(listener: MyLambdaListener) {
+ listener(Foo())
+ }
// Las funciones pueden tomar funciones como argumentos y
// retornar funciones.
@@ -185,13 +225,13 @@ fun main(args: Array<String>) {
// La función "with" es similar a la expresión de JavaScript "with".
data class MutableDataClassExample (var x: Int, var y: Int, var z: Int)
- val fooMutableDate = MutableDataClassExample(7, 4, 9)
- with (fooMutableDate) {
+ val fooMutableData = MutableDataClassExample(7, 4, 9)
+ with (fooMutableData) {
x -= 2
y += 2
z--
}
- println(fooMutableDate) // => MutableDataClassExample(x=5, y=6, z=8)
+ println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8)
/*
Podemos crear una lista utilizando la función "listOf".
@@ -219,6 +259,11 @@ fun main(args: Array<String>) {
val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9)
// Se puede acceder a los valores del mapa por su llave.
println(fooMap["a"]) // => 8
+
+ // Tanto Map como cualquier colección iterable, tienen la función de extensión forEach
+ fooMap.forEach {
+ println("${it.key} ${it.value}")
+ }
/*
Las secuencias representan colecciones evaluadas diferidamente.
@@ -245,7 +290,7 @@ fun main(args: Array<String>) {
val y = fibonacciSequence().take(10).toList()
println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
- // Kotlin provee funciones de Orden-Mayor para trabajar con colecciones.
+ // Kotlin provee funciones de orden superior para trabajar con colecciones.
val z = (1..9).map {it * 3}
.filter {it < 20}
.groupBy {it % 2 == 0}
@@ -305,17 +350,11 @@ fun main(args: Array<String>) {
ese tipo sin convertido de forma explícita.
*/
fun smartCastExample(x: Any) : Boolean {
- if (x is Boolean) {
- // x es automaticamente convertido a Boolean
- return x
- } else if (x is Int) {
- // x es automaticamente convertido a Int
- return x > 0
- } else if (x is String) {
- // x es automaticamente convertido a String
- return x.isNotEmpty()
- } else {
- return false
+ return when (x) {
+ is Boolean -> x // x es automaticamente convertido a Boolean
+ is Int -> x > 0 // x es automaticamente convertido a Int
+ is String -> x.isNotEmpty() // x es automaticamente convertido a String
+ else -> false
}
}
println(smartCastExample("Hola, mundo!")) // => true
@@ -345,7 +384,8 @@ enum class EnumExample {
/*
La palabra clave "object" se puede utilizar para crear objetos únicos.
No podemos asignarlo a una variable, pero podemos hacer referencia a ella por su nombre.
-Esto es similar a los objetos únicos de Scala
+Esto es similar a los objetos únicos de Scala.
+En la mayoría de ocasiones, los objetos únicos se usan como alternativa a los Singleton.
*/
object ObjectExample {
fun hello() : String {
diff --git a/es-es/lambda-calculus-es.html.markdown b/es-es/lambda-calculus-es.html.markdown
new file mode 100644
index 00000000..d49545c2
--- /dev/null
+++ b/es-es/lambda-calculus-es.html.markdown
@@ -0,0 +1,216 @@
+---
+category: Algorithms & Data Structures
+name: Lambda Calculus
+contributors:
+ - ["Max Sun", "http://github.com/maxsun"]
+ - ["Yan Hui Hang", "http://github.com/yanhh0"]
+translators:
+ - ["Ivan Alburquerque", "https://github.com/AlburIvan"]
+lang: es-es
+---
+
+# Cálculo Lambda
+
+Cálculo Lambda (Cálculo-λ), originalmente creado por
+[Alonzo Church](https://es.wikipedia.org/wiki/Alonzo_Church),
+es el lenguaje de programación más pequeño del mundo.
+A pesar de no tener números, cadenas, valores booleanos o cualquier
+tipo de datos no funcional, el cálculo lambda se puede utilizar para
+representar cualquier máquina de Turing.
+
+El cálculo lambda se compone de 3 elementos: **variables**, **funciones** y
+**aplicaciones**.
+
+| Nombre | Sintaxis | Ejemplo | Explicación |
+|-------------|------------------------------------|-----------|-----------------------------------------------|
+| Variable | `<nombre>` | `x` | una variable llamada "x" |
+| Función | `λ<parámetro>.<cuerpo>` | `λx.x` | una función con parámetro "x" y cuerpo "x" |
+| Aplicación | `<función><variable o función>` | `(λx.x)a` | llamando a la función "λx.x" con el argumento "a" |
+
+La función más básica es la función de identidad: `λx.x` que es equivalente a
+`f(x) = x`. La primera "x" es el argumento de la función y la segunda es el
+cuerpo de la función.
+
+## Variables Libres vs. Enlazadas:
+
+- En la función `λx.x`, "x" se llama una variable enlazada porque está tanto en
+ el cuerpo de la función como en el parámetro.
+- En `λx.y`, "y" se llama variable libre porque nunca se declara de antemano.
+
+## Evaluación:
+
+Evaluación se realiza a través de
+[β-Reduction](https://es.wikipedia.org/wiki/C%C3%A1lculo_lambda#%CE%B2-reducci%C3%B3n),
+que es, esencialmente, sustitución de ámbito léxico.
+
+Al evaluar la expresión `(λx.x)a`, reemplazamos todas las ocurrencias de "x"
+en el cuerpo de la función con "a".
+
+- `(λx.x)a` evalúa a: `a`
+- `(λx.y)a` evalúa a: `y`
+
+Incluso puedes crear funciones de orden superior:
+
+- `(λx.(λy.x))a` evalúa a: `λy.a`
+
+Aunque el cálculo lambda tradicionalmente solo admite funciones
+de un solo parámetro, podemos crear funciones multiparamétricas usando
+una técnica llamada [Currificación](https://es.wikipedia.org/wiki/Currificación).
+
+- `(λx.λy.λz.xyz)` es equivalente a `f(x, y, z) = ((x y) z)`
+
+Algunas veces `λxy.<cuerpo>` es usado indistintamente con: `λx.λy.<cuerpo>`
+
+----
+
+Es importante reconocer que el cálculo lambda tradicional **no tiene números,
+caracteres ni ningún tipo de datos que no sea de función.**
+
+## Lógica Booleana:
+
+No hay "Verdadero" o "Falso" en el cálculo lambda. Ni siquiera hay un 1 o un 0.
+
+En vez:
+
+`T` es representado por: `λx.λy.x`
+
+`F` es representado por: `λx.λy.y`
+
+Primero, podemos definir una función "if" `λbtf` que devuelve
+`t` si `b` es Verdadero y `f` si `b` es Falso
+
+`IF` es equivalente a: `λb.λt.λf.b t f`
+
+Usando `IF` podemos definir los operadores lógicos booleanos básicos:
+
+`a AND b` es equivalente a: `λab.IF a b F`
+
+`a OR b` es equivalente a: `λab.IF a T b`
+
+`a NOT b` es equivalente a: `λa.IF a F T`
+
+*Note: `IF a b c` es esencialmente diciendo: `IF((a b) c)`*
+
+## Números:
+
+Aunque no hay números en el cálculo lambda, podemos codificar números usando
+[Númeral de Church](https://en.wikipedia.org/wiki/Church_encoding).
+
+Para cualquier número n: <code>n = λf.f <sup> n </sup></code> así:
+
+`0 = λf.λx.x`
+
+`1 = λf.λx.f x`
+
+`2 = λf.λx.f(f x)`
+
+`3 = λf.λx.f(f(f x))`
+
+Para incrementar un númeral de Church, usamos la función sucesora
+`S(n) = n + 1` que es:
+
+`S = λn.λf.λx.f((n f) x)`
+
+Usando el sucesor, podemos definir AGREGAR:
+
+`AGREGAR = λab.(a S)n`
+
+**Desafío:** intenta definir tu propia función de multiplicación!
+
+## Vamos más pequeño: SKI, SK y Iota
+
+### Combinador de SKI
+
+Sean S, K, I las siguientes funciones:
+
+`I x = x`
+
+`K x y = x`
+
+`S x y z = x z (y z)`
+
+Podemos convertir una expresión en el cálculo lambda en una expresión
+en el cálculo del combinador de SKI:
+
+1. `λx.x = I`
+2. `λx.c = Kc`
+3. `λx.(y z) = S (λx.y) (λx.z)`
+
+Tome el número 2 de Church por ejemplo:
+
+`2 = λf.λx.f(f x)`
+
+Para la parte interior `λx.f(f x)`:
+```
+ λx.f(f x)
+= S (λx.f) (λx.(f x)) (case 3)
+= S (K f) (S (λx.f) (λx.x)) (case 2, 3)
+= S (K f) (S (K f) I) (case 2, 1)
+```
+
+Así que:
+```
+ 2
+= λf.λx.f(f x)
+= λf.(S (K f) (S (K f) I))
+= λf.((S (K f)) (S (K f) I))
+= S (λf.(S (K f))) (λf.(S (K f) I)) (case 3)
+```
+
+Para el primer argumento `λf.(S (K f))`:
+```
+ λf.(S (K f))
+= S (λf.S) (λf.(K f)) (case 3)
+= S (K S) (S (λf.K) (λf.f)) (case 2, 3)
+= S (K S) (S (K K) I) (case 2, 3)
+```
+
+Para el segundo argumento `λf.(S (K f) I)`:
+```
+ λf.(S (K f) I)
+= λf.((S (K f)) I)
+= S (λf.(S (K f))) (λf.I) (case 3)
+= S (S (λf.S) (λf.(K f))) (K I) (case 2, 3)
+= S (S (K S) (S (λf.K) (λf.f))) (K I) (case 1, 3)
+= S (S (K S) (S (K K) I)) (K I) (case 1, 2)
+```
+
+Uniéndolos:
+```
+ 2
+= S (λf.(S (K f))) (λf.(S (K f) I))
+= S (S (K S) (S (K K) I)) (S (S (K S) (S (K K) I)) (K I))
+```
+
+Al expandir esto, terminaríamos con la misma expresión para el número 2 de Church nuevamente.
+
+### Cálculo del combinador SKI
+
+El cálculo del combinador SKI puede reducirse aún más. Podemos eliminar
+el combinador I observando que `I = SKK`. Podemos sustituir
+todos los 'I' con `SKK`.
+
+### Combinador Iota
+
+El cálculo del combinador SK todavía no se encuentra en su expresión mínima.
+Definiendo:
+
+```
+ι = λf.((f S) K)
+```
+
+Tenemos que:
+
+```
+I = ιι
+K = ι(ιI) = ι(ι(ιι))
+S = ι(K) = ι(ι(ι(ιι)))
+```
+
+## Para una lectura más avanzada:
+
+1. [A Tutorial Introduction to the Lambda Calculus](http://www.inf.fu-berlin.de/lehre/WS03/alpi/lambda.pdf)
+2. [Cornell CS 312 Recitation 26: The Lambda Calculus](http://www.cs.cornell.edu/courses/cs3110/2008fa/recitations/rec26.html)
+3. [Wikipedia - Lambda Calculus](https://es.wikipedia.org/wiki/Cálculo_lambda)
+4. [Wikipedia - SKI combinator calculus](https://en.wikipedia.org/wiki/SKI_combinator_calculus)
+5. [Wikipedia - Iota and Jot](https://en.wikipedia.org/wiki/Iota_and_Jot)
diff --git a/es-es/learnsmallbasic-es.html.markdown b/es-es/learnsmallbasic-es.html.markdown
new file mode 100644
index 00000000..ff320afb
--- /dev/null
+++ b/es-es/learnsmallbasic-es.html.markdown
@@ -0,0 +1,132 @@
+---
+language: SmallBASIC
+filename: learnsmallbasic-es.bas
+contributors:
+ - ["Chris Warren-Smith", "http://smallbasic.sourceforge.net"]
+translators:
+ - ["José Juan Hernández García", "http://jjuanhdez.es"]
+lang: es-es
+---
+
+## Acerca de
+
+SmallBASIC es un intérprete del lenguaje BASIC rápido y fácil de aprender, ideal para cálculos cotidianos, scripts y prototipos. SmallBASIC incluye funciones trigonométricas, matrices y álgebra, un IDE integrado, una potente librería de cadenas de texto, comandos de sistema, sonido y gráficos, junto con una sintaxis de programación estructurada.
+
+## Desarrollo
+
+SmallBASIC fue desarrollado originalmente por Nicholas Christopoulos a finales de 1999 para el Palm Pilot. El desarrollo del proyecto ha sido continuado por Chris Warren-Smith desde el año 2005.
+Versiones de SmallBASIC se han hecho para una serie dispositivos de mano antiguos, incluyendo Franklin eBookman y el Nokia 770. También se han publicado varias versiones de escritorio basadas en una variedad de kits de herramientas GUI, algunas de las cuales han desaparecido. Las plataformas actualmente soportadas son Linux y Windows basadas en SDL2 y Android basadas en NDK. También está disponible una versión de línea de comandos de escritorio, aunque no suele publicarse en formato binario.
+Alrededor de 2008 una gran corporación lanzó un entorno de programación BASIC con un nombre de similar. SmallBASIC no está relacionado con este otro proyecto.
+
+```
+REM Esto es un comentario
+' y esto tambien es un comentario
+
+REM Imprimir texto
+PRINT "hola"
+? "? es la abreviatura de PRINT"
+
+REM Estructuras de control
+FOR index = 0 TO 10 STEP 2
+ ? "Este es el numero de linea "; index
+NEXT
+J = 0
+REPEAT
+ J++
+UNTIL J = 10
+WHILE J > 0
+ J--
+WEND
+
+REM Estructura Select Case
+SELECT CASE "Cool"
+ CASE "null", 1, 2, 3, 4, 5, 6, 7, 8, "Cool", "blah"
+ CASE "No Cool"
+ PRINT "Fallo epico"
+ CASE ELSE
+ PRINT "Fallo"
+END SELECT
+
+REM Captura de errores con TRY/CATCH
+TRY
+ fn = Freefile
+ OPEN filename FOR INPUT As #fn
+CATCH err
+ PRINT "No se pudo abrir"
+END TRY
+
+REM Procedimientos y funciones definidas por el usuario
+FUNC add2(x, y)
+ ' variables pueden declararse como locales en el ambito de una SUB o FUNC
+ LOCAL k
+ k = "k dejara de existir cuando retorne FUNC"
+ add2 = x + y
+END
+PRINT add2(5, 5)
+
+SUB print_it(it)
+ PRINT it
+END
+print_it "IT...."
+
+REM Visualizacion de lineas y pixeles
+At 0, ymax / 2 + txth ("Q")
+COLOR 1: ? "sin(x)":
+COLOR 8: ? "cos(x)":
+COLOR 12: ? "tan(x)"
+LINE 0, ymax / 2, xmax, ymax / 2
+FOR i = 0 TO xmax
+ PSET i, ymax / 2 - SIN(i * 2 * pi / ymax) * ymax / 4 COLOR 1
+ PSET i, ymax / 2 - COS(i * 2 * pi / ymax) * ymax / 4 COLOR 8
+ PSET i, ymax / 2 - TAN(i * 2 * pi / ymax) * ymax / 4 COLOR 12
+NEXT
+SHOWPAGE
+
+REM SmallBASIC es ideal para experimentar con fractales y otros efectos interesantes
+DELAY 3000
+RANDOMIZE
+ff = 440.03
+FOR j = 0 TO 20
+ r = RND * 1000 % 255
+ b = RND * 1000 % 255
+ g = RND * 1000 % 255
+ c = RGB(r, b, g)
+ ff += 9.444
+ FOR i = 0 TO 25000
+ ff += ff
+ x = MIN(xmax, -x + COS(f * i))
+ y = MIN(ymax, -y + SIN(f * i))
+ PSET x, y COLOR c
+ IF (i % 1000 == 0) THEN
+ SHOWPAGE
+ fi
+ NEXT
+NEXT j
+
+REM Para historiadores de computadoras, SmallBASIC puede ejecutar programas
+REM encontrados en los primeros libros de computacion y revistas, por ejemplo:
+10 LET A = 9
+20 LET B = 7
+30 PRINT A * B
+40 PRINT A / B
+
+REM SmallBASIC también tiene soporte para algunos conceptos modernos como JSON
+aa = ARRAY("{\"cat\":{\"name\":\"harry\"},\"pet\":\"true\"}")
+IF (ismap(aa) == false) THEN
+ THROW "no es un mapa"
+END IF
+PRINT aa
+
+PAUSE
+
+```
+## Artículos
+
+* [Primeros pasos](http://smallbasic.sourceforge.net/?q=node/1573)
+* [Bienvenido a SmallBASIC](http://smallbasic.sourceforge.net/?q=node/838)
+
+## GitHub
+
+* [Código fuente](https://github.com/smallbasic/SmallBASIC)
+* [Reference snapshot](http://smallbasic.github.io/)
+
diff --git a/es-es/markdown-es.html.markdown b/es-es/markdown-es.html.markdown
index 0505b4cb..e23a94ea 100644
--- a/es-es/markdown-es.html.markdown
+++ b/es-es/markdown-es.html.markdown
@@ -14,7 +14,7 @@ fácilmente a HTML (y, actualmente, otros formatos también).
¡Denme toda la retroalimentación que quieran! / ¡Sientanse en la libertad de hacer forks o pull requests!
-```markdown
+```md
<!-- Markdown está basado en HTML, así que cualquier archivo HTML es Markdown
válido, eso significa que podemos usar elementos HTML en Markdown como, por
ejemplo, el comentario y no serán afectados por un parseador Markdown. Aún
diff --git a/es-es/matlab-es.html.markdown b/es-es/matlab-es.html.markdown
new file mode 100644
index 00000000..9f1656bb
--- /dev/null
+++ b/es-es/matlab-es.html.markdown
@@ -0,0 +1,568 @@
+---
+language: Matlab
+filename: learnmatlab-es.mat
+contributors:
+ - ["mendozao", "http://github.com/mendozao"]
+ - ["jamesscottbrown", "http://jamesscottbrown.com"]
+ - ["Colton Kohnke", "http://github.com/voltnor"]
+ - ["Claudson Martins", "http://github.com/claudsonm"]
+translators:
+ - ["Ivan Alburquerque", "https://github.com/AlburIvan"]
+lang: es-es
+---
+
+MATLAB significa 'MATrix LABoratory'. Es un poderoso lenguaje de computación numérica comúnmente usado en ingeniería y matemáticas.
+
+Si tiene algún comentario, no dude en ponerse en contacto el autor en
+[@the_ozzinator](https://twitter.com/the_ozzinator), o
+[osvaldo.t.mendoza@gmail.com](mailto:osvaldo.t.mendoza@gmail.com).
+
+```matlab
+%% Una sección de código comienza con dos símbolos de porcentaje. Los títulos de la sección van en la misma líneas.
+% Los comentarios comienzan con un símbolo de porcentaje.
+
+%{
+Los Comentarios de multiples líneas se
+ven
+como
+esto
+%}
+
+% Dos símbolos de porcentaje denotan el comienzo de una nueva sección de código.
+% Secciones de código individuales pueden ser ejecutadas moviendo el cursor hacia la sección,
+% seguida por un clic en el botón de “Ejecutar Sección”
+% o usando Ctrl+Shift+Enter (Windows) o Cmd+Shift+Return (OS X)
+
+%% Este es el comienzo de una sección de código
+% Una forma de usar las secciones es separar un código de inicio costoso que no cambia, como cargar datos
+load learnmatlab.mat y
+
+%% Esta es otra sección de código
+% Esta sección puede ser editada y ejecutada de manera repetida por sí misma,
+% y es útil para la programación exploratoria y demostraciones.
+A = A * 2;
+plot(A);
+
+%% Las secciones de código también son conocidas como celdas de código o modo celda (no ha de ser confundido con arreglo de celdas)
+
+
+% Los comandos pueden abarcar varias líneas, usando '...'
+ a = 1 + 2 + ...
+ + 4
+
+% Los comandos se pueden pasar al sistema operativo
+!ping google.com
+
+who % Muestra todas las variables en la memoria
+whos % Muestra todas las variables en la memoria con sus tipos
+clear % Borra todas tus variables de la memoria
+clear('A') % Borra una variable en particular
+openvar('A') % Variable abierta en editor de variables
+
+clc % Borra la escritura en la ventana de Comando
+diary % Alterna la escritura del texto de la ventana de comandos al archivo
+ctrl-c % Aborta el cálculo actual
+
+edit('myfunction.m') % Abrir función/script en el editor
+type('myfunction.m') % Imprime la fuente de la función/script en la ventana de comandos
+
+profile on % Enciende el generador de perfilador de código
+profile off % Apaga el generador de perfilador de código
+profile viewer % Abre el perfilador de código
+
+help command % Muestra la documentación del comando en la ventana de comandos
+doc command % Muestra la documentación del comando en la ventana de Ayuda
+lookfor command % Busca el comando en la primera línea comentada de todas las funciones
+lookfor command -all % busca el comando en todas las funciones
+
+
+% Formato de salida
+format short % 4 decimales en un número flotante
+format long % 15 decimales
+format bank % solo dos dígitos después del punto decimal - para cálculos financieros
+fprintf('texto') % imprime "texto" en la pantalla
+disp('texto') % imprime "texto" en la pantalla
+
+% Variables y expresiones
+myVariable = 4 % Espacio de trabajo de aviso muestra la variable recién creada
+myVariable = 4; % Punto y coma suprime la salida a la Ventana de Comando
+4 + 6 % ans = 10
+8 * myVariable % ans = 32
+2 ^ 3 % ans = 8
+a = 2; b = 3;
+c = exp(a)*sin(pi/2) % c = 7.3891
+
+% Llamar funciones se pueden realizar de dos maneras:
+% Sintaxis de función estándar:
+load('myFile.mat', 'y') % argumentos entre paréntesis, separados por comas
+% Sintaxis del comando:
+load myFile.mat y % sin paréntesis, y espacios en lugar de comas
+% Tenga en cuenta la falta de comillas en el formulario de comandos:
+% las entradas siempre se pasan como texto literal; no pueden pasar valores de variables.
+% Además, no puede recibir salida:
+[V,D] = eig(A); % esto no tiene equivalente en forma de comando
+[~,D] = eig(A); % si solo se quiere D y no V
+
+
+
+% Operadores lógicos
+1 > 5 % ans = 0
+10 >= 10 % ans = 1
+3 ~= 4 % No es igual a -> ans = 1
+3 == 3 % Es igual a -> ans = 1
+3 > 1 && 4 > 1 % AND -> ans = 1
+3 > 1 || 4 > 1 % OR -> ans = 1
+~1 % NOT -> ans = 0
+
+% Los operadores lógicos se pueden aplicar a matrices:
+A > 5
+% para cada elemento, si la condición es verdadera, ese elemento es 1 en la matriz devuelta
+A( A > 5 )
+% devuelve un vector que contiene los elementos en A para los que la condición es verdadera
+
+% Cadenas
+a = 'MiCadena'
+length(a) % ans = 8
+a(2) % ans = y
+[a,a] % ans = MiCadenaMiCadena
+
+
+% Celdas
+a = {'uno', 'dos', 'tres'}
+a(1) % ans = 'uno' - retorna una celda
+char(a(1)) % ans = uno - retorna una cadena
+
+% Estructuras
+A.b = {'uno','dos'};
+A.c = [1 2];
+A.d.e = false;
+
+% Vectores
+x = [4 32 53 7 1]
+x(2) % ans = 32, los índices en Matlab comienzan 1, no 0
+x(2:3) % ans = 32 53
+x(2:end) % ans = 32 53 7 1
+
+x = [4; 32; 53; 7; 1] % Vector de columna
+
+x = [1:10] % x = 1 2 3 4 5 6 7 8 9 10
+x = [1:2:10] % Incrementa por 2, i.e. x = 1 3 5 7 9
+
+% Matrices
+A = [1 2 3; 4 5 6; 7 8 9]
+% Las filas están separadas por un punto y coma; los elementos se separan con espacio o coma
+% A =
+
+% 1 2 3
+% 4 5 6
+% 7 8 9
+
+A(2,3) % ans = 6, A(fila, columna)
+A(6) % ans = 8
+% (concatena implícitamente columnas en el vector, luego indexa en base a esto)
+
+
+A(2,3) = 42 % Actualiza la fila 2 col 3 con 42
+% A =
+
+% 1 2 3
+% 4 5 42
+% 7 8 9
+
+A(2:3,2:3) % Crea una nueva matriz a partir de la anterior
+%ans =
+
+% 5 42
+% 8 9
+
+A(:,1) % Todas las filas en la columna 1
+%ans =
+
+% 1
+% 4
+% 7
+
+A(1,:) % Todas las columnas en la fila 1
+%ans =
+
+% 1 2 3
+
+[A ; A] % Concatenación de matrices (verticalmente)
+%ans =
+
+% 1 2 3
+% 4 5 42
+% 7 8 9
+% 1 2 3
+% 4 5 42
+% 7 8 9
+
+% esto es lo mismo que
+vertcat(A,A);
+
+
+[A , A] % Concatenación de matrices (horizontalmente)
+
+%ans =
+
+% 1 2 3 1 2 3
+% 4 5 42 4 5 42
+% 7 8 9 7 8 9
+
+% esto es lo mismo que
+horzcat(A,A);
+
+
+A(:, [3 1 2]) % Reorganiza las columnas de la matriz original
+%ans =
+
+% 3 1 2
+% 42 4 5
+% 9 7 8
+
+size(A) % ans = 3 3
+
+A(1, :) =[] % Elimina la primera fila de la matriz
+A(:, 1) =[] % Elimina la primera columna de la matriz
+
+transpose(A) % Transponer la matriz, que es lo mismo que:
+A one
+ctranspose(A) % Hermitian transpone la matriz
+% (la transposición, seguida de la toma del conjugado complejo de cada elemento)
+A' % Versión concisa de transposición compleja
+A.' % Versión concisa de transposición (sin tomar complejo conjugado)
+
+
+
+
+% Elemento por elemento Aritmética vs. Matriz Aritmética
+% Por sí solos, los operadores aritméticos actúan sobre matrices completas. Cuando preceden
+% por un punto, actúan en cada elemento en su lugar. Por ejemplo:
+A * B % Multiplicación de matrices
+A .* B % Multiplica cada elemento en A por su elemento correspondiente en B
+
+% Hay varios pares de funciones, donde una actúa sobre cada elemento y
+% la otra (cuyo nombre termina en m) actúa sobre la matriz completa.
+exp(A) % exponencializar cada elemento
+expm(A) % calcular la matriz exponencial
+sqrt(A) % tomar la raíz cuadrada de cada elemento
+sqrtm(A) % encuentra la matriz cuyo cuadrado es A
+
+
+% Trazando
+x = 0:.10:2*pi; % Crea un vector que comienza en 0 y termina en 2 * pi con incrementos de .1
+y = sin(x);
+plot(x,y)
+xlabel('x axis')
+ylabel('y axis')
+title('Plot of y = sin(x)')
+axis([0 2*pi -1 1]) % x rango de 0 a 2 * pi, y rango de -1 a 1
+
+plot(x,y1,'-',x,y2,'--',x,y3,':') % Para múltiples funciones en una parcela.
+legend('Line 1 label', 'Line 2 label') % Etiquetar curvas con una leyenda.
+
+% Método alternativo para trazar múltiples funciones en una parcela.
+% mientras 'hold' está activado, los comandos se agregan al gráfico existente en lugar de reemplazarlo.
+plot(x, y)
+hold on
+plot(x, z)
+hold off
+
+loglog(x, y) % Un diagrama de log-log.
+semilogx(x, y) % Un diagrama con el eje x logarítmico.
+semilogy(x, y) % Un diagrama con el eje y logarítmico.
+
+fplot (@(x) x^2, [2,5]) % Un diagrama con el eje y logarítmico...
+
+grid on % Muestra la cuadrícula; apague con 'grid off'.
+axis square % Hace que la región actual de los ejes sea cuadrada.
+axis equal % Establece la relación de aspecto para que las unidades de datos sean las mismas en todas las direcciones.
+
+scatter(x, y); % Gráfico de dispersión
+hist(x); % Histograma
+stem(x); % Traza los valores como tallos, útiles para mostrar datos discretos.
+bar(x); % Diagrama de barras
+
+z = sin(x);
+plot3(x,y,z); % Trazado de línea 3D.
+
+pcolor(A) % Trazado de línea 3D...
+contour(A) % Diagrama de contorno de la matriz.
+mesh(A) % Traza una superficie de malla.
+
+h = figure % Crea nuevo objeto figura, con el mango h.
+figure(h) % Hace que la figura correspondiente al mango h la figura actual.
+close(h) % Cierra la figura con mango h.
+close all % Cierra todas las ventanas con figura abierta.
+close % Cierra ventana de figura actual.
+
+shg % Trae una ventana gráfica existente hacia adelante, o crea una nueva si es necesario.
+clf clear % Borra la ventana de la figura actual y restablece la mayoría de las propiedades de la figura.
+
+% Las propiedades se pueden establecer y cambiar a través de un identificador de figura.
+% Puede guardar un identificador de una figura cuando la crea.
+% La función get devuelve un handle a la figura actual
+h = plot(x, y); % Puedes guardar un control de una figura cuando la creas
+set(h, 'Color', 'r')
+% 'y' yellow; 'm' magenta, 'c' cyan, 'r' red, 'g' green, 'b' blue, 'w' white, 'k' black
+set(h, 'LineStyle', '--')
+% '--' es línea continua, '---' discontinua, ':' punteada, '-.' dash-dot, 'none' es sin línea
+get (h, 'LineStyle')
+
+
+% La función gca devuelve un mango a los ejes para la figura actual
+set(gca, 'XDir', 'reverse'); % invierte la dirección del eje x
+
+% Para crear una figura que contenga varios ejes en posiciones de mosaico, use 'subplot'
+subplot(2,3,1); % seleccione la primera posición en una grilla de subtramas de 2 por 3
+plot(x1); title('First Plot') % traza algo en esta posición
+subplot(2,3,2); % selecciona la segunda posición en la grilla
+plot(x2); title('Second Plot') % trazar algo allí
+
+
+% Para usar funciones o scripts, deben estar en su ruta o directorio actual
+path % muestra la ruta actual
+addpath /path/to/dir % agrega a la ruta
+rmpath /path/to/dir % elimina de la ruta
+cd /path/to/move/into % cambia de directorio
+
+
+% Las variables se pueden guardar en archivos .mat
+save('myFileName.mat') % Guarda las variables en su espacio de trabajo
+load('myFileName.mat') % Carga las variables guardadas en espacio de trabajo
+
+% M-file Scripts
+% Un archivo de script es un archivo externo que contiene una secuencia de instrucciones.
+% Permiten evitar escribir repetidamente el mismo código en la ventana de comandos
+% Tienen extensiones .m
+
+% M-file Functions
+% Al igual que los scripts, y tienen la misma extensión .m
+% Pero pueden aceptar argumentos de entrada y devolver una salida
+% Además, tienen su propio espacio de trabajo (es decir, diferente alcance variable).
+% El nombre de la función debe coincidir con el nombre del archivo (por lo tanto, guarde este ejemplo como double_input.m).
+% 'help double_input.m' devuelve los comentarios en la línea que comienza la función
+function output = double_input(x)
+ % double_input(x) devuelve el doble del valor de x
+ output = 2*x;
+end
+double_input(6) % ans = 12
+
+
+% También puede tener subfunciones y funciones anidadas.
+% Las subfunciones están en el mismo archivo que la función primaria, y solo pueden ser
+% llamadas por funciones en el archivo. Las funciones anidadas se definen dentro de otra
+% otras funciones y tienen acceso tanto a su área de trabajo como a su propio espacio de trabajo.
+
+% Si desea crear una función sin crear un nuevo archivo, puede usar una
+% función anónima. Útil cuando se define rápidamente una función para pasar a
+% otra función (por ejemplo, trazar con fplot, evaluar una integral indefinida
+% con quad, encuentra roots con fzero, o encuentra mínimo con fminsearch).
+% Ejemplo que devuelve el cuadrado de su entrada, asignado al identificador sqr:
+sqr = @(x) x.^2;
+sqr(10) % ans = 100
+doc function_handle % averiguar más
+
+% User input
+a = input('Ingrese el valor:')
+
+% Detiene la ejecución del archivo y le da control al teclado: el usuario puede examinar
+% o cambiar las variables. Escriba 'return' para continuar la ejecución, o 'dbquit' para salir del teclado
+
+% Lectura de datos (también xlsread / importdata / imread para archivos de excel / CSV / image)
+fopen(filename)
+
+% Salida
+disp(a) % Imprime el valor de la variable a
+disp('Hola Mundo') % Imprime una cadena
+fprintf % Imprime en la ventana de comandos con más control
+
+% Declaraciones condicionales (los paréntesis son opcionales, pero buen estilo)
+if (a > 15)
+ disp('Mayor que 15')
+elseif (a == 23)
+ disp('a es 23')
+else
+ disp('Ninguna condicion se ha cumplido')
+end
+
+% Bucles
+% NB. haciendo un bucle sobre los elementos de un vector / matriz es lento!
+% Siempre que sea posible, use funciones que actúen en todo el vector / matriz a la vez
+for k = 1:5
+ disp(k)
+end
+
+k = 0;
+while (k < 5)
+ k = k + 1;
+end
+
+% Ejecución del código de tiempo: 'toc' imprime el tiempo desde que se llamó 'tic'
+tic
+A = rand(1000);
+A*A*A*A*A*A*A;
+toc
+
+% Conectarse a una base de datos MySQL
+dbname = 'database_name';
+username = 'root';
+password = 'root';
+driver = 'com.mysql.jdbc.Driver';
+dburl = ['jdbc:mysql://localhost:8889/' dbname];
+javaclasspath('mysql-connector-java-5.1.xx-bin.jar'); %xx depende de la versión, descarga disponible en http://dev.mysql.com/downloads/connector/j/
+conn = database(dbname, username, password, driver, dburl);
+sql = ['SELECT * from table_name where id = 22'] % Ejemplo de instrucción sql
+a = fetch(conn, sql) %a contendrá sus datos
+
+
+% Funciones matemáticas comunes
+sin(x)
+cos(x)
+tan(x)
+asin(x)
+acos(x)
+atan(x)
+exp(x)
+sqrt(x)
+log(x)
+log10(x)
+abs(x) % Si x es complejo, devuelve la magnitud
+min(x)
+max(x)
+ceil(x)
+floor(x)
+round(x)
+rem(x)
+rand % Números pseudoaleatorios distribuidos uniformemente
+randi % Enteros pseudoaleatorios distribuidos uniformemente
+randn % Números pseudoaleatorios distribuidos normalmente
+
+% Operaciones matemáticas complejas
+abs(x) % Magnitud de la variable compleja x
+phase(x) % Fase (o ángulo) de la variable compleja x
+real(x) % Retorna la parte real de x (es decir, devuelve a si x = a + jb)
+imag(x) % Retorna la parte imaginaria de x (es decir, devuelve b si x = a + jb)
+conj(x) % Retorna el complejo conjugado
+
+
+% Constantes comunes
+pi
+NaN
+inf
+
+% Resolviendo ecuaciones matriciales (si no hay solución, devuelve una solución de mínimos cuadrados)
+%Los operadores \ y / son equivalentes a las funciones mldivide y mrdivide
+x=A\b % Resuelve Ax = b. Más rápido y más numéricamente preciso que usar inv (A) * b.
+x=b/A % Resuelve xA = b
+
+inv(A) % calcular la matriz inversa
+pinv(A) % calcular el pseudo-inverso
+
+% Funciones de matriz comunes
+zeros(m,n) % m x n matriz de 0
+ones(m,n) % m x n matriz de 1
+diag(A) % Extrae los elementos diagonales de una matriz A
+diag(x) % Construya una matriz con elementos diagonales enumerados en x, y ceros en otra parte
+eye(m,n) % Matriz de identidad
+linspace(x1, x2, n) % Devuelve n puntos equiespaciados, con min x1 y max x2
+inv(A) % Inverso de la matriz A
+det(A) % Determinante de A
+eig(A) % Valores propios y vectores propios de A
+trace(A) % Traza de la matriz: equivalente a sum(diag(A))
+isempty(A) % Determina si la matriz está vacía
+all(A) % Determina si todos los elementos son distintos de cero o verdaderos
+any(A) % Determina si alguno de los elementos es distinto de cero o verdadero
+isequal(A, B) % Determina la igualdad de dos matrices
+numel(A) % Cantidad de elementos en matriz
+triu(x) % Devuelve la parte triangular superior de x
+tril(x) % Devuelve la parte triangular inferior de x
+cross(A,B) % Devuelve el producto cruzado de los vectores A y B
+dot(A,B) % Devuelve un producto escalar de dos vectores (debe tener la misma longitud)
+transpose(A) % Devuelve la transposición de A
+fliplr(A) % Voltea la matriz de izquierda a derecha
+flipud(A) % Voltea la matriz de arriba hacia abajo
+
+% Factorizaciones de matrices
+[L, U, P] = lu(A) % Descomposición LU: PA = LU, L es triangular inferior, U es triangular superior, P es matriz de permutación
+[P, D] = eig(A) % eigen-decomposition: AP = PD, las columnas de P son autovectores y las diagonales de D'son valores propios
+[U,S,V] = svd(X) % SVD: XV = US, U y V son matrices unitarias, S tiene elementos diagonales no negativos en orden decreciente
+
+% Funciones comunes de vectores
+max % componente más grande
+min % componente más pequeño
+length % longitud de un vector
+sort % ordenar en orden ascendente
+sum % suma de elementos
+prod % producto de elementos
+mode % valor modal
+median % valor mediano
+mean % valor medio
+std % desviación estándar
+perms(x) % enumera todas las permutaciones de elementos de x
+find(x) % Encuentra todos los elementos distintos de cero de x y devuelve sus índices, puede usar operadores de comparación,
+ % i.e. find( x == 3 ) devuelve índices de elementos que son iguales a 3
+ % i.e. find( x >= 3 ) devuelve índices de elementos mayores o iguales a 3
+
+
+% Clases
+% Matlab puede soportar programación orientada a objetos.
+% Las clases deben colocarse en un archivo del nombre de la clase con la extensión .m.
+% Para comenzar, creamos una clase simple para almacenar puntos de referencia de GPS.
+% Comience WaypointClass.m
+classdef WaypointClass % El nombre de la clase.
+ properties % Las propiedades de la clase se comportan como Estructuras
+ latitude
+ longitude
+ end
+ methods
+ % Este método que tiene el mismo nombre de la clase es el constructor.
+ function obj = WaypointClass(lat, lon)
+ obj.latitude = lat;
+ obj.longitude = lon;
+ end
+
+ % Otras funciones que usan el objeto Waypoint
+ function r = multiplyLatBy(obj, n)
+ r = n*[obj.latitude];
+ end
+
+ % Si queremos agregar dos objetos Waypoint juntos sin llamar
+ % a una función especial, podemos sobrecargar la aritmética de Matlab así:
+ function r = plus(o1,o2)
+ r = WaypointClass([o1.latitude] +[o2.latitude], ...
+ [o1.longitude]+[o2.longitude]);
+ end
+ end
+end
+% Fin WaypointClass.m
+
+% Podemos crear un objeto de la clase usando el constructor
+a = WaypointClass(45.0, 45.0)
+
+% Las propiedades de clase se comportan exactamente como estructuras de Matlab.
+a.latitude = 70.0
+a.longitude = 25.0
+
+% Los métodos se pueden llamar de la misma manera que las funciones
+ans = multiplyLatBy(a,3)
+
+% El método también se puede llamar usando notación de puntos. En este caso, el objeto
+% no necesita ser pasado al método.
+ans = a.multiplyLatBy(a,1/3)
+
+% Las funciones de Matlab pueden sobrecargarse para manejar objetos.
+% En el método anterior, hemos sobrecargado cómo maneja Matlab
+% la adición de dos objetos Waypoint.
+b = WaypointClass(15.0, 32.0)
+c = a + b
+
+```
+
+## Más sobre Matlab
+
+* [The official website (EN)](http://www.mathworks.com/products/matlab/)
+* [The official MATLAB Answers forum (EN)](http://www.mathworks.com/matlabcentral/answers/)
+* [Loren on the Art of MATLAB (EN)](http://blogs.mathworks.com/loren/)
+* [Cleve's Corner (EN)](http://blogs.mathworks.com/cleve/)
+
diff --git a/es-es/objective-c-es.html.markdown b/es-es/objective-c-es.html.markdown
index bdbce524..26cd14d9 100644
--- a/es-es/objective-c-es.html.markdown
+++ b/es-es/objective-c-es.html.markdown
@@ -13,7 +13,7 @@ Objective C es el lenguaje de programación principal utilizado por Apple para l
Es un lenguaje de programación para propósito general que le agrega al lenguaje de programación C una mensajería estilo "Smalltalk".
-```objective_c
+```objectivec
// Los comentarios de una sola línea inician con //
/*
diff --git a/es-es/pascal-es.html.markdown b/es-es/pascal-es.html.markdown
new file mode 100644
index 00000000..8328fa1e
--- /dev/null
+++ b/es-es/pascal-es.html.markdown
@@ -0,0 +1,205 @@
+---
+language: Pascal
+filename: learnpascal-es.pas
+contributors:
+ - ["Ganesha Danu", "http://github.com/blinfoldking"]
+ - ["Keith Miyake", "https://github.com/kaymmm"]
+translators:
+ - ["Ivan Alburquerque", "https://github.com/AlburIvan"]
+lang: es-es
+---
+
+
+>Pascal es un lenguaje de programación imperativo y de procedimiento, que Niklaus Wirth diseñó en 1968–69 y publicó en 1970, como un lenguaje pequeño y eficiente destinado a fomentar las buenas prácticas de programación utilizando programación estructurada y estructuración de datos. Se nombra en honor al matemático, filósofo y físico francés Blaise Pascal. fuente: [wikipedia](https://es.wikipedia.org/wiki/Pascal_(lenguaje_de_programación)))
+
+Para compilar y ejecutar un programa pascal puede usar un compilador pascal gratuito. [Descargar aquí](https://www.freepascal.org/)
+
+```pascal
+//Anatomía de un programa en Pascal
+//Esto es un comentario
+{
+ Esto es un
+ comentario multilínea
+}
+
+//nombre del programa
+program learn_pascal; //<-- no olvides el punto y coma
+
+const
+ {
+ Aquí es donde se debe declarar valores constantes.
+ }
+type
+ {
+ Aquí es donde se debe declarar un tipo de datos personalizado
+ }
+var
+ {
+ aquí es donde se debe declarar una variable
+ }
+
+//área principal del programa
+begin
+ {
+ área para declarar su instrucción
+ }
+end. // El final de un área principal del programa debe requerir un símbolo "."
+```
+
+```pascal
+//declarando variable
+//puedes hacer esto
+var a:integer;
+var b:integer;
+//o esto
+var
+ a : integer;
+ b : integer;
+//o esto
+var a,b : integer;
+```
+
+```pascal
+program Learn_More;
+//Aprendamos sobre los tipos de datos y sus operaciones.
+
+const
+ PI = 3.141592654;
+ GNU = 'GNU No Es Unix';
+ // las constantes se nombran convencionalmente usando CAPS (mayúscula)
+ // sus valores son fijos y no se pueden cambiar durante el tiempo de ejecución
+ // tiene cualquier tipo de datos estándar (enteros, reales, booleanos, characteres, cadenas)
+
+type
+ ch_array : array [0..255] of char;
+ // los son nuevos 'tipos' que especifican la longitud y el tipo de datos
+ // esto define un nuevo tipo de datos que contiene 255 caracteres
+ // (esto es funcionalmente equivalente a una variable string[256])
+ md_array : array of array of integer;
+ // los arreglos anidados son equivalentes a los arreglos multidimensionales
+ // puede definir arreglos de longitud cero (0) que son de tamaño dinámico
+ // esta es una matriz bidimensional de enteros
+
+//Declarando variables
+var
+ int, c, d : integer;
+ // Tres variables que contienen números enteros.
+ // los enteros son de 16 bits y están limitados al rango [-32,768..32,767]
+ r : real;
+ // una variable que contiene un número real como tipos de datos
+ // el rango de los reales pueden variar entre [3.4E-38..3.4E38]
+ bool : boolean;
+ // una variable que contiene un valor booleano (True/False)
+ ch : char;
+ // una variable que contiene un valor de carácter
+ // Las variables char se almacenan como tipos de datos de 8 bits, por lo que no hay UTF
+ str : string;
+ // una variable no estándar que contiene un valor de cadena
+ // Las cadenas son una extensión incluida en la mayoría de los compiladores de Pascal.
+ // se almacenan como una matriz de caracteres con una longitud predeterminada de 255.
+ s : string[50];
+ // una cadena con longitud máxima de 50 caracteres.
+ // puede especificar la longitud de la cadena para minimizar el uso de memoria
+ my_str: ch_array;
+ // Puedes declarar variables de tipos personalizados.
+ my_2d : md_array;
+ // Las matrices de tamaño dinámico deben dimensionarse antes de que puedan usarse.
+
+ // tipos de datos enteros adicionales
+ b : byte; // rango [0..255]
+ shi : shortint; // rango [-128..127]
+ smi : smallint; // rango [-32,768..32,767] (entero estándar)
+ w : word; // rango [0..65,535]
+ li : longint; // rango [-2,147,483,648..2,147,483,647]
+ lw : longword; // rango [0..4,294,967,295]
+ c : cardinal; // longword
+ i64 : int64; // rango [-9223372036854775808..9223372036854775807]
+ qw : qword; // rango [0..18,446,744,073,709,551,615]
+
+ // tipos reales adicionales
+ rr : real; // rango depende de la plataforma (i.e., 8-bit, 16-bit, etc.)
+ rs : single; // rango [1.5E-45..3.4E38]
+ rd : double; // rango [5.0E-324 .. 1.7E308]
+ re : extended; // rango [1.9E-4932..1.1E4932]
+ rc : comp; // rango [-2E64+1 .. 2E63-1]
+
+Begin
+ int := 1;// como asignar un valor a una variable
+ r := 3.14;
+ ch := 'a';
+ str := 'manzana';
+ bool := true;
+ //pascal no es un lenguaje sensible a mayúsculas y minúsculas
+ //operación aritmética
+ int := 1 + 1; // int = 2 sobrescribiendo la asignacion anterior
+ int := int + 1; // int = 2 + 1 = 3;
+ int := 4 div 2; //int = 2 operación de división donde el resultado será redondeado.
+ int := 3 div 2; //int = 1
+ int := 1 div 2; //int = 0
+
+ bool := true or false; // bool = true
+ bool := false and true; // bool = false
+ bool := true xor true; // bool = false
+
+ r := 3 / 2; // un operador de división para reales
+ r := int; // Puede asignar un entero a una variable real pero no a la inversa
+
+ c := str[1]; // asigna la primera letra de str a c
+ str := 'hola' + 'mundo'; // combinando cadenas
+
+ my_str[0] := 'a'; // asignación de matriz necesita un índice
+
+ setlength(my_2d,10,10); // inicializa matrices de tamaño dinámico: matriz 10 × 10
+ for c := 0 to 9 do // los arreglos comienzan en 0 y terminan en longitud - 1
+ for d := 0 to 9 do // Para los contadores de bucle hay que declarar variables.
+ my_2d[c,d] := c * d;
+ // aborda las matrices multidimensionales con un único conjunto de corchete
+
+End.
+```
+
+```pascal
+program Functional_Programming;
+
+Var
+ i, dummy : integer;
+
+function recursion_factorial(const a: integer) : integer;
+{ calcula recursivamente el factorial del parámetro entero a }
+
+// Declare variables locales dentro de la función.
+// e.g.:
+// Var
+// local_a : integer;
+
+Begin
+ If a >= 1 Then
+ // devuelva valores de las funciones asignando un valor al nombre de la función
+ recursion_factorial := a * recursion_factorial(a-1)
+ Else
+ recursion_factorial := 1;
+End; // termine una función usando un punto y coma después de la instrucción End.
+
+procedure obtener_entero(var i : integer; dummy : integer);
+{ obten la entrada del usuario y almacenarla en el parámetro entero i.
+ los parámetros que preceden a 'var' son variables, lo que significa que su valor
+ puede cambiar fuera del parámetro. Los parámetros de valor (sin 'var') como 'dummy'
+ son estáticos y los cambios realizados dentro del alcance de la función/procedimiento
+ no afectan la variable que se pasa como parámetro }
+
+Begin
+ write('Escriba un entero: ');
+ readln(i);
+ dummy := 4; // dummy no cambiará el valor fuera del procedimiento
+End;
+
+Begin // bloque de programa principal
+ dummy := 3;
+ obtener_entero(i, dummy);
+ writeln(i, '! = ', recursion_factorial(i));
+ // muestra i!
+ writeln('dummy = ', dummy); // siempre muestra '3' ya que dummy no ha cambiado.
+End.
+
+```
+
diff --git a/es-es/pcre-es.html.markdown b/es-es/pcre-es.html.markdown
new file mode 100644
index 00000000..279c9a39
--- /dev/null
+++ b/es-es/pcre-es.html.markdown
@@ -0,0 +1,84 @@
+---
+language: PCRE
+filename: pcre-es.txt
+contributors:
+ - ["Sachin Divekar", "http://github.com/ssd532"]
+translators:
+ - ["Roberto R", "https://github.com/rrodriguze"]
+lang: es-es
+---
+
+Una expresión regular (regex o regexp para abreviar) es una cadena especial
+utilizada para definir un patrón, por ejemplo, buscar una secuencia de
+caracteres; por ejemplo, `/^[a-z]+:/` se puede usar para extraer `http:`
+desde la URL `http://github.com/`.
+
+PCRE (Pearl Compatible Regular Expressions) es una biblioteca para expresiones
+muy similar a la Perls, desde ahí el nombre. Se trata de una de las sintaxis
+más comunes para escribir expresiones regulares.
+
+Hay dos tipos de metacaracteres (caracteres con una función especial):
+
+* Caracteres reconocidos en todas partes excepto corchetes
+
+```
+ \ caracter de escape
+ ^ buscar al principio de la cadena (o línea, en modo multilínea)
+ $ busca al final de la cadena (o línea, en modo multilínea)
+ . cualquier caracter exceptoo las nuevas líneas
+ [ inicio de clase de caracter
+ | condiciones alternativas del separador
+ ( inicio del subpatrón
+ ) fin del subpatrón
+ ? cuantificador "0 o 1"
+ * quantificatore "0 o más"
+ + quantificatore "1 o más"
+ { inicio de cuantificador numérico
+```
+
+* Caracteres reconocidos entre corchetes
+
+```
+ \ caracter de escape
+ ^ negar la clase si es el primer caracter
+ - indica una serie de caracteres
+ [ clase de caracteres POSIX (si sigue la sintaxis POSIX)
+ ] termina la clase de caracteres
+```
+
+PCRE también proporciona clases de caracteres predefinidas
+
+```
+ \d cifra decimal
+ \D cifra NO decimal
+ \h espacio horizontal vacío
+ \H espacio horizontal NO vacío
+ \s espacio
+ \S NO esoacui
+ \v espacio vertical vacío
+ \V espacio vertical NO vacío
+ \w palabra
+ \W "NO palabra"
+```
+
+## Ejemplos
+
+Usaremos la siguiente cadena para nuestras pruebas:
+
+```
+66.249.64.13 - - [18/Sep/2004:11:07:48 +1000] "GET /robots.txt HTTP/1.0" 200 468 "-" "Googlebot/2.1"
+```
+
+Se trata de una línea de log del servidor web Apache.
+
+| Regex | Resultado | Comentario |
+| :---- | :-------------- | :------ |
+| `GET` | GET | Busque exactamente la cadena "GET" (distingue entre mayúsculas y minúsculas) |
+| `\d+.\d+.\d+.\d+` | 66.249.64.13 | `\d+` identifica uno o más (cuantificador `+`) números [0-9], `\.` identifica el caracter `.` |
+| `(\d+\.){3}\d+` | 66.249.64.13 | `(\d+\.){3}` busca el grupo (`\d+\.`) exactamente 3 veces. |
+| `\[.+\]` | [18/Sep/2004:11:07:48 +1000] | `.+` identifica cualquier caracter, excepto las nuevas líneas; `.` indica cualquier carácter |
+| `^\S+` | 66.249.64.13 | `^` buscar al inicio de la cadena, `\S+` identifica la primera cadena de caracteres que no sea espacio |
+| `\+[0-9]+` | +1000 | `\+` identifica el caracter `+`. `[0-9]` indica una cifra de 0 a 9. La expresión es equivalente a `\+\d+` |
+
+## Otros recursos
+[Regex101](https://regex101.com/) - probador de expresiones regulares
diff --git a/es-es/perl-es.html.markdown b/es-es/perl-es.html.markdown
index 644182ff..76e9b6e6 100644
--- a/es-es/perl-es.html.markdown
+++ b/es-es/perl-es.html.markdown
@@ -11,9 +11,9 @@ translators:
lang: es-es
---
-Perl 5 es un lenguaje de programación altamente capaz, rico en características, con más de 25 años de desarrollo.
+Perl es un lenguaje de programación altamente capaz, rico en características, con más de 25 años de desarrollo.
-Perl 5 corre en más de 100 plataformas, desde portátiles hasta ordenadores centrales, y es adecuado para realizar desde prototipos rápidos hasta desarrollar proyectos a gran escala.
+Perl corre en más de 100 plataformas, desde portátiles hasta ordenadores centrales, y es adecuado para realizar desde prototipos rápidos hasta desarrollar proyectos a gran escala.
```perl
# Comentarios de una sola línea con un carácter hash
@@ -31,7 +31,7 @@ Perl 5 corre en más de 100 plataformas, desde portátiles hasta ordenadores cen
my $animal = "camello";
my $respuesta = 42;
-# Los valores escalares pueden ser cadenas de caracteres, números enteros o
+# Los valores escalares pueden ser cadenas de caracteres, números enteros o
# de punto flotante; Perl automáticamente los convertirá como sea requerido
## Arreglos
@@ -52,7 +52,7 @@ my %color_fruta = (
# Los escalares, arreglos y hashes están más documentados en perldata (perldoc perldata)
-# Los tipos de datos más complejos se pueden construir utilizando
+# Los tipos de datos más complejos se pueden construir utilizando
# referencias, las cuales le permiten construir listas y hashes dentro
# de listas y hashes
@@ -61,7 +61,7 @@ my %color_fruta = (
# Perl tiene la mayoría de las estructuras condicionales y de ciclos más comunes
if ( $var ) {
...;
-} elsif ( $var eq 'bar' ) {
+} elsif ( $var eq 'bar' ) {
...;
} else {
...;
@@ -98,7 +98,7 @@ foreach (@array) {
#### Expresiones regulares
-# El soporte de expresiones regulares en Perl es muy amplio y profundo, y
+# El soporte de expresiones regulares en Perl es muy amplio y profundo, y
# está sujeto a una extensa documentación en perlrequick, perlretut, entre otros.
# Sin embargo, resumiendo:
@@ -113,7 +113,7 @@ $a =~ s/foo/bar/g; # remplaza TODAS LAS INSTANCIAS de "foo" con "bar" en
#### Archivos y E/S
-# Puede abrir un archivo para obtener datos o escribirlos utilizando la
+# Puede abrir un archivo para obtener datos o escribirlos utilizando la
# función "open()"
open(my $entrada, "<" "entrada.txt") or die "No es posible abrir entrada.txt: $!";
@@ -122,7 +122,7 @@ open(my $log, ">>", "mi.log") or die "No es posible abrir mi.log: $!";
# Es posible leer desde un gestor de archivo abierto utilizando el operador "<>".
# En contexto escalar, leer una sola línea desde el gestor de archivo, y
-# en contexto de lista, leer el archivo completo en donde asigna
+# en contexto de lista, leer el archivo completo en donde asigna
# cada línea a un elemento de la lista
my $linea = <$entrada>;
diff --git a/es-es/pyqt-es.html.markdown b/es-es/pyqt-es.html.markdown
new file mode 100644
index 00000000..6d4fdde7
--- /dev/null
+++ b/es-es/pyqt-es.html.markdown
@@ -0,0 +1,82 @@
+---
+category: tool
+tool: PyQT
+filename: learnpyqt-es.py
+contributors:
+ - ["Nathan Hughes", "https://github.com/sirsharpest"]
+translators:
+ - ["Adrian Rocamora", "https://github.com/adrianrocamora"]
+lang: es-es
+---
+
+**Qt** es un sistema altamente reconocido que permite desarrollar software multiplataforma que puede correr en diferentes entornos de software y hardware con pocos o ningún cambio. Aun así conserva la velocidad y poder de una aplicación nativa. **Qt** fue originalmente escrito en *C++*.
+
+Esta es una adaptación de la introducción a QT con C++ por [Aleksey Kholovchuk](https://github.com/vortexxx192), parte del código ejemplo debería resultar en la misma funcionalidad ¡pero usando python con PyQT!
+
+```python
+import sys
+from PyQt4 import QtGui
+
+def window():
+ # Crear el objeto de la aplicación
+ app = QtGui.QApplication(sys.argv)
+ # Crear un widget en el que colocaremos nuestra etiqueta
+ w = QtGui.QWidget()
+ # Agregamos nuestra etiqueta al widget
+ b = QtGui.QLabel(w)
+ # Agregamos texto a nuestra etiqueta
+ b.setText("Hello World!")
+ # Fijemos información de posición y tamaño del widget
+ w.setGeometry(100, 100, 200, 50)
+ b.move(50, 20)
+ # Proporcionemos un título a nuestra ventana
+ w.setWindowTitle("PyQt")
+ # Mostremos todo
+ w.show()
+ # Ejecutemos lo que hayamos solicitado ya inicializado el resto
+ sys.exit(app.exec_())
+
+if __name__ == '__main__':
+ window()
+
+```
+
+Para poder hacer uso de las funciones más avanzades en **pyqt** necesitamos agregar elementos adicionales.
+Aquí mostramos cómo introducir una caja de diálogo popup, útil para permitir al usuario confirmar su decisión o para brindarnos información.
+
+```Python
+import sys
+from PyQt4.QtGui import *
+from PyQt4.QtCore import *
+
+
+def window():
+ app = QApplication(sys.argv)
+ w = QWidget()
+ # Crear un botón y adjuntarlo al widget w
+ b = QPushButton(w)
+ b.setText("Press me")
+ b.move(50, 50)
+ # Indicar al botón b que llame esta función cuando reciba un click
+ # Nótese la falta de "()" en la llamada de la función
+ b.clicked.connect(showdialog)
+ w.setWindowTitle("PyQt Dialog")
+ w.show()
+ sys.exit(app.exec_())
+
+# Esta función debería crear una ventana de diálogo con un botón
+# que espera a recibir un click y luego sale del programa
+def showdialog():
+ d = QDialog()
+ b1 = QPushButton("ok", d)
+ b1.move(50, 50)
+ d.setWindowTitle("Dialog")
+ # Esta modalidad le indica al popup que bloquee al padre mientras activo
+ d.setWindowModality(Qt.ApplicationModal)
+ # Al recibir un click me gustaría que el proceso termine
+ b1.clicked.connect(sys.exit)
+ d.exec_()
+
+if __name__ == '__main__':
+ window()
+```
diff --git a/es-es/python-es.html.markdown b/es-es/python-es.html.markdown
index a27203d1..7deec286 100644
--- a/es-es/python-es.html.markdown
+++ b/es-es/python-es.html.markdown
@@ -1,26 +1,25 @@
---
-language: python
+language: Python
contributors:
- - ["Louie Dinh", "http://ldinh.ca"]
+ - ["Louie Dinh", "http://pythonpracticeprojects.com"]
translators:
- - ["Camilo Garrido", "http://www.twitter.com/hirohope"]
- - ["Fabio Souto", "http://fabiosouto.me"]
+ - ["Camilo Garrido", "http://twitter.com/hirohope"]
lang: es-es
filename: learnpython-es.py
---
-Python fue creado por Guido Van Rossum en el principio de los 90. Ahora es uno
-de los lenguajes más populares que existen. Me enamoré de Python por su claridad sintáctica.
+Python fue creado por Guido Van Rossum en el principio de los 90'. Ahora es uno
+de los lenguajes más populares en existencia. Me enamoré de Python por su claridad sintáctica.
Es básicamente pseudocódigo ejecutable.
¡Comentarios serán muy apreciados! Pueden contactarme en [@louiedinh](http://twitter.com/louiedinh) o louiedinh [at] [servicio de email de google]
-Nota: Este artículo aplica a Python 2.7 específicamente, pero debería ser aplicable a Python 2.x. ¡Pronto un recorrido por Python 3!
-
```python
+
# Comentarios de una línea comienzan con una almohadilla (o signo gato)
-""" Strings multilínea pueden escribirse
- usando tres "'s, y comúnmente son usados
+
+""" Strings multilinea pueden escribirse
+ usando tres "'s, y comunmente son usados
como comentarios.
"""
@@ -31,69 +30,49 @@ Nota: Este artículo aplica a Python 2.7 específicamente, pero debería ser apl
# Tienes números
3 #=> 3
-# Evidentemente puedes realizar operaciones matemáticas
-1 + 1 #=> 2
-8 - 1 #=> 7
-10 * 2 #=> 20
-35 / 5 #=> 7
-
-# La división es un poco complicada. Es división entera y toma la parte entera
-# de los resultados automáticamente.
-5 / 2 #=> 2
+# Matemática es lo que esperarías
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
-# Para arreglar la división necesitamos aprender sobre 'floats'
-# (números de coma flotante).
-2.0 # Esto es un 'float'
-11.0 / 4.0 #=> 2.75 ahhh...mucho mejor
+# Excepto la división la cual por defecto retorna un número 'float' (número de coma flotante)
+35 / 5 # => 7.0
+# Sin embargo también tienes disponible división entera
+34 // 5 # => 6
-# Resultado de la división de enteros truncada para positivos y negativos
-5 // 3 # => 1
-5.0 // 3.0 # => 1.0 # funciona con números de coma flotante
--5 // 3 # => -2
--5.0 // 3.0 # => -2.0
-
-# El operador módulo devuelve el resto de una división entre enteros
-7 % 3 # => 1
-
-# Exponenciación (x elevado a y)
-2**4 # => 16
+# Cuando usas un float, los resultados son floats
+3 * 2.0 # => 6.0
# Refuerza la precedencia con paréntesis
-(1 + 3) * 2 #=> 8
+(1 + 3) * 2 # => 8
-# Operadores booleanos
-# Nota: "and" y "or" son sensibles a mayúsculas
-True and False #=> False
-False or True #=> True
-# Podemos usar operadores booleanos con números enteros
-0 and 2 #=> 0
--5 or 0 #=> -5
-0 == False #=> True
-2 == True #=> False
-1 == True #=> True
+# Valores 'boolean' (booleanos) son primitivos
+True
+False
# Niega con 'not'
-not True #=> False
-not False #=> True
+not True # => False
+not False # => True
+
# Igualdad es ==
-1 == 1 #=> True
-2 == 1 #=> False
+1 == 1 # => True
+2 == 1 # => False
# Desigualdad es !=
-1 != 1 #=> False
-2 != 1 #=> True
+1 != 1 # => False
+2 != 1 # => True
# Más comparaciones
-1 < 10 #=> True
-1 > 10 #=> False
-2 <= 2 #=> True
-2 >= 2 #=> True
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
# ¡Las comparaciones pueden ser concatenadas!
-1 < 2 < 3 #=> True
-2 < 3 < 2 #=> False
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
# Strings se crean con " o '
"Esto es un string."
@@ -105,40 +84,41 @@ not False #=> True
# Un string puede ser tratado como una lista de caracteres
"Esto es un string"[0] #=> 'E'
-# % pueden ser usados para formatear strings, como esto:
-"%s pueden ser %s" % ("strings", "interpolados")
+# .format puede ser usaro para darle formato a los strings, así:
+"{} pueden ser {}".format("strings", "interpolados")
-# Una forma más reciente de formatear strings es el método 'format'.
-# Este método es la forma preferida
-"{0} pueden ser {1}".format("strings", "formateados")
-# Puedes usar palabras clave si no quieres contar.
-"{nombre} quiere comer {comida}".format(nombre="Bob", comida="lasaña")
+# Puedes reutilizar los argumentos de formato si estos se repiten.
+"{0} sé ligero, {0} sé rápido, {0} brinca sobre la {1}".format("Jack", "vela") #=> "Jack sé ligero, Jack sé rápido, Jack brinca sobre la vela"
+# Puedes usar palabras claves si no quieres contar.
+"{nombre} quiere comer {comida}".format(nombre="Bob", comida="lasaña") #=> "Bob quiere comer lasaña"
+# También puedes interpolar cadenas usando variables en el contexto
+nombre = 'Bob'
+comida = 'Lasaña'
+f'{nombre} quiere comer {comida}' #=> "Bob quiere comer lasaña"
# None es un objeto
-None #=> None
+None # => None
# No uses el símbolo de igualdad `==` para comparar objetos con None
-# Usa `is` en lugar de
+# Usa `is` en su lugar
"etc" is None #=> False
None is None #=> True
-# El operador 'is' prueba la identidad del objeto. Esto no es
-# muy útil cuando se trata de datos primitivos, pero es
-# muy útil cuando se trata de objetos.
-
-# None, 0, y strings/listas vacíos(as) todas se evalúan como False.
+# None, 0, y strings/listas/diccionarios/conjuntos vacíos(as) todos se evalúan como False.
# Todos los otros valores son True
-bool(0) #=> False
-bool("") #=> False
+bool(0) # => False
+bool("") # => False
+bool([]) #=> False
+bool({}) #=> False
+bool(set()) #=> False
####################################################
## 2. Variables y Colecciones
####################################################
-# Imprimir es muy fácil
-print "Soy Python. ¡Encantado de conocerte!"
-
+# Python tiene una función para imprimir
+print("Soy Python. Encantado de conocerte")
# No hay necesidad de declarar las variables antes de asignarlas.
una_variable = 5 # La convención es usar guiones_bajos_con_minúsculas
@@ -148,19 +128,16 @@ una_variable #=> 5
# Ve Control de Flujo para aprender más sobre el manejo de excepciones.
otra_variable # Levanta un error de nombre
-# 'if' puede ser usado como una expresión
-"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
-
-# Las listas almacenan secuencias
+# Listas almacena secuencias
lista = []
# Puedes empezar con una lista prellenada
otra_lista = [4, 5, 6]
# Añadir cosas al final de una lista con 'append'
-lista.append(1) # lista ahora es [1]
-lista.append(2) # lista ahora es [1, 2]
-lista.append(4) # lista ahora es [1, 2, 4]
-lista.append(3) # lista ahora es [1, 2, 4, 3]
+lista.append(1) #lista ahora es [1]
+lista.append(2) #lista ahora es [1, 2]
+lista.append(4) #lista ahora es [1, 2, 4]
+lista.append(3) #lista ahora es [1, 2, 4, 3]
# Remueve del final de la lista con 'pop'
lista.pop() #=> 3 y lista ahora es [1, 2, 4]
# Pongámoslo de vuelta
@@ -181,6 +158,12 @@ lista[1:3] #=> [2, 4]
lista[2:] #=> [4, 3]
# Omite el final
lista[:3] #=> [1, 2, 4]
+# Selecciona cada dos elementos
+lista[::2] # =>[1, 4]
+# Invierte la lista
+lista[::-1] # => [3, 4, 2, 1]
+# Usa cualquier combinación de estos para crear trozos avanzados
+# lista[inicio:final:pasos]
# Remueve elementos arbitrarios de una lista con 'del'
del lista[2] # lista ahora es [1, 2, 3]
@@ -191,14 +174,14 @@ lista + otra_lista #=> [1, 2, 3, 4, 5, 6] - Nota: lista y otra_lista no se tocan
# Concatenar listas con 'extend'
lista.extend(otra_lista) # lista ahora es [1, 2, 3, 4, 5, 6]
-# Chequea la existencia en una lista con
+# Verifica la existencia en una lista con 'in'
1 in lista #=> True
-# Examina el tamaño de una lista con 'len'
+# Examina el largo de una lista con 'len'
len(lista) #=> 6
-# Las tuplas son como las listas, pero son inmutables.
+# Tuplas son como listas pero son inmutables.
tupla = (1, 2, 3)
tupla[0] #=> 1
tupla[0] = 3 # Levanta un error TypeError
@@ -217,7 +200,7 @@ d, e, f = 4, 5, 6
e, d = d, e # d ahora es 5 y e ahora es 4
-# Diccionarios almacenan mapeos
+# Diccionarios relacionan llaves y valores
dicc_vacio = {}
# Aquí está un diccionario prellenado
dicc_lleno = {"uno": 1, "dos": 2, "tres": 3}
@@ -225,16 +208,16 @@ dicc_lleno = {"uno": 1, "dos": 2, "tres": 3}
# Busca valores con []
dicc_lleno["uno"] #=> 1
-# Obtén todas las llaves como una lista
-dicc_lleno.keys() #=> ["tres", "dos", "uno"]
+# Obtén todas las llaves como una lista con 'keys()'. Necesitamos envolver la llamada en 'list()' porque obtenemos un iterable. Hablaremos de eso luego.
+list(dicc_lleno.keys()) #=> ["tres", "dos", "uno"]
# Nota - El orden de las llaves del diccionario no está garantizada.
# Tus resultados podrían no ser los mismos del ejemplo.
-# Obtén todos los valores como una lista
-dicc_lleno.values() #=> [3, 2, 1]
+# Obtén todos los valores como una lista. Nuevamente necesitamos envolverlas en una lista para sacarlas del iterable.
+list(dicc_lleno.values()) #=> [3, 2, 1]
# Nota - Lo mismo que con las llaves, no se garantiza el orden.
-# Chequea la existencia de una llave en el diccionario con 'in'
+# Verifica la existencia de una llave en el diccionario con 'in'
"uno" in dicc_lleno #=> True
1 in dicc_lleno #=> False
@@ -248,19 +231,18 @@ dicc_lleno.get("cuatro") #=> None
dicc_lleno.get("uno", 4) #=> 1
dicc_lleno.get("cuatro", 4) #=> 4
-# El método 'setdefault' es una manera segura de añadir nuevos pares
-# llave-valor en un diccionario
+# El método 'setdefault' inserta en un diccionario solo si la llave no está presente
dicc_lleno.setdefault("cinco", 5) #dicc_lleno["cinco"] es puesto con valor 5
dicc_lleno.setdefault("cinco", 6) #dicc_lleno["cinco"] todavía es 5
+# Remueve llaves de un diccionario con 'del'
+del dicc_lleno['uno'] # Remueve la llave 'uno' de dicc_lleno
+
# Sets (conjuntos) almacenan ... bueno, conjuntos
conjunto_vacio = set()
-# Inicializar un conjunto con montón de valores
-un_conjunto = set([1,2,2,3,4]) # un_conjunto ahora es set([1, 2, 3, 4])
-
-# Desde Python 2.7, {} puede ser usado para declarar un conjunto
-conjunto_lleno = {1, 2, 2, 3, 4} # => {1 2 3 4}
+# Inicializar un conjunto con montón de valores. Yeah, se ve un poco como un diccionario. Lo siento.
+un_conjunto = {1,2,2,3,4} # un_conjunto ahora es {1, 2, 3, 4}
# Añade más valores a un conjunto
conjunto_lleno.add(5) # conjunto_lleno ahora es {1, 2, 3, 4, 5}
@@ -275,7 +257,7 @@ conjunto_lleno | otro_conjunto #=> {1, 2, 3, 4, 5, 6}
# Haz diferencia de conjuntos con -
{1,2,3,4} - {2,3,5} #=> {1, 4}
-# Chequea la existencia en un conjunto con 'in'
+# Verifica la existencia en un conjunto con 'in'
2 in conjunto_lleno #=> True
10 in conjunto_lleno #=> False
@@ -284,32 +266,30 @@ conjunto_lleno | otro_conjunto #=> {1, 2, 3, 4, 5, 6}
## 3. Control de Flujo
####################################################
-# Hagamos sólo una variable
-una_variable = 5
+# Creemos una variable para experimentar
+some_var = 5
-# Aquí está una declaración de un 'if'. ¡La indentación es importante en Python!
+# Aquí está una declaración de un 'if'. ¡La indentación es significativa en Python!
# imprime "una_variable es menor que 10"
if una_variable > 10:
- print "una_variable es completamente mas grande que 10."
+ print("una_variable es completamente mas grande que 10.")
elif una_variable < 10: # Este condición 'elif' es opcional.
- print "una_variable es mas chica que 10."
+ print("una_variable es mas chica que 10.")
else: # Esto también es opcional.
- print "una_variable es de hecho 10."
-
+ print("una_variable es de hecho 10.")
"""
-For itera sobre listas
+For itera sobre iterables (listas, cadenas, diccionarios, tuplas, generadores...)
imprime:
perro es un mamifero
gato es un mamifero
raton es un mamifero
"""
for animal in ["perro", "gato", "raton"]:
- # Puedes usar % para interpolar strings formateados
- print "%s es un mamifero" % animal
+ print("{} es un mamifero".format(animal))
"""
-`range(número)` retorna una lista de números
+`range(número)` retorna un generador de números
desde cero hasta el número dado
imprime:
0
@@ -318,7 +298,7 @@ imprime:
3
"""
for i in range(4):
- print i
+ print(i)
"""
While itera hasta que una condición no se cumple.
@@ -330,18 +310,49 @@ imprime:
"""
x = 0
while x < 4:
- print x
+ print(x)
x += 1 # versión corta de x = x + 1
# Maneja excepciones con un bloque try/except
-
-# Funciona desde Python 2.6 en adelante:
try:
# Usa raise para levantar un error
raise IndexError("Este es un error de indice")
except IndexError as e:
pass # Pass no hace nada. Usualmente harias alguna recuperacion aqui.
+# Python oferce una abstracción fundamental llamada Iterable.
+# Un iterable es un objeto que puede ser tratado como una sequencia.
+# El objeto es retornado por la función 'range' es un iterable.
+
+dicc_lleno = {"uno": 1, "dos": 2, "tres": 3}
+nuestro_iterable = dicc_lleno.keys()
+print(nuestro_iterable) #=> dict_keys(['uno', 'dos', 'tres']). Este es un objeto que implementa nuestra interfaz Iterable
+
+Podemos recorrerla.
+for i in nuestro_iterable:
+ print(i) # Imprime uno, dos, tres
+
+# Aunque no podemos selecionar un elemento por su índice.
+nuestro_iterable[1] # Genera un TypeError
+
+# Un iterable es un objeto que sabe como crear un iterador.
+nuestro_iterator = iter(nuestro_iterable)
+
+# Nuestro iterador es un objeto que puede recordar el estado mientras lo recorremos.
+# Obtenemos el siguiente objeto llamando la función __next__.
+nuestro_iterator.__next__() #=> "uno"
+
+# Mantiene el estado mientras llamamos __next__.
+nuestro_iterator.__next__() #=> "dos"
+nuestro_iterator.__next__() #=> "tres"
+
+# Después que el iterador ha retornado todos sus datos, da una excepción StopIterator.
+nuestro_iterator.__next__() # Genera StopIteration
+
+# Puedes obtener todos los elementos de un iterador llamando a list() en el.
+list(dicc_lleno.keys()) #=> Retorna ["uno", "dos", "tres"]
+
+
####################################################
## 4. Funciones
@@ -349,7 +360,7 @@ except IndexError as e:
# Usa 'def' para crear nuevas funciones
def add(x, y):
- print "x es %s y y es %s" % (x, y)
+ print("x es {} y y es {}".format(x, y))
return x + y # Retorna valores con una la declaración return
# Llamando funciones con parámetros
@@ -358,6 +369,7 @@ add(5, 6) #=> imprime "x es 5 y y es 6" y retorna 11
# Otra forma de llamar funciones es con argumentos de palabras claves
add(y=6, x=5) # Argumentos de palabra clave pueden ir en cualquier orden.
+
# Puedes definir funciones que tomen un número variable de argumentos
def varargs(*args):
return args
@@ -373,6 +385,7 @@ def keyword_args(**kwargs):
# Llamémosla para ver que sucede
keyword_args(pie="grande", lago="ness") #=> {"pie": "grande", "lago": "ness"}
+
# Puedes hacer ambas a la vez si quieres
def todos_los_argumentos(*args, **kwargs):
print args
@@ -410,23 +423,28 @@ filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
# Podemos usar listas por comprensión para mapeos y filtros agradables
[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]
+# también hay diccionarios
+{k:k**2 for k in range(3)} #=> {0: 0, 1: 1, 2: 4}
+# y conjuntos por comprensión
+{c for c in "la cadena"} #=> {'d', 'l', 'a', 'n', ' ', 'c', 'e'}
####################################################
-## 5. Clases
+## 5. Classes
####################################################
+
# Heredamos de object para obtener una clase.
class Humano(object):
# Un atributo de clase es compartido por todas las instancias de esta clase
especie = "H. sapiens"
- # Constructor básico, se llama al instanciar la clase.
+ # Constructor basico
def __init__(self, nombre):
# Asigna el argumento al atributo nombre de la instancia
self.nombre = nombre
- # Un método de instancia. Todos los metodos toman self como primer argumento
+ # Un metodo de instancia. Todos los metodos toman self como primer argumento
def decir(self, msg):
return "%s: %s" % (self.nombre, msg)
@@ -436,7 +454,7 @@ class Humano(object):
def get_especie(cls):
return cls.especie
- # Un metodo estático es llamado sin la clase o instancia como referencia
+ # Un metodo estatico es llamado sin la clase o instancia como referencia
@staticmethod
def roncar():
return "*roncar*"
@@ -467,12 +485,12 @@ Humano.roncar() #=> "*roncar*"
# Puedes importar módulos
import math
-print math.sqrt(16) #=> 4
+print(math.sqrt(16)) #=> 4.0
# Puedes obtener funciones específicas desde un módulo
from math import ceil, floor
-print ceil(3.7) #=> 4.0
-print floor(3.7) #=> 3.0
+print(ceil(3.7)) #=> 4.0
+print(floor(3.7))#=> 3.0
# Puedes importar todas las funciones de un módulo
# Precaución: Esto no es recomendable
@@ -495,52 +513,48 @@ dir(math)
## 7. Avanzado
####################################################
-# Los generadores permiten evaluación perezosa
+# Los generadores te ayudan a hacer un código perezoso (lazy)
def duplicar_numeros(iterable):
for i in iterable:
yield i + i
-# Un generador crea valores sobre la marcha
-# En vez de generar y devolver todos los valores de una vez, crea un valor
-# en cada iteración. En este ejemplo los valores mayores que 15 no serán
-# procesados en duplicar_numeros.
-# Nota: xrange es un generador que hace lo mismo que range.
-# Crear una lista de 1 a 900000000 lleva mucho tiempo y ocupa mucho espacio.
-# xrange crea un generador, mientras que range crea toda la lista.
-# Añadimos un guión bajo a los nombres de variable que coinciden con palabras
-# reservadas de python.
-xrange_ = xrange(1, 900000000)
-
-# duplica todos los números hasta que encuentra un resultado >= 30
-for i in duplicar_numeros(xrange_):
- print i
+# Un generador crea valores sobre la marcha.
+# En vez de generar y retornar todos los valores de una vez, crea uno en cada iteración.
+# Esto significa que valores más grandes que 15 no serán procesados en 'duplicar_numeros'.
+# Fíjate que 'range' es un generador. Crear una lista 1-900000000 tomaría mucho tiempo en crearse.
+_rango = range(1, 900000000)
+# Duplicará todos los números hasta que un resultado >= se encuentre.
+for i in duplicar_numeros(_rango):
+ print(i)
if i >= 30:
break
+
# Decoradores
-# en este ejemplo pedir rodea a hablar
-# Si por_favor es True se cambiará el mensaje.
+# en este ejemplo 'pedir' envuelve a 'decir'
+# Pedir llamará a 'decir'. Si decir_por_favor es True entonces cambiará el mensaje a retornar
from functools import wraps
-def pedir(target_function):
- @wraps(target_function)
+def pedir(_decir):
+ @wraps(_decir)
def wrapper(*args, **kwargs):
- msg, por_favor = target_function(*args, **kwargs)
- if por_favor:
- return "{} {}".format(msg, "¡Por favor! Soy pobre :(")
- return msg
+ mensaje, decir_por_favor = _decir(*args, **kwargs)
+ if decir_por_favor:
+ return "{} {}".format(mensaje, "¡Por favor! Soy pobre :(")
+ return mensaje
return wrapper
@pedir
-def hablar(por_favor=False):
- msg = "¿Me puedes comprar una cerveza?"
- return msg, por_favor
+def say(decir_por_favor=False):
+ mensaje = "¿Puedes comprarme una cerveza?"
+ return mensaje, decir_por_favor
+
-print hablar() # ¿Me puedes comprar una cerveza?
-print hablar(por_favor=True) # ¿Me puedes comprar una cerveza? ¡Por favor! Soy pobre :(
+print(decir()) # ¿Puedes comprarme una cerveza?
+print(decir(decir_por_favor=True)) # ¿Puedes comprarme una cerveza? ¡Por favor! Soy pobre :()
```
## ¿Listo para más?
@@ -549,9 +563,10 @@ print hablar(por_favor=True) # ¿Me puedes comprar una cerveza? ¡Por favor! So
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
* [Dive Into Python](http://www.diveintopython.net/)
-* [The Official Docs](http://docs.python.org/2.6/)
+* [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 Module of the Week](http://pymotw.com/2/)
+* [Python Module of the Week](http://pymotw.com/3/)
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
### Encuadernados
diff --git a/es-es/python3-es.html.markdown b/es-es/pythonlegacy-es.html.markdown
index 05fd7065..0a7304e9 100644
--- a/es-es/python3-es.html.markdown
+++ b/es-es/pythonlegacy-es.html.markdown
@@ -1,15 +1,16 @@
---
-language: python3
+language: Python 2 (legacy)
contributors:
- - ["Louie Dinh", "http://pythonpracticeprojects.com"]
+ - ["Louie Dinh", "http://ldinh.ca"]
translators:
- - ["Camilo Garrido", "http://twitter.com/hirohope"]
+ - ["Camilo Garrido", "http://www.twitter.com/hirohope"]
+ - ["Fabio Souto", "http://fabiosouto.me"]
lang: es-es
-filename: learnpython3-es.py
+filename: learnpythonlegacy-es.py
---
-Python fue creado por Guido Van Rossum en el principio de los 90'. Ahora es uno
-de los lenguajes más populares en existencia. Me enamoré de Python por su claridad sintáctica.
+Python fue creado por Guido Van Rossum en el principio de los 90. Ahora es uno
+de los lenguajes más populares que existen. Me enamoré de Python por su claridad sintáctica.
Es básicamente pseudocódigo ejecutable.
¡Comentarios serán muy apreciados! Pueden contactarme en [@louiedinh](http://twitter.com/louiedinh) o louiedinh [at] [servicio de email de google]
@@ -17,11 +18,9 @@ Es básicamente pseudocódigo ejecutable.
Nota: Este artículo aplica a Python 2.7 específicamente, pero debería ser aplicable a Python 2.x. ¡Pronto un recorrido por Python 3!
```python
-
# Comentarios de una línea comienzan con una almohadilla (o signo gato)
-
-""" Strings multilinea pueden escribirse
- usando tres "'s, y comunmente son usados
+""" Strings multilínea pueden escribirse
+ usando tres "'s, y comúnmente son usados
como comentarios.
"""
@@ -32,47 +31,69 @@ Nota: Este artículo aplica a Python 2.7 específicamente, pero debería ser apl
# Tienes números
3 #=> 3
-# Matemática es lo que esperarías
-1 + 1 #=> 2
-8 - 1 #=> 7
-10 * 2 #=> 20
+# Evidentemente puedes realizar operaciones matemáticas
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# La división es un poco complicada. Es división entera y toma la parte entera
+# de los resultados automáticamente.
+5 / 2 #=> 2
+
+# Para arreglar la división necesitamos aprender sobre 'floats'
+# (números de coma flotante).
+2.0 # Esto es un 'float'
+11.0 / 4.0 #=> 2.75 ahhh...mucho mejor
-# Excepto la división la cual por defecto retorna un número 'float' (número de coma flotante)
-35 / 5 # => 7.0
+# Resultado de la división de enteros truncada para positivos y negativos
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # funciona con números de coma flotante
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
-# Cuando usas un float, los resultados son floats
-3 * 2.0 # => 6.0
+# El operador módulo devuelve el resto de una división entre enteros
+7 % 3 # => 1
+
+# Exponenciación (x elevado a y)
+2**4 # => 16
# Refuerza la precedencia con paréntesis
-(1 + 3) * 2 # => 8
+(1 + 3) * 2 #=> 8
+# Operadores booleanos
+# Nota: "and" y "or" son sensibles a mayúsculas
+True and False #=> False
+False or True #=> True
-# Valores 'boolean' (booleanos) son primitivos
-True
-False
+# Podemos usar operadores booleanos con números enteros
+0 and 2 #=> 0
+-5 or 0 #=> -5
+0 == False #=> True
+2 == True #=> False
+1 == True #=> True
# Niega con 'not'
-not True # => False
-not False # => True
-
+not True #=> False
+not False #=> True
# Igualdad es ==
-1 == 1 # => True
-2 == 1 # => False
+1 == 1 #=> True
+2 == 1 #=> False
# Desigualdad es !=
-1 != 1 # => False
-2 != 1 # => True
+1 != 1 #=> False
+2 != 1 #=> True
# Más comparaciones
-1 < 10 # => True
-1 > 10 # => False
-2 <= 2 # => True
-2 >= 2 # => True
+1 < 10 #=> True
+1 > 10 #=> False
+2 <= 2 #=> True
+2 >= 2 #=> True
# ¡Las comparaciones pueden ser concatenadas!
-1 < 2 < 3 # => True
-2 < 3 < 2 # => False
+1 < 2 < 3 #=> True
+2 < 3 < 2 #=> False
# Strings se crean con " o '
"Esto es un string."
@@ -84,37 +105,40 @@ not False # => True
# Un string puede ser tratado como una lista de caracteres
"Esto es un string"[0] #=> 'E'
-# .format puede ser usaro para darle formato a los strings, así:
-"{} pueden ser {}".format("strings", "interpolados")
-
-# Puedes repetir los argumentos de formateo para ahorrar tipeos.
-"{0} sé ligero, {0} sé rápido, {0} brinca sobre la {1}".format("Jack", "vela") #=> "Jack sé ligero, Jack sé rápido, Jack brinca sobre la vela"
-# Puedes usar palabras claves si no quieres contar.
-"{nombre} quiere comer {comida}".format(nombre="Bob", food="lasaña") #=> "Bob quiere comer lasaña"
+# % pueden ser usados para formatear strings, como esto:
+"%s pueden ser %s" % ("strings", "interpolados")
+# Una forma más reciente de formatear strings es el método 'format'.
+# Este método es la forma preferida
+"{0} pueden ser {1}".format("strings", "formateados")
+# Puedes usar palabras clave si no quieres contar.
+"{nombre} quiere comer {comida}".format(nombre="Bob", comida="lasaña")
# None es un objeto
-None # => None
+None #=> None
# No uses el símbolo de igualdad `==` para comparar objetos con None
-# Usa `is` en su lugar
+# Usa `is` en lugar de
"etc" is None #=> False
None is None #=> True
-# None, 0, y strings/listas/diccionarios vacíos(as) todos se evalúan como False.
+# El operador 'is' prueba la identidad del objeto. Esto no es
+# muy útil cuando se trata de datos primitivos, pero es
+# muy útil cuando se trata de objetos.
+
+# None, 0, y strings/listas vacíos(as) todas se evalúan como False.
# Todos los otros valores son True
-bool(0) # => False
-bool("") # => False
-bool([]) #=> False
-bool({}) #=> False
+bool(0) #=> False
+bool("") #=> False
####################################################
## 2. Variables y Colecciones
####################################################
-# Python tiene una función para imprimir
-print("Soy Python. Encantado de conocerte")
+# Imprimir es muy fácil
+print "Soy Python. ¡Encantado de conocerte!"
+
# No hay necesidad de declarar las variables antes de asignarlas.
una_variable = 5 # La convención es usar guiones_bajos_con_minúsculas
@@ -124,16 +148,19 @@ una_variable #=> 5
# Ve Control de Flujo para aprender más sobre el manejo de excepciones.
otra_variable # Levanta un error de nombre
-# Listas almacena secuencias
+# 'if' puede ser usado como una expresión
+"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+
+# Las listas almacenan secuencias
lista = []
# Puedes empezar con una lista prellenada
otra_lista = [4, 5, 6]
# Añadir cosas al final de una lista con 'append'
-lista.append(1) #lista ahora es [1]
-lista.append(2) #lista ahora es [1, 2]
-lista.append(4) #lista ahora es [1, 2, 4]
-lista.append(3) #lista ahora es [1, 2, 4, 3]
+lista.append(1) # lista ahora es [1]
+lista.append(2) # lista ahora es [1, 2]
+lista.append(4) # lista ahora es [1, 2, 4]
+lista.append(3) # lista ahora es [1, 2, 4, 3]
# Remueve del final de la lista con 'pop'
lista.pop() #=> 3 y lista ahora es [1, 2, 4]
# Pongámoslo de vuelta
@@ -154,12 +181,6 @@ lista[1:3] #=> [2, 4]
lista[2:] #=> [4, 3]
# Omite el final
lista[:3] #=> [1, 2, 4]
-# Selecciona cada dos elementos
-lista[::2] # =>[1, 4]
-# Invierte la lista
-lista[::-1] # => [3, 4, 2, 1]
-# Usa cualquier combinación de estos para crear trozos avanzados
-# lista[inicio:final:pasos]
# Remueve elementos arbitrarios de una lista con 'del'
del lista[2] # lista ahora es [1, 2, 3]
@@ -170,14 +191,14 @@ lista + otra_lista #=> [1, 2, 3, 4, 5, 6] - Nota: lista y otra_lista no se tocan
# Concatenar listas con 'extend'
lista.extend(otra_lista) # lista ahora es [1, 2, 3, 4, 5, 6]
-# Chequea la existencia en una lista con 'in'
+# Chequea la existencia en una lista con
1 in lista #=> True
-# Examina el largo de una lista con 'len'
+# Examina el tamaño de una lista con 'len'
len(lista) #=> 6
-# Tuplas son como listas pero son inmutables.
+# Las tuplas son como las listas, pero son inmutables.
tupla = (1, 2, 3)
tupla[0] #=> 1
tupla[0] = 3 # Levanta un error TypeError
@@ -204,13 +225,13 @@ dicc_lleno = {"uno": 1, "dos": 2, "tres": 3}
# Busca valores con []
dicc_lleno["uno"] #=> 1
-# Obtén todas las llaves como una lista con 'keys()'. Necesitamos envolver la llamada en 'list()' porque obtenemos un iterable. Hablaremos de eso luego.
-list(dicc_lleno.keys()) #=> ["tres", "dos", "uno"]
+# Obtén todas las llaves como una lista
+dicc_lleno.keys() #=> ["tres", "dos", "uno"]
# Nota - El orden de las llaves del diccionario no está garantizada.
# Tus resultados podrían no ser los mismos del ejemplo.
-# Obtén todos los valores como una lista. Nuevamente necesitamos envolverlas en una lista para sacarlas del iterable.
-list(dicc_lleno.values()) #=> [3, 2, 1]
+# Obtén todos los valores como una lista
+dicc_lleno.values() #=> [3, 2, 1]
# Nota - Lo mismo que con las llaves, no se garantiza el orden.
# Chequea la existencia de una llave en el diccionario con 'in'
@@ -227,18 +248,19 @@ dicc_lleno.get("cuatro") #=> None
dicc_lleno.get("uno", 4) #=> 1
dicc_lleno.get("cuatro", 4) #=> 4
-# El método 'setdefault' inserta en un diccionario solo si la llave no está presente
+# El método 'setdefault' es una manera segura de añadir nuevos pares
+# llave-valor en un diccionario
dicc_lleno.setdefault("cinco", 5) #dicc_lleno["cinco"] es puesto con valor 5
dicc_lleno.setdefault("cinco", 6) #dicc_lleno["cinco"] todavía es 5
-# Remueve llaves de un diccionario con 'del'
-del dicc_lleno['uno'] # Remueve la llave 'uno' de dicc_lleno
-
# Sets (conjuntos) almacenan ... bueno, conjuntos
conjunto_vacio = set()
-# Inicializar un conjunto con montón de valores. Yeah, se ve un poco como un diccionario. Lo siento.
-un_conjunto = {1,2,2,3,4} # un_conjunto ahora es {1, 2, 3, 4}
+# Inicializar un conjunto con montón de valores
+un_conjunto = set([1,2,2,3,4]) # un_conjunto ahora es set([1, 2, 3, 4])
+
+# Desde Python 2.7, {} puede ser usado para declarar un conjunto
+conjunto_lleno = {1, 2, 2, 3, 4} # => {1 2 3 4}
# Añade más valores a un conjunto
conjunto_lleno.add(5) # conjunto_lleno ahora es {1, 2, 3, 4, 5}
@@ -262,17 +284,18 @@ conjunto_lleno | otro_conjunto #=> {1, 2, 3, 4, 5, 6}
## 3. Control de Flujo
####################################################
-# Let's just make a variable
-some_var = 5
+# Hagamos sólo una variable
+una_variable = 5
-# Aquí está una declaración de un 'if'. ¡La indentación es significativa en Python!
+# Aquí está una declaración de un 'if'. ¡La indentación es importante en Python!
# imprime "una_variable es menor que 10"
if una_variable > 10:
- print("una_variable es completamente mas grande que 10.")
+ print "una_variable es completamente mas grande que 10."
elif una_variable < 10: # Este condición 'elif' es opcional.
- print("una_variable es mas chica que 10.")
+ print "una_variable es mas chica que 10."
else: # Esto también es opcional.
- print("una_variable es de hecho 10.")
+ print "una_variable es de hecho 10."
+
"""
For itera sobre listas
@@ -283,7 +306,7 @@ imprime:
"""
for animal in ["perro", "gato", "raton"]:
# Puedes usar % para interpolar strings formateados
- print("{} es un mamifero".format(animal))
+ print "%s es un mamifero" % animal
"""
`range(número)` retorna una lista de números
@@ -295,7 +318,7 @@ imprime:
3
"""
for i in range(4):
- print(i)
+ print i
"""
While itera hasta que una condición no se cumple.
@@ -307,49 +330,18 @@ imprime:
"""
x = 0
while x < 4:
- print(x)
+ print x
x += 1 # versión corta de x = x + 1
# Maneja excepciones con un bloque try/except
+
+# Funciona desde Python 2.6 en adelante:
try:
# Usa raise para levantar un error
raise IndexError("Este es un error de indice")
except IndexError as e:
pass # Pass no hace nada. Usualmente harias alguna recuperacion aqui.
-# Python oferce una abstracción fundamental llamada Iterable.
-# Un iterable es un objeto que puede ser tratado como una sequencia.
-# El objeto es retornado por la función 'range' es un iterable.
-
-dicc_lleno = {"uno": 1, "dos": 2, "tres": 3}
-nuestro_iterable = dicc_lleno.keys()
-print(nuestro_iterable) #=> range(1,10). Este es un objeto que implementa nuestra interfaz Iterable
-
-Podemos recorrerla.
-for i in nuestro_iterable:
- print(i) # Imprime uno, dos, tres
-
-# Aunque no podemos selecionar un elemento por su índice.
-nuestro_iterable[1] # Genera un TypeError
-
-# Un iterable es un objeto que sabe como crear un iterador.
-nuestro_iterator = iter(nuestro_iterable)
-
-# Nuestro iterador es un objeto que puede recordar el estado mientras lo recorremos.
-# Obtenemos el siguiente objeto llamando la función __next__.
-nuestro_iterator.__next__() #=> "uno"
-
-# Mantiene el estado mientras llamamos __next__.
-nuestro_iterator.__next__() #=> "dos"
-nuestro_iterator.__next__() #=> "tres"
-
-# Después que el iterador ha retornado todos sus datos, da una excepción StopIterator.
-nuestro_iterator.__next__() # Genera StopIteration
-
-# Puedes obtener todos los elementos de un iterador llamando a list() en el.
-list(dicc_lleno.keys()) #=> Retorna ["uno", "dos", "tres"]
-
-
####################################################
## 4. Funciones
@@ -357,7 +349,7 @@ list(dicc_lleno.keys()) #=> Retorna ["uno", "dos", "tres"]
# Usa 'def' para crear nuevas funciones
def add(x, y):
- print("x es {} y y es {}".format(x, y))
+ print "x es %s y y es %s" % (x, y)
return x + y # Retorna valores con una la declaración return
# Llamando funciones con parámetros
@@ -366,7 +358,6 @@ add(5, 6) #=> imprime "x es 5 y y es 6" y retorna 11
# Otra forma de llamar funciones es con argumentos de palabras claves
add(y=6, x=5) # Argumentos de palabra clave pueden ir en cualquier orden.
-
# Puedes definir funciones que tomen un número variable de argumentos
def varargs(*args):
return args
@@ -382,7 +373,6 @@ def keyword_args(**kwargs):
# Llamémosla para ver que sucede
keyword_args(pie="grande", lago="ness") #=> {"pie": "grande", "lago": "ness"}
-
# Puedes hacer ambas a la vez si quieres
def todos_los_argumentos(*args, **kwargs):
print args
@@ -422,22 +412,21 @@ filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
####################################################
-## 5. Classes
+## 5. Clases
####################################################
-
# Heredamos de object para obtener una clase.
class Humano(object):
# Un atributo de clase es compartido por todas las instancias de esta clase
especie = "H. sapiens"
- # Constructor basico
+ # Constructor básico, se llama al instanciar la clase.
def __init__(self, nombre):
# Asigna el argumento al atributo nombre de la instancia
self.nombre = nombre
- # Un metodo de instancia. Todos los metodos toman self como primer argumento
+ # Un método de instancia. Todos los metodos toman self como primer argumento
def decir(self, msg):
return "%s: %s" % (self.nombre, msg)
@@ -447,7 +436,7 @@ class Humano(object):
def get_especie(cls):
return cls.especie
- # Un metodo estatico es llamado sin la clase o instancia como referencia
+ # Un metodo estático es llamado sin la clase o instancia como referencia
@staticmethod
def roncar():
return "*roncar*"
@@ -478,12 +467,12 @@ Humano.roncar() #=> "*roncar*"
# Puedes importar módulos
import math
-print(math.sqrt(16)) #=> 4.0
+print math.sqrt(16) #=> 4.0
# Puedes obtener funciones específicas desde un módulo
from math import ceil, floor
-print(ceil(3.7)) #=> 4.0
-print(floor(3.7))#=> 3.0
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
# Puedes importar todas las funciones de un módulo
# Precaución: Esto no es recomendable
@@ -506,48 +495,52 @@ dir(math)
## 7. Avanzado
####################################################
-# Los generadores te ayudan a hacer un código perezoso (lazy)
+# Los generadores permiten evaluación perezosa
def duplicar_numeros(iterable):
for i in iterable:
yield i + i
-# Un generador crea valores sobre la marcha.
-# En vez de generar y retornar todos los valores de una vez, crea uno en cada iteración.
-# Esto significa que valores más grandes que 15 no serán procesados en 'duplicar_numeros'.
-# Fíjate que 'range' es un generador. Crear una lista 1-900000000 tomaría mucho tiempo en crearse.
-_rango = range(1, 900000000)
-# Duplicará todos los números hasta que un resultado >= se encuentre.
-for i in duplicar_numeros(_rango):
- print(i)
+# Un generador crea valores sobre la marcha
+# En vez de generar y devolver todos los valores de una vez, crea un valor
+# en cada iteración. En este ejemplo los valores mayores que 15 no serán
+# procesados en duplicar_numeros.
+# Nota: xrange es un generador que hace lo mismo que range.
+# Crear una lista de 1 a 900000000 lleva mucho tiempo y ocupa mucho espacio.
+# xrange crea un generador, mientras que range crea toda la lista.
+# Añadimos un guión bajo a los nombres de variable que coinciden con palabras
+# reservadas de python.
+xrange_ = xrange(1, 900000000)
+
+# duplica todos los números hasta que encuentra un resultado >= 30
+for i in duplicar_numeros(xrange_):
+ print i
if i >= 30:
break
-
# Decoradores
-# en este ejemplo 'pedir' envuelve a 'decir'
-# Pedir llamará a 'decir'. Si decir_por_favor es True entonces cambiará el mensaje a retornar
+# en este ejemplo pedir rodea a hablar
+# Si por_favor es True se cambiará el mensaje.
from functools import wraps
-def pedir(_decir):
- @wraps(_decir)
+def pedir(target_function):
+ @wraps(target_function)
def wrapper(*args, **kwargs):
- mensaje, decir_por_favor = _decir(*args, **kwargs)
- if decir_por_favor:
- return "{} {}".format(mensaje, "¡Por favor! Soy pobre :(")
- return mensaje
+ msg, por_favor = target_function(*args, **kwargs)
+ if por_favor:
+ return "{} {}".format(msg, "¡Por favor! Soy pobre :(")
+ return msg
return wrapper
@pedir
-def say(decir_por_favor=False):
- mensaje = "¿Puedes comprarme una cerveza?"
- return mensaje, decir_por_favor
-
+def hablar(por_favor=False):
+ msg = "¿Me puedes comprar una cerveza?"
+ return msg, por_favor
-print(decir()) # ¿Puedes comprarme una cerveza?
-print(decir(decir_por_favor=True)) # ¿Puedes comprarme una cerveza? ¡Por favor! Soy pobre :()
+print hablar() # ¿Me puedes comprar una cerveza?
+print hablar(por_favor=True) # ¿Me puedes comprar una cerveza? ¡Por favor! Soy pobre :(
```
## ¿Listo para más?
@@ -556,10 +549,9 @@ print(decir(decir_por_favor=True)) # ¿Puedes comprarme una cerveza? ¡Por favo
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
* [Dive Into Python](http://www.diveintopython.net/)
-* [Ideas for Python Projects](http://pythonpracticeprojects.com)
-* [The Official Docs](http://docs.python.org/3/)
+* [The Official Docs](http://docs.python.org/2.6/)
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
-* [Python Module of the Week](http://pymotw.com/3/)
+* [Python Module of the Week](http://pymotw.com/2/)
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
### Encuadernados
diff --git a/es-es/pythonstatcomp-es.html.markdown b/es-es/pythonstatcomp-es.html.markdown
index 0130b72a..b3d2f0ff 100644
--- a/es-es/pythonstatcomp-es.html.markdown
+++ b/es-es/pythonstatcomp-es.html.markdown
@@ -1,5 +1,6 @@
---
-language: Statistical computing with Python
+category: tool
+tool: Statistical Computing with Python
contributors:
- ["e99n09", "https://github.com/e99n09"]
filename: pythonstatcomp-es.py
diff --git a/es-es/raku-es.html.markdown b/es-es/raku-es.html.markdown
new file mode 100644
index 00000000..e916d0fd
--- /dev/null
+++ b/es-es/raku-es.html.markdown
@@ -0,0 +1,1935 @@
+---
+name: perl6
+category: language
+language: Raku
+filename: learnraku-es.raku
+contributors:
+ - ["vendethiel", "http://github.com/vendethiel"]
+ - ["Samantha McVey", "https://cry.nu"]
+translators:
+ - ["Luis F. Uceta", "https://github.com/uzluisf"]
+lang: es-es
+---
+
+Raku es un lenguaje de programación altamente capaz y con características
+abundantes para hacerlo el lenguage ideal por los próximos 100 años.
+
+El compilador primario de Raku se llama [Rakudo](http://rakudo.org), el cual
+se ejecuta en JVM y en [MoarVM](http://moarvm.com).
+
+Meta-nota: dos signos de números (##) son usados para indicar párrafos,
+mientras que un solo signo de número (#) indica notas.
+
+`#=>` representa la salida de un comando.
+
+```perl6
+# Un comentario de una sola línea comienza con un signo de número
+
+#`(
+ Comentarios multilíneas usan #` y signos de encerradura tales
+ como (), [], {}, 「」, etc.
+)
+```
+
+## Variables
+
+```perl6
+## En Raku, se declara una variable lexical usando `my`
+my $variable;
+## Raku tiene 3 tipos básicos de variables: escalares, arrays, y hashes.
+```
+
+### Escalares
+
+```perl6
+# Un escalar representa un solo valor. Variables escalares comienzan
+# con un `$`
+
+my $str = 'Cadena';
+# Las comillas inglesas ("") permiten la intepolación (lo cual veremos
+# luego):
+my $str2 = "Cadena";
+
+## Los nombres de variables pueden contener pero no terminar con comillas
+## simples y guiones. Sin embargo, pueden contener
+## (y terminar con) guiones bajos (_):
+my $nombre'de-variable_ = 5; # Esto funciona!
+
+my $booleano = True; # `True` y `False` son valores booleanos en Raku.
+my $inverso = !$booleano; # Puedes invertir un booleano con el operador prefijo `!`
+my $bool-forzado = so $str; # Y puedes usar el operador prefijo `so` que
+ # convierte su operador en un Bool
+```
+
+### Arrays y Listas
+
+```perl6
+## Un array representa varios valores. Variables arrays comienzan con `@`.
+## Las listas son similares pero son un tipo inmutable.
+
+my @array = 'a', 'b', 'c';
+# equivalente a:
+my @letras = <a b c>; # array de palabras, delimitado por espacios.
+ # Similar al qw de perl, o el %w de Ruby.
+my @array = 1, 2, 3;
+
+say @array[2]; # Los índices de un array empiezan por el 0 -- Este es
+ # el tercer elemento.
+
+say "Interpola todos los elementos de un array usando [] : @array[]";
+#=> Interpola todos los elementos de un array usando [] : 1 2 3
+
+@array[0] = -1; # Asigna un nuevo valor a un índice del array
+@array[0, 1] = 5, 6; # Asigna varios valores
+
+my @llaves = 0, 2;
+@array[@llaves] = @letras; # Asignación usando un array que contiene valores
+ # índices
+say @array; #=> a 6 b
+```
+
+### Hashes, o Pairs (pares) de llaves-valores.
+
+```perl6
+## Un hash contiene parejas de llaves y valores.
+## Puedes construir un objeto Pair usando la sintaxis `LLave => Valor`.
+## Tablas de hashes son bien rápidas para búsqueda, y son almacenadas
+## sin ningún orden.
+## Ten en cuenta que las llaves son "aplanadas" en contexto de hash, y
+## cualquier llave duplicada es deduplicada.
+my %hash = 1 => 2,
+ 3 => 4;
+my %hash = foo => "bar", # las llaves reciben sus comillas
+ # automáticamente.
+ "some other" => "value", # las comas colgantes estań bien.
+ ;
+
+## Aunque los hashes son almacenados internamente de forma diferente a los
+## arrays, Raku te permite crear un hash usando un array
+## con un número par de elementos fácilmente.
+my %hash = <llave1 valor1 llave2 valor2>;
+
+my %hash = llave1 => 'valor1', llave2 => 'valor2'; # ¡el mismo resultado!
+
+## También puedes usar la sintaxis "pareja con dos puntos":
+## (especialmente útil para parámetros nombrados que verás más adelante)
+my %hash = :w(1), # equivalente a `w => 1`
+ # esto es útil para el atajo `True`:
+ :truey, # equivalente a `:truey(True)`, o `truey => True`
+ # y para el `False`:
+ :!falsey, # equivalente a `:falsey(False)`, o `falsey => False`
+ ;
+
+say %hash{'llave1'}; # Puedes usar {} para obtener el valor de una llave
+say %hash<llave2>; # Si es una cadena de texto, puedes actualmente usar <>
+ # (`{llave1}` no funciona, debido a que Raku no tiene
+ # palabras desnudas (barewords en inglés))
+```
+
+## Subrutinas
+
+```perl6
+## Subrutinas, o funciones como otros lenguajes las llaman, son
+## creadas con la palabra clave `sub`.
+sub di-hola { say "¡Hola, mundo!" }
+
+## Puedes proveer argumentos (tipados). Si especificado,
+## el tipo será chequeado al tiempo de compilación si es posible.
+## De lo contrario, al tiempo de ejecución.
+sub di-hola-a(Str $nombre) {
+ say "¡Hola, $nombre!";
+}
+
+## Una subrutina devuelve el último valor evaluado del bloque.
+sub devolver-valor {
+ 5;
+}
+say devolver-valor; # imprime 5
+sub devolver-vacio {
+}
+say devolver-vacio; # imprime Nil
+
+## Algunas estructuras de control producen un valor. Por ejemplo if:
+sub devuelva-si {
+ if True {
+ "Truthy";
+ }
+}
+say devuelva-si; # imprime Truthy
+
+## Otras no, como un bucle for:
+sub return-for {
+ for 1, 2, 3 { }
+}
+say return-for; # imprime Nil
+
+## Una subrutina puede tener argumentos opcionales:
+sub con-opcional($arg?) { # el signo "?" marca el argumento opcional
+ say "Podría returnar `(Any)` (valor de Perl parecido al 'null') si no me pasan
+ un argumento, o returnaré mi argumento";
+ $arg;
+}
+con-opcional; # devuelve Any
+con-opcional(); # devuelve Any
+con-opcional(1); # devuelve 1
+
+## También puedes proveer un argumento por defecto para
+## cuando los argumentos no son proveídos:
+sub hola-a($nombre = "Mundo") {
+ say "¡Hola, $nombre!";
+}
+hola-a; #=> ¡Hola, Mundo!
+hola-a(); #=> ¡Hola, Mundo!
+hola-a('Tú'); #=> ¡Hola, Tú!
+
+## De igual manera, al usar la sintaxis parecida a la de los hashes
+## (¡Hurra, sintaxis unificada!), puedes pasar argumentos *nombrados*
+## a una subrutina. Ellos son opcionales, y por defecto son del tipo "Any".
+sub con-nombre($arg-normal, :$nombrado) {
+ say $arg-normal + $nombrado;
+}
+con-nombre(1, nombrado => 6); #=> 7
+## Sin embargo, debes tener algo en cuenta aquí:
+## Si pones comillas alrededor de tu llave, Raku no será capaz de verla
+## al tiempo de compilación, y entonces tendrás un solo objeto Pair como
+## un argumento posicional, lo que significa que el siguiente ejemplo
+## falla:
+con-nombre(1, 'nombrado' => 6);
+
+con-nombre(2, :nombrado(5)); #=> 7
+
+## Para hacer un argumento nombrado mandatorio, puedes utilizar el
+## inverso de `?`, `!`:
+sub con-nombre-mandatorio(:$str!) {
+ say "$str!";
+}
+con-nombre-mandatorio(str => "Mi texto"); #=> Mi texto!
+con-nombre-mandatorio; # error al tiempo de ejecución:
+ # "Required named parameter not passed"
+ # ("Parámetro nombrado requerido no proveído")
+con-nombre-mandatorio(3);# error al tiempo de ejecución:
+ # "Too many positional parameters passed"
+ # ("Demasiados argumentos posicionales proveídos")
+
+## Si una subrutina toma un argumento booleano nombrado ...
+sub toma-un-bool($nombre, :$bool) {
+ say "$nombre toma $bool";
+}
+## ... puedes usar la misma sintaxis de hash de un "booleano corto":
+takes-a-bool('config', :bool); # config toma True
+takes-a-bool('config', :!bool); # config toma False
+
+## También puedes proveer tus argumentos nombrados con valores por defecto:
+sub nombrado-definido(:$def = 5) {
+ say $def;
+}
+nombrado-definido; #=> 5
+nombrado-definido(def => 15); #=> 15
+
+## Dado que puedes omitir los paréntesis para invocar una función sin
+## argumentos, necesitas usar "&" en el nombre para almacenar la función
+## `di-hola` en una variable.
+my &s = &di-hola;
+my &otra-s = sub { say "¡Función anónima!" }
+
+## Una subrutina puede tener un parámetro "slurpy", o "no importa cuantos",
+## indicando que la función puede recibir cualquier número de parámetros.
+sub muchos($principal, *@resto) { #`*@` (slurpy) consumirá lo restante
+## Nota: Puedes tener parámetros *antes que* un parámetro "slurpy" (como
+## aquí) pero no *después* de uno.
+ say @resto.join(' / ') ~ "!";
+}
+say muchos('Feliz', 'Cumpleaño', 'Cumpleaño'); #=> Feliz / Cumpleaño!
+ # Nota que el asterisco (*) no
+ # consumió el parámetro frontal.
+
+## Puedes invocar un función con un array usando el
+## operador "aplanador de lista de argumento" `|`
+## (actualmente no es el único rol de este operador pero es uno de ellos)
+sub concat3($a, $b, $c) {
+ say "$a, $b, $c";
+}
+concat3(|@array); #=> a, b, c
+ # `@array` fue "aplanado" como parte de la lista de argumento
+```
+
+## Contenedores
+
+```perl6
+## En Raku, valores son actualmente almacenados en "contenedores".
+## El operador de asignación le pregunta al contenedor en su izquierda
+## almacenar el valor a su derecha. Cuando se pasan alrededor, contenedores
+## son marcados como inmutables. Esto significa que, en una función, tu
+## tendrás un error si tratas de mutar uno de tus argumentos.
+## Si realmente necesitas hacerlo, puedes preguntar por un contenedor
+## mutable usando `is rw`:
+sub mutar($n is rw) {
+ $n++;
+ say "¡\$n es ahora $n!";
+}
+
+my $m = 42;
+mutar $m; # ¡$n es ahora 43!
+
+## Esto funciona porque estamos pasando el contenedor $m para mutarlo. Si
+## intentamos pasar un número en vez de pasar una variable, no funcionará
+## dado que no contenedor ha sido pasado y números enteros son inmutables
+## por naturaleza:
+
+mutar 42; # Parámetro '$n' esperaba un contenedor mutable,
+ # pero recibió un valor Int
+
+## Si en cambio quieres una copia, debes usar `is copy`.
+
+## Por si misma, una subrutina devuelve un contenedor, lo que significa
+## que puede ser marcada con rw:
+my $x = 42;
+sub x-almacena() is rw { $x }
+x-almacena() = 52; # En este caso, los paréntesis son mandatorios
+ # (porque de otra forma, Raku piensa que la función
+ # `x-almacena` es un identificador).
+say $x; #=> 52
+```
+
+## Estructuras de control
+### Condicionales
+
+```perl6
+## - `if`
+## Antes de hablar acerca de `if`, necesitamos saber cuales valores son
+## "Truthy" (representa True (verdadero)), y cuales son "Falsey"
+## (o "Falsy") -- representa False (falso). Solo estos valores son
+## Falsey: 0, (), {}, "", Nil, un tipo (como `Str` o`Int`) y
+## por supuesto False. Todos los valores son Truthy.
+if True {
+ say "¡Es verdadero!";
+}
+
+unless False {
+ say "¡No es falso!";
+}
+
+## Como puedes observar, no necesitas paréntesis alrededor de condiciones.
+## Sin embargo, necesitas las llaves `{}` alrededor del cuerpo de un bloque:
+# if (true) say; # !Esto no funciona!
+
+## También puedes usar sus versiones sufijos seguidas por la palabra clave:
+say "Un poco verdadero" if True;
+
+## - La condicional ternaria, "?? !!" (como `x ? y : z` en otros lenguajes)
+## devuelve $valor-si-verdadera si la condición es verdadera y
+## $valor-si-falsa si es falsa.
+## my $resultado = $valor condición ?? $valor-si-verdadera !! $valor-si-falsa;
+
+my $edad = 30;
+say $edad > 18 ?? "Eres un adulto" !! "Eres menor de 18";
+```
+
+### given/when, ó switch
+
+```perl6
+## - `given`-`when` se parece al `switch` de otros lenguajes, pero es más
+## poderoso gracias a la coincidencia inteligente ("smart matching" en inglés)
+## y la "variable tópica" $_ de Perl.
+##
+## Esta variable ($_) contiene los argumentos por defecto de un bloque,
+## la iteración actual de un loop (a menos que sea explícitamente
+## nombrado), etc.
+##
+## `given` simplemente pone su argumento en `$_` (como un bloque lo haría),
+## y `when` lo compara usando el operador de "coincidencia inteligente" (`~~`).
+##
+## Dado que otras construcciones de Raku usan esta variable (por ejemplo,
+## el bucle `for`, bloques, etc), esto se significa que el poderoso `when` no
+## solo se aplica con un `given`, sino que se puede usar en cualquier
+## lugar donde exista una variable `$_`.
+
+given "foo bar" {
+ say $_; #=> foo bar
+ when /foo/ { # No te preocupies acerca de la coincidencia inteligente –
+ # solo ten presente que `when` la usa.
+ # Esto es equivalente a `if $_ ~~ /foo/`.
+ say "¡Yay!";
+ }
+ when $_.chars > 50 { # coincidencia inteligente con cualquier cosa True es True,
+ # i.e. (`$a ~~ True`)
+ # por lo tanto puedes también poner condiciones "normales".
+ # Este `when` es equivalente a este `if`:
+ # if $_ ~~ ($_.chars > 50) {...}
+ # que significa:
+ # if $_.chars > 50 {...}
+ say "¡Una cadena de texto bien larga!";
+ }
+ default { # lo mismo que `when *` (usando la Whatever Star)
+ say "Algo más";
+ }
+}
+```
+
+### Construcciones de bucle
+
+```perl6
+## - `loop` es un bucle infinito si no le pasas sus argumentos,
+## pero también puede ser un bucle for al estilo de C:
+loop {
+ say "¡Este es un bucle infinito!";
+ last; # last interrumpe el bucle, como la palabra clave `break`
+ # en otros lenguajes.
+}
+
+loop (my $i = 0; $i < 5; $i++) {
+ next if $i == 3; # `next` salta a la siguiente iteración, al igual
+ # que `continue` en otros lenguajes. Ten en cuenta que
+ # también puedes usar la condicionales postfix (sufijas)
+ # bucles, etc.
+ say "¡Este es un bucle al estilo de C!";
+}
+
+## - `for` - Hace iteraciones en un array
+for @array -> $variable {
+ say "¡He conseguido una $variable!";
+}
+
+## Como vimos con `given`, la variable de una "iteración actual" por defecto
+## es `$_`. Esto significa que puedes usar `when` en un bucle `for` como
+## normalmente lo harías con `given`.
+for @array {
+ say "he conseguido a $_";
+
+ .say; # Esto es también permitido.
+ # Una invocación con punto (dot call) sin "tópico" (recibidor) es
+ # enviada a `$_` por defecto.
+ $_.say; # lo mismo de arriba, lo cual es equivalente.
+}
+
+for @array {
+ # Puedes...
+ next if $_ == 3; # Saltar a la siguiente iteración (`continue` en
+ # lenguages parecido a C)
+ redo if $_ == 4; # Re-hacer la iteración, manteniendo la
+ # misma variable tópica (`$_`)
+ last if $_ == 5; # Salir fuera del bucle (como `break`
+ # en lenguages parecido a C)
+}
+
+## La sintaxis de "bloque puntiagudo" no es específica al bucle for.
+## Es solo una manera de expresar un bloque en Raku.
+if computación-larga() -> $resultado {
+ say "El resultado es $resultado";
+}
+```
+
+## Operadores
+
+```perl6
+## Dados que los lenguajes de la familia Perl son lenguages basados
+## mayormente en operadores, los operadores de Raku son actualmente
+## subrutinas un poco cómicas en las categorías sintácticas. Por ejemplo,
+## infix:<+> (adición) o prefix:<!> (bool not).
+
+## Las categorías son:
+## - "prefix" (prefijo): anterior a (como `!` en `!True`).
+## - "postfix" (sufijo): posterior a (como `++` en `$a++`).
+## - "infix" (infijo): en medio de (como `*` en `4 * 3`).
+## - "circumfix" (circunfijo): alrededor de (como `[`-`]` en `[1, 2]`).
+## - "post-circumfix" (pos-circunfijo): alrededor de un término,
+## posterior a otro término.
+## (como `{`-`}` en `%hash{'key'}`)
+
+## La lista de asociatividad y precedencia se explica más abajo.
+
+## ¡Bueno, ya estás listo(a)!
+
+## * Chequeando igualdad
+
+## - `==` se usa en comparaciones numéricas.
+3 == 4; # Falso
+3 != 4; # Verdadero
+
+## - `eq` se usa en comparaciones de cadenas de texto.
+'a' eq 'b';
+'a' ne 'b'; # no igual
+'a' !eq 'b'; # lo mismo que lo anterior
+
+## - `eqv` es equivalencia canónica (or "igualdad profunda")
+(1, 2) eqv (1, 3);
+
+## - Operador de coincidencia inteligente (smart matching): `~~`
+## Asocia (aliasing en inglés) el lado izquierda a la variable $_
+## y después evalúa el lado derecho.
+## Aquí algunas comparaciones semánticas comunes:
+
+## Igualdad de cadena de texto o numérica
+
+'Foo' ~~ 'Foo'; # True si las cadenas de texto son iguales.
+12.5 ~~ 12.50; # True si los números son iguales.
+
+## Regex - Para la comparación de una expresión regular en contra
+## del lado izquierdo. Devuelve un objeto (Match), el cual evalúa
+## como True si el regex coincide con el patrón.
+
+my $obj = 'abc' ~~ /a/;
+say $obj; # 「a」
+say $obj.WHAT; # (Match)
+
+## Hashes
+'llave' ~~ %hash; # True si la llave existe en el hash
+
+## Tipo - Chequea si el lado izquierdo "tiene un tipo" (puede chequear
+## superclases y roles)
+
+1 ~~ Int; # True (1 es un número entero)
+
+## Coincidencia inteligente contra un booleano siempre devuelve ese
+## booleano (y lanzará una advertencia).
+
+1 ~~ True; # True
+False ~~ True; # True
+
+## La sintaxis general es $arg ~~ &función-returnando-bool;
+## Para una lista completa de combinaciones, usa esta tabla:
+## http://perlcabal.org/syn/S03.html#Smart_matching
+
+## También, por supuesto, tienes `<`, `<=`, `>`, `>=`.
+## Sus equivalentes para cadenas de texto están disponibles:
+## `lt`, `le`, `gt`, `ge`.
+3 > 4;
+
+## * Constructores de rango
+3 .. 7; # 3 a 7, ambos incluidos
+## `^` en cualquier lado excluye a ese lado:
+3 ^..^ 7; # 3 a 7, no incluidos (básicamente `4 .. 6`)
+## Esto también funciona como un atajo para `0..^N`:
+^10; # significa 0..^10
+
+## Esto también nos permite demostrar que Raku tiene arrays
+## ociosos/infinitos, usando la Whatever Star:
+my @array = 1..*; # 1 al Infinito! `1..Inf` es lo mismo.
+say @array[^10]; # puedes pasar arrays como subíndices y devolverá
+ # un array de resultados. Esto imprimirá
+ # "1 2 3 4 5 6 7 8 9 10" (y no se quedaré sin memoria!)
+## Nota: Al leer una lista infinita, Raku "cosificará" los elementos que
+## necesita y los mantendrá en la memoria. Ellos no serán calculados más de
+## una vez. Tampoco calculará más elementos de los que necesita.
+
+## Un índice de array también puede ser una clausura ("closure" en inglés).
+## Será llamada con la longitud como el argumento
+say join(' ', @array[15..*]); #=> 15 16 17 18 19
+## lo que es equivalente a:
+say join(' ', @array[-> $n { 15..$n }]);
+## Nota: Si tratas de hacer cualquiera de esos con un array infinito,
+## provocará un array infinito (tu programa nunca terminará)
+
+## Puedes usar eso en los lugares que esperaría, como durante la asignación
+## a un array
+my @números = ^20;
+
+## Aquí los números son incrementados por "6"; más acerca del
+## operador `...` adelante.
+my @seq = 3, 9 ... * > 95; # 3 9 15 21 27 [...] 81 87 93 99;
+@números[5..*] = 3, 9 ... *; # aunque la secuencia es infinita,
+ # solo los 15 números necesarios será calculados.
+say @números; #=> 0 1 2 3 4 3 9 15 21 [...] 81 87
+ # (solamente 20 valores)
+
+## * And &&, Or ||
+3 && 4; # 4, el cual es Truthy. Invoca `.Bool` en `4` y obtiene `True`.
+0 || False; # False. Invoca `.Bool` en `0`
+
+## * Versiones circuito corto de lo de arriba
+## && Devuelve el primer argumento que evalúa a False, o el último.
+
+my ( $a, $b, $c ) = 1, 0, 2;
+$a && $b && $c; # Devuelve 0, el primer valor que es False
+
+## || Devuelve el primer argumento que evalúa a True.
+$b || $a; # 1
+
+## Y porque tu lo querrás, también tienes operadores de asignación
+## compuestos:
+$a *= 2; # multiplica y asigna. Equivalente a $a = $a * 2;
+$b %%= 5; # divisible por y asignación. Equivalente $b = $b %% 5;
+@array .= sort; # invoca el método `sort` y asigna el resultado devuelto.
+```
+
+## ¡Más sobre subrutinas!
+
+```perl6
+## Como dijimos anteriormente, Raku tiene subrutinas realmente poderosas.
+## Veremos unos conceptos claves que la hacen mejores que en cualquier otro
+## lenguaje :-).
+```
+
+### !Desempacado!
+
+```perl6
+## Es la abilidad de extraer arrays y llaves (También conocido como
+## "destructuring"). También funcionará en `my` y en las listas de parámetros.
+my ($f, $g) = 1, 2;
+say $f; #=> 1
+my ($, $, $h) = 1, 2, 3; # mantiene los anónimos no interesante
+say $h; #=> 3
+
+my ($cabeza, *@cola) = 1, 2, 3; # Sí, es lo mismo que con subrutinas "slurpy"
+my (*@small) = 1;
+
+sub desempacar_array(@array [$fst, $snd]) {
+ say "Mi primero es $fst, mi segundo es $snd! De todo en todo, soy un @array[].";
+ # (^ recuerda que `[]` interpola el array)
+}
+desempacar_array(@cola); #=> My first is 2, my second is 3 ! All in all, I'm 2 3
+
+
+## Si no está usando el array, puedes también mantenerlo anónimo, como un
+## escalar:
+sub primero-de-array(@ [$fst]) { $fst }
+primero-de-array(@small); #=> 1
+primero-de-array(@tail); # Lanza un error "Demasiados argumentos posicionales
+ # proveídos"
+ # (lo que significa que el array es muy grande).
+
+## También puedes usar un slurp ...
+sub slurp-en-array(@ [$fst, *@rest]) { # Podrías mantener `*@rest` anónimos
+ say $fst + @rest.elems; # `.elems` returna la longitud de una lista.
+ # Aquí, `@rest` es `(3,)`, since `$fst` holds the `2`.
+}
+slurp-en-array(@tail); #=> 3
+
+## Hasta podrías hacer un extracción usando una slurpy (pero no sería útil ;-).)
+sub fst(*@ [$fst]) { # o simplemente: `sub fst($fst) { ... }`
+ say $fst;
+}
+fst(1); #=> 1
+fst(1, 2); # errores con "Too many positional parameters passed"
+
+## También puedes desestructurar hashes (y clases, las cuales
+## veremos adelante). La sintaxis es básicamente
+## `%nombre-del-hash (:llave($variable-para-almacenar))`.
+## El hash puede permanecer anónimos si solo necesitas los valores extraídos.
+sub llave-de(% (:azul($val1), :red($val2))) {
+ say "Valores: $val1, $val2.";
+}
+## Después invócala con un hash: (necesitas mantener las llaves
+## de los parejas de llave y valor para ser un hash)
+llave-de({azul => 'blue', rojo => "red"});
+#llave-de(%hash); # lo mismo (para un `%hash` equivalente)
+
+## La última expresión de una subrutina es devuelta inmediatamente
+## (aunque puedes usar la palabra clave `return`):
+sub siguiente-indice($n) {
+ $n + 1;
+}
+my $nuevo-n= siguiente-indice(3); # $nuevo-n es ahora 4
+
+## Este es cierto para todo, excepto para las construcciones de bucles
+## (debido a razones de rendimiento): Hay una razón de construir una lista
+## si la vamos a desechar todos los resultados.
+## Si todavías quieres construir una, puedes usar la sentencia prefijo `do`:
+## (o el prefijo `gather`, el cual veremos luego)
+sub lista-de($n) {
+ do for ^$n { # nota el uso del operador de rango `^` (`0..^N`)
+ $_ # iteración de bucle actual
+ }
+}
+my @list3 = lista-de(3); #=> (0, 1, 2)
+```
+
+### lambdas
+
+```perl6
+## Puedes crear una lambda con `-> {}` ("bloque puntiagudo") o `{}` ("bloque")
+my &lambda = -> $argumento { "El argumento pasado a esta lambda es $argumento" }
+## `-> {}` y `{}` son casi la misma cosa, excepto que la primerra puede
+## tomar argumentos, y la segunda puede ser malinterpretada como un hash
+## por el parseador.
+
+## Podemos, por ejemplo, agregar 3 a cada valor de un array usando map:
+my @arraymas3 = map({ $_ + 3 }, @array); # $_ es el argumento implícito
+
+## Una subrutina (`sub {}`) tiene semánticas diferentes a un
+## bloque (`{}` or `-> {}`): Un bloque no tiene "contexto funcional"
+## (aunque puede tener argumentos), lo que significa que si quieres devolver
+## algo desde un bloque, vas a returnar desde la función parental. Compara:
+sub is-in(@array, $elem) {
+ # esto `devolverá` desde la subrutina `is-in`
+ # Una vez que la condición evalúa a True, el bucle terminará
+ map({ return True if $_ == $elem }, @array);
+}
+sub truthy-array(@array) {
+ # esto producirá un array de `True` Y `False`:
+ # (también puedes decir `anon sub` para "subrutina anónima")
+ map(sub ($i) { if $i { return True } else { return False } }, @array);
+ # ^ el `return` solo devuelve desde la `sub`
+}
+
+## También puedes usar la "whatever star" para crear una función anónima
+## (terminará con el último operador en la expresión actual)
+my @arraymas3 = map(*+3, @array); # `*+3` es lo mismo que `{ $_ + 3 }`
+my @arraymas3 = map(*+*+3, @array); # lo mismo que `-> $a, $b { $a + $b + 3 }`
+ # también `sub ($a, $b) { $a + $b + 3 }`
+say (*/2)(4); #=> 2
+ # Inmediatamente ejecuta la función que Whatever creó.
+say ((*+3)/5)(5); #=> 1.6
+ # ¡funciona hasta con los paréntesis!
+
+## Pero si necesitas más que un argumento (`$_`) en un bloque
+## (sin depender en `-> {}`), también puedes usar la sintaxis implícita
+## de argumento, `$` :
+map({ $^a + $^b + 3 }, @array); # equivalente a lo siguiente:
+map(sub ($a, $b) { $a + $b + 3 }, @array); # (aquí con `sub`)
+
+## Nota : Esos son ordernados lexicográficamente.
+# `{ $^b / $^a }` es como `-> $a, $b { $b / $a }`
+```
+
+### Acerca de tipos...
+
+```perl6
+## Raku es gradualmente tipado. Esto quiere decir que tu especifica el
+## tipo de tus variables/argumentos/devoluciones (return), o puedes omitirlos
+## y serán "Any" por defecto.
+## Obviamente tienes acceso a algunas tipos básicos, como Int y Str.
+## Las construcciones para declarar tipos son "class", "role", lo cual
+## verás más adelante.
+
+## Por ahora, examinemos "subset" (subconjunto).
+## Un "subset" es un "sub-tipo" con chequeos adicionales.
+## Por ejemplo: "un número entero bien grande es un Int que es mayor que 500"
+## Puedes especificar el tipo del que creas el subconjunto (por defecto, Any),
+## y añadir chequeos adicionales con la palabra clave "where" (donde):
+subset EnteroGrande of Int where * > 500;
+```
+
+### Despacho Múltiple (Multiple Dispatch)
+
+```perl6
+## Raku puede decidir que variante de una subrutina invocar basado en el
+## tipo de los argumento, o precondiciones arbitrarias, como con un tipo o
+## un `where`:
+
+## con tipos
+multi sub dilo(Int $n) { # nota la palabra clave `multi` aquí
+ say "Número: $n";
+}
+multi dilo(Str $s) { # un multi es una subrutina por defecto
+ say "Cadena de texto: $s";
+}
+dilo("azul"); # prints "Cadena de texto: azul"
+dilo(True); # falla al *tiempo de compilación* con
+ # "calling 'dilo' will never work with arguments of types ..."
+ # (invocar 'dilo' nunca funcionará con argumentos de tipos ...")
+## con precondición arbitraria (¿recuerdas los subconjuntos?):
+multi es-grande(Int $n where * > 50) { "¡Sí!" } # usando una clausura
+multi es-grande(Int $ where 10..50) { "Tal vez." } # Usando coincidencia inteligente
+ # (podrías usar un regexp, etc)
+multi es-grande(Int $) { "No" }
+
+subset Par of Int where * %% 2;
+
+multi inpar-o-par(Par) { "Par" } # El caso principal usando el tipo.
+ # No nombramos los argumentos,
+multi inpar-o-par($) { "Inpar" } # "else"
+
+## ¡Podrías despachar basado en la presencia de argumentos posicionales!
+multi sin_ti-o-contigo(:$with!) { # Necesitas hacerlo mandatorio
+ # para despachar en contra del argumento.
+ say "¡Puedo vivir! Actualmente, no puedo.";
+}
+multi sin_ti-o-contigo {
+ say "Definitivamente no puedo vivir.";
+}
+## Esto es muy útil para muchos propósitos, como subrutinas `MAIN` (de las
+## cuales hablaremos luego), y hasta el mismo lenguaje la está usando
+## en muchos lugares.
+##
+## - `is`, por ejemplo, es actualmente un `multi sub` llamado
+## `trait_mod:<is>`.
+## - `is rw`, es simplemente un despacho a una función con esta signatura:
+## sub trait_mod:<is>(Routine $r, :$rw!) {}
+##
+## (¡lo pusimos en un comentario dado que ejecutando esto sería una terrible
+## idea!)
+```
+
+## Ámbito (Scoping)
+
+```perl6
+## En Raku, a diferencia de otros lenguajes de scripting, (tales como
+## (Python, Ruby, PHP), debes declarar tus variables antes de usarlas. El
+## declarador `my`, del cual aprendiste anteriormente, usa "ámbito léxical".
+## Hay otros declaradores (`our`, `state`, ..., ) los cuales veremos luego.
+## Esto se llama "ámbito léxico", donde en los bloques internos,
+## puedes acceder variables de los bloques externos.
+my $archivo-en-ámbito = 'Foo';
+sub externo {
+ my $ámbito-externo = 'Bar';
+ sub interno {
+ say "$archivo-en-ámbito $ámbito-externo";
+ }
+ &interno; # devuelve la función
+}
+outer()(); #=> 'Foo Bar'
+
+## Como puedes ver, `$archivo-en-ámbito` y `$ámbito-externo`
+## fueron capturados. Pero si intentaramos usar `$bar` fuera de `foo`,
+## la variable estaría indefinida (y obtendrías un error al tiempo de
+## compilación).
+```
+
+## Twigils
+
+```perl6
+## Hay muchos `twigils` especiales (sigilos compuestos) en Raku.
+## Los twigils definen el ámbito de las variables.
+## Los twigils * y ? funcionan con variables regulares:
+## * Variable dinámica
+## ? Variable al tiempo de compilación
+## Los twigils ! y . son usados con los objetos de Raku:
+## ! Atributo (miembro de la clase)
+## . Método (no una variable realmente)
+
+## El twigil `*`: Ámbito dinámico
+## Estas variables usan el twigil `*` para marcar variables con ámbito
+## dinámico. Variables con ámbito dinámico son buscadas a través del
+## invocador, no a través del ámbito externo.
+
+my $*ambito_din_1 = 1;
+my $*ambito_din_2 = 10;
+
+sub di_ambito {
+ say "$*ambito_din_1 $*ambito_din_2";
+}
+
+sub invoca_a_di_ambito {
+ my $*ambito_din_1 = 25; # Define a $*ambito_din_1 solo en esta subrutina.
+ $*ambito_din_2 = 100; # Cambiará el valor de la variable en ámbito.
+ di_ambito(); #=> 25 100 $*ambito_din_1 y 2 serán buscadas en la invocación.
+ # Se usa el valor de $*ambito_din_1 desde el ámbito léxico de esta
+ # subrutina aunque los bloques no están anidados (están anidados por
+ # invocación).
+}
+di_ambito(); #=> 1 10
+invoca_a_di_ambito(); #=> 25 100
+ # Se usa a $*ambito_din_1 como fue definida en invoca_a_di_ambito
+ # aunque la estamos invocando desde afuera.
+di_ambito(); #=> 1 100 Cambiamos el valor de $*ambito_din_2 en invoca_a_di_ambito
+ # por lo tanto su valor a cambiado.
+```
+
+## Modelo de Objeto
+
+```perl6
+## Para invocar a un método en un objeto, agrega un punto seguido por el
+## nombre del objeto:
+## => $object.method
+## Las classes son declaradas usando la palabra clave `class`. Los atributos
+## son declarados con la palabra clave `has`, y los métodos con `method`.
+## Cada atributo que es privado usa el twigil `!`. Por ejemplo: `$!attr`.
+## Atributos públicos inmutables usan el twigil `.` (los puedes hacer
+## mutables con `is rw`).
+## La manera más fácil de recordar el twigil `$.` is comparándolo
+## con como los métodos son llamados.
+
+## El modelo de objeto de Raku ("SixModel") es muy flexible, y te permite
+## agregar métodos dinámicamente, cambiar la semántica, etc ...
+## (no hablaremos de todo esto aquí. Por lo tanto, refiérete a:
+## https://docs.raku.org/language/objects.html).
+
+class Clase-Atrib {
+ has $.atrib; # `$.atrib` es inmutable.
+ # Desde dentro de la clase, usa `$!atrib` para modificarlo.
+ has $.otro-atrib is rw; # Puedes marcar un atributo como público con `rw`.
+ has Int $!atrib-privado = 10;
+
+ method devolver-valor {
+ $.atrib + $!atrib-privado;
+ }
+
+ method asignar-valor($param) { # Métodos pueden tomar parámetros.
+ $!attrib = $param; # Esto funciona porque `$!` es siempre mutable.
+ # $.attrib = $param; # Incorrecto: No puedes usar la versión inmutable `$.`.
+
+ $.otro-atrib = 5; # Esto funciona porque `$.otro-atrib` es `rw`.
+ }
+
+ method !metodo-privado {
+ say "Este método es privado para la clase !";
+ }
+};
+
+## Crear una nueva instancia de Clase-Atrib con $.atrib asignado con 5:
+## Nota: No puedes asignarle un valor a atrib-privado desde aquí (más de
+## esto adelante).
+my $class-obj = Clase-Atrib.new(atrib => 5);
+say $class-obj.devolver-valor; #=> 5
+# $class-obj.atrib = 5; # Esto falla porque `has $.atrib` es inmutable
+$class-obj.otro-atrib = 10; # En cambio, esto funciona porque el atributo
+ # público es mutable (`rw`).
+```
+
+### Herencia de Objeto
+
+```perl6
+## Raku también tiene herencia (junto a herencia múltiple)
+## Mientras los métodos declarados con `method` son heredados, aquellos
+## declarados con `submethod` no lo son.
+## Submétodos son útiles para la construcción y destrucción de tareas,
+## tales como BUILD, o métodos que deben ser anulados por subtipos.
+## Aprenderemos acerca de BUILD más adelante.
+
+class Padre {
+ has $.edad;
+ has $.nombre;
+ # Este submétodo no será heredado por la clase Niño.
+ submethod color-favorito {
+ say "Mi color favorito es Azul";
+ }
+ # Este método será heredado
+ method hablar { say "Hola, mi nombre es $!nombre" }
+}
+# Herencia usa la palabra clave `is`
+class Niño is Padre {
+ method hablar { say "Goo goo ga ga" }
+ # Este método opaca el método `hablar` de Padre.
+ # Este niño no ha aprendido a hablar todavía.
+}
+my Padre $Richard .= new(edad => 40, nombre => 'Richard');
+$Richard.color-favorito; #=> "Mi color favorito es Azul"
+$Richard.hablar; #=> "Hola, mi nombre es Richard"
+## $Richard es capaz de acceder el submétodo; él sabe como decir su nombre.
+
+my Niño $Madison .= new(edad => 1, nombre => 'Madison');
+$Madison.hablar; # imprime "Goo goo ga ga" dado que el método fue cambiado
+ # en la clase Niño.
+# $Madison.color-favorito # no funciona porque no es heredado
+
+## Cuando se usa `my T $var` (donde `T` es el nombre de la clase), `$var`
+## inicia con `T` en si misma, por lo tanto puedes invocar `new` en `$var`.
+## (`.=` es sólo la invocación por punto y el operador de asignación:
+## `$a .= b` es lo mismo que `$a = $a.b`)
+## Por ejemplo, la instancia $Richard pudo también haber sido declarada así:
+## my $Richard = Padre.new(edad => 40, nombre => 'Richard');
+
+## También observa que `BUILD` (el método invocado dentro de `new`)
+## asignará propiedades de la clase padre, por lo que puedes pasar
+## `val => 5`.
+```
+
+### Roles, o Mixins
+
+```perl6
+## Roles son suportados también (comúnmente llamados Mixins en otros
+## lenguajes)
+role PrintableVal {
+ has $!counter = 0;
+ method print {
+ say $.val;
+ }
+}
+
+## Se "importa" un mixin (un "role") con "does":
+class Item does PrintableVal {
+ has $.val;
+
+ ## Cuando se utiliza `does`, un `rol` se mezcla en al clase literalmente:
+ ## los métodos y atributos se ponen juntos, lo que significa que una clase
+ ## puede acceder los métodos y atributos privados de su rol (pero no lo inverso!):
+ method access {
+ say $!counter++;
+ }
+
+ ## Sin embargo, esto:
+ ## method print {}
+ ## es SÓLO válido cuando `print` no es una `multi` con el mismo dispacho.
+ ## (esto significa que una clase padre puede opacar una `multi print() {}`
+ ## de su clase hijo/a, pero es un error sin un rol lo hace)
+
+ ## NOTA: Puedes usar un rol como una clase (con `is ROLE`). En este caso,
+ ## métodos serán opacados, dado que el compilador considerará `ROLE`
+ ## como una clase.
+}
+```
+
+## Excepciones
+
+```perl6
+## Excepciones están construidas al tope de las clases, en el paquete
+## `X` (como `X::IO`).
+## En Raku, excepciones son lanzadas automáticamente.
+open 'foo'; #=> Failed to open file foo: no such file or directory
+## También imprimirá la línea donde el error fue lanzado y otra información
+## concerniente al error.
+
+## Puedes lanzar una excepción usando `die`:
+die 'Error!'; #=> Error!
+
+## O más explícitamente:
+die X::AdHoc.new(payload => 'Error!');
+
+## En Raku, `orelse` es similar al operador `or`, excepto que solamente
+## coincide con variables indefinidas, en cambio de cualquier cosa
+## que evalúa a falso.
+## Valores indefinidos incluyen: `Nil`, `Mu` y `Failure`, también como
+## `Int`, `Str` y otros tipos que no han sido inicializados a ningún valor
+## todavía.
+## Puedes chequear si algo está definido o no usando el método defined:
+my $no-inicializada;
+say $no-inicializada.defined; #=> False
+## Al usar `orelse`, se desarmará la excepción y creará un alias de dicho
+## fallo en $_
+## Esto evitará que sea automáticamente manejado e imprima una marejada de
+## mensajes de errores en la pantalla.
+## Podemos usar el método de excepción en $_ para acceder la excepción:
+open 'foo' orelse say "Algo pasó {.exception}";
+
+## Esto también funciona:
+open 'foo' orelse say "Algo pasó $_"; #=> Algo pasó
+ #=> Failed to open file foo: no such file or directory
+## Ambos ejemplos anteriores funcionan pero en caso de que consigamos un
+## objeto desde el lado izquierdo que no es un fallo, probablemente
+## obtendremos una advertencia. Más abajo vemos como usar `try` y `CATCH`
+## para ser más expecíficos con las excepciones que capturamos.
+```
+
+### Usando `try` y `CATCH`
+
+```perl6
+## Al usar `try` y `CATCH`, puedes contener y manejar excepciones sin
+## interrumpir el resto del programa. `try` asignará la última excepción
+## a la variable especial `$!`.
+## Nota: Esto no tiene ninguna relación con las variables $!.
+
+try open 'foo';
+say "Bueno, lo intenté! $!" if defined $!; #=> Bueno, lo intenté! Failed to open file
+ #foo: no such file or directory
+## Ahora, ¿qué debemos hacer si queremos más control sobre la excepción?
+## A diferencia de otros lenguajes, en Raku se pone el bloque `CATCH`
+## *dentro* del bloque a intentar (`try`). Similarmente como $_ fue asignada
+## cuando 'disarmamos' la excepción con `orelse`, también usamos $_ en el
+## bloque CATCH.
+## Nota: ($! es solo asignada *después* del bloque `try`)
+## Por defecto, un bloque `try` tiene un bloque `CATCH` que captura
+## cualquier excepción (`CATCH { default {} }`).
+
+try { my $a = (0 %% 0); CATCH { say "Algo pasó: $_" } }
+ #=> Algo pasó: Attempt to divide by zero using infix:<%%>
+
+## Puedes redefinir lo anterior usando `when` y (`default`)
+## para manejar las excepciones que desees:
+try {
+ open 'foo';
+ CATCH { # En el bloque `CATCH`, la excepción es asignada a $_
+ when X::AdHoc { say "Error: $_" }
+ #=>Error: Failed to open file /dir/foo: no such file or directory
+
+ ## Cualquier otra excepción será levantada de nuevo, dado que no
+ ## tenemos un `default`.
+ ## Básicamente, si un `when`
+ ## Basically, if a `when` matches (or there's a `default`) marks the
+ ## exception as
+ ## "handled" so that it doesn't get re-thrown from the `CATCH`.
+ ## You still can re-throw the exception (see below) by hand.
+ }
+}
+
+## En Raku, excepciones poseen ciertas sutilezas. Algunas
+## subrutinas en Raku devuelven un `Failure`, el cual es un tipo de
+## "excepción no levantada". Ellas no son levantadas hasta que tu intentas
+## mirar a sus contenidos, a menos que invoques `.Bool`/`.defined` sobre
+## ellas - entonces, son manejadas.
+## (el método `.handled` es `rw`, por lo que puedes marcarlo como `False`
+## por ti mismo)
+## Puedes levantar un `Failure` usando `fail`. Nota que si el pragma
+## `use fatal` estás siendo utilizado, `fail` levantará una excepión (como
+## `die`).
+fail "foo"; # No estamos intentando acceder el valor, por lo tanto no problema.
+try {
+ fail "foo";
+ CATCH {
+ default { say "Levantó un error porque intentamos acceder el valor del fallo!" }
+ }
+}
+
+## También hay otro tipo de excepción: Excepciones de control.
+## Esas son excepciones "buenas", las cuales suceden cuando cambias el flujo
+## de tu programa, usando operadores como `return`, `next` or `last`.
+## Puedes capturarlas con `CONTROL` (no lista un 100% en Rakudo todavía).
+```
+
+## Paquetes
+
+```perl6
+## Paquetes son una manera de reusar código. Paquetes son como
+## "espacio de nombres" (namespaces en inglés), y cualquier elemento del
+## modelo seis (`module`, `role`, `class`, `grammar`, `subset` y `enum`)
+## son paquetes por ellos mismos. (Los paquetes son como el mínimo común
+## denominador)
+## Los paquetes son importantes - especialmente dado que Perl es bien
+## reconocido por CPAN, the Comprehensive Perl Archive Nertwork.
+
+## Puedes usar un módulo (traer sus declaraciones al ámbito) con `use`
+use JSON::Tiny; # si intalaste Rakudo* o Panda, tendrás este módulo
+say from-json('[1]').perl; #=> [1]
+
+## A diferencia de Perl, no deberías declarar paquetes usando
+## la palabra clave `package`. En vez, usa `class Nombre::Paquete::Aquí;`
+## para declarar una clase, o si solamente quieres exportar
+## variables/subrutinas, puedes usar `module`.
+
+module Hello::World { # forma de llaves
+ # Si `Hello` no existe todavía, solamente será una cola ("stub"),
+ # que puede ser redeclarada más tarde.
+ # ... declaraciones aquí ...
+}
+unit module Parse::Text; # forma de ámbito de archivo
+
+grammar Parse::Text::Grammar { # Una gramática (grammar en inglés) es un paquete,
+ # en el cual puedes usar `use`
+} # Aprenderás más acerca de gramáticas en la sección de regex
+
+## Como se dijo anteriormente, cualquier parte del modelo seis es también un
+## paquete. Dado que `JSON::Tiny` usa su propia clase `JSON::Tiny::Actions`,
+## tu puedes usarla de la manera siguiente:
+my $acciones = JSON::Tiny::Actions.new;
+
+## Veremos como exportar variables y subrutinas en la siguiente parte:
+```
+
+## Declaradores
+
+```perl6
+## En Raku, tu obtienes diferentes comportamientos basado en como declaras
+## una variable.
+## Ya has visto `my` y `has`, ahora exploraremos el resto.
+
+## * las declaraciones `our` ocurren al tiempo `INIT` (ve "Phasers" más abajo)
+## Es como `my`, pero también crea una variable paquete.
+## (Todas las cosas relacionadas con paquetes (`class`, `role`, etc) son
+## `our` por defecto)
+module Var::Incrementar {
+ our $nuestra-var = 1; # Nota: No puedes colocar una restricción de tipo
+ my $mi-var = 22; # como Int (por ejemplo) en una variable `our`.
+ our sub Inc {
+
+ our sub disponible { # Si tratas de hacer subrutinas internas `our`...
+ # Mejor que sepas lo que haces (No lo haga!).
+ say "No hagas eso. En serio. Estás jugando con fuego y te quemarás.";
+ }
+
+ my sub no-disponible { # `my sub` es por defecto
+ say "No puedes acceder aquí desde fuera. Soy 'my'!";
+ }
+ say ++$nuestra-var; # Incrementa la variable paquete y muestra su valor
+ }
+
+}
+say $Var::Incrementar::nuestra-var; #=> 1 Esto funciona
+say $Var::Incrementar::mi-var; #=> (Any) Esto no funcionará.
+
+Var::Incrementar::Inc; #=> 2
+Var::Incrementar::Inc; #=> 3 # Nota como el valor de $nuestra-var fue
+ # retenido
+Var::Incrementar::no-disponible; #=> Could not find symbol '&no-disponible'
+
+## * `constant` (ocurre al tiempo `BEGIN`)
+## Puedes usar la palabra clave `constant` para declarar una
+## variable/símbolo al tiempo de compilación:
+constant Pi = 3.14;
+constant $var = 1;
+
+## Y por si te estás preguntando, sí, también puede contener listas infinitas.
+constant porque-no = 5, 15 ... *;
+say porque-no[^5]; #=> 5 15 25 35 45
+
+## * `state` (ocurre al tiempo de ejecución, pero una sola vez)
+## Variables "states" son solo inicializadas una vez.
+## (ellas existen en otros lenguaje como `static` en C)
+sub aleatorio-fijo {
+ state $valor = rand;
+ say $valor;
+}
+aleatorio-fijo for ^10; # imprimirá el mismo número 10 veces
+
+## Nota, sin embargo, que ellas existen separadamente en diferentes contextos.
+## Si declaras una función con un `state` dentro de un bucle, recreará la
+## variable por cada iteración del bucle. Observa:
+for ^5 -> $a {
+ sub foo {
+ state $valor = rand; # Esto imprimirá un valor diferente
+ # por cada valor de `$a`
+ }
+ for ^5 -> $b {
+ say foo; # Esto imprimirá el mismo valor 5 veces, pero sólo 5.
+ # La siguiente iteración ejecutará `rand` nuevamente.
+ }
+}
+```
+
+## Phasers
+
+```perl6
+## Un phaser en Raku es un bloque que ocurre a determinados puntos de tiempo
+## en tu programa. Se les llama phaser porque marca un cambio en la fase de
+## de tu programa. Por ejemplo, cuando el programa es compilado, un bucle
+## for se ejecuta, dejas un bloque, o una excepción se levanta.
+## (¡`CATCH` es actualmente un phaser!)
+## Algunos de ellos pueden ser utilizados por sus valores devueltos, otros
+## no pueden (aquellos que tiene un "[*]" al inicio de su texto de
+## explicación).
+## ¡Tomemos una mirada!
+
+## * Phasers al tiempo de compilación
+BEGIN { say "[*] Se ejecuta al tiempo de compilación, " ~
+ "tan pronto como sea posible, una sola vez" }
+CHECK { say "[*] Se ejecuta al tiempo de compilación, " ~
+ "tan tarde como sea posible, una sola vez" }
+
+## * Phasers al tiempo de ejecución
+INIT { say "[*] Se ejecuta al tiempo de ejecución, " ~
+ "tan pronto como sea posible, una sola vez" }
+END { say "Se ejecuta al tiempo de ejecución, " ~
+ "tan tarde como sea posible, una sola vez" }
+
+## * Phasers de bloques
+ENTER { say "[*] Se ejecuta cada vez que entra en un bloque, " ~
+ "se repite en bloques de bucle" }
+LEAVE { say "Se ejecuta cada vez que abandona un bloque, incluyendo " ~
+ "cuando una excepción ocurre. Se repite en bloques de bucle"}
+
+PRE {
+ say "Impone una precondición a cada entrada de un bloque, " ~
+ "antes que ENTER (especialmente útil para bucles)";
+ say "Si este bloque no returna un valor truthy, " ~
+ "una excepción del tipo X::Phaser::PrePost será levantada.";
+}
+
+## Ejemplos:
+for 0..2 {
+ PRE { $_ > 1 } # Esto fallará con un "Precondition failed"
+}
+
+POST {
+ say "Impone una postcondAsserts a poscondición a la salida de un bloque, " ~
+ "después de LEAVE (especialmente útil para bucles)";
+ say "Si este bloque no returna un valor truthy, " ~
+ "una excepción del tipo X::Phaser::PrePost será levantada, como con PRE.";
+}
+for 0..2 {
+ POST { $_ < 2 } # Esto fallará con un "Postcondition failed"
+}
+
+## * Phasers de bloques/excepciones
+sub {
+ KEEP { say "Se ejecuta cuando sales de un bloque exitosamente
+ (sin lanzar un excepción)" }
+ UNDO { say "Se ejecuta cuando sale de bloque sin éxito
+ (al lanzar una excepción)" }
+}
+
+## * Phasers de bucle
+for ^5 {
+ FIRST { say "[*] La primera vez que un bucle se ejecuta, antes que ENTER" }
+ NEXT { say "Al tiempo de la continuación del bucle, antes que LEAVE" }
+ LAST { say "Al tiempo de la terminación del bucle, después de LEAVE" }
+}
+
+## * Phasers de rol/clase
+COMPOSE { "Cuando un rol es compuesto en una clase. /!\ NO IMPLEMENTADO TODAVÍA" }
+
+## Ellos permite pequeños trucos o código brillante...:
+say "Este código tomó " ~ (time - CHECK time) ~ "s para compilar";
+
+## ... o brillante organización:
+sub do-db-stuff {
+ $db.start-transaction; # comienza una transacción nueva
+ KEEP $db.commit; # commit (procede con) la transacción si todo estuvo bien
+ UNDO $db.rollback; # o retrocede si todo falló
+}
+```
+
+## Prefijos de sentencias
+
+```perl6
+## Los prefijos de sentencias actúan como los phasers: Ellos afectan el
+## comportamiento del siguiente código.
+## Debido a que son ejecutados en línea con el código ejecutable, ellos
+## se escriben en letras minúsculas. (`try` and `start` están teoréticamente
+## en esa lista, pero serán explicados en otra parte)
+## Nota: Ningunos de estos (excepto `start`) necesitan las llaves `{` y `}`.
+
+## - `do` (el cual ya viste) - ejecuta un bloque o una sentencia como un
+## término.
+## Normalmente no puedes usar una sentencia como un valor (o término):
+##
+## my $valor = if True { 1 } # `if` es una sentencia - error del parseador
+##
+## Esto funciona:
+my $a = do if True { 5 } # con `do`, `if` ahora se comporta como un término.
+
+## - `once` - se asegura que una porción de código se ejecute una sola vez.
+for ^5 { once say 1 }; #=> 1
+ # solo imprime ... una sola vez.
+## Al igual que `state`, ellos son clonados por ámbito
+for ^5 { sub { once say 1 }() } #=> 1 1 1 1 1
+ # Imprime una sola vez por ámbito léxico
+
+## - `gather` - Hilo de co-rutina
+## `gather` te permite tomar (`take`) varios valores en un array,
+## al igual que `do`. Encima de esto, te permite tomar cualquier expresión.
+say gather for ^5 {
+ take $_ * 3 - 1;
+ take $_ * 3 + 1;
+} #=> -1 1 2 4 5 7 8 10 11 13
+say join ',', gather if False {
+ take 1;
+ take 2;
+ take 3;
+} # no imprime nada.
+
+## - `eager` - Evalúa una sentencia ávidamente (forza contexto ávido)
+## No intentes esto en casa:
+##
+## eager 1..*; # esto probablemente se colgará por un momento
+## # (y podría fallar...).
+##
+## Pero considera lo siguiente:
+constant tres-veces = gather for ^3 { say take $_ }; # No imprime nada
+
+## frente a esto:
+constant tres-veces = eager gather for ^3 { say take $_ }; #=> 0 1 2
+```
+
+## Iterables
+
+```perl6
+## En Raku, los iterables son objetos que pueden ser iterados similar
+## a la construcción `for`.
+## `flat`, aplana iterables:
+say (1, 10, (20, 10) ); #=> (1 10 (20 10)) Nota como la agrupación se mantiene
+say (1, 10, (20, 10) ).flat; #=> (1 10 20 10) Ahora el iterable es plano
+
+## - `lazy` - Aplaza la evaluación actual hasta que el valor sea requirido
+## (forza contexto perezoso)
+my @lazy-array = (1..100).lazy;
+say @lazy-array.is-lazy; #=> True # Chequea por "pereza" con el método `is-lazy`.
+say @lazy-array; #=> [...] No se ha iterado sobre la lista
+for @lazy-array { .print }; # Esto funciona y hará tanto trabajo como sea necesario.
+
+[//]: # ( TODO explica que gather/take y map son todos perezosos)
+## - `sink` - Un `eager` que desecha los resultados (forza el contexto sink)
+constant nilthingie = sink for ^3 { .say } #=> 0 1 2
+say nilthingie.perl; #=> Nil
+
+## - `quietly` - Un bloque `quietly` reprime las advertencias:
+quietly { warn 'Esto es una advertencia!' }; #=> No salida
+
+## - `contend` - Intenta efectos secundarios debajo de STM
+## ¡No implementado todavía!
+```
+
+## ¡Más operadores!
+
+```perl6
+## ¡Todo el mundo ama los operadores! Tengamos más de ellos.
+
+## La lista de precedencia puede ser encontrada aquí:
+## https://docs.raku.org/language/operators#Operator_Precedence
+## Pero primero, necesitamos un poco de explicación acerca
+## de la asociatividad:
+
+## * Operadores binarios:
+$a ! $b ! $c; # con asociatividad izquierda `!`, esto es `($a ! $b) ! $c`
+$a ! $b ! $c; # con asociatividad derecha `!`, esto es `$a ! ($b ! $c)`
+$a ! $b ! $c; # sin asociatividad `!`, esto es ilegal
+$a ! $b ! $c; # con una cadena de asociatividad `!`, esto es `($a ! $b) and ($b ! $c)`
+$a ! $b ! $c; # con asociatividad de lista `!`, esto es `infix:<>`
+
+## * Operadores unarios:
+!$a! # con asociatividad izquierda `!`, esto es `(!$a)!`
+!$a! # con asociatividad derecha `!`, esto es `!($a!)`
+!$a! # sin asociatividad `!`, esto es ilegal
+```
+
+### ¡Crea tus propios operadores!
+
+```perl6
+## Okay, has leído todo esto y me imagino que debería mostrarte
+## algo interesante.
+## Te mostraré un pequeño secreto (o algo no tan secreto):
+## En Raku, todos los operadores son actualmente solo subrutinas.
+
+## Puedes declarar un operador como declaras una subrutina:
+sub prefix:<ganar>($ganador) { # se refiere a las categorías de los operadores
+ # (exacto, es el "operador de palabras" `<>`)
+ say "¡$ganador ganó!";
+}
+ganar "El Rey"; #=> ¡El Rey Ganó!
+ # (prefijo se pone delante)
+
+## todavías puedes invocar la subrutina con su "nombre completo":
+say prefix:<!>(True); #=> False
+
+sub postfix:<!>(Int $n) {
+ [*] 2..$n; # usando el meta-operador reduce ... Ve más abajo!
+}
+say 5!; #=> 120
+ # Operadores sufijos (postfix) van *directamente* después del témino.
+ # No espacios en blanco. Puedes usar paréntesis para disambiguar,
+ # i.e. `(5!)!`
+
+
+sub infix:<veces>(Int $n, Block $r) { # infijo va en el medio
+ for ^$n {
+ $r(); # Necesitas los paréntesis explícitos para invocar la función
+ # almacenada en la variable `$r`. De lo contrario, te estaría
+ # refiriendo a la variable (no a la función), como con `&r`.
+ }
+}
+3 veces -> { say "hola" }; #=> hola
+ #=> hola
+ #=> hola
+ # Se te recomienda que ponga espacios
+ # alrededor de la invocación de operador infijo.
+
+## Para los circunfijos y pos-circunfijos
+sub circumfix:<[ ]>(Int $n) {
+ $n ** $n
+}
+say [5]; #=> 3125
+ # un circunfijo va alrededor. De nuevo, no espacios en blanco.
+
+sub postcircumfix:<{ }>(Str $s, Int $idx) {
+ ## un pos-circunfijo es
+ ## "después de un término y alrededor de algo"
+ $s.substr($idx, 1);
+}
+say "abc"{1}; #=> b
+ # depués del término `"abc"`, y alrededor del índice (1)
+
+## Esto es de gran valor -- porque todo en Raku usa esto.
+## Por ejemplo, para eliminar una llave de un hash, tu usas el adverbio
+## `:delete` (un simple argumento con nombre debajo):
+%h{$llave}:delete;
+## es equivalente a:
+postcircumfix:<{ }>(%h, $llave, :delete); # (puedes invocar
+ # operadores de esta forma)
+## ¡*Todos* usan los mismos bloques básicos!
+## Categorías sintácticas (prefix, infix, ...), argumentos nombrados
+## (adverbios), ... - usados para construir el lenguaje - están al alcance
+## de tus manos y disponibles para ti.
+## (obviamente, no se te recomienda que hagas un operador de *cualquier
+## cosa* -- Un gran poder conlleva una gran responsabilidad.)
+```
+
+### Meta-operadores!
+
+```perl6
+## ¡Prepárate! Prepárate porque nos estamos metiendo bien hondo
+## en el agujero del conejo, y probablemente no querrás regresar a
+## otros lenguajes después de leer esto.
+## (Me imagino que ya no quieres a este punto).
+## Meta-operadores, como su nombre lo sugiere, son operadores *compuestos*.
+## Básicamente, ellos son operadores que se aplican a otros operadores.
+
+## * El meta-operador reduce (reducir)
+## Es un meta-operador prefijo que toman una función binaria y
+## una o varias listas. Sino se pasa ningún argumento,
+## returna un "valor por defecto" para este operador
+## (un valor sin significado) o `Any` si no hay ningún valor.
+##
+## De lo contrario, remueve un elemento de la(s) lista(s) uno a uno, y
+## aplica la función binaria al último resultado (o al primer elemento de
+## la lista y el elemento que ha sido removido).
+##
+## Para sumar una lista, podrías usar el meta-operador "reduce" con `+`,
+## i.e.:
+say [+] 1, 2, 3; #=> 6
+## es equivalente a `(1+2)+3`
+
+say [*] 1..5; #=> 120
+## es equivalente a `((((1*2)*3)*4)*5)`.
+
+## Puedes reducir con cualquier operador, no solo con operadores matemáticos.
+## Por ejemplo, podrías reducir con `//` para conseguir
+## el primer elemento definido de una lista:
+say [//] Nil, Any, False, 1, 5; #=> False
+ # (Falsey, pero definido)
+
+## Ejemplos con valores por defecto:
+say [*] (); #=> 1
+say [+] (); #=> 0
+ # valores sin significado, dado que N*1=N y N+0=N.
+say [//]; #=> (Any)
+ # No hay valor por defecto para `//`.
+## También puedes invocarlo con una función de tu creación usando
+## los dobles corchetes:
+sub add($a, $b) { $a + $b }
+say [[&add]] 1, 2, 3; #=> 6
+
+## * El meta-operador zip
+## Este es un meta-operador infijo que también puede ser usado como un
+## operador "normal". Toma una función binaria opcional (por defecto, solo
+## crear un par), y remueve un valor de cada array e invoca su función
+## binaria hasta que no tenga más elementos disponibles. Al final, returna
+## un array con todos estos nuevos elementos.
+(1, 2) Z (3, 4); # ((1, 3), (2, 4)), dado que por defecto, la función
+ # crea un array.
+1..3 Z+ 4..6; # (5, 7, 9), usando la función personalizada infix:<+>
+
+## Dado que `Z` tiene asociatividad de lista (ve la lista más arriba),
+## puedes usarlo en más de una lista
+(True, False) Z|| (False, False) Z|| (False, False); # (True, False)
+
+## Y pasa que también puedes usarlo con el meta-operador reduce:
+[Z||] (True, False), (False, False), (False, False); # (True, False)
+
+
+## Y para terminar la lista de operadores:
+
+## * El operador secuencia
+## El operador secuencia es uno de la más poderosas características de
+## Raku: Está compuesto, en la izquierda, de la lista que quieres que
+## Raku use para deducir (y podría incluir una clausura), y en la derecha,
+## un valor o el predicado que dice cuando parar (o Whatever para una
+## lista infinita perezosa).
+my @list = 1, 2, 3 ... 10; # deducción básica
+#my @list = 1, 3, 6 ... 10; # esto muere porque Raku no puede deducir el final
+my @list = 1, 2, 3 ...^ 10; # como con rangos, puedes excluir el último elemento
+ # (la iteración cuando el predicado iguala).
+my @list = 1, 3, 9 ... * > 30; # puedes usar un predicado
+ # (con la Whatever Star, aquí).
+my @list = 1, 3, 9 ... { $_ > 30 }; # (equivalente a lo de arriba)
+
+my @fib = 1, 1, *+* ... *; # lista infinita perezosa de la serie fibonacci,
+ # computada usando una clausura!
+my @fib = 1, 1, -> $a, $b { $a + $b } ... *; # (equivalene a lo de arriba)
+my @fib = 1, 1, { $^a + $^b } ... *; #(... también equivalene a lo de arriba)
+## $a and $b siempre tomarán el valor anterior, queriendo decir que
+## ellos comenzarán con $a = 1 y $b = 1 (valores que hemos asignado
+## de antemano). Por lo tanto, $a = 1 y $b = 2 (resultado del anterior $a+$b),
+## etc.
+
+say @fib[^10]; #=> 1 1 2 3 5 8 13 21 34 55
+ # (usandi un rango como el índice)
+## Nota: Los elementos de un rango, una vez cosificados, no son re-calculados.
+## Esta es la razón por la cual `@primes[^100]` tomará más tiempo la primera
+## vez que se imprime. Después de esto, será hará en un instante.
+```
+
+## Expresiones Regulares
+
+```perl6
+## Estoy seguro que has estado esperando por esta parte. Bien, ahora que
+## sabes algo acerca de Raku, podemos comenzar. Primeramente, tendrás
+## que olvidarte acerca de "PCRE regexps" (perl-compatible regexps)
+## (expresiones regulares compatible de perl).
+##
+## IMPORTANTE: No salte esto porque ya sabes acerca de PCRE. Son totalmente
+## distintos. Algunas cosas son las mismas (como `?`, `+`, y `*`) pero
+## algunas veces la semántica cambia (`|`). Asegúrate de leer esto
+## cuidadosamente porque podrías trospezarte sino lo haces.
+##
+## Raku tiene muchas características relacionadas con RegExps. Después de
+## todo, Rakudo se parsea a si mismo. Primero vamos a estudiar la sintaxis
+## por si misma, después hablaremos acerca de gramáticas (parecido a PEG),
+## las diferencias entre los declaradores `token`, `regex`, y `rule` y
+## mucho más.
+## Nota aparte: Todavía tienes acceso a los regexes PCRE usando el
+## mofificador `:P5` (Sin embargo, no lo discutiremos en este tutorial).
+##
+## En esencia, Raku implementa PEG ("Parsing Expression Grammars")
+## ("Parseado de Expresiones de Gramáticas") nativamente. El orden jerárquico
+## para los parseos ambiguos es determinado por un examen multi-nivel de
+## desempate:
+## - La coincidencia de token más larga. `foo\s+` le gana a `foo`
+## (por 2 o más posiciones)
+## - El prefijo literal más largo. `food\w*` le gana a `foo\w*` (por 1)
+## - Declaración desde la gramática más derivada a la menos derivada
+## (las gramáticas son actualmente clases)
+## - La declaración más temprana gana
+say so 'a' ~~ /a/; #=> True
+say so 'a' ~~ / a /; #=> True # ¡Más legible con los espacios!
+
+## Nota al lector (del traductor):
+## Como pudiste haber notado, he decidido traducir "match" y sus diferentes
+## formas verbales como "coincidir" y sus diferentes formas. Cuando digo que
+## un regex (o regexp) coincide con cierto texto, me refiero a que el regex
+## describe cierto patrón dentro del texto. Por ejemplo, el regex "cencia"
+## coincide con el texto "reminiscencia", lo que significa que dentro del
+## texto aparece ese patrón de caracteres (una `c`, seguida de una `e`,
+## (seguida de una `n`, etc.)
+
+## En todos nuestros ejemplos, vamos a usar el operador de
+## "coincidencia inteligente" contra una expresión regular ("regexp" or
+## "regex" de aquí en adelante). Estamos convirtiendo el resultado usando `so`,
+## pero en efecto, está devolviendo un objeto Match. Ellos saben como responder
+## a la indexación de lista, indexación de hash, y devolver la cadena de
+## texto coincidente.
+## Los resultados de la coincidencia están disponible como `$/` (en
+## ámbito implícito lexical). También puedes usar las variables de captura
+## las cuales comienzan con 0:
+## `$0`, `$1', `$2`...
+##
+## Nota que `~~` no hace un chequeo de inicio/final (es decir,
+## el regexp puede coincider con solo un carácter de la cadena de texto).
+## Explicaremos luego como hacerlo.
+
+## En Raku, puedes tener un carácter alfanumérico como un literal,
+## todo lo demás debe escaparse usando una barra invertida o comillas.
+say so 'a|b' ~~ / a '|' b /; # `True`. No sería lo mismo si no se escapara `|`
+say so 'a|b' ~~ / a \| b /; # `True`. Otra forma de escaparlo
+
+## El espacio en blanco actualmente no se significa nada en un regexp,
+## a menos que uses el adverbio `:s` (`:sigspace`, espacio significante).
+say so 'a b c' ~~ / a b c /; #=> `False`. Espacio no significa nada aquí.
+say so 'a b c' ~~ /:s a b c /; #=> `True`. Agregamos el modificador `:s` aquí.
+## Si usamos solo un espacio entre cadenas de texto en un regexp, Raku
+## nos advertirá:
+say so 'a b c' ~~ / a b c /; #=> 'False' # Espacio no significa nada aquí.
+## Por favor usa comillas o el modificador :s (:sigspace) para suprimir
+## esta advertencia, omitir el espacio, o cambiar el espaciamiento. Para
+## arreglar esto y hacer los espacios menos ambiguos, usa por lo menos
+## dos espacios entre las cadenas de texto o usa el adverbio `:s`.
+
+## Como vimos anteriormente, podemos incorporar `:s` dentro de los
+## delimitadores de barras. También podemos ponerlos fuera de ellos si
+## especificamos `m` for `match` (coincidencia):
+say so 'a b c' ~~ m:s/a b c/; #=> `True`
+## Al usar `m` para especificar 'match', podemos también otros delimitadore:
+say so 'abc' ~~ m{a b c}; #=> `True`
+say so 'abc' ~~ m[a b c]; #=> `True`
+
+## Usa el adverbio :i para especificar que no debería haber distinción entre
+## minúsculas y mayúsculas:
+say so 'ABC' ~~ m:i{a b c}; #=> `True`
+
+## Sin embargo, es importante para como los modificadores son aplicados
+## (lo cual verás más abajo)...
+
+## Cuantificando - `?`, `+`, `*` y `**`.
+## - `?` - 0 o 1
+so 'ac' ~~ / a b c /; # `False`
+so 'ac' ~~ / a b? c /; # `True`, la "b" coincidió (apareció) 0 veces.
+so 'abc' ~~ / a b? c /; # `True`, la "b" coincidió 1 vez.
+
+## ... Como debes saber, espacio en blancos son importante porque
+## determinan en que parte del regexp es el objetivo del modificador:
+so 'def' ~~ / a b c? /; # `False`. Solamente la `c` es opcional
+so 'def' ~~ / a b? c /; # `False`. Espacio en blanco no es significante
+so 'def' ~~ / 'abc'? /; # `True`. El grupo "abc"completo es opcional.
+
+## Aquí (y más abajo) el cuantificador aplica solamente a la `b`
+
+## - `+` - 1 o más
+so 'ac' ~~ / a b+ c /; # `False`; `+` quiere por lo menos una coincidencia
+so 'abc' ~~ / a b+ c /; # `True`; una es suficiente
+so 'abbbbc' ~~ / a b+ c /; # `True`, coincidió con 4 "b"s
+
+## - `*` - 0 o más
+so 'ac' ~~ / a b* c /; # `True`, todos son opcionales.
+so 'abc' ~~ / a b* c /; # `True`
+so 'abbbbc' ~~ / a b* c /; # `True`
+so 'aec' ~~ / a b* c /; # `False`. "b"(s) son opcionales, no reemplazables.
+
+## - `**` - Cuantificador (sin límites)
+## Si entrecierras los ojos lo suficiente, pueder ser que entiendas
+## por qué la exponenciación es usada para la cantidad.
+so 'abc' ~~ / a b**1 c /; # `True` (exactamente una vez)
+so 'abc' ~~ / a b**1..3 c /; # `True` (entre una y tres veces)
+so 'abbbc' ~~ / a b**1..3 c /; # `True`
+so 'abbbbbbc' ~~ / a b**1..3 c /; # `False` (demasiado)
+so 'abbbbbbc' ~~ / a b**3..* c /; # `True` (rangos infinitos no son un problema)
+
+## - `<[]>` - Clases de carácteres
+## Las clases de carácteres son equivalentes a las clases `[]` de PCRE,
+## pero usan una sintaxis de Raku:
+say 'fooa' ~~ / f <[ o a ]>+ /; #=> 'fooa'
+
+## Puedes usar rangos:
+say 'aeiou' ~~ / a <[ e..w ]> /; #=> 'ae'
+
+## Al igual que regexes normales, si quieres usar un carácter especial,
+## escápalo (el último está escapando un espacio)
+say 'he-he !' ~~ / 'he-' <[ a..z \! \ ]> + /; #=> 'he-he !'
+
+## Obtendrás una advertencia si pones nombres duplicados
+## (lo cual tiene el efecto de capturar la frase escrita)
+'he he' ~~ / <[ h e ' ' ]> /; # Advierte "Repeated characters found in characters
+ # class"
+
+## También puedes negarlos... (equivalenta a `[^]` en PCRE)
+so 'foo' ~~ / <-[ f o ]> + /; # False
+
+## ... y componerlos:
+so 'foo' ~~ / <[ a..z ] - [ f o ]> + /; # False (cualquier letra excepto f y o)
+so 'foo' ~~ / <-[ a..z ] + [ f o ]> + /; # True (no letra excepto f and o)
+so 'foo!' ~~ / <-[ a..z ] + [ f o ]> + /; # True (el signo + no reemplaza la
+ # parte de la izquierda)
+```
+
+### Grupos y Capturas
+
+```perl6
+## Grupo: Puedes agrupar partes de tu regexp con `[]`.
+## Estos grupos *no son* capturados (como con `(?:)` en PCRE).
+so 'abc' ~~ / a [ b ] c /; # `True`. El agrupamiento no hace casi nada
+so 'foo012012bar' ~~ / foo [ '01' <[0..9]> ] + bar /;
+## La línea anterior returna `True`.
+## Coincidimos (o encotramos el patrón) "012" una o más de una vez (
+## (el signo `+` fue aplicado al grupo).
+## Pero esto no va demasiado lejos, porque no podemos actualmente obtener
+## devuelta el patrón que coincidió.
+
+## Captura: Podemos actualmente *capturar* los resultados del regexp,
+## usando paréntesis.
+so 'fooABCABCbar' ~~ / foo ( 'A' <[A..Z]> 'C' ) + bar /; # `True`. (usando `so`
+ # aquí, `$/` más abajo)
+
+## Ok. Comenzando con las explicaciones de grupos. Como dijimos,
+### nuestra objeto `Match` está disponible en la variable `$/`:
+say $/; # Imprimirá algo extraño (explicaremos luego) o
+ # "Nil" si nada coincidió
+
+## Como dijimos anteriormente, un objeto Match tiene indexación de array:
+say $/[0]; #=> 「ABC」 「ABC」
+ # Estos corchetes extranos son los objetos `Match`.
+ # Aquí, tenemos un array de ellos.
+say $0; # Lo mismo que lo anterior.
+
+## Nuestra captura es `$0` porque es la primera y única captura en el
+## regexp. Podrías estarte preguntando porque un array y la respuesta es
+## simple: Algunas capturas (indezadas usando `$0`, `$/[0]` o una nombrada)
+## será un array si y solo si puedes tener más de un elemento.
+## (Así que, con `*`, `+` y `**` (cualquiera los operandos), pero no con `?`).
+## Usemos algunos ejemplos para ver como funciona:
+
+## Nota: Pusimos A B C entre comillas para demostrar que el espacio en blanco
+## entre ellos no es significante. Si queremos que el espacio en blanco
+## *sea* significante, podemos utilizar el modificador `:sigspace`.
+so 'fooABCbar' ~~ / foo ( "A" "B" "C" )? bar /; # `True`
+say $/[0]; #=> 「ABC」
+say $0.WHAT; #=> (Match)
+ # Puede haber más de uno, por lo tanto es solo un solo objeto match.
+so 'foobar' ~~ / foo ( "A" "B" "C" )? bar /; #=> True
+say $0.WHAT; #=> (Any)
+ # Esta captura no coincidió, por lo tanto está vacía
+so 'foobar' ~~ / foo ( "A" "B" "C" ) ** 0..1 bar /; # `True`
+say $0.WHAT; #=> (Array)
+ # Un cuantificador específico siempre capturará un Array,
+ # puede ser un rango o un valor específico (hasta 1).
+
+## Las capturas son indezadas por anidación. Esto quiere decir que un grupo
+## dentro de un grup estará anidado dentro de su grupo padre: `$/[0][0]`,
+## para este código:
+'hello-~-world' ~~ / ( 'hello' ( <[ \- \~ ]> + ) ) 'world' /;
+say $/[0].Str; #=> hello~
+say $/[0][0].Str; #=> ~
+
+## Esto se origina de un hecho bien simple: `$/` no contiene cadenas de
+## texto, números enteros o arrays sino que solo contiene objetos Match.
+## Estos objetos contienen los métodos `.list`, `.hash` y `.Str`. (Pero
+## también puedes usar `match<llave>` para accesar un hash y `match[indice]`
+## para accesar un array.
+say $/[0].list.perl; #=> (Match.new(...),).list
+ # Podemos ver que es una lista de objetos Match.
+ # Estos contienen un montón de información: dónde la
+ # coincidencia comenzó o terminó, el "ast"
+ # (chequea las acciones más abajo), etc.
+ # Verás capturas nombradas más abajo con las gramáticas.
+
+## Alternativas - el `or` de regexes
+## Advertencia: Es diferente a los regexes de PCRE.
+so 'abc' ~~ / a [ b | y ] c /; # `True`. o "b" o "y".
+so 'ayc' ~~ / a [ b | y ] c /; # `True`. Obviamente suficiente...
+
+## La diferencia entre este `|` y el otro al que estás acustombrado es LTM.
+## LTM significa "Longest Token Matching", traducido libremente como
+## "Coincidencia de Token Más Larga". Esto significa que el motor ("engine")
+## siempre intentará coindidir tanto como sea posible en la cadena de texto.
+## Básicamente, intentará el patrón más largo que concuerde con el regexp.
+'foo' ~~ / fo | foo /; # `foo` porque es más largo.
+## Para decidir cual parte es la "más larga", primero separa el regex en
+## dos partes:
+## El "prefijo declarativo" (la parte que puede ser analizada estáticamente)
+## y las partes procedimentales.
+## Los prefijos declarativos incluyen alternaciones (`|`), conjunciones (`&`),
+## invocaciones de sub-reglas (no han sido introducidos todavía), clases de
+## caracteres y cuantificadores.
+## Las partes procidimentales incluyen todo lo demás: referencias a elementos
+## anteriores, aserciones de código, y otras cosas que tradicionalmente no pueden
+## ser representadas por regexes normales.
+##
+## Entonces, todas las alternativas se intentan al mismo tiempo, y la
+## más larga gana.
+## Ejemplos:
+## DECLARATIVO | PROCEDIMENTAL
+/ 'foo' \d+ [ <subrule1> || <subrule2> ] /;
+## DECLARATIVO (grupos anidados no son un problema)
+/ \s* [ \w & b ] [ c | d ] /;
+## Sin embargo, las clausuras y la recursión (de regexes nombrados)
+## son procedimentales.
+## ... Hay más reglas complicadas, como la especifidad (los literales ganan
+## son las clases de caracteres)
++
+## Nota: la primera coincidencia `or` todavía existen, pero ahora se
+## deletrea `||`
+'foo' ~~ / fo || foo /; # `fo` ahora.
+```
+
+## Extra: la subrutina MAIN
+
+```perl6
+## La subrutina `MAIN` se invoca cuando tu ejecuta un archivo de Raku
+## directamente. Es realmente poderosa porque Raku actualmente parsea
+## los argumentos y los pasas a la subrutina. También maneja argumentos
+## nombrados (`--foo`) y hasta autogenerará un `--help`.
+sub MAIN($nombre) { say "¡Hola, $nombre!" }
+## Esto produce:
+## $ raku cli.pl
+## Uso:
+## t.pl <nombre>
+
+## Y dado que una subrutina regular en Raku, puedes tener múltiples
+## despachos:
+## (usando un "Bool" por un argumento nombrado para que podamos hacer
+## `--replace` a cambio de `--replace=1`)
+subset File of Str where *.IO.d; # convierte a un objeto IO para chequear si
+ # un archivo existe
+
+multi MAIN('add', $key, $value, Bool :$replace) { ... }
+multi MAIN('remove', $key) { ... }
+multi MAIN('import', File, Str :$as) { ... } # omitiendo parámetros nombrados
+## Esto produce:
+## $ raku cli.pl
+## Uso:
+## t.pl [--replace] add <key> <value>
+## t.pl remove <key>
+## t.pl [--as=<Str>] import (File)
+## Como puedes ver, esto es *realmente* poderoso.
+## Fue tan lejos como para mostrar las constantes en líneas.
+## (el tipo solo se muestra cuando el argumento `$`/ es nombrado)
+```
+
+## APÉNDICE A:
+### Lista de cosas
+
+```perl6
+## Consideramos que por ahora ya sabes lo básico de Raku.
+## Esta sección es solo para listar algunas operaciones comunes
+## las cuales no están en la "parte principal" del tutorial.
+
+## Operadores
+
+## * Comparación para ordenar
+## Ellos returnan un valor de los enum `Order`: `Less`, `Same` y `More`
+## (los cuales representan los números -1, 0 o +1).
+1 <=> 4; # comparación de orden para caracteres numéricos
+'a' leg 'b'; # comparación de orden para cadenas de texto
+$obj eqv $obj2; # comparación de orden usando la semántica eqv
+
+## * Ordenación genérica
+3 before 4; # True
+'b' after 'a'; # True
+
+## * Operador (por defecto) de circuito corto
+## Al igual que `or` y `||`, pero devuelve el primer valor *defined*
+## (definido):
+say Any // Nil // 0 // 5; #=> 0
+
+## * Circuito corto exclusivo or (XOR)
+## Devuelve `True` si uno (y solo uno) de sus argumentos es verdadero:
+say True ^^ False; #=> True
+
+## * Flip Flop
+## Los operadores flip flop (`ff` y `fff`, equivalente a `..`/`...` en P5)
+## son operadores que toman dos predicados para evalualarlos:
+## Ellos son `False` hasta que su lado izquierdo devuelve `True`, entonces
+## son `True` hasta que su lado derecho devuelve `True`.
+## Como los rangos, tu puedes excluir la iteración cuando se convierte en
+## `True`/`False` usando `^` en cualquier lado.
+## Comencemos con un ejemplo:
+for <well met young hero we shall meet later> {
+ # por defecto, `ff`/`fff` hace coincidencia inteligente (`~~`) contra `$_`:
+ if 'met' ^ff 'meet' { # no entrará el bucle if por "met"
+ # (se explica más abajo).
+ .say
+ }
+
+ if rand == 0 ff rand == 1 { # compara variables más que `$_`
+ say "Esto ... probablemente nunca se ejecutará ...";
+ }
+}
+## Esto imprimirá "young hero we shall meet" (exluyendo "met"):
+## el flip-flop comenzará devolviendo `True` cuando primero encuentra "met"
+## (pero no returnará `False` por "met" dabido al `^` al frente de `ff`),
+## hasta que ve "meet", lo cual es cuando comenzará devolviendo `False`.
+
+## La diferencia entre `ff` (al estilo de awk) y `fff` (al estilo de sed)
+## es que `ff` probará su lado derecho cuando su lado izquierdo cambia
+## a `True`, y puede returnar a `False` inmediamente (*excepto* que será
+## `True` por la iteración con la cual coincidió). Por lo contrario,
+## `fff` esperará por la próxima iteración para intentar su lado
+## derecho, una vez que su lado izquierdo ha cambiado:
+.say if 'B' ff 'B' for <A B C B A>; #=> B B
+ # porque el lado derecho se puso a prueba
+ # directamente (y returnó `True`).
+ # Las "B"s se imprimen dadó que coincidió
+ # en ese momento (returnó a `False`
+ # inmediatamente).
+.say if 'B' fff 'B' for <A B C B A>; #=> B C B
+ # El lado derecho no se puso a prueba
+ # hasta que `$_` se convirtió en "C"
+ # (y por lo tanto no coincidió
+ # inmediamente).
+
+## Un flip-flop puede cambiar estado cuantas veces se necesite:
+for <test start print it stop not printing start print again stop not anymore> {
+ .say if $_ eq 'start' ^ff^ $_ eq 'stop'; # excluye a "start" y "stop",
+ #=> "print it print again"
+}
+
+## También podrías usar una Whatever Star, lo cual es equivalente
+## a `True` para el lado izquierdo o `False` para el lado derecho:
+for (1, 3, 60, 3, 40, 60) { # Nota: los paréntesis son superfluos aquí
+ # (algunas veces se les llaman "paréntesis superticiosos")
+ .say if $_ > 50 ff *; # Una vez el flip-flop alcanza un número mayor que 50,
+ # no returnará jamás a `False`
+ #=> 60 3 40 60
+}
+
+## También puedes usar esta propiedad para crear un `If`
+## que no pasará la primera vez:
+for <a b c> {
+ .say if * ^ff *; # el flip-flop es `True` y nunca returna a `False`,
+ # pero el `^` lo hace *que no se ejecute* en la
+ # primera iteración
+ #=> b c
+}
+
+## - `===` es la identidad de valor y usa `.WHICH`
+## en los objetos para compararlos.
+## - `=:=` es la identidad de contenedor y usa `VAR()`
+## en los objetos para compararlos.
+
+```
+Si quieres ir más allá de lo que se muestra aquí, puedes:
+
+ - Leer la [documentación de Raku](https://docs.raku.org/). Esto es un recurso
+ grandioso acerca de Raku. Si estás buscando por algo en particular, usa la
+ barra de búsquedas. Esto te dará un menú de todas las páginas concernientes
+ a tu término de búsqueda (¡Es mucho mejor que usar Google para encontrar
+ documentos acerca de Raku!)
+ - Leer el [Raku Advent Calendar](https://rakuadventcalendar.wordpress.com/). Este es
+ un gran recurso de fragmentos de código de Raku y explicaciones. Si la documentación
+ no describe algo lo suficientemente bien, puedes encontrar información más detallada
+ aquí. Esta información puede ser un poquito más antigua pero hay muchos ejemplos y
+ explicaciones. Las publicaciones fueron suspendidas al final del 2015 cuando
+ el lenguaje fue declarado estable y Raku.c fue lanzado.
+ - Unirte a `#raku` en `irc.freenode.net`. Las personas aquí son siempre serviciales.
+ - Chequear la [fuente de las funciones y clases de Raku
+ ](https://github.com/rakudo/rakudo/tree/master/src/core.c). Rakudo está principalmente
+ escrito en Raku (con mucho de NQP, "Not Quite Perl" ("No Perl Todavía"), un
+ subconjunto de Raku que es más fácil de implementar y optimizar).
+ - Leer [documentos acerca del diseño del lenguaje](http://design.raku.org).
+ Estos explican P6 desde la perspectiva de un implementador, lo cual es bastante
+ interesante.
diff --git a/es-es/ruby-es.html.markdown b/es-es/ruby-es.html.markdown
index e3e43c18..63a47e89 100644
--- a/es-es/ruby-es.html.markdown
+++ b/es-es/ruby-es.html.markdown
@@ -139,7 +139,7 @@ status == :pendiente #=> true
status == 'pendiente' #=> false
-status == :aprovado #=> false
+status == :aprobado #=> false
# Arreglos
diff --git a/es-es/sass-es.html.markdown b/es-es/sass-es.html.markdown
index 89e56ba5..d130fe8c 100644
--- a/es-es/sass-es.html.markdown
+++ b/es-es/sass-es.html.markdown
@@ -1,6 +1,6 @@
---
language: sass
-filename: learnsass.scss
+filename: learnsass-es.scss
contributors:
- ["Laura Kyle", "https://github.com/LauraNK"]
- ["Sean Corrales", "https://github.com/droidenator"]
diff --git a/es-es/scala-es.html.markdown b/es-es/scala-es.html.markdown
new file mode 100644
index 00000000..2dcb9e7f
--- /dev/null
+++ b/es-es/scala-es.html.markdown
@@ -0,0 +1,741 @@
+---
+language: Scala
+filename: learnscala-es.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:
+ - ["Pablo Arranz Ropero", "http://arranzropablo.com"]
+lang: es-es
+---
+
+Scala - El lenguaje escalable
+
+```scala
+
+/////////////////////////////////////////////////
+// 0. Básicos
+/////////////////////////////////////////////////
+/*
+ Configurar Scala:
+
+ 1) Descarga Scala - http://www.scala-lang.org/downloads
+ 2) Unzip/untar a tu carpeta elegida y pon la subcarpeta bin en tu variable de entorno `PATH`
+*/
+
+/*
+ Prueba REPL
+
+ Scala tiene una herramienta llamada REPL (Read-Eval-Print Loop, en español: Bucle de lectura-evaluación-impresión) que es analogo a interpretes de la linea de comandos en muchos otros lenguajes.
+ Puedes escribir cualquier expresión en Scala y el resultado será evaluado e impreso.
+
+ REPL es una herramienta muy práctica para testear y verificar código.
+ Puedes usarla mientras lees este tutorial para explorar conceptos por tu cuenta.
+*/
+
+// Inicia Scala REPL ejecutando `scala` en tu terminal. Deberías ver:
+$ scala
+scala>
+
+// Por defecto cada expresión que escribes es guardada como un nuevo valor numerado:
+scala> 2 + 2
+res0: Int = 4
+
+// Los valores por defecto pueden ser reusados. Fíjate en el tipo del valor mostrado en el resultado...
+scala> res0 + 2
+res1: Int = 6
+
+// Scala es un lenguaje fuertemente tipado. Puedes usar REPL para comprobar el tipo sin evaluar una expresión.
+scala> :type (true, 2.0)
+(Boolean, Double)
+
+// Las sesiones REPL pueden ser guardadas
+scala> :save /sites/repl-test.scala
+
+// Se pueden cargar archivos en REPL
+scala> :load /sites/repl-test.scala
+Loading /sites/repl-test.scala...
+res2: Int = 4
+res3: Int = 6
+
+// Puedes buscar en tu historial reciente
+scala> :h?
+1 2 + 2
+2 res0 + 2
+3 :save /sites/repl-test.scala
+4 :load /sites/repl-test.scala
+5 :h?
+
+// Ahora que sabes como jugar, aprendamos un poco de Scala...
+
+/////////////////////////////////////////////////
+// 1. Básicos
+/////////////////////////////////////////////////
+
+// Los comentarios de una linea comienzan con dos barras inclinadas
+
+/*
+ Los comentarios de varias lineas, como ya has visto arriba, se hacen de esta manera.
+*/
+
+// Así imprimimos forzando una nueva linea en la siguiente impresión
+println("Hola mundo!")
+println(10)
+// Hola mundo!
+// 10
+
+// Así imprimimos sin forzar una nueva linea en la siguiente impresión
+print("Hola mundo")
+print(10)
+// Hola mundo10
+
+// Para declarar valores usamos var o val.
+// Valores decalrados con val son inmutables, mientras que los declarados con var son mutables.
+// La inmutabilidad es algo bueno.
+val x = 10 // x es 10
+x = 20 // error: reassignment to val
+var y = 10
+y = 20 // y es 20
+
+/*
+ Scala es un lenguaje tipado estáticamente, aunque se puede ver en las expresiones anteriores que no hemos especificado un tipo.
+ Esto es debido a una funcionalidad del lenguaje llamada inferencia. En la mayoría de los casos, el compilador de Scala puede adivinar cual es el tipo de una variable, así que no hace falta escribirlo siempre.
+ Podemos declarar explicitamente el tipo de una variable de la siguiente manera:
+*/
+val z: Int = 10
+val a: Double = 1.0
+
+// Observa la conversión automática de Int a Double, el resultado será 10.0, no 10
+val b: Double = 10
+
+// Valores Booleanos
+true
+false
+
+// Operaciones Booleanas
+!true // false
+!false // true
+true == false // false
+10 > 5 // true
+
+// Las operaciones matemáticas se realizan como siempre
+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
+
+
+// Evaluar una expresión en REPL te da el tipo y valor del resultado
+
+1 + 7
+
+/* La linea superior tienen como resultado:
+
+ scala> 1 + 7
+ res29: Int = 8
+
+ Esto quiere decir que el resultado de evaluar 1 + 7 es un objeto de tipo Int con valor 8
+
+ Observa que "res29" es un nombre de variable secuencialmente generado para almacenar los resultados de las expresiones escritas, la salida que observes puede diferir en este sentido.
+*/
+
+"Las cadenas en Scala están rodeadas por comillas dobles"
+'a' // Un caracter en Scala
+// 'Las cadenas con comillas simples no existen' <= Esto causa un error
+
+// Las cadenas tienen los los típicos metodos de Java definidos
+"hello world".length
+"hello world".substring(2, 6)
+"hello world".replace("C", "3")
+
+// También tienen algunos métodos extra de Scala. Ver: scala.collection.immutable.StringOps
+"hello world".take(5)
+"hello world".drop(5)
+
+// Interpolación de cadenas: Observa el prefijo "s"
+val n = 45
+s"Tengo $n manzanas" // => "Tengo 45 manzanas"
+
+// Es posible colocar expresiones dentro de cadenas interpoladas
+val a = Array(11, 9, 6)
+s"Mi segunda hija tiene ${a(0) - a(2)} años." // => "Mi segunda hija tiene 5 años."
+s"Hemos doblado la cantidad de ${n / 2.0} manzanas." // => "Hemos doblado la cantidad de 22.5 manzanas."
+s"Potencia de 2: ${math.pow(2, 2)}" // => "Potencia de 2: 4"
+
+// Podemos formatear cadenas interpoladas con el prefijo "f"
+f"Potencia de 5: ${math.pow(5, 2)}%1.0f" // "Potencia de 5: 25"
+f"Raiz cuadrada de 122: ${math.sqrt(122)}%1.4f" // "Raiz cuadrada de 122: 11.0454"
+
+// Las cadenas puras ignoran caracteres especiales.
+raw"Nueva linea: \n. Retorno: \r." // => "Nueva linea: \n. Retorno: \r."
+
+// Algunos caracteres necesitn ser escapados, por ejemplo unas comillas dobles dentro de una cadena:
+"Se quedaron fuera de \"Rose and Crown\"" // => "Se quedaron fuera de "Rose and Crown""
+
+// Las triples comillas dobles dejan que las cadenas se expandan por multiples filas y contengan comillas dobles o simples
+val html = """<form id="daform">
+ <p>Press belo', Joe</p>
+ <input type="submit">
+ </form>"""
+
+
+/////////////////////////////////////////////////
+// 2. Funciones
+/////////////////////////////////////////////////
+
+// Las funciones se definen de la siguiente manera:
+//
+// def nombreFuncion(argumentos...): TipoRetorno = { cuerpo... }
+//
+// Si estás acostumbrado a lenguajes más tradicionales, observa la omisión de la palabra return.
+// En Scala, la última expresión en el bloque de función es el valor de retorno.
+def sumaDeCuadrados(x: Int, y: Int): Int = {
+ val x2 = x * x
+ val y2 = y * y
+ x2 + y2
+}
+
+// Los { } pueden omitirse si el cuerpo de la función es una única expresión:
+def sumaDeCuadradosCorta(x: Int, y: Int): Int = x * x + y * y
+
+// La sintaxis para llamar funciones es familiar:
+sumaDeCuadrados(3, 4) // => 25
+
+// Puedes usar los nombres de los parámetros para llamarlos en orden diferente
+def restar(x: Int, y: Int): Int = x - y
+
+restar(10, 3) // => 7
+restar(y=10, x=3) // => -7
+
+// En la mayoría de los casos (siendo las funciones recursivas la excepción más notable),
+// el tipo de retorno de la función puede ser omitido, y la misma inferencia de tipos que vimos con las variables
+// funcionará con los valores de retorno de las funciones:
+def sq(x: Int) = x * x // El compilador puede adivinar que el tipo de retorno es Int
+
+// Las funciones pueden tener parametros por defecto:
+def sumarConDefecto(x: Int, y: Int = 5) = x + y
+sumarConDefecto(1, 2) // => 3
+sumarConDefecto(1) // => 6
+
+
+// Las funciones anónimas se escriben así:
+(x: Int) => x * x
+
+// Al contrario que los defs, incluso el tipo de entrada de las funciones anónimas puede ser omitido si
+// el contexto lo deja claro. Observa el tipo "Int => Int" que significa que es una función
+// que recibe Int y retorna Int.
+val sq: Int => Int = x => x * x
+
+// Las funciones anónimas pueden ser llamadas como las demás:
+sq(10) // => 100
+
+// Si cada argumento en tu función anónima es usado solo una vez,
+// Scala te da una manera incluso más corta de definirlos.
+// Estas funciones anónimas son extremadamente comunes,
+// como será obvio en la sección de estructuras de datos.
+val sumarUno: Int => Int = _ + 1
+val sumaRara: (Int, Int) => Int = (_ * 2 + _ * 3)
+
+sumarUno(5) // => 6
+sumaRara(2, 4) // => 16
+
+
+// La palabra return existe en Scala, pero solo retorna desde la función más interna que la rodea.
+// ADVERTENCIA: Usar return en Scala puede inducir a errores y debe ser evitado
+// No tiene efecto en funciones anónimas. Por ejemplo:
+def foo(x: Int): Int = {
+ val funcAnon: Int => Int = { z =>
+ if (z > 5)
+ return z // Esta línea hace que z sea el valor de retorno de foo!
+ else
+ z + 2 // Esta línea es el valor de retorno de funcAnon
+ }
+ anonFunc(x) // Esta línea es el valor de retorno de foo
+}
+
+
+/////////////////////////////////////////////////
+// 3. Control del flujo
+/////////////////////////////////////////////////
+
+1 to 5
+val r = 1 to 5
+r.foreach(println)
+
+r foreach println
+// Nota: Scala es un lenguaje muy permisivo cuando se trata de puntos y parentesis - estudia las
+// reglas separadamente. Esto ayuda a escribir DSLs y APIs que se lean en lenguaje natural.
+
+// Por qué `println` no necesita parámetros aquí?
+// Presta atención a las funciones de primera clase en la sección de Programación Funcional más abajo!
+(5 to 1 by -1) foreach (println)
+
+// Un bucle while
+var i = 0
+while (i < 10) { println("i " + i); i += 1 }
+
+while (i < 10) { println("i " + i); i += 1 } // Si, de nuevo. Qué ocurrió? Por qué?
+
+i // Muestra el valor de i. Observa que while es un loop en el sentido clásico -
+ // se ejecuta secuencialmente mientras cambia la variable del bucle. while es muy
+ // rápido, pero los combinadores y comprensiones anteriores son más sencillos
+ // de entender y paralelizar
+
+// Un bucle do-while
+i = 0
+do {
+ println("i es aún menor que 10")
+ i += 1
+} while (i < 10)
+
+// La recursion es la manera idiomática de repetir una acción en Scala (como en la mayoría de
+// lenguajes funcionales).
+// Las funciones recursivas necesitan un tipo de retorno explicito, el compilador no puede inferirlo.
+// En Scala tenemos Unit, que es análogo al tipo de retorno `void` en Java
+def enseñaNumerosEnUnRango(a: Int, b: Int): Unit = {
+ print(a)
+ if (a < b)
+ enseñaNumerosEnUnRango(a + 1, b)
+}
+enseñaNumerosEnUnRango(1, 14)
+
+
+// Condicionales
+
+val 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. Estructuras de datos
+/////////////////////////////////////////////////
+
+val a = Array(1, 2, 3, 5, 8, 13)
+a(0) // Int = 1
+a(3) // Int = 5
+a(21) // Lanza una excepción
+
+val m = Map("fork" -> "tenedor", "spoon" -> "cuchara", "knife" -> "cuchillo")
+m("fork") // java.lang.String = tenedor
+m("spoon") // java.lang.String = cuchara
+m("bottle") // Lanza una excepción
+
+val mapaSeguro = m.withDefaultValue("no lo se")
+mapaSeguro("bottle") // java.lang.String = no lo se
+
+val s = Set(1, 3, 7)
+s(0) // Boolean = false
+s(1) // Boolean = true
+
+/* Hecha un vistazo a la documentación de Map aquí -
+ * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
+ * y asegúrate de que puedes leerla
+ */
+
+
+// Tuplas
+
+(1, 2)
+
+(4, 3, 2)
+
+(1, 2, "three")
+
+(a, 2, "three")
+
+// Por qué tener esto?
+val dividirEnteros = (x: Int, y: Int) => (x / y, x % y)
+
+// La función dividirEnteros te da el resultado y el resto
+dividirEnteros(10, 3) // (Int, Int) = (3,1)
+
+// Para acceder a los elementos de una tupla, usa _._n donde n es el indice (comenzando por 1)
+// del elemento
+val d = dividirEnteros(10, 3) // (Int, Int) = (3,1)
+
+d._1 // Int = 3
+d._2 // Int = 1
+
+// Alternativamente puedes asignar multiples variables desde una tupla, lo que
+// resulta más conveniente y legible en muchos casos.
+val (div, mod) = dividirEnteros(10, 3)
+
+div // Int = 3
+mod // Int = 1
+
+
+/////////////////////////////////////////////////
+// 5. Programación Orientada a Objetos
+/////////////////////////////////////////////////
+
+/*
+ Nota: Todo lo que hemos hecho hasta ahora en este tutorial han sido
+ simples expresiones (valores, funciones, etc). Estas expresiones son validas
+ para hacer pruebas rapidas en el interprete de la linea de comandos,
+ pero no pueden existir por si solas en un archivo de Scala. Por ejemplo,
+ no puedes tener simplemente "val x = 5" en un archivo Scala. En lugar de eso,
+ las únicas construcciones de alto nivel en Scala son:
+
+ - Objetos
+ - Clases
+ - Case clases
+ - Traits
+
+ Y ahora explicaremos lo que son estas.
+*/
+
+// Las clases son similares a las clases de otros lenguajes. Los argumentos del constructor
+// son declarados despues del nombre de la clase, y la inicialización se hace en el cuerpo de la clase.
+class Perro(r: String) {
+ // Código del constructor aquí
+ var raza: String = r
+
+ // Define un método llamado ladrar, que devuelva un String
+ def ladrar = "Woof, woof!"
+
+ // Los valores y métodos son asumidos como públicos.
+ // Las palabras "protected" y "private" también son válidas.
+ private def dormir(horas: Int) =
+ println(s"Estoy durmiendo $horas horas")
+
+ // Los métodos abstractos son simplemente métodos sin cuerpo.
+ // Si descomentamos la linea de debajo, la clase Perro necesitaría ser abstracta:
+ // abstract class Perro(...) { ... }
+ // def perseguir(algo: String): String
+}
+
+val miperro = new Dog("greyhound")
+println(mydog.raza) // => "greyhound"
+println(mydog.ladrar) // => "Woof, woof!"
+
+
+// La palabra "object" crea un tipo y una instancia singleton de ese tipo.
+// Es común que las clases en Scala tengan un "companion object", de manera que
+// el comportamiento por instancia es controlado por las clases y el comportamiento
+// relacionado a todas las instancias de esa clase es controlado por el objeto
+// La relación es similar a los métodos de las clases con los métodos estáticos
+// en otros lenguajes. Observa que los objetos y clases pueden tener el mismo nombre.
+object Perro {
+ def todasLasRazasConocidas = List("pitbull", "shepherd", "retriever")
+ def crearPerro(raza: String) = new Dog(breed)
+}
+
+
+// Case clases son clases que tienen funcionalidad extra añadida. Una pregunta
+// común para los principiantes en Scala es cuando usar case clases y cuando usar
+// clases. La linea no está bien definida, pero en general, las clases tienden a
+// enfocarse en la encapsulación, polimorfismo y comportamiento. Los valores en
+// estas clases tienden a ser privados, y solo se exponen los métodos.
+// El propósito principal de las case clases es tener datos inmutables.
+// A menudo tienen pocos métodos, y los métodos raramente tienen efectos secundarios.
+case class Persona(nombre: String, telefono: String)
+
+// Para crear instancia nuevas, observa que las case clases no necesitan "new"
+val george = Persona("George", "1234")
+val kate = Persona("Kate", "4567")
+
+// Con las case clases tienes unas pocas ventajas, como el acceso a los campos:
+george.telefono // => "1234"
+
+// Para la igualdad de campos no necesitas sobreescribir el método equals
+Persona("George", "1234") == Persona("Kate", "1236") // => false
+
+// Manera fácil de copiar
+// otroGeorge == Persona("George", "9876")
+val otroGeorge = george.copy(telefono = "9876")
+
+// Y muchas otras. Las case clases también tienen comparación de patrones, que veremos más abajo.
+
+// Traits
+// De manera similar a las interfaces Java, los traits definen un tipo de objeto y métodos.
+// Scala permite la implementación parcial de dichos métodos.
+// No se permiten parámetros de constructor. Los traits pueden heredar de otros traits o
+// clases sin parámetros.
+
+trait Perro {
+ def raza: String
+ def color: String
+ def ladra: Boolean = true
+ def muerde: Boolean
+}
+class SanBernardo extends Perro {
+ val raza = "San Bernardo"
+ val color = "marrón"
+ def muerde = false
+}
+
+scala> b
+res0: SanBernardo = SanBernardo@3e57cd70
+scala> b.raza
+res1: String = San Bernardo
+scala> b.ladra
+res2: Boolean = true
+scala> b.muerde
+res3: Boolean = false
+
+// Un trait tambien puede ser usado mezclado con otros traits.
+// La clase extiende el primer trait, pero la palabra "with"
+// puede añadir traits adicionales.
+
+trait Ladra {
+ def ladra: String = "Guau"
+}
+trait Perro {
+ def raza: String
+ def color: String
+}
+class SanBernardo extends Perro with Ladra {
+ val raza = "San Bernardo"
+ val color = "marrón"
+}
+
+scala> val b = new SanBernardo
+b: SanBernardo = SanBernardo@7b69c6ba
+scala> b.ladra
+res0: String = Guau
+
+
+/////////////////////////////////////////////////
+// 6. Comparación de patrones
+/////////////////////////////////////////////////
+
+// La comparación de patrones es una poderosa función de Scala.
+// Ahora veremos como comparar patrones en una case clase.
+// Nota: A diferencia de otros lenguajes, Scala "cases" no necesitan
+// "break", porque no ejecuta los "case" posteriores.
+
+def comparaPersona(persona: Persona): String = persona match {
+ // Aqui especificas los patrones:
+ case Persona("George", telefono) => "Hemos encontrado a George! Su número es " + telefono
+ case Persona("Kate", telefono) => "Hemos encontrado a Kate! Su número es " + telefono
+ case Persona(nombre, telefono) => "Hemos encontrado alguien : " + nombre + ", teléfono : " + telefono
+}
+
+// Las expresiones regulares también están incorporadas.
+// Creas una expresión regular con el método `r` en una cadena:
+val email = "(.*)@(.*)".r
+
+// La comparación de patrones puede parecerse al bloque switch en la familia de lenguajes de C,
+// pero aquí es mucho más poderosa. En Scala, puedes hacer más comparaciones:
+def comparaTodo(obj: Any): String = obj match {
+ // Puedes comparar valores:
+ case "Hola mundo" => "Tengo la cadena Hola mundo"
+
+ // Puedes comparar tipos:
+ case x: Double => "Tengo un double: " + x
+
+ // Puedes especificar condiciones:
+ case x: Int if x > 10000 => "Tengo un número muy grande!"
+
+ // Puedes comparar case clases como antes:
+ case Persona(nombre, telefono) => s"Tengo la información de contacto de $nombre!"
+
+ // Puedes comparar expresiones regulares:
+ case email(nombre, dominio) => s"Tengo la dirección de correo $nombre@$dominio"
+
+ // Puedes comparar tuplas:
+ case (a: Int, b: Double, c: String) => s"Tengo la tupla: $a, $b, $c"
+
+ // Puedes comparar estructuras:
+ case List(1, b, c) => s"Tengo un alista con tres elementos que empieza con 1: 1, $b, $c"
+
+ // Puedes anidar patrones:
+ case List(List((1, 2, "YAY"))) => "Tengo una lista de listas de tuplas"
+
+ // Comparar cualquier case (default) si todos los anteriores no han coincido
+ case _ => "Tengo un objeto desconocido"
+}
+
+// De hecho puedes comparar un patrón con cualquier objeto con el método "unapply".
+// Esta función es tan poderosa que Scala te deja definir funciones enteras como patrones:
+val funcPatron: Person => String = {
+ case Persona("George", telefono) => s"Teléfono de George: $telefono"
+ case Persona(nombre, telefono) => s"Teléfono de una persona aleatoria: $telefono"
+}
+
+
+/////////////////////////////////////////////////
+// 7. Programación funcional
+/////////////////////////////////////////////////
+
+// Scala permite a los métodos y funciones devolver o
+// recibir como parámetros otras funciones o métodos
+
+val suma10: Int => Int = _ + 10 // Una función que recibe y devuelve un Int
+List(1, 2, 3) map suma10 // List(11, 12, 13) - suma10 es aplicado a cada elemento
+
+// Las funciones anónimas pueden ser usadas en vez de funciones con nombre:
+List(1, 2, 3) map (x => x + 10)
+
+// Y la barra baja puede ser usada si solo hay un argumento en la función anónima.
+// Se usa como la variable.
+List(1, 2, 3) map (_ + 10)
+
+// Si el bloque anónimo Y la función que estás usando usan los dos un argumento,
+// puedes incluso omitir la barra baja.
+List("Dom", "Bob", "Natalia") foreach println
+
+
+// Combinadores
+// Usando s de arriba:
+// val s = Set(1, 3, 7)
+
+s.map(sq)
+
+val sCuadrado = s. map(sq)
+
+sSquared.filter(_ < 10)
+
+sSquared.reduce (_+_)
+
+// La función filter toma un predicado (una función A -> Boolean) y
+// selecciona todos los elementos que satisfacen el predicado.
+List(1, 2, 3) filter (_ > 2) // List(3)
+case class Persona(nombre: String, edad: Int)
+List(
+ Persona(nombre = "Dom", edad = 23),
+ Persona(nombre = "Bob", edad = 30)
+).filter(_.edad > 25) // List(Persona("Bob", 30))
+
+
+// Ciertas colecciones (como List) en Scala tienen un método `foreach`,
+// que toma como argumento un tipo que devuelva Unit (un método void)
+val unaListaDeNumeros = List(1, 2, 3, 4, 10, 20, 100)
+unaListaDeNumeros foreach (x => println(x))
+unaListaDeNumeros foreach println
+
+// Para comprensiones
+
+for { n <- s } yield sq(n)
+
+val nCuadrado2 = for { n <- s } yield sq(n)
+
+for { n <- nSquared2 if n < 10 } yield n
+
+for { n <- s; nSquared = n * n if nSquared < 10} yield nSquared
+
+/* Nota: Esos no son bucles. La semántica de un bucle es repetir, mientras que un for de comprension define una relación entre dos conjuntos de datos.*/
+
+
+/////////////////////////////////////////////////
+// 8. Implicitos
+/////////////////////////////////////////////////
+
+/* ATENCIÓN ATENCIÓN: Los implicitos son un conjunto de poderosas características de Scala
+ * y es fácil abusar de ellos. Si eres principiante en Scala deberías resistir la tentación
+ * de usarlos hasta que entiendas no solo como funcionan, sino también las mejores prácticas
+ * con ellos. Nosotros solo incluiremos esta sección en el tutorial porque son tan comunes
+ * en las librerias de Scala que es imposible hacer algo significativo sin usar una librería
+ * que tenga implicitos. Esto es para que entiendas como funcionan los implicitos, no para
+ * que definas los tuyos propios.
+ */
+
+// Cualquier valor (val, funciones, objetos, etc) puede ser declarado como implicito usando
+// la palabra "implicit". Observa que usamos la clase Perro de la sección 5.
+implicit val miEnteroImplicito = 100
+implicit def miFunciónImplicita(raza: String) = new Perro("Golden " + raza)
+
+// Por si misma, la palabra implicit no cambia el comportamiento de un valor,
+// así que estos valores pueden ser usados como siempre.
+miEnteroImplicito + 2 // => 102
+miFunciónImplicita("Pitbull").raza // => "Golden Pitbull"
+
+// La diferencia es que estos valores ahora pueden ser usados cuando otra pieza de código
+// necesite un valor implicito. Una situación así puede darse con argumentos implicitos de función:
+def enviaSaludos(aQuien: String)(implicit cuantos: Int) =
+ s"Hola $aQuien, $cuantos saludos a ti y a los tuyos!"
+
+// Si proporcionamos un valor para "cuantos", la función se comporta como siempre
+enviaSaludos("John")(1000) // => "Hola John, 1000 saludos a ti y a los tuyos!"
+
+// Pero si omitimos el parámetro implicito, un valor implicito del mismo tipo es usado,
+// en este caso, "miEnteroImplicito":
+enviaSaludos("Jane") // => "Hello Jane, 100 blessings to you and yours!"
+
+// Los parámetros de función implicit nos permiten simular clases tipo en otros lenguajes funcionales.
+// Es usado tan a menudo que tiene su propio atajo. Las dos siguientes lineas significan lo mismo:
+// def foo[T](implicit c: C[T]) = ...
+// def foo[T : C] = ...
+
+
+// Otra situación en la que el compilador busca un implicit es si tienes
+// obj.método(...)
+// pero "obj" no tiene "método" como un método. En este caso, si hay una conversión
+// implicita de tipo A => B, donde A es el tipo de obj y B tiene un método llamado
+// "método", esa conversión es aplicada. Así que teniendo miFunciónImplicita, podemos decir:
+"Retriever".raza // => "Golden Retriever"
+"Sheperd".ladra // => "Woof, woof!"
+
+// Aquí la cadena es convertida primero a Perro usando nuestra función miFunciónImplicita,
+// y entonces el método apropiado es llamado. Esta es una herramienta extremadamente poderosa
+// pero de nuevo, no puede usarse con ligereza. De hecho, cuando definiste la función implicita,
+// tu compilador debería haber mostrado una advertencia, diciendo que no deberías hacer esto
+// a no ser que realmente sepas lo que estás haciendo.
+
+/////////////////////////////////////////////////
+// 9. Misc
+/////////////////////////////////////////////////
+
+// Importando cosas
+import scala.collection.immutable.List
+
+// Importando todos los "sub paquetes"
+import scala.collection.immutable._
+
+// Importando multiples clases en una línea
+import scala.collection.immutable.{List, Map}
+
+// Renombrar un import usando '=>'
+import scala.collection.immutable.{List => ImmutableList}
+
+// Importar todas las clases, excepto algunas. La siguiente linea excluye Map y Set:
+import scala.collection.immutable.{Map => _, Set => _, _}
+
+// Las clases de Java pueden ser importadas también con sintaxis de Scala:
+import java.swing.{JFrame, JWindow}
+
+// El punto de entrada de tus programas está definido en un fichero scala usando un object,
+// con un solo método, main:
+object Application {
+ def main(args: Array[String]): Unit = {
+ // Aquí va tu código.
+ }
+}
+
+// Los ficheros pueden contener multiples clases y objetos. Compila con scalac
+
+
+// Salida y entrada
+
+// Leer un fichero línea por línea
+import scala.io.Source
+for(line <- Source.fromFile("miarchivo.txt").getLines())
+ println(line)
+
+// Para escribir un archivo usa el PrintWriter de Java
+val writer = new PrintWriter("miarchivo.txt")
+writer.write("Escribiendo linea por linea" + util.Properties.lineSeparator)
+writer.write("Otra linea" + util.Properties.lineSeparator)
+writer.close()
+
+```
+
+## Más recursos
+
+* [Scala para los impacientes](http://horstmann.com/scala/)
+* [Escuela de Scala en Twitter](http://twitter.github.io/scala_school/)
+* [La documentación de Scala](http://docs.scala-lang.org/)
+* [Prueba Scala en tu navegador](http://scalatutorials.com/tour/)
+* Unete al [grupo de usuarios de Scala](https://groups.google.com/forum/#!forum/scala-user)
diff --git a/es-es/sql-es.html.markdown b/es-es/sql-es.html.markdown
new file mode 100644
index 00000000..1ee0d454
--- /dev/null
+++ b/es-es/sql-es.html.markdown
@@ -0,0 +1,115 @@
+---
+language: SQL
+filename: learnsql-es.sql
+contributors:
+ - ["Bob DuCharme", "http://bobdc.com/"]
+translators:
+ - ["FedeHC", "https://github.com/FedeHC"]
+lang: es-es
+---
+
+El lenguaje de consulta estructurada (SQL en inglés) es un lenguaje estándar ISO para crear y trabajar con bases de datos almacenados en un conjunto de tablas. Las implementaciones generalmente añaden sus propias extensiones al lenguaje; [Comparación entre diferentes implementaciones de SQL](http://troels.arvin.dk/db/rdbms/) es una buena referencia sobre las diferencias entre distintos productos.
+
+Las implementaciones típicamente proveen de una línea de comandos donde uno puede introducir los comandos que se muestran aquí en forma interactiva, y también ofrecen una forma de ejecutar una serie de estos comandos almacenados en un archivo de script (mostrar que uno ha terminado con el prompt interactivo es un buen ejemplo de algo que no está estandarizado - la mayoría de las implementaciones de SQL soportan las palabras clave QUIT, EXIT, o ambas).
+
+Varios de estos comandos que sirven de ejemplo asumen que la [base de datos de empleados de muestra de MySQL](https://dev.mysql.com/doc/employee/en/) disponible en [github](https://github.com/datacharmer/test_db) ya ha sido cargada. Los archivos github son scripts de comandos, similares a los comandos que aparecen a continuación, que crean y cargan tablas de datos sobre los empleados de una empresa ficticia. La sintaxis para ejecutar estos scripts dependerá de la implementación de SQL que esté utilizando. Una aplicación que se ejecuta desde el prompt del sistema operativo suele ser lo habitual.
+
+
+```sql
+-- Los comentarios empiezan con dos guiones. Se termina cada comando con punto
+-- y coma.
+
+-- SQL no distingue entre mayúsculas y minúsculas en palabras clave. Los
+-- comandos de ejemplo que aquí se muestran siguen la convención de ser escritos
+-- en mayúsculas porque hace más fácil distinguirlos de los nombres de las bases
+-- de datos, de las tablas y de las columnas.
+
+-- A cont. se crea y se elimina una base de datos. Los nombres de la base de
+-- datos y de la tabla son sensibles a mayúsculas y minúsculas.
+CREATE DATABASE someDatabase;
+DROP DATABASE someDatabase;
+
+-- Lista todas las bases de datos disponibles.
+SHOW DATABASES;
+
+-- Usa una base de datos existente en particular.
+USE employees;
+
+-- Selecciona todas las filas y las columnas de la tabla departments en la base
+-- de datos actual. La actividad predeterminada es que el intérprete desplace
+-- los resultados por la pantalla.
+SELECT * FROM departments;
+
+-- Recupera todas las filas de la tabla departments, pero sólo las columnas
+-- dept_no y dept_name.
+-- Separar los comandos en varias líneas está permitido.
+SELECT dept_no,
+ dept_name FROM departments;
+
+-- Obtiene todas las columnas de departments, pero se limita a 5 filas.
+SELECT * FROM departments LIMIT 5;
+
+-- Obtiene los valores de la columna dept_name desde la tabla departments cuando
+-- dept_name tiene como valor la subcadena 'en'.
+SELECT dept_name FROM departments WHERE dept_name LIKE '%en%';
+
+-- Recuperar todas las columnas de la tabla departments donde la columna
+-- dept_name comienza con una 'S' y tiene exactamente 4 caracteres después
+-- de ella.
+SELECT * FROM departments WHERE dept_name LIKE 'S____';
+
+-- Selecciona los valores de los títulos de la tabla titles, pero no muestra
+-- duplicados.
+SELECT DISTINCT title FROM titles;
+
+-- Igual que el anterior, pero ordenado por los valores de title (se distingue
+-- entre mayúsculas y minúsculas).
+SELECT DISTINCT title FROM titles ORDER BY title;
+
+-- Muestra el número de filas de la tabla departments.
+SELECT COUNT(*) FROM departments;
+
+-- Muestra el número de filas en la tabla departments que contiene 'en' como
+-- subcadena en la columna dept_name.
+SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%';
+
+-- Una unión (JOIN) de información desde varias tablas: la tabla titles muestra
+-- quién tiene qué títulos de trabajo, según sus números de empleados, y desde
+-- qué fecha hasta qué fecha. Se obtiene esta información, pero en lugar del
+-- número de empleado se utiliza el mismo como una referencia cruzada a la
+-- tabla employee para obtener el nombre y apellido de cada empleado (y se
+-- limita los resultados a 10 filas).
+SELECT employees.first_name, employees.last_name,
+ titles.title, titles.from_date, titles.to_date
+FROM titles INNER JOIN employees ON
+ employees.emp_no = titles.emp_no LIMIT 10;
+
+-- Se enumera todas las tablas de todas las bases de datos. Las implementaciones
+-- típicamente proveen sus propios comandos para hacer esto con la base de datos
+-- actualmente en uso.
+SELECT * FROM INFORMATION_SCHEMA.TABLES
+WHERE TABLE_TYPE='BASE TABLE';
+
+-- Crear una tabla llamada tablename1, con las dos columnas mostradas, a partir
+-- de la base de datos en uso. Hay muchas otras opciones disponibles para la
+-- forma en que se especifican las columnas, como por ej. sus tipos de datos.
+CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20));
+
+-- Insertar una fila de datos en la tabla tablename1. Se asume que la tabla ha
+-- sido definida para aceptar estos valores como aptos.
+INSERT INTO tablename1 VALUES('Richard','Mutt');
+
+-- En tablename1, se cambia el valor de fname a 'John' para todas las filas que
+-- tengan un valor en lname igual a 'Mutt'.
+UPDATE tablename1 SET fname='John' WHERE lname='Mutt';
+
+-- Se borra las filas de la tabla tablename1 donde el valor de lname comience
+-- con 'M'.
+DELETE FROM tablename1 WHERE lname like 'M%';
+
+-- Se borra todas las filas de la tabla tablename1, dejando la tabla vacía.
+DELETE FROM tablename1;
+
+-- Se elimina toda la tabla tablename1 por completo.
+DROP TABLE tablename1;
+```
diff --git a/es-es/swift-es.html.markdown b/es-es/swift-es.html.markdown
index 8f63517a..22e3c532 100644
--- a/es-es/swift-es.html.markdown
+++ b/es-es/swift-es.html.markdown
@@ -446,48 +446,48 @@ if let circle = myEmptyCircle {
// Al igual que las clases, pueden contener métodos
enum Suit {
- case Spades, Hearts, Diamonds, Clubs
+ case spades, hearts, diamonds, clubs
func getIcon() -> String {
switch self {
- case .Spades: return "♤"
- case .Hearts: return "♡"
- case .Diamonds: return "♢"
- case .Clubs: return "♧"
+ case .spades: return "♤"
+ case .hearts: return "♡"
+ case .diamonds: return "♢"
+ case .clubs: return "♧"
}
}
}
// Los valores de enum permite la sintaxis corta, sin necesidad de poner
// el tipo del enum cuando la variable es declarada de manera explícita
-var suitValue: Suit = .Hearts
+var suitValue: Suit = .hearts
// Enums de tipo no-entero requiere asignaciones de valores crudas directas
enum BookName: String {
- case John = "John"
- case Luke = "Luke"
+ case john = "John"
+ case luke = "Luke"
}
-print("Name: \(BookName.John.rawValue)")
+print("Name: \(BookName.john.rawValue)")
// Enum con valores asociados
enum Furniture {
// Asociación con Int
- case Desk(height: Int)
+ case desk(height: Int)
// Asociación con String e Int
- case Chair(String, Int)
+ case chair(String, Int)
func description() -> String {
switch self {
- case .Desk(let height):
+ case .desk(let height):
return "Desk with \(height) cm"
- case .Chair(let brand, let height):
+ case .chair(let brand, let height):
return "Chair of \(brand) with \(height) cm"
}
}
}
-var desk: Furniture = .Desk(height: 80)
+var desk: Furniture = .desk(height: 80)
print(desk.description()) // "Desk with 80 cm"
-var chair = Furniture.Chair("Foo", 40)
+var chair = Furniture.chair("Foo", 40)
print(chair.description()) // "Chair of Foo with 40 cm"
diff --git a/es-es/tcl-es.html.markdown b/es-es/tcl-es.html.markdown
new file mode 100644
index 00000000..5db72ae1
--- /dev/null
+++ b/es-es/tcl-es.html.markdown
@@ -0,0 +1,600 @@
+---
+language: Tcl
+contributors:
+ - ["Poor Yorick", "https://pooryorick.com/"]
+translators:
+ - ["Héctor Romojaro", "https://github.com/hromojaro"]
+lang: es-es
+filename: learntcl-es.tcl
+---
+
+Tcl fue creado por [John Ousterhout](https://wiki.tcl.tk/John%20Ousterout) como
+un lenguaje reutilizable de scripting para herramientas de diseño de circuitos
+de las que él era autor. En 1997 recibió el
+[ACM Software System Award](https://en.wikipedia.org/wiki/ACM_Software_System_Award)
+por Tcl. Tcl puede ser utilizado tanto como lenguaje de scripting embebido,
+como lenguaje de programación general. Puede ser utilizado también como una
+biblioteca portable de C, incluso en casos donde no se requieren capacidades
+de scripting, ya que provee de estructuras de datos tales como cadenas (*string*)
+de caracteres dinámicas, listas y tablas hash. La biblioteca de C también
+provee funcionalidad portable para cargar bibliotecas dinámicas, formato de
+cadenas y conversión de código, operaciones sobre el sistema de ficheros,
+operaciones de red y más. Algunas características reseñables de Tcl:
+
+* Conveniente API de red multiplataforma
+
+* Sistema de ficheros totalmente virtualizado
+
+* Canales apilables de E/S
+
+* Asíncrono hasta el núcleo
+
+* Corrutinas completas
+
+* Un modelo de hebras reconocido como robusto y fácil de usar
+
+
+Tcl tiene mucho en común con Lisp pero, en lugar de listas, Tcl utiliza cadenas
+de caracteres como moneda de cambio del lenguaje. Todos los valores son cadenas.
+Una lista es una cadena con un formato definido, y el cuerpo de un procedimiento
+(un script) es también una cadena en lugar de un bloque. Para incrementar el
+rendimiento, Tcl cachea internamente representaciones estructuradas de estos
+valores. Las rutinas con listas, por ejemplo, operan en la representación interna
+en caché, y Tcl se ocupa de actualizar la representación en cadenas si es realmente
+necesario en el script. El diseño *copy-on-write* de Tcl permite a los autores
+de scripts mover grandes volúmenes de datos sin incurrir en el consumo adicional
+de memoria. Los procedimientos son automáticamente compilados (*byte-compiled*)
+a no ser que utilicen rutinas dinámicas como "uplevel", "upvar" o "trace".
+
+Programar en Tcl es un placer. Le resultará atractivo a hackers que encuentren
+atractivo Lisp, Forth o Smalltalk, y a ingenieros y científicos que simplemente
+quieren ponerse a trabajar con una herramienta que se doblega a su voluntad. La
+disciplina de exponer toda la funcionalidad programática como rutinas, incluyendo
+cosas como iteraciones y operaciones matemáticas que normalmente están en la
+sintaxis de otros lenguajes, permitiendo fundirse en el fondo de cualquier
+funcionalidad específica del dominio que necesita un proyecto. Su sintaxis,
+incluso más simple que la de lisp, simplemente se quita de en medio.
+
+
+
+```tcl
+#! /bin/env tclsh
+
+###############################################################################
+## 1. Directrices
+###############################################################################
+
+# ¡Tcl no es ni Sh ni C! Es necesario decirlo porque el entrecomillado estándar
+# de shell casi funciona en Tcl, y es común que la gente empiece con Tcl e
+# intente utilizar sintaxis de otros lenguajes. Funciona al principio, pero
+# rápidamente conduce a frustración cuando los scripts se vuelven más complejos.
+
+# Las llaves son un mecanismo de entrecomillado, no de sintaxis para la construcción
+# de bloques de código o listas. Tcl no tiene ninguna de ellas. Las llaves se
+# usan para escapar caracteres especiales, lo que las hace apropiadas para
+# entrecomillar cuerpos de procedimientos y cadenas que deberían ser interpretadas
+# como listas.
+
+
+###############################################################################
+## 2. Sintaxis
+###############################################################################
+
+# Un script consiste en comandos delimitados por saltos de línea o puntos y coma.
+# Cada comando es una llamada a una rutina. La primera palabra es el nombre de
+# la rutina a llamar, y las siguientes palabras son argumentos de la rutina.
+# Las palabras están delimitadas por espacios. Puesto que cada argumento es una
+# palabra en el comando, y una cadena de caracteres, puede no ser entrecomillada:
+set part1 Sal
+set part2 ut; set part3 ations
+
+
+# el símbolo del dólar introduce la sustitución de variables:
+set greeting $part1$part2$part3
+
+
+# Cuando "set"recibe sólamente el nombre de una variable, devuelve su valor:
+set part3 ;# Returns the value of the variable.
+
+
+# Los corchetes delimitan un script que será evaluado y sustituido por su resultado:
+set greeting $part1$part2[set part3]
+
+
+# Un script incrustado puede estar compuesto de múltiples comandos, el último de
+# los cuales devuelve el resultado de la sustitución:
+set greeting $greeting[
+ incr i
+ incr i
+ incr i
+]
+puts $greeting ;# La salida es "Salutations3"
+
+# Cada palabra en un comando es una cadena, incluyendo el nombre de la rutina,
+# así que se pueden utilizar sustituciones allí también. Dada esta asignación
+# de variable,
+
+set action pu
+
+# los siguientes tres comandos son equivalentes:
+puts $greeting
+${action}ts $greeting
+[set action]ts $greeting
+
+
+# La barra invertida suprime el significado especial de los caracteres:
+set amount \$16.42
+
+
+# La barra invertida añade significado especial a ciertos caracteres:
+puts lots\nof\n\n\n\n\n\nnewlines
+
+
+# Una palabra encerrada entre llaves no está sujeta a interpretación especial o
+# sustitución, excepto que una barra invertida antes de una llave no cuenta al
+# buscar la llave de cierre:
+set somevar {
+ This is a literal $ sign, and this \} escaped
+ brace remains uninterpreted
+}
+
+
+# En una palabra delimitada por comillas dobles, los espacios pierden su significado
+# especial:
+set name Neo
+set greeting "Hello, $name"
+
+
+# Un nombre de variable puede ser cualquier cadena:
+set {first name} New
+
+
+# La forma de sustitución de variables utilizando llaves permite nombres de
+# variable más complejos:
+set greeting "Hello, ${first name}"
+
+
+# "set" puede utilizarse siempre en lugar de la sustitución de variables, y permite
+# utilizar cualquier nombre de variable:
+set greeting "Hello, [set {first name}]"
+
+
+# Para desempaquetar una lista en un el comando, se utiliza el operador de expansión,
+# "{*}". Estos dos comandos son equivalentes:
+set name Neo
+set {*}{name Neo}
+
+
+# Un array es una variable especial que sirve como contenedor de otras variables.
+set person(name) Neo
+set person(destiny) {The One}
+set greeting "Hello, $person(name)"
+
+
+# "variable" se puede utilizar para declarar o asignar variables. Al contrario
+# que "set", que utiliza el espacio de nombres global y el actual para resolver
+# un nombre de variable, "variable" usa solamente el actual:
+variable name New
+
+
+# "namespace eval" crea un nuevo espacio de nombres en caso de no existir.
+# Un espacio de nombres puede contener tanto rutinas como variables:
+namespace eval people {
+ namespace eval person1 {
+ variable name Neo
+ }
+}
+
+
+# Use dos o más ":" para delimitar componentes del espacio de nombres en nombres
+# de variables:
+namespace eval people {
+ set greeting "Hello $person1::name"
+}
+
+# Dos o más ":" también delimitan componentes del espacio de nombres en nombres
+# de rutinas:
+proc people::person1::speak {} {
+ puts {I am The One.}
+}
+
+# Nombres completos comienzan con dos ":":
+set greeting "Hello $::people::person1::name"
+
+
+
+###############################################################################
+## 3. No más sintaxis
+###############################################################################
+
+# El resto de funcionalidades se implementa mediante rutinas. Desde este punto,
+# no hay nueva sintaxis. Todo lo que queda para aprender Tcl es acerca del
+# comportamiento de rutinas individuales y el significado que asignan a sus
+# argumentos.
+
+
+
+###############################################################################
+## 4. Variables y espacios de nombres
+###############################################################################
+
+# Cada variable y cada rutina están asociadas a algún espacio de nombres
+
+# Para terminar con un intérprete inútil, sólo hay que eliminar el espacio de
+# nombres global. No es algo muy útil, pero sirve para ilustrar la naturaleza
+# de Tcl. El nombre del espacio de nombres global es en realidad la cadena
+# vacía, pero la única forma de representarlo es como un nombre completo. Para
+# probarlo, se puede usar esta rutina.
+proc delete_global_namespace {} {
+ namespace delete ::
+}
+
+# Como "set" siempre mantiene su vista en los espacios de nombres global y actual,
+# es más seguro utilizar "variable" para declarar o asignar un valor a una
+# variable. Si una variable llamada "nombre" ya existe en el espacio de nombres
+# global, usar "set" asignará un valor a la variable local en lugar de a la
+# variable del espacio de nombres actual, mientras que "variable" opera en el
+# espacio de nombres actual solamente.
+namespace eval people {
+ namespace eval person1 {
+ variable name Neo
+ }
+}
+
+# Una vez que una variable es declarada en un espacio de nombres, [set] la vé
+# en lugar de una variable de idéntico nombre en el espacio de nombres global:
+namespace eval people {
+ namespace eval person1 {
+ variable name
+ set name Neo
+ }
+}
+
+# En cambio, si "set" tiene que crear una nueva variable, siempre lo hace en el
+# espacio de nombres actual:
+unset name
+namespace eval people {
+ namespace eval person1 {
+ set name neo
+ }
+
+}
+set people::person1::name
+
+
+# Un nombre absoluto siempre comienza con el nombre del espacio de nombres global
+# (cadena vacía), seguido de dos ":":
+set ::people::person1::name Neo
+
+
+# En el interior de un procedimiento, la variable enlaza una variable en el espacio
+# de nombres actual en el ámbito local:
+namespace eval people::person1 {
+ proc fly {} {
+ variable name
+ puts "$name is flying!"
+ }
+}
+
+
+
+
+###############################################################################
+## 4. Rutinas incorporadas
+###############################################################################
+
+# Las operaciones matemáticas se pueden hacer con "expr":
+set a 3
+set b 4
+set c [expr {$a + $b}]
+
+# Como "expr" realiza sustituciones de variables por sí mismo, es necesario
+# poner la expresión entre llaves para prevenir a Tcl sustituir las variables
+# primero. Ver "http://wiki.tcl.tk/Brace%20your%20#%20expr-essions" para más
+# detalles.
+
+
+# "expr" entiende sustitución de variables y scripts:
+set c [expr {$a + [set b]}]
+
+
+# "expr" provee de un conjunto de funciones matemáticas:
+set c [expr {pow($a,$b)}]
+
+
+# Los operadores matemáticos están disponibles como rutinas en el espacio de
+# nombres ::tcl::mathop
+::tcl::mathop::+ 5 3
+
+# Las rutinas pueden ser importadas desde otros espacios de nombres:
+namespace import ::tcl::mathop::+
+set result [+ 5 3]
+
+
+# Los valores no numéricos deben ser entrecomillados, y los operadores como "eq"
+# pueden utilizarse para restringir la operación a una comparación de cadenas:
+set name Neo
+expr {{Bob} eq $name}
+
+# Los operadores generales recurren a la comparación de cadenas si una operación
+# numérica no es factible.
+expr {{Bob} == $name}
+
+
+# "proc" crea nuevas rutinas:
+proc greet name {
+ return "Hello, $name!"
+}
+
+# Se pueden especificar múltiples parámetros:
+proc greet {greeting name} {
+ return "$greeting, $name!"
+}
+
+
+# Como se dijo antes, las llaves no construyen un bloque de código. Cada valor,
+# incluso el tercer argumento de "proc", es una cadena. El comando anterior
+# puede ser reescrito sin usar llaves:
+proc greet greeting\ name return\ \"\$greeting,\ \$name!\"
+
+
+
+# Cuando el último parámetro es el valor literal "args", todos los argumentos
+# extra pasados a la rutina son recogidos en una lista y asignado a "args":
+proc fold {cmd first args} {
+ foreach arg $args {
+ set first [$cmd $first $arg]
+ }
+ return $first
+}
+fold ::tcl::mathop::* 5 3 3 ;# -> 45
+
+
+# La ejecución condicional se implementa como una rutina:
+if {3 > 4} {
+ puts {This will never happen}
+} elseif {4 > 4} {
+ puts {This will also never happen}
+} else {
+ puts {This will always happen}
+}
+
+
+# Los bucles se implementan como rutinas. Los primer y tercer argumentos de "for"
+# son tratados como scripts, mientras que el segundo lo es como una expresión:
+set res 0
+for {set i 0} {$i < 10} {incr i} {
+ set res [expr {$res + $i}]
+}
+unset res
+
+
+# El primer argumento de "while" se trata también como una expresión:
+set i 0
+while {$i < 10} {
+ incr i 2
+}
+
+
+# Una lista es una cadena, y los elementos de la lista se delimitan con espacios
+# en blanco:
+set amounts 10\ 33\ 18
+set amount [lindex $amounts 1]
+
+# El espacio en blanco dentro de una lista debe ser entrecomillado:
+set inventory {"item 1" item\ 2 {item 3}}
+
+
+# Generalmente, es mejor idea usar rutinas de listas al modificarlas:
+lappend inventory {item 1} {item 2} {item 3}
+
+
+# Las llaves y barras invertidas pueden utilizarse para formatear valores más
+# complejos en una lista. Una lista parece un script, excepto en que el carácter
+# de nueva línea y el ":" pierden su significado especial, y no hay sustitución
+# de variable o scripts. Esta característica hace Tcl homoicónico. Hay tres
+# elementos en la siguiente lista:
+set values {
+
+ one\ two
+
+ {three four}
+
+ five\{six
+
+}
+
+
+# Como, al igual que todos los valores, una lista es una cadena, operaciones de
+# cadenas pueden ser realizadas sobre ellas, corriendo el riesgo de corromper
+# el formato de la lista:
+set values {one two three four}
+set values [string map {two \{} $values] ;# $values is no-longer a \
+ properly-formatted list
+
+
+# La forma segura de conseguir una lista debidamente formateada es utilizando
+# las rutinas propias de lista:
+set values [list one \{ three four]
+lappend values { } ;# add a single space as an item in the list
+
+
+# Se puede utilizar "eval" para evaluar un valor como un script:
+eval {
+ set name Neo
+ set greeting "Hello, $name"
+}
+
+
+# Una lista siempre puede ser pasada a "eval" como un script compuesto de un único
+# comando:
+eval {set name Neo}
+eval [list set greeting "Hello, $name"]
+
+
+# Por lo tanto, cuando se utiliza "eval", use "list" para construir el comando
+# deseado:
+set command {set name}
+lappend command {Archibald Sorbisol}
+eval $command
+
+
+# Un error común es no usar funciones de listas al construir un comando:
+set command {set name}
+append command { Archibald Sorbisol}
+try {
+ eval $command ;# El error es que "set" tiene demasiados argumentos en \
+ {set name Archibald Sorbisol}
+} on error {result eoptions} {
+ puts [list {received an error} $result]
+}
+
+# Este error puede ocurrir fácilmente con "subst":
+
+set replacement {Archibald Sorbisol}
+set command {set name $replacement}
+set command [subst $command]
+try {
+ eval $command ;# El mismo error que antes: demasiados argumentos a "set" en \
+ {set name Archibald Sorbisol}
+} trap {TCL WRONGARGS} {result options} {
+ puts [list {received another error} $result]
+}
+
+
+# "list" formatea correctamente un valor para su sustitución:
+set replacement [list {Archibald Sorbisol}]
+set command {set name $replacement}
+set command [subst $command]
+eval $command
+
+
+# "list" se utiliza normalmente para formatear valores para su sustitución en
+# scripts: Hay muchos ejemplos de esto más abajo.
+
+
+# "apply" evalúa una lista de dos elementos como una rutina:
+set cmd {{greeting name} {
+ return "$greeting, $name!"
+}}
+apply $cmd Whaddup Neo
+
+# Un tercer elemento puede ser utilizado para especificar el espacio de nombres
+# donde aplicar la rutina:
+set cmd [list {greeting name} {
+ return "$greeting, $name!"
+} [namespace current]]
+apply $cmd Whaddup Neo
+
+
+# "uplevel" evalúa un script en un nivel superior de la pila de llamadas:
+proc greet {} {
+ uplevel {puts "$greeting, $name"}
+}
+
+proc set_double {varname value} {
+ if {[string is double $value]} {
+ uplevel [list variable $varname $value]
+ } else {
+ error [list {not a double} $value]
+ }
+}
+
+
+# "upvar" enlaza una variable en el nivel actual de la pila de llamadas a una
+# variable en un nivel superior:
+proc set_double {varname value} {
+ if {[string is double $value]} {
+ upvar 1 $varname var
+ set var $value
+ } else {
+ error [list {not a double} $value]
+ }
+}
+
+
+# Deshacerse de la rutina "while" incorporada, y utilizar "proc" para definir
+# una nueva:
+rename ::while {}
+# la manipulación se deja como ejercicio:
+proc while {condition script} {
+ if {[uplevel 1 [list expr $condition]]} {
+ uplevel 1 $script
+ tailcall [namespace which while] $condition $script
+ }
+}
+
+
+# "coroutine" crea una nueva pila de llamadas, una nueva rutina en la que
+# introducir esa pila de llamadas, y luego llama a dicha rutina. "yield" suspende
+# la evaluación en esa pila y devuelve el control a la pila que efectúa la llamada.
+proc countdown count {
+ # devuelve algo al creador de la corrutina, efectivamente pausando esta
+ # pila de llamadas por ahora.
+ yield [info coroutine]
+
+ while {$count > 1} {
+ yield [incr count -1]
+ }
+ return 0
+}
+coroutine countdown1 countdown 3
+coroutine countdown2 countdown 5
+puts [countdown1] ;# -> 2
+puts [countdown2] ;# -> 4
+puts [countdown1] ;# -> 1
+puts [countdown1] ;# -> 0
+catch {
+ puts [coundown1] ;# -> invalid command name "countdown1"
+} cres copts
+puts $cres
+puts [countdown2] ;# -> 3
+
+
+# Pilas de corrutinas pueden cederse el control entre sí:
+
+proc pass {whom args} {
+ return [yieldto $whom {*}$args]
+}
+
+coroutine a apply {{} {
+ yield
+ set result [pass b {please pass the salt}]
+ puts [list got the $result]
+ set result [pass b {please pass the pepper}]
+ puts [list got the $result]
+}}
+
+coroutine b apply {{} {
+ set request [yield]
+ while 1 {
+ set response [pass c $request]
+ puts [list [info coroutine] is now yielding]
+ set request [pass a $response]
+ }
+}}
+
+coroutine c apply {{} {
+ set request [yield]
+ while 1 {
+ if {[string match *salt* $request]} {
+ set request [pass b salt]
+ } else {
+ set request [pass b huh?]
+ }
+ }
+}}
+
+# Pon las cosas en marcha
+a
+
+
+```
+
+## Reference
+
+[Documentación oficial de Tcl](http://www.tcl.tk/man/tcl/)
+
+[Tcl Wiki](http://wiki.tcl.tk)
+
+[Tcl Subreddit](http://www.reddit.com/r/Tcl)
diff --git a/es-es/visualbasic-es.html.markdown b/es-es/visualbasic-es.html.markdown
index c7f581c0..c677c20f 100644
--- a/es-es/visualbasic-es.html.markdown
+++ b/es-es/visualbasic-es.html.markdown
@@ -4,13 +4,11 @@ contributors:
- ["Brian Martin", "http://brianmartin.biz"]
translators:
- ["Adolfo Jayme Barrientos", "https://github.com/fitojb"]
-author: Brian Martin
-author_url: https://github.com/fitojb
filename: learnvisualbasic-es.vb
lang: es-es
---
-```vb
+```
Module Module1
Sub Main()
diff --git a/es-es/xml-es.html.markdown b/es-es/xml-es.html.markdown
index 2e9326cf..23831f3b 100644
--- a/es-es/xml-es.html.markdown
+++ b/es-es/xml-es.html.markdown
@@ -1,6 +1,6 @@
---
language: xml
-filename: learnxml.xml
+filename: learnxml-es.xml
contributors:
- ["João Farias", "https://github.com/JoaoGFarias"]
translators:
diff --git a/es-es/yaml-es.html.markdown b/es-es/yaml-es.html.markdown
index cd3143fb..582fa60e 100644
--- a/es-es/yaml-es.html.markdown
+++ b/es-es/yaml-es.html.markdown
@@ -3,7 +3,7 @@ language: yaml
lang: es-es
filename: learnyaml-es.yaml
contributors:
- - ["Adam Brenecki", "https://github.com/adambrenecki"]
+ - ["Leigh Brenecki", "https://github.com/adambrenecki"]
- ["Everardo Medina","https://github.com/everblut"]
translators:
- ["Daniel Zendejas","https://github.com/DanielZendejas"]
diff --git a/fa-ir/bf-fa.html.markdown b/fa-ir/bf-fa.html.markdown
index bc5d8dc4..81c73980 100644
--- a/fa-ir/bf-fa.html.markdown
+++ b/fa-ir/bf-fa.html.markdown
@@ -1,5 +1,6 @@
---
language: bf
+filename: bf-fa.bf
contributors:
- ["Mohammad Valipour", "https://github.com/mvalipour"]
lang: fa-ir
diff --git a/fa-ir/java-fa.html.markdown b/fa-ir/java-fa.html.markdown
new file mode 100644
index 00000000..cb965fc4
--- /dev/null
+++ b/fa-ir/java-fa.html.markdown
@@ -0,0 +1,902 @@
+---
+language: java
+lang: fa-ir
+contributors:
+ - ["Jake Prather", "https://github.com/JakeHP"]
+ - ["Jakukyo Friel", "https://weakish.github.io"]
+ - ["Madison Dickson", "https://github.com/mix3d"]
+ - ["Simon Morgan", "https://sjm.io/"]
+ - ["Zachary Ferguson", "https://github.com/zfergus2"]
+ - ["Cameron Schermerhorn", "https://github.com/cschermerhorn"]
+ - ["Rachel Stiyer", "https://github.com/rstiyer"]
+ - ["Michael Dähnert", "https://github.com/JaXt0r"]
+ - ["Rob Rose", "https://github.com/RobRoseKnows"]
+ - ["Sean Nam", "https://github.com/seannam"]
+translators:
+ - ["ghaseminya", "https://github.com/ghaseminya"]
+filename: LearnJava-fa.java
+---
+
+جاوا یک زبان برنامه نویسی کامپیوتری چند منظوره، با قابلیت همزمانی، برپایه کلاس و شی گرایی می باشد.
+[مطالعه بیشتر.](https://docs.oracle.com/javase/tutorial/java/)
+
+```java
+// Single-line comments start with //
+
+/*
+Multi-line comments look like this.
+*/
+
+/**
+ * JavaDoc comments look like this. Used to describe the Class or various
+ * attributes of a Class.
+ * Main attributes:
+ *
+ * @author @ghaseminya
+ * @version v1.0
+*/
+
+// Import ArrayList class inside of the java.util package
+import java.util.ArrayList;
+// Import all classes inside of java.security package
+import java.security.*;
+
+// Each .java file contains one outer-level public class, with the same name
+// as the file.
+public class LearnJava {
+
+ // In order to run a java program, it must have a main method as an entry
+ // point.
+ public static void main (String[] args) {
+
+ ///////////////////////////////////////
+ // Input/Output
+ ///////////////////////////////////////
+
+ /*
+ * Output
+ */
+
+ // Use System.out.println() to print lines.
+ System.out.println("Hello World!");
+ System.out.println(
+ "Integer: " + 10 +
+ " Double: " + 3.14 +
+ " Boolean: " + true);
+
+ // To print without a newline, use System.out.print().
+ System.out.print("Hello ");
+ System.out.print("World");
+
+ // Use System.out.printf() for easy formatted printing.
+ System.out.printf("pi = %.5f", Math.PI); // => pi = 3.14159
+
+ /*
+ * Input
+ */
+
+ // use Scanner to read input
+ // must import java.util.Scanner;
+ Scanner scanner = new Scanner(System.in);
+
+ // read string input
+ String name = scanner.next();
+
+ // read byte input
+ byte numByte = scanner.nextByte();
+
+ // read int input
+ int numInt = scanner.nextInt();
+
+ // read long input
+ float numFloat - scanner.nextFloat();
+
+ // read double input
+ double numDouble = scanner.nextDouble();
+
+ // read boolean input
+ boolean bool = scanner.nextBoolean();
+
+ ///////////////////////////////////////
+ // Variables
+ ///////////////////////////////////////
+
+ /*
+ * Variable Declaration
+ */
+ // Declare a variable using <type> <name>
+ int fooInt;
+ // Declare multiple variables of the same
+ // type <type> <name1>, <name2>, <name3>
+ int fooInt1, fooInt2, fooInt3;
+
+ /*
+ * Variable Initialization
+ */
+
+ // Initialize a variable using <type> <name> = <val>
+ int barInt = 1;
+ // Initialize multiple variables of same type with same
+ // value <type> <name1>, <name2>, <name3> = <val>
+ int barInt1, barInt2, barInt3;
+ barInt1 = barInt2 = barInt3 = 1;
+
+ /*
+ * Variable types
+ */
+ // Byte - 8-bit signed two's complement integer
+ // (-128 <= byte <= 127)
+ byte fooByte = 100;
+
+ // If you would like to interpret a byte as an unsigned integer
+ // then this simple operation can help
+ int unsignedIntLessThan256 = 0xff & fooByte;
+ // this contrasts a cast which can be negative.
+ int signedInt = (int) fooByte;
+
+ // Short - 16-bit signed two's complement integer
+ // (-32,768 <= short <= 32,767)
+ short fooShort = 10000;
+
+ // Integer - 32-bit signed two's complement integer
+ // (-2,147,483,648 <= int <= 2,147,483,647)
+ int bazInt = 1;
+
+ // Long - 64-bit signed two's complement integer
+ // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ long fooLong = 100000L;
+ // L is used to denote that this variable value is of type Long;
+ // anything without is treated as integer by default.
+
+ // Note: byte, short, int and long are signed. They can have positive and negative values.
+ // There are no unsigned variants.
+ // char, however, is 16-bit unsigned.
+
+ // Float - Single-precision 32-bit IEEE 754 Floating Point
+ // 2^-149 <= float <= (2-2^-23) * 2^127
+ float fooFloat = 234.5f;
+ // f or F is used to denote that this variable value is of type float;
+ // otherwise it is treated as double.
+
+ // Double - Double-precision 64-bit IEEE 754 Floating Point
+ // 2^-1074 <= x <= (2-2^-52) * 2^1023
+ double fooDouble = 123.4;
+
+ // Boolean - true & false
+ boolean fooBoolean = true;
+ boolean barBoolean = false;
+
+ // Char - A single 16-bit Unicode character
+ char fooChar = 'A';
+
+ // final variables can't be reassigned to another object,
+ final int HOURS_I_WORK_PER_WEEK = 9001;
+ // but they can be initialized later.
+ final double E;
+ E = 2.71828;
+
+ // BigInteger - Immutable arbitrary-precision integers
+ //
+ // BigInteger is a data type that allows programmers to manipulate
+ // integers longer than 64-bits. Integers are stored as an array of
+ // of bytes and are manipulated using functions built into BigInteger
+ //
+ // BigInteger can be initialized using an array of bytes or a string.
+ BigInteger fooBigInteger = new BigInteger(fooByteArray);
+
+ // BigDecimal - Immutable, arbitrary-precision signed decimal number
+ //
+ // A BigDecimal takes two parts: an arbitrary precision integer
+ // unscaled value and a 32-bit integer scale
+ //
+ // BigDecimal allows the programmer complete control over decimal
+ // rounding. It is recommended to use BigDecimal with currency values
+ // and where exact decimal precision is required.
+ //
+ // BigDecimal can be initialized with an int, long, double or String
+ // or by initializing the unscaled value (BigInteger) and scale (int).
+ BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt);
+
+ // Be wary of the constructor that takes a float or double as
+ // the inaccuracy of the float/double will be copied in BigDecimal.
+ // Prefer the String constructor when you need an exact value.
+ BigDecimal tenCents = new BigDecimal("0.1");
+
+ // Strings
+ String fooString = "My String Is Here!";
+
+ // \n is an escaped character that starts a new line
+ String barString = "Printing on a new line?\nNo Problem!";
+ // \t is an escaped character that adds a tab character
+ String bazString = "Do you want to add a tab?\tNo Problem!";
+ System.out.println(fooString);
+ System.out.println(barString);
+ System.out.println(bazString);
+
+ // String Building
+ // #1 - with plus operator
+ // That's the basic way to do it (optimized under the hood)
+ String plusConcatenated = "Strings can " + "be concatenated " + "via + operator.";
+ System.out.println(plusConcatenated);
+ // Output: Strings can be concatenated via + operator.
+
+ // #2 - with StringBuilder
+ // This way doesn't create any intermediate strings. It just stores the string pieces, and ties them together
+ // when toString() is called.
+ // Hint: This class is not thread safe. A thread-safe alternative (with some impact on performance) is StringBuffer.
+ StringBuilder builderConcatenated = new StringBuilder();
+ builderConcatenated.append("You ");
+ builderConcatenated.append("can use ");
+ builderConcatenated.append("the StringBuilder class.");
+ System.out.println(builderConcatenated.toString()); // only now is the string built
+ // Output: You can use the StringBuilder class.
+
+ // StringBuilder is efficient when the fully constructed String is not required until the end of some processing.
+ StringBuilder stringBuilder = new StringBuilder();
+ String inefficientString = "";
+ for(int i = 0 ; i < 10; i++){
+ stringBuilder.append(i).append(" ");
+ inefficientString += i + " ";
+ }
+ System.out.println(inefficientString);
+ System.out.println(stringBuilder.toString());
+ // inefficientString requires a lot more work to produce, as it generates a String on every loop iteration.
+ // Simple concatenation with + is compiled to a StringBuilder and toString()
+ // Avoid string concatenation in loops.
+
+ // #3 - with String formatter
+ // Another alternative way to create strings. Fast and readable.
+ String.format("%s may prefer %s.", "Or you", "String.format()");
+ // Output: Or you may prefer String.format().
+
+ // Arrays
+ // The array size must be decided upon instantiation
+ // The following formats work for declaring an array
+ // <datatype>[] <var name> = new <datatype>[<array size>];
+ // <datatype> <var name>[] = new <datatype>[<array size>];
+ int[] intArray = new int[10];
+ String[] stringArray = new String[1];
+ boolean boolArray[] = new boolean[100];
+
+ // Another way to declare & initialize an array
+ int[] y = {9000, 1000, 1337};
+ String names[] = {"Bob", "John", "Fred", "Juan Pedro"};
+ boolean bools[] = {true, false, false};
+
+ // Indexing an array - Accessing an element
+ System.out.println("intArray @ 0: " + intArray[0]);
+
+ // Arrays are zero-indexed and mutable.
+ intArray[1] = 1;
+ System.out.println("intArray @ 1: " + intArray[1]); // => 1
+
+ // Other data types worth checking out
+ // ArrayLists - Like arrays except more functionality is offered, and
+ // the size is mutable.
+ // LinkedLists - Implementation of doubly-linked list. All of the
+ // operations perform as could be expected for a
+ // doubly-linked list.
+ // Maps - A set of objects that map keys to values. Map is
+ // an interface and therefore cannot be instantiated.
+ // The type of keys and values contained in a Map must
+ // be specified upon instantiation of the implementing
+ // class. Each key may map to only one corresponding value,
+ // and each key may appear only once (no duplicates).
+ // HashMaps - This class uses a hashtable to implement the Map
+ // interface. This allows the execution time of basic
+ // operations, such as get and insert element, to remain
+ // constant even for large sets.
+ // TreeMap - This class is a sorted tree structure. It implements a red
+ // black tree and sorts the entries based on the key value or
+ // the comparator provided while creating the object
+
+ ///////////////////////////////////////
+ // Operators
+ ///////////////////////////////////////
+ System.out.println("\n->Operators");
+
+ int i1 = 1, i2 = 2; // Shorthand for multiple declarations
+
+ // Arithmetic is straightforward
+ System.out.println("1+2 = " + (i1 + i2)); // => 3
+ System.out.println("2-1 = " + (i2 - i1)); // => 1
+ System.out.println("2*1 = " + (i2 * i1)); // => 2
+ System.out.println("1/2 = " + (i1 / i2)); // => 0 (int/int returns int)
+ System.out.println("1/2 = " + (i1 / (double)i2)); // => 0.5
+
+ // Modulo
+ System.out.println("11%3 = "+(11 % 3)); // => 2
+
+ // Comparison operators
+ System.out.println("3 == 2? " + (3 == 2)); // => false
+ System.out.println("3 != 2? " + (3 != 2)); // => true
+ System.out.println("3 > 2? " + (3 > 2)); // => true
+ System.out.println("3 < 2? " + (3 < 2)); // => false
+ System.out.println("2 <= 2? " + (2 <= 2)); // => true
+ System.out.println("2 >= 2? " + (2 >= 2)); // => true
+
+ // Boolean operators
+ System.out.println("3 > 2 && 2 > 3? " + ((3 > 2) && (2 > 3))); // => false
+ System.out.println("3 > 2 || 2 > 3? " + ((3 > 2) || (2 > 3))); // => true
+ System.out.println("!(3 == 2)? " + (!(3 == 2))); // => true
+
+ // Bitwise operators!
+ /*
+ ~ Unary bitwise complement
+ << Signed left shift
+ >> Signed/Arithmetic right shift
+ >>> Unsigned/Logical right shift
+ & Bitwise AND
+ ^ Bitwise exclusive OR
+ | Bitwise inclusive OR
+ */
+
+ // Increment operators
+ int i = 0;
+ System.out.println("\n->Inc/Dec-rementation");
+ // The ++ and -- operators increment and decrement by 1 respectively.
+ // If they are placed before the variable, they increment then return;
+ // after the variable they return then increment.
+ System.out.println(i++); // i = 1, prints 0 (post-increment)
+ System.out.println(++i); // i = 2, prints 2 (pre-increment)
+ System.out.println(i--); // i = 1, prints 2 (post-decrement)
+ System.out.println(--i); // i = 0, prints 0 (pre-decrement)
+
+ ///////////////////////////////////////
+ // Control Structures
+ ///////////////////////////////////////
+ System.out.println("\n->Control Structures");
+
+ // If statements are c-like
+ int j = 10;
+ if (j == 10) {
+ System.out.println("I get printed");
+ } else if (j > 10) {
+ System.out.println("I don't");
+ } else {
+ System.out.println("I also don't");
+ }
+
+ // While loop
+ int fooWhile = 0;
+ while(fooWhile < 100) {
+ System.out.println(fooWhile);
+ // Increment the counter
+ // Iterated 100 times, fooWhile 0,1,2...99
+ fooWhile++;
+ }
+ System.out.println("fooWhile Value: " + fooWhile);
+
+ // Do While Loop
+ int fooDoWhile = 0;
+ do {
+ System.out.println(fooDoWhile);
+ // Increment the counter
+ // Iterated 99 times, fooDoWhile 0->99
+ fooDoWhile++;
+ } while(fooDoWhile < 100);
+ System.out.println("fooDoWhile Value: " + fooDoWhile);
+
+ // For Loop
+ // for loop structure => for(<start_statement>; <conditional>; <step>)
+ for (int fooFor = 0; fooFor < 10; fooFor++) {
+ System.out.println(fooFor);
+ // Iterated 10 times, fooFor 0->9
+ }
+ System.out.println("fooFor Value: " + fooFor);
+
+ // Nested For Loop Exit with Label
+ outer:
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ if (i == 5 && j ==5) {
+ break outer;
+ // breaks out of outer loop instead of only the inner one
+ }
+ }
+ }
+
+ // For Each Loop
+ // The for loop is also able to iterate over arrays as well as objects
+ // that implement the Iterable interface.
+ int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ // for each loop structure => for (<object> : <iterable>)
+ // reads as: for each element in the iterable
+ // note: the object type must match the element type of the iterable.
+ for (int bar : fooList) {
+ System.out.println(bar);
+ //Iterates 9 times and prints 1-9 on new lines
+ }
+
+ // Switch Case
+ // A switch works with the byte, short, char, and int data types.
+ // It also works with enumerated types (discussed in Enum Types), the
+ // String class, and a few special classes that wrap primitive types:
+ // Character, Byte, Short, and Integer.
+ int month = 3;
+ String monthString;
+ switch (month) {
+ case 1: monthString = "January";
+ break;
+ case 2: monthString = "February";
+ break;
+ case 3: monthString = "March";
+ break;
+ default: monthString = "Some other month";
+ break;
+ }
+ System.out.println("Switch Case Result: " + monthString);
+
+ // Starting in Java 7 and above, switching Strings works like this:
+ String myAnswer = "maybe";
+ switch(myAnswer) {
+ case "yes":
+ System.out.println("You answered yes.");
+ break;
+ case "no":
+ System.out.println("You answered no.");
+ break;
+ case "maybe":
+ System.out.println("You answered maybe.");
+ break;
+ default:
+ System.out.println("You answered " + myAnswer);
+ break;
+ }
+
+
+ // Try-with-resources (Java 7+)
+ // Try-catch-finally statements work as expected in Java but in Java 7+
+ // the try-with-resources statement is also available. Try-with-resources
+ // simplifies try-catch-finally statements be closing resources
+ // automatically.
+
+ // In order to use a try-with-resources, include a an instance of a class
+ // in the try statement. The class must implement java.lang.AutoCloseable.
+ try(BufferedReader br = new BufferedReader(new FileReader("foo.txt"))) {
+ // You can attempt to do something that could throw an exception.
+ System.out.println(br.readLine());
+ // In Java 7, the resource will always be closed, even if it throws
+ // an Exception.
+ } catch (Exception ex) {
+ //The resource will be closed before the catch statement executes.
+ System.out.println("readLine() failed.");
+ }
+ // No need for a finally statement in this case, the BufferedReader is
+ // already closed. This can be used to avoid certain edge cases where
+ // a finally statement might not be called.
+ // To learn more:
+ // https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
+
+
+ // Conditional Shorthand
+ // You can use the '?' operator for quick assignments or logic forks.
+ // Reads as "If (statement) is true, use <first value>, otherwise, use
+ // <second value>"
+ int foo = 5;
+ String bar = (foo < 10) ? "A" : "B";
+ System.out.println(bar); // Prints A, because the statement is true
+
+ ////////////////////////////////////////
+ // Converting Data Types And Typecasting
+ ////////////////////////////////////////
+
+ // Converting data
+
+ // Convert String To Integer
+ Integer.parseInt("123");//returns an integer version of "123"
+
+ // Convert Integer To String
+ Integer.toString(123);//returns a string version of 123
+
+ // For other conversions check out the following classes:
+ // Double
+ // Long
+ // String
+
+ // Typecasting
+ // You can also cast Java objects, there's a lot of details and deals
+ // with some more intermediate concepts. Feel free to check it out here:
+ // https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
+
+ ///////////////////////////////////////
+ // Classes And Functions
+ ///////////////////////////////////////
+
+ System.out.println("\n->Classes & Functions");
+
+ // (definition of the Bicycle class follows)
+
+ // Use new to instantiate a class
+ Bicycle trek = new Bicycle();
+
+ // Call object methods
+ trek.speedUp(3); // You should always use setter and getter methods
+ trek.setCadence(100);
+
+ // toString returns this Object's string representation.
+ System.out.println("trek info: " + trek.toString());
+
+ // Double Brace Initialization
+ // The Java Language has no syntax for how to create static Collections
+ // in an easy way. Usually you end up in the following way:
+ private static final Set<String> COUNTRIES = new HashSet<String>();
+ static {
+ COUNTRIES.add("DENMARK");
+ COUNTRIES.add("SWEDEN");
+ COUNTRIES.add("FINLAND");
+ }
+
+ // But there's a nifty way to achieve the same thing in an
+ // easier way, by using something that is called Double Brace
+ // Initialization.
+ private static final Set<String> COUNTRIES = new HashSet<String>() {{
+ add("DENMARK");
+ add("SWEDEN");
+ add("FINLAND");
+ }}
+
+ // The first brace is creating a new AnonymousInnerClass and the
+ // second one declares an instance initializer block. This block
+ // is called when the anonymous inner class is created.
+ // This does not only work for Collections, it works for all
+ // non-final classes.
+
+ } // End main method
+} // End LearnJava class
+
+// You can include other, non-public outer-level classes in a .java file,
+// but it is not good practice. Instead split classes into separate files.
+
+// Class Declaration Syntax:
+// <public/private/protected> class <class name> {
+// // data fields, constructors, functions all inside.
+// // functions are called as methods in Java.
+// }
+
+class Bicycle {
+
+ // Bicycle's Fields/Variables
+ public int cadence; // Public: Can be accessed from anywhere
+ private int speed; // Private: Only accessible from within the class
+ protected int gear; // Protected: Accessible from the class and subclasses
+ String name; // default: Only accessible from within this package
+ static String className; // Static class variable
+
+ // Static block
+ // Java has no implementation of static constructors, but
+ // has a static block that can be used to initialize class variables
+ // (static variables).
+ // This block will be called when the class is loaded.
+ static {
+ className = "Bicycle";
+ }
+
+ // Constructors are a way of creating classes
+ // This is a constructor
+ public Bicycle() {
+ // You can also call another constructor:
+ // this(1, 50, 5, "Bontrager");
+ gear = 1;
+ cadence = 50;
+ speed = 5;
+ name = "Bontrager";
+ }
+ // This is a constructor that takes arguments
+ public Bicycle(int startCadence, int startSpeed, int startGear,
+ String name) {
+ this.gear = startGear;
+ this.cadence = startCadence;
+ this.speed = startSpeed;
+ this.name = name;
+ }
+
+ // Method Syntax:
+ // <public/private/protected> <return type> <function name>(<args>)
+
+ // Java classes often implement getters and setters for their fields
+
+ // Method declaration syntax:
+ // <access modifier> <return type> <method name>(<args>)
+ public int getCadence() {
+ return cadence;
+ }
+
+ // void methods require no return statement
+ public void setCadence(int newValue) {
+ cadence = newValue;
+ }
+ public void setGear(int newValue) {
+ gear = newValue;
+ }
+ public void speedUp(int increment) {
+ speed += increment;
+ }
+ public void slowDown(int decrement) {
+ speed -= decrement;
+ }
+ public void setName(String newName) {
+ name = newName;
+ }
+ public String getName() {
+ return name;
+ }
+
+ //Method to display the attribute values of this Object.
+ @Override // Inherited from the Object class.
+ public String toString() {
+ return "gear: " + gear + " cadence: " + cadence + " speed: " + speed +
+ " name: " + name;
+ }
+} // end class Bicycle
+
+// PennyFarthing is a subclass of Bicycle
+class PennyFarthing extends Bicycle {
+ // (Penny Farthings are those bicycles with the big front wheel.
+ // They have no gears.)
+
+ public PennyFarthing(int startCadence, int startSpeed) {
+ // Call the parent constructor with super
+ super(startCadence, startSpeed, 0, "PennyFarthing");
+ }
+
+ // You should mark a method you're overriding with an @annotation.
+ // To learn more about what annotations are and their purpose check this
+ // out: http://docs.oracle.com/javase/tutorial/java/annotations/
+ @Override
+ public void setGear(int gear) {
+ this.gear = 0;
+ }
+}
+
+// Interfaces
+// Interface declaration syntax
+// <access-level> interface <interface-name> extends <super-interfaces> {
+// // Constants
+// // Method declarations
+// }
+
+// Example - Food:
+public interface Edible {
+ public void eat(); // Any class that implements this interface, must
+ // implement this method.
+}
+
+public interface Digestible {
+ public void digest();
+ // In Java 8, interfaces can have default method.
+ // public void digest() {
+ // System.out.println("digesting ...");
+ // }
+}
+
+// We can now create a class that implements both of these interfaces.
+public class Fruit implements Edible, Digestible {
+ @Override
+ public void eat() {
+ // ...
+ }
+
+ @Override
+ public void digest() {
+ // ...
+ }
+}
+
+// In Java, you can extend only one class, but you can implement many
+// interfaces. For example:
+public class ExampleClass extends ExampleClassParent implements InterfaceOne,
+ InterfaceTwo {
+ @Override
+ public void InterfaceOneMethod() {
+ }
+
+ @Override
+ public void InterfaceTwoMethod() {
+ }
+
+}
+
+// Abstract Classes
+
+// Abstract Class declaration syntax
+// <access-level> abstract <abstract-class-name> extends <super-abstract-classes> {
+// // Constants and variables
+// // Method declarations
+// }
+
+// Marking a class as abstract means that it contains abstract methods that
+// must be defined in a child class. Similar to interfaces, abstract classes
+// cannot be instantiated, but instead must be extended and the abstract
+// methods defined. Different from interfaces, abstract classes can contain a
+// concrete and abstract methods. Methods in an interface cannot have a body,
+// mixture of unless the method is static, and variables are final by default,
+// unlike an abstract class. Also abstract classes CAN have the "main" method.
+public abstract class Animal
+{
+ public abstract void makeSound();
+
+ // Method can have a body
+ public void eat()
+ {
+ System.out.println("I am an animal and I am Eating.");
+ // Note: We can access private variable here.
+ age = 30;
+ }
+
+ // No need to initialize, however in an interface
+ // a variable is implicitly final and hence has
+ // to be initialized.
+ protected int age;
+
+ public void printAge()
+ {
+ System.out.println(age);
+ }
+
+ // Abstract classes can have main function.
+ public static void main(String[] args)
+ {
+ System.out.println("I am abstract");
+ }
+}
+
+class Dog extends Animal
+{
+ // Note still have to override the abstract methods in the
+ // abstract class.
+ @Override
+ public void makeSound()
+ {
+ System.out.println("Bark");
+ // age = 30; ==> ERROR! age is private to Animal
+ }
+
+ // NOTE: You will get an error if you used the
+ // @Override annotation here, since java doesn't allow
+ // overriding of static methods.
+ // What is happening here is called METHOD HIDING.
+ // Check out this SO post: http://stackoverflow.com/questions/16313649/
+ public static void main(String[] args)
+ {
+ Dog pluto = new Dog();
+ pluto.makeSound();
+ pluto.eat();
+ pluto.printAge();
+ }
+}
+
+// Final Classes
+
+// Final Class declaration syntax
+// <access-level> final <final-class-name> {
+// // Constants and variables
+// // Method declarations
+// }
+
+// Final classes are classes that cannot be inherited from and are therefore a
+// final child. In a way, final classes are the opposite of abstract classes
+// because abstract classes must be extended, but final classes cannot be
+// extended.
+public final class SaberToothedCat extends Animal
+{
+ // Note still have to override the abstract methods in the
+ // abstract class.
+ @Override
+ public void makeSound()
+ {
+ System.out.println("Roar");
+ }
+}
+
+// Final Methods
+public abstract class Mammal()
+{
+ // Final Method Syntax:
+ // <access modifier> final <return type> <function name>(<args>)
+
+ // Final methods, like, final classes cannot be overridden by a child
+ // class, and are therefore the final implementation of the method.
+ public final boolean isWarmBlooded()
+ {
+ return true;
+ }
+}
+
+// Enum Type
+//
+// An enum type is a special data type that enables for a variable to be a set
+// of predefined constants. The variable must be equal to one of the values
+// that have been predefined for it. Because they are constants, the names of
+// an enum type's fields are in uppercase letters. In the Java programming
+// language, you define an enum type by using the enum keyword. For example,
+// you would specify a days-of-the-week enum type as:
+public enum Day {
+ SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
+ THURSDAY, FRIDAY, SATURDAY
+}
+
+// We can use our enum Day like that:
+public class EnumTest {
+ // Variable Enum
+ Day day;
+
+ public EnumTest(Day day) {
+ this.day = day;
+ }
+
+ public void tellItLikeItIs() {
+ switch (day) {
+ case MONDAY:
+ System.out.println("Mondays are bad.");
+ break;
+ case FRIDAY:
+ System.out.println("Fridays are better.");
+ break;
+ case SATURDAY:
+ case SUNDAY:
+ System.out.println("Weekends are best.");
+ break;
+ default:
+ System.out.println("Midweek days are so-so.");
+ break;
+ }
+ }
+
+ public static void main(String[] args) {
+ EnumTest firstDay = new EnumTest(Day.MONDAY);
+ firstDay.tellItLikeItIs(); // => Mondays are bad.
+ EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
+ thirdDay.tellItLikeItIs(); // => Midweek days are so-so.
+ }
+}
+
+// Enum types are much more powerful than we show above.
+// The enum body can include methods and other fields.
+// You can see more at https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
+
+```
+
+## مطالب بیشتر
+
+لینکهای زیر را می توانید برای پیگیرهای بیشتر استفاده کنید.
+البته همیشه گوگل را در کنار دستتان داشته باشید!
+
+**سایت های راهنمای اصلی**:
+
+* [Java Tutorial Trail from Sun / Oracle](https://docs.oracle.com/javase/tutorial/index.html)
+
+* [Java Access level modifiers](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
+
+* [Object-Oriented Programming Concepts](https://docs.oracle.com/javase/tutorial/java/concepts/index.html):
+ * [Inheritance](https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html)
+ * [Polymorphism](https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html)
+ * [Abstraction](https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)
+
+* [Exceptions](https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html)
+
+* [Interfaces](https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html)
+
+* [Generics](https://docs.oracle.com/javase/tutorial/java/generics/index.html)
+
+* [Java Code Conventions](https://www.oracle.com/technetwork/java/codeconvtoc-136057.html)
+
+* New features in Java 8:
+ * [Lambda expressions (functional programming)](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html)
+ * [Date and time API (java.time package)](http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html)
+
+**راهنما و سایت های آموزشی**
+
+* [Learneroo.com - Learn Java](http://www.learneroo.com)
+
+* [Codingbat.com](http://codingbat.com/java)
+
+**کتاب‌ها**:
+
+* [Head First Java](http://www.headfirstlabs.com/books/hfjava/)
+
+* [Thinking in Java](http://www.mindview.net/Books/TIJ/)
+
+* [Objects First with Java](https://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660)
+
+* [Java The Complete Reference](https://www.amazon.com/gp/product/0071606300)
diff --git a/fa-ir/javascript-fa.html.markdown b/fa-ir/javascript-fa.html.markdown
index fe3555af..d4d3a657 100644
--- a/fa-ir/javascript-fa.html.markdown
+++ b/fa-ir/javascript-fa.html.markdown
@@ -1,7 +1,7 @@
---
language: javascript
contributors:
- - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Leigh Brenecki", "https://leigh.net.au"]
translators:
- ["Mohammad Valipour", "https://github.com/mvalipour"]
filename: javascript-fa.js
@@ -17,8 +17,8 @@ lang: fa-ir
قدر دان نظرات سازنده شما هستم! شما میتوانید از طریق زیر با من تماس بگیرید:
</p>
-[@adambrenecki](https://twitter.com/adambrenecki), or
-[adam@brenecki.id.au](mailto:adam@brenecki.id.au).
+[@ExcitedLeigh](https://twitter.com/ExcitedLeigh), or
+[l@leigh.net.au](mailto:l@leigh.net.au).
<p dir='rtl'>
// توضیحات همانند C هستند. توضیحات یک خطی با دو خط مورب شروع میشوند.,
diff --git a/factor.html.markdown b/factor.html.markdown
index 79596d83..53c692df 100644
--- a/factor.html.markdown
+++ b/factor.html.markdown
@@ -9,7 +9,7 @@ Factor is a modern stack-based language, based on Forth, created by Slava Pestov
Code in this file can be typed into Factor, but not directly imported because the vocabulary and import header would make the beginning thoroughly confusing.
-```
+```factor
! This is a comment
! Like Forth, all programming is done by manipulating the stack.
diff --git a/fi-fi/go-fi.html.markdown b/fi-fi/go-fi.html.markdown
index 9ed4e0d2..af304099 100644
--- a/fi-fi/go-fi.html.markdown
+++ b/fi-fi/go-fi.html.markdown
@@ -84,7 +84,7 @@ func learnTypes() {
// Lyhyt ilmoitus antaa yleensä haluamasi.
str := "Opi Go!" // merkkijonotyyppi.
- s2 := `"raaka" todellisarvoinen merrkijono
+ s2 := `"raaka" todellisarvoinen merkkijono
voi sisältää rivinvaihtoja.` // Sama merkkijonotyyppi.
// Ei-ASCII todellisarvo. Go-lähdekoodi on UTF-8.
diff --git a/fi-fi/markdown-fi.html.markdown b/fi-fi/markdown-fi.html.markdown
index c5ee52b0..defc7100 100644
--- a/fi-fi/markdown-fi.html.markdown
+++ b/fi-fi/markdown-fi.html.markdown
@@ -10,7 +10,7 @@ lang: fi-fi
John Gruber loi Markdownin vuona 2004. Sen tarkoitus on olla helposti luettava ja kirjoitettava syntaksi joka muuntuu helposti HTML:ksi (ja nyt myös moneksi muuksi formaatiksi).
-```markdown
+```md
<!-- Jokainen HTML-tiedosto on pätevää Markdownia. Tämä tarkoittaa että voimme
käyttää HTML-elementtejä Markdownissa, kuten kommentteja, ilman että markdown
-jäsennin vaikuttaa niihin. Tästä johtuen et voi kuitenkaan käyttää markdownia
diff --git a/forth.html.markdown b/forth.html.markdown
index 55d755b2..ff094017 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 )
@@ -59,7 +59,7 @@ Forth, but most of what is written here should work elsewhere.
\ ---------------------- More Advanced Stack Manipulation ----------------------
-1 2 3 4 tuck \ duplicate the top item into the second slot: 1 2 4 3 4 ok
+1 2 3 4 tuck \ duplicate the top item below the second slot: 1 2 4 3 4 ok
1 2 3 4 over \ duplicate the second item to the top: 1 2 3 4 3 ok
1 2 3 4 2 roll \ *move* the item at that position to the top: 1 3 4 2 ok
1 2 3 4 2 pick \ *duplicate* the item at that position to the top: 1 2 3 4 2 ok
diff --git a/fortran95.html.markdown b/fortran95.html.markdown
index 5d1424bf..c256bb38 100644
--- a/fortran95.html.markdown
+++ b/fortran95.html.markdown
@@ -6,7 +6,7 @@ filename: learnfortran.f95
---
Fortran is one of the oldest computer languages. It was developed in the 1950s
-by IBM for numeric calculations (Fortran is an abreviation of "Formula
+by IBM for numeric calculations (Fortran is an abbreviation of "Formula
Translation"). Despite its age, it is still used for high-performance computing
such as weather prediction. However, the language has changed considerably over
the years, although mostly maintaining backwards compatibility; well known
@@ -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.
@@ -242,7 +242,7 @@ program example !declare a program called example.
close(12)
! There are more features available than discussed here and alternative
- ! variants due to backwards compatability with older Fortran versions.
+ ! variants due to backwards compatibility with older Fortran versions.
! Built-in Functions
diff --git a/fr-fr/asymptotic-notation-fr.html.markdown b/fr-fr/asymptotic-notation-fr.html.markdown
new file mode 100644
index 00000000..491dc3c4
--- /dev/null
+++ b/fr-fr/asymptotic-notation-fr.html.markdown
@@ -0,0 +1,152 @@
+---
+category: Algorithms & Data Structures
+name: Asymptotic Notation
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+ - ["Divay Prakash", "http://github.com/divayprakash"]
+translators:
+ - ["Agathe Begault", "https://github.com/begault"]
+lang: fr-fr
+---
+
+# Notations Asymptotiques
+
+## Qu'est ce que c'est?
+
+Les notations asymptotiques sont des langages qui nous permettent d'analyser l'ordre de grandeur du temps d'exécution d'un algorithme en identifiant son comportement à mesure que les données d'entrée de l'algorithme augmentent. On appelle également cela le taux de croissance d'un algorithme.
+
+Est ce que l'algorithme devient soudainement extrêmement lent si on augmente sa taille d'entrée ? Est ce qu'il arrive à maintenir un temps d'exécution rapide ? La notation asymptotique nous permet simplement de répondre à ces questions et d'ainsi comparer différents algorithmes.
+
+## Y a t-il des alternatives pour répondre à ces problématiques ?
+
+Une première solution serait de compter le nombre d'opérations primitives, en fonction de la taille d'entrée.
+Cette méthode est viable mais nécessite une quantité de travail trop importante par rapport à son utilisation, même sur des algorithmes simples.
+
+Une autre approche serait de mesurer physiquement le temps qu'un algorithme met pour traiter différentes quantités de données. Cependant, la précision et la relativité de cette méthode (les temps obtenus n'étant relatifs qu'à la machine sur laquelle ils ont été calculés) est liée à des variables environnementales comme les spécifications du matériel informatique utilisé, la puissance de traitement de la machine, etc.
+
+## Les types de Notations asymptotiques
+
+En première partie de ce document, nous avons décris comment une notation asymptotique identifie le comportement d'un algorithme à mesure que la taille des données d'entrée change. Imaginons un algorithme comme une fonction f, ayant comme taille de donnée d'entrée n, et f(n) étant le temps d'exécution. Ainsi, pour un algorithme donné f, avec une taille d'entrée n, nous obtenons en résultat un temps d'exécution f(n). Cela nous fournit un graphique où l'axe Y est le temps d'exécution, l'axe X est la taille d'entrée et la courbe tracée est le résultat du temps utilisé pour traiter chaque quantité de données.
+
+Vous pouvez décrire une fonction ou un algorithme avec une notation asymptotique de plusieurs manières. Par exemple, vous pouvez décrire un algorithme en partant du meilleur des cas, du pire ou d'un cas intermédiaire. Le plus courant est de commencer à analyser un algorithme avec le pire cas. Le meilleur cas n'est pas nécessaire car ce ne sont pas les conditions que vous envisagez. L'algorithme de tri est un très bon exemple, particulièrement en ajoutant des éléments à une structure arborescente. Le meilleur cas pour la plupart des algorithmes ne nécessite qu'une simple opération alors que dans la plupart des cas, l'élément à ajouter aura besoin d'être trié de manière appropriée à travers l'arbre de données. Cette action pourrait signifier l'examen d'une branche entière de l'arbre. C'est d'ailleurs le pire cas et celui que nous prévoyons.
+
+### Les types de fonctions, limites et simplifications
+
+```
+Fonction logarithmique - log n
+Fonction linéaire - an + b
+Fonction quadratique - an^2 + bn + c
+Fonction polynomiale - an^z + . . . + an^2 + a*n^1 + a*n^0, où z est une constante
+Fonction exponentielle - a^n, où a est une constante
+```
+
+Voici une classification de fonctions croissantes de base, utilisées dans de nombreuses notations. La liste commence par la plus lente des fonctions croissantes (logarithmique, le temps d'exécution le plus rapide) et finit avec la plus croissante des fonctions (exponentielle, le temps d'exécution le plus lent). Notez que lorsque 'n' ou les données d'entrée augmentent pour chacune de ces fonctions, le résultat augmente clairement plus rapidement avec les fonctions quadratique, polynomiale et exponentielle qu'avec les fonctions logarithmique et linéaire.
+
+Il est important de noter que les notations suivantes doivent être utilisées avec les termes les plus simples. Cela signifie d'ignorer les constantes et termes de l'ordre inférieur. En effet, puisque la taille d'entrée (ou n dans notre exemple f(n)) peut augmenter à l'infini (limites mathématiques), les termes et constantes de l'ordre inférieur sont insignifiants. Ceci dit, si vous avez une constante égale à 2^9001, ou toute autre valeur ridicule et inimaginable, dans ce cas la simplification nuira à votre précision de notation.
+
+Puisque nous voulons la forme la plus simple, modifions un peu notre table...
+
+```
+Logarithmique - log n
+Linéaire - n
+Quadratique - n^2
+Polynomiale - n^z, où z est une constante
+Exponentielle - a^n, où a est une constante
+```
+
+### Big-O
+
+Big-O, couramment écris **O**, est une notation asymptotique pour le cas le plus mauvais (ou plafond de croissance) d'une fonction donnée. Il nous fournit une _**limite supérieure asymptotique**_ pour le taux de croissance du temps d'exécution d'un algorithme.
+
+Prenons 'f(n)' comme temps d'exécution de notre algorithme et 'g(n)' comme complexité de temps arbitraire que nous essayons d'appliquer à notre algorithme. 'f(n)' est O(g(n)), si pour certaines constantes c (c > 0) et n<sub>0</sub>, 'f(n)' <= 'c g(n)' pour toute taille d'entrée n (n > n<sub>0</sub>).
+
+*Exemple 1*
+
+```
+f(n) = 3log n + 100
+g(n) = log n
+```
+
+Est-ce que `f(n)` O(g(n))?
+Est-ce que `3 log n + 100` O(log n)?
+Regardons maintenant la définition de Big-O.
+
+```
+3log n + 100 <= c * log n
+```
+
+Existe t-il une paire de constantes c, n<sub>0</sub> qui satisfait cela pour tout n > <sub>0</sub>?
+
+```
+3log n + 100 <= 150 * log n, n > 2 (Indéfini avec n = 1)
+```
+
+Oui ! La définition de Big-O a été satisfaite, donc `f(n)` is O(g(n)).
+
+*Exemple 2*
+
+```
+f(n) = 3*n^2
+g(n) = n
+```
+
+Est-ce que `f(n)` O(g(n))?
+Est-ce que `3 * n^2` O(n)?
+Regardons de nouveau la définition de Big-O.
+
+```
+3 * n^2 <= c * n
+```
+
+Existe t-il une paire de constantes c, n<sub>0</sub> qui satisfait cela pour tout n > <sub>0</sub>?
+Non, il n'en existe pas. `f(n)` n'est pas égal à O(g(n)).
+
+### Big-Omega
+
+Big-Omega, courrament écris **Ω**, est une notation asymptotique pour le meilleur cas (ou limite de croissance basse) d'une fonction donnée. Il nous fournit une _**limite inférieure asymptotique**_ pour le taux de croissance du temps d'exécution d'un algorithme.
+
+Prenons 'f(n)' comme temps d'exécution de notre algorithme et 'g(n)' comme complexité de temps arbitraire que nous essayons d'appliquer à notre algorithme. 'f(n)' est Ω(g(n)), si pour certaines constantes c (c > 0) et n<sub>0</sub>, 'f(n)' >= 'c g(n)' pour toute taille d'entrée n (n > n<sub>0</sub>).
+
+### Remarque
+
+Les taux de croissance asymptotiques fournis par les notations big-O et big-omega peuvent ou non être asymptotiquement serrés. Nous utilisons ainsi les notations small-o et small-omega pour désigner des limites qui ne sont pas asymptotiquement serrées.
+
+### Small-o
+Small-o, couramment écris **o**, est une notation asymptotique pour désigner la limite supérieure (ce qui n'est pas asymptotiquement serré) du taux de croissance du temps d'exécution d'un algorithme.
+
+`f(n)` est o(g(n)), si pour certaines constantes c (c > 0) et n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` < `c g(n)`
+pour toute taille d'entrée n (n > n<sub>0</sub>).
+
+Les définitions de O-notation et o-notation sont similaires. La principale différence est visible quand f(n) = O(g(n)). Dans ce cas, la limite f(n) <= g(n) est appliquée pour _**quelques**_ constantes c > 0. Lorsque f(n) = o(g(n)), la limite f(n) < c g(n) est appliquée pour _**toute**_ constante c > 0.
+
+### Small-omega
+Small-omega, couramment écris **ω**, est une notation asymptotique pour désigner la limite inférieure (ce qui n'est pas asymptotiquement serré) du taux de croissance du temps d'exécution d'un algorithme.
+
+`f(n)` est ω(g(n)), si pour certaines constantes c (c > 0) et n<sub>0</sub> (n<sub>0</sub> > 0), `f(n)` > `c g(n)`
+pour toute taille d'entrée n (n > n<sub>0</sub>).
+
+Les définitions de Ω-notation et ω-notation sont similaires. La principale différence est visible quand f(n) = Ω(g(n)). Dans ce cas, la limite f(n) >= g(n) est appliquée pour _**quelques**_ constantes c > 0. Lorsque f(n) = ω(g(n)), la limite f(n) > c g(n) est appliquée pour _**toute**_ constante c > 0.
+
+### Theta
+Theta, couramment écris **Θ**, est une notation asymptotique pour désigner la _**borne asymptotique sous contrainte**_ du taux de croissance du temps d'exécution d'un algorithme.
+
+`f(n)` est Θ(g(n)), si pour certaines constantes réelles c1, c2 et n<sub>0</sub> (c1 > 0, c2 > 0, n<sub>0</sub> > 0), `c1 g(n)` < `f(n)` < `c2 g(n)` pour toute taille d'entrée n (n > n<sub>0</sub>).
+
+∴ `f(n)` est Θ(g(n)) implique que `f(n)` est égal à O(g(n)) autant que `f(n)` est égal à Ω(g(n)).
+
+N'hésitez pas à trouver de plus amples informations à ce sujet. Big-O est la notation la plus couramment utilisée pour le calcul de complexité du temps d'un algorithme.
+
+### Notes de fin
+Il est difficile de traiter ce type de sujets dans un article court tant les exemples, méthodes et informations sont nombreuses. C'est pourquoi nous vous invitons à jeter un oeil aux livres et liens listés ci-dessous.
+Ces ressources apportent plus de détails avec des exemples et des définitions.
+
+## Livres
+
+* [Algorithmes](http://www.amazon.com/Algorithms-4th-Robert-Sedgewick/dp/032157351X)
+* [Conception algorithmique](http://www.amazon.com/Algorithm-Design-Foundations-Analysis-Internet/dp/0471383651)
+
+## Ressources en ligne
+
+* [MIT](http://web.mit.edu/16.070/www/lecture/big_o.pdf)
+* [KhanAcademy](https://www.khanacademy.org/computing/computer-science/algorithms/asymptotic-notation/a/asymptotic-notation)
+* [Big-O Cheatsheet](http://bigocheatsheet.com/) - Structures, opérations, et algorithmes communs, classés par complexité.
diff --git a/fr-fr/awk-fr.html.markdown b/fr-fr/awk-fr.html.markdown
new file mode 100644
index 00000000..75c48811
--- /dev/null
+++ b/fr-fr/awk-fr.html.markdown
@@ -0,0 +1,377 @@
+---
+category: tool
+tool: awk
+filename: learnawk-fr.awk
+contributors:
+ - ["Marshall Mason", "http://github.com/marshallmason"]
+translators:
+ - ["GannonTdW", "https://github.com/GannonTdW"]
+lang: fr-fr
+
+---
+
+AWK est un outil standard présent dans chaque système UNIX conforme aux normes POSIX.
+C’est un outil en ligne de commande qui ressemble au Perl et qui est excellent dans les tâches de traitement de fichiers texte.
+Vous pouvez l’appeler à partir d’un script shell, ou l’utiliser comme un langage de script autonome.
+
+Pourquoi utiliser AWK au lieu du langage Perl ?
+Principalement, car AWK fait partie d'UNIX et est donc présent par défaut sur une très grande partie des systèmes d'exploitation UNIX et Linux.
+AWK est aussi plus facile à lire que le langage Perl ; et est l'outil idéal pour ce qui concerne le traitement de texte simple. Notamment le traitement de ceux qui necéssitent de lire des fichiers ligne par ligne ; chaque ligne comportant des champs séparés par des délimiteur.
+
+
+```awk
+#!/usr/bin/awk -f
+
+# Les commentaires commencent par un #
+
+
+# les programmes AWK consistent en une collection de règles et d'actions
+règle1 { action; }
+règle2 { action; }
+
+# AWK lit et analyse automatiquement chaque ligne de chaque fichier fourni.
+# Chaque ligne est divisée par un délimiteur FS qui est par défaut l'espace (plusieurs espaces ou une tabulation comptent pour un espace). Ce délimiteur peut être changer grâce à l'option -F ou être renseigné au début d'un bloc (exemple: FS = " ").
+
+# BEGIN est une règle spécifique exécutée au début du programme. C'est à cet endroit que vous mettrez tout le code à exécuter avant de traiter les fichiers texte. Si vous ne disposez pas de fichiers texte, considérez BEGIN comme le point d’entrée principal du script.
+# A l'opposé de BEGIN, il existe la règle END. Cette règle est présente après chaque fin de fichier (EOF : End Of File).
+
+BEGIN {
+
+ # Les variables sont globales. Pas besoin de les déclarer.
+ count = 0;
+
+ # les opérateurs sont identiques au langage C et aux langages similaires (exemple: C#, C++)
+ a = count + 1; # addition
+ b = count - 1; # soustraction
+ c = count * 1; # multiplication
+ d = count / 1; # division entière
+ e = count % 1; # modulo, reste de la division entière
+ f = count ^ 1; # exponentiel
+
+ a += 1;
+ b -= 1;
+ c *= 1;
+ d /= 1;
+ e %= 1;
+ f ^= 1;
+
+ # Incrémenter et décrémenter par un
+ a++;
+ b--;
+
+ # En tant qu'opérateur préfixé, c'est la valeur incrémentée qui est retournée
+ ++a;
+ --b;
+
+ # Instruction de contrôle
+ if (conteur == 0)
+ print "Nombre de départ 0";
+ else
+ print "Hein?";
+
+ # Vous pouvez aussi utiliser l'opérateur ternaire
+ print (compteur == 0) ? "Nombre de départ 0" : "Hein?";
+
+ # Les blocs sont composés d'une multitude de lignes entre accolades
+ while (a < 10) {
+ print "La concaténation de chaînes de caractères" " se fait avec des séries de chaînes " " séparées par des espaces";
+ print a;
+
+ a++;
+ }
+
+ for (i = 0; i < 10; i++)
+ print "le bon vieux for pour les boucles";
+
+ # Les opérateurs de comparaison sont standard
+ # a < b # plus petit que
+ # a <= b # plus petit ou égale à
+ # a != b # non égale
+ # a == b # égale
+ # a > b # Plus grand que
+ # a >= b # Plus grand ou égale à
+
+ # Les opérateurs logiques sont
+ # a && b # ET
+ # a || b # OU
+
+ # En plus, il y a les expressions régulières
+ if ("foo" ~ "^fo+$")
+ print "Fooey!";
+ if ("boo" !~ "^fo+$")
+ print "Boo!";
+
+ # Les Tableaux
+ arr[0] = "foo";
+ arr[1] = "bar";
+
+ # Vous pouvez aussi initialiser un tableau avec la fonction split()
+
+ n = split("foo:bar:baz", arr, ":");
+
+ # Il y a aussi les tableaux associatifs
+ assoc["foo"] = "bar";
+ assoc["bar"] = "baz";
+
+ # et les tableaux multi-dimentions, avec certaines limitations que l'on ne mentionnera pas ici
+ multidim[0,0] = "foo";
+ multidim[0,1] = "bar";
+ multidim[1,0] = "baz";
+ multidim[1,1] = "boo";
+
+ # Vous pouvez tester l'appartenance à un tableau
+ if ("foo" in assoc)
+ print "Fooey!";
+
+ # Vous pouvez aussi utilisez l'opérateur 'in' pour parcourir les clés d'un tableau
+ for (key in assoc)
+ print assoc[key];
+
+ # La ligne de commande est dans un tableau spécifique appelé ARGV
+ for (argnum in ARGV)
+ print ARGV[argnum];
+
+ # Vous pouvez supprimer des éléments d'un tableau
+ # C'est utile pour empêcher AWK de supposer que certains arguments soient des fichiers à traiter.
+ delete ARGV[1];
+
+ # Le nombre d'arguments de la ligne de commande est dans une variable appellée ARGC
+ print ARGC;
+
+ # AWK inclue trois catégories de fonction.
+ # On les examinera plus tard
+
+ return_value = arithmetic_functions(a, b, c);
+ string_functions();
+ io_functions();
+}
+
+# Voici comment définir une fonction
+function arithmetic_functions(a, b, c, d) {
+
+ # La partie la plus ennuieuse de AWK est probablement l’absence de variables locales.
+ # Tout est global. Pour les scripts courts, c'est très utile, mais pour les scripts plus longs,
+ # cela peut poser problème.
+
+ # Il y a cepandant une solution de contournement (enfin ... une bidouille).
+ # Les arguments d'une fonction sont locaux à cette fonction.
+ # Et AWK vous permet de définir plus d'arguments à la fonction que nécessaire.
+ # Il suffit donc de mettre une variable locale dans la déclaration de fonction,
+ # comme ci-dessus. La convention veut que vous mettiez quelques espaces supplémentaires
+ # pour faire la distinction entre les paramètres réels et les variables locales.
+ # Dans cet exemple, a, b et c sont des paramètres réels,
+ # alors que d est simplement une variable locale.
+
+ # Maintenant, les fonctions arithmétiques
+
+ # La plupart des implémentations de AWK ont des fonctions trigonométriques standards
+ localvar = sin(a);
+ localvar = cos(a);
+ localvar = atan2(b, a); # arc tangente de b / a
+
+ # Les exponentiels et logarithmes décimaux sont aussi là
+ localvar = exp(a);
+ localvar = log(a);
+
+ # Les racines carrées
+ localvar = sqrt(a);
+
+ # Tronquer un nombre décimal en nombre entier
+ localvar = int(5.34); # localvar => 5
+
+ # Les nombres aléatoires
+ srand();
+ # L'argument de la fonction srand() est la valeur de départ pour générer
+ # les nombres aléatoires . Par défaut, il utilise l'heure du système
+
+ localvar = rand(); # Nombre aléatoire entre 0 et 1.
+
+ # Maintenant on retourne la valeur
+ return localvar;
+}
+
+function string_functions( localvar, arr) {
+
+ # AWK a plusieurs fonctions pour le traitement des chaînes de caractères,
+ # dont beaucoup reposent sur des expressions régulières.
+
+ # Chercher et remplacer, la première occurence (sub) ou toutes les occurences (gsub)
+ # Les deux renvoient le nombre de correspondances remplacées
+ localvar = "fooooobar";
+ sub("fo+", "Meet me at the ", localvar); # localvar => "Meet me at the bar"
+ gsub("e+", ".", localvar); # localvar => "m..t m. at th. bar"
+
+ # Rechercher une chaîne de caractères qui correspond à une expression régulière
+ # index() fait la même chose, mais n'autorise pas les expressions régulières
+ match(localvar, "t"); # => 4, puisque 't' est le quatrième caractère
+
+ # Séparer par un délimiteur
+ n = split("foo-bar-baz", arr, "-"); # a[1] = "foo"; a[2] = "bar"; a[3] = "baz"; n = 3
+
+ # Autre astuces utiles
+ sprintf("%s %d %d %d", "Testing", 1, 2, 3); # => "Testing 1 2 3"
+ substr("foobar", 2, 3); # => "oob"
+ substr("foobar", 4); # => "bar"
+ length("foo"); # => 3
+ tolower("FOO"); # => "foo"
+ toupper("foo"); # => "FOO"
+}
+
+function io_functions( localvar) {
+
+ # Vous avez déjà vu print
+ print "Hello world";
+
+ # Mais il y a aussi printf
+ printf("%s %d %d %d\n", "Testing", 1, 2, 3);
+
+ # AWK n'a pas de descripteur de fichier en soi. Il ouvrira automatiquement
+ # un descripteur de fichier lorsque vous utilisez quelque chose qui en a besoin.
+ # La chaîne de caractères que vous avez utilisée pour cela peut être traitée
+ # comme un descripteur de fichier à des fins d'entrée / sortie.
+
+ outfile = "/tmp/foobar.txt";
+
+ print "foobar" > outfile;
+
+ # Maintenant, la chaîne de caractères "outfile" est un descripteur de fichier.
+ # Vous pouvez le fermer
+ close(outfile);
+
+ # Voici comment exécuter quelque chose dans le shell
+ system("echo foobar"); # => affiche foobar
+
+ # Lire quelque chose depuis l'entrée standard et la stocker dans une variable locale
+ getline localvar;
+
+ # Lire quelque chose à partir d'un pipe (encore une fois, utilisez une chaine de caractère
+ # que vous fermerez proprement)
+ "echo foobar" | getline localvar # localvar => "foobar"
+ close("echo foobar")
+
+ # Lire une ligne d'un fichier et la stocker dans une variable locale
+ infile = "/tmp/foobar.txt";
+ getline localvar < infile;
+ close(infile);
+}
+
+# Comme dit au début, AWK consiste en une collection de règles et d'actions.
+# Vous connaissez déjà les règles BEGIN et END. Les autres règles ne sont utilisées que si vous traitez
+# des lignes à partir de fichiers ou l'entrée standard (stdin).
+# Quand vous passez des arguments à AWK, ils sont considérés comme des noms de fichiers à traiter.
+# AWK les traitera tous dans l'ordre. Voyez les comme dans à une boucle implicite,
+# parcourant les lignes de ces fichiers.
+# Ces règles et ces actions ressemblent à des instructions switch dans la boucle.
+
+/^fo+bar$/ {
+
+ # Cette action sera exécutée pour chaque ligne qui correspond à l'expression régulière,
+ # /^fo+bar$/, et sera ignorée pour toute ligne qui n'y correspond pas.
+ # Imprimons simplement la ligne:
+
+ print;
+
+ # Pas d'argument ! C'est parce que print a un défaut : $0.
+ # $0 est le nom de la ligne en cours de traitement. Il est créé automatiquement.
+
+ # Vous devinez probablement qu'il existe d'autres variables $.
+ # Chaque ligne est divisée implicitement avant que chaque action soit exécutée, comme
+ # le fait le shell. Et, comme le shell, chaque champ est accessible avec un signe dollar
+
+ # Ceci affichera les deuxième et quatrième champs de la ligne.
+ print $2, $4;
+
+ # AWK défini automatiquement beaucoup d'autres variables qui peuvent vous aider
+ # à inspecter et traiter chaque ligne. La plus importante est NF
+
+ # Affiche le nombre de champs de la ligne
+ print NF;
+
+ # Afficher le dernier champ de la ligne
+ print $NF;
+}
+
+# Chaque règle est en réalité un test conditionel.
+
+a > 0 {
+ # Ceci s’exécutera une fois pour chaque ligne, tant que le test est positif
+}
+
+# Les expressions régulières sont également des tests conditionels.
+#Si le test de l'expression régulières n'est pas vrais alors le bloc n'est pas executé
+$0 /^fobar/ {
+ print "la ligne commance par fobar"
+}
+
+# Dans le cas où vous voulez tester votre chaine de caractères sur la ligne en cours de traitement
+# $0 est optionnelle.
+
+/^[a-zA-Z0-9]$/ {
+ print "La ligne courante ne contient que des caractères alphanumériques.";
+}
+
+
+# AWK peut parcourir un fichier texte ligne par ligne et exécuter des actions en fonction de règles établies
+# Cela est si courant sous UNIX qu'AWK est un langage de script.
+
+# Ce qui suit est un exemple rapide d'un petit script, pour lequel AWK est parfait.
+# Le script lit un nom à partir de l'entrée standard, puis affiche l'âge moyen de toutes les
+# personnes portant ce prénom.
+# Supposons que vous fournissiez comme argument le nom d'un fichier comportant ces données:
+#
+# Bob Jones 32
+# Jane Doe 22
+# Steve Stevens 83
+# Bob Smith 29
+# Bob Barker 72
+#
+# Le script est le suivant :
+
+BEGIN {
+
+ # Premièrement, on demande à l'utilisateur le prénom voulu
+ print "Pour quel prénom vouldriez vous savoir l'age moyen ?";
+
+ # On récupère la ligne à partir de l'entrée standard, pas de la ligne de commande
+ getline name < "/dev/stdin";
+}
+
+# Maintenant, pour chaque ligne dont le premier champ est le prénom donné
+$1 == name {
+
+ # Ici, nous avons accès à un certain nombre de variables utiles déjà préchargées :
+ # $0 est la ligne entière
+ # $3 est le troisième champ. Ici il correspond à l'age qui nous intéresse
+ # NF est le nombre de champs et vaut 3
+ # NR est le nombre d'enregistrements (lignes) vus jusqu'à présent
+ # FILENAME est le nom du fichier en cours de traitement
+ # FS est séparateur de champs, ici c'est " " (un espace)
+ # ...etc. Et beaucoup d'autre que vous pouvez connaître dans le manuel de man.
+ # Pour cela exécutez "man awk" dans votre terminal
+
+ # Garder une trace du total accumulé et du nombre de lignes correspondant.
+ sum += $3;
+ nlines++;
+}
+
+# Un autre motif spécial est END. Il fonctionnera après le traitement de tous
+# les fichiers texte. Contrairement à BEGIN, il ne fonctionne que si vous lui
+# donnez une entrée à traiter. Il sera exécuté une fois que tous les fichiers
+# auront été lus et traités conformément aux règles et aux actions que vous
+# avez fournies. Le but est généralement de produire un rapport final
+# ou de faire quelque chose avec l'ensemble des données que vous avez
+# accumulées au cours du script.
+
+
+END {
+ if (nlines)
+ print "L'age moyen pour le prénom " name " est " sum / nlines;
+}
+
+```
+Pour plus d'informations :
+
+* [Awk tutorial](http://www.grymoire.com/Unix/Awk.html)
+* [Awk man page](https://linux.die.net/man/1/awk)
+* [The GNU Awk User's Guide](https://www.gnu.org/software/gawk/manual/gawk.html) GNU Awk est dans la majorité des systèmes Linux.
+* [AWK one-liner collection](http://tuxgraphics.org/~guido/scripts/awk-one-liner.html)
diff --git a/fr-fr/c++-fr.html.markdown b/fr-fr/c++-fr.html.markdown
new file mode 100644
index 00000000..c8603756
--- /dev/null
+++ b/fr-fr/c++-fr.html.markdown
@@ -0,0 +1,915 @@
+---
+language: c++
+filename: learncpp-fr.cpp
+contributors:
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Matt Kline", "https://github.com/mrkline"]
+ - ["Geoff Liu", "http://geoffliu.me"]
+ - ["Connor Waters", "http://github.com/connorwaters"]
+translators:
+ - ["Xuan-thi Nguyen", "http://github.com/mellenguyen"]
+lang: fr-fr
+---
+
+C++ est un langage de programmation système qui,
+[selon son créateur Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
+fut créé pour
+
+- être un "C amélioré"
+- gérer l'abstraction des données
+- gérer la programmation orienté objet
+- gérer la programmation générique
+
+Bien que sa syntaxe puisse être plus difficile ou complexe que des langages
+récents, il est largement utilisé car il compile en instructions natives qui
+peuvent être directement exécutées par le processeur et offre un contrôle
+rigoureux du matériel (comme le C) tout en fournissant des caractéristiques de
+haut niveau telles que la généricité, les exceptions et les classes.
+Cette combinaison de vitesse et de fonctionnalités rend le C++ un des langages
+de programmation les plus utilisés au monde.
+
+```c++
+/////////////////////////////////
+// Comparaison avec le C
+/////////////////////////////////
+
+// C++ est _presque_ un sur-ensemble du C et partage sa syntaxe basique pour les
+// déclarations de variables, les types primitifs et les fonctions.
+
+// Tout comme en C, le point d'entrée de votre programme est une fonction
+// appelée main, avec un integer comme type de retour.
+// Cette valeur constitue l'état de fin d'exécution du programme.
+// Voir http://en.wikipedia.org/wiki/Exit_status pour plus d'informations.
+int main(int argc, char** argv)
+{
+ // Les arguments de ligne de commande sont passés avec argc et argv de la
+ // même manière qu'en C.
+ // argc indique le nombre d'arguments,
+ // et argv est un tableau de chaînes façon C (char*)
+ // représentant les arguments.
+ // Le premier argument est le nom par lequel le programme est appelé.
+ // argc et argv peuvent être omis si vous ne vous souciez pas des
+ // arguments, nous donnant comme signature de fonction int main()
+
+ // Un état de fin d'exécution 0 indique le succès.
+ return 0;
+}
+
+// Cependant, C++ varie du C selon certains éléments:
+
+// En C++, les caractères littéraux sont des chars
+sizeof('c') == sizeof(char) == 1
+
+// En C, les caractères littéraux sont des ints
+sizeof('c') == sizeof(int)
+
+// C++ a un prototypage strict
+void func(); // fonction qui ne prend aucun argument
+
+// En C
+void func(); // fonction qui peut prendre n'importe quel nombre d'arguments
+
+// Utilise nullptr au lieu de NULL en C++
+int* ip = nullptr;
+
+// Les en-têtes standards du C sont disponibles en C++,
+// mais sont préfixés avec "c" et n'ont pas de suffixe .h
+#include <cstdio>
+
+int main()
+{
+ printf("Bonjour tout le monde!\n");
+ return 0;
+}
+
+/////////////////////////////////
+// Surchage de fonctions
+/////////////////////////////////
+
+// C++ gère la surchage de fonctions
+// Chaque fonction fournie prend différents paramètres.
+
+void print(char const* maChaine)
+{
+ printf("Chaîne %s\n", maChaine);
+}
+
+void print(int monEntier)
+{
+ printf("Mon entier est %d", monEntier);
+}
+
+int main()
+{
+ print("Bonjour"); // Utilise void print(const char*)
+ print(15); // Utilise void print(int)
+}
+
+/////////////////////////////////////////////
+// Arguments par défaut de fonctions
+/////////////////////////////////////////////
+
+// Vous pouvez fournir des arguments par défaut pour une fonction s'ils ne sont
+// pas fournis par l'appelant.
+
+void faitDesChosesAvecDesEntiers(int a = 1, int b = 4)
+{
+ // Do something with the ints here
+}
+
+int main()
+{
+ faitDesChosesAvecDesEntiers(); // a = 1, b = 4
+ faitDesChosesAvecDesEntiers(20); // a = 20, b = 4
+ faitDesChosesAvecDesEntiers(20, 5); // a = 20, b = 5
+}
+
+// Les arguments par défaut doivent être à la fin de la liste des arguments.
+
+void invalidDeclaration(int a = 1, int b) // Erreur !
+{
+}
+
+
+//////////////////////////
+// Espaces de nom
+//////////////////////////
+
+// Les espaces de nom fournissent une séparation des portées pour les
+// variables, fonctions, et autres déclarations.
+// Les espaces de nom peuvent être imbriqués.
+
+namespace Premier {
+ namespace Imbrique {
+ void foo()
+ {
+ printf("Ceci est le Premier::Imbrique::foo\n");
+ }
+ } // fin de l'espace de nom Imbrique
+} // fin de l'espace de nom Premier
+
+namespace Second {
+ void foo()
+ {
+ printf("Ceci est le Second::foo\n")
+ }
+}
+
+void foo()
+{
+ printf("Ceci est un foo global\n");
+}
+
+int main()
+{
+ // Inclut tous les symboles de l'espace de nom Second dans la portée
+ // actuelle. Notez que le foo() simple ne marche plus, car l'appel est
+ // ambigu entre le foo de l'espace de nom Second et celui de premier
+ // niveau.
+ using namespace Second;
+
+ Second::foo(); // imprime "Ceci est le Second::foo"
+ Premier::Imbrique::foo(); // imprime "Ceci est le Premier::Imbrique::foo"
+ ::foo(); // imprime "Ceci est un foo global"
+}
+
+/////////////////////////
+// Entrée/Sortie
+/////////////////////////
+
+// Les entrées et sorties en C++ utilisent des flux (streams)
+// cin, cout et cerr représentent stdin, stdout et stderr.
+// << est l'opérateur d'insertion et >> est l'opérateur d'extraction.
+
+#include <iostream> // Inclusion pour les flux d'entrée/sortie
+
+// Les flux sont dans l'espace de nom std (librairie standard)
+using namespace std;
+
+int main()
+{
+ int monEntier;
+
+ // Affiche sur stdout (ou le terminal/l'écran)
+ cout << "Entrez votre chiffre favori:\n";
+ // Prend l'entrée clavier
+ cin >> monEntier;
+
+ // cout peut également être formaté
+ cout << "Votre chiffre favori est " << monEntier << "\n";
+ // imprime "Votre chiffre favori est <monEntier>"
+
+ cerr << "Utilisé pour les messages d'erreurs";
+}
+
+/////////////////////////////////
+// Chaînes de caractères
+/////////////////////////////////
+
+// Les chaînes de caractères en C++ sont des objets et ont plusieurs fonctions
+// membres
+#include <string>
+
+// Les chaînes de caractères sont aussi dans l'espace de
+// nom std (librairie standard)
+using namespace std;
+
+string maChaine = "Bonjour";
+string monAutreChaine = " tout le monde !";
+
+// + est utilisé pour la concaténation.
+cout << maChaine + monAutreChaine; // Bonjour tout le monde !"
+
+cout << maChaine + " toi !"; // "Bonjour toi !"
+
+// Les chaînes de caractères C++ sont mutables.
+maChaine.append(" le chien !");
+cout << maChaine; // "Bonjour le chien !"
+
+
+//////////////////////
+// Références
+//////////////////////
+
+// En plus des pointeurs comme ceux en C,
+// C++ possède des _références_.
+// Ce sont des types de pointeurs qui ne peuvent pas être réassignés
+// une fois initialisés, et ne peuvent pas être nulles.
+// Ils partagent la même syntaxe que les variables elles-mêmes:
+// les * ne sont pas nécessaires pour les déréférencer et
+// & (addresse de) n'est pas utilisé pour l'assignement.
+
+using namespace std;
+
+string foo = "Je suis foo";
+string bar = "Je suis bar";
+
+
+string& fooRef = foo; // Ceci créé une référence à foo
+fooRef += ". Salut!"; // Modifie foo à travers la référence
+cout << fooRef; // Affiche "Je suis foo. Salut!"
+
+// Ne réassigne pas "fooRef". Ceci revient à faire "foo = bar", et
+// foo == "I am bar"
+// après cette ligne.
+cout << &fooRef << endl; // Affiche l'adresse de foo
+fooRef = bar;
+cout << &fooRef << endl; // Affiche toujours l'adresse de foo
+cout << fooRef; // Affiche "Je suis bar"
+
+// L'adresse de fooRef reste la même, c.-à-d. référence toujours foo.
+
+
+const string& barRef = bar; // Créé une référence constante de bar.
+// Comme en C, les valeurs constantes (et pointeurs et références) ne peuvent
+// être modifiées.
+
+// Erreur, les valeurs constantes ne peuvent être modifiées.
+barRef += ". Salut!";
+
+// Parenthèse: avant de développer le sujet des références, nous devons
+// introduire un concept appelé un objet temporaire. Supposons que nous ayons
+// le code suivant :
+string objetTemporaireFun() { ... }
+string valeurRetenu = objetTemporaireFun();
+
+// Les différents événements se déroulant à la seconde ligne sont :
+// - un objet chaîne de caractères est retourné de objetTemporaireFun
+// - une nouvelle chaîne de caractères est construite avec la valeur
+// retournée comme argument du constructeur
+// - l'objet retourné est détruit.
+// L'objet retourné est appelé un objet temporaire. Les objets temporaires sont
+// créés chaque fois qu'une fonction retourne un objet, et sont détruits à la
+// fin de l'évaluation de l'expression fermante (c'est ce que le standard
+// énonce, mais les compilateurs sont autorisés à changer ce comportement.
+// Cherchez "optimisation valeur de retour" si vous êtes intéressé par ce genre
+// de détails).
+// Dans cette ligne de code :
+foo(bar(objetTemporaireFun()))
+
+// en supposant que foo et bar existent, l'objet retourné de objetTemporaireFun
+// est passé à bar, et est détruit avant que foo soit appelé.
+
+// Revenons maintenant aux références. L'exception à la règle "objet détruit à
+// la fin de l'expression fermante" s'applique dans le cas d'un objet
+// temporaire lié à une référence constante, où sa durée de vie se voit
+// prolongée à la portée courante :
+
+void referenceConstanteObjetTemporaireFun() {
+ // referenceConst prend l'objet temporaire, et est valide jusqu'à la fin de
+ // la fonction.
+ const string& referenceConst = objetTemporaireFun();
+ ...
+}
+
+// Un autre type de référence introduit en C++11 est spécifiquement pour les
+// objets temporaires. Vous ne pouvez pas avoir de variable de ce type, mais
+// il prime dans la résolution de surcharge :
+
+void fonctionFun(string& s) { ... } // Référence régulière
+void fonctionFun(string&& s) { ... } // Référence un objet temporaire
+
+string foo;
+// Appelle la version avec référence régulière
+fonctionFun(foo);
+
+// Appelle la version avec référence temporaire
+fonctionFun(objetTemporaireFun());
+
+// Par exemple, vous aurez ces deux versions de constructeurs pour
+// std::basic_string :
+basic_string(const basic_string& other);
+basic_string(basic_string&& other);
+
+// L'idéal étant de construire une nouvelle chaîne de caractères avec un objet
+// temporaire (qui sera détruit de toute façon), nous pouvons ainsi avoir un
+// constructeur qui "sauve" des parties de cette chaîne de caractères
+// temporaire. Vous verrez ce concept sous le nom de "sémantique de mouvement".
+
+////////////////////////
+// Enumérations
+////////////////////////
+
+// Les énumérations sont un moyen d'assigner une valeur à une constante
+// fréquemment utilisée pour une meilleure visualisation et lecture du code.
+enum ETypesDeVoitures
+{
+ Berline,
+ Hayon,
+ 4x4,
+ Break
+};
+
+ETypesDeVoitures ObtenirVoiturePreferee()
+{
+ return ETypesDeVoitures::Hayon;
+}
+
+// En C++11, il existe une manière simple d'assigner un type à une énumération,
+// ce qui peut-être utile en sérialisation de données et conversion
+// d'énumérations entre le type voulu et ses constantes respectives.
+enum ETypesDeVoitures : uint8_t
+{
+ Berline, // 0
+ Hayon, // 1
+ 4x4 = 254, // 254
+ Hybride // 255
+};
+
+void EcrireOctetDansLeFichier(uint8_t ValeurEntree)
+{
+ // Sérialise la valeur d'entrée dans un fichier
+}
+
+void EcrireTypeVoiturePrefereDansLeFichier(ETypesDeVoitures TypeVoitureEntree)
+{
+ // L'énumération est implicitement convertie en uint8_t du à la déclaration
+ // de son type d'énumération
+ EcrireOctetDansLeFichier(TypeVoitureEntree);
+}
+
+// D'autre part, vous pourriez ne pas vouloir que des énumérations soient
+// accidentellement converties en entiers ou en d'autres énumérations. Il est
+// donc possible de créer une classe d'énumération qui ne sera pas
+// implicitement convertie.
+enum class ETypesDeVoitures : uint8_t
+{
+ Berline, // 0
+ Hayon, // 1
+ 4x4 = 254, // 254
+ Hybride // 255
+};
+
+void EcrireOctetDansLeFichier(uint8_t ValeurEntree)
+{
+ // Sérialise la valeur d'entrée dans un fichier
+}
+
+void EcrireTypeVoiturePrefereDansLeFichier(ETypesDeVoitures TypeVoitureEntree)
+{
+ // Ne compilera pas même si ETypesDeVoitures est un uint8_t car
+ // l'énumération est déclarée en tant que "classe d'énumération" !
+ EcrireOctetDansLeFichier(TypeVoitureEntree);
+}
+
+///////////////////////////////////////////////////
+// Classes et programmation orientée objet
+///////////////////////////////////////////////////
+
+#include <iostream>
+
+// Déclare une classe.
+// Les classes sont habituellement déclarées dans les fichiers d'en-tête (.h ou .hpp).
+class Chien {
+ // Les variables et fonctions membres sont privées par défaut.
+ std::string nom;
+ int poids;
+
+// Tous les membres suivants sont publiques jusqu'à ce que "private:" ou
+// "protected:" soit trouvé
+public:
+
+ // Constructeur par défaut
+ Chien();
+
+ // Déclaractions de fonctions membres (implémentations à suivre)
+ // Notez que nous utilisons std::string ici au lieu de placer
+ // using namespace std;
+ // au-dessus.
+ // Ne jamais utiliser une instruction "using namespace" dans l'en-tête.
+ void initialiserNom(const std::string& nomDuChien);
+
+ void initialiserPoids(int poidsDuChien);
+
+ // Les fonctions qui ne modifient pas l'état de l'objet devraient être
+ // marquées en constantes avec const.
+ // Ceci vous permet de les appeler avec une référence constante vers l'objet.
+ // Notez aussi que les fonctions devant être surchargées dans des classes
+ // dérivées doivent être explicitement déclarées avec _virtual_.
+ // Les fonctions ne sont pas virtuelles par défault pour des raisons de
+ // performances.
+ virtual void imprimer() const;
+
+ // Les fonctions peuvent également être définies à l'intérieur du corps de
+ // la classe. Ces fonctions sont automatiquement "inline".
+ void aboyer() const { std::cout << nom << " fait ouaf !\n"; }
+
+ // En plus des constructeurs, C++ fournit des destructeurs.
+ // Ils sont appelés quand l'objet est supprimé ou dépasse le cadre de sa
+ // portée. Ceci permet de puissants paradigmes tels que RAII
+ // (voir plus loin)
+ // Le destructeur devrait être virtuel si la classe est abstraite;
+ // s'il n'est pas virtuel, alors le destructeur de la classe dérivée ne
+ // sera pas appelé si l'objet est détruit par le biais d'une référence à la
+ // classe de base ou d'un pointeur.
+ virtual ~Chien();
+
+}; // Un point virgule doit clôre la définition de la classe.
+
+// Les fonctions membres de la classe sont habituellement implémentées dans des
+// fichiers .cpp.
+Chien::Chien()
+{
+ std::cout << "Un chien a été construit\n";
+}
+
+// Les objets (comme les chaînes de caractères) devraient être passés par
+// référence si vous les modifiez ou par référence constante si vous ne les
+// modifiez pas.
+void Chien::initialiserNom(const std::string& nomDuChien)
+{
+ nom = nomDuChien;
+}
+
+void Chien::initialiserPoids(int poidsDuChien)
+{
+ poids = poidsDuChien;
+}
+
+// Notez que le mot-clé "virtual" est nécessaire uniquement à la déclaration,
+// et non à la définition.
+void Chien::imprimer() const
+{
+ std::cout << "Le chien s'appelle " << nom << " et pèse " << poids << "kg\n";
+}
+
+Chien::~Chien()
+{
+ cout << "Au revoir " << nom << " !\n";
+}
+
+int main() {
+ Chien monChien; // imprime "Un chien a été construit"
+ monChien.initialiserNom("Barkley");
+ monChien.initialiserPoids(10);
+ monChien.imprime(); // imprime "Le chien s'appelle Barkley et pèse 10 kg"
+ return 0;
+} // prints "Au revoir Barkley !"
+
+// Héritage :
+
+// Cette classe hérite de toutes les propriétés publiques et protégées de la
+// classe Chien ainsi que celles privées, mais n'ont pas accès direct aux
+// membres et méthodes privés sans l'aide d'une méthode publique ou protégée
+class ChienDomestique : public ChienDomestique {
+
+ void definirProprietaire(const std::string& proprietaireDuChien);
+
+ // Surcharge le comportement de la fonction d'impression pour tous les
+ // ChienDomestiques.
+ // Voir https://fr.wikipedia.org/wiki/Polymorphisme_(informatique)#Polymorphisme_par_sous-typage
+ // pour une introduction plus générale si vous n'êtes pas familier avec le
+ // concept de polymorphisme par sous-typage (appelé aussi polymorphisme
+ // d'inclusion).
+ // Le mot-clé "override" est optionnel mais assure que vous surchargez bien
+ // la méthode de la classe de base.
+ void imprimer() const override;
+
+private:
+ std::string proprietaire;
+};
+
+// Pendant ce temps, dans le fichier .cpp correspondant :
+
+void ChienDomestique::definirProprietaire(const std::string& proprietaireDuChien)
+{
+ proprietaire = proprietaireDuChien;
+}
+
+void ChienDomestique::imprimer() const
+{
+ // Appelle la fonction "imprimer" dans la classe de base Chien
+ Chien::imprimer();
+ std::cout << "Le chien appartient à " << proprietaire << "\n";
+ // Affiche "Le chien est <nom> et pèse <poids>"
+ // "Le chien appartient à <proprietaire>"
+}
+
+////////////////////////////////////////////////////
+// Initialisation et opérateur de surcharge
+////////////////////////////////////////////////////
+
+// En C++, vous pouvez surcharger le comportement d'opérateurs tels
+// que +, -, *, /, etc.
+// La surcharge se fait en définissant une fonction qui sera appelée à chaque
+// fois que l'opérateur sera utilisé.
+
+#include <iostream>
+using namespace std;
+
+class Point {
+public:
+ // Les variables membres peuvent avoir des valeurs par défaut
+ double x = 0;
+ double y = 0;
+
+ // Définit un constructeur par défaut qui ne fait rien
+ // mais initialise le Point à la valeur par défaut (0, 0)
+ Point() { };
+
+ // La syntaxe suivante s'appelle une liste d'initialisation et est
+ // la façon correcte d'initialiser les valeurs des membres d'une classe.
+ Point (double a, double b) :
+ x(a),
+ y(b)
+ { /* Ne fait rien à part initialiser les valeurs */ }
+
+ // Surcharge l'opérateur +
+ Point operator+(const Point& rhs) const;
+
+ // Surcharge l'opérateur +=
+ Point& operator+=(const Point& rhs);
+
+ // Il serait également logique d'ajouter les opérateurs - et -=,
+ // mais nous les éclipsons par soucis de concision.
+};
+
+Point Point::operator+(const Point& rhs) const
+{
+ // Créé un nouveau point qui est la somme de celui-ci de rhs.
+ return Point(x + rhs.x, y + rhs.y);
+}
+
+Point& Point::operator+=(const Point& rhs)
+{
+ x += rhs.x;
+ y += rhs.y;
+ return *this;
+}
+
+int main () {
+ Point haut (0,1);
+ Point droite (1,0);
+ // Appelle l'opérateur + du Point
+ // Le point "haut" appelle la fonction + avec "droite" comme paramètre
+ Point resultat = haut + droite;
+ // Affiche "Le résultat est haut-droite (1,1)"
+ cout << "Le résultat est haut-droite (" << resultat.x << ','
+ << resultat.y << ")\n";
+ return 0;
+}
+
+////////////////////////////////
+// Patrons (templates)
+////////////////////////////////
+
+// Les templates (patrons) en C++ sont majoritairement
+// utilisés pour la programmation générique, bien qu'ils soient bien plus
+// puissants que les constructeurs génériques dans d'autres langages.
+// Ils gèrent également la spécialisation explicite et partielle ainsi que
+// les classes fonctionnelles; en fait, ils sont un langage fonctionnelles
+// Turing-complete embedded in C++ !
+
+// Nous commencons avec le genre de programmation générique auquel vous êtes
+// peut-être familier. Pour définir une classe ou fonction qui prend un type de
+// paramètre particulier :
+template<class T>
+class Boite {
+public:
+ // Dans cette classe, T représente n'importe quel type possible.
+ void inserer(const T&) { ... }
+};
+
+// Pendant la compilation, le compilateur génère des copies de chaque template
+// avec les paramètres substitués; ainsi, la définition complète de chaque
+// classe doit être présente à chaque appel. C'est pourquoi vous verrez les
+// classes de templates définies entièrement dans les fichiers d'en-tête.
+
+// Pour instancier une classe de template sur la pile ("stack") :
+Boite<int> boiteDEntiers;
+
+// et vous pouvez l'utiliser comme prévu :
+boiteDEntiers.inserer(123);
+
+// Vous pouvez, bien sûr, imbriquer les templates :
+Boite<Boite<int> > boiteDeBoites;
+boiteDeBoites.inserer(boiteDEntiers);
+
+// Jusqu'à C++11, il était nécessaire de placer un espace entre les deux '>'s,
+// sinon '>>' était parsé en tant qu'opérateur de décalage vers la droite.
+
+// Vous croiserez peut-être cette syntaxe
+// template<typename T>
+// à la place. Les mot-clé 'class' et 'typename' sont _généralement_
+// interchangeables. Pour plus d'explications, allez à
+// http://en.wikipedia.org/wiki/Typename
+// ou
+// https://fr.wikibooks.org/wiki/Programmation_C-C%2B%2B/Les_templates/Mot-cl%C3%A9_typename
+// (oui, ce mot-clé a sa propre page Wikipedia).
+
+// De manière similaire, un patron de fonction :
+template<class T>
+void aboyerTroisFois(const T& entree)
+{
+ entree.aboyer();
+ entree.aboyer();
+ entree.aboyer();
+}
+
+// Remarquez ici que rien n'est spécifié à propos du type du paramètre. Le
+// compilateur va générer et vérifier le type à chaque appel du patron, c'est
+// pourquoi l'appel de fonction suivant marche pour n'importe quel type 'T' qui
+// a une méthode constante 'aboyer' !
+
+Chien docile;
+docile.initialiserNom("Docile")
+aboyerTroisFois(docile); // Affiche "Docile fait ouaf !" trois fois.
+
+// Les paramètres génériques (ou paramètres template) ne sont pas forcément des
+// classes :
+template<int Y>
+void imprimerMessage() {
+ cout << "Apprenez le C++ en " << Y << " minutes !" << endl;
+}
+
+// Vous pouvez explicitement spécialiser les templates pour un code plus
+// optimisé. Bien sûr, les utilisations effectives de la spécialisation ne sont
+// pas aussi triviales que celle-ci.
+// Notez que vous avez toujours besoin de déclarer la fonction (ou classe)
+// comme template, même si vous spécifiez explicitement tous les paramètres.
+template<>
+void imprimerMessage<10>() {
+ cout << "Apprenez le C++ plus vite en seulement 10 minutes !" << endl;
+}
+
+// Affiche "Apprenez le C++ en 20 minutes !"
+imprimerMessage<20>();
+// Affiche "Apprenez le C++ plus vite en seulement 10 minutes !"
+imprimerMessage<10>();
+
+//////////////////////////////////
+// Gestion des exceptions
+//////////////////////////////////
+
+// La bibliothèque standard fournit quelques types d'exception
+// (voir http://en.cppreference.com/w/cpp/error/exception)
+// mais n'importe quel type peut être lancé en tant qu'exception.
+#include <exception>
+#include <stdexcept>
+
+// Toutes les exceptions lancées à l'intérieur d'un block _try_ peuvent être
+// attrapées par les blocs de traitement d'erreurs (_catch_ handlers).
+try {
+ // N'allouez pas des exceptions sur le tas (heap) en utilisant _new_.
+ throw std::runtime_error("Un problème s'est produit");
+}
+
+// Attrapez les exceptions avec des références constantes si ce sont des objets
+catch (const std::exception& ex)
+{
+ std::cout << ex.what();
+}
+
+// Attrape n'importe quelle exception non attrapée par les blocs _catch_
+// précédents
+catch (...)
+{
+ std::cout << "Exception inconnue attrapée";
+ throw; // Re-lance l'exception
+}
+
+////////////////
+// RAII
+////////////////
+
+// RAII signifie "Resource Acquisition Is Initialization", soit l'Acquisition
+// d'une Ressource est une Initialisation en français.
+// Il est souvent considéré comme le paradigme le plus puissant en C++ et
+// est le concept simple qu'un constructeur d'un objet acquiert les ressources
+// d'un objet et que le destructeur les libère.
+
+// Afin de comprendre son utilité, considérons une fonction qui utilise la
+// gestion d'un fichier C :
+void faireQuelqueChoseAvecUnFichier(const char* nomDuFichier)
+{
+ // Pour commencer, supposons que rien ne peut échouer.
+
+ FILE* fh = fopen(nomDuFichier, "r"); // Ouvre le fichier en lecture
+
+ faireQuelqueChoseAvecLeFichier(fh);
+ faireAutreChoseAvec(fh);
+
+ fclose(fh); // Ferme la gestion du fichier.
+}
+
+// Malheureusement, les choses deviennent compliquées avec la gestion
+// d'erreurs. Supposons que fopen échoue, et que faireQuelqueChoseAvecLeFichier
+// et faireAutreChoseAvec retournent des codes d'erreur si elles échouent.
+// (Les exceptions sont le meilleur moyen de gérer l'échec, mais des
+// programmeurs, surtout avec un passif en C,
+// sont en désaccord avec l'utilité des exceptions).
+// Nous devons maintenant vérifier chaque appel en cas d'échec et fermer la
+// gestion du fichier si un problème se produit.
+bool faireQuelqueChoseAvecUnFichier(const char* nomDuFichier)
+{
+ FILE* fh = fopen(nomDuFichier, "r"); // Ouvre le fichier en mode lecture.
+ if (fh == nullptr) // Le pointeur retourné est null à un échec.
+ return false; // Signale cet échec à l'appelant.
+
+ // Suppose que chaque fonction retourne faux si elle échoue
+ if (!faireQuelqueChoseAvecLeFichier(fh)) {
+        fclose(fh); // Ferme le flux d'entrée du fichier pour empêcher les fuites
+        return false; // Propage l'erreur
+ }
+ if (!faireAutreChoseAvec(fh)) {
+ fclose(fh);
+ return false;
+ }
+
+ fclose(fh);
+ return true;
+}
+
+// Les programmeurs en C clarifient souvent tout cela en utilisant goto :
+bool faireQuelqueChoseAvecUnFichier(const char* nomDuFichier)
+{
+ FILE* fh = fopen(nomDuFichier, "r");
+ if (fh == nullptr)
+ return false;
+
+ if (!faireQuelqueChoseAvecLeFichier(fh))
+ goto echec;
+
+ if (!faireAutreChoseAvec(fh))
+ goto echec;
+
+ fclose(fh); // Ferme la gestion du fichier
+ return true; // Indique le succès
+
+echec:
+ fclose(fh);
+ return false; // Propage l'erreur
+}
+
+// Si les fonctions indiquent des erreurs en utilisant des exceptions,
+// les choses sont un peu plus claires, mais toujours sous-optimales.
+void faireQuelqueChoseAvecUnFichier(const char* nomDuFichier)
+{
+ FILE* fh = fopen(nomDuFichier, "r"); // Ouvre le fichier en lecture
+ if (fh == nullptr)
+ throw std::runtime_error("Ouverture du fichier impossible.");
+
+ try {
+ faireQuelqueChoseAvecLeFichier(fh);
+ faireAutreChoseAvec(fh);
+ }
+ catch (...) {
+ // Assurez-vous de bien fermer le fichier si une erreur arrive
+ fclose(fh);
+ throw; // Puis re-lancer l'exception
+ }
+
+ fclose(fh); // Ferme le fichier
+ // Tout s'est déroulé correctement
+}
+
+// Comparez ceci à l'utilisation de la classe de flux de fichier
+// en C++ (fstream).
+// fstream utilise son destructeur pour fermer le fichier.
+// Pour rappel, les destructeurs sont automatiquement appelée dès qu'un objet
+// sort du cadre de sa portée.
+void faireQuelqueChoseAvecUnFichier(const std::string& nomDuFichier)
+{
+ // ifstream is short for input file stream
+ std::ifstream fh(nomDuFichier); // Ouvre le fichier
+
+ // Faire des choses avec le fichier
+ faireQuelqueChoseAvecLeFichier(fh);
+ faireAutreChoseAvec(fh);
+
+} // Le fichier est automatiquement fermé ici par le destructeur
+
+// Ceci a des avantages _énormes_ :
+// 1. Peu importe la situation, la ressource (dans ce cas précis la gestion
+// de fichier) sera libérée. Si le destructeur est écrit correctement,
+// il est _impossible_ d'oublier de fermer la gestion et d'entraîner une
+// une fuite de ressources (si l'objet est sur la pile).
+// 2. Remarquez que le code est beaucoup plus clair.
+// Le destructeur gère la fermeture du fichier discrètement sans avoir
+// besoin de s'en préoccuper.
+// 3. Le code est fiable par rapport aux exceptions.
+// Une exception peut être lancée n'importe où dans la fonction, le
+// nettoyage se fera toujours.
+
+// Tout code C++ idiomatique utilise considérablement RAII pour toutes les
+// ressources.
+// Des exemples additionnels inclus :
+// - La mémoire utilisant unique_ptr et shared_ptr
+// - Des conteneurs (containers) - la liste chaînée de la librairie standard,
+// des vecteurs (c.-à-d. tableaux auto-redimensionnés), tables de hachage, et
+// ainsi de suite. Tous détruisent leur contenu quand ils sortent du cadre
+// de leur portée.
+// - Les mutex utilisant lock_guard et unique_lock
+
+
+//////////////////
+// Divers
+//////////////////
+
+// Ici sont regroupés des aspects du C++ qui peuvent être surprenants aux
+// novices (et même à quelques habitués).
+// Cette section est, malheureusement, grandement incomplète; C++ est un des
+// langages où il est très facile de se tirer soi-même dans le pied.
+
+// Vous pouvez surcharger des méthodes privées !
+class Foo {
+ virtual void bar();
+};
+class FooSub : public Foo {
+ virtual void bar(); // Surcharge Foo::bar!
+};
+
+// 0 == false == NULL (la plupart du temps) !
+bool* pt = new bool;
+*pt = 0; // Affecte false à la valeur de la variable pointée par 'pt'.
+pt = 0; // Affecte le pointeur null à 'pt'.
+// Les deux lignes compilent sans avertissement.
+
+// nullptr est supposé régler un peu ce problème :
+int* pt2 = new int;
+*pt2 = nullptr; // Ne compile pas
+pt2 = nullptr; // Affecte null à pt2
+
+// Il y a une exception faite pour les booléens.
+// Ceci vous permet de tester les pointeurs null avec if(!ptr),
+// mais par conséquent, vous pouvez assigner nullptr à un booléen directement !
+*pt = nullptr; // Ceci compile toujours, même si '*pt' est un booléen !
+
+// '=' != '=' != '='!
+// Appelle Foo::Foo(const Foo&) ou une variante du (voir sémantiques de mouvement)
+// constructeur par copie.
+Foo f2;
+Foo f1 = f2;
+
+// Appelle Foo::Foo(const Foo&) ou une variante, mais copie seulement la partie
+// 'Foo' de 'fooSub'. Tout membre extra de 'fooSub' est ignoré.
+// Ce comportement parfois horrifiant est appelé "object slicing".
+FooSub fooSub;
+Foo f1 = fooSub;
+
+// Appelle Foo::operator=(Foo&) ou une variante.
+Foo f1;
+f1 = f2;
+
+// Comment vraiment nettoyer un conteneur :
+class Foo { ... };
+vector<Foo> v;
+for (int i = 0; i < 10; ++i)
+ v.push_back(Foo());
+
+// La ligne suivante affecte la taille de v à 0, mais les destructeurs ne sont
+// appelés et les ressources ne sont pas libérées !
+v.empty();
+// La nouvelle valeur est copiée dans le premier Foo que nous avons inséré
+v.push_back(Foo());
+
+// Ceci nettoie toutes les valeurs de v. Voir la section à propos des objets
+// temporaires pour comprendre pourquoi cela fonctionne.
+v.swap(vector<Foo>());
+
+```
+Lecture complémentaire :
+
+* Une référence à jour du langage est disponible à [CPP Reference](http://cppreference.com/w/cpp).
+* Des ressources supplémentaires sont disponibles à [CPlusPlus](http://cplusplus.com).
+* Un tutoriel couvrant les bases du langage et la configuration d'un environnement de codage est disponible à l'adresse [TheChernoProject - C ++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb).
diff --git a/fr-fr/crystal-fr.html.markdown b/fr-fr/crystal-fr.html.markdown
new file mode 100644
index 00000000..02ab3b2b
--- /dev/null
+++ b/fr-fr/crystal-fr.html.markdown
@@ -0,0 +1,554 @@
+---
+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: 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 ont 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/css-fr.html.markdown b/fr-fr/css-fr.html.markdown
index 35673c47..74a49c9a 100644
--- a/fr-fr/css-fr.html.markdown
+++ b/fr-fr/css-fr.html.markdown
@@ -1,5 +1,6 @@
---
language: css
+filename: cascading-fr.css
contributors:
- ["Mohammad Valipour", "https://github.com/mvalipour"]
- ["Marco Scannadinari", "https://github.com/marcoms"]
diff --git a/fr-fr/d.html.markdown b/fr-fr/d-fr.html.markdown
index bfb9f2ce..8d98f9dc 100644
--- a/fr-fr/d.html.markdown
+++ b/fr-fr/d-fr.html.markdown
@@ -54,7 +54,7 @@ void main() {
} while(n > 0);
// For et while sont très utiles, mais en D, on préfère foreach.
- // Les deux points : '..', créent un intervalle continue de valeurs
+ // Les deux points : '..', créent un intervalle continu de valeurs
// incluant la première mais excluant la dernière.
foreach(i; 1..1_000_000) {
if(n % 2 == 0)
@@ -72,7 +72,7 @@ void main() {
}
```
On peut définir de nouveaux types avec les mots-clés `struct`, `class`,
-`union` et `enum`. Ces types sont passés au fonction par valeur (ils sont copiés)
+`union` et `enum`. Ces types sont passés à la fonction par valeur (ils sont copiés)
De plus, on peut utiliser les templates pour rendre toutes ces abstractions génériques.
```c
@@ -88,7 +88,7 @@ struct LinkedList(T) {
class BinTree(T) {
T data = null;
- // Si il n'y a qu'un seul paramètre de template,
+ // S'il n'y a qu'un seul paramètre de template,
// on peut s'abstenir de mettre des parenthèses.
BinTree!T left;
BinTree!T right;
@@ -152,7 +152,7 @@ class MyClass(T, U) {
T _data;
U _other;
- // Les constructeurs s'apellent toujours 'this'.
+ // Les constructeurs s'appellent toujours 'this'.
this(T t, U u) {
// Ceci va appeller les setters ci-dessous.
data = t;
@@ -197,8 +197,8 @@ void main() {
writefln("Later: data = %d, str = %s", mc.data, mc.other);
}
```
-Avec les propriétés, on peut constuire nos setters et nos getters
-comme on le souhaite, tout en gardant un syntaxe très propre,
+Avec les propriétés, on peut construire nos setters et nos getters
+comme on le souhaite, tout en gardant une syntaxe très propre,
comme si on accédait directement à des membres de la classe.
Les autres fonctionnalités orientées objets à notre disposition
@@ -208,8 +208,8 @@ d'une seule classe et implémenter autant d'interface que voulu.
Nous venons d'explorer les fonctionnalités objet du D, mais changeons
un peu de domaine. D permet la programmation fonctionelle, avec les fonctions
-de premier ordre, les fonctions `pure` et les données immuables.
-De plus, tout vos algorithmes fonctionelles favoris (map, reduce, filter)
+de premier ordre, les fonctions `pures` et les données immuables.
+De plus, tout vos algorithmes fonctionels favoris (map, reduce, filter)
sont disponibles dans le module `std.algorithm`.
```c
@@ -217,11 +217,11 @@ import std.algorithm : map, filter, reduce;
import std.range : iota; // construit un intervalle excluant la dernière valeur.
void main() {
- // On veut un algorithm qui affiche la somme de la listes des carrés
+ // On veut un algorithme qui affiche la somme de la liste des carrés
// des entiers paires de 1 à 100. Un jeu d'enfant !
- // On se content de passer des expressions lambda en paramètre à des templates.
- // On peut fournier au template n'importe quelle fonction, mais dans notre
+ // On se contente de passer des expressions lambda en paramètre à des templates.
+ // On peut fournir au template n'importe quelle fonction, mais dans notre
// cas, les lambdas sont pratiques.
auto num = iota(1, 101).filter!(x => x % 2 == 0)
.map!(y => y ^^ 2)
@@ -231,15 +231,15 @@ void main() {
}
```
-Vous voyez comme on a calculé `num` comme on le ferait en haskell par exemple ?
-C'est grâce à une innvoation de D qu'on appelle "Uniform Function Call Syntax".
-Avec l'UFCS, on peut choisir d'écrire un appelle à une fonction de manière
-classique, ou comme un appelle à une méthode. Walter Brighter a écrit un
+Vous voyez qu'on a calculé `num` comme on le ferait en haskell par exemple ?
+C'est grâce à une innovation de D qu'on appelle "Uniform Function Call Syntax".
+Avec l'UFCS, on peut choisir d'écrire un appel à une fonction de manière
+classique, ou comme un appel à une méthode. Walter Brighter a écrit un
article en anglais sur l'UFCS [ici.](http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394)
Pour faire court, on peut appeller une fonction dont le premier paramètre
est de type A, comme si c'était une méthode de A.
-J'aime le parallélisme. Vous aimez les parallélisme ? Bien sur que vous aimez ça
+J'aime le parallélisme. Vous aimez le parallélisme ? Bien sûr que vous aimez ça.
Voyons comment on le fait en D !
```c
@@ -248,7 +248,7 @@ import std.parallelism : parallel;
import std.math : sqrt;
void main() {
- // On veut calculer la racine carré de tous les nombres
+ // On veut calculer la racine carrée de tous les nombres
// dans notre tableau, et profiter de tous les coeurs
// à notre disposition.
auto arr = new double[1_000_000];
diff --git a/fr-fr/dynamic-programming-fr.html.markdown b/fr-fr/dynamic-programming-fr.html.markdown
index 24e8c95f..ea547dae 100644
--- a/fr-fr/dynamic-programming-fr.html.markdown
+++ b/fr-fr/dynamic-programming-fr.html.markdown
@@ -8,7 +8,6 @@ translators:
lang: fr-fr
---
-
# Programmation dynamique
## Introduction
@@ -17,9 +16,9 @@ La programmation dynamique est une technique très efficace pour résoudre une c
## Moyens de résoudre ces problèmes
-1.) *De haut en bas* : Commençons à résoudre le problème en le séparant en morceaux. Si nous voyons que le problème a déjà été résolu, alors nous retournons la réponse précédemment sauvegardée. Si le problème n'a pas été résolu, alors nous le résolvons et sauvegardons la réponse. C'est généralement facile et intuitif de réfléchir de cette façon. Cela s'appelle la Mémorisation.
+1. *De haut en bas* : Commençons à résoudre le problème en le séparant en morceaux. Si nous voyons que le problème a déjà été résolu, alors nous retournons la réponse précédemment sauvegardée. Si le problème n'a pas été résolu, alors nous le résolvons et sauvegardons la réponse. C'est généralement facile et intuitif de réfléchir de cette façon. Cela s'appelle la Mémorisation.
-2.) *De bas en haut* : Il faut analyser le problème et trouver les sous-problèmes, et l'ordre dans lequel il faut les résoudre. Ensuite, nous devons résoudre les sous-problèmes et monter jusqu'au problème que nous voulons résoudre. De cette façon, nous sommes assurés que les sous-problèmes sont résolus avant de résoudre le vrai problème. Cela s'appelle la Programmation Dynamique.
+2. *De bas en haut* : Il faut analyser le problème et trouver les sous-problèmes, et l'ordre dans lequel il faut les résoudre. Ensuite, nous devons résoudre les sous-problèmes et monter jusqu'au problème que nous voulons résoudre. De cette façon, nous sommes assurés que les sous-problèmes sont résolus avant de résoudre le vrai problème. Cela s'appelle la Programmation Dynamique.
## Exemple de Programmation Dynamique
@@ -27,7 +26,7 @@ Le problème de la plus grande sous-chaîne croissante est de trouver la plus gr
Premièrement, nous avons à trouver la valeur de la plus grande sous-chaîne (LSi) à chaque index `i`, avec le dernier élément de la sous-chaîne étant ai. Alors, la plus grande sous-chaîne sera le plus gros LSi. Pour commencer, LSi est égal à 1, car ai est le seul élément de la chaîne (le dernier). Ensuite, pour chaque `j` tel que `j<i` et `aj<ai`, nous trouvons le plus grand LSj et ajoutons le à LSi. L'algorithme fonctionne en temps *O(n2)*.
Pseudo-code pour trouver la longueur de la plus grande sous-chaîne croissante :
-La complexité de cet algorithme peut être réduite en utilisant une meilleure structure de données qu'un tableau. Par exemple, si nous sauvegardions le tableau d'origine, ou une variable comme plus_grande_chaîne_jusqu'à_maintenant et son index, nous pourrions sauver beaucoup de temps.
+La complexité de cet algorithme peut être réduite en utilisant une meilleure structure de données qu'un tableau. Par exemple, si nous sauvegardions le tableau d'origine, ou une variable comme `plus_grande_chaîne_jusqu'à_maintenant` et son index, nous pourrions sauver beaucoup de temps.
Le même concept peut être appliqué pour trouver le chemin le plus long dans un graphe acyclique orienté.
@@ -43,12 +42,9 @@ Le même concept peut être appliqué pour trouver le chemin le plus long dans u
### Problèmes classiques de programmation dynamique
-L'algorithme de Floyd Warshall(EN)) - Tutorial and C Program source code:http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code
-
-Problème du sac à dos(EN) - Tutorial and C Program source code: http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem
-
-
-Plus longue sous-chaîne commune(EN) - Tutorial and C Program source code : http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence
+- [L'algorithme de Floyd Warshall(EN) - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code)
+- [Problème du sac à dos(EN) - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem)
+- [Plus longue sous-chaîne commune(EN) - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence)
## Online Resources
diff --git a/fr-fr/elisp-fr.html.markdown b/fr-fr/elisp-fr.html.markdown
new file mode 100644
index 00000000..f9bf589c
--- /dev/null
+++ b/fr-fr/elisp-fr.html.markdown
@@ -0,0 +1,372 @@
+---
+language: elisp
+contributors:
+ - ["Bastien Guerry", "https://bzg.fr"]
+ - ["Saurabh Sandav", "http://github.com/SaurabhSandav"]
+translators:
+ - ["Bastien Guerry", "https://bzg.fr"]
+filename: learn-emacs-lisp-fr.el
+lang: fr-fr
+---
+
+```scheme
+;; Ceci est une introduction à Emacs Lisp en 15 minutes (v0.2d)
+;;
+;; Auteur : Bastien / @bzg2 / https://bzg.fr
+;;
+;; Prenez d'abord le temps de lire ce texte en anglais de Peter Norvig :
+;; http://norvig.com/21-days.html
+;;
+;; Ensuite installez GNU Emacs 24.3 (ou une version ultérieure) :
+;;
+;; Debian : apt-get install emacs (voir les instructions pour votre distribution)
+;; MacOSX : http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg
+;; Windows : http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip
+;;
+;; Vous trouverez plus d'informations sur l'installation :
+;; http://www.gnu.org/software/emacs/#Obtaining
+
+;; Avertissement important :
+;;
+;; Suivre ce tutoriel ne risque pas d'endommager votre ordinateur,
+;; sauf si vous vous énervez au point de le jeter par terre. En tout
+;; cas, je décline toute responsabilité en cas de problème.
+;; Amusez-vous bien !
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Lancez Emacs.
+;;
+;; Tapez la touche "q" pour enlever le message d'accueil.
+;;
+;; Maintenant regardez la ligne grise au pied de la fenêtre :
+;;
+;; "*scratch*" est le nom de l'espace d'édition dans lequel vous vous
+;; trouvez. Cet espace d'édition est appelé un "buffer".
+;;
+;; Le buffer scratch est le buffer par défaut quand on ouvre Emacs.
+;; Vous n'éditez jamais de fichier directement : vous éditez des
+;; buffers que vous pouvez sauvegarder dans des fichiers.
+;;
+;; "Lisp interaction" désigne le jeu de commandes disponible ici.
+;;
+;; Emacs a un jeu de commandes par défaut pour chaque buffer, et
+;; plusieurs autres jeux de commandes disponibles quand vous activez
+;; un mode particulier. Ici nous utilisons `lisp-interaction-mode',
+;; qui propose des commandes pour évaluer et naviguer dans du code
+;; Elisp.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Le point-virgule commence un commentaire partout sur une ligne.
+;;
+;; Les programmes Elisp sont composés d'expressions symboliques aussi
+;; appelées "sexps" :
+(+ 2 2)
+
+;; Cette expression symbolique se lit "Ajouter 2 à 2".
+
+;; Les sexps sont placées entre parenthèses, possiblement sur
+;; plusieurs niveaux :
+(+ 2 (+ 1 1))
+
+;; Une expression symbolique contient des atomes ou d'autres
+;; expressions symboliques. Dans les exemples ci-dessus, 1 et 2 sont
+;; des atomes et (+ 2 (+ 1 1)) et (+ 1 1) des expressions symboliques.
+
+;; Dans le mode `lisp-interaction-mode' vous pouvez évaluer les sexps.
+;; Placez le curseur juste après la parenthèse fermante, tenez la
+;; touche "Control" enfoncée et appuyez sur la touche "j" (soit le
+;; raccourci "C-j").
+
+(+ 3 (+ 1 2))
+;; ^ curseur ici
+;; `C-j' => 6
+
+;; `C-j' insère le résultat de l'évaluation dans le buffer.
+
+;; `C-x C-e' affiche le même résultat dans la ligne tout en bas
+;; d'Emacs, appelée le "minibuffer". On utilise en général `C-x C-e',
+;; pour ne pas encombrer le buffer avec du texte inutile.
+
+;; `setq' assigne une valeur à une variable :
+(setq my-name "Bastien")
+;; `C-x C-e' => "Bastien" (affiché dans le minibuffer)
+
+;; `insert' va insérer "Hello!" là où se trouve le curseur :
+(insert "Hello!")
+;; `C-x C-e' => "Hello!"
+
+;; Nous utilisons `insert' avec un seul argument "Hello!", mais
+;; nous pouvons passer plus d'arguments - ici nous en passons deux :
+
+(insert "Hello" " world!")
+;; `C-x C-e' => "Hello world!"
+
+;; Vous pouvez utiliser des variables au lieu de chaînes de caractères :
+(insert "Hello, I am " my-name)
+;; `C-x C-e' => "Hello, I am Bastien"
+
+;; Vous pouvez combiner les sexps en fonctions :
+(defun hello () (insert "Hello, I am " my-name))
+;; `C-x C-e' => hello
+
+;; Vous pouvez évaluer les fonctions :
+(hello)
+;; `C-x C-e' => Hello, I am Bastien
+
+;; Les parenthèses vides dans la définition de la fonction signifient
+;; qu'elle ne prend pas d'argument. Mais toujours utiliser `my-name'
+;; est ennuyant, demandons à la fonction d'accepter un argument (ici
+;; l'argument est appelé "name") :
+
+(defun hello (name) (insert "Hello " name))
+;; `C-x C-e' => hello
+
+;; Maintenant appelons la fonction avec la chaîne de caractères "you"
+;; comme valeur de son unique argument :
+(hello "you")
+;; `C-x C-e' => "Hello you"
+
+;; Youpi!
+
+;; Faites une pause.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Maintenant ouvrez un nouveau buffer appelé "*test*" dans une
+;; nouvelle fenêtre :
+
+(switch-to-buffer-other-window "*test*")
+;; `C-x C-e'
+;; => [l'écran a deux fenêtres et le curseur est dans le buffer *test*]
+
+;; Placez la souris sur la fenêtre du haut et cliquez-gauche pour
+;; retourner dans cette fenêtre. Ou bien utilisez `C-x o' (i.e. tenez
+;; control-x appuyé et appuyez sur o) pour aller dans l'autre fenêtre
+;; interactivement.
+
+;; Vous pouvez combiner plusieurs sexps avec `progn' :
+(progn
+ (switch-to-buffer-other-window "*test*")
+ (hello "you"))
+;; `C-x C-e'
+;; => [L'écran a deux fenêtres et le curseur est dans le buffer *test*]
+
+;; Maintenant si ça ne vous dérange pas, je vais arrêter de vous
+;; demander de faire `C-x C-e' : faites-le pour chaque sexp qui suit.
+
+;; Retournez toujours dans le buffer *scratch* avec la souris ou `C-x o'.
+
+;; Il est souvent utile d'effacer le contenu du buffer :
+(progn
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (hello "there"))
+
+;; Ou d'aller à l'autre fenêtre :
+(progn
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (hello "you")
+ (other-window 1))
+
+;; Vous pouvez associer une valeur à une variable locale avec `let' :
+(let ((local-name "you"))
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (hello local-name)
+ (other-window 1))
+
+;; Dans ce cas pas besoin d'utiliser `progn' puisque `let' combine
+;; aussi plusieurs sexps.
+
+;; Mettons en forme une chaîne de caractères :
+(format "Hello %s!\n" "visitor")
+
+;; %s désigne l'emplacement de la chaîne, remplacé par "visitor".
+;; \n est le caractère de saut de ligne.
+
+;; Améliorons notre fonction en utilisant "format" :
+(defun hello (name)
+ (insert (format "Hello %s!\n" name)))
+
+(hello "you")
+
+;; Créons une autre fonction qui utilise `let' :
+(defun greeting (name)
+ (let ((your-name "Bastien"))
+ (insert (format "Hello %s!\n\nI am %s."
+ name ; l'argument de la fonction
+ your-name ; la variable "let-bindée" "Bastien"
+ ))))
+
+;; Et évaluons-la :
+(greeting "you")
+
+;; Certaines fonctions sont interactives :
+(read-from-minibuffer "Enter your name: ")
+
+;; Évaluer cette fonction va renvoyer ce que vous avez saisi dans le
+;; minibuffer.
+
+;; Faisons que notre fonction `greeting' vous demande votre nom :
+(defun greeting (from-name)
+ (let ((your-name (read-from-minibuffer "Enter your name: ")))
+ (insert (format "Hello!\n\nI am %s and you are %s."
+ from-name ; l'argument de la fonction
+ your-name ; la variable "let-bindée", entrée dans le minibuffer
+ ))))
+
+(greeting "Bastien")
+
+;; Complétons la fonction pour qu'elle affiche le résultat dans
+;; l'autre fenêtre :
+(defun greeting (from-name)
+ (let ((your-name (read-from-minibuffer "Enter your name: ")))
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (insert (format "Hello %s!\n\nI am %s." your-name from-name))
+ (other-window 1)))
+
+;; Maintenant testons :
+(greeting "Bastien")
+
+;; Faites une pause.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Stockons une liste de noms :
+(setq list-of-names '("Sarah" "Chloe" "Mathilde"))
+
+;; Récupérez le premier élément de la liste avec `car' :
+(car list-of-names)
+
+;; Récupérez tous les élements sauf le premier avec `cdr' :
+(cdr list-of-names)
+
+;; Ajoutez un élément au début avec `push' :
+(push "Stephanie" list-of-names)
+
+;; Note : `car' et `cdr' ne modifient pas la liste, mais `push' oui.
+;; C'est une différence importante : certaines fonctions n'ont pas
+;; d'effets de bord (comme `car') et d'autres oui (comme `push').
+
+;; Évaluons `hello' pour tous les éléments dans `list-of-names' :
+(mapcar 'hello list-of-names)
+
+;; Améliorons `greeting' pour dire hello aux noms de `list-of-names' :
+(defun greeting ()
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (mapcar 'hello list-of-names)
+ (other-window 1))
+
+(greeting)
+
+;; Vous vous souvenez de la fonction `hello' définie ci-dessus ? Elle
+;; prend seulement un argument, un nom. `mapcar' appelle `hello' en
+;; utilisant successivement chaque élément de `list-of-names' comme
+;; argument de `hello'.
+
+;; Maintenant arrangeons un peu ce qui est affiché dans le buffer :
+
+(defun replace-hello-by-bonjour ()
+ (switch-to-buffer-other-window "*test*")
+ (goto-char (point-min))
+ (while (search-forward "Hello")
+ (replace-match "Bonjour"))
+ (other-window 1))
+
+;; (goto-char (point-min)) va au début du buffer.
+;; (search-forward "Hello") cherche la chaîne "Hello".
+;; (while x y) évalue la sexp(s) y tant que x renvoie quelque chose.
+;; Si x renvoie `nil' (rien), nous sortons de la boucle.
+
+(replace-hello-by-bonjour)
+
+;; Vous devriez voir toutes les occurrences de "Hello" dans le buffer
+;; *test* remplacées par "Bonjour".
+
+;; Vous devriez aussi avoir une erreur : "Search failed: Hello".
+;;
+;; Pour éviter cette erreur, il faut dire à `search-forward' si la
+;; recherche doit s'arrêter à un certain point du buffer, et si elle
+;; doit s'arrêter silencieusement si aucune chaîne n'est trouvée.
+
+;; (search-forward "Hello" nil t) fait ça :
+
+;; L'argument `nil' indique que la recherche n'est pas limitée à une
+;; position. L'argument `t' indique de s'arrêter silencieusement si
+;; rien n'est trouvé.
+
+;; Nous utilisons cette sexp dans la fonction ci-dessous, qui ne
+;; renvoie pas d'erreur :
+
+(defun hello-to-bonjour ()
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ ;; Dit hello aux noms de `list-of-names'
+ (mapcar 'hello list-of-names)
+ (goto-char (point-min))
+ ;; Remplace "Hello" par "Bonjour"
+ (while (search-forward "Hello" nil t)
+ (replace-match "Bonjour"))
+ (other-window 1))
+
+(hello-to-bonjour)
+
+;; Mettons les noms en gras :
+
+(defun boldify-names ()
+ (switch-to-buffer-other-window "*test*")
+ (goto-char (point-min))
+ (while (re-search-forward "Bonjour \\(.+\\)!" nil t)
+ (add-text-properties (match-beginning 1)
+ (match-end 1)
+ (list 'face 'bold)))
+ (other-window 1))
+
+;; Cette fonction introduit `re-search-forward' : au lieu de chercher
+;; la chaîne "Bonjour", nous cherchons un motif ("pattern" en anglais)
+;; en utilisant une "expression régulière" (le préfixe "re-" signifie
+;; "regular expression").
+
+;; L'expression régulière est "Bonjour \\(.+\\)!" et se lit :
+;; la chaîne "Bonjour ", et
+;; un groupe de | c'est la syntaxe \\( ... \\)
+;; n'importe quel caractère | c'est le .
+;; une ou plusieurs fois | c'est le +
+;; et la chaîne "!".
+
+;; Prêt ? Testons !
+
+(boldify-names)
+
+;; `add-text-properties' ajoute des propriétés textuelles telles que
+;; des "faces" (une "face" définit la fonte, la couleur, la taille et
+;; d'autres propriétés du texte.)
+
+;; Et voilà, c'est fini. Happy hacking!
+
+;; Si vous voulez en savoir plus sur une variable ou une fonction :
+;;
+;; C-h v une-variable RET
+;; C-h f une-fonction RET
+;;
+;; Pour lire le manuel Emacs Lisp avec Emacs :
+;;
+;; C-h i m elisp RET
+;;
+;; Pour lire en ligne une introduction à Emacs Lisp :
+;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html
+
+;; Merci à ces personnes pour leurs retours et suggestions :
+;; - Wes Hardaker
+;; - notbob
+;; - Kevin Montuori
+;; - Arne Babenhauserheide
+;; - Alan Schmitt
+;; - LinXitoW
+;; - Aaron Meurer
+```
diff --git a/fr-fr/elixir-fr.html.markdown b/fr-fr/elixir-fr.html.markdown
new file mode 100644
index 00000000..90cdad7c
--- /dev/null
+++ b/fr-fr/elixir-fr.html.markdown
@@ -0,0 +1,479 @@
+---
+language: elixir
+contributors:
+ - ["Joao Marques", "http://github.com/mrshankly"]
+ - ["Dzianis Dashkevich", "https://github.com/dskecse"]
+ - ["Ryan Plant", "https://github.com/ryanplant-au"]
+ - ["Ev Bogdanov", "https://github.com/evbogdanov"]
+translator:
+ - ["Timothé Pardieu", "https://github.com/timprd"]
+filename: learnelixir-fr.ex
+lang: fr-fr
+---
+Elixir est un langage de programmation fonctionnel moderne reposant sur la machine virtuelle BEAM, qui héberge aussi Erlang.
+Il est totalement compatible avec Erlang mais dispose d'une syntaxe plus agréable et apporte de nouvelles fonctionnalités.
+
+
+```elixir
+
+# Un commentaire simple sur une seule ligne commence par un dièse.
+
+# Il n'y a pas de commentaire multi-ligne,
+# Mais il est possible de les empiler comme ici.
+
+# La commande `iex` permet de lancer le shell Elixir.
+# La commande `elixirc` permet de compiler vos modules.
+
+# Les deux devraient être dans votre path si vous avez installé Elixir correctement.
+
+## ---------------------------
+## -- Types basiques
+## ---------------------------
+
+# Il y a les nombres
+3 # Integer
+0x1F # Integer
+3.0 # Float
+
+# Les atomes, des littéraux, qui sont des constantes avec comme valeur leur nom.
+# Ils commencent par `:`.
+
+:hello # atom
+
+# Il existe également des n-uplets dont les valeurs sont stockés de manière contiguë
+# en mémoire.
+
+{1,2,3} # tuple
+
+# Il est possible d'accéder à un element d'un tuple avec la fonction
+# `elem`:
+elem({1, 2, 3}, 0) #=> 1
+
+# Les listes sont implémentées sous forme de listes chainées.
+[1,2,3] # list
+
+# La tête et le reste d'une liste peuvent être récupérés comme cela :
+[head | tail] = [1,2,3]
+head #=> 1
+tail #=> [2,3]
+
+# En Elixir, comme en Erlang, le `=` dénote un 'pattern matching'
+# (Filtrage par motif) et non une affectation.
+# Cela signifie que la partie de gauche (pattern) est comparé (match) à
+# la partie de droite.
+
+
+# Une erreur sera lancée si aucun model (match) est trouvé.
+# Dans cet exemple les tuples ont des tailles différentes
+# {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
+
+# Il y a aussi les binaires
+<<1,2,3>> # binary
+
+# Chaine de caractères et liste de caractères
+"hello" # string
+'hello' # char list
+
+# Chaine de caractères sur plusieurs lignes
+"""
+Je suis une chaine de caractères
+sur plusieurs lignes.
+"""
+#=> "Je suis une chaine de caractères\nsur plusieurs lignes.\n"
+
+# Les chaines de caractères sont encodées en UTF-8 :
+"héllò" #=> "héllò"
+
+# Les chaines de caractères sont des binaires tandis que
+# les listes de caractères sont des listes.
+<<?a, ?b, ?c>> #=> "abc"
+[?a, ?b, ?c] #=> 'abc'
+
+# `?a` en Elixir retourne le code ASCII (Integer) de la lettre `a`
+?a #=> 97
+
+# Pour concaténer des listes il faut utiliser `++`, et `<>` pour les
+# binaires
+[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"
+
+# Les intervalles sont représentés de cette sorte `début..fin`
+# (tout deux inclusifs)
+1..10 #=> 1..10
+bas..haut = 1..10 # Possibilité d'utiliser le pattern matching sur les intervalles aussi.
+[bas, haut] #=> [1, 10]
+
+# Les Maps (Tableau associatif) sont des paires clée - valeur
+genders = %{"david" => "male", "gillian" => "female"}
+genders["david"] #=> "male"
+
+# Les maps avec des atomes peuvent être utilisés comme cela
+genders = %{david: "male", gillian: "female"}
+genders.gillian #=> "female"
+
+## ---------------------------
+## -- Operateurs
+## ---------------------------
+
+# Mathématiques
+1 + 1 #=> 2
+10 - 5 #=> 5
+5 * 2 #=> 10
+10 / 2 #=> 5.0
+
+# En Elixir l'opérateur `/` retourne toujours un Float (virgule flottante).
+
+# Pour faire une division avec entier il faut utiliser `div`
+div(10, 2) #=> 5
+
+# Pour obtenir le reste de la division il faut utiliser `rem`
+rem(10, 3) #=> 1
+
+# Il y a aussi les opérateurs booléen: `or`, `and` et `not`.
+# Ces opérateurs attendent un booléen en premier argument.
+true and true #=> true
+false or true #=> true
+# 1 and true
+#=> ** (BadBooleanError) expected a booléens on left-side of "and", got: 1
+
+# Elixir fournit aussi `||`, `&&` et `!` qui acceptent des arguments de
+# tout type.
+# Chaque valeur sauf `false` et `nil` seront évalués à vrai (true).
+1 || true #=> 1
+false && 1 #=> false
+nil && 20 #=> nil
+!true #=> false
+
+# Pour les comparaisons il y a : `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` et `>`
+1 == 1 #=> true
+1 != 1 #=> false
+1 < 2 #=> true
+
+# `===` et `!==` sont plus stricts en comparant les Integers (entiers)
+# et les Floats (nombres à virgules) :
+1 == 1.0 #=> true
+1 === 1.0 #=> false
+
+# On peut aussi comparer deux types de données différents :
+1 < :hello #=> true
+
+# L'ordre est défini de la sorte :
+# number < atom < reference < functions < port < pid < tuple < list < bit string
+
+# Pour citer Joe Armstrong : "The actual order is not important,
+# but that a total ordering is well defined is important."
+
+## ---------------------------
+## -- Structure de contrôle
+## ---------------------------
+
+# Condition avec `if` (si)
+if false do
+ "Cela ne sera pas vu"
+else
+ "Cela le sera"
+end
+
+# Condition avec `unless` (sauf).
+# Il correspond à la négation d'un `if` (si)
+unless true do
+ "Cela ne sera pas vu"
+else
+ "Cela le sera"
+end
+
+# Beaucoup de structures en Elixir se basent sur le pattern matching.
+# `case` permet de comparer une valeur à plusieurs modèles:
+case {:one, :two} do
+ {:four, :five} ->
+ "Ne match pas"
+ {:one, x} ->
+ "Match et lie `x` à `:two` dans ce cas"
+ _ ->
+ "Match toutes les valeurs"
+end
+
+# Il est commun de lier la valeur à `_` si on ne l'utilise pas.
+# Par exemple, si seulement la tête d'une liste nous intéresse:
+[head | _] = [1,2,3]
+head #=> 1
+
+# Pour plus de lisibilité, ce procédé est utilisé:
+[head | _tail] = [:a, :b, :c]
+head #=> :a
+
+# `cond` permet de vérifier plusieurs conditions à la fois.
+# Il est conseillé d'utiliser `cond` plutôt que des `if` imbriqués.
+cond do
+ 1 + 1 == 3 ->
+ "Je ne serai pas vu"
+ 2 * 5 == 12 ->
+ "Moi non plus"
+ 1 + 2 == 3 ->
+ "Mais moi oui"
+end
+
+# Il est commun d'attribuer la dernière condition à true (vrai), qui
+# matchera toujours.
+cond do
+ 1 + 1 == 3 ->
+ "Je ne serai pas vu"
+ 2 * 5 == 12 ->
+ "Moi non plus"
+ true ->
+ "Mais moi oui (représente un else)"
+end
+
+# `try/catch` est utilisé pour attraper les valeurs rejetées.
+# Il supporte aussi un
+# `after` qui est appelé autant si une valeur est jetée ou non.
+try do
+ throw(:hello)
+catch
+ message -> "Message : #{message}."
+after
+ IO.puts("Je suis la clause after (après).")
+end
+#=> Je suis la clause after (après).
+# "Message : :hello"
+
+## ---------------------------
+## -- Modules et Fonctions
+## ---------------------------
+
+# Fonctions anonymes (notez le point).
+square = fn(x) -> x * x end
+square.(5) #=> 25
+
+# Les fonctions anonymes acceptent aussi de nombreuses clauses et guards (gardes).
+# Les guards permettent d'affiner le pattern matching,
+# ils sont indiqués par le mot-clef `when` :
+f = fn
+ x, y when x > 0 -> x + y
+ x, y -> x * y
+end
+
+f.(1, 3) #=> 4
+f.(-1, 3) #=> -3
+
+# Elixir propose aussi de nombreuses fonctions internes.
+is_number(10) #=> true
+is_list("hello") #=> false
+elem({1,2,3}, 0) #=> 1
+
+# Il est possible de grouper plusieurs fonctions dans un module.
+# Dans un module, les fonctions sont définies par `def`
+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
+
+# Pour compiler notre module `Math`,
+# il faut le sauvegarder en tant que `math.ex` et utiliser `elixirc`.
+# Executez ainsi `elixirc math.ex` dans le terminal.
+
+# Au sein d'un module, nous pouvons définir les fonctions avec `def`
+# et `defp` pour les fonctions privées.
+# Une fonction définie par `def` est disponible dans les autres
+# modules. Une fonction privée est disponible localement seulement.
+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 déclaration de fonction supporte également les guards (gardes)
+# et les clauses.
+# Quand une fonction avec plusieurs clauses est appelée,
+# la première fonction dont la clause est satisfaite par les arguments sera appelée.
+# Exemple: le code `area({:circle, 3})` appelle la deuxième fonction definie plus bas,
+# et non la première car ses arguments correspondent à la signature de cette dernière:
+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
+
+# En raison de l'immutabilité, la récursivité est une grande partie
+# d'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
+
+# Les modules Elixir supportent des attributs internes,
+# ceux-ci peuvent aussi être personnalisés.
+defmodule MyMod do
+ @moduledoc """
+ This is a built-in attribute on a example module.
+ """
+
+ @my_data 100 # Attribut personnel.
+ IO.inspect(@my_data) #=> 100
+end
+
+# L'opérateur pipe (|>) permet de passer la sortie d'une expression
+# en premier paramètre d'une fonction.
+
+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 et Exceptions
+## ---------------------------
+
+# Les Structs sont des extensions des Maps.
+# Apportant en plus les valeurs par defaut, le polymorphisme et
+# la vérification à la compilation dans Elixir.
+defmodule Person do
+ defstruct name: nil, age: 0, height: 0
+end
+
+jean_info = %Person{ name: "Jean", age: 30, height: 180 }
+#=> %Person{age: 30, height: 180, name: "Jean"}
+
+# Access the value of name
+jean_info.name #=> "Jean"
+
+# Update the value of age
+older_jean_info = %{ jean_info | age: 31 }
+#=> %Person{age: 31, height: 180, name: "Jean"}
+
+# Le bloc `try` avec le mot-clef `rescue` est utilisé pour gérer les exceptions
+try do
+ raise "some error"
+rescue
+ RuntimeError -> "rescued a runtime error"
+ _error -> "this will rescue any error"
+end
+#=> "rescued a runtime error"
+
+# Chaque exception possède un message
+try do
+ raise "some error"
+rescue
+ x in [RuntimeError] ->
+ x.message
+end
+#=> "some error"
+
+## ---------------------------
+## -- Concurrence
+## ---------------------------
+
+# Elixir se repose sur le modèle d'acteur pour gérer la concurrence.
+# Pour écrire un programme concurrent en Elixir il faut trois
+# primitives: spawning processes (création), sending messages (envoi)
+# et receiving messages (réception).
+
+# Pour débuter un nouveau processus, il faut utiliser
+# la fonction `spawn` qui prend en argument une fonction.
+f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
+spawn(f) #=> #PID<0.40.0>
+
+# `spawn` retourn un pid (identifiant de processus), il est possible
+# d'utiliser ce pid pour envoyer un message au processus.
+# Pour faire parvenir le message il faut utiliser l'opérateur `send`.
+# Pour que cela soit utile il faut être capable de recevoir les
+# messages.
+# Cela est possible grâce au mechanisme de `receive`:
+
+# Le bloc `receive do` est utilisé pour écouter les messages et les traiter
+# au moment de la réception. Un bloc `receive do` pourra traiter un seul
+# message reçu.
+# Pour traiter plusieurs messages, une fonction avec un bloc `receive do`
+# doit s'appeler elle-même récursivement.
+
+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
+
+# Ceci compile le module et créer un processus qui évalue dans le terminal `area_loop`
+pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
+# Alternativement
+pid = spawn(Geometry, :area_loop, [])
+
+# On envoi un message au `pid` qui correspond à la régle de réception.
+send pid, {:rectangle, 2, 3}
+#=> Area = 6
+# {:rectangle,2,3}
+
+send pid, {:circle, 2}
+#=> Area = 12.56000000000000049738
+# {:circle,2}
+
+# Le shell est aussi un processus, il est possible d'utiliser `self`
+# pour obtenir le pid du processus courant.
+self() #=> #PID<0.27.0>
+
+## ---------------------------
+## -- Agents
+## ---------------------------
+
+# Un agent est un processus qui garde les traces des valeurs modifiées.
+
+# Pour créer un agent on utilise `Agent.start_link` avec une fonction.
+# L'état initial de l'agent sera ce que la fonction retourne
+{ok, my_agent} = Agent.start_link(fn -> ["red", "green"] end)
+
+# `Agent.get` prend un nom d'agent et une fonction (`fn`).
+# Qu'importe ce que cette `fn` retourne, l'état sera ce qui est retourné.
+Agent.get(my_agent, fn colors -> colors end) #=> ["red", "green"]
+
+# Modification de l'état de l'agent
+Agent.update(my_agent, fn colors -> ["blue" | colors] end)
+```
+
+## Références
+
+* [Guide de debut](http://elixir-lang.org/getting-started/introduction.html) depuis le site [Elixir](http://elixir-lang.org)
+* [Documentation Elixir ](https://elixir-lang.org/docs.html)
+* ["Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) de Dave Thomas
+* [Elixir Cheat Sheet](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf)
+* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) de Fred Hebert
+* ["Programming Erlang: Software for a Concurrent World"](https://pragprog.com/book/jaerlang2/programming-erlang) de Joe Armstrong
diff --git a/fr-fr/erlang-fr.html.markdown b/fr-fr/erlang-fr.html.markdown
index 55453c56..1073d6ad 100644
--- a/fr-fr/erlang-fr.html.markdown
+++ b/fr-fr/erlang-fr.html.markdown
@@ -28,7 +28,7 @@ lang: fr-fr
%% 1. Variables et filtrage par motif
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-(L'équivalent anglais de *filtrage par motif* est *pattern patching*.)
+(L'équivalent anglais de *filtrage par motif* est *pattern matching*.)
Nb = 42. % Chaque nom de variable doit commencer par une lettre majuscule.
@@ -64,7 +64,7 @@ Point = {point, 10, 45}.
{point, X, Y} = Point. % X = 10, Y = 45
% On peut utiliser `_` comme caractère joker pour les variables qui ne nous
-% intéressent pas. Le symbol `_` est appelé variable muette. Contrairement
+% intéressent pas. Le symbole `_` est appelé variable muette. Contrairement
% aux variables normales, de multiples apparitions de `_` dans un même motif
% ne lient pas nécessairement à la même valeur.
Personne = {personne, {nom, {prenom, joe}, {famille, armstrong}},
diff --git a/fr-fr/fsharp-fr.html.markdown b/fr-fr/fsharp-fr.html.markdown
new file mode 100644
index 00000000..dda9945f
--- /dev/null
+++ b/fr-fr/fsharp-fr.html.markdown
@@ -0,0 +1,632 @@
+---
+language: F#
+lang: fr-fr
+contributors:
+ - ["Scott Wlaschin", "http://fsharpforfunandprofit.com/"]
+translators:
+ - ["Alois de Gouvello", "https://github.com/aloisdg"]
+filename: learnfsharp-fr.fs
+---
+
+F# est un langage de programmation fonctionnel et orienté objet. Il est gratuit et son code source est ouvert. Il tourne sur Linux, Mac, Windows et plus.
+
+Il possède un puissant système de type qui piège de nombreuses erreurs à la compilation, mais il utilise l'inférence de type ce qui lui permet d'être lu comme un langage dynamique.
+
+La syntaxe de F# est différente des langages héritant de C.
+
+* Les accolades ne sont pas utilisées pour délimiter les blocs de code. À la place, l'indentation est utilisée (à la manière de Python).
+* Les espaces sont utilisés pour séparer les paramètres à la place des virgules.
+
+Si vous voulez essayer le code ci-dessous, vous pouvez vous rendre sur [tryfsharp.org](http://www.tryfsharp.org/Create) et le coller dans le [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop).
+
+```fsharp
+
+// Les commentaires d'une seule ligne commencent par un double slash
+(* Les commentaires multilignes utilise les paires (* . . . *)
+
+-fin du commentaire multilignes- *)
+
+// ================================================
+// Syntaxe de base
+// ================================================
+
+// ------ "Variables" (mais pas vraiment) ------
+// Le mot clé "let" définit une valeur (immutable)
+let myInt = 5
+let myFloat = 3.14
+let myString = "hello" // Notons qu'aucun type n'est nécessaire
+
+// ------ Listes ------
+let twoToFive = [2;3;4;5] // Les crochets créent une liste avec
+ // des point-virgules pour délimiteurs.
+let oneToFive = 1 :: twoToFive // :: crée une liste avec un nouvel élément
+// Le résultat est [1;2;3;4;5]
+let zeroToFive = [0;1] @ twoToFive // @ concatène deux listes
+
+// IMPORTANT: les virgules ne sont jamais utilisées pour délimiter,
+// seulement les point-virgules !
+
+// ------ Fonctions ------
+// Le mot clé "let" définit aussi le nom d'une fonction.
+let square x = x * x // Notons qu'aucune parenthèse n'est utilisée.
+square 3 // Maitenant, exécutons la fonction.
+ // Encore une fois, aucune parenthèse.
+
+let add x y = x + y // N'utilisez pas add (x,y) ! Cela signifie
+ // quelque chose de complètement différent.
+add 2 3 // À présent, exécutons la fonction.
+
+// Pour définir une fonction sur plusieurs lignes, utilisons l'indentation.
+// Les point-virgules ne sont pas nécessaires.
+let evens list =
+ let isEven x = x%2 = 0 // Définit "isEven" comme une fonction imbriquée
+ List.filter isEven list // List.filter est une fonction de la librairie
+ // à deux paramètres: un fonction retournant un
+ // booléen et une liste sur laquelle travailler
+
+evens oneToFive // À présent, exécutons la fonction.
+
+// Vous pouvez utilisez les parenthèses pour clarifier.
+// Dans cet exemple, "map" est exécutée en première, avec deux arguments,
+// ensuite "sum" est exécutée sur le résultat.
+// Sans les parenthèses, "List.map" serait passé en argument à List.sum.
+let sumOfSquaresTo100 =
+ List.sum ( List.map square [1..100] )
+
+// Vous pouvez rediriger la sortie d'une fonction vers une autre avec "|>"
+// Rediriger des données est très commun en F#, comme avec les pipes UNIX.
+
+// Voici la même fonction sumOfSquares écrite en utilisant des pipes
+let sumOfSquaresTo100piped =
+ [1..100] |> List.map square |> List.sum // "square" est déclaré avant
+
+// Vous pouvez définir des lambdas (fonctions anonymes) grâce au mot clé "fun"
+let sumOfSquaresTo100withFun =
+ [1..100] |> List.map (fun x -> x*x) |> List.sum
+
+// En F#, il n'y a pas de mot clé "return". Une fonction retourne toujours
+// la valeur de la dernière expression utilisée.
+
+// ------ Pattern Matching ------
+// Match..with.. est une surcharge de la condition case/switch.
+let simplePatternMatch =
+ let x = "a"
+ match x with
+ | "a" -> printfn "x is a"
+ | "b" -> printfn "x is b"
+ | _ -> printfn "x is something else" // underscore correspond à tout le reste
+
+// F# n'autorise pas la valeur null par défaut -- vous devez utiliser le type Option
+// et ensuite faire correspondre le pattern.
+// Some(..) et None sont approximativement analogue à des wrappers de Nullable
+let validValue = Some(99)
+let invalidValue = None
+
+// Dans cet exemple, match..with trouve une correspondance à "Some" et à "None",
+// et affiche la valeur du "Some" en même temps.
+let optionPatternMatch input =
+ match input with
+ | Some i -> printfn "input is an int=%d" i
+ | None -> printfn "input is missing"
+
+optionPatternMatch validValue
+optionPatternMatch invalidValue
+
+// ------ Affichage ------
+// Les fonctions printf/printfn sont similaires aux fonctions
+// Console.Write/WriteLine de C#.
+printfn "Printing an int %i, a float %f, a bool %b" 1 2.0 true
+printfn "A string %s, and something generic %A" "hello" [1;2;3;4]
+
+// Il y a aussi les fonctions printf/sprintfn pour formater des données
+// en string. C'est similaire au String.Format de C#.
+
+// ================================================
+// Plus sur les fonctions
+// ================================================
+
+// F# est un véritable langage fonctionel -- les fonctions sont des
+// entités de premier ordre et peuvent êtres combinées facilement
+// pour créer des constructions puissantes
+
+// Les modules sont utilisés pour grouper des fonctions ensemble.
+// L'indentation est nécessaire pour chaque module imbriqué.
+module FunctionExamples =
+
+ // définit un simple fonction d'addition
+ let add x y = x + y
+
+ // usage basique d'une fonction
+ let a = add 1 2
+ printfn "1+2 = %i" a
+
+ // application partielle des paramètres (curryfication ou "currying" en anglais)
+ // add42 est une nouvelle fonction qui ne prend plus qu'un paramètre
+ let add42 = add 42
+ let b = add42 1
+ printfn "42+1 = %i" b
+
+ // composition pour combiner des fonctions
+ let add1 = add 1
+ let add2 = add 2
+ let add3 = add1 >> add2
+ let c = add3 7
+ printfn "3+7 = %i" c
+
+ // fonctions de premier ordre
+ [1..10] |> List.map add3 |> printfn "new list is %A"
+
+ // listes de fonction et plus
+ let add6 = [add1; add2; add3] |> List.reduce (>>)
+ let d = add6 7
+ printfn "1+2+3+7 = %i" d
+
+// ================================================
+// Listes et collections
+// ================================================
+
+// Il y a trois types de collection ordonnée :
+// * Les listes sont les collections immutables les plus basiques
+// * Les tableaux sont mutables et plus efficients
+// * Les séquences sont lazy et infinies (e.g. un enumerator)
+//
+// Des autres collections incluent des maps immutables et des sets
+// plus toutes les collections de .NET
+
+module ListExamples =
+
+ // les listes utilisent des crochets
+ let list1 = ["a";"b"]
+ let list2 = "c" :: list1 // :: pour un ajout au début
+ let list3 = list1 @ list2 // @ pour la concatenation
+
+ // Compréhensions des listes (aka générateurs)
+ let squares = [for i in 1..10 do yield i*i]
+
+ // Générateur de nombre premier
+ let rec sieve = function
+ | (p::xs) -> p :: sieve [ for x in xs do if x % p > 0 then yield x ]
+ | [] -> []
+ let primes = sieve [2..50]
+ printfn "%A" primes
+
+ // le pattern matching pour les listes
+ let listMatcher aList =
+ match aList with
+ | [] -> printfn "the list is empty"
+ | [first] -> printfn "the list has one element %A " first
+ | [first; second] -> printfn "list is %A and %A" first second
+ | _ -> printfn "the list has more than two elements"
+
+ listMatcher [1;2;3;4]
+ listMatcher [1;2]
+ listMatcher [1]
+ listMatcher []
+
+ // Récursion en utilisant les listes
+ let rec sum aList =
+ match aList with
+ | [] -> 0
+ | x::xs -> x + sum xs
+ sum [1..10]
+
+ // -----------------------------------------
+ // Fonctions de la librairie standard
+ // -----------------------------------------
+
+ // map
+ let add3 x = x + 3
+ [1..10] |> List.map add3
+
+ // filtre
+ let even x = x % 2 = 0
+ [1..10] |> List.filter even
+
+ // beaucoup plus -- se référer à la documentation
+
+module ArrayExamples =
+
+ // les tableaux utilisent les crochets avec des barres
+ let array1 = [| "a";"b" |]
+ let first = array1.[0] // accès à l'index en utilisant un point
+
+ // le pattern matching des tableaux est le même que celui des listes
+ let arrayMatcher aList =
+ match aList with
+ | [| |] -> printfn "the array is empty"
+ | [| first |] -> printfn "the array has one element %A " first
+ | [| first; second |] -> printfn "array is %A and %A" first second
+ | _ -> printfn "the array has more than two elements"
+
+ arrayMatcher [| 1;2;3;4 |]
+
+ // Fonctions de la librairie standard comme celles des listes
+ [| 1..10 |]
+ |> Array.map (fun i -> i+3)
+ |> Array.filter (fun i -> i%2 = 0)
+ |> Array.iter (printfn "value is %i. ")
+
+module SequenceExamples =
+
+ // Les séquences utilisent des accolades
+ let seq1 = seq { yield "a"; yield "b" }
+
+ // Les séquences peuvent utiliser yield et
+ // peuvent contenir des sous-sequences
+ let strange = seq {
+ // "yield" ajoute un élément
+ yield 1; yield 2;
+
+ // "yield!" ajoute une sous-sequence complète
+ yield! [5..10]
+ yield! seq {
+ for i in 1..10 do
+ if i%2 = 0 then yield i }}
+ // test
+ strange |> Seq.toList
+
+ // Les séquences peuvent être créées en utilisant "unfold"
+ // Voici la suite de fibonacci
+ let fib = Seq.unfold (fun (fst,snd) ->
+ Some(fst + snd, (snd, fst + snd))) (0,1)
+
+ // test
+ let fib10 = fib |> Seq.take 10 |> Seq.toList
+ printf "first 10 fibs are %A" fib10
+
+// ================================================
+// Types de données
+// ================================================
+
+module DataTypeExamples =
+
+ // Toutes les données sont immutables par défaut
+
+ // Les tuples sont de simple et rapide types anonymes
+ // -- Utilisons une virgule pour créer un tuple
+ let twoTuple = 1,2
+ let threeTuple = "a",2,true
+
+ // Pattern match pour déballer
+ let x,y = twoTuple // assigne x=1 y=2
+
+ // ------------------------------------
+ // Record types ont des champs nommés
+ // ------------------------------------
+
+ // On utilise "type" avec des accolades pour définir un type record
+ type Person = {First:string; Last:string}
+
+ // On utilise "let" avec des accolades pour créer un record (enregistrement)
+ let person1 = {First="John"; Last="Doe"}
+
+ // Pattern match pour déballer
+ let {First=first} = person1 // assigne first="john"
+
+ // ------------------------------------
+ // Union types (ou variants) ont un set (ensemble) de choix
+ // Un seul cas peut être valide à la fois.
+ // ------------------------------------
+
+ // On utilise "type" avec bar/pipe pour definir un union type
+ type Temp =
+ | DegreesC of float
+ | DegreesF of float
+
+ // On utilise un de ces choix pour en créér un
+ let temp1 = DegreesF 98.6
+ let temp2 = DegreesC 37.0
+
+ // Pattern match on all cases to unpack(?)
+ let printTemp = function
+ | DegreesC t -> printfn "%f degC" t
+ | DegreesF t -> printfn "%f degF" t
+
+ printTemp temp1
+ printTemp temp2
+
+ // ------------------------------------
+ // Types récursif
+ // ------------------------------------
+
+ // Les types peuvent être combinés récursivement de façon complexe
+ // sans avoir à créer des sous-classes
+ type Employee =
+ | Worker of Person
+ | Manager of Employee list
+
+ let jdoe = {First="John";Last="Doe"}
+ let worker = Worker jdoe
+
+ // ------------------------------------
+ // Modelling with types(?)
+ // ------------------------------------
+
+ // Les types union sont excellents pour modelling state without using flags(?)
+ type EmailAddress =
+ | ValidEmailAddress of string
+ | InvalidEmailAddress of string
+
+ let trySendEmail email =
+ match email with // utilisations du pattern matching
+ | ValidEmailAddress address -> () // envoyer
+ | InvalidEmailAddress address -> () // ne pas envoyer
+
+ // Combiner ensemble, les types union et les types record
+ // offrent une excellente fondation pour le domain driven design.
+ // Vous pouvez créer des centaines de petit types qui reflèteront fidèlement
+ // le domain.
+
+ type CartItem = { ProductCode: string; Qty: int }
+ type Payment = Payment of float
+ type ActiveCartData = { UnpaidItems: CartItem list }
+ type PaidCartData = { PaidItems: CartItem list; Payment: Payment}
+
+ type ShoppingCart =
+ | EmptyCart // aucune donnée
+ | ActiveCart of ActiveCartData
+ | PaidCart of PaidCartData
+
+ // ------------------------------------
+ // Comportement natif des types
+ // ------------------------------------
+
+ // Les types natifs ont un comportement "prêt-à-l'emploi" des plus utiles, sans code à ajouter.
+ // * Immutabilité
+ // * Pretty printing au debug
+ // * Egalité et comparaison
+ // * Sérialisation
+
+ // Le Pretty printing s'utilise avec %A
+ printfn "twoTuple=%A,\nPerson=%A,\nTemp=%A,\nEmployee=%A"
+ twoTuple person1 temp1 worker
+
+ // L'égalité et la comparaison sont innés
+ // Voici un exemple avec des cartes.
+ type Suit = Club | Diamond | Spade | Heart
+ type Rank = Two | Three | Four | Five | Six | Seven | Eight
+ | Nine | Ten | Jack | Queen | King | Ace
+
+ let hand = [ Club,Ace; Heart,Three; Heart,Ace;
+ Spade,Jack; Diamond,Two; Diamond,Ace ]
+
+ // tri
+ List.sort hand |> printfn "sorted hand is (low to high) %A"
+ List.max hand |> printfn "high card is %A"
+ List.min hand |> printfn "low card is %A"
+
+// ================================================
+// Les Active patterns
+// ================================================
+
+module ActivePatternExamples =
+
+ // F# a un type particulier de pattern matching nommé "active patterns"
+ // où le pattern peut être parsé ou détecté dynamiquement.
+
+ // "banana clips" est la syntaxe pour l'active patterns
+
+ // par exemple, on définit un "active" pattern pour correspondre à des types "character"...
+ 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
+ else Other
+
+ // ... et ensuite on l'utilise pour rendre la logique de parsing plus claire
+ let printChar ch =
+ match ch with
+ | Digit -> printfn "%c is a Digit" ch
+ | Letter -> printfn "%c is a Letter" ch
+ | Whitespace -> printfn "%c is a Whitespace" ch
+ | _ -> printfn "%c is something else" ch
+
+ // afficher une liste
+ ['a';'b';'1';' ';'-';'c'] |> List.iter printChar
+
+ // -----------------------------------------
+ // FizzBuzz en utilisant les active patterns
+ // -----------------------------------------
+
+ // Vous pouvez créer un partial matching patterns également
+ // On utilise just un underscore dans la définition, et on retourne Some si ça correspond.
+ let (|MultOf3|_|) i = if i % 3 = 0 then Some MultOf3 else None
+ let (|MultOf5|_|) i = if i % 5 = 0 then Some MultOf5 else None
+
+ // la fonction principale
+ let fizzBuzz i =
+ match i with
+ | MultOf3 & MultOf5 -> printf "FizzBuzz, "
+ | MultOf3 -> printf "Fizz, "
+ | MultOf5 -> printf "Buzz, "
+ | _ -> printf "%i, " i
+
+ // test
+ [1..20] |> List.iter fizzBuzz
+
+// ================================================
+// Concision
+// ================================================
+
+module AlgorithmExamples =
+
+ // F# a un haut ratio signal/bruit, permettant au code de se lire
+ // presque comme un véritable algorithme
+
+ // ------ Exemple: definir une fonction sumOfSquares ------
+ let sumOfSquares n =
+ [1..n] // 1) Prendre tous les nombres de 1 à n
+ |> List.map square // 2) Elever chacun d'entre eux au carré
+ |> List.sum // 3) Effectuer leur somme
+
+ // test
+ sumOfSquares 100 |> printfn "Sum of squares = %A"
+
+ // ------ Exemple: definir un fonction de tri ------
+ let rec sort list =
+ match list with
+ // Si la liste est vide
+ | [] ->
+ [] // on retourne une liste vide
+ // si la list n'est pas vide
+ | firstElem::otherElements -> // on prend le premier élément
+ let smallerElements = // on extrait les éléments plus petits
+ otherElements // on prend les restants
+ |> List.filter (fun e -> e < firstElem)
+ |> sort // et on les trie
+ let largerElements = // on extrait les plus grands
+ otherElements // de ceux qui restent
+ |> List.filter (fun e -> e >= firstElem)
+ |> sort // et on les trie
+ // On combine les 3 morceaux dans une nouvelle liste que l'on retourne
+ List.concat [smallerElements; [firstElem]; largerElements]
+
+ // test
+ sort [1;5;23;18;9;1;3] |> printfn "Sorted = %A"
+
+// ================================================
+// Code Asynchrone
+// ================================================
+
+module AsyncExample =
+
+ // F# inclus des fonctionnalités pour aider avec le code asynchrone
+ // sans rencontrer la "pyramid of doom"
+ //
+ // L'exemple suivant télécharge une séquence de page web en parallèle.
+
+ open System.Net
+ open System
+ open System.IO
+ open Microsoft.FSharp.Control.CommonExtensions
+
+ // Récupérer le contenu d'une URL de manière asynchrone
+ let fetchUrlAsync url =
+ async { // Le mot clé "async" et les accolades
+ // créent un objet "asynchrone"
+ let req = WebRequest.Create(Uri(url))
+ use! resp = req.AsyncGetResponse()
+ // use! est un assignement asynchrone
+ use stream = resp.GetResponseStream()
+ // "use" déclenche automatiquement close()
+ // sur les ressources à la fin du scope
+ use reader = new IO.StreamReader(stream)
+ let html = reader.ReadToEnd()
+ printfn "finished downloading %s" url
+ }
+
+ // une liste des sites à rapporter
+ let sites = ["http://www.bing.com";
+ "http://www.google.com";
+ "http://www.microsoft.com";
+ "http://www.amazon.com";
+ "http://www.yahoo.com"]
+
+ // C'est parti!
+ sites
+ |> List.map fetchUrlAsync // créez une liste de tâche asynchrone
+ |> Async.Parallel // dites aux tâches de tourner en parallèle
+ |> Async.RunSynchronously // démarrez les!
+
+// ================================================
+// .NET compatabilité
+// ================================================
+
+module NetCompatibilityExamples =
+
+ // F# peut réaliser presque tout ce que C# peut faire, et il s'intègre
+ // parfaitement avec les librairies .NET ou Mono.
+
+ // ------- Travaillez avec les fonctions des librairies existantes -------
+
+ let (i1success,i1) = System.Int32.TryParse("123");
+ if i1success then printfn "parsed as %i" i1 else printfn "parse failed"
+
+ // ------- Implémentez des interfaces à la volée! -------
+
+ // Créer un nouvel objet qui implémente IDisposable
+ let makeResource name =
+ { new System.IDisposable
+ with member this.Dispose() = printfn "%s disposed" name }
+
+ let useAndDisposeResources =
+ use r1 = makeResource "first resource"
+ printfn "using first resource"
+ for i in [1..3] do
+ let resourceName = sprintf "\tinner resource %d" i
+ use temp = makeResource resourceName
+ printfn "\tdo something with %s" resourceName
+ use r2 = makeResource "second resource"
+ printfn "using second resource"
+ printfn "done."
+
+ // ------- Code orienté objet -------
+
+ // F# est aussi un véritable language OO.
+ // Il supporte les classes, l'héritage, les méthodes virtuelles, etc.
+
+ // interface avec type générique
+ type IEnumerator<'a> =
+ abstract member Current : 'a
+ abstract MoveNext : unit -> bool
+
+ // Classe de base abstraite avec méthodes virtuelles
+ [<AbstractClass>]
+ type Shape() =
+ // propriétés en lecture seule
+ abstract member Width : int with get
+ abstract member Height : int with get
+ // méthode non-virtuelle
+ member this.BoundingArea = this.Height * this.Width
+ // méthode virtuelle avec implémentation de la classe de base
+ abstract member Print : unit -> unit
+ default this.Print () = printfn "I'm a shape"
+
+ // classe concrète qui hérite de sa classe de base et surcharge
+ type Rectangle(x:int, y:int) =
+ inherit Shape()
+ override this.Width = x
+ override this.Height = y
+ override this.Print () = printfn "I'm a Rectangle"
+
+ // test
+ let r = Rectangle(2,3)
+ printfn "The width is %i" r.Width
+ printfn "The area is %i" r.BoundingArea
+ r.Print()
+
+ // ------- extension de méthode -------
+
+ // Juste comme en C#, F# peut étendre des classes existantes avec des extensions de méthode.
+ type System.String with
+ member this.StartsWithA = this.StartsWith "A"
+
+ // test
+ let s = "Alice"
+ printfn "'%s' starts with an 'A' = %A" s s.StartsWithA
+
+ // ------- événements -------
+
+ type MyButton() =
+ let clickEvent = new Event<_>()
+
+ [<CLIEvent>]
+ member this.OnClick = clickEvent.Publish
+
+ member this.TestEvent(arg) =
+ clickEvent.Trigger(this, arg)
+
+ // test
+ let myButton = new MyButton()
+ myButton.OnClick.Add(fun (sender, arg) ->
+ printfn "Click event with arg=%O" arg)
+
+ myButton.TestEvent("Hello World!")
+
+```
+
+## Plus d'information
+
+Pour plus de démonstration de F#, rendez-vous sur le site [Try F#](http://www.tryfsharp.org/Learn), ou suivez la série [why use F#](http://fsharpforfunandprofit.com/why-use-fsharp/).
+
+Apprenez en davantage à propose de F# sur [fsharp.org](http://fsharp.org/).
diff --git a/fr-fr/haml-fr.html.markdown b/fr-fr/haml-fr.html.markdown
index 24be8bf9..f5d096fe 100644
--- a/fr-fr/haml-fr.html.markdown
+++ b/fr-fr/haml-fr.html.markdown
@@ -1,6 +1,6 @@
---
language: haml
-filename: learnhaml.haml
+filename: learnhaml-fr.haml
contributors:
- ["Simon Neveu", "https://github.com/sneveu"]
- ["Thibault", "https://github.com/iTech-"]
diff --git a/fr-fr/haskell.html.markdown b/fr-fr/haskell-fr.html.markdown
index d9d3151f..a34dc098 100644
--- a/fr-fr/haskell.html.markdown
+++ b/fr-fr/haskell-fr.html.markdown
@@ -66,7 +66,7 @@ not False -- True
----------------------------------------------------
--- Listes et tuples
+-- 2. Listes et tuples
----------------------------------------------------
-- Tous les éléments d'une liste doit avoir le même type.
diff --git a/fr-fr/java-fr.html.markdown b/fr-fr/java-fr.html.markdown
new file mode 100644
index 00000000..d6c68343
--- /dev/null
+++ b/fr-fr/java-fr.html.markdown
@@ -0,0 +1,939 @@
+---
+language: java
+contributors:
+ - ["Jake Prather", "https://github.com/JakeHP"]
+ - ["Jakukyo Friel", "https://weakish.github.io"]
+ - ["Madison Dickson", "https://github.com/mix3d"]
+ - ["Simon Morgan", "https://sjm.io/"]
+ - ["Zachary Ferguson", "https://github.com/zfergus2"]
+ - ["Cameron Schermerhorn", "https://github.com/cschermerhorn"]
+ - ["Rachel Stiyer", "https://github.com/rstiyer"]
+ - ["Michael Dähnert", "https://github.com/JaXt0r"]
+ - ["Rob Rose", "https://github.com/RobRoseKnows"]
+ - ["Sean Nam", "https://github.com/seannam"]
+filename: java-fr.java
+translators:
+ - ['Mathieu Gemard', 'https://github.com/mgemard']
+lang: fr-fr
+---
+Java est un langage orienté objet, concurrent et très facilement portable. Java
+est inspiré du C++ mais ne reprend pas tous les concepts comme par exemple les
+pointeurs et en ajoute de nouveaux comme les interfaces.
+[En savoir plus.](https://fr.wikipedia.org/wiki/Java_(langage))
+
+```java
+// Les commentaires sur une seule ligne commencent par //
+
+/*
+Les commentaires sur plusieurs lignes ressemblent à ceci.
+*/
+
+/**
+ * Les commentaires de la JavaDoc ressemblent à ceci. Ils sont utilisés pour
+ * décrire la classe et ses différents attributs.
+ * Attributs principaux:
+ *
+ * @author Nom (et information de contact comme l'email) de(s) auteur(s).
+ * @version Version actuelle du programme.
+ * @since Date à laquelle cette partie du programme a été ajouté.
+ * @param Décrit les différents paramètres pour d'une méthode.
+ * @return Décrit le retour de la méthode.
+ * @deprecated Indique si le code est déprécié ou ne doit plus être utilisé.
+ * @see Lien vers une autre partie de la documentation.
+*/
+
+// Importe la classe ArrayList qui se trouve dans le package java.util
+import java.util.ArrayList;
+// Importe toutes les classes qui se trouvent dans le package java.security
+import java.security.*;
+
+// Chaque fichier .java doit contenir une classe public portant le même nom que
+le fichier.
+public class JavaFr {
+
+ // Pour exécuter un programme Java, celui-ci doit posséder une méthode main
+ // qui fournir un point d'entrée.
+ public static void main(String[] args) {
+
+ ///////////////////////////////////////
+ // Entrée/Sortie
+ ///////////////////////////////////////
+
+ /*
+ * Sortie
+ */
+
+ // Utilisez System.out.println() pour afficher un texte dans la console.
+ System.out.println("Hello World!");
+ System.out.println(
+ "Integer: " + 10 +
+ " Double: " + 3.14 +
+ " Boolean: " + true);
+
+ // Pour afficher sans retour à la ligne, on utilise System.out.print().
+ System.out.print("Hello ");
+ System.out.print("World");
+
+ // Utilisez System.out.printf() pour formatter les données à afficher.
+ System.out.printf("pi = %.5f", Math.PI); // => pi = 3.14159
+
+ /*
+ * Entrée
+ */
+
+ // Utilisez Scanner pour lire l'entrée
+ // Nécessite: import java.util.Scanner;
+ Scanner scanner = new Scanner(System.in);
+
+ // Lire une chaîne de caractères
+ String name = scanner.next();
+
+ // Lire un byte
+ byte numByte = scanner.nextByte();
+
+ // Lire un entier
+ int numInt = scanner.nextInt();
+
+ // Lire une entrée de type long
+ float numFloat = scanner.nextFloat();
+
+ // Lire une entrée de type double
+ double numDouble = scanner.nextDouble();
+
+ // Lire une entrée de type boolean
+ boolean bool = scanner.nextBoolean();
+
+ ///////////////////////////////////////
+ // Variables
+ ///////////////////////////////////////
+
+ /*
+ * Déclaration de variable
+ */
+ // Déclarez une variable avec la forme <type> <name>
+ int fooInt;
+ // Declarez plusieurs variables du même type <type> <name1>, <name2>,
+ // <name3>
+ int fooInt1, fooInt2, fooInt3;
+
+ /*
+ * Initialisation de variable
+ */
+
+ // Initialisez une variable sous la forme <type> <name> = <val>
+ int barInt = 1;
+ // Initialisez plusieurs variables du même type et avec la même valeur
+ // sous la forme
+ // <type> <name1>, <name2>, <name3>
+ // <name1> = <name2> = <name3> = <val>
+ int barInt1, barInt2, barInt3;
+ barInt1 = barInt2 = barInt3 = 1;
+
+ /*
+ * Types de variable
+ */
+ // byte - Entier signé utilisant la notation en complément à deux sur
+ // 8 bits
+ // (-128 <= byte <= 127)
+ byte fooByte = 100;
+
+ // Si vous voulez interpréter un byte en entier non-signé, cette simple
+ // opération peut vous aider
+ int unsignedIntLessThan256 = 0xff & fooByte;
+ // cela contraste avec une conversion qui peut être négative.
+ int signedInt = (int) fooByte;
+
+ // short - Entier signé utilisant la notation en complément à deux sur
+ // 16 bits
+ // (-32,768 <= short <= 32,767)
+ short fooShort = 10000;
+
+ // int - Entier signé utilisant la notation en complément à deux sur
+ // 32 bits
+ // (-2,147,483,648 <= int <= 2,147,483,647)
+ int bazInt = 1;
+
+ // long - Entier signé utilisant la notation en complément à deux sur
+ // 64 bits
+ // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ long fooLong = 100000L;
+ // L est utilisé pour indiquer que la variable est de type long;
+ // le nombre serait traité comme un int sans le L
+
+ // Note: byte, short, int et long sont signés. Ils peuvent avoir des
+ // valeurs positives et négatives.
+ // Il n'existe pas de variantes non-signées.
+ // char, toutefois, est non-signé sur 16 bits
+
+ // float - nombre à virgule flottante selon la norme IEEE 754 utilisant
+ // le format simple précision sur 32 bits
+ // 2^-149 <= float <= (2-2^-23) * 2^127
+ float fooFloat = 234.5f;
+ // f ou F sont utilisés pour indiquer que la variable est de type float;
+ // autrement elle serait traitée comme un double.
+
+ // double - nombre à virgule flottante selon la norme IEEE 754 utilisant
+ // le format double précision sur 64 bits
+ // 2^-1074 <= x <= (2-2^-52) * 2^1023
+ double fooDouble = 123.4;
+
+ // boolean - vrai & faux
+ boolean fooBoolean = true;
+ boolean barBoolean = false;
+
+ // char - un caractère Unicode sur 16 bits
+ char fooChar = 'A';
+
+ // les variables final ne peuvent pas être réassignés à un autre objet,
+ final int HOURS_I_WORK_PER_WEEK = 9001;
+ // mais ils peuvent être initialisés plus tard.
+ final double E;
+ E = 2.71828;
+
+ // BigInteger - entier immuable de taille arbitraire
+ //
+ // BigInteger est un type de donné qui autorise les développeurs à
+ // manipuler des entiers au delà de 64 bits. Les entiers sont stockés
+ // dans un tableau de bytes et sont manipulés grâce à des functions
+ // de la classe BigIntger
+ //
+ // BigInteger peut être initialiser en utilisant un tableau de bytes ou
+ // une chaîne de caractère.
+ BigInteger fooBigInteger = new BigInteger(fooByteArray);
+
+ // BigDecimal - entier immuable et positif de taille arbitraire
+ //
+ // BigDecimal comprend deux parties: une entier de taille arbitraire
+ // (BigInteger) et un entier de 32 bits représantant la position de la
+ // virgule.
+ //
+ // BigDecimal donne aux développeurs un contrôle total pour l'arrondie
+ // à la décimale. Il est recommandé de l'utiliser pour les valeurs
+ // monétaires et pour les cas où la value exacte de l'arondie à la
+ // décimale est requis.
+ //
+ // BigInteger peut être initialiser en utilisant un int, long, double ou
+ // String.
+ // On peut également utiliser un BigInteger et un int pour la
+ // position de la virgule.
+ BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt);
+
+ // Sachez que la création d'un BigDecimal avec un float ou
+ // un double prendra en compte l'inexactitude des représention en float
+ // ou double.
+ // Préférez String pour une représention exacte.
+ BigDecimal tenCents = new BigDecimal("0.1");
+
+ // String - Chaîne de caractères
+ String fooString = "My String Is Here!";
+
+ // \n est un caractère d'échappement qui indique une nouvelle ligne
+ String barString = "Printing on a new line?\nNo Problem!";
+ // \t est un caractère d'échappement qui indique une tabulation
+ String bazString = "Do you want to add a tab?\tNo Problem!";
+ System.out.println(fooString);
+ System.out.println(barString);
+ System.out.println(bazString);
+
+ // Construction de chaînes de caractères
+ // #1 - avec l'opérateur +
+ // C'est la manière la plus simple et optimisé par le compilateur
+ String plusConcatenated = "Strings can " + "be concatenated " + "via + operator.";
+ System.out.println(plusConcatenated);
+ // Affiche: Strings can be concatenated via + operator.
+
+ // #2 - avec StringBuilder
+ // Cette méthode ne nécessite pas d'objet String intermédiaire. Elle
+ // stocke juste les différentes chaînes de caractères et les assemble
+ // lorsque la méthode toString() est appelée.
+ // Attention: Cette classe n'est pas thread-safe (l'objet ne peut pas être partagé
+ // entre les threads). Une alternative
+ // (avec un impact sur les performances) thread-safe est d'utiliser la
+ // classe StringBuffer.
+ StringBuilder builderConcatenated = new StringBuilder();
+ builderConcatenated.append("You ");
+ builderConcatenated.append("can use ");
+ builderConcatenated.append("the StringBuilder class.");
+ System.out.println(builderConcatenated.toString()); // only now is the string built
+ // Affiche: You can use the StringBuilder class.
+
+ // StringBuffer est efficace quand la chaîne de caractères n'est pas
+ // utilisée avec la fin de sa construction.
+ StringBuilder stringBuilder = new StringBuilder();
+ String inefficientString = "";
+ for (int i = 0 ; i < 10; i++) {
+ stringBuilder.append(i).append(" ");
+ inefficientString += i + " ";
+ }
+ System.out.println(inefficientString);
+ System.out.println(stringBuilder.toString());
+ // inefficientString est moins performant car une chaîne de caractères
+ // est créée à chaque itération de la boucle.
+ // Les concaténations avec + sont compilés en un StringBuilder et
+ // toString().
+ // Evitez les concaténations de string dans les boucles.
+
+ // #3 - avec la méthode format() de la classe String.
+ // Une autre alternative. Rapide et lisible.
+ String.format("%s may prefer %s.", "Or you", "String.format()");
+ // Affiche: Or you may prefer String.format().
+
+ // Tableau
+ // La taille du tableau doit être précisée à l'instantiation
+ // Les formats suivant sont possibles pour déclarer un tableau
+ // <datatype>[] <var name> = new <datatype>[<array size>];
+ // <datatype> <var name>[] = new <datatype>[<array size>];
+ int[] intArray = new int[10];
+ String[] stringArray = new String[1];
+ boolean boolArray[] = new boolean[100];
+
+ // Une autre manière de déclarer et initialiser un tableau
+ int[] y = {9000, 1000, 1337};
+ String names[] = {"Bob", "John", "Fred", "Juan Pedro"};
+ boolean bools[] = {true, false, false};
+
+ // Accéder à un élément
+ System.out.println("intArray @ 0: " + intArray[0]);
+
+ // Les tableaus commencent à 0 et sont muables
+ intArray[1] = 1;
+ System.out.println("intArray @ 1: " + intArray[1]); // => 1
+
+ // Les autres types de donnés utiles sont
+ // ArrayList - Identique aux tableaux mais avec plus de fonctionnalités
+ // et de taille muable.
+ // LinkedList - Implémentation de listes doublement chaînées. Toutes Les
+ // opérations éffectuées le sont comme attendue pour une
+ // liste doublement chaînée.
+ // Map - Une collection d'objets qui fait correspondre une valeur à une
+ // clé. Map est une interface et ne peut pas être instantiée. Le
+ // type des clés et des valeurs doit être précisés à
+ // l'instantiation. Chaque clé doit correspondre à une seule
+ // valeur et chaque clé doit être unique (pas de clés dupliquées).
+ // HashMap - Cette classe utilise une table de hachage pour implémenter
+ // l'interface Map. Cela garantie que le temps d'exécution des
+ // opérations basiques, comme get (récuper une valeur) et
+ // insert (insérer une valeur), reste constant quelque soit la
+ // la taille.
+ // TreeMap - Cette classe utilise une structure en arbre et est
+ // ordonnée. Elle implémente un arbre bicolore (ou arbre rouge
+ // et noir) et ordonne les éléments en se basant sur la clé ou
+ // en utilisant un comparateur fournit à la création.
+
+ ///////////////////////////////////////
+ // Opérateurs
+ ///////////////////////////////////////
+ System.out.println("\n->Operators");
+
+ int i1 = 1, i2 = 2; // Raccourcis pour des déclarations multiples
+
+ // L'arithmétique
+ System.out.println("1+2 = " + (i1 + i2)); // => 3
+ System.out.println("2-1 = " + (i2 - i1)); // => 1
+ System.out.println("2*1 = " + (i2 * i1)); // => 2
+ System.out.println("1/2 = " + (i1 / i2)); // => 0 (int/int returns int)
+ System.out.println("1/2 = " + (i1 / (double)i2)); // => 0.5
+
+ // Le modulo
+ System.out.println("11%3 = "+(11 % 3)); // => 2
+
+ // Opérateurs de comparaison
+ System.out.println("3 == 2? " + (3 == 2)); // => faux
+ System.out.println("3 != 2? " + (3 != 2)); // => vrai
+ System.out.println("3 > 2? " + (3 > 2)); // => vrai
+ System.out.println("3 < 2? " + (3 < 2)); // => faux
+ System.out.println("2 <= 2? " + (2 <= 2)); // => vrai
+ System.out.println("2 >= 2? " + (2 >= 2)); // => vrai
+
+ // Opérateurs boolean
+ System.out.println("3 > 2 && 2 > 3? " + ((3 > 2) && (2 > 3))); // => false
+ System.out.println("3 > 2 || 2 > 3? " + ((3 > 2) || (2 > 3))); // => true
+ System.out.println("!(3 == 2)? " + (!(3 == 2))); // => true
+
+ // Opérateurs sur les bits
+ /*
+ ~ Complément à un
+ << Décalage des bits vers la gauche
+ >> Décalage des bits vers la droite, le signe est conservé
+ >>> Décalage des bits vers la droite, zéro est utilisé pour les bits
+ les plus à gauche
+ & Opérateur ET
+ ^ Opérateur OU exlusif
+ | Opérateur OU inclusif
+ */
+
+ // Opérateurs d'incrémentation
+ int i = 0;
+ System.out.println("\n->Inc/Dec-rementation");
+ // Les opérateurs ++ et -- incrémentent et décrémentent respectivement
+ // de 1.
+ // S'ils sont placés avant la variable, ils incrémentent la variable puis
+ // retournent la valeur. Placés après la varible, ils retournent la variable
+ // puis l'incrémentent.
+ System.out.println(i++); // i = 1, affiche 0 (pré-incrément)
+ System.out.println(++i); // i = 2, affiche 2 (post-incrément)
+ System.out.println(i--); // i = 1, affiche 2 (post-incrément)
+ System.out.println(--i); // i = 0, affiche 0 (pré-incrément)
+
+ ///////////////////////////////////////
+ // Structures de contôles
+ ///////////////////////////////////////
+ System.out.println("\n->Control Structures");
+
+ // Les instructions conditionnelle sont identiques aux langage C
+ int j = 10;
+ if (j == 10) {
+ System.out.println("I get printed");
+ } else if (j > 10) {
+ System.out.println("I don't");
+ } else {
+ System.out.println("I also don't");
+ }
+
+ // Bouble while
+ int fooWhile = 0;
+ while(fooWhile < 100) {
+ System.out.println(fooWhile);
+ // Incrémente le compteur
+ // Itéré 100 fois, fooWhile 0,1,2...99
+ fooWhile++;
+ }
+ System.out.println("fooWhile Value: " + fooWhile);
+
+ // Boucle do-while
+ int fooDoWhile = 0;
+ do {
+ System.out.println(fooDoWhile);
+ // Incrémente le compteur
+ // Itéré 99 fois, fooDoWhile 0->99
+ fooDoWhile++;
+ } while(fooDoWhile < 100);
+ System.out.println("fooDoWhile Value: " + fooDoWhile);
+
+ // Boucle for
+ // De la forme for(<start_statement>; <conditional>; <step>)
+ for (int fooFor = 0; fooFor < 10; fooFor++) {
+ System.out.println(fooFor);
+ // Itéré 10 fois, fooFor 0->9
+ }
+ System.out.println("fooFor Value: " + fooFor);
+
+ // Fin d'une boucle for avec un label
+ outer:
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ if (i == 5 && j ==5) {
+ break outer;
+ // termine l'itération de la boucle englobante avec le label outer
+ }
+ }
+ }
+
+ // Boucle for-each
+ // La boucle for est également capable d'itérer aussi bien sur un
+ // tableau que sur des objets qui implémentent l'interface Iterable.
+ int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ // De la forme: for (<object> : <iterable>)
+ // Lu comme: "Pour chaque élément du tableau"
+ // note: le type doit correspondre à celui de l'objet itérable
+ for (int bar : fooList) {
+ System.out.println(bar);
+ //Itère 9 fois et affiche les chiffres de 1 à 9
+ }
+
+ // Le switch-case
+ // Un switch fonctionne avec les données de type byte, short, char et
+ // int.
+ // On peut également utiliser le type Enum, la classe String et les
+ // classes spéciales qui englobent les types primitifs (Character, Byte,
+ // Short et Integer).
+ // Depuis Java 7, on peut utiliser le type String.
+ int month = 3;
+ String monthString;
+ switch (month) {
+ case 1: monthString = "January";
+ break;
+ case 2: monthString = "February";
+ break;
+ case 3: monthString = "March";
+ break;
+ default: monthString = "Some other month";
+ break;
+ }
+ System.out.println("Switch Case Result: " + monthString);
+
+ // try-with-resources (Java 7+)
+ // Le mécanisme de gestion des erreurs try-catch-finally peut être
+ // utilisé mais depuis Java 7 il est également possible d'utiliser
+ // try-with-ressources.
+ // try-with-resources simplifie try-catch-finally en fermant
+ // automatiquement les ressources
+
+ // Pour utiliser un try-with-resources, il suffit d'inclure l'instance
+ // d'une classe qui implémente l'interface java.lang.AutoCloseable
+ try (BufferedReader br = new BufferedReader(new FileReader("foo.txt"))) {
+ // Ici, vous pouvez essayer de faire quelque chose qui lance une
+ // exception.
+ System.out.println(br.readLine());
+ // Avec Java 7, la ressource sera toujours fermé, même si elle lance
+ // une exception.
+ } catch (Exception ex) {
+ // La ressource sera fermé avant que le catch s'exécute.
+ System.out.println("readLine() failed.");
+ }
+ // Il n'y a pas besoin de finally dans ce cas, l'objet BufferedReader
+ // sera déjà fermé. Cela peut être utile dans certains cas spécifiques
+ // où le code contenu dans finally ne serait pas exécuté.
+ // Consulter la documention Oracle pour en savoir plus (en anglais) :
+ // https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
+
+
+ // Expression ternaire
+ // Vous pouvez utiliser l'opérateur ternaire '?' pour faire un
+ // assignement rapide avec une condition logique.
+ // Il faut lire "Si la (condition) est vraie alors utiliser la
+ // <première valeur> sinon utilisez la <deuxième valeur>".
+ int foo = 5;
+ String bar = (foo < 10) ? "A" : "B";
+ System.out.println("bar : " + bar); // Affiche "bar : A", car la condition est vraie
+ // Ou alors plus simplement
+ System.out.println("bar : " + (foo < 10 ? "A" : "B")); // Affiche également "bar : A"
+
+ ////////////////////////////////////////
+ // Conversion de type
+ ////////////////////////////////////////
+
+ // Autoboxing
+
+ // Convertir un objet String en un objet Integer
+ Integer.parseInt("123"); // retourne un le type primitif int de 123
+
+ // Convert Integer To String
+ Integer.toString(123); // retourne un object String correspondant à"123"
+
+ // Pour les autres conversions, référer vous aux classes suivantes:
+ // Double
+ // Long
+ // String
+
+ ///////////////////////////////////////
+ // Classes et fonctions
+ ///////////////////////////////////////
+
+ System.out.println("\n->Classes & Functions");
+
+ // (voir plus loin pour la définition de la classe Bicycle)
+
+ // Utilisez new pour instancier une classe
+ Bicycle trek = new Bicycle();
+
+ // Pour appeler une méthode de l'objet
+ trek.speedUp(3); // !! Il est conseillé de passer par une méthode pour
+ // changer la valeur d'une variable.
+ trek.setCadence(100);
+
+ // toString retourne une représentation de l'objet en chaîne de caractères.
+ System.out.println("trek info: " + trek.toString());
+
+ // Initialisation avec double accolades
+ // Le langage Java ne permet pas de créer des collections statiques d'une
+ // manière simple. Généralement, on utilise la forme suivante:
+ private static final Set<String> COUNTRIES = new HashSet<String>();
+ static {
+ COUNTRIES.add("DENMARK");
+ COUNTRIES.add("SWEDEN");
+ COUNTRIES.add("FINLAND");
+ }
+
+ // Mais on peut le faire d'une manière plus habile, dite initialisation
+ // avec double semi-colonnes
+ private static final Set<String> COUNTRIES = new HashSet<String>() {{
+ add("DENMARK");
+ add("SWEDEN");
+ add("FINLAND");
+ }}
+
+ // La première semi-colonne crée une classe anonyme et la deuxième est
+ // un bloc d'initialisation du bloc. Ce dernier est appelé lorsque Copyright (c)
+ // classe anonyme est crée. Cela ne fonctionne pas uniquement pour les
+ // collections mais également pour toutes les classes n'étant pas
+ // déclarées comme final.
+
+ } // Fin de la méthode main
+} // Fin de la class JavaFr
+
+// Vous pouvez inclure des classes qui ne sont pas publics dans un fichier Java.
+// Cependant, il est préférable de séparer les
+// classes dans des fichiers différents.
+
+// Syntaxe de déclaration des classes:
+// <public/private/protected> class <Nom de la classe> {
+// // Les attributs, les constructeurs et les méthodes de la classe vont ici.
+// // Les functions de classes sont appelées méthode.
+// }
+
+class Bicycle {
+
+ // Attributs et variables de la classe Bicycle
+ public int cadence; // Public: Peut être accesible depuis n'importe où
+ private int speed; // Private: Accisible depuis la classe
+ protected int gear; // Protected: Accisible depuis la classe et ses sous-
+ // classes
+ String name; // default: Uniquement accesible depuis ce package
+ static String className; // Variable de classe static
+
+ // Bloc static
+ // Java n'a pas d'implémentation pour les constructeurs statiques mais
+ // possède le bloc static qui peut être utilisé pour initialiser les
+ // variables de classe.
+ // Ce bloc sera appelé lorsque la classe sera chargée.
+ static {
+ className = "Bicycle";
+ }
+
+ // Les constructeurs sont un moyen de créer les classe
+ // Ceci est le constructeur de la classe Bicycle
+ public Bicycle() {
+ // Vous pouvez aussie appeler un autre constructeur. Par exemple en
+ // appelant le constructeur de la classe mère (voir héritage):
+ // this(1, 50, 5, "Bontrager");
+ gear = 1;
+ cadence = 50;
+ speed = 5;
+ name = "Bontrager";
+ }
+ // Le constructeur peut prendre plusieurs arguments
+ public Bicycle(int startCadence, int startSpeed, int startGear,
+ String name) {
+ this.gear = startGear;
+ this.cadence = startCadence;
+ this.speed = startSpeed;
+ this.name = name;
+ }
+
+ // Syntaxe d'une méthode :
+ // <public/private/protected> <type de retour> <nom de la fonction>(
+ // <arguments>)
+
+ // Les classes Java possèdent souvent des accesseurs (getters) et mutateurs
+ // (setters) pour leurs attributs.
+
+ public int getCadence() {
+ return cadence;
+ }
+
+ // Les méthodes void ne retourne aucune valeur
+ public void setCadence(int newValue) {
+ cadence = newValue;
+ }
+ public void setGear(int newValue) {
+ gear = newValue;
+ }
+ public void speedUp(int increment) {
+ speed += increment;
+ }
+ public void slowDown(int decrement) {
+ speed -= decrement;
+ }
+ public void setName(String newName) {
+ name = newName;
+ }
+ public String getName() {
+ return name;
+ }
+
+ // Méthode pour afficher la valeur des attributs de l'objet. @Override est
+ // une annotation (voir plus loin).
+ @Override //On dit ici qu'on remplace la méthode de la classe Objet.
+ public String toString() {
+ return "gear: " + gear + " cadence: " + cadence + " speed: " + speed +
+ " name: " + name;
+ }
+} // Fin de la classe Bicycle
+
+// PennyFarthing est une sous-classe de Bicycle
+class PennyFarthing extends Bicycle {
+ // (Les Penny Farthings sont des bicyclette avec une grande roue avant.
+ // Il n'y a pas de roue libre, le cycliste est obligé de pédaler en
+ // permanence.)
+
+ public PennyFarthing(int startCadence, int startSpeed) {
+ // Appelez le constructeur parent avec la méthode super()
+ super(startCadence, startSpeed, 0, "PennyFarthing");
+ }
+
+ // Ici nous modifions la méthode setGear() de la classe mère. Il faut donc
+ // utiliser l'annotation @Overide. Pour en savoir plus sur les annotations,
+ // consulter la documention officiel (en anglais) :
+ // out: http://docs.oracle.com/javase/tutorial/java/annotations/
+ @Override
+ public void setGear(int gear) {
+ this.gear = 0;
+ }
+}
+
+// Polymorphisme (cast d'objets)
+// Comme la classe PennyFarthing héritent de la classe Bicycle, on peut dire
+// qu'un PennyFarthing est un Bicycle (un vélo en anglais) et écrire :
+// Bicycle bicycle = new PennyFarthing();
+// Le polymorphisme est la capacité d'un objet de se faire passer pour un autre.
+// Vous pouvez consulter la documentation Oracle pour plus de détails et
+// concepts (en anglais) :
+// https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
+
+// Interfaces
+// Déclaration d'une interface
+// <niveau d'accès> interface <nom de l'interface> extends <nom de l'interface
+// mère> {
+// // Constantes
+// // Délaration des méthodes
+// }
+
+// Exemple - Toute nourriture peut être mangée et digégée différemment
+// L'interface Edible (traduction : comestible) décrit l'action de manger
+public interface Edible {
+ public void eat(); // Toute classe qui implémente cette interface doit
+ // implémenter cette méthode
+}
+
+// L'interface Digestible décrit l'action de digérer
+public interface Digestible {
+ public void digest();
+ // Depuis Java 8, les interfaces peuvent avoir des méthodes par défaut.
+ public void defaultMethod() {
+ System.out.println("Hi from default method ...");
+ }
+}
+
+// On peut maintenant créer une classe qui implémente chacune de ces interfaces.
+public class Fruit implements Edible, Digestible {
+ @Override
+ public void eat() {
+ // ...
+ }
+
+ @Override
+ public void digest() {
+ // ...
+ }
+}
+
+// En Java, on peut hériter uniquement d'une classe mais on peut implémenter
+// plusieurs interfaces:
+public class ExampleClass extends ExampleClassParent implements InterfaceOne,
+ InterfaceTwo {
+ @Override
+ public void InterfaceOneMethod() {
+ }
+
+ @Override
+ public void InterfaceTwoMethod() {
+ }
+
+}
+
+// Classes abstraites
+
+// Syntaxe de déclaration:
+// <niveau d'accès> abstract class <nom de la classe abstraite> extends <nom de la
+// classe mère abstraite> {
+// // Constantes et variables
+// // Méthodes
+// }
+
+// Une classe abstraite contient au moins une méthode abstraite qui doit être
+// définee dans la classe fille. Comme les interfaces, les classes abstraites ne
+// peuvent pas être instanciées mais doivent être étendues avec les méthodes
+// abstraites implémentées. À la différence des interfaces, une classe abstraite
+// peut contenir des méthodes abstraites ou non-abstraites. Les méthodes dans une
+// interfaces ne peuvent pas être implémentées à l'exception des méthodes static.
+// Les variables d'une classe abstraite sont déclarées comme final par défaut à
+// l'opposé des interfaces. Finalement les classes abstraites peuvent avoir une
+// méthode main.
+public abstract class Animal
+{
+ public abstract void makeSound();
+
+ // Les méthodes peuvent avoir une implémentation dans une classe abstraite.
+ public void eat()
+ {
+ System.out.println("I am an animal and I am Eating.");
+ // Note: On peut accéder à une variable privée ici.
+ age = 30;
+ }
+
+ // On n'a pas besoin d'initialiser les variables dans les classe abstraites.
+ // Cependant, dans une interfaces, les variables sont implicitement
+ // déclarées comme final et doivent donc être initialisées.
+ private int age;
+
+ public void printAge()
+ {
+ System.out.println(age);
+ }
+
+ // Les classes abstraites peuvent avoir une fonction main.
+ public static void main(String[] args)
+ {
+ System.out.println("I am abstract");
+ }
+}
+
+class Dog extends Animal
+{
+ // On doit également utiliser l'annotation @Override lors de la surchage de
+ // la méthode abstraite d'une classe abstraite.
+ @Override
+ public void makeSound()
+ {
+ System.out.println("Bark");
+ // age = 30; ==> ERREUR! age est privé et n'est pas accesible.
+ }
+
+ // NOTE: Vous obtiendrez une erreur si vous utilisé l'annotation @Override
+ // ici car Java n'autorise pas la surcharge de méthodes statiques. Ce qui ce
+ // passe est appelé "method hiding". Si vous voulez en savoir plus,
+ // consultez cette discussion (en anglais) :
+ // http://stackoverflow.com/questions/16313649/
+ public static void main(String[] args)
+ {
+ Dog pluto = new Dog();
+ pluto.makeSound();
+ pluto.eat();
+ pluto.printAge();
+ }
+}
+
+// Classes finales
+
+// Syntaxe de déclaration
+// <niveau d'accès> final <nom de la classe final> {
+// // Constantes et variables
+// // Méthodes déclarations
+// }
+
+// Les classe déclarées comme final ne peuvent pas avoir de classe fille. Elles
+// peuvent être considérées comme l'opposé des classes abstraites.
+public final class SaberToothedCat extends Animal
+{
+ // On doit également utiliser l'annotation @Override lors de la surchage de
+ // la méthode abstraite d'une classe abstraite.
+ @Override
+ public void makeSound()
+ {
+ System.out.println("Roar");
+ }
+}
+
+// Méthodes final
+public abstract class Mammal()
+{
+ // Syntaxe:
+ // <niveau d'accès> final <type de retour> <nom de la fonction>(<arguments>)
+
+ // Les méthodes déclarées comme final ne peuvent pas être surchargées par
+ // une classe fille et en sont donc l'implémentation finale.
+ public final boolean isWarmBlooded()
+ {
+ return true;
+ }
+}
+
+// Enumérations
+//
+// Le type enum est un type de donnée spécial qui permet à une variable de ne
+// prendre que certaines valeurs prédéfinies. La variable doit être égales à une
+// des valeurs pédéfinies pour celle-ci. En Java, les variables constantes sont
+// notées en majuscules.
+// On définie un type enum en utilisant le mot clé enum. Par exemple pour les
+// jours de l'année:
+public enum Day {
+ SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
+ THURSDAY, FRIDAY, SATURDAY
+}
+
+// On l'utilise ainsi:
+public class EnumTest {
+ // On utilise notre énumération
+ Day day;
+
+ public EnumTest(Day day) {
+ this.day = day;
+ }
+
+ public void tellItLikeItIs() {
+ switch (day) {
+ case MONDAY:
+ System.out.println("Mondays are bad.");
+ break;
+ case FRIDAY:
+ System.out.println("Fridays are better.");
+ break;
+ case SATURDAY:
+ case SUNDAY:
+ System.out.println("Weekends are best.");
+ break;
+ default:
+ System.out.println("Midweek days are so-so.");
+ break;
+ }
+ }
+
+ public static void main(String[] args) {
+ EnumTest firstDay = new EnumTest(Day.MONDAY);
+ firstDay.tellItLikeItIs(); // => affiche "Mondays are bad"
+ EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
+ thirdDay.tellItLikeItIs(); // => affiche "Midweek days are so-so"
+ }
+}
+
+// Le type enum permet de faire bien plus que ce qui est montré ici. Il ne se
+// limite pas à une liste de constante mais peut inclure des champs et méthodes.
+// Vous pouvez en savoir plus ici (en anglais):
+//https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
+
+```
+
+## Pour aller plus loin (en anglais)
+
+Les liens ci-dessous sont données si vous souhaitez approfondir sur le sujet,
+n'hésitez pas à consulter Google pour trouver des exemples spécifiques.
+
+**Guides officiels d'Oracle**:
+
+* [Java Tutorial Trail from Sun / Oracle](https://docs.oracle.com/javase/tutorial/index.html)
+
+* [Java Access level modifiers](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
+
+* [Object-Oriented Programming Concepts](https://docs.oracle.com/javase/tutorial/java/concepts/index.html):
+ * [Inheritance](https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html)
+ * [Polymorphism](https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html)
+ * [Abstraction](https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)
+
+* [Exceptions](https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html)
+
+* [Interfaces](https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html)
+
+* [Generics](https://docs.oracle.com/javase/tutorial/java/generics/index.html)
+
+* [Java Code Conventions](https://www.oracle.com/technetwork/java/codeconvtoc-136057.html)
+
+* Nouvelles fonctionnalités Java 8:
+ * [Lambda expressions (functional programming)](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html)
+ * [Date and time API (java.time package)](http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html)
+
+**Pratiquer en ligne et tutoriels**
+
+* [Learneroo.com - Learn Java](http://www.learneroo.com)
+
+* [Codingbat.com](http://codingbat.com/java)
+
+**Livres**:
+
+* [Head First Java](http://www.headfirstlabs.com/books/hfjava/)
+
+* [Thinking in Java](http://www.mindview.net/Books/TIJ/)
+
+* [Objects First with Java](https://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660)
+
+* [Java The Complete Reference](https://www.amazon.com/gp/product/0071606300)
diff --git a/fr-fr/javascript-fr.html.markdown b/fr-fr/javascript-fr.html.markdown
index f1977dac..186859ab 100644
--- a/fr-fr/javascript-fr.html.markdown
+++ b/fr-fr/javascript-fr.html.markdown
@@ -1,12 +1,12 @@
---
language: javascript
contributors:
- - ['Adam Brenecki', 'http://adam.brenecki.id.au']
- - ['Ariel Krakowski', 'http://www.learneroo.com']
+ - ["Leigh Brenecki", "https://leigh.net.au"]
+ - ["Ariel Krakowski", "http://www.learneroo.com"]
filename: javascript-fr.js
translators:
- - ['@nbrugneaux', 'https://nicolasbrugneaux.me']
- - ['Michel Antoine', 'https://github.com/antoin-m']
+ - ["@nbrugneaux", "https://nicolasbrugneaux.me"]
+ - ["Michel Antoine", "https://github.com/antoin-m"]
lang: fr-fr
---
@@ -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;
@@ -328,13 +328,15 @@ for (var x in person){
}
description; // = "Paul Ken 18 "
-// *ES6:* La boucle for...of permet d'itérer sur les propriétés d'un objet
-var description = "";
-var person = {fname:"Paul", lname:"Ken", age:18};
-for (var x of person){
- description += x + " ";
+// *ES6:* La boucle for...of permet de parcourir un objet itérable
+// (ce qui inclut les objets Array, Map, Set, String, ... Mais pas un objet littéral !)
+let myPets = "";
+const pets = ["cat", "dog", "hamster", "hedgehog"];
+for (let pet of pets){ //`(const pet of pets)` est également possible
+
+ myPets += pet + " ";
}
-description; // = "Paul Ken 18 "
+myPets; // = 'cat dog hamster hedgehog '
// && est le "et" logique, || est le "ou" logique
if (house.size === 'big' && house.colour === 'blue'){
diff --git a/fr-fr/jquery-fr.html.markdown b/fr-fr/jquery-fr.html.markdown
index 1842e02b..1a5baf71 100644
--- a/fr-fr/jquery-fr.html.markdown
+++ b/fr-fr/jquery-fr.html.markdown
@@ -13,6 +13,7 @@ jQuery est une bibliothèque JavaScript dont le but est de permettre de "faire p
C'est pourquoi aujourd'hui, jQuery est utilisée par de nombreuses grandes entreprises et par des développeurs du monde entier.
Étant donné que jQuery est une bibliothèque JavaScript, vous devriez d'abord [apprendre le JavaScript](https://learnxinyminutes.com/docs/fr-fr/javascript-fr/)
+
```js
@@ -138,5 +139,5 @@ $('p').each(function() {
});
-``
+```
diff --git a/fr-fr/lambda-calculus-fr.html.markdown b/fr-fr/lambda-calculus-fr.html.markdown
new file mode 100644
index 00000000..c91f21d6
--- /dev/null
+++ b/fr-fr/lambda-calculus-fr.html.markdown
@@ -0,0 +1,106 @@
+---
+category: Algorithms & Data Structures
+name: Lambda Calculus
+contributors:
+ - ["Max Sun", "http://github.com/maxsun"]
+translators:
+ - ["Yvan Sraka", "https://github.com/yvan-sraka"]
+lang: fr-fr
+---
+
+# Lambda-calcul
+
+Le Lambda-calcul (λ-calcul), créé à l'origine par [Alonzo Church](https://en.wikipedia.org/wiki/Alonzo_Church), est le plus petit langage de programmation au monde. En dépit de ne pas avoir de nombres, de chaînes, de booléens, ou de tout type de données sans fonction, le lambda calcul peut être utilisé pour représenter n'importe quelle machine de Turing!
+
+Le Lambda-calcul est composé de 3 éléments : **variables**, **fonctions** et **applications**.
+
+
+| Nom | Syntaxe | Exemple | Explication |
+|-------------|------------------------------------|-----------|---------------------------------------------------|
+| Variable | `<nom>` | `x` | une variable nommée "x" |
+| Fonction | `λ<paramètres>.<corps>` | `λx.x` | une fonction avec le paramètre "x" et le corps "x"|
+| Application | `<fonction><variable ou function>` | `(λx.x)a` | appel de la fonction "λx.x" avec l'argument "a" |
+
+La fonction la plus fondamentale est la fonction identité: `λx.x` qui est équivalente à `f(x) = x`. Le premier "x" est l'argument de la fonction, et le second est le corps de la fonction.
+
+## Variables libres et liées :
+
+- Dans la fonction `λx.x`, "x" s'appelle une variable liée car elle est à la fois dans le corps de la fonction et l'un des paramètres.
+- Dans `λx.y`, "y" est appelé une variable libre car elle n'a pas été déclarée plus tôt.
+
+## Évaluation :
+
+L'évaluation est réalisée par [β-Réduction](https://en.wikipedia.org/wiki/Lambda_calculus#Beta_reduction), qui est essentiellement une substitution lexicale.
+
+Lors de l'évaluation de l'expression `(λx.x)a`, nous remplaçons toutes les occurrences de "x" dans le corps de la fonction par "a".
+
+- `(λx.x)a` vaut après évaluation: `a`
+- `(λx.y)a` vaut après évaluation: `y`
+
+Vous pouvez même créer des fonctions d'ordre supérieur:
+
+- `(λx.(λy.x))a` vaut après évaluation: `λy.a`
+
+Bien que le lambda-calcul ne prenne traditionnellement en charge que les fonctions à un seul paramètre, nous pouvons créer des fonctions multi-paramètres en utilisant une technique appelée currying.
+
+- `(λx.λy.λz.xyz)` est équivalent à `f(x, y, z) = x(y(z))`
+
+Parfois, `λxy.<corps>` est utilisé de manière interchangeable avec: `λx.λy.<corps>`
+
+----
+
+Il est important de reconnaître que le lambda-calcul traditionnel n'a pas de nombres, de caractères ou tout autre type de données sans fonction!
+
+## Logique booléenne :
+
+Il n'y a pas de "Vrai" ou de "Faux" dans le calcul lambda. Il n'y a même pas 1 ou 0.
+
+Au lieu:
+
+`T` est représenté par: `λx.λy.x`
+
+`F` est représenté par: `λx.λy.y`
+
+Premièrement, nous pouvons définir une fonction "if" `λbtf` qui renvoie `t` si `b` est vrai et `f` si `b` est faux
+
+`IF` est équivalent à: `λb.λt.λf.b t f`
+
+En utilisant `IF`, nous pouvons définir les opérateurs logiques de base booléens:
+
+`a AND b` est équivalent à: `λab.IF a b F`
+
+`a OR b` est équivalent à: `λab.IF a T b`
+
+`a NOT b` est équivalent à: `λa.IF a F T`
+
+*Note: `IF a b c` est equivalent à : `IF(a(b(c)))`*
+
+## Nombres :
+
+Bien qu'il n'y ait pas de nombres dans le lambda-calcul, nous pouvons encoder des nombres en utilisant les [nombres de Church](https://en.wikipedia.org/wiki/Church_encoding).
+
+Pour tout nombre n: <code>n = λf.f<sup>n</sup></code> donc:
+
+`0 = λf.λx.x`
+
+`1 = λf.λx.f x`
+
+`2 = λf.λx.f(f x)`
+
+`3 = λf.λx.f(f(f x))`
+
+Pour incrémenter un nombre de Church, nous utilisons la fonction successeur `S(n) = n + 1` qui est:
+
+`S = λn.λf.λx.f((n f) x)`
+
+En utilisant `S`, nous pouvons définir la fonction `ADD`:
+
+`ADD = λab.(a S)n`
+
+**Défi:** essayez de définir votre propre fonction de multiplication!
+
+## Pour aller plus loin :
+
+1. [A Tutorial Introduction to the Lambda Calculus](http://www.inf.fu-berlin.de/lehre/WS03/alpi/lambda.pdf)
+2. [Cornell CS 312 Recitation 26: The Lambda Calculus](http://www.cs.cornell.edu/courses/cs3110/2008fa/recitations/rec26.html)
+3. [Wikipedia - Lambda Calculus](https://en.wikipedia.org/wiki/Lambda_calculus)
diff --git a/fr-fr/make-fr.html.markdown b/fr-fr/make-fr.html.markdown
index 48d24549..7b4864b5 100644
--- a/fr-fr/make-fr.html.markdown
+++ b/fr-fr/make-fr.html.markdown
@@ -1,5 +1,6 @@
---
-language: make
+category: tool
+tool: make
contributors:
- ["Robert Steed", "https://github.com/robochat"]
translators:
diff --git a/fr-fr/markdown-fr.html.markdown b/fr-fr/markdown-fr.html.markdown
new file mode 100644
index 00000000..1fd22883
--- /dev/null
+++ b/fr-fr/markdown-fr.html.markdown
@@ -0,0 +1,367 @@
+---
+language: markdown
+contributors:
+- ["Andrei Curelaru", "http://www.infinidad.fr"]
+filename: markdown-fr.md
+lang: fr-fr
+---
+
+
+Markdown a été créé par John Gruber en 2004. Il se veut être d'une syntaxe
+facile à lire et à écrire, aisément convertible en HTML (et dans beaucoup
+d'autres formats aussi).
+
+Les implémentations du Markdown varient d'un analyseur syntaxique à un autre.
+Ce guide va essayer de clarifier quand une fonctionnalité est universelle ou
+quand elle est specifique à un certain analyseur syntaxique.
+
+- [Balises HTML](#balises-html)
+- [En-têtes](#en-tetes)
+- [Styles de texte basiques](#style-de-text-basiques)
+- [Paragraphes](#paragraphes)
+- [Listes](#listes)
+- [Blocs de code](#blocs-de-code)
+- [Séparateur horizontal](#separateur-horizontal)
+- [Liens hypertextes](#liens-hypertextes)
+- [Images](#images)
+- [Divers](#divers)
+
+## Balises HTML
+
+Markdown est un sur-ensemble du HTML, donc tout fichier HTML est un ficher
+Markdown valide.
+
+```md
+<!-- Ce qui veut dire que vous pouvez utiliser des balises HTML dans un fichier
+Markdown, comme la balise commentaire dans laquelle nous sommes à présent, car
+celle-ci ne sera pas affectée par l'analyseur syntaxique du Markdown.
+Toutefois, si vous voulez créer une balise HTML dans un fichier Markdown,
+vous ne pourrez pas utiliser du Markdown à l'intérieur de cette derniere. -->
+```
+
+## En-têtes
+
+Vous pouvez facilement créer des balises HTML `<h1>` à `<h6>` en précédant le
+texte de votre futur titre par un ou plusieurs dièses ( # ), de un à six, selon
+le niveau de titre souhaité.
+
+```md
+# Ceci est un <h1>
+## Ceci est un <h2>
+### Ceci est un <h3>
+#### Ceci est un <h4>
+##### Ceci est un <h5>
+###### Ceci est un <h6>
+```
+
+Markdown fournit également une façon alternative de marquer les `<h1>` et `<h2>`
+
+```md
+Ceci est un h1
+=============
+
+Ceci est un h2
+-------------
+```
+
+## Styles de texte basiques
+
+On peut facilement rendre un texte "gras" ou "italique" en Markdown.
+
+```md
+*Ce texte est en italique.*
+_Celui-ci aussi._
+
+**Ce texte est en gras.**
+__Celui-là aussi.__
+
+***Ce texte a les deux styles.***
+**_Pareil ici_**
+*__Et là!__*
+```
+
+Dans le "GitHub Flavored Markdown", utilisé pour interpréter le Markdown sur
+GitHub, on a également le texte barré.
+
+```md
+~~Ce texte est barré.~~
+```
+
+## Paragraphes
+
+Les paragraphes sont représentés par une ou plusieurs lignes de texte séparées
+par une ou plusieurs lignes vides.
+
+```md
+Ceci est un paragraphe. Là, je suis dans un paragraphe, facile non?
+
+Maintenant je suis dans le paragraphe 2.
+Je suis toujours dans le paragraphe 2!
+
+
+Puis là, eh oui, le paragraphe 3!
+```
+
+Si jamais vous souhaitez insérer une balise HTML `<br />`, vous pouvez ajouter
+un ou plusieurs espaces à la fin de votre paragraphe, et en commencer un
+nouveau.
+
+```md
+J'ai deux espaces vides à la fin (sélectionnez moi pour les voir).
+
+Bigre, il y a un <br /> au dessus de moi!
+```
+
+Les blocs de citations sont générés aisément, grâce au caractère `>`.
+
+```md
+> Ceci est une superbe citation. Vous pouvez même
+> revenir à la ligne quand ça vous chante, et placer un `>`
+> devant chaque bout de ligne faisant partie
+> de la citation.
+> La taille ne compte pas^^ tant que chaque ligne commence par un `>`.
+
+> Vous pouvez aussi utiliser plus d'un niveau
+>> d'imbrication!
+> Classe et facile, pas vrai?
+```
+
+## Listes
+
+Les listes non ordonnées sont marquées par des asterisques, signes plus ou
+signes moins.
+
+```md
+* Item
+* Item
+* Un autre item
+```
+
+ou
+
+```md
++ Item
++ Item
++ Encore un item
+```
+
+ou
+
+```md
+- Item
+- Item
+- Un dernier item
+```
+
+Les listes ordonnées sont générées via un nombre suivi d'un point.
+
+```md
+1. Item un
+2. Item deux
+3. Item trois
+```
+
+Vous pouvez même vous passer de tout numéroter, et Markdown générera les bons
+chiffres. Ceci dit, cette variante perd en clarté.
+
+```md
+1. Item un
+1. Item deux
+1. Item trois
+```
+
+(Cette liste sera interprétée de la même façon que celle au dessus)
+
+Vous pouvez également utiliser des sous-listes.
+
+```md
+1. Item un
+2. Item deux
+3. Item trois
+ * Sub-item
+ * Sub-item
+4. Item quatre
+```
+
+Il y a même des listes de taches. Elles génèrent des champs HTML de type case à
+cocher.
+
+```md
+Les [ ] ci-dessous, n'ayant pas de [ x ], deviendront des cases à cocher HTML
+non-cochées.
+- [ ] Première tache à réaliser.
+- [ ] Une autre chose à faire.
+La case suivante sera une case à cocher HTML cochée.
+- [x] Ça ... c'est fait!
+```
+
+## Blocs de code
+
+Pour marquer du texte comme étant du code (qui utilise la balise `<code>`), il
+suffit d'indenter chaque ligne avec 4 espaces ou une tabulation.
+
+```md
+ echo "Ça, c'est du Code!";
+ var Ça = "aussi !";
+```
+
+L'indentation par tabulation (ou série de quatre espaces) fonctionne aussi à
+l'intérieur du bloc de code.
+
+```md
+ my_array.each do |item|
+ puts item
+ end
+```
+
+Des bouts de code en mode en ligne s'ajoutent en utilisant le caractères
+`` ` ``.
+
+```md
+La fonction `run()` ne vous oblige pas à aller courir!
+```
+
+En Markdown GitHub, vous pouvez utiliser des syntaxes spécifiques.
+
+ ```ruby
+ def foobar
+ puts "Hello world!"
+ end
+ ```
+
+Pas besoin d'indentation pour le code juste au-dessus, de plus, GitHub
+va utiliser une coloration syntaxique pour le langage indiqué après les <code>```</code>.
+
+## Ligne Horizontale
+
+Pour insérer une ligne horizontale, utilisez trois ou plusieurs astérisques ou tirets, avec ou sans espaces entre.
+
+```md
+***
+---
+- - -
+****************
+```
+
+## Liens hypertextes
+
+Une des fonctionnalités sympathiques du Markdown est la facilité d'ajouter des
+liens hypertextes. Le texte du lien entre crochet `` [] ``, l'url entre
+parenthèses `` () ``, et voilà le travail.
+
+```md
+[Clic moi!](http://test.com/)
+```
+
+Pour ajouter un attribut `Title`, collez-le entre guillemets, avec le lien.
+
+```md
+[Clic moi!](http://test.com/ "Lien vers Test.com")
+```
+
+Markdown supporte aussi les liens relatifs.
+
+```md
+[En avant la musique](/music/).
+```
+
+Les liens de références sont eux aussi disponibles en Markdown.
+
+<div class="highlight"><code><pre>
+[<span class="nv">Cliquez ici</span>][<span class="ss">link1</span>] pour plus d'information!
+[<span class="nv">Regardez aussi par ici</span>][<span class="ss">foobar</span>] si vous voulez.
+
+[<span class="nv">link1</span>]: <span class="sx">http://test.com/</span> <span class="nn">"Cool!"</span>
+[<span class="nv">foobar</span>]: <span class="sx">http://foobar.biz/</span> <span class="nn">"Génial!"</span>
+</pre></code></div>
+
+Le titre peut aussi être entouré de guillemets simples, ou de parenthèses, ou
+absent. Les références peuvent être placées où vous voulez dans le document et
+les identifiants peuvent être n'importe quoi tant qu'ils sont uniques.
+
+Il y a également le nommage implicite qui transforme le texte du lien en
+identifiant.
+
+<div class="highlight"><code><pre>
+[<span class="nv">Ceci</span>][] est un lien.
+
+[<span class="nv">Ceci</span>]:<span class="sx">http://ceciestunlien.com/</span>
+</pre></code></div>
+
+Mais ce n'est pas beaucoup utilisé.
+
+## Images
+
+Pour les images, la syntaxe est identique à celle des liens, sauf que précédée
+d'un point d'exclamation!
+
+```md
+![Attribut ALT de l'image](http://imgur.com/monimage.jpg "Titre optionnel")
+```
+
+Là aussi, on peut utiliser le mode "références".
+
+
+<div class="highlight"><code><pre>
+![<span class="nv">Ceci est l'attribut ALT de l'image</span>][<span class="ss">monimage</span>]
+
+[<span class="nv">monimage</span>]: <span class="sx">relative/urls/cool/image.jpg</span> <span class="nn">"si vous voulez un titre, c'est ici."</span>
+</pre></code></div>
+
+## Divers
+
+### Liens Automatiques
+
+```md
+<http://testwebsite.com/> est équivalent à :
+[http://testwebsite.com/](http://testwebsite.com/)
+```
+
+### Liens Automatiques pour emails
+
+```md
+<foo@bar.com>
+```
+
+### Caracteres d'echappement
+
+Il suffit de précéder les caractères spécifiques à ignorer par des backslash `\`.
+
+```md
+Pour taper *ce texte* entouré d'astérisques mais pas en italique :
+Tapez \*ce texte\*.
+```
+
+### Touches de clavier
+
+Avec le "Github Flavored Markdown", vous pouvez utiliser la balise `<kdb>`
+pour représenter une touche du clavier.
+
+```md
+Ton ordinateur a planté? Essayer de taper :
+<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd>
+```
+
+### Tableaux
+
+Les tableaux ne sont disponibles que dans le "GitHub Flavored Markdown" et
+ne sont pas tres agréable d'utilisation. Mais si vous en avez besoin :
+
+```md
+| Col1 | Col2 | Col3 |
+| :----------- | :------: | ------------: |
+| Alignement Gauche | Centré | Alignement Droite |
+| bla | bla | bla |
+```
+
+ou bien, pour un résultat équivalent :
+
+```md
+Col 1 | Col2 | Col3
+:-- | :-: | --:
+Ough que c'est moche | svp | arrêtez
+```
+
+Pour plus d'information, consultez le post officiel de Jhon Gruber à propos de
+la syntaxe [ici](http://daringfireball.net/projects/markdown/syntax) et la
+superbe fiche pense-bête de Adam Pritchard [là](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).
diff --git a/fr-fr/markdown.html.markdown b/fr-fr/markdown.html.markdown
deleted file mode 100644
index 2e4e8461..00000000
--- a/fr-fr/markdown.html.markdown
+++ /dev/null
@@ -1,289 +0,0 @@
----
-language: markdown
-contributors:
-- ["Andrei Curelaru", "http://www.infinidad.fr"]
-filename: markdown-fr.md
-lang: fr-fr
----
-
-Markdown a été créé par John Gruber en 2004. Il se veut être d'une syntaxe
-facile à lire et à écrire, aisément convertible en HTML
- (et beaucoup d'autres formats aussi à présent).
-
-Faites moi autant de retours que vous voulez! Sentez vous libre de "forker"
-et envoyer des pull request!
-
-
-```markdown
-<!-- Markdown est une sorte de cousin du HTML, si bien que tout document HTML
-est un document Markdown valide. Autrement dit, vous pouvez utiliser des
-balises HTML dans un fichier Markdown, comme la balise commentaire dans
-laquelle nous sommes à présent, car celle-ci ne sera pas affectée par
-le parser( analyseur syntaxique ) Markdown. -->
-
-<!-- Toutefois, si vous voulez créer un élément HTML dans un fichier Markdown,
- vous ne pourrez pas utiliser du Markdown à l'intérieur de ce dernier. -->
-
-<!-- Le Markdown est implémenté de différentes manières, selon le parser.
-Ce guide va alors tenter de trier les fonctionnalités universelles de celles
-spécifiques à un parser. -->
-
-<!-- Headers ( En-têtes ) -->
-<!-- Vous pouvez facilement créer des éléments HTML <h1> à <h6> en précédant
- le texte de votre futur titre par un ou plusieurs dièses ( # ), de un à six,
- selon le niveau de titre souhaité. -->
-# Ceci est un <h1>
-## Ceci est un <h2>
-### Ceci est un <h3>
-#### Ceci est un <h4>
-##### Ceci est un <h5>
-###### Ceci est un <h6>
-
-<!--
-Markdown fournit également une façon alternative de marquer les h1 et h2
--->
-
-Ceci est un h1
-=============
-
-Ceci est un h2
--------------
-
-<!-- Styles basiques pour du texte -->
-<!-- On peut facilement rendre un texte "gras" ou "italique" en Markdown -->
-
-*Ce texte est en italique.*
-_Celui-ci aussi._
-
-**Ce texte est en gras.**
-__Celui-là aussi.__
-
-***Ce texte a les deux styles.***
-**_Pareil ici_**
-*__Et là!__*
-
-<!-- Dans le "GitHub Flavored Markdown", utilisé pour interpréter le Markdown
-sur GitHub, on a également le strikethrough ( texte barré ) : -->
-
-~~Ce texte est barré avec strikethrough.~~
-
-<!-- Les Paragraphes sont représentés par une ou plusieurs lignes de texte
-séparées par une ou plusieurs lignes vides. -->
-
-Ceci est un paragraphe. Là, je suis dans un paragraphe, facile non?
-
-Maintenant je suis dans le paragraphe 2.
-Je suis toujours dans le paragraphe 2!
-
-
-Puis là, eh oui, le paragraphe 3!
-
-<!--
-Si jamais vous souhaitez insérer une balise HTML <br />, vous pouvez ajouter
-un ou plusieurs espaces à la fin de votre paragraphe, et en commencer
-un nouveau.
--->
-
-J'ai deux espaces vides à la fin (sélectionnez moi pour les voir).
-
-Bigre, il y a un <br /> au dessus de moi!
-
-<!-- Les 'Blocs de Citations' sont générés aisément, grâce au caractère > -->
-
-> Ceci est une superbe citation. Vous pouvez même
-> revenir à la ligne quand ça vous chante, et placer un `>`
-> devant chaque bout de ligne faisant partie
-> de la citation.
-> La taille ne compte pas^^ tant que chaque ligne commence par un `>`.
-
-> Vous pouvez aussi utiliser plus d'un niveau
->> d'imbrication!
-> Classe et facile, pas vrai?
-
-<!-- les Listes -->
-<!-- les Listes non ordonnées sont marquées par des asterisques,
-signes plus ou signes moins. -->
-
-* Item
-* Item
-* Un autre item
-
-ou
-
-+ Item
-+ Item
-+ Encore un item
-
-ou
-
-- Item
-- Item
-- Un dernier item
-
-<!-- les Listes Ordonnées sont générées via un nombre suivi d'un point -->
-
-1. Item un
-2. Item deux
-3. Item trois
-
-<!-- Vous pouvez même vous passer de tout numéroter, et Markdown générera
-les bons chiffres. Ceci dit, cette variante perd en clarté.-->
-
-1. Item un
-1. Item deux
-1. Item trois
-<!-- ( cette liste sera interprétée de la même façon que celle au dessus ) -->
-
-<!-- Vous pouvez également utiliser des sous-listes -->
-
-1. Item un
-2. Item deux
-3. Item trois
-* Sub-item
-* Sub-item
-4. Item quatre
-
-<!-- Il y a même des "listes de Taches". Elles génèrent des champs HTML
-de type checkbox. -->
-
-Les [ ] ci dessous, n'ayant pas de [ x ],
-deviendront des cases à cocher HTML non-cochées.
-
-- [ ] Première tache à réaliser.
-- [ ] Une autre chose à faire.
-La case suivante sera une case à cocher HTML cochée.
-- [x] Ça ... c'est fait!
-
-<!-- les Blocs de Code -->
-<!-- Pour marquer du texte comme étant du code, il suffit de commencer
-chaque ligne en tapant 4 espaces (ou un Tab) -->
-
- echo "Ça, c'est du Code!";
- var Ça = "aussi !";
-
-<!-- L'indentation par tab ou série de quatre espaces
-fonctionne aussi à l'intérieur du bloc de code -->
-
- my_array.each do |item|
- puts item
- end
-
-<!-- Des bouts de code en mode 'inline' s'ajoutent en les entourant de ` -->
-
-La fonction `run()` ne vous oblige pas à aller courir!
-
-<!-- Via GitHub Flavored Markdown, vous pouvez utiliser
-des syntaxes spécifiques -->
-
-\`\`\`ruby
-<!-- mais enlevez les backslashes quand vous faites ça,
-gardez juste ```ruby ( ou nom de la syntaxe correspondant à votre code )-->
-def foobar
-puts "Hello world!"
-end
-\`\`\` <!-- pareil, pas de backslashes, juste ``` en guise de fin -->
-
-<-- Pas besoin d'indentation pour le code juste au dessus, de plus, GitHub
-va utiliser une coloration syntaxique pour le langage indiqué après les ``` -->
-
-<!-- Ligne Horizontale (<hr />) -->
-<!-- Pour en insérer une, utilisez trois ou plusieurs astérisques ou tirets,
-avec ou sans espaces entre chaque un. -->
-
-***
----
-- - -
-****************
-
-<!-- Liens -->
-<!-- Une des fonctionnalités sympathiques du Markdown est la facilité
-d'ajouter des liens. Le texte du lien entre [ ], l'url entre ( ),
-et voilà l'travail.
--->
-
-[Clic moi!](http://test.com/)
-
-<!--
-Pour ajouter un attribut Title, collez le entre guillemets, avec le lien.
--->
-
-[Clic moi!](http://test.com/ "Lien vers Test.com")
-
-<!-- les Liens Relatifs marchent aussi -->
-
-[En avant la musique](/music/).
-
-<!-- Les liens façon "références" sont eux aussi disponibles en Markdown -->
-
-[Cliquez ici][link1] pour plus d'information!
-[Regardez aussi par ici][foobar] si vous voulez.
-
-[link1]: http://test.com/ "Cool!"
-[foobar]: http://foobar.biz/ "Alright!"
-
-<!-- Le titre peut aussi être entouré de guillemets simples,
-entre parenthèses ou absent. Les références peuvent être placées
-un peu où vous voulez dans le document, et les identifiants
-(link1, foobar, ...) quoi que ce soit tant qu'ils sont uniques -->
-
-<!-- Il y a également le "nommage implicite" qui transforme le texte du lien
- en identifiant -->
-
-[Ceci][] est un lien.
-
-[ceci]: http://ceciestunlien.com/
-
-<!-- mais ce n'est pas beaucoup utilisé. -->
-
-<!-- Images -->
-<!-- Pour les images, la syntaxe est identique aux liens, sauf que précédée
- d'un point d'exclamation! -->
-
-![Attribut ALT de l'image](http://imgur.com/monimage.jpg "Titre optionnel")
-
-<!-- Là aussi, on peut utiliser le mode "références" -->
-
-![Ceci est l'attribut ALT de l'image][monimage]
-
-[monimage]: relative/urls/cool/image.jpg "si vous voulez un titre, c'est ici."
-
-<!-- Divers -->
-<!-- Liens Automatiques -->
-
-<http://testwebsite.com/> est équivalent à :
-[http://testwebsite.com/](http://testwebsite.com/)
-
-<!-- Liens Automatiques pour emails -->
-
-<foo@bar.com>
-
-<!-- Escaping -->
-Il suffit de précéder les caractères spécifiques à ignorer par des backslash \
-
-Pour taper *ce texte* entouré d'astérisques mais pas en italique :
-Tapez \*ce texte\*.
-
-<!-- Tableaux -->
-<!-- les Tableaux ne sont disponibles que dans le GitHub Flavored Markdown
- et c'est ce n'est pas super agréable d'utilisation.
- Mais si vous en avez besoin :
- -->
-
-| Col1 | Col2 | Col3 |
-| :----------- | :------: | ------------: |
-| Alignement Gauche | Centé | Alignement Droite |
-| bla | bla | bla |
-
-<!-- ou bien, pour un résultat équivalent : -->
-
-Col 1 | Col2 | Col3
-:-- | :-: | --:
-Ough que c'est moche | svp | arrêtez
-
-<!-- Fin! -->
-
-```
-
-Pour plus d'information :
- consultez [ici](http://daringfireball.net/projects/markdown/syntax) le post officiel de Jhon Gruber à propos de la syntaxe,
- et [là](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) la superbe cheatsheet de Adam Pritchard.
diff --git a/fr-fr/perl-fr.html.markdown b/fr-fr/perl-fr.html.markdown
index e737b7aa..e073bcf5 100644
--- a/fr-fr/perl-fr.html.markdown
+++ b/fr-fr/perl-fr.html.markdown
@@ -10,9 +10,9 @@ translators:
- ["Matteo Taroli", "http://www.matteotaroli.be"]
lang: fr-fr
---
-Perl 5 est un langage de programmation riche en fonctionnalité, avec plus de 25 ans de développement.
+Perl est un langage de programmation riche en fonctionnalité, avec plus de 25 ans de développement.
-Perl 5 fonctionne sur plus de 100 plateformes, allant des pc portables aux mainframes et
+Perl fonctionne sur plus de 100 plateformes, allant des pc portables aux mainframes et
est autant adapté à un prototypage rapide qu'à des projets de grande envergure.
```perl
diff --git a/fr-fr/php.html.markdown b/fr-fr/php-fr.html.markdown
index f4eaf396..45a02d75 100644
--- a/fr-fr/php.html.markdown
+++ b/fr-fr/php-fr.html.markdown
@@ -1,14 +1,16 @@
---
language: PHP
+filename: php-fr.php
contributors:
- ["Malcolm Fell", "http://emarref.net/"]
- ["Trismegiste", "https://github.com/Trismegiste"]
translators:
- ["Pascal Boutin", "http://pboutin.net/"]
+ - ["Julien M'Poy", "https://github.com/groovytron"]
lang: fr-fr
---
-This document describes PHP 5+.
+Ce document décrit PHP 5+.
```php
// Le code PHP doit être placé à l'intérieur de balises '<?php'
@@ -47,7 +49,7 @@ Hello World Again!
// Un nom de variable valide commence par une lettre ou un souligné,
// suivi de n'importe quelle lettre, nombre ou de soulignés.
-// Les valeurs booléenes ne sont pas sensibles à la casse
+// Les valeurs booléennes ne sont pas sensibles à la casse
$boolean = true; // ou TRUE ou True
$boolean = false; // ou FALSE ou False
@@ -83,30 +85,30 @@ $number /= $float; // Divise et assigne le quotient à $number
$sgl_quotes = '$String'; // => '$String'
// Évitez les guillemets sauf pour inclure le contenu d'une autre variable
-$dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.'
+$dbl_quotes = "Ceci est une $sgl_quotes."; // => 'Ceci est une $String.'
// Les caractères spéciaux sont seulement échappés avec des guillemets
-$escaped = "This contains a \t tab character.";
-$unescaped = 'This just contains a slash and a t: \t';
+$escaped = "Ceci contient \t une tabulation.";
+$unescaped = 'Ceci contient juste un slash et un t: \t';
// En cas de besoin, placez la variable dans des accolades
-$money = "I have $${number} in the bank.";
+$money = "J'ai $${number} sur mon compte en banque.";
// Depuis PHP 5.3, Nowdoc peut être utilisé pour faire des chaînes
// multi-lignes non-interprétées
$nowdoc = <<<'END'
-Multi line
-string
+String
+mutli-lignes
END;
// Heredoc peut être utilisé pour faire des chaînes multi-lignes interprétées
$heredoc = <<<END
-Multi line
$sgl_quotes
+multi-lignes
END;
// La concaténation de chaînes se fait avec un .
-echo 'This string ' . 'is concatenated';
+echo 'Cette string ' . 'est concatenée'; // => 'Cette string est concaténée'
/********************************
@@ -121,7 +123,7 @@ echo 'This string ' . 'is concatenated';
define("FOO", "something");
// on peut accéder à une constante en utilisant directement son nom
-echo 'This outputs '.FOO;
+echo 'Ceci affiche ' . FOO;
/********************************
@@ -148,6 +150,14 @@ $array[] = 'Four';
// Retrait d'un élément du tableau
unset($array[3]);
+// Depuis PHP 7, il est possible de déclarer des tableaux constants en
+// utilisant 'define'.
+define('ANIMAUX', [
+ 'chien',
+ 'chat',
+ 'oiseau',
+]);
+
/********************************
* Affichage
*/
@@ -158,11 +168,13 @@ echo('Hello World!');
print('Hello World!'); // Pareil à "écho"
-// Pour écho, vous n'avez pas besoin des parenthèses
+// 'echo' et 'print' sont des language constructs.
+// Il n'ont pas besoin de parenthèses car ils sont traités comme
+// des opérateurs unaires.
echo 'Hello World!';
-print 'Hello World!'; // Pour print non plus
+print 'Hello World!';
-$paragraph = 'paragraph';
+$paragraph = 'paragraphe';
echo 100; // Affichez un scalaire directement
echo $paragraph; // ou des variables
@@ -201,7 +213,8 @@ $b = '0';
$c = '1';
$d = '1';
-// assert affiche un avertissement dans son argument n'est pas vrai
+// assert affiche un avertissement quand l'expression booléenne passée
+// en argument n'est pas vraie.
// Ces comparaisons vont toujours être vraies, même si leurs
// types ne sont pas les mêmes.
@@ -314,7 +327,7 @@ if ($x === '0') {
switch ($x) {
case '0':
print 'Les switch font du transtypage implicite';
- break; // Il est important de déclaré un 'break', sinon les cas
+ break; // Il est important de déclarer un 'break', sinon les cas
// 'two' et 'three' seront évalués
case 'two':
case 'three':
@@ -389,9 +402,10 @@ function my_function () {
echo my_function(); // => "Hello"
-// Les noms de fonction débutent par le symbole $
-// Un nom de variable valide commence par une lettre ou un souligné,
+// Un nom de fonction valide commence par une lettre ou un souligné,
// suivi de n'importe quelle lettre, nombre ou de soulignés.
+// Les noms des arguments d'une fonction doivent respecter le même format que
+// celui des variables.
function add ($x, $y = 1) { // $y est facultatif et sa valeur par défaut est 1
$result = $x + $y;
@@ -518,7 +532,7 @@ class MyClass
public static function myStaticMethod()
{
- print 'I am static';
+ print 'Je suis static';
}
}
@@ -526,7 +540,7 @@ class MyClass
echo MyClass::MY_CONST; // Outputs 'value';
echo MyClass::$staticVar; // Retourne 'static';
-MyClass::myStaticMethod(); // Retourne 'I am static';
+MyClass::myStaticMethod(); // Retourne 'Je suis static';
// On peut instancier une classe en utilisant le mot clé 'new'
$my_class = new MyClass('An instance property');
@@ -583,7 +597,7 @@ echo $x->property; // Va utiliser la méthode __get()
$x->property = 'Something'; // Va utiliser la méthode __set()
// Les classes peuvent être abstraites (en utilisant le mot clé 'abstract'), ou
-// elle peuvent implémenter une interface (en utilisant le mot clé 'implement').
+// elle peuvent implémenter une interface (en utilisant le mot clé 'implements').
// Une interface peut être déclarée avec le mot clé 'interface'
@@ -636,6 +650,35 @@ class SomeOtherClass implements InterfaceOne, InterfaceTwo
}
}
+// Il est possible de déclarer des classes internes anonymes depuis PHP 7
+
+interface Logger {
+ public function log(string $msg);
+}
+
+class Application {
+ private $logger;
+
+ public function getLogger(): Logger {
+ return $this->logger;
+ }
+
+ public function setLogger(Logger $logger) {
+ $this->logger = $logger;
+ }
+}
+
+$app = new Application;
+
+$app->setLogger(new class implements Logger {
+ public function log(string $msg) {
+ echo $msg;
+ }
+});
+
+var_dump($app->getLogger()); // => 'object(class@anonymous)#2 (0) {}'
+
+
/********************************
* Espaces de noms (namespaces)
*/
diff --git a/fr-fr/pyqt-fr.html.markdown b/fr-fr/pyqt-fr.html.markdown
new file mode 100644
index 00000000..6da9a380
--- /dev/null
+++ b/fr-fr/pyqt-fr.html.markdown
@@ -0,0 +1,85 @@
+---
+category: tool
+tool: PyQT
+filename: learnpyqt-fr.py
+contributors:
+ - ["Nathan Hughes", "https://github.com/sirsharpest"]
+translators:
+ - ["DevHugo", "http://twitter.com/devhugo"]
+lang: fr-fr
+---
+
+**Qt** est un framework très connu pour le développement de logiciel cross-platform qui peuvent être lancé sur différents systèmes avec de petit ou aucun changement dans le code, tout en ayant la puissance et la vitesse des applications natives. Bien que **Qt** ait été écrit à l'origine en *C++*.
+
+
+Ceci est une adaptation de l'intro C++ à QT par [Aleksey Kholovchuk](https://github.com/vortexxx192
+), certains exemples du code doivent avoir la même fonctionnalité,
+cette version ayant juste été faite en utilisant pyqt!
+
+```python
+import sys
+from PyQt4 import QtGui
+
+def window():
+ # Création de l'objet application
+ app = QtGui.QApplication(sys.argv)
+ # Création d'un widget où notre label sera placé
+ w = QtGui.QWidget()
+ # Ajout d'un label au widget
+ b = QtGui.QLabel(w)
+ # Assignation de texte au label
+ b.setText("Hello World!")
+ # Assignation des tailles et des informations de placement
+ w.setGeometry(100, 100, 200, 50)
+ b.move(50, 20)
+ # Assignation d'un nom à notre fenêtre
+ w.setWindowTitle("PyQt")
+ # Affichage de la fenêtre
+ w.show()
+ # Exécution de l'application
+ sys.exit(app.exec_())
+
+if __name__ == '__main__':
+ window()
+
+```
+
+Pour obtenir certaines des fonctionnalités les plus avancées de **pyqt** nous devons commencer par chercher à construire des éléments supplémentaires.
+Ici nous voyons comment introduire une boîte de dialogue popup, utile pour demander une confirmation à un utilisateur ou fournir des informations.
+
+```Python
+import sys
+from PyQt4.QtGui import *
+from PyQt4.QtCore import *
+
+
+def window():
+ app = QApplication(sys.argv)
+ w = QWidget()
+ # Creation d'un bouton attaché au widget w
+ b = QPushButton(w)
+ b.setText("Press me")
+ b.move(50, 50)
+ # Dire à b d'appeler cette fonction quand il est cliqué
+ # remarquez l'absence de "()" sur l'appel de la fonction
+ b.clicked.connect(showdialog)
+ w.setWindowTitle("PyQt Dialog")
+ w.show()
+ sys.exit(app.exec_())
+
+# Cette fonction devrait créer une fenêtre de dialogue avec un bouton
+# qui attend d'être cliqué puis quitte le programme
+def showdialog():
+ d = QDialog()
+ b1 = QPushButton("ok", d)
+ b1.move(50, 50)
+ d.setWindowTitle("Dialog")
+ # Cette modalité dit au popup de bloquer le parent pendant qu'il est actif
+ d.setWindowModality(Qt.ApplicationModal)
+ # En cliquant je voudrais que tout le processus se termine
+ b1.clicked.connect(sys.exit)
+ d.exec_()
+
+if __name__ == '__main__':
+ window()
+```
diff --git a/fr-fr/python-fr.html.markdown b/fr-fr/python-fr.html.markdown
index d78291be..ca510d66 100644
--- a/fr-fr/python-fr.html.markdown
+++ b/fr-fr/python-fr.html.markdown
@@ -1,293 +1,377 @@
---
-language: python
-filename: learnpython-fr.py
+language: Python
contributors:
- - ["Louie Dinh", "http://ldinh.ca"]
+ - ["Louie Dinh", "http://pythonpracticeprojects.com"]
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+ - ["Zachary Ferguson", "http://github.com/zfergus2"]
translators:
- - ["Sylvain Zyssman", "https://github.com/sylzys"]
- - ["Nami-Doc", "https://github.com/Nami-Doc"]
+ - ["Gnomino", "https://github.com/Gnomino"]
+ - ["Julien M'Poy", "http://github.com/groovytron"]
+filename: learnpython-fr.py
lang: fr-fr
---
-Python a été créé par Guido Van Rossum au début des années 90. C'est maintenant un des langages de programmation les plus populaires.
-Je suis tombé amoureux de Python de par la clarté de sa syntaxe. C'est pratiquement du pseudo-code exécutable.
+Python a été créé par Guido Van Rossum au début des années 90. C'est maintenant un des
+langages les plus populaires. Je suis tombé amoureux de Python pour la clarté de sa syntaxe.
+C'est tout simplement du pseudo-code exécutable.
-Vos retours sont grandement appréciés. Vous pouvez me contacter sur Twitter [@louiedinh](http://twitter.com/louiedinh) ou par e-mail: louiedinh [at] [google's email service]
+L'auteur original apprécierait les retours (en anglais): vous pouvez le contacter sur Twitter à [@louiedinh](http://twitter.com/louiedinh) ou par mail à l'adresse louiedinh [at] [google's email service]
-N.B. : Cet article s'applique spécifiquement à Python 2.7, mais devrait s'appliquer pour toute version Python 2.x. Python 2.7 est en fin de vie et ne sera plus maintenu à partir de 2020, il est donc recommandé d'apprendre Python avec Python 3. Pour Python 3.x, il existe un autre [tutoriel pour Python 3](http://learnxinyminutes.com/docs/fr-fr/python3-fr/).
+Note : Cet article s'applique spécifiquement à Python 3. Jettez un coup d'oeil [ici](http://learnxinyminutes.com/docs/fr-fr/python-fr/) pour apprendre le vieux Python 2.7
```python
-# Une ligne simple de commentaire commence par un dièse
-""" Les lignes de commentaires multipes peuvent être écrites
- en utilisant 3 guillemets ("), et sont souvent utilisées
- pour les commentaires
+
+# Un commentaire d'une ligne commence par un dièse
+
+""" Les chaînes de caractères peuvent être écrites
+ avec 3 guillemets doubles ("), et sont souvent
+ utilisées comme des commentaires.
"""
####################################################
-## 1. Types Primaires et Opérateurs
+## 1. Types de données primaires et opérateurs
####################################################
-# Les nombres
-3 #=> 3
-
-# Les calculs produisent les résultats mathématiques escomptés
-1 + 1 #=> 2
-8 - 1 #=> 7
-10 * 2 #=> 20
-35 / 5 #=> 7
+# On a des nombres
+3 # => 3
-# La division est un peu spéciale. C'est une division d'entiers, et Python arrondi le résultat par défaut automatiquement.
-5 / 2 #=> 2
-
-# Pour corriger ce problème, on utilise les float.
-2.0 # Voici un float
-11.0 / 4.0 #=> 2.75 ahhh... beaucoup mieux
-
-# Forcer la priorité avec les parenthèses
-(1 + 3) * 2 #=> 8
-
-# Les valeurs booléenes sont de type primitif
-True
-False
+# Les calculs sont ce à quoi on s'attend
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
-# Pour la négation, on utilise "not"
-not True #=> False
-not False #=> True
+# Sauf pour la division qui retourne un float (nombre à virgule flottante)
+35 / 5 # => 7.0
-# Pour l'égalité, ==
-1 == 1 #=> True
-2 == 1 #=> False
+# Résultats de divisions entières tronqués pour les nombres positifs et négatifs
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # works on floats too
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
-# L'inégalité est symbolisée par !=
-1 != 1 #=> False
-2 != 1 #=> True
+# Quand on utilise un float, le résultat est un float
+3 * 2.0 # => 6.0
-# D'autres comparateurs
-1 < 10 #=> True
-1 > 10 #=> False
-2 <= 2 #=> True
-2 >= 2 #=> True
+# Modulo (reste de la division)
+7 % 3 # => 1
-# On peut enchaîner les comparateurs !
-1 < 2 < 3 #=> True
-2 < 3 < 2 #=> False
+# Exponentiation (x**y, x élevé à la puissance y)
+2**4 # => 16
-# Les chaînes de caractères sont créées avec " ou '
-"C'est une chaîne."
-'C\'est aussi une chaîne.'
+# Forcer la priorité de calcul avec des parenthèses
+(1 + 3) * 2 # => 8
-# On peut aussi les "additioner" !
-"Hello " + "world!" #=> "Hello world!"
-
-# Une chaîne peut être traitée comme une liste de caractères
-"C'est une chaîne"[0] #=> 'C'
+# Les valeurs booléennes sont primitives
+True
+False
-# % peut être utilisé pour formatter des chaîne, comme ceci:
-"%s can be %s" % ("strings", "interpolated")
+# Négation avec not
+not True # => False
+not False # => True
+
+# Opérateurs booléens
+# On note que "and" et "or" sont sensibles à la casse
+True and False #=> False
+False or True #=> True
+
+# Utilisation des opérations booléennes avec des entiers :
+0 and 2 #=> 0
+-5 or 0 #=> -5
+0 == False #=> True
+2 == True #=> False
+1 == True #=> True
+
+# On vérifie une égalité avec ==
+1 == 1 # => True
+2 == 1 # => False
+
+# On vérifie une inégalité avec !=
+1 != 1 # => False
+2 != 1 # => True
+
+# Autres opérateurs de comparaison
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# On peut enchaîner les comparaisons
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# (is vs. ==) is vérifie si deux variables pointent sur le même objet, mais == vérifie
+# si les objets ont la même valeur.
+a = [1, 2, 3, 4] # a pointe sur une nouvelle liste, [1, 2, 3, 4]
+b = a # b pointe sur a
+b is a # => True, a et b pointent sur le même objet
+b == a # => True, les objets a et b sont égaux
+b = [1, 2, 3, 4] # b pointe sur une nouvelle liste, [1, 2, 3, 4]
+b is a # => False, a et b ne pointent pas sur le même objet
+b == a # => True, les objets a et b ne pointent pas sur le même objet
+
+# Les chaînes (ou strings) sont créées avec " ou '
+"Ceci est une chaine"
+'Ceci est une chaine aussi.'
+
+# On peut additionner des chaînes aussi ! Mais essayez d'éviter de le faire.
+"Hello " + "world!" # => "Hello world!"
+# On peut aussi le faire sans utiliser '+'
+"Hello " "world!" # => "Hello world!"
+
+# On peut traîter une chaîne comme une liste de caractères
+"This is a string"[0] # => 'T'
+
+# .format peut être utilisé pour formatter des chaînes, comme ceci:
+"{} peuvent etre {}".format("Les chaînes", "interpolées")
+
+# On peut aussi réutiliser le même argument pour gagner du temps.
+"{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"
+
+# On peut aussi utiliser des mots clés pour éviter de devoir compter.
+"{name} wants to eat {food}".format(name="Bob", food="lasagna") #=> "Bob wants to eat lasagna"
+
+# Il est également possible d'utiliser les f-strings depuis Python 3.6 (https://docs.python.org/3/whatsnew/3.6.html#pep-498-formatted-string-literals)
+name = "Fred"
+f"Il a dit que son nom est {name}." #=> "Il a dit que son nom est Fred."
+
+# Si votre code doit aussi être compatible avec Python 2.5 et moins,
+# vous pouvez encore utiliser l'ancienne syntaxe :
+"Les %s peuvent être %s avec la %s méthode" % ("chaînes", "interpolées", "vieille")
-# Une autre manière de formatter les chaînes de caractères est d'utiliser la méthode 'format'
-# C'est la méthode à privilégier
-"{0} peut être {1}".format("La chaîne", "formattée")
-# On peut utiliser des mot-clés au lieu des chiffres.
-"{name} veut manger des {food}".format(name="Bob", food="lasagnes")
# None est un objet
-None #=> None
+None # => None
-# Ne pas utiliser le symbole d'inégalité "==" pour comparer des objet à None
-# Il faut utiliser "is"
-"etc" is None #=> False
-None is None #=> True
+# N'utilisez pas "==" pour comparer des objets à None
+# Utilisez plutôt "is". Cela permet de vérifier l'égalité de l'identité des objets.
+"etc" is None # => False
+None is None # => True
-# L'opérateur 'is' teste l'identité de l'objet.
-# Ce n'est pas très utilisé avec les types primitifs, mais cela peut être très utile
-# lorsque l'on utilise des objets.
-
-# None, 0, et les chaînes de caractères vides valent False.
+# None, 0, and les strings/lists/dicts (chaînes/listes/dictionnaires) valent False lorsqu'ils sont convertis en booléens.
# Toutes les autres valeurs valent True
-0 == False #=> True
-"" == False #=> True
+bool(0) # => False
+bool("") # => False
+bool([]) #=> False
+bool({}) #=> False
####################################################
## 2. Variables et Collections
####################################################
-# Afficher du texte, c'est facile
-print "Je suis Python. Enchanté!"
-
+# Python a une fonction print pour afficher du texte
+print("I'm Python. Nice to meet you!")
-# Il n'y a pas besoin de déclarer les variables avant de les assigner.
-some_var = 5 # La convention veut que l'on utilise des minuscules_avec_underscores
-some_var #=> 5
+# Par défaut, la fonction print affiche aussi une nouvelle ligne à la fin.
+# Utilisez l'argument optionnel end pour changer ce caractère de fin.
+print("Hello, World", end="!") # => Hello, World!
-# Accéder à une variable non assignée lève une exception
-# Voyez les structures de contrôle pour en apprendre plus sur la gestion des exceptions.
-some_other_var # Lève une exception
+# Pas besoin de déclarer des variables avant de les définir.
+# La convention est de nommer ses variables avec des minuscules_et_underscores
+some_var = 5
+some_var # => 5
-# 'if' peut être utilisé comme expression
-"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+# Tenter d'accéder à une variable non définie lève une exception.
+# Voir Structures de contrôle pour en apprendre plus sur le traitement des exceptions.
+une_variable_inconnue # Lève une NameError
-# Listes
+# Les listes permettent de stocker des séquences
li = []
-# On peut remplir liste dès l'instanciation
+# On peut initialiser une liste pré-remplie
other_li = [4, 5, 6]
-# On ajoute des éléments avec 'append'
-li.append(1) #li contient [1]
-li.append(2) #li contient [1, 2]
-li.append(4) #li contient [1, 2, 4]
-li.append(3) #li contient [1, 2, 4, 3]
-
-# Et on les supprime avec 'pop'
-li.pop() #=> 3 et li contient [1, 2, 4]
-# Remettons-le dans la liste
-li.append(3) # li contient [1, 2, 4, 3] de nouveau.
-
-# On accède aux éléments d'une liste comme à ceux un tableau.
-li[0] #=> 1
-# Le dernier élément
-li[-1] #=> 3
-
-# Accèder aux indices hors limite lève une exception
-li[4] # Lève un 'IndexError'
-
-# On peut accèder à des rangs de valeurs avec la syntaxe "slice"
-# (C'est un rang de type 'fermé/ouvert' pour les plus matheux)
-li[1:3] #=> [2, 4]
-# Sans spécifier de fin de rang, on "saute" le début de la liste
-li[2:] #=> [4, 3]
-# Sans spécifier de début de rang, on "saute" la fin de la liste
-li[:3] #=> [1, 2, 4]
-
-# Retirer un élément spécifique dee la liste avec "del"
-del li[2] # li contient [1, 2, 3]
-
-# On peut additionner des listes entre elles
-li + other_li #=> [1, 2, 3, 4, 5, 6] - Note: li et other_li existent toujours à part entière
+# On ajoute des objets à la fin d'une liste avec .append
+li.append(1) # li vaut maintenant [1]
+li.append(2) # li vaut maintenant [1, 2]
+li.append(4) # li vaut maintenant [1, 2, 4]
+li.append(3) # li vaut maintenant [1, 2, 4, 3]
+# On enlève le dernier élément avec .pop
+li.pop() # => 3 et li vaut maintenant [1, 2, 4]
+# Et on le remet
+li.append(3) # li vaut de nouveau [1, 2, 4, 3]
+
+# Accès à un élément d'une liste :
+li[0] # => 1
+# Accès au dernier élément :
+li[-1] # => 3
+
+# Accéder à un élément en dehors des limites lève une IndexError
+li[4] # Lève une IndexError
+
+# On peut accéder à une intervalle avec la syntaxe "slice"
+# (c'est un rang du type "fermé/ouvert")
+li[1:3] # => [2, 4]
+# Omettre les deux premiers éléments
+li[2:] # => [4, 3]
+# Prendre les trois premiers
+li[:3] # => [1, 2, 4]
+# Sélectionner un élément sur deux
+li[::2] # =>[1, 4]
+# Avoir une copie de la liste à l'envers
+li[::-1] # => [3, 4, 2, 1]
+# Pour des "slices" plus élaborées :
+# li[debut:fin:pas]
+
+# Faire une copie d'une profondeur de un avec les "slices"
+li2 = li[:] # => li2 = [1, 2, 4, 3] mais (li2 is li) vaut False.
+
+# Enlever des éléments arbitrairement d'une liste
+del li[2] # li is now [1, 2, 3]
+
+# On peut additionner des listes
+# Note: les valeurs de li et other_li ne sont pas modifiées.
+li + other_li # => [1, 2, 3, 4, 5, 6]
# Concaténer des listes avec "extend()"
-li.extend(other_li) # li vaut maintenant [1, 2, 3, 4, 5, 6]
+li.extend(other_li) # Maintenant li contient [1, 2, 3, 4, 5, 6]
-# Vérifier l'existence d'un élément dans une liste avec "in"
-1 in li #=> True
+# Vérifier la présence d'un objet dans une liste avec "in"
+1 in li # => True
-# Récupérer la longueur avec "len()"
-len(li) #=> 6
+# Examiner la longueur avec "len()"
+len(li) # => 6
-# Les "tuples" sont comme des listes, mais sont immuables.
+# Les tuples sont comme des listes mais sont immuables.
tup = (1, 2, 3)
-tup[0] #=> 1
-tup[0] = 3 # Lève un 'TypeError'
-
-# Mais vous pouvez faire tout ceci sur les tuples:
-len(tup) #=> 3
-tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
-tup[:2] #=> (1, 2)
-2 in tup #=> True
-
-# Vous pouvez "dé-packager" les tuples (ou les listes) dans des variables
-a, b, c = (1, 2, 3) # a vaut maintenant 1, b vaut maintenant 2 and c vaut maintenant 3
-# Sans parenthèses, un tuple est créé par défaut
+tup[0] # => 1
+tup[0] = 3 # Lève une TypeError
+
+# Note : un tuple de taille un doit avoir une virgule après le dernier élément,
+# mais ce n'est pas le cas des tuples d'autres tailles, même zéro.
+type((1)) # => <class 'int'>
+type((1,)) # => <class 'tuple'>
+type(()) # => <class 'tuple'>
+
+# On peut utiliser la plupart des opérations des listes sur des tuples.
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# Vous pouvez décomposer des tuples (ou des listes) dans des variables
+a, b, c = (1, 2, 3) # a vaut 1, b vaut 2 et c vaut 3
+# Les tuples sont créés par défaut sans parenthèses
d, e, f = 4, 5, 6
-# Voyez maintenant comme il est facile d'inverser 2 valeurs
-e, d = d, e # d is now 5 and e is now 4
+# Voyez comme il est facile d'intervertir deux valeurs :
+e, d = d, e # d vaut maintenant 5 et e vaut maintenant 4
-# Dictionnaires
+# Créer un dictionnaire :
empty_dict = {}
-# Un dictionnaire pré-rempli
+# Un dictionnaire pré-rempli :
filled_dict = {"one": 1, "two": 2, "three": 3}
-# Trouver des valeurs avec []
-filled_dict["one"] #=> 1
+# Note : les clés des dictionnaires doivent être de types immuables.
+# Elles doivent être convertibles en une valeur constante pour une recherche rapide.
+# Les types immuables incluent les ints, floats, strings et tuples.
+invalid_dict = {[1,2,3]: "123"} # => Lève une TypeError: unhashable type: 'list'
+valid_dict = {(1,2,3):[1,2,3]} # Par contre, les valeurs peuvent être de tout type.
+
+# On trouve une valeur avec []
+filled_dict["one"] # => 1
+
+# On obtient toutes les clés sous forme d'un itérable avec "keys()" Il faut l'entourer
+# de list() pour avoir une liste Note: l'ordre n'est pas garanti.
+list(filled_dict.keys()) # => ["three", "two", "one"]
-# Récupérer toutes les clés sous forme de liste avec "keys()"
-filled_dict.keys() #=> ["three", "two", "one"]
-# Note - l'ordre des clés du dictionnaire n'est pas garanti.
-# Vos résultats peuvent différer de ceux ci-dessus.
-# Récupérer toutes les valeurs sous forme de liste avec "values()"
-filled_dict.values() #=> [3, 2, 1]
-# Note - Même remarque qu'au-dessus concernant l'ordre des valeurs.
+# On obtient toutes les valeurs sous forme d'un itérable avec "values()".
+# Là aussi, il faut utiliser list() pour avoir une liste.
+# Note : l'ordre n'est toujours pas garanti.
+list(filled_dict.values()) # => [3, 2, 1]
-# Vérifier l'existence d'une clé dans le dictionnaire avec "in"
-"one" in filled_dict #=> True
-1 in filled_dict #=> False
-# Chercher une clé non existante lève une 'KeyError'
-filled_dict["four"] # KeyError
+# On vérifie la présence d'une clé dans un dictionnaire avec "in"
+"one" in filled_dict # => True
+1 in filled_dict # => False
-# Utiliser la méthode "get()" pour éviter 'KeyError'
-filled_dict.get("one") #=> 1
-filled_dict.get("four") #=> None
-# La méthode get() prend un argument par défaut quand la valeur est inexistante
-filled_dict.get("one", 4) #=> 1
-filled_dict.get("four", 4) #=> 4
+# L'accès à une clé non-existente lève une KeyError
+filled_dict["four"] # KeyError
-# La méthode "setdefault()" permet d'ajouter de manière sécuris une paire clé-valeur dans le dictionnnaire
-filled_dict.setdefault("five", 5) #filled_dict["five"] vaut 5
-filled_dict.setdefault("five", 6) #filled_dict["five"] is toujours 5
+# On utilise "get()" pour éviter la KeyError
+filled_dict.get("one") # => 1
+filled_dict.get("four") # => None
+# La méthode get accepte une valeur de retour par défaut en cas de valeur non-existante.
+filled_dict.get("one", 4) # => 1
+filled_dict.get("four", 4) # => 4
+# "setdefault()" insère une valeur dans un dictionnaire si la clé n'est pas présente.
+filled_dict.setdefault("five", 5) # filled_dict["five"] devient 5
+filled_dict.setdefault("five", 6) # filled_dict["five"] est toujours 5
-# Les sets stockent ... des sets
+# Ajouter à un dictionnaire
+filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4}
+#filled_dict["four"] = 4 # une autre méthode
+
+# Enlever des clés d'un dictionnaire avec del
+del filled_dict["one"] # Enlever la clé "one" de filled_dict.
+
+
+# Les sets stockent des ensembles
empty_set = set()
-# On initialise un "set()" avec tout un tas de valeurs
-some_set = set([1,2,2,3,4]) # some_set vaut maintenant set([1, 2, 3, 4])
+# Initialiser un set avec des valeurs. Oui, ça ressemble aux dictionnaires, désolé.
+some_set = {1, 1, 2, 2, 3, 4} # some_set est maintenant {1, 2, 3, 4}
+
+# Comme les clés d'un dictionnaire, les éléments d'un set doivent être immuables.
+invalid_set = {[1], 1} # => Lève une TypeError: unhashable type: 'list'
+valid_set = {(1,), 1}
-# Depuis Python 2.7, {} peut être utilisé pour déclarer un 'set'
-filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+# On peut changer un set :
+filled_set = some_set
-# Ajouter plus d'éléments au set
-filled_set.add(5) # filled_set contient maintenant {1, 2, 3, 4, 5}
+# Ajouter un objet au set :
+filled_set.add(5) # filled_set vaut maintenant {1, 2, 3, 4, 5}
-# Intersection de sets avec &
+# Chercher les intersections de deux sets avec &
other_set = {3, 4, 5, 6}
-filled_set & other_set #=> {3, 4, 5}
+filled_set & other_set # => {3, 4, 5}
-# Union de sets avec |
-filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+# On fait l'union de sets avec |
+filled_set | other_set # => {1, 2, 3, 4, 5, 6}
-# Différence de sets avec -
-{1,2,3,4} - {2,3,5} #=> {1, 4}
+# On fait la différence de deux sets avec -
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+
+# On vérifie la présence d'un objet dans un set avec in
+2 in filled_set # => True
+10 in filled_set # => False
-# Vérifier l'existence d'une valeur dans un set avec "in"
-2 in filled_set #=> True
-10 in filled_set #=> False
####################################################
-## 3. Structure de contrôle
+## 3. Structures de contrôle et Itérables
####################################################
-# Initialisons une variable
+# On crée juste une variable
some_var = 5
-# Voici une condition 'if'. L'indentation est significative en Python !
-# Affiche "some_var est inférieur à 10"
+# Voici une condition "si". L'indentation est significative en Python!
+# Affiche: "some_var is smaller than 10"
if some_var > 10:
- print "some_var est supérieur à 10."
-elif some_var < 10: # La clause elif est optionnelle
- print "some_var iinférieur à 10."
-else: # La clause else également
- print "some_var vaut 10."
+ print("some_var is totally bigger than 10.")
+elif some_var < 10: # La clause elif ("sinon si") est optionelle
+ print("some_var is smaller than 10.")
+else: # La clause else ("sinon") l'est aussi.
+ print("some_var is indeed 10.")
"""
-Les boucles "for" permettent d'itérer sur les listes
+Les boucles "for" itèrent sur une liste
Affiche:
- chien : mammifère
- chat : mammifère
- souris : mammifère
+ chien est un mammifère
+ chat est un mammifère
+ souris est un mammifère
"""
for animal in ["chien", "chat", "souris"]:
- # On peut utiliser % pour l'interpolation des chaînes formattées
- print "%s : mammifère" % animal
+ # On peut utiliser format() pour interpoler des chaînes formattées
+ print("{} est un mammifère".format(animal))
"""
-"range(number)" retourne une liste de nombres
-de 0 au nombre donné
+"range(nombre)" retourne un itérable de nombres
+de zéro au nombre donné
Affiche:
0
1
@@ -295,10 +379,34 @@ Affiche:
3
"""
for i in range(4):
- print i
+ print(i)
+
+"""
+"range(debut, fin)" retourne un itérable de nombre
+de debut à fin.
+Affiche:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print(i)
"""
-Les boucles "while" boucle jusqu'à ce que leur condition ne soit plus vraie
+"range(debut, fin, pas)" retourne un itérable de nombres
+de début à fin en incrémentant de pas.
+Si le pas n'est pas indiqué, la valeur par défaut est 1.
+Affiche:
+ 4
+ 6
+ 8
+"""
+for i in range(4, 8, 2):
+ print(i)
+"""
+
+Les boucles "while" bouclent jusqu'à ce que la condition devienne fausse.
Affiche:
0
1
@@ -307,66 +415,135 @@ Affiche:
"""
x = 0
while x < 4:
- print x
+ print(x)
x += 1 # Raccourci pour x = x + 1
-# Gérer les exceptions avec un bloc try/except
-
-# Fonctionne pour Python 2.6 et ultérieur:
+# On gère les exceptions avec un bloc try/except
try:
- # Utiliser "raise" pour lever une exception
- raise IndexError("This is an index error")
+ # On utilise "raise" pour lever une erreur
+ raise IndexError("Ceci est une erreur d'index")
except IndexError as e:
- pass # Pass ne prend pas d'arguments. Généralement, on gère l'erreur ici.
+ pass # Pass signifie simplement "ne rien faire". Généralement, on gère l'erreur ici.
+except (TypeError, NameError):
+ pass # Si besoin, on peut aussi gérer plusieurs erreurs en même temps.
+else: # Clause optionelle des blocs try/except. Doit être après tous les except.
+ print("Tout va bien!") # Uniquement si aucune exception n'est levée.
+finally: # Éxécuté dans toutes les circonstances.
+ print("On nettoie les ressources ici")
+
+# Au lieu de try/finally pour nettoyer les ressources, on peut utiliser with
+with open("myfile.txt") as f:
+ for line in f:
+ print(line)
+
+# Python offre une abstraction fondamentale : l'Iterable.
+# Un itérable est un objet pouvant être traîté comme une séquence.
+# L'objet retourné par la fonction range() est un itérable.
+
+filled_dict = {"one": 1, "two": 2, "three": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) #=> range(1,10). C'est un objet qui implémente l'interface Iterable
+
+# On peut boucler dessus
+for i in our_iterable:
+ print(i) # Affiche one, two, three
+
+# Cependant, on ne peut pas accéder aux éléments par leur adresse.
+our_iterable[1] # Lève une TypeError
+
+# Un itérable est un objet qui sait créer un itérateur.
+our_iterator = iter(our_iterable)
+
+# Notre itérateur est un objet qui se rappelle de notre position quand on le traverse.
+# On passe à l'élément suivant avec "next()".
+next(our_iterator) #=> "one"
+
+# Il garde son état quand on itère.
+next(our_iterator) #=> "two"
+next(our_iterator) #=> "three"
+
+# Après que l'itérateur a retourné toutes ses données, il lève une exception StopIterator
+next(our_iterator) # Lève une StopIteration
+
+# On peut mettre tous les éléments d'un itérateur dans une liste avec list()
+list(filled_dict.keys()) #=> Returns ["one", "two", "three"]
####################################################
## 4. Fonctions
####################################################
-# Utiliser "def" pour créer une nouvelle fonction
+# On utilise "def" pour créer des fonctions
def add(x, y):
- print "x vaut %s et y vaur %s" % (x, y)
- return x + y # Renvoi de valeur avec 'return'
+ print("x est {} et y est {}".format(x, y))
+ return x + y # On retourne une valeur avec return
-# Appeller une fonction avec des paramètres
-add(5, 6) #=> Affichet "x is 5 et y vaut 6" et renvoie 11
+# Appel d'une fonction avec des paramètres :
+add(5, 6) # => affiche "x est 5 et y est 6" et retourne 11
-# Une autre manière d'appeller une fonction, avec les arguments
-add(y=6, x=5) # Les arguments peuvent venir dans n'importe quel ordre.
+# Une autre manière d'appeler une fonction : avec des arguments
+add(y=6, x=5) # Les arguments peuvent être dans n'importe quel ordre.
-# On peut définir une foncion qui prend un nombre variable de paramètres
+# Définir une fonction qui prend un nombre variable d'arguments
def varargs(*args):
return args
-varargs(1, 2, 3) #=> (1,2,3)
+varargs(1, 2, 3) # => (1, 2, 3)
-
-# On peut également définir une fonction qui prend un nombre
-# variable d'arguments
+# On peut aussi définir une fonction qui prend un nombre variable de paramètres.
def keyword_args(**kwargs):
return kwargs
-# Appelons-là et voyons ce qu'il se passe
-keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+# Appelons la pour voir ce qu'il se passe :
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
+
-# On peut faire les deux à la fois si on le souhaite
+# On peut aussi faire les deux à la fois :
def all_the_args(*args, **kwargs):
- print args
- print kwargs
+ print(args)
+ print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) affiche:
(1, 2)
{"a": 3, "b": 4}
"""
-# En appellant les fonctions, on peut faire l'inverse des paramètres / arguments !
-# Utiliser * pour développer les paramètres, et ** pour développer les arguments
-params = (1, 2, 3, 4)
-args = {"a": 3, "b": 4}
-all_the_args(*args) # equivaut à foo(1, 2, 3, 4)
-all_the_args(**kwargs) # equivaut à foo(a=3, b=4)
-all_the_args(*args, **kwargs) # equivaut à foo(1, 2, 3, 4, a=3, b=4)
+# En appelant des fonctions, on peut aussi faire l'inverse :
+# utiliser * pour étendre un tuple de paramètres
+# et ** pour étendre un dictionnaire d'arguments.
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # équivalent à foo(1, 2, 3, 4)
+all_the_args(**kwargs) # équivalent à foo(a=3, b=4)
+all_the_args(*args, **kwargs) # équivalent à foo(1, 2, 3, 4, a=3, b=4)
+
+# Retourne plusieurs valeurs (avec un tuple)
+def swap(x, y):
+ return y, x # Retourne plusieurs valeurs avec un tuple sans parenthèses.
+ # (Note: on peut aussi utiliser des parenthèses)
+
+x = 1
+y = 2
+x, y = swap(x, y) # => x = 2, y = 1
+# (x, y) = swap(x,y) # Là aussi, rien ne nous empêche d'ajouter des parenthèses
+
+# Portée des fonctions :
+x = 5
+
+def setX(num):
+ # La variable locale x n'est pas la même que la variable globale x
+ x = num # => 43
+ print (x) # => 43
+
+def setGlobalX(num):
+ global x
+ print (x) # => 5
+ x = num # la variable globale x est maintenant 6
+ print (x) # => 6
+
+setX(43)
+setGlobalX(6)
+
# Python a des fonctions de première classe
def create_adder(x):
@@ -375,67 +552,78 @@ def create_adder(x):
return adder
add_10 = create_adder(10)
-add_10(3) #=> 13
+add_10(3) # => 13
-# Mais également des fonctions anonymes
-(lambda x: x > 2)(3) #=> True
+# Mais aussi des fonctions anonymes
+(lambda x: x > 2)(3) # => True
+(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
-# On trouve aussi des fonctions intégrées plus évoluées
-map(add_10, [1,2,3]) #=> [11, 12, 13]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+# TODO - Fix for iterables
+# Il y a aussi des fonctions de base
+map(add_10, [1, 2, 3]) # => [11, 12, 13]
+map(max, [1, 2, 3], [4, 2, 1]) # => [4, 2, 3]
-# On peut utiliser la syntaxe des liste pour construire les "maps" et les "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]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+
+# On peut utiliser les compréhensions de listes pour de jolies maps et filtres.
+# Une compréhension de liste stocke la sortie comme une liste qui peut elle même être une liste imbriquée.
+[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
####################################################
## 5. Classes
####################################################
-# Une classe est un objet
-class Human(object):
- # Un attribut de classe. Il est partagé par toutes les instances de cette classe.
+# On utilise l'opérateur "class" pour définir une classe
+class Human:
+
+ # Un attribut de la classe. Il est partagé par toutes les instances de la classe.
species = "H. sapiens"
- # Initialiseur basique
+ # L'initialiseur de base. Il est appelé quand la classe est instanciée.
+ # Note : les doubles underscores au début et à la fin sont utilisés pour
+ # les fonctions et attributs utilisés par Python mais contrôlés par l'utilisateur.
+ # Les méthodes (ou objets ou attributs) comme: __init__, __str__,
+ # __repr__ etc. sont appelés méthodes magiques.
+ # Vous ne devriez pas inventer de noms de ce style.
def __init__(self, name):
- # Assigne le paramètre à l'attribut de l'instance de classe.
+ # Assigner l'argument à l'attribut de l'instance
self.name = name
- # Une méthode de l'instance. Toutes les méthodes prennent "self" comme 1er paramètre.
+ # Une méthode de l'instance. Toutes prennent "self" comme premier argument.
def say(self, msg):
- return "%s: %s" % (self.name, msg)
+ return "{name}: {message}".format(name=self.name, message=msg)
- # Une méthode de classe est partagée par toutes les instances.
- # On les appelle avec le nom de la classe en premier paramètre
+ # Une méthode de classe est partagée avec entre les instances
+ # Ils sont appelés avec la classe comme premier argument
@classmethod
def get_species(cls):
return cls.species
- # Une méthode statique est appellée sans référence à une classe ou à une instance
+ # Une méthode statique est appelée sans référence à une instance ni à une classe.
@staticmethod
def grunt():
return "*grunt*"
-# Instancier une classe
+# Instantier une classe
i = Human(name="Ian")
-print i.say("hi") # Affiche "Ian: hi"
+print(i.say("hi")) # affiche "Ian: hi"
j = Human("Joel")
-print j.say("hello") #Affiche "Joel: hello"
+print(j.say("hello")) # affiche "Joel: hello"
# Appeller notre méthode de classe
-i.get_species() #=> "H. sapiens"
+i.get_species() # => "H. sapiens"
# Changer les attributs partagés
Human.species = "H. neanderthalensis"
-i.get_species() #=> "H. neanderthalensis"
-j.get_species() #=> "H. neanderthalensis"
+i.get_species() # => "H. neanderthalensis"
+j.get_species() # => "H. neanderthalensis"
# Appeller la méthode statique
-Human.grunt() #=> "*grunt*"
+Human.grunt() # => "*grunt*"
####################################################
@@ -444,45 +632,101 @@ Human.grunt() #=> "*grunt*"
# On peut importer des modules
import math
-print math.sqrt(16) #=> 4
+print(math.sqrt(16)) # => 4.0
-# Et récupérer des fonctions spécifiques d'un module
+# On peut importer des fonctions spécifiques d'un module
from math import ceil, floor
-print ceil(3.7) #=> 4.0
-print floor(3.7) #=> 3.0
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
-# Récuperer toutes les fonctions d'un module
-# Attention, ce n'est pas recommandé.
+# On peut importer toutes les fonctions d'un module
+# Attention: ce n'est pas recommandé.
from math import *
-# On peut raccourcir le nom d'un module
+# On peut raccourcir un nom de module
import math as m
-math.sqrt(16) == m.sqrt(16) #=> True
+math.sqrt(16) == m.sqrt(16) # => True
-# Les modules Python sont juste des fichiers Python ordinaires.
-# On peut écrire ses propres modules et les importer.
-# Le nom du module doit être le même que le nom du fichier.
+# Les modules Python sont juste des fichiers Python.
+# Vous pouvez écrire les vôtres et les importer. Le nom du module
+# est le nom du fichier.
-# On peut trouver quelle fonction et attributs déterminent un module
+# On peut voir quels fonctions et objets un module définit
import math
dir(math)
+####################################################
+## 7. Avancé
+####################################################
+
+# Les générateurs aident à faire du code paresseux (lazy)
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# Un générateur crée des valeurs à la volée.
+# Au lieu de générer et retourner toutes les valeurs en une fois, il en crée une à chaque
+# itération. Cela signifie que les valeurs supérieures à 30 ne seront pas traîtées par
+# double_numbers.
+# Note : range est un générateur aussi.
+# Créer une liste 1-900000000 prendrait beaucoup de temps
+# On met un underscore à la fin d'un nom de variable normalement réservé par Python.
+range_ = range(1, 900000000)
+# Double tous les nombres jusqu'à ce qu'un nombre >=30 soit trouvé
+for i in double_numbers(range_):
+ print(i)
+ if i >= 30:
+ break
+
+
+# Decorateurs
+# Dans cet exemple, beg enveloppe say
+# Beg appellera say. Si say_please vaut True le message retourné sera changé
+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()) # affiche Can you buy me a beer?
+print(say(say_please=True)) # affiche Can you buy me a beer? Please! I am poor :(
```
-## Prêt à aller plus loin?
+## Prêt pour encore plus ?
-### En ligne gratuitement
+### En ligne et gratuit (en anglais)
+* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
* [Dive Into Python](http://www.diveintopython.net/)
-* [The Official Docs](http://docs.python.org/2.6/)
+* [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 Module of the Week](http://pymotw.com/2/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+* [Python Course](http://www.python-course.eu/index.php)
+* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
+
+### En ligne et gratuit (en français)
-### Format papier
+* [Le petit guide des batteries à découvrir](https://he-arc.github.io/livre-python/)
+
+### Livres (en anglais)
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
-
diff --git a/fr-fr/python3-fr.html.markdown b/fr-fr/python3-fr.html.markdown
deleted file mode 100644
index 3d60157c..00000000
--- a/fr-fr/python3-fr.html.markdown
+++ /dev/null
@@ -1,723 +0,0 @@
----
-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"]
-translators:
- - ["Gnomino", "https://github.com/Gnomino"]
-filename: learnpython3-fr.py
-lang: fr-fr
----
-
-Python a été créé par Guido Van Rossum au début des années 90. C'est maintenant un des
-langages les populaires. Je suis tombé amoureux de Python pour la clarté de sa syntaxe.
-C'est tout simplement du pseudo-code exécutable.
-
-L'auteur original apprécierait les retours (en anglais): vous pouvez le contacter sur Twitter à [@louiedinh](http://twitter.com/louiedinh) ou par mail à l'adresse louiedinh [at] [google's email service]
-
-Note : Cet article s'applique spécifiquement à Python 3. Jettez un coup d'oeil [ici](http://learnxinyminutes.com/docs/fr-fr/python-fr/) pour apprendre le vieux Python 2.7
-
-```python
-
-# Un commentaire d'une ligne commence par un dièse
-
-""" Les chaînes de caractères peuvent être écrites
- avec 3 guillemets doubles ("), et sont souvent
- utilisées comme des commentaires.
-"""
-
-####################################################
-## 1. Types de données primaires et opérateurs
-####################################################
-
-# On a des nombres
-3 # => 3
-
-# Les calculs sont ce à quoi on s'attend
-1 + 1 # => 2
-8 - 1 # => 7
-10 * 2 # => 20
-
-# Sauf pour la division qui retourne un float (nombre à virgule flottante)
-35 / 5 # => 7.0
-
-# Résultats de divisions entières tronqués pour les nombres positifs et négatifs
-5 // 3 # => 1
-5.0 // 3.0 # => 1.0 # works on floats too
--5 // 3 # => -2
--5.0 // 3.0 # => -2.0
-
-# Quand on utilise un float, le résultat est un float
-3 * 2.0 # => 6.0
-
-# Modulo (reste de la division)
-7 % 3 # => 1
-
-# Exponentiation (x**y, x élevé à la puissance y)
-2**4 # => 16
-
-# Forcer la priorité de calcul avec des parenthèses
-(1 + 3) * 2 # => 8
-
-# Les valeurs booléennes sont primitives
-True
-False
-
-# Négation avec not
-not True # => False
-not False # => True
-
-# Opérateurs booléens
-# On note que "and" et "or" sont sensibles à la casse
-True and False #=> False
-False or True #=> True
-
-# Utilisation des opérations booléennes avec des entiers :
-0 and 2 #=> 0
--5 or 0 #=> -5
-0 == False #=> True
-2 == True #=> False
-1 == True #=> True
-
-# On vérifie une égalité avec ==
-1 == 1 # => True
-2 == 1 # => False
-
-# On vérifie une inégalité avec !=
-1 != 1 # => False
-2 != 1 # => True
-
-# Autres opérateurs de comparaison
-1 < 10 # => True
-1 > 10 # => False
-2 <= 2 # => True
-2 >= 2 # => True
-
-# On peut enchaîner les comparaisons
-1 < 2 < 3 # => True
-2 < 3 < 2 # => False
-
-# (is vs. ==) is vérifie si deux variables pointent sur le même objet, mais == vérifie
-# si les objets ont la même valeur.
-a = [1, 2, 3, 4] # a pointe sur une nouvelle liste, [1, 2, 3, 4]
-b = a # b pointe sur a
-b is a # => True, a et b pointent sur le même objet
-b == a # => True, les objets a et b sont égaux
-b = [1, 2, 3, 4] # b pointe sur une nouvelle liste, [1, 2, 3, 4]
-b is a # => False, a et b ne pointent pas sur le même objet
-b == a # => True, les objets a et b ne pointent pas sur le même objet
-
-# Les chaînes (ou strings) sont créées avec " ou '
-"Ceci est une chaine"
-'Ceci est une chaine aussi.'
-
-# On peut additionner des chaînes aussi ! Mais essayez d'éviter de le faire.
-"Hello " + "world!" # => "Hello world!"
-# On peut aussi le faire sans utiliser '+'
-"Hello " "world!" # => "Hello world!"
-
-# On peut traîter une chaîne comme une liste de caractères
-"This is a string"[0] # => 'T'
-
-# .format peut être utilisé pour formatter des chaînes, comme ceci:
-"{} peuvent etre {}".format("Les chaînes", "interpolées")
-
-# On peut aussi réutiliser le même argument pour gagner du temps.
-"{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"
-
-# On peut aussi utiliser des mots clés pour éviter de devoir compter.
-"{name} wants to eat {food}".format(name="Bob", food="lasagna") #=> "Bob wants to eat lasagna"
-
-# Si votre code doit aussi être compatible avec Python 2.5 et moins,
-# vous pouvez encore utiliser l'ancienne syntaxe :
-"Les %s peuvent être %s avec la %s méthode" % ("chaînes", "interpolées", "vieille")
-
-
-# None est un objet
-None # => None
-
-# N'utilisez pas "==" pour comparer des objets à None
-# Utilisez plutôt "is". Cela permet de vérifier l'égalité de l'identité des objets.
-"etc" is None # => False
-None is None # => True
-
-# None, 0, and les strings/lists/dicts (chaînes/listes/dictionnaires) valent False lorsqu'ils sont convertis en booléens.
-# Toutes les autres valeurs valent True
-bool(0) # => False
-bool("") # => False
-bool([]) #=> False
-bool({}) #=> False
-
-
-####################################################
-## 2. Variables et Collections
-####################################################
-
-# Python a une fonction print pour afficher du texte
-print("I'm Python. Nice to meet you!")
-
-# Par défaut, la fonction print affiche aussi une nouvelle ligne à la fin.
-# Utilisez l'argument optionnel end pour changer ce caractère de fin.
-print("Hello, World", end="!") # => Hello, World!
-
-# Pas besoin de déclarer des variables avant de les définir.
-# La convention est de nommer ses variables avec des minuscules_et_underscores
-some_var = 5
-some_var # => 5
-
-# Tenter d'accéder à une variable non définie lève une exception.
-# Voir Structures de contrôle pour en apprendre plus sur le traitement des exceptions.
-une_variable_inconnue # Lève une NameError
-
-# Les listes permettent de stocker des séquences
-li = []
-# On peut initialiser une liste pré-remplie
-other_li = [4, 5, 6]
-
-# On ajoute des objets à la fin d'une liste avec .append
-li.append(1) # li vaut maintenant [1]
-li.append(2) # li vaut maintenant [1, 2]
-li.append(4) # li vaut maintenant [1, 2, 4]
-li.append(3) # li vaut maintenant [1, 2, 4, 3]
-# On enlève le dernier élément avec .pop
-li.pop() # => 3 et li vaut maintenant [1, 2, 4]
-# Et on le remet
-li.append(3) # li vaut de nouveau [1, 2, 4, 3]
-
-# Accès à un élément d'une liste :
-li[0] # => 1
-# Accès au dernier élément :
-li[-1] # => 3
-
-# Accéder à un élément en dehors des limites lève une IndexError
-li[4] # Lève une IndexError
-
-# On peut accéder à une intervalle avec la syntaxe "slice"
-# (c'est un rang du type "fermé/ouvert")
-li[1:3] # => [2, 4]
-# Omettre les deux premiers éléments
-li[2:] # => [4, 3]
-# Prendre les trois premiers
-li[:3] # => [1, 2, 4]
-# Sélectionner un élément sur deux
-li[::2] # =>[1, 4]
-# Avoir une copie de la liste à l'envers
-li[::-1] # => [3, 4, 2, 1]
-# Pour des "slices" plus élaborées :
-# li[debut:fin:pas]
-
-# Faire une copie d'une profondeur de un avec les "slices"
-li2 = li[:] # => li2 = [1, 2, 4, 3] mais (li2 is li) vaut False.
-
-# Enlever des éléments arbitrairement d'une liste
-del li[2] # li is now [1, 2, 3]
-
-# On peut additionner des listes
-# Note: les valeurs de li et other_li ne sont pas modifiées.
-li + other_li # => [1, 2, 3, 4, 5, 6]
-
-# Concaténer des listes avec "extend()"
-li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
-
-# Vérifier la présence d'un objet dans une liste avec "in"
-1 in li # => True
-
-# Examiner la longueur avec "len()"
-len(li) # => 6
-
-
-# Les tuples sont comme des listes mais sont immuables.
-tup = (1, 2, 3)
-tup[0] # => 1
-tup[0] = 3 # Lève une TypeError
-
-# Note : un tuple de taille un doit avoir une virgule après le dernier élément,
-# mais ce n'est pas le cas des tuples d'autres tailles, même zéro.
-type((1)) # => <class 'int'>
-type((1,)) # => <class 'tuple'>
-type(()) # => <class 'tuple'>
-
-# On peut utiliser la plupart des opérations des listes sur des tuples.
-len(tup) # => 3
-tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
-tup[:2] # => (1, 2)
-2 in tup # => True
-
-# Vous pouvez décomposer des tuples (ou des listes) dans des variables
-a, b, c = (1, 2, 3) # a vaut 1, b vaut 2 et c vaut 3
-# Les tuples sont créés par défaut sans parenthèses
-d, e, f = 4, 5, 6
-# Voyez comme il est facile d'intervertir deux valeurs :
-e, d = d, e # d vaut maintenant 5 et e vaut maintenant 4
-
-
-# Créer un dictionnaire :
-empty_dict = {}
-# Un dictionnaire pré-rempli :
-filled_dict = {"one": 1, "two": 2, "three": 3}
-
-# Note : les clés des dictionnaires doivent être de types immuables.
-# Elles doivent être convertibles en une valeur constante pour une recherche rapide.
-# Les types immuables incluent les ints, floats, strings et tuples.
-invalid_dict = {[1,2,3]: "123"} # => Lève une TypeError: unhashable type: 'list'
-valid_dict = {(1,2,3):[1,2,3]} # Par contre, les valeurs peuvent être de tout type.
-
-# On trouve une valeur avec []
-filled_dict["one"] # => 1
-
-# On obtient toutes les clés sous forme d'un itérable avec "keys()" Il faut l'entourer
-# de list() pour avoir une liste Note: l'ordre n'est pas garanti.
-list(filled_dict.keys()) # => ["three", "two", "one"]
-
-
-# On obtient toutes les valeurs sous forme d'un itérable avec "values()".
-# Là aussi, il faut utiliser list() pour avoir une liste.
-# Note : l'ordre n'est toujours pas garanti.
-list(filled_dict.values()) # => [3, 2, 1]
-
-
-# On vérifie la présence d'une clé dans un dictionnaire avec "in"
-"one" in filled_dict # => True
-1 in filled_dict # => False
-
-# L'accès à une clé non-existente lève une KeyError
-filled_dict["four"] # KeyError
-
-# On utilise "get()" pour éviter la KeyError
-filled_dict.get("one") # => 1
-filled_dict.get("four") # => None
-# La méthode get accepte une valeur de retour par défaut en cas de valeur non-existante.
-filled_dict.get("one", 4) # => 1
-filled_dict.get("four", 4) # => 4
-
-# "setdefault()" insère une valeur dans un dictionnaire si la clé n'est pas présente.
-filled_dict.setdefault("five", 5) # filled_dict["five"] devient 5
-filled_dict.setdefault("five", 6) # filled_dict["five"] est toujours 5
-
-# Ajouter à un dictionnaire
-filled_dict.update({"four":4}) #=> {"one": 1, "two": 2, "three": 3, "four": 4}
-#filled_dict["four"] = 4 # une autre méthode
-
-# Enlever des clés d'un dictionnaire avec del
-del filled_dict["one"] # Enlever la clé "one" de filled_dict.
-
-
-# Les sets stockent des ensembles
-empty_set = set()
-# Initialiser un set avec des valeurs. Oui, ça ressemble aux dictionnaires, désolé.
-some_set = {1, 1, 2, 2, 3, 4} # some_set est maintenant {1, 2, 3, 4}
-
-# Comme les clés d'un dictionnaire, les éléments d'un set doivent être immuables.
-invalid_set = {[1], 1} # => Lève une TypeError: unhashable type: 'list'
-valid_set = {(1,), 1}
-
-# On peut changer un set :
-filled_set = some_set
-
-# Ajouter un objet au set :
-filled_set.add(5) # filled_set vaut maintenant {1, 2, 3, 4, 5}
-
-# Chercher les intersections de deux sets avec &
-other_set = {3, 4, 5, 6}
-filled_set & other_set # => {3, 4, 5}
-
-# On fait l'union de sets avec |
-filled_set | other_set # => {1, 2, 3, 4, 5, 6}
-
-# On fait la différence de deux sets avec -
-{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
-
-# On vérifie la présence d'un objet dans un set avec in
-2 in filled_set # => True
-10 in filled_set # => False
-
-
-
-####################################################
-## 3. Structures de contrôle et Itérables
-####################################################
-
-# On crée juste une variable
-some_var = 5
-
-# Voici une condition "si". L'indentation est significative en Python!
-# Affiche: "some_var is smaller than 10"
-if some_var > 10:
- print("some_var is totally bigger than 10.")
-elif some_var < 10: # La clause elif ("sinon si") est optionelle
- print("some_var is smaller than 10.")
-else: # La clause else ("sinon") l'est aussi.
- print("some_var is indeed 10.")
-
-
-"""
-Les boucles "for" itèrent sur une liste
-Affiche:
- chien est un mammifère
- chat est un mammifère
- souris est un mammifère
-"""
-for animal in ["chien", "chat", "souris"]:
- # On peut utiliser format() pour interpoler des chaînes formattées
- print("{} est un mammifère".format(animal))
-
-"""
-"range(nombre)" retourne un itérable de nombres
-de zéro au nombre donné
-Affiche:
- 0
- 1
- 2
- 3
-"""
-for i in range(4):
- print(i)
-
-"""
-"range(debut, fin)" retourne un itérable de nombre
-de debut à fin.
-Affiche:
- 4
- 5
- 6
- 7
-"""
-for i in range(4, 8):
- print(i)
-
-"""
-"range(debut, fin, pas)" retourne un itérable de nombres
-de début à fin en incrémentant de pas.
-Si le pas n'est pas indiqué, la valeur par défaut est 1.
-Affiche:
- 4
- 6
- 8
-"""
-for i in range(4, 8, 2):
- print(i)
-"""
-
-Les boucles "while" bouclent jusqu'à ce que la condition devienne fausse.
-Affiche:
- 0
- 1
- 2
- 3
-"""
-x = 0
-while x < 4:
- print(x)
- x += 1 # Raccourci pour x = x + 1
-
-# On gère les exceptions avec un bloc try/except
-try:
- # On utilise "raise" pour lever une erreur
- raise IndexError("Ceci est une erreur d'index")
-except IndexError as e:
- pass # Pass signifie simplement "ne rien faire". Généralement, on gère l'erreur ici.
-except (TypeError, NameError):
- pass # Si besoin, on peut aussi gérer plusieurs erreurs en même temps.
-else: # Clause optionelle des blocs try/except. Doit être après tous les except.
- print("Tout va bien!") # Uniquement si aucune exception n'est levée.
-finally: # Éxécuté dans toutes les circonstances.
- print("On nettoie les ressources ici")
-
-# Au lieu de try/finally pour nettoyer les ressources, on peut utiliser with
-with open("myfile.txt") as f:
- for line in f:
- print(line)
-
-# Python offre une abstraction fondamentale : l'Iterable.
-# Un itérable est un objet pouvant être traîté comme une séquence.
-# L'objet retourné par la fonction range() est un itérable.
-
-filled_dict = {"one": 1, "two": 2, "three": 3}
-our_iterable = filled_dict.keys()
-print(our_iterable) #=> range(1,10). C'est un objet qui implémente l'interface Iterable
-
-# On peut boucler dessus
-for i in our_iterable:
- print(i) # Affiche one, two, three
-
-# Cependant, on ne peut pas accéder aux éléments par leur adresse.
-our_iterable[1] # Lève une TypeError
-
-# Un itérable est un objet qui sait créer un itérateur.
-our_iterator = iter(our_iterable)
-
-# Notre itérateur est un objet qui se rappelle de notre position quand on le traverse.
-# On passe à l'élément suivant avec "next()".
-next(our_iterator) #=> "one"
-
-# Il garde son état quand on itère.
-next(our_iterator) #=> "two"
-next(our_iterator) #=> "three"
-
-# Après que l'itérateur a retourné toutes ses données, il lève une exception StopIterator
-next(our_iterator) # Lève une StopIteration
-
-# On peut mettre tous les éléments d'un itérateur dans une liste avec list()
-list(filled_dict.keys()) #=> Returns ["one", "two", "three"]
-
-
-####################################################
-## 4. Fonctions
-####################################################
-
-# On utilise "def" pour créer des fonctions
-def add(x, y):
- print("x est {} et y est {}".format(x, y))
- return x + y # On retourne une valeur avec return
-
-# Appel d'une fonction avec des paramètres :
-add(5, 6) # => affiche "x est 5 et y est 6" et retourne 11
-
-# Une autre manière d'appeller une fonction : avec des arguments
-add(y=6, x=5) # Les arguments peuvent être dans n'importe quel ordre.
-
-# Définir une fonction qui prend un nombre variable d'arguments
-def varargs(*args):
- return args
-
-varargs(1, 2, 3) # => (1, 2, 3)
-
-# On peut aussi définir une fonction qui prend un nombre variable de paramètres.
-def keyword_args(**kwargs):
- return kwargs
-
-# Appelons la pour voir ce qu'il se passe :
-keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
-
-
-# On peut aussi faire les deux à la fois :
-def all_the_args(*args, **kwargs):
- print(args)
- print(kwargs)
-"""
-all_the_args(1, 2, a=3, b=4) affiche:
- (1, 2)
- {"a": 3, "b": 4}
-"""
-
-# En appelant des fonctions, on peut aussi faire l'inverse :
-# utiliser * pour étendre un tuple de paramètres
-# et ** pour étendre un dictionnaire d'arguments.
-args = (1, 2, 3, 4)
-kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # équivalent à foo(1, 2, 3, 4)
-all_the_args(**kwargs) # équivalent à foo(a=3, b=4)
-all_the_args(*args, **kwargs) # équivalent à foo(1, 2, 3, 4, a=3, b=4)
-
-# Retourne plusieurs valeurs (avec un tuple)
-def swap(x, y):
- return y, x # Retourne plusieurs valeurs avec un tuple sans parenthèses.
- # (Note: on peut aussi utiliser des parenthèses)
-
-x = 1
-y = 2
-x, y = swap(x, y) # => x = 2, y = 1
-# (x, y) = swap(x,y) # Là aussi, rien ne nous empêche d'ajouter des parenthèses
-
-# Portée des fonctions :
-x = 5
-
-def setX(num):
- # La variable locale x n'est pas la même que la variable globale x
- x = num # => 43
- print (x) # => 43
-
-def setGlobalX(num):
- global x
- print (x) # => 5
- x = num # la variable globale x est maintenant 6
- print (x) # => 6
-
-setX(43)
-setGlobalX(6)
-
-
-# Python a des fonctions de première classe
-def create_adder(x):
- def adder(y):
- return x + y
- return adder
-
-add_10 = create_adder(10)
-add_10(3) # => 13
-
-# Mais aussi des fonctions anonymes
-(lambda x: x > 2)(3) # => True
-(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
-
-# TODO - Fix for iterables
-# Il y a aussi des fonctions de base
-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]
-
-# On peut utiliser les compréhensions de listes pour de jolies maps et filtres.
-# Une compréhension de liste stocke la sortie comme une liste qui peut elle même être une liste imbriquée.
-[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
-[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
-
-####################################################
-## 5. Classes
-####################################################
-
-
-# On utilise l'opérateur "classe" pour définir une classe
-class Human:
-
- # Un attribut de la classe. Il est partagé par toutes les instances de la classe.
- species = "H. sapiens"
-
- # L'initialiseur de base. Il est appelé quand la classe est instanciée.
- # Note : les doubles underscores au début et à la fin sont utilisés pour
- # les fonctions et attributs utilisés par Python mais contrôlés par l'utilisateur.
- # Les méthodes (ou objets ou attributs) comme: __init__, __str__,
- # __repr__ etc. sont appelés méthodes magiques.
- # Vous ne devriez pas inventer de noms de ce style.
- def __init__(self, name):
- # Assigner l'argument à l'attribut de l'instance
- self.name = name
-
- # Une méthode de l'instance. Toutes prennent "self" comme premier argument.
- def say(self, msg):
- return "{name}: {message}".format(name=self.name, message=msg)
-
- # Une méthode de classe est partagée avec entre les instances
- # Ils sont appelés avec la classe comme premier argument
- @classmethod
- def get_species(cls):
- return cls.species
-
- # Une méthode statique est appelée sans référence à une instance ni à une classe.
- @staticmethod
- def grunt():
- return "*grunt*"
-
-
-# Instantier une classe
-i = Human(name="Ian")
-print(i.say("hi")) # affiche "Ian: hi"
-
-j = Human("Joel")
-print(j.say("hello")) # affiche "Joel: hello"
-
-# Appeller notre méthode de classe
-i.get_species() # => "H. sapiens"
-
-# Changer les attributs partagés
-Human.species = "H. neanderthalensis"
-i.get_species() # => "H. neanderthalensis"
-j.get_species() # => "H. neanderthalensis"
-
-# Appeller la méthode statique
-Human.grunt() # => "*grunt*"
-
-
-####################################################
-## 6. Modules
-####################################################
-
-# On peut importer des modules
-import math
-print(math.sqrt(16)) # => 4.0
-
-# On peut importer des fonctions spécifiques d'un module
-from math import ceil, floor
-print(ceil(3.7)) # => 4.0
-print(floor(3.7)) # => 3.0
-
-# On peut importer toutes les fonctions d'un module
-# Attention: ce n'est pas recommandé.
-from math import *
-
-# On peut raccourcir un nom de module
-import math as m
-math.sqrt(16) == m.sqrt(16) # => True
-
-# Les modules Python sont juste des fichiers Python.
-# Vous pouvez écrire les vôtres et les importer. Le nom du module
-# est le nom du fichier.
-
-# On peut voir quels fonctions et objets un module définit
-import math
-dir(math)
-
-
-####################################################
-## 7. Avancé
-####################################################
-
-# Les générateurs aident à faire du code paresseux (lazy)
-def double_numbers(iterable):
- for i in iterable:
- yield i + i
-
-# Un générateur crée des valeurs à la volée.
-# Au lieu de générer et retourner toutes les valeurs en une fois, il en crée une à chaque
-# itération. Cela signifie que les valeurs supérieures à 15 ne seront pas traîtées par
-# double_numbers.
-# Note : range est un générateur aussi.
-# Créer une liste 1-900000000 prendrait beaucoup de temps
-# On met un underscore à la fin d'un nom de variable normalement réservé par Python.
-range_ = range(1, 900000000)
-# Double tous les nombres jusqu'à ce qu'un nombre >=30 soit trouvé
-for i in double_numbers(range_):
- print(i)
- if i >= 30:
- break
-
-
-# Decorateurs
-# Dans cet exemple, beg enveloppe say
-# Beg appellera say. Si say_please vaut True le message retourné sera changé
-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()) # affiche Can you buy me a beer?
-print(say(say_please=True)) # affiche Can you buy me a beer? Please! I am poor :(
-```
-
-## Prêt pour encore plus ?
-
-### En ligne et gratuit (en anglais)
-
-* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
-* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
-* [Dive Into Python](http://www.diveintopython.net/)
-* [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/)
-* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
-* [Python Course](http://www.python-course.eu/index.php)
-* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
-
-### Livres (en anglais)
-
-* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
-* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
-* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
diff --git a/fr-fr/pythonlegacy-fr.html.markdown b/fr-fr/pythonlegacy-fr.html.markdown
new file mode 100644
index 00000000..10b1a0a6
--- /dev/null
+++ b/fr-fr/pythonlegacy-fr.html.markdown
@@ -0,0 +1,488 @@
+---
+language: Python 2 (legacy)
+filename: learnpythonlegacy-fr.py
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+translators:
+ - ["Sylvain Zyssman", "https://github.com/sylzys"]
+ - ["Nami-Doc", "https://github.com/Nami-Doc"]
+lang: fr-fr
+---
+
+Python a été créé par Guido Van Rossum au début des années 90. C'est maintenant un des langages de programmation les plus populaires.
+Je suis tombé amoureux de Python de par la clarté de sa syntaxe. C'est pratiquement du pseudo-code exécutable.
+
+Vos retours sont grandement appréciés. Vous pouvez me contacter sur Twitter [@louiedinh](http://twitter.com/louiedinh) ou par e-mail: louiedinh [at] [google's email service]
+
+N.B. : Cet article s'applique spécifiquement à Python 2.7, mais devrait s'appliquer pour toute version Python 2.x. Python 2.7 est en fin de vie et ne sera plus maintenu à partir de 2020, il est donc recommandé d'apprendre Python avec Python 3. Pour Python 3.x, il existe un autre [tutoriel pour Python 3](http://learnxinyminutes.com/docs/fr-fr/python3-fr/).
+
+```python
+# Une ligne simple de commentaire commence par un dièse
+""" Les lignes de commentaires multipes peuvent être écrites
+ en utilisant 3 guillemets ("), et sont souvent utilisées
+ pour les commentaires
+"""
+
+####################################################
+## 1. Types Primaires et Opérateurs
+####################################################
+
+# Les nombres
+3 #=> 3
+
+# Les calculs produisent les résultats mathématiques escomptés
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# La division est un peu spéciale. C'est une division d'entiers, et Python arrondi le résultat par défaut automatiquement.
+5 / 2 #=> 2
+
+# Pour corriger ce problème, on utilise les float.
+2.0 # Voici un float
+11.0 / 4.0 #=> 2.75 ahhh... beaucoup mieux
+
+# Forcer la priorité avec les parenthèses
+(1 + 3) * 2 #=> 8
+
+# Les valeurs booléenes sont de type primitif
+True
+False
+
+# Pour la négation, on utilise "not"
+not True #=> False
+not False #=> True
+
+# Pour l'égalité, ==
+1 == 1 #=> True
+2 == 1 #=> False
+
+# L'inégalité est symbolisée par !=
+1 != 1 #=> False
+2 != 1 #=> True
+
+# D'autres comparateurs
+1 < 10 #=> True
+1 > 10 #=> False
+2 <= 2 #=> True
+2 >= 2 #=> True
+
+# On peut enchaîner les comparateurs !
+1 < 2 < 3 #=> True
+2 < 3 < 2 #=> False
+
+# Les chaînes de caractères sont créées avec " ou '
+"C'est une chaîne."
+'C\'est aussi une chaîne.'
+
+# On peut aussi les "additioner" !
+"Hello " + "world!" #=> "Hello world!"
+
+# Une chaîne peut être traitée comme une liste de caractères
+"C'est une chaîne"[0] #=> 'C'
+
+# % peut être utilisé pour formatter des chaîne, comme ceci:
+"%s can be %s" % ("strings", "interpolated")
+
+# Une autre manière de formatter les chaînes de caractères est d'utiliser la méthode 'format'
+# C'est la méthode à privilégier
+"{0} peut être {1}".format("La chaîne", "formattée")
+# On peut utiliser des mot-clés au lieu des chiffres.
+"{name} veut manger des {food}".format(name="Bob", food="lasagnes")
+
+# None est un objet
+None #=> None
+
+# Ne pas utiliser le symbole d'inégalité "==" pour comparer des objet à None
+# Il faut utiliser "is"
+"etc" is None #=> False
+None is None #=> True
+
+# L'opérateur 'is' teste l'identité de l'objet.
+# Ce n'est pas très utilisé avec les types primitifs, mais cela peut être très utile
+# lorsque l'on utilise des objets.
+
+# None, 0, et les chaînes de caractères vides valent False.
+# Toutes les autres valeurs valent True
+0 == False #=> True
+"" == False #=> True
+
+
+####################################################
+## 2. Variables et Collections
+####################################################
+
+# Afficher du texte, c'est facile
+print "Je suis Python. Enchanté!"
+
+
+# Il n'y a pas besoin de déclarer les variables avant de les assigner.
+some_var = 5 # La convention veut que l'on utilise des minuscules_avec_underscores
+some_var #=> 5
+
+# Accéder à une variable non assignée lève une exception
+# Voyez les structures de contrôle pour en apprendre plus sur la gestion des exceptions.
+some_other_var # Lève une exception
+
+# 'if' peut être utilisé comme expression
+"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+
+# Listes
+li = []
+# On peut remplir liste dès l'instanciation
+other_li = [4, 5, 6]
+
+# On ajoute des éléments avec 'append'
+li.append(1) #li contient [1]
+li.append(2) #li contient [1, 2]
+li.append(4) #li contient [1, 2, 4]
+li.append(3) #li contient [1, 2, 4, 3]
+
+# Et on les supprime avec 'pop'
+li.pop() #=> 3 et li contient [1, 2, 4]
+# Remettons-le dans la liste
+li.append(3) # li contient [1, 2, 4, 3] de nouveau.
+
+# On accède aux éléments d'une liste comme à ceux un tableau.
+li[0] #=> 1
+# Le dernier élément
+li[-1] #=> 3
+
+# Accèder aux indices hors limite lève une exception
+li[4] # Lève un 'IndexError'
+
+# On peut accèder à des rangs de valeurs avec la syntaxe "slice"
+# (C'est un rang de type 'fermé/ouvert' pour les plus matheux)
+li[1:3] #=> [2, 4]
+# Sans spécifier de fin de rang, on "saute" le début de la liste
+li[2:] #=> [4, 3]
+# Sans spécifier de début de rang, on "saute" la fin de la liste
+li[:3] #=> [1, 2, 4]
+
+# Retirer un élément spécifique dee la liste avec "del"
+del li[2] # li contient [1, 2, 3]
+
+# On peut additionner des listes entre elles
+li + other_li #=> [1, 2, 3, 4, 5, 6] - Note: li et other_li existent toujours à part entière
+
+# Concaténer des listes avec "extend()"
+li.extend(other_li) # li vaut maintenant [1, 2, 3, 4, 5, 6]
+
+# Vérifier l'existence d'un élément dans une liste avec "in"
+1 in li #=> True
+
+# Récupérer la longueur avec "len()"
+len(li) #=> 6
+
+
+# Les "tuples" sont comme des listes, mais sont immuables.
+tup = (1, 2, 3)
+tup[0] #=> 1
+tup[0] = 3 # Lève un 'TypeError'
+
+# Mais vous pouvez faire tout ceci sur les tuples:
+len(tup) #=> 3
+tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
+tup[:2] #=> (1, 2)
+2 in tup #=> True
+
+# Vous pouvez "dé-packager" les tuples (ou les listes) dans des variables
+a, b, c = (1, 2, 3) # a vaut maintenant 1, b vaut maintenant 2 and c vaut maintenant 3
+# Sans parenthèses, un tuple est créé par défaut
+d, e, f = 4, 5, 6
+# Voyez maintenant comme il est facile d'inverser 2 valeurs
+e, d = d, e # d is now 5 and e is now 4
+
+
+# Dictionnaires
+empty_dict = {}
+# Un dictionnaire pré-rempli
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Trouver des valeurs avec []
+filled_dict["one"] #=> 1
+
+# Récupérer toutes les clés sous forme de liste avec "keys()"
+filled_dict.keys() #=> ["three", "two", "one"]
+# Note - l'ordre des clés du dictionnaire n'est pas garanti.
+# Vos résultats peuvent différer de ceux ci-dessus.
+
+# Récupérer toutes les valeurs sous forme de liste avec "values()"
+filled_dict.values() #=> [3, 2, 1]
+# Note - Même remarque qu'au-dessus concernant l'ordre des valeurs.
+
+# Vérifier l'existence d'une clé dans le dictionnaire avec "in"
+"one" in filled_dict #=> True
+1 in filled_dict #=> False
+
+# Chercher une clé non existante lève une 'KeyError'
+filled_dict["four"] # KeyError
+
+# Utiliser la méthode "get()" pour éviter 'KeyError'
+filled_dict.get("one") #=> 1
+filled_dict.get("four") #=> None
+# La méthode get() prend un argument par défaut quand la valeur est inexistante
+filled_dict.get("one", 4) #=> 1
+filled_dict.get("four", 4) #=> 4
+
+# La méthode "setdefault()" permet d'ajouter de manière sécuris une paire clé-valeur dans le dictionnnaire
+filled_dict.setdefault("five", 5) #filled_dict["five"] vaut 5
+filled_dict.setdefault("five", 6) #filled_dict["five"] is toujours 5
+
+
+# Les sets stockent ... des sets
+empty_set = set()
+# On initialise un "set()" avec tout un tas de valeurs
+some_set = set([1,2,2,3,4]) # some_set vaut maintenant set([1, 2, 3, 4])
+
+# Depuis Python 2.7, {} peut être utilisé pour déclarer un 'set'
+filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+
+# Ajouter plus d'éléments au set
+filled_set.add(5) # filled_set contient maintenant {1, 2, 3, 4, 5}
+
+# Intersection de sets avec &
+other_set = {3, 4, 5, 6}
+filled_set & other_set #=> {3, 4, 5}
+
+# Union de sets avec |
+filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+
+# Différence de sets avec -
+{1,2,3,4} - {2,3,5} #=> {1, 4}
+
+# Vérifier l'existence d'une valeur dans un set avec "in"
+2 in filled_set #=> True
+10 in filled_set #=> False
+
+
+####################################################
+## 3. Structure de contrôle
+####################################################
+
+# Initialisons une variable
+some_var = 5
+
+# Voici une condition 'if'. L'indentation est significative en Python !
+# Affiche "some_var est inférieur à 10"
+if some_var > 10:
+ print "some_var est supérieur à 10."
+elif some_var < 10: # La clause elif est optionnelle
+ print "some_var iinférieur à 10."
+else: # La clause else également
+ print "some_var vaut 10."
+
+
+"""
+Les boucles "for" permettent d'itérer sur les listes
+Affiche:
+ chien : mammifère
+ chat : mammifère
+ souris : mammifère
+"""
+for animal in ["chien", "chat", "souris"]:
+ # On peut utiliser % pour l'interpolation des chaînes formattées
+ print "%s : mammifère" % animal
+
+"""
+"range(number)" retourne une liste de nombres
+de 0 au nombre donné
+Affiche:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+Les boucles "while" boucle jusqu'à ce que leur condition ne soit plus vraie
+Affiche:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # Raccourci pour x = x + 1
+
+# Gérer les exceptions avec un bloc try/except
+
+# Fonctionne pour Python 2.6 et ultérieur:
+try:
+ # Utiliser "raise" pour lever une exception
+ raise IndexError("This is an index error")
+except IndexError as e:
+ pass # Pass ne prend pas d'arguments. Généralement, on gère l'erreur ici.
+
+
+####################################################
+## 4. Fonctions
+####################################################
+
+# Utiliser "def" pour créer une nouvelle fonction
+def add(x, y):
+ print "x vaut %s et y vaur %s" % (x, y)
+ return x + y # Renvoi de valeur avec 'return'
+
+# Appeller une fonction avec des paramètres
+add(5, 6) #=> Affichet "x is 5 et y vaut 6" et renvoie 11
+
+# Une autre manière d'appeller une fonction, avec les arguments
+add(y=6, x=5) # Les arguments peuvent venir dans n'importe quel ordre.
+
+# On peut définir une foncion qui prend un nombre variable de paramètres
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) #=> (1,2,3)
+
+
+# On peut également définir une fonction qui prend un nombre
+# variable d'arguments
+def keyword_args(**kwargs):
+ return kwargs
+
+# Appelons-là et voyons ce qu'il se passe
+keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+
+# On peut faire les deux à la fois si on le souhaite
+def all_the_args(*args, **kwargs):
+ print args
+ print kwargs
+"""
+all_the_args(1, 2, a=3, b=4) affiche:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# En appellant les fonctions, on peut faire l'inverse des paramètres / arguments !
+# Utiliser * pour développer les paramètres, et ** pour développer les arguments
+params = (1, 2, 3, 4)
+args = {"a": 3, "b": 4}
+all_the_args(*args) # equivaut à foo(1, 2, 3, 4)
+all_the_args(**kwargs) # equivaut à foo(a=3, b=4)
+all_the_args(*args, **kwargs) # equivaut à foo(1, 2, 3, 4, a=3, b=4)
+
+# Python a des fonctions de première classe
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) #=> 13
+
+# Mais également des fonctions anonymes
+(lambda x: x > 2)(3) #=> True
+
+# On trouve aussi des fonctions intégrées plus évoluées
+map(add_10, [1,2,3]) #=> [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+
+# On peut utiliser la syntaxe des liste pour construire les "maps" et les "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]
+
+####################################################
+## 5. Classes
+####################################################
+
+# Une classe est un objet
+class Human(object):
+
+ # Un attribut de classe. Il est partagé par toutes les instances de cette classe.
+ species = "H. sapiens"
+
+ # Initialiseur basique
+ def __init__(self, name):
+ # Assigne le paramètre à l'attribut de l'instance de classe.
+ self.name = name
+
+ # Une méthode de l'instance. Toutes les méthodes prennent "self" comme 1er paramètre.
+ def say(self, msg):
+ return "%s: %s" % (self.name, msg)
+
+ # Une méthode de classe est partagée par toutes les instances.
+ # On les appelle avec le nom de la classe en premier paramètre
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Une méthode statique est appellée sans référence à une classe ou à une instance
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+
+# Instancier une classe
+i = Human(name="Ian")
+print i.say("hi") # Affiche "Ian: hi"
+
+j = Human("Joel")
+print j.say("hello") #Affiche "Joel: hello"
+
+# Appeller notre méthode de classe
+i.get_species() #=> "H. sapiens"
+
+# Changer les attributs partagés
+Human.species = "H. neanderthalensis"
+i.get_species() #=> "H. neanderthalensis"
+j.get_species() #=> "H. neanderthalensis"
+
+# Appeller la méthode statique
+Human.grunt() #=> "*grunt*"
+
+
+####################################################
+## 6. Modules
+####################################################
+
+# On peut importer des modules
+import math
+print math.sqrt(16) #=> 4.0
+
+# Et récupérer des fonctions spécifiques d'un module
+from math import ceil, floor
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
+
+# Récuperer toutes les fonctions d'un module
+# Attention, ce n'est pas recommandé.
+from math import *
+
+# On peut raccourcir le nom d'un module
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
+
+# Les modules Python sont juste des fichiers Python ordinaires.
+# On peut écrire ses propres modules et les importer.
+# Le nom du module doit être le même que le nom du fichier.
+
+# On peut trouver quelle fonction et attributs déterminent un module
+import math
+dir(math)
+
+
+```
+
+## Prêt à aller plus loin?
+
+### En ligne gratuitement
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+
+### Format papier
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+
diff --git a/fr-fr/ruby-ecosystem-fr.html.markdown b/fr-fr/ruby-ecosystem-fr.html.markdown
index 9b52069a..edc69068 100644
--- a/fr-fr/ruby-ecosystem-fr.html.markdown
+++ b/fr-fr/ruby-ecosystem-fr.html.markdown
@@ -6,6 +6,7 @@ contributors:
- ["Rafal Chmiel", "http://github.com/rafalchmiel"]
translators:
- ["Xuan-thi Nguyen", "http://github.com/mellenguyen"]
+ - ["Sylvain Abélard", "http://github.com/abelards"]
lang: fr-fr
---
@@ -17,9 +18,9 @@ dépendances des gems.
## Ruby Managers
Quelques plateformes possèdent Ruby pré-installé ou disponible en tant que
-paquet. La plupart des rubyists ne les utilisent pas, ou si c'est le cas, ne
-les utilise que pour faire démarrer un autre installateur ou implémentation de
-Ruby. Les rubyists tendent plutôt à installer un manager Ruby pour installer
+paquet. La plupart des rubyistes ne les utilisent pas, ou si c'est le cas, ne
+les utilisent que pour faire démarrer un autre installateur ou implémentation de
+Ruby. Les rubyistes tendent plutôt à installer un gestionnaire en Ruby pour installer
et changer entre les différentes et nombreuses versions de Ruby et les
environnements de leurs projets Ruby.
@@ -47,14 +48,14 @@ Implementation).
Les trois versions majeures de Ruby actuellement utilisées sont :
-* 2.0.0 - Sortie en février 2013. La plupart des librairies et frameworks
+* 2.0.0 - Sortie en février 2013. La plupart des bibliothèques et frameworks
gèrent la versions 2.0.0.
* 1.9.3 - Sortie en octobre 2011. Il s'agit de la version que la majorité des
rubyists utilisent actuellement. [Fin de vie](https://www.ruby-lang.org/en/news/2015/02/23/support-for-ruby-1-9-3-has-ended/)
* 1.8.7 - Sortie en juin 2006. [Fin de vie](http://www.ruby-lang.org/en/news/2013/06/30/we-retire-1-8-7/).
-Les changements entre 1.8.7 à 1.9.x sont bien plus grands qu'entre 1.9.3
-jusqu'à 2.0.0. Par exemple, les versions 1.9 ont introduit le support des
+Les changements entre 1.8.7 et 1.9.x sont bien plus grands qu'entre 1.9.3
+et 2.0.0. Par exemple, les versions 1.9 ont introduit le support des
encodages et d'une VM bytecode ([YARV](https://fr.wikipedia.org/wiki/YARV)).
Il y a toujours des projets sur 1.8.7, mais ils deviennent minoritaires, étant
donné que la majorité de la communauté a migré vers au moins 1.9.2 ou 1.9.3.
@@ -89,7 +90,7 @@ Mpyennement mature/compatible:
* [Maglev](http://maglev.github.io/) - Basée sur Gemstone, une VM Smalltalk.
Smalltalk possède quelques outils impressionnants, et ce projet tente
de les apporter dans le développement Ruby.
-* [RubyMotion](http://www.rubymotion.com/) - Ruby pour développement iOS.
+* [RubyMotion](http://www.rubymotion.com/) - Ruby pour développement iOS et Android.
* [Opal](http://opalrb.org/) - Compile le Ruby en Javascript
Les implémentations de Ruby peuvent avoir leurs propres numéros de versions,
@@ -122,17 +123,17 @@ l(es) auteur(s) et la/les licence(s).
## Bundler
-[Bundler](http://bundler.io/) est un résolveur de dépendances des gems. Il
-utilise le Gemfile d'un projet ppur trouver les dépendances, et récupère
+[Bundler](http://bundler.io/) est un outil de résolution de dépendances des gems. Il
+utilise le Gemfile d'un projet pour en trouver les dépendances, et récupère
ensuite les dépendances de ces dépendances récursivement. Il déroule cet
algorithme jusqu'à ce que toutes les dépendances soient résolues et
téléchargées, ou s'arrête si un conflit est trouvé.
Bundler lèvera une erreur s'il trouve des conflits de dépendances. Par exemple,
si la gem A recquiert la version 3 ou plus de gem Z, mais que gem B recquiert
-seulement la version 2, Bundler vous notifiera ce conflict. Cela devient
+seulement la version 2 de la même gem Z, Bundler vous notifiera ce conflit. Cela devient
extrêmement utile, étant donné que beaucoup de gems font référence à d'autres
-gems (qui se réfèrent à d'autres gems), ce qui peut former un large graphe de
+gems (qui se réfèrent à d'autres gems et ainsi de suite), ce qui peut former un large graphe de
dépendance à résoudre.
# Les tests
@@ -151,4 +152,4 @@ différents.
La communauté Ruby est fière d'être une communauté ouverte, riche et
accueillante. Matz lui-même est extrêmement sociable, et la générosité des
-rubyists est généralement remarquable.
+rubyistes est généralement remarquable.
diff --git a/fr-fr/ruby-fr.html.markdown b/fr-fr/ruby-fr.html.markdown
index 1564d2b6..6b487a07 100644
--- a/fr-fr/ruby-fr.html.markdown
+++ b/fr-fr/ruby-fr.html.markdown
@@ -7,9 +7,11 @@ contributors:
- ["Luke Holder", "http://twitter.com/lukeholder"]
- ["Tristan Hume", "http://thume.ca/"]
- ["Nick LaMuro", "https://github.com/NickLaMuro"]
+
translators:
- ["Geoffrey Roguelon", "https://github.com/GRoguelon"]
- ["Nami-Doc", "https://github.com/Nami-Doc"]
+ - ["Sylvain Abélard", "http://github.com/abelards"]
lang: fr-fr
---
@@ -22,19 +24,23 @@ Personne ne les utilise
Vous devriez en faire de même
=end
-# Tout d'abord : Tout est un objet.
+# Tout d'abord : tout est un objet.
# Les nombres sont des objets
-3.class #=> Fixnum
+3.class #=> Fixnum # on voit que c'est une classe Ruby et non un "type spécial"
-3.to_s #=> "3"
+3.to_s #=> "3" # on peut appeler des méthodes sur ces objets, comme `to_s` (transforme en texte)
# Les opérateurs de base
1 + 1 #=> 2
8 - 1 #=> 7
10 * 2 #=> 20
-35 / 5 #=> 7
+22 / 7 #=> 3 # si les deux éléments sont entiers, c'est une division entière
+22.0 / 7 #=> 3.142857142857143
+22 / 7.0 #=> 3.142857142857143
+2**10 #=> 1024 # exposant
+1024 % 10 #=> 4 # modulo (reste de la division euclidienne)
# Les opérateurs sont juste des raccourcis
# pour appeler une méthode sur un objet
@@ -42,9 +48,9 @@ Vous devriez en faire de même
10.* 5 #=> 50
# Les valeurs spéciales sont des objets
-nil # Nul
-true # Vrai
-false # Faux
+nil # nul, vide ou indéfini
+true # vrai
+false # faux
nil.class #=> NilClass
true.class #=> TrueClass
@@ -60,8 +66,7 @@ false.class #=> FalseClass
!true #=> false
!false #=> true
-# à part false lui-même, nil est la seule autre valeur 'false'
-
+# à part false lui-même, nil est la seule autre valeur "considérée comme fausse"
!nil #=> true
!false #=> true
!0 #=> false
@@ -73,7 +78,6 @@ false.class #=> FalseClass
2 >= 2 #=> true
# Les chaînes de caractères sont des objets
-
'Je suis une chaîne de caractères'.class #=> String
"Je suis également une chaîne de caractères".class #=> String
@@ -84,6 +88,15 @@ placeholder = "utiliser l'interpolation de chaîne de caractères"
# Affichez un message
puts "J'affiche à l'écran!"
+# Il y a quelques autres raccourcis pour les chaînes de caractères
+rb = "Ruby"
+interpolation = "Bonjour Ruby" # s'écrit aussi %Q[Bonjour #{rb}] %Q{Bonjour #{rb}} avec l'interpolation
+literal = "Bonjour \#{rb}" # avec le backslash, le dièse est un "vrai dièse" (le slash ne s'affiche que pour le debug)
+literal == %q[Bonjour #{rb}] # le Q majuscule fait l'interpolation, le q minuscule ne la fait pas
+multi = %Q[Cette chaîne
+est sur plusieurs
+lignes] # => "Cette chaîne\nest sur plusieurs\nlignes" # le caractère \n signifie retour à la ligne
+
# Variables
x = 25 #=> 25
x #=> 25
@@ -131,7 +144,7 @@ array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
[1, "hello", false] #=> [1, "hello", false]
# Les tableaux peuvent être indexés
-# Du début
+# Trouver la valeur en donnant la position en partant du début (le premier élément est à l'index 0)
array[0] #=> 1
array[12] #=> nil
@@ -140,13 +153,13 @@ array[12] #=> nil
array.[] 0 #=> 1
array.[] 12 #=> nil
-# Depuis la fin
+# On peut compter en partant de la fin avec un index négatif (le dernier élément est à l'index -1)
array[-1] #=> 5
-# Avec un index de début et de fin
-array[2, 4] #=> [3, 4, 5]
+# Avec un index de début et un nombre d'éléments [position, nombre]
+array[1, 3] #=> [2, 3, 4]
-# Ou avec un intervalle
+# Ou avec un intervalle [index de début .. index de fin]
array[1..3] #=> [2, 3, 4]
# Ajoutez un élément au tableau comme ceci
@@ -180,11 +193,11 @@ new_hash.keys #=> [:defcon, :action]
# Structures de contrôle
if true
- "si instruction"
+ "si l'instruction est vraie"
elsif false
- "autrement si, facultatif"
+ "si l'instruction de départ n'était pas vraie, et que cette nouvelle condition est vraie (facultatif)"
else
- "autrement, également facultatif"
+ "tous les autres cas (il est également facultatif de faire une clause else)"
end
for compteur in 1..5
diff --git a/fr-fr/rust-fr.html.markdown b/fr-fr/rust-fr.html.markdown
index 6ab559a3..b3675f5b 100644
--- a/fr-fr/rust-fr.html.markdown
+++ b/fr-fr/rust-fr.html.markdown
@@ -14,16 +14,16 @@ Il atteint ces objectifs sans avoir besoin d'un ramasse-miettes ou environnement
La première version de Rust, 0.1, est sortie en janvier 2012 et a tellement évolué rapidement que jusqu'à récemment, l'utilisation de versions stables était déconseillée - à la place ce était conseillé d'utiliser les nightly builds.
-Le 15 mai 2015, Rust 1.0 a été libéré avec une garantie complète de compatibilité ascendante. Améliorations aux temps de compilation et d'autres aspects du compilateur sont actuellement disponibles dans la nightly builds. Rust a adopté un modèle de libération à bord du train avec les versions régulières toutes les six semaines. Rust 1.1 beta a été mis à la disposition dans le même temps de la libération de Rust 1.0.
+Le 15 mai 2015, Rust 1.0 a été libéré avec une garantie complète de compatibilité ascendante. Améliorations aux temps de compilation et d'autres aspects du compilateur sont actuellement disponibles dans la nightly builds. Rust a adopté un modèle de train de livraison avec les versions régulières toutes les six semaines. Rust 1.1 beta a été mis à disposition au moment de la livraison de Rust 1.0.
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/fr-fr/scala.html.markdown b/fr-fr/scala-fr.html.markdown
index c6d06361..c6a61745 100644
--- a/fr-fr/scala.html.markdown
+++ b/fr-fr/scala-fr.html.markdown
@@ -276,7 +276,7 @@ i // Montre la valeur de i. Notez que while est une boucle au sens classique.
i = 0
// La boucle do while
do {
- println("x is still less then 10");
+ println("x is still less than 10");
i += 1
} while (i < 10)
diff --git a/fr-fr/vim.html.markdown b/fr-fr/vim-fr.html.markdown
index 8e84bf33..b2f1d24d 100644
--- a/fr-fr/vim.html.markdown
+++ b/fr-fr/vim-fr.html.markdown
@@ -1,7 +1,7 @@
---
category: tool
tool: vim
-filename: LearnVim.txt
+filename: LearnVim-fr.txt
contributors:
- ["RadhikaG", "https://github.com/RadhikaG"]
translators:
@@ -10,7 +10,7 @@ lang: fr-fr
---
-[Vim](www.vim.org)
+[Vim](http://www.vim.org)
(Vi IMproved) est le clone le plus populaire de l'éditeur de texte vi sous Unix.
Vim est un éditeur de texte omniprésent sur les systèmes de type Unix, et a pour
objectif la rapidité ainsi que l'augmentation de la productivité. Il a de
diff --git a/fr-fr/yaml-fr.html.markdown b/fr-fr/yaml-fr.html.markdown
index 1e8296d3..c7cb9421 100644
--- a/fr-fr/yaml-fr.html.markdown
+++ b/fr-fr/yaml-fr.html.markdown
@@ -1,6 +1,6 @@
---
language: yaml
-filename: learnyaml.yaml
+filename: learnyaml-fr.yaml
contributors:
- ["Andrei Curelaru", "http://www.infinidad.fr"]
lang: fr-fr
diff --git a/fsharp.html.markdown b/fsharp.html.markdown
index bbf477ba..c140d6b1 100644
--- a/fsharp.html.markdown
+++ b/fsharp.html.markdown
@@ -14,7 +14,7 @@ The syntax of F# is different from C-style languages:
* Curly braces are not used to delimit blocks of code. Instead, indentation is used (like Python).
* Whitespace is used to separate parameters rather than commas.
-If you want to try out the code below, you can go to [tryfsharp.org](http://www.tryfsharp.org/Create) and paste it into an interactive REPL.
+If you want to try out the code below, you can go to [https://try.fsharp.org](https://try.fsharp.org) and paste it into an interactive REPL.
```csharp
@@ -34,7 +34,7 @@ let myFloat = 3.14
let myString = "hello" // note that no types needed
// ------ Lists ------
-let twoToFive = [2; 3; 4; 5] // Square brackets create a list with
+let twoToFive = [2; 3; 4; 5] // Square brackets create a list with
// semicolon delimiters.
let oneToFive = 1 :: twoToFive // :: creates list with new 1st element
// The result is [1; 2; 3; 4; 5]
@@ -53,7 +53,8 @@ add 2 3 // Now run the function.
// to define a multiline function, just use indents. No semicolons needed.
let evens list =
- let isEven x = x % 2 = 0 // Define "isEven" as a sub function
+ let isEven x = x % 2 = 0 // Define "isEven" as a sub function. Note
+ // that equality operator is single char "=".
List.filter isEven list // List.filter is a library function
// with two parameters: a boolean function
// and a list to work on
@@ -193,7 +194,7 @@ module ListExamples =
| [] -> printfn "the list is empty"
| [first] -> printfn "the list has one element %A " first
| [first; second] -> printfn "list is %A and %A" first second
- | _ -> printfn "the list has more than two elements"
+ | first :: _ -> printfn "the list has more than two elements, first element %A" first
listMatcher [1; 2; 3; 4]
listMatcher [1; 2]
@@ -306,7 +307,7 @@ module DataTypeExamples =
// ------------------------------------
// Union types (aka variants) have a set of choices
- // Only case can be valid at a time.
+ // Only one case can be valid at a time.
// ------------------------------------
// Use "type" with bar/pipe to define a union type
@@ -632,6 +633,6 @@ module NetCompatibilityExamples =
## More Information
-For more demonstrations of F#, go to the [Try F#](http://www.tryfsharp.org/Learn) site, or my [why use F#](http://fsharpforfunandprofit.com/why-use-fsharp/) series.
+For more demonstrations of F#, go to my [why use F#](http://fsharpforfunandprofit.com/why-use-fsharp/) series.
-Read more about F# at [fsharp.org](http://fsharp.org/).
+Read more about F# at [fsharp.org](http://fsharp.org/) and [dotnet's F# page](https://dotnet.microsoft.com/languages/fsharp).
diff --git a/git.html.markdown b/git.html.markdown
index 01dc92c1..a40ef01b 100644
--- a/git.html.markdown
+++ b/git.html.markdown
@@ -8,6 +8,7 @@ contributors:
- ["Bruno Volcov", "http://github.com/volcov"]
- ["Andrew Taylor", "http://github.com/andrewjt71"]
- ["Jason Stathopulos", "http://github.com/SpiritBreaker226"]
+ - ["Milo Gilad", "http://github.com/Myl0g"]
filename: LearnGit.txt
---
@@ -23,13 +24,13 @@ manage your source code.
Version control is a system that records changes to a file(s), over time.
-### Centralized Versioning VS Distributed Versioning
+### Centralized Versioning vs. Distributed Versioning
-* Centralized version control focuses on synchronizing, tracking, and backing
+* Centralized version control focuses on synchronizing, tracking, and backing
up files.
-* Distributed version control focuses on sharing changes. Every change has a
+* Distributed version control focuses on sharing changes. Every change has a
unique id.
-* Distributed systems have no defined structure. You could easily have a SVN
+* Distributed systems have no defined structure. You could easily have a SVN
style, centralized system, with git.
[Additional Information](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
@@ -56,7 +57,7 @@ A git repository is comprised of the .git directory & working tree.
### .git Directory (component of repository)
-The .git directory contains all the configurations, logs, branches, HEAD, and
+The .git directory contains all the configurations, logs, branches, HEAD, and
more.
[Detailed List.](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
@@ -67,36 +68,36 @@ referred to as your working directory.
### Index (component of .git dir)
-The Index is the staging area in git. It's basically a layer that separates
-your working tree from the Git repository. This gives developers more power
+The Index is the staging area in git. It's basically a layer that separates
+your working tree from the Git repository. This gives developers more power
over what gets sent to the Git repository.
### Commit
-A git commit is a snapshot of a set of changes, or manipulations to your
-Working Tree. For example, if you added 5 files, and removed 2 others, these
-changes will be contained in a commit (or snapshot). This commit can then be
+A git commit is a snapshot of a set of changes, or manipulations to your
+Working Tree. For example, if you added 5 files, and removed 2 others, these
+changes will be contained in a commit (or snapshot). This commit can then be
pushed to other repositories, or not!
### Branch
A branch is essentially a pointer to the last commit you made. As you go on
-committing, this pointer will automatically update to point the latest commit.
+committing, this pointer will automatically update to point to the latest commit.
### Tag
A tag is a mark on specific point in history. Typically people use this
-functionality to mark release points (v1.0, and so on)
+functionality to mark release points (v1.0, and so on).
### HEAD and head (component of .git dir)
-HEAD is a pointer that points to the current branch. A repository only has 1
-*active* HEAD.
-head is a pointer that points to any commit. A repository can have any number
+HEAD is a pointer that points to the current branch. A repository only has 1
+*active* HEAD.
+head is a pointer that points to any commit. A repository can have any number
of heads.
### Stages of Git
-* Modified - Changes have been made to a file but file has not been committed
+* Modified - Changes have been made to a file but file has not been committed
to Git Database yet
* Staged - Marks a modified file to go into your next commit snapshot
* Committed - Files have been committed to the Git Database
@@ -110,7 +111,7 @@ to Git Database yet
### init
-Create an empty Git repository. The Git repository's settings, stored
+Create an empty Git repository. The Git repository's settings, stored
information, and more is stored in a directory (a folder) named ".git".
```bash
@@ -157,6 +158,7 @@ $ git init --help
To intentionally untrack file(s) & folder(s) from git. Typically meant for
private & temp files which would otherwise be shared in the repository.
+
```bash
$ echo "temp/" >> .gitignore
$ echo "private_key" >> .gitignore
@@ -177,7 +179,7 @@ $ git help status
### add
-To add files to the staging area/index. If you do not `git add` new files to
+To add files to the staging area/index. If you do not `git add` new files to
the staging area/index, they will not be included in commits!
```bash
@@ -189,6 +191,9 @@ $ git add /path/to/file/HelloWorld.c
# Regular Expression support!
$ git add ./*.java
+
+# You can also add everything in your working directory to the staging area.
+$ git add -A
```
This only adds a file to the staging area/index, it doesn't commit it to the
@@ -196,7 +201,7 @@ working directory/repo.
### branch
-Manage your branches. You can view, edit, create, delete branches using this
+Manage your branches. You can view, edit, create, delete branches using this
command.
```bash
@@ -226,7 +231,7 @@ Manage your tags
$ git tag
# Create a annotated tag
-# The -m specifies a tagging message,which is stored with the tag.
+# The -m specifies a tagging message, which is stored with the tag.
# If you don’t specify a message for an annotated tag,
# Git launches your editor so you can type it in.
$ git tag -a v2.0 -m 'my version 2.0'
@@ -245,7 +250,7 @@ $ git push origin --tags
### checkout
-Updates all files in the working tree to match the version in the index, or
+Updates all files in the working tree to match the version in the index, or
specified tree.
```bash
@@ -264,7 +269,7 @@ $ git checkout -b newBranch
### clone
Clones, or copies, an existing repository into a new directory. It also adds
-remote-tracking branches for each branch in the cloned repo, which allows you
+remote-tracking branches for each branch in the cloned repo, which allows you
to push to a remote branch.
```bash
@@ -280,13 +285,17 @@ $ git clone -b master-cn https://github.com/adambard/learnxinyminutes-docs.git -
### commit
-Stores the current contents of the index in a new "commit." This commit
+Stores the current contents of the index in a new "commit." This commit
contains the changes made and a message created by the user.
```bash
# commit with a message
$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
+# signed commit with a message (user.signingkey must have been set
+# with your GPG key e.g. git config --global user.signingkey 5173AAD5)
+$ git commit -S -m "signed commit message"
+
# automatically stage modified or deleted files, except new files, and then commit
$ git commit -a -m "Modified foo.php and removed bar.php"
@@ -392,11 +401,11 @@ Pulls from a repository and merges it with another branch.
$ git pull origin master
# By default, git pull will update your current branch
-# by merging in new changes from its remote-tracking branch
+# by merging in new changes from its remote-tracking branch
$ git pull
# Merge in changes from remote branch and rebase
-# branch commits onto your local repo, like: "git fetch <remote> <branch>, git
+# branch commits onto your local repo, like: "git fetch <remote> <branch>, git
# rebase <remote>/<branch>"
$ git pull origin master --rebase
```
@@ -412,7 +421,7 @@ Push and merge changes from a branch to a remote & branch.
$ git push origin master
# By default, git push will push and merge changes from
-# the current branch to its remote-tracking branch
+# the current branch to its remote-tracking branch
$ git push
# To link up current local branch with a remote branch, add -u flag:
@@ -423,11 +432,11 @@ $ git push
### stash
-Stashing takes the dirty state of your working directory and saves it on a
+Stashing takes the dirty state of your working directory and saves it on a
stack of unfinished changes that you can reapply at any time.
Let's say you've been doing some work in your git repo, but you want to pull
-from the remote. Since you have dirty (uncommited) changes to some files, you
+from the remote. Since you have dirty (uncommitted) changes to some files, you
are not able to run `git pull`. Instead, you can run `git stash` to save your
changes onto a stack!
@@ -455,7 +464,7 @@ nothing to commit, working directory clean
```
You can see what "hunks" you've stashed so far using `git stash list`.
-Since the "hunks" are stored in a Last-In-First-Out stack, our most recent
+Since the "hunks" are stored in a Last-In-First-Out stack, our most recent
change will be at top.
```bash
@@ -486,7 +495,7 @@ Now you're ready to get back to work on your stuff!
### rebase (caution)
-Take all changes that were committed on one branch, and replay them onto
+Take all changes that were committed on one branch, and replay them onto
another branch.
*Do not rebase commits that you have pushed to a public repo*.
@@ -501,7 +510,7 @@ $ git rebase master experimentBranch
### reset (caution)
Reset the current HEAD to the specified state. This allows you to undo merges,
-pulls, commits, adds, and more. It's a great command but also dangerous if you
+pulls, commits, adds, and more. It's a great command but also dangerous if you
don't know what you are doing.
```bash
@@ -516,7 +525,7 @@ $ git reset --hard
$ git reset 31f2bb1
# Moves the current branch tip backward to the specified commit
-# and makes the working dir match (deletes uncommited changes and all commits
+# and makes the working dir match (deletes uncommitted changes and all commits
# after the specified commit).
$ git reset --hard 31f2bb1
```
@@ -526,12 +535,13 @@ $ git reset --hard 31f2bb1
Reflog will list most of the git commands you have done for a given time period,
default 90 days.
-This give you the a change to reverse any git commands that have gone wrong
-for instance if a rebase is has broken your application.
+This give you the chance to reverse any git commands that have gone wrong
+(for instance, if a rebase has broken your application).
You can do this:
1. `git reflog` to list all of the git commands for the rebase
+
```
38b323f HEAD@{0}: rebase -i (finish): returning to refs/heads/feature/add_git_reflog
38b323f HEAD@{1}: rebase -i (pick): Clarify inc/dec operators
@@ -548,8 +558,8 @@ ed8ddf2 HEAD@{4}: rebase -i (pick): pythonstatcomp spanish translation (#1748)
### revert
-Revert can be used to undo a commit. It should not be confused with reset which
-restores the state of a project to a previous point. Revert will add a new
+Revert can be used to undo a commit. It should not be confused with reset which
+restores the state of a project to a previous point. Revert will add a new
commit which is the inverse of the specified commit, thus reverting it.
```bash
@@ -594,3 +604,5 @@ $ git rm /pather/to/the/file/HelloWorld.c
* [Pro Git](http://www.git-scm.com/book/en/v2)
* [An introduction to Git and GitHub for Beginners (Tutorial)](http://product.hubspot.com/blog/git-and-github-tutorial-for-beginners)
+
+* [The New Boston tutorial to Git covering basic commands and workflow](https://www.youtube.com/playlist?list=PL6gx4Cwl9DGAKWClAD_iKpNC0bGHxGhcx)
diff --git a/go.html.markdown b/go.html.markdown
index f097caeb..5a9214b0 100644
--- a/go.html.markdown
+++ b/go.html.markdown
@@ -12,24 +12,32 @@ contributors:
- ["Alexej Friesen", "https://github.com/heyalexej"]
- ["Clayton Walker", "https://github.com/cwalk"]
- ["Leonid Shevtsov", "https://github.com/leonid-shevtsov"]
+ - ["Michael Graf", "https://github.com/maerf0x0"]
+ - ["John Arundel", "https://github.com/bitfield"]
---
Go was created out of the need to get work done. It's not the latest trend
-in computer science, but it is the newest fastest way to solve real-world
+in programming language theory, but it is a way to solve real-world
problems.
-It has familiar concepts of imperative languages with static typing.
+It draws concepts from imperative languages with static typing.
It's fast to compile and fast to execute, it adds easy-to-understand
-concurrency to leverage today's multi-core CPUs, and has features to
-help with large-scale programming.
+concurrency because multi-core CPUs are now common, and it's used successfully
+in large codebases (~100 million loc at Google, Inc.).
-Go comes with a great standard library and an enthusiastic community.
+Go comes with a good standard library and a sizeable community.
```go
// Single line comment
/* Multi-
line comment */
+ /* A build tag is a line comment starting with // +build
+ and can be executed by go build -tags="foo bar" command.
+ Build tags are placed before the package clause near or at the top of the file
+ followed by a blank line or other line comments. */
+// +build prod, dev, test
+
// A package clause starts every source file.
// Main is a special name declaring an executable rather than a library.
package main
@@ -48,7 +56,7 @@ import (
// executable program. Love it or hate it, Go uses brace brackets.
func main() {
// Println outputs a line to stdout.
- // Qualify it with the package name, fmt.
+ // It comes from the package fmt.
fmt.Println("Hello world!")
// Call another function within this package.
@@ -99,16 +107,26 @@ can include line breaks.` // Same string type.
// Arrays have size fixed at compile time.
var a4 [4]int // An array of 4 ints, initialized to all 0.
- a3 := [...]int{3, 1, 5} // An array initialized with a fixed size of three
- // elements, with values 3, 1, and 5.
+ a5 := [...]int{3, 1, 5, 10, 100} // An array initialized with a fixed size of five
+ // elements, with values 3, 1, 5, 10, and 100.
+
+ // Arrays have value semantics.
+ a4_cpy := a4 // a4_cpy is a copy of a4, two separate instances.
+ a4_cpy[0] = 25 // Only a4_cpy is changed, a4 stays the same.
+ fmt.Println(a4_cpy[0] == a4[0]) // false
// Slices have dynamic size. Arrays and slices each have advantages
// but use cases for slices are much more common.
- s3 := []int{4, 5, 9} // Compare to a3. No ellipsis here.
+ s3 := []int{4, 5, 9} // Compare to a5. No ellipsis here.
s4 := make([]int, 4) // Allocates slice of 4 ints, initialized to all 0.
var d2 [][]float64 // Declaration only, nothing allocated here.
bs := []byte("a slice") // Type conversion syntax.
+ // Slices (as well as maps and channels) have reference semantics.
+ s3_cpy := s3 // Both variables point to the same instance.
+ s3_cpy[0] = 0 // Which means both are updated.
+ fmt.Println(s3_cpy[0] == s3[0]) // true
+
// Because they are dynamic, slices can be appended to on-demand.
// To append elements to a slice, the built-in append() function is used.
// First argument is a slice to which we are appending. Commonly,
@@ -134,7 +152,7 @@ can include line breaks.` // Same string type.
// Unused variables are an error in Go.
// The underscore lets you "use" a variable but discard its value.
- _, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs
+ _, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a5, s4, bs
// Usually you use it to ignore one of the return values of a function
// For example, in a quick and dirty script you might ignore the
// error value returned from os.Create, and expect that the file
@@ -161,10 +179,11 @@ func learnNamedReturns(x, y int) (z int) {
// Go is fully garbage collected. It has pointers but no pointer arithmetic.
// You can make a mistake with a nil pointer, but not by incrementing a pointer.
+// Unlike in C/Cpp taking and returning an address of a local varible is also safe.
func learnMemory() (p, q *int) {
// Named return values p and q have type pointer to int.
p = new(int) // Built-in function new allocates memory.
- // The allocated int is initialized to 0, p is no longer nil.
+ // The allocated int slice is initialized to 0, p is no longer nil.
s := make([]int, 20) // Allocate 20 ints as a single block of memory.
s[3] = 7 // Assign one of them.
r := -2 // Declare another local variable.
@@ -180,7 +199,7 @@ func learnFlowControl() {
if true {
fmt.Println("told ya")
}
- // Formatting is standardized by the command line command "go fmt."
+ // Formatting is standardized by the command line command "go fmt".
if false {
// Pout.
} else {
@@ -190,7 +209,7 @@ func learnFlowControl() {
x := 42.0
switch x {
case 0:
- case 1:
+ case 1, 2: // Can have multiple matches on one case
case 42:
// Cases don't "fall through".
/*
@@ -202,6 +221,19 @@ func learnFlowControl() {
default:
// Default case is optional.
}
+
+ // Type switch allows switching on the type of something instead of value
+ var data interface{}
+ data = ""
+ switch c := data.(type) {
+ case string:
+ fmt.Println(c, "is a string")
+ case int64:
+ fmt.Printf("%d is an int64\n", c)
+ default:
+ // all other cases
+ }
+
// Like if, for doesn't use parens either.
// Variables declared in for and if are local to their scope.
for x := 0; x < 3; x++ { // ++ is a statement.
@@ -277,7 +309,8 @@ func sentenceFactory(mystring string) func(before, after string) string {
}
func learnDefer() (ok bool) {
- // Deferred statements are executed just before the function returns.
+ // A defer statement pushes a function call onto a list. The list of saved
+ // calls is executed AFTER the surrounding function returns.
defer fmt.Println("deferred statements execute in reverse (LIFO) order.")
defer fmt.Println("\nThis line is being printed first because")
// Defer is commonly used to close a file, so the function closing the
@@ -295,7 +328,7 @@ type pair struct {
x, y int
}
-// Define a method on type pair. Pair now implements Stringer.
+// Define a method on type pair. Pair now implements Stringer because Pair has defined all the methods in the interface.
func (p pair) String() string { // p is called the "receiver"
// Sprintf is another public function in package fmt.
// Dot syntax references fields of p.
@@ -427,7 +460,7 @@ There you can follow the tutorial, play interactively, and read lots.
Aside from a tour, [the docs](https://golang.org/doc/) contain information on
how to write clean and effective Go code, package and command docs, and release history.
-The language definition itself is highly recommended. It's easy to read
+The [Go language specification](https://golang.org/ref/spec) itself is highly recommended. It's easy to read
and amazingly short (as language definitions go these days.)
You can play around with the code on [Go playground](https://play.golang.org/p/tnWMjr16Mm). Try to change it and run it from your browser! Note that you can use [https://play.golang.org](https://play.golang.org) as a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) to test things and code in your browser, without even installing Go.
@@ -440,4 +473,9 @@ documentation](http://golang.org/pkg/) and the source code comes up!
Another great resource to learn Go is [Go by example](https://gobyexample.com/).
+There are many excellent conference talks and video tutorials on Go available on YouTube, and here are three playlists of the very best, tailored for beginners, intermediate, and advanced Gophers respectively:
+* [Golang University 101](https://www.youtube.com/playlist?list=PLEcwzBXTPUE9V1o8mZdC9tNnRZaTgI-1P) introduces fundamental Go concepts and shows you how to use the Go tools to create and manage Go code
+* [Golang University 201](https://www.youtube.com/playlist?list=PLEcwzBXTPUE_5m_JaMXmGEFgduH8EsuTs) steps it up a notch, explaining important techniques like testing, web services, and APIs
+* [Golang University 301](https://www.youtube.com/watch?v=YHRO5WQGh0k&list=PLEcwzBXTPUE8KvXRFmmfPEUmKoy9LfmAf) dives into more advanced topics like the Go scheduler, implementation of maps and channels, and optimisation techniques
+
Go Mobile adds support for mobile platforms (Android and iOS). You can write all-Go native mobile apps or write a library that contains bindings from a Go package, which can be invoked via Java (Android) and Objective-C (iOS). Check out the [Go Mobile page](https://github.com/golang/go/wiki/Mobile) for more information.
diff --git a/groovy.html.markdown b/groovy.html.markdown
index a3a45757..0d589c10 100644
--- a/groovy.html.markdown
+++ b/groovy.html.markdown
@@ -181,6 +181,21 @@ class Foo {
}
/*
+ Methods with optional parameters
+*/
+
+// A method can have default values for parameters
+def say(msg = 'Hello', name = 'world') {
+ "$msg $name!"
+}
+
+// It can be called in 3 different ways
+assert 'Hello world!' == say()
+// Right most parameter with default value is eliminated first.
+assert 'Hi world!' == say('Hi')
+assert 'learn groovy' == say('learn', 'groovy')
+
+/*
Logical Branching and Looping
*/
@@ -230,10 +245,12 @@ for (i in array) {
//Iterate over a map
def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
-x = 0
+x = ""
for ( e in map ) {
x += e.value
+ x += " "
}
+assert x.equals("Roberto Grails Groovy ")
/*
Operators
diff --git a/hack.html.markdown b/hack.html.markdown
index b3d19f8e..fb6af8e1 100644
--- a/hack.html.markdown
+++ b/hack.html.markdown
@@ -257,7 +257,7 @@ class InvalidFooSubclass extends ConsistentFoo
// ...
}
- // Using the __Override annotation on a non-overriden method will cause a
+ // Using the __Override annotation on a non-overridden method will cause a
// type checker error:
//
// "InvalidFooSubclass::otherMethod() is marked as override; no non-private
@@ -299,7 +299,7 @@ $cat instanceof KittenInterface === true; // True
## More Information
Visit the [Hack language reference](http://docs.hhvm.com/manual/en/hacklangref.php)
-for detailed explainations of the features Hack adds to PHP, or the [official Hack website](http://hacklang.org/)
+for detailed explanations of the features Hack adds to PHP, or the [official Hack website](http://hacklang.org/)
for more general information.
Visit the [official HHVM website](http://hhvm.com/) for HHVM installation instructions.
diff --git a/haml.html.markdown b/haml.html.markdown
index 0948e9ef..bb8bdc54 100644
--- a/haml.html.markdown
+++ b/haml.html.markdown
@@ -3,6 +3,7 @@ language: haml
filename: learnhaml.haml
contributors:
- ["Simon Neveu", "https://github.com/sneveu"]
+ - ["Vasiliy Petrov", "https://github.com/Saugardas"]
---
Haml is a markup language predominantly used with Ruby that cleanly and simply describes the HTML of any web document without the use of inline code. It is a popular alternative to using Rails templating language (.erb) and allows you to embed Ruby code into your markup.
@@ -11,7 +12,9 @@ It aims to reduce repetition in your markup by closing tags for you based on the
You can also use Haml on a project independent of Ruby, by installing the Haml gem on your machine and using the command line to convert it to html.
+```shell
$ haml input_file.haml output_file.html
+```
```haml
@@ -36,7 +39,7 @@ $ haml input_file.haml output_file.html
To write a multi line comment, indent your commented code to be
wrapped by the forward slash
--# This is a silent comment, which means it wont be rendered into the doc at all
+-# This is a silent comment, which means it won't be rendered into the doc at all
/ -------------------------------------------
@@ -55,8 +58,17 @@ $ haml input_file.haml output_file.html
</header>
</body>
-/ The div tag is the default element, so they can be written simply like this
-.foo
+/
+ The div tag is the default element, so it can be omitted.
+ You can define only class/id using . or #
+ For example
+
+%div.my_class
+ %div#my_id
+
+/ Can be written
+.my_class
+ #my_id
/ To add content to a tag, add the text directly after the declaration
%h1 Headline copy
@@ -97,6 +109,15 @@ $ haml input_file.haml output_file.html
/ To write data-attributes, use the :data key with its value as another hash
%div{:data => {:attribute => 'foo'}}
+/ For Ruby version 1.9 or higher you can use Ruby's new hash syntax
+%div{ data: { attribute: 'foo' } }
+
+/ Also you can use HTML-style attribute syntax.
+%a(href='#' title='bar')
+
+/ And both syntaxes together
+%a(href='#'){ title: @my_class.title }
+
/ -------------------------------------------
/ Inserting Ruby
@@ -120,7 +141,7 @@ $ haml input_file.haml output_file.html
- books.shuffle.each_with_index do |book, index|
%h1= book
- if book do
+ - if book do
%p This is a book
/ Adding ordered / unordered list
@@ -166,12 +187,33 @@ $ haml input_file.haml output_file.html
/ -------------------------------------------
/
- Use the colon to define Haml filters, one example of a filter you can
- use is :javascript, which can be used for writing inline js
+ Filters pass the block to another filtering program and return the result in Haml
+ To use a filter, type a colon and the name of the filter
+
+/ Markdown filter
+:markdown
+ # Header
+ Text **inside** the *block*
+
+/ The code above is compiled into
+<h1>Header</h1>
+
+<p>Text <strong>inside</strong> the <em>block</em></p>
+
+/ Javascript filter
:javascript
console.log('This is inline <script>');
+/ is compiled into
+<script>
+ console.log('This is inline <script>');
+</script>
+
+/
+ There are many types of filters (:markdown, :javascript, :coffee, :css, :ruby and so on)
+ Also you can define your own filters using Haml::Filters
+
```
## Additional resources
diff --git a/haskell.html.markdown b/haskell.html.markdown
index 4ce1a839..328da5c9 100644
--- a/haskell.html.markdown
+++ b/haskell.html.markdown
@@ -1,5 +1,6 @@
---
language: Haskell
+filename: learnhaskell.hs
contributors:
- ["Adit Bhargava", "http://adit.io"]
---
@@ -60,15 +61,17 @@ not False -- True
-- A string is a list of characters
['H', 'e', 'l', 'l', 'o'] -- "Hello"
+
+-- Lists can be indexed with the `!!` operator followed by an index
"This is a string" !! 0 -- 'T'
----------------------------------------------------
--- Lists and Tuples
+-- 2. Lists and Tuples
----------------------------------------------------
-- Every element in a list must have the same type.
--- These two lists are the same:
+-- These two lists are equal:
[1, 2, 3, 4, 5]
[1..5]
@@ -77,11 +80,11 @@ not False -- True
-- You can create a step in a range.
[0,2..10] -- [0, 2, 4, 6, 8, 10]
-[5..1] -- This doesn't work because Haskell defaults to incrementing.
+[5..1] -- [] (Haskell defaults to incrementing)
[5,4..1] -- [5, 4, 3, 2, 1]
-- indexing into a list
-[1..10] !! 3 -- 4
+[1..10] !! 3 -- 4 (zero-based indexing)
-- You can also have infinite lists in Haskell!
[1..] -- a list of all the natural numbers
@@ -123,6 +126,9 @@ last [1..5] -- 5
fst ("haskell", 1) -- "haskell"
snd ("haskell", 1) -- 1
+-- pair element accessing does not work on n-tuples (i.e. triple, quadruple, etc)
+snd ("snd", "can't touch this", "da na na na") -- error! see function below
+
----------------------------------------------------
-- 3. Functions
----------------------------------------------------
@@ -152,14 +158,14 @@ fib x
| otherwise = fib (x - 1) + fib (x - 2)
-- Pattern matching is similar. Here we have given three different
--- definitions for fib. Haskell will automatically call the first
--- function that matches the pattern of the value.
+-- equations that define fib. Haskell will automatically use the first
+-- equation whose left hand side pattern matches the value.
fib 1 = 1
fib 2 = 2
fib x = fib (x - 1) + fib (x - 2)
--- Pattern matching on tuples:
-foo (x, y) = (x + 1, y + 2)
+-- Pattern matching on tuples
+sndOfTriple (_, y, _) = y -- use a wild card (_) to bypass naming unused value
-- Pattern matching on lists. Here `x` is the first element
-- in the list, and `xs` is the rest of the list. We can write
@@ -198,15 +204,15 @@ foo 5 -- 15
-- multiplies the result of that by 4, and then returns the final value.
foo = (4*) . (10+)
--- 4*(10 + 5) = 60
+-- 4*(10+5) = 60
foo 5 -- 60
-- fixing precedence
--- Haskell has another operator called `$`. This operator applies a function
--- to a given parameter. In contrast to standard function application, which
--- has highest possible priority of 10 and is left-associative, the `$` operator
+-- Haskell has an operator called `$`. This operator applies a function
+-- to a given parameter. In contrast to standard function application, which
+-- has highest possible priority of 10 and is left-associative, the `$` operator
-- has priority of 0 and is right-associative. Such a low priority means that
--- the expression on its right is applied as the parameter to the function on its left.
+-- the expression on its right is applied as a parameter to the function on its left.
-- before
even (fib 7) -- false
@@ -222,7 +228,7 @@ even . fib $ 7 -- false
-- 5. Type signatures
----------------------------------------------------
--- Haskell has a very strong type system, and every valid expression has a type.
+-- Haskell has a very strong type system, and every valid expression has a type.
-- Some basic types:
5 :: Integer
@@ -244,10 +250,10 @@ double x = x * 2
-- 6. Control Flow and If Expressions
----------------------------------------------------
--- if expressions
+-- if-expressions
haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
--- if expressions can be on multiple lines too, indentation is important
+-- if-expressions can be on multiple lines too, indentation is important
haskell = if 1 == 1
then "awesome"
else "awful"
@@ -289,19 +295,79 @@ foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
-- 7. Data Types
----------------------------------------------------
--- Here's how you make your own data type in Haskell
+-- A data type is declared with a 'type constructor' on the left
+-- and one or more 'data constructors' on the right, separated by
+-- the pipe | symbol. This is a sum/union type. Each data constructor
+-- is a (possibly nullary) function that creates an object of the type
+-- named by the type constructor.
+
+-- This is essentially an enum
data Color = Red | Blue | Green
-- Now you can use it in a function:
-
say :: Color -> String
-say Red = "You are Red!"
-say Blue = "You are Blue!"
-say Green = "You are Green!"
+say Red = "You are Red!"
+say Blue = "You are Blue!"
+say Green = "You are Green!"
+
+-- Note that the type constructor is used in the type signature
+-- and the data constructors are used in the body of the function
+-- Data constructors are primarily pattern-matched against
+
+-- This next one is a traditional container type holding two fields
+-- In a type declaration, data constructors take types as parameters
+-- Data constructors can have the same name as type constructors
+-- This is common where the type only has a single data constructor
+
+data Point = Point Float Float
+
+-- This can be used in a function like:
+
+distance :: Point -> Point -> Float
+distance (Point x y) (Point x' y') = sqrt $ dx + dy
+ where dx = (x - x') ** 2
+ dy = (y - y') ** 2
+
+-- Types can have multiple data constructors with arguments, too
+
+data Name = Mononym String
+ | FirstLastName String String
+ | FullName String String String
+
+-- To make things clearer we can use record syntax
+
+data Point2D = CartesianPoint2D { x :: Float, y :: Float }
+ | PolarPoint2D { r :: Float, theta :: Float }
+
+myPoint = CartesianPoint2D { x = 7.0, y = 10.0 }
+
+-- Using record syntax automatically creates accessor functions
+-- (the name of the field)
+
+xOfMyPoint = x myPoint
+
+-- xOfMyPoint is equal to 7.0
+
+-- Record syntax also allows a simple form of update
--- Your data types can have parameters too:
+myPoint' = myPoint { x = 9.0 }
+
+-- myPoint' is CartesianPoint2D { x = 9.0, y = 10.0 }
+
+-- Even if a type is defined with record syntax, it can be declared like
+-- a simple data constructor. This is fine:
+
+myPoint'2 = CartesianPoint2D 3.3 4.0
+
+-- It's also useful to pattern match data constructors in `case` expressions
+
+distanceFromOrigin x =
+ case x of (CartesianPoint2D x y) -> sqrt $ x ** 2 + y ** 2
+ (PolarPoint2D r _) -> r
+
+-- Your data types can have type parameters too:
data Maybe a = Nothing | Just a
@@ -310,8 +376,98 @@ Just "hello" -- of type `Maybe String`
Just 1 -- of type `Maybe Int`
Nothing -- of type `Maybe a` for any `a`
+-- For convenience we can also create type synonyms with the 'type' keyword
+
+type String = [Char]
+
+-- Unlike `data` types, type synonyms need no constructor, and can be used
+-- anywhere a synonymous data type could be used. Say we have the
+-- following type synonyms and items with the following type signatures
+
+type Weight = Float
+type Height = Float
+type Point = (Float, Float)
+getMyHeightAndWeight :: Person -> (Height, Weight)
+findCenter :: Circle -> Point
+somePerson :: Person
+someCircle :: Circle
+distance :: Point -> Point -> Float
+
+-- The following would compile and run without issue,
+-- even though it does not make sense semantically,
+-- because the type synonyms reduce to the same base types
+
+distance (getMyHeightAndWeight somePerson) (findCenter someCircle)
+
+----------------------------------------------------
+-- 8. Typeclasses
+----------------------------------------------------
+
+-- Typeclasses are one way Haskell does polymorphism
+-- They are similar to interfaces in other languages
+-- A typeclass defines a set of functions that must
+-- work on any type that is in that typeclass.
+
+-- The Eq typeclass is for types whose instances can
+-- be tested for equality with one another.
+
+class Eq a where
+ (==) :: a -> a -> Bool
+ (/=) :: a -> a -> Bool
+ x == y = not (x /= y)
+ x /= y = not (x == y)
+
+-- This defines a typeclass that requires two functions, (==) and (/=)
+-- It also declares that one function can be declared in terms of another
+-- So it is enough that *either* the (==) function or the (/=) is defined
+-- And the other will be 'filled in' based on the typeclass definition
+
+-- To make a type a member of a type class, the instance keyword is used
+
+instance Eq TrafficLight where
+ Red == Red = True
+ Green == Green = True
+ Yellow == Yellow = True
+ _ == _ = False
+
+-- Now we can use (==) and (/=) with TrafficLight objects
+
+canProceedThrough :: TrafficLight -> Bool
+canProceedThrough t = t /= Red
+
+-- You can NOT create an instance definition for a type synonym
+
+-- Functions can be written to take typeclasses with type parameters,
+-- rather than types, assuming that the function only relies on
+-- features of the typeclass
+
+isEqual (Eq a) => a -> a -> Bool
+isEqual x y = x == y
+
+-- Note that x and y MUST be the same type, as they are both defined
+-- as being of type parameter 'a'.
+-- A typeclass does not state that different types in the typeclass can
+-- be mixed together.
+-- So `isEqual Red 2` is invalid, even though 2 is an Int which is an
+-- instance of Eq, and Red is a TrafficLight which is also an instance of Eq
+
+-- Other common typeclasses are:
+-- Ord for types that can be ordered, allowing you to use >, <=, etc.
+-- Read for types that can be created from a string representation
+-- Show for types that can be converted to a string for display
+-- Num, Real, Integral, Fractional for types that can do math
+-- Enum for types that can be stepped through
+-- Bounded for types with a maximum and minimum
+
+-- Haskell can automatically make types part of Eq, Ord, Read, Show, Enum,
+-- and Bounded with the `deriving` keyword at the end of the type declaration
+
+data Point = Point Float Float deriving (Eq, Read, Show)
+
+-- In this case it is NOT necessary to create an 'instance' definition
+
----------------------------------------------------
--- 8. Haskell IO
+-- 9. Haskell IO
----------------------------------------------------
-- While IO can't be explained fully without explaining monads,
@@ -384,15 +540,15 @@ main'' = do
-- The type `IO` is an example of a "monad". The way Haskell uses a monad to
-- do IO allows it to be a purely functional language. Any function that
-- interacts with the outside world (i.e. does IO) gets marked as `IO` in its
--- type signature. This lets us reason about what functions are "pure" (don't
--- interact with the outside world or modify state) and what functions aren't.
+-- type signature. This lets us reason about which functions are "pure" (don't
+-- interact with the outside world or modify state) and which functions aren't.
-- This is a powerful feature, because it's easy to run pure functions
-- concurrently; so, concurrency in Haskell is very easy.
----------------------------------------------------
--- 9. The Haskell REPL
+-- 10. The Haskell REPL
----------------------------------------------------
-- Start the repl by typing `ghci`.
@@ -444,5 +600,6 @@ qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
There are two popular ways to install Haskell: The traditional [Cabal-based installation](http://www.haskell.org/platform/), and the newer [Stack-based process](https://www.stackage.org/install).
You can find a much gentler introduction from the excellent
-[Learn you a Haskell](http://learnyouahaskell.com/) or
+[Learn you a Haskell](http://learnyouahaskell.com/),
+[Happy Learn Haskell Tutorial](http://www.happylearnhaskelltutorial.com/) or
[Real World Haskell](http://book.realworldhaskell.org/).
diff --git a/haxe.html.markdown b/haxe.html.markdown
index ee214540..e086dd7a 100644
--- a/haxe.html.markdown
+++ b/haxe.html.markdown
@@ -6,18 +6,19 @@ contributors:
- ["Dan Korostelev", "https://github.com/nadako/"]
---
-Haxe is a web-oriented language that provides platform support for C++, C#,
-Swf/ActionScript, Javascript, Java, and Neko byte code (also written by the
-Haxe author). Note that this guide is for Haxe version 3. Some of the guide
-may be applicable to older versions, but it is recommended to use other
-references.
+[Haxe](https://haxe.org/) is a general-purpose language that provides platform support for C++, C#,
+Swf/ActionScript, JavaScript, Java, PHP, Python, Lua, HashLink, and Neko bytecode
+(the latter two being also written by the Haxe author). Note that this guide is for
+Haxe version 3. Some of the guide may be applicable to older versions, but it is
+recommended to use other references.
```csharp
/*
Welcome to Learn Haxe 3 in 15 minutes. http://www.haxe.org
This is an executable tutorial. You can compile and run it using the haxe
compiler, while in the same directory as LearnHaxe.hx:
- $> haxe -main LearnHaxe3 -x out
+
+ $ haxe -main LearnHaxe3 --interp
Look for the slash-star marks surrounding these paragraphs. We are inside
a "Multiline comment". We can leave some notes here that will get ignored
@@ -26,16 +27,14 @@ references.
Multiline comments are also used to generate javadoc-style documentation for
haxedoc. They will be used for haxedoc if they immediately precede a class,
class function, or class variable.
-
*/
-// Double slashes like this will give a single-line comment
-
+// Double slashes like this will give a single-line comment.
/*
This is your first actual haxe code coming up, it's declaring an empty
- package. A package isn't necessary, but it's useful if you want to create a
- namespace for your code (e.g. org.yourapp.ClassName).
+ package. A package isn't necessary, but it's useful if you want to create
+ a namespace for your code (e.g. org.yourapp.ClassName).
Omitting package declaration is the same as declaring an empty package.
*/
@@ -47,8 +46,9 @@ package; // empty package, no namespace.
must be lower case while module names are capitalized. A module contain one
or more types whose names are also capitalized.
- E.g, the class "org.yourapp.Foo" should have the folder structure org/module/Foo.hx,
- as accessible from the compiler's working directory or class path.
+ E.g, the class "org.yourapp.Foo" should have the folder structure
+ org/module/Foo.hx, as accessible from the compiler's working directory or
+ class path.
If you import code from other files, it must be declared before the rest of
the code. Haxe provides a lot of common default classes to get you started:
@@ -64,34 +64,27 @@ import Lambda.array;
// you can also use "*" to import all static fields
import Math.*;
-/*
- You can also import classes in a special way, enabling them to extend the
- functionality of other classes like a "mixin". More on 'using' later.
- */
+// You can also import classes in a special way, enabling them to extend the
+// functionality of other classes like a "mixin". More on 'using' later.
using StringTools;
-/*
- Typedefs are like variables... for types. They must be declared before any
- code. More on this later.
- */
+// Typedefs are like variables... for types. They must be declared before any
+// code. More on this later.
typedef FooString = String;
// Typedefs can also reference "structural" types, more on that later as well.
typedef FooObject = { foo: String };
-/*
- Here's the class definition. It's the main class for the file, since it has
- the same name (LearnHaxe3).
- */
-class LearnHaxe3{
+// Here's the class definition. It's the main class for the file, since it has
+// the same name (LearnHaxe3).
+class LearnHaxe3 {
/*
If you want certain code to run automatically, you need to put it in
a static main function, and specify the class in the compiler arguments.
In this case, we've specified the "LearnHaxe3" class in the compiler
arguments above.
*/
- static function main(){
-
+ static function main() {
/*
Trace is the default method of printing haxe expressions to the
screen. Different targets will have different methods of
@@ -103,17 +96,13 @@ class LearnHaxe3{
*/
trace("Hello World, with trace()!");
- /*
- Trace can handle any type of value or object. It will try to print
- a representation of the expression as best it can. You can also
- concatenate strings with the "+" operator:
- */
- trace( " Integer: " + 10 + " Float: " + 3.14 + " Boolean: " + true);
+ // Trace can handle any type of value or object. It will try to print
+ // a representation of the expression as best it can. You can also
+ // concatenate strings with the "+" operator:
+ trace("Integer: " + 10 + " Float: " + 3.14 + " Boolean: " + true);
- /*
- In Haxe, it's required to separate expressions in the same block with
- semicolons. But, you can put two expressions on one line:
- */
+ // In Haxe, it's required to separate expressions in the same block with
+ // semicolons. But, you can put two expressions on one line:
trace('two expressions..'); trace('one line');
@@ -122,14 +111,11 @@ class LearnHaxe3{
//////////////////////////////////////////////////////////////////
trace("***Types & Variables***");
- /*
- You can save values and references to data structures using the
- "var" keyword:
- */
+ // You can save values and references to data structures using the
+ // "var" keyword:
var an_integer:Int = 1;
trace(an_integer + " is the value for an_integer");
-
/*
Haxe is statically typed, so "an_integer" is declared to have an
"Int" type, and the rest of the expression assigns the value "1" to
@@ -150,46 +136,36 @@ class LearnHaxe3{
Haxe uses platform precision for Int and Float sizes. It also
uses the platform behavior for overflow.
(Other numeric types and behavior are possible using special
- libraries)
- */
-
- /*
+ libraries.)
+
In addition to simple values like Integers, Floats, and Booleans,
Haxe provides standard library implementations for common data
structures like strings, arrays, lists, and maps:
*/
- var a_string = "some" + 'string'; // strings can have double or single quotes
+ // Strings can have double or single quotes.
+ var a_string = "some" + 'string';
trace(a_string + " is the value for a_string");
- /*
- Strings can be "interpolated" by inserting variables into specific
- positions. The string must be single quoted, and the variable must
- be preceded with "$". Expressions can be enclosed in ${...}.
- */
+ // Strings can be "interpolated" by inserting variables into specific
+ // positions. The string must be single quoted, and the variable must
+ // be preceded with "$". Expressions can be enclosed in ${...}.
var x = 1;
var an_interpolated_string = 'the value of x is $x';
var another_interpolated_string = 'the value of x + 1 is ${x + 1}';
- /*
- Strings are immutable, instance methods will return a copy of
- parts or all of the string.
- (See also the StringBuf class).
- */
+ // Strings are immutable, instance methods will return a copy of
+ // parts or all of the string. (See also the StringBuf class).
var a_sub_string = a_string.substr(0,4);
trace(a_sub_string + " is the value for a_sub_string");
- /*
- Regexes are also supported, but there's not enough space to go into
- much detail.
- */
+ // Regexes are also supported, but there's not enough space here to go
+ // into much detail.
var re = ~/foobar/;
trace(re.match('foo') + " is the value for (~/foobar/.match('foo')))");
- /*
- Arrays are zero-indexed, dynamic, and mutable. Missing values are
- defined as null.
- */
+ // Arrays are zero-indexed, dynamic, and mutable. Missing values are
+ // defined as null.
var a = new Array<String>(); // an array that contains Strings
a[0] = 'foo';
trace(a.length + " is the value for a.length");
@@ -197,41 +173,34 @@ class LearnHaxe3{
trace(a.length + " is the value for a.length (after modification)");
trace(a[3] + " is the value for a[3]"); //null
- /*
- Arrays are *generic*, so you can indicate which values they contain
- with a type parameter:
- */
+ // Arrays are *generic*, so you can indicate which values they contain
+ // with a type parameter:
var a2 = new Array<Int>(); // an array of Ints
var a3 = new Array<Array<String>>(); // an Array of Arrays (of Strings).
- /*
- Maps are simple key/value data structures. The key and the value
- can be of any type.
- */
- var m = new Map<String, Int>(); // The keys are strings, the values are Ints.
+ // Maps are simple key/value data structures. The key and the value
+ // can be of any type.
+ // Here, the keys are strings, and the values are Ints:
+ var m = new Map<String, Int>();
m.set('foo', 4);
- // You can also use array notation;
+ // You can also use array notation:
m['bar'] = 5;
trace(m.exists('bar') + " is the value for m.exists('bar')");
trace(m.get('bar') + " is the value for m.get('bar')");
trace(m['bar'] + " is the value for m['bar']");
- var m2 = ['foo' => 4, 'baz' => 6]; // Alternative map syntax
+ var m2 = ['foo' => 4, 'baz' => 6]; // Alternative map syntax
trace(m2 + " is the value for m2");
- /*
- Remember, you can use type inference. The Haxe compiler will
- decide the type of the variable the first time you pass an
- argument that sets a type parameter.
- */
+ // Remember, you can use type inference. The Haxe compiler will
+ // decide the type of the variable the first time you pass an
+ // argument that sets a type parameter.
var m3 = new Map();
m3.set(6, 'baz'); // m3 is now a Map<Int,String>
trace(m3 + " is the value for m3");
- /*
- Haxe has some more common datastructures in the haxe.ds module, such as
- List, Stack, and BalancedTree
- */
+ // Haxe has some more common datastructures in the haxe.ds module, such
+ // as List, Stack, and BalancedTree.
//////////////////////////////////////////////////////////////////
@@ -243,11 +212,11 @@ class LearnHaxe3{
trace((4 + 3) + " is the value for (4 + 3)");
trace((5 - 1) + " is the value for (5 - 1)");
trace((2 * 4) + " is the value for (2 * 4)");
- trace((8 / 3) + " is the value for (8 / 3) (division always produces Floats)");
+ // Division always produces Floats.
+ trace((8 / 3) + " is the value for (8 / 3) (a Float)");
trace((12 % 4) + " is the value for (12 % 4)");
-
- //basic comparison
+ // basic comparison
trace((3 == 2) + " is the value for 3 == 2");
trace((3 != 2) + " is the value for 3 != 2");
trace((3 > 2) + " is the value for 3 > 2");
@@ -257,22 +226,22 @@ class LearnHaxe3{
// standard bitwise operators
/*
- ~ Unary bitwise complement
- << Signed left shift
- >> Signed right shift
- >>> Unsigned right shift
- & Bitwise AND
- ^ Bitwise exclusive OR
- | Bitwise inclusive OR
+ ~ Unary bitwise complement
+ << Signed left shift
+ >> Signed right shift
+ >>> Unsigned right shift
+ & Bitwise AND
+ ^ Bitwise exclusive OR
+ | Bitwise inclusive OR
*/
-
- //increments
+
var i = 0;
- trace("Increments and decrements");
- trace(i++); //i = 1. Post-Incrementation
- trace(++i); //i = 2. Pre-Incrementation
- trace(i--); //i = 1. Post-Decrementation
- trace(--i); //i = 0. Pre-Decrementation
+ trace("Pre-/Post- Increments and Decrements");
+ trace(i++); // i = 1. Post-Increment
+ trace(++i); // i = 2. Pre-Increment
+ trace(i--); // i = 1. Post-Decrement
+ trace(--i); // i = 0. Pre-Decrement
+
//////////////////////////////////////////////////////////////////
// Control Structures
@@ -281,21 +250,19 @@ class LearnHaxe3{
// if statements
var j = 10;
- if (j == 10){
+ if (j == 10) {
trace("this is printed");
- } else if (j > 10){
+ } else if (j > 10) {
trace("not greater than 10, so not printed");
} else {
trace("also not printed.");
}
// there is also a "ternary" if:
- (j == 10) ? trace("equals 10") : trace("not equals 10");
+ (j == 10) ? trace("equals 10") : trace("not equals 10");
- /*
- Finally, there is another form of control structures that operates
- at compile time: conditional compilation.
- */
+ // Finally, there is another form of control structure that operates
+ // at compile time: conditional compilation.
#if neko
trace('hello from neko');
#elseif js
@@ -303,43 +270,40 @@ class LearnHaxe3{
#else
trace('hello from another platform!');
#end
- /*
- The compiled code will change depending on the platform target.
- Since we're compiling for neko (-x or -neko), we only get the neko
- greeting.
- */
+
+ // The compiled code will change depending on the platform target.
+ // Since we're compiling for neko (-x or -neko), we only get the neko
+ // greeting.
trace("Looping and Iteration");
// while loop
var k = 0;
- while(k < 100){
+ while (k < 100) {
// trace(counter); // will print out numbers 0-99
k++;
}
// do-while loop
- var l = 0;
- do{
+ var l = 0;
+ do {
trace("do statement always runs at least once");
} while (l > 0);
// for loop
- /*
- There is no c-style for loop in Haxe, because they are prone
- to error, and not necessary. Instead, Haxe has a much simpler
- and safer version that uses Iterators (more on those later).
- */
- var m = [1,2,3];
- for (val in m){
+ // There is no c-style for loop in Haxe, because they are prone
+ // to error, and not necessary. Instead, Haxe has a much simpler
+ // and safer version that uses Iterators (more on those later).
+ var m = [1, 2, 3];
+ for (val in m) {
trace(val + " is the value for val in the m array");
}
// Note that you can iterate on an index using a range
// (more on ranges later as well)
var n = ['foo', 'bar', 'baz'];
- for (val in 0...n.length){
+ for (val in 0...n.length) {
trace(val + " is the value for val (an index for n)");
}
@@ -354,8 +318,11 @@ class LearnHaxe3{
var modified_n = [for (val in n) val += '!'];
trace(modified_n + " is the value for modified_n");
- var filtered_and_modified_n = [for (val in n) if (val != "foo") val += "!"];
- trace(filtered_and_modified_n + " is the value for filtered_and_modified_n");
+ var filtered_and_modified_n
+ = [for (val in n) if (val != "foo") val += "!"];
+ trace(filtered_and_modified_n
+ + " is the value for filtered_and_modified_n");
+
//////////////////////////////////////////////////////////////////
// Switch Statements (Value Type)
@@ -366,50 +333,50 @@ class LearnHaxe3{
Switch statements in Haxe are very powerful. In addition to working
on basic values like strings and ints, they can also work on the
generalized algebraic data types in enums (more on enums later).
- Here's some basic value examples for now:
+ Here are some basic value examples for now:
*/
var my_dog_name = "fido";
var favorite_thing = "";
- switch(my_dog_name){
+ switch (my_dog_name) {
case "fido" : favorite_thing = "bone";
case "rex" : favorite_thing = "shoe";
case "spot" : favorite_thing = "tennis ball";
default : favorite_thing = "some unknown treat";
- // case _ : favorite_thing = "some unknown treat"; // same as default
+ // same as default:
+ // case _ : favorite_thing = "some unknown treat";
}
- // The "_" case above is a "wildcard" value
- // that will match anything.
+ // The "_" case above is a "wildcard" value that will match anything.
- trace("My dog's name is" + my_dog_name
+ trace("My dog's name is " + my_dog_name
+ ", and his favorite thing is a: "
+ favorite_thing);
+
//////////////////////////////////////////////////////////////////
// Expression Statements
//////////////////////////////////////////////////////////////////
trace("***EXPRESSION STATEMENTS***");
- /*
- Haxe control statements are very powerful because every statement
- is also an expression, consider:
- */
+ // Haxe control statements are very powerful because every statement
+ // is also an expression, consider:
// if statements
var k = if (true) 10 else 20;
trace("k equals ", k); // outputs 10
- var other_favorite_thing = switch(my_dog_name) {
+ var other_favorite_thing = switch (my_dog_name) {
case "fido" : "teddy";
case "rex" : "stick";
case "spot" : "football";
default : "some unknown treat";
}
- trace("My dog's name is" + my_dog_name
+ trace("My dog's name is " + my_dog_name
+ ", and his other favorite thing is a: "
+ other_favorite_thing);
+
//////////////////////////////////////////////////////////////////
// Converting Value Types
//////////////////////////////////////////////////////////////////
@@ -418,14 +385,14 @@ class LearnHaxe3{
// You can convert strings to ints fairly easily.
// string to integer
- Std.parseInt("0"); // returns 0
- Std.parseFloat("0.4"); // returns 0.4;
+ Std.parseInt("0"); // returns 0
+ Std.parseFloat("0.4"); // returns 0.4
// integer to string
- Std.string(0); // returns "0";
+ Std.string(0); // returns "0"
// concatenation with strings will auto-convert to string.
- 0 + ""; // returns "0";
- true + ""; // returns "true";
+ 0 + ""; // returns "0"
+ true + ""; // returns "true"
// See documentation for parsing in Std for more details.
@@ -434,14 +401,13 @@ class LearnHaxe3{
//////////////////////////////////////////////////////////////////
/*
-
As mentioned before, Haxe is a statically typed language. All in
all, static typing is a wonderful thing. It enables
precise autocompletions, and can be used to thoroughly check the
correctness of a program. Plus, the Haxe compiler is super fast.
- *HOWEVER*, there are times when you just wish the compiler would let
- something slide, and not throw a type error in a given case.
+ *HOWEVER*, there are times when you just wish the compiler would
+ let something slide, and not throw a type error in a given case.
To do this, Haxe has two separate keywords. The first is the
"Dynamic" type:
@@ -456,17 +422,16 @@ class LearnHaxe3{
The other more extreme option is the "untyped" keyword:
*/
-
- untyped {
- var x:Int = 'foo'; // this can't be right!
- var y:String = 4; // madness!
- }
+ untyped {
+ var x:Int = 'foo'; // This can't be right!
+ var y:String = 4; // Madness!
+ }
/*
The untyped keyword operates on entire *blocks* of code, skipping
any type checks that might be otherwise required. This keyword should
be used very sparingly, such as in limited conditionally-compiled
- situations where type checking is a hinderance.
+ situations where type checking is a hindrance.
In general, skipping type checks is *not* recommended. Use the
enum, inheritance, or structural type models in order to help ensure
@@ -474,74 +439,66 @@ class LearnHaxe3{
of the type models work should you resort to "Dynamic" or "untyped".
*/
+
//////////////////////////////////////////////////////////////////
// Basic Object Oriented Programming
//////////////////////////////////////////////////////////////////
trace("***BASIC OBJECT ORIENTED PROGRAMMING***");
-
- /*
- Create an instance of FooClass. The classes for this are at the
- end of the file.
- */
+ // Create an instance of FooClass. The classes for this are at the
+ // end of the file.
var foo_instance = new FooClass(3);
// read the public variable normally
- trace(foo_instance.public_any + " is the value for foo_instance.public_any");
+ trace(foo_instance.public_any
+ + " is the value for foo_instance.public_any");
// we can read this variable
- trace(foo_instance.public_read + " is the value for foo_instance.public_read");
- // but not write it
- // foo_instance.public_read = 4; // this will throw an error if uncommented:
+ trace(foo_instance.public_read
+ + " is the value for foo_instance.public_read");
+ // but not write it; this will throw an error if uncommented:
+ // foo_instance.public_read = 4;
// trace(foo_instance.public_write); // as will this.
- // calls the toString method:
+ // Calls the toString method:
trace(foo_instance + " is the value for foo_instance");
// same thing:
- trace(foo_instance.toString() + " is the value for foo_instance.toString()");
-
+ trace(foo_instance.toString()
+ + " is the value for foo_instance.toString()");
- /*
- The foo_instance has the "FooClass" type, while acceptBarInstance
- has the BarClass type. However, since FooClass extends BarClass, it
- is accepted.
- */
+ // The foo_instance has the "FooClass" type, while acceptBarInstance
+ // has the BarClass type. However, since FooClass extends BarClass, it
+ // is accepted.
BarClass.acceptBarInstance(foo_instance);
- /*
- The classes below have some more advanced examples, the "example()"
- method will just run them here.
- */
+ // The classes below have some more advanced examples, the "example()"
+ // method will just run them here.
SimpleEnumTest.example();
ComplexEnumTest.example();
TypedefsAndStructuralTypes.example();
UsingExample.example();
-
}
-
}
-/*
- This is the "child class" of the main LearnHaxe3 Class
- */
-class FooClass extends BarClass implements BarInterface{
+// This is the "child class" of the main LearnHaxe3 Class.
+class FooClass extends BarClass implements BarInterface {
public var public_any:Int; // public variables are accessible anywhere
public var public_read (default, null): Int; // enable only public read
public var public_write (null, default): Int; // or only public write
- public var property (get, set): Int; // use this style to enable getters/setters
+ // Use this style to enable getters/setters:
+ public var property (get, set): Int;
// private variables are not available outside the class.
// see @:allow for ways around this.
var _private:Int; // variables are private if they are not marked public
// a public constructor
- public function new(arg:Int){
+ public function new(arg:Int) {
// call the constructor of the parent object, since we extended BarClass:
super();
this.public_any = 0;
this._private = arg;
-
}
// getter for _private
@@ -555,47 +512,40 @@ class FooClass extends BarClass implements BarInterface{
return val;
}
- // special function that is called whenever an instance is cast to a string.
- public function toString(){
+ // Special function that is called whenever an instance is cast to a string.
+ public function toString() {
return _private + " with toString() method!";
}
// this class needs to have this function defined, since it implements
// the BarInterface interface.
- public function baseFunction(x: Int) : String{
+ public function baseFunction(x: Int) : String {
// convert the int to string automatically
return x + " was passed into baseFunction!";
}
}
-/*
- A simple class to extend
-*/
+// A simple class to extend.
class BarClass {
var base_variable:Int;
- public function new(){
+ public function new() {
base_variable = 4;
}
- public static function acceptBarInstance(b:BarClass){
- }
+ public static function acceptBarInstance(b:BarClass) {}
}
-/*
- A simple interface to implement
-*/
-interface BarInterface{
+// A simple interface to implement
+interface BarInterface {
public function baseFunction(x:Int):String;
}
+
//////////////////////////////////////////////////////////////////
// Enums and Switch Statements
//////////////////////////////////////////////////////////////////
-/*
- Enums in Haxe are very powerful. In their simplest form, enums
- are a type with a limited number of states:
- */
-
+// Enums in Haxe are very powerful. In their simplest form, enums
+// are a type with a limited number of states:
enum SimpleEnum {
Foo;
Bar;
@@ -603,12 +553,12 @@ enum SimpleEnum {
}
// Here's a class that uses it:
-
-class SimpleEnumTest{
- public static function example(){
- var e_explicit:SimpleEnum = SimpleEnum.Foo; // you can specify the "full" name
+class SimpleEnumTest {
+ public static function example() {
+ // You can specify the "full" name,
+ var e_explicit:SimpleEnum = SimpleEnum.Foo;
var e = Foo; // but inference will work as well.
- switch(e){
+ switch (e) {
case Foo: trace("e was Foo");
case Bar: trace("e was Bar");
case Baz: trace("e was Baz"); // comment this line to throw an error.
@@ -621,18 +571,16 @@ class SimpleEnumTest{
You can also specify a default for enum switches as well:
*/
- switch(e){
+ switch (e) {
case Foo: trace("e was Foo again");
default : trace("default works here too");
}
}
}
-/*
- Enums go much further than simple states, we can also enumerate
- *constructors*, but we'll need a more complex enum example
- */
-enum ComplexEnum{
+// Enums go much further than simple states, we can also enumerate
+// *constructors*, but we'll need a more complex enum example.
+enum ComplexEnum {
IntEnum(i:Int);
MultiEnum(i:Int, j:String, k:Float);
SimpleEnumEnum(s:SimpleEnum);
@@ -641,55 +589,47 @@ enum ComplexEnum{
// Note: The enum above can include *other* enums as well, including itself!
// Note: This is what's called *Algebraic data type* in some other languages.
-class ComplexEnumTest{
- public static function example(){
+class ComplexEnumTest {
+ public static function example() {
var e1:ComplexEnum = IntEnum(4); // specifying the enum parameter
- /*
- Now we can switch on the enum, as well as extract any parameters
- it might of had.
- */
- switch(e1){
+ // Now we can switch on the enum, as well as extract any parameters
+ // it might have had.
+ switch (e1) {
case IntEnum(x) : trace('$x was the parameter passed to e1');
default: trace("Shouldn't be printed");
}
// another parameter here that is itself an enum... an enum enum?
var e2 = SimpleEnumEnum(Foo);
- switch(e2){
+ switch (e2){
case SimpleEnumEnum(s): trace('$s was the parameter passed to e2');
default: trace("Shouldn't be printed");
}
// enums all the way down
var e3 = ComplexEnumEnum(ComplexEnumEnum(MultiEnum(4, 'hi', 4.3)));
- switch(e3){
- // You can look for certain nested enums by specifying them explicitly:
+ switch (e3) {
+ // You can look for certain nested enums by specifying them
+ // explicitly:
case ComplexEnumEnum(ComplexEnumEnum(MultiEnum(i,j,k))) : {
trace('$i, $j, and $k were passed into this nested monster');
}
default: trace("Shouldn't be printed");
}
- /*
- Check out "generalized algebraic data types" (GADT) for more details
- on why these are so great.
- */
+ // Check out "generalized algebraic data types" (GADT) for more details
+ // on why these are so great.
}
}
class TypedefsAndStructuralTypes {
- public static function example(){
- /*
- Here we're going to use typedef types, instead of base types.
- At the top we've declared the type "FooString" to mean a "String" type.
- */
+ public static function example() {
+ // Here we're going to use typedef types, instead of base types.
+ // At the top we've declared the type "FooString" to mean a "String" type.
var t1:FooString = "some string";
- /*
- We can use typedefs for "structural types" as well. These types are
- defined by their field structure, not by class inheritance. Here's
- an anonymous object with a String field named "foo":
- */
-
+ // We can use typedefs for "structural types" as well. These types are
+ // defined by their field structure, not by class inheritance. Here's
+ // an anonymous object with a String field named "foo":
var anon_obj = { foo: 'hi' };
/*
@@ -699,8 +639,7 @@ class TypedefsAndStructuralTypes {
that structure, we can use it anywhere that a "FooObject" type is
expected.
*/
-
- var f = function(fo:FooObject){
+ var f = function(fo:FooObject) {
trace('$fo was passed in to this function');
}
f(anon_obj); // call the FooObject signature function with anon_obj.
@@ -712,9 +651,7 @@ class TypedefsAndStructuralTypes {
?optionalString: String,
requiredInt: Int
}
- */
- /*
Typedefs work well with conditional compilation. For instance,
we could have included this at the top of the file:
@@ -728,15 +665,14 @@ class TypedefsAndStructuralTypes {
typedef Surface = java.awt.geom.GeneralPath;
#end
- That would give us a single "Surface" type to work with across
- all of those platforms.
- */
+ That would give us a single "Surface" type to work with across
+ all of those platforms.
+ */
}
}
class UsingExample {
public static function example() {
-
/*
The "using" import keyword is a special type of class import that
alters the behavior of any static methods in the class.
@@ -763,26 +699,24 @@ class UsingExample {
instance, and the compiler still generates code equivalent to a
static method.
*/
- }
-
+ }
}
```
We're still only scratching the surface here of what Haxe can do. For a formal
-overiew of all Haxe features, checkout the [online
-manual](http://haxe.org/manual), the [online api](http://api.haxe.org/), and
-"haxelib", the [haxe library repo] (http://lib.haxe.org/).
+overview of all Haxe features, see the [manual](https://haxe.org/manual) and
+the [API docs](https://api.haxe.org/). For a comprehensive directory of available
+third-party Haxe libraries, see [Haxelib](https://lib.haxe.org/).
For more advanced topics, consider checking out:
-* [Abstract types](http://haxe.org/manual/abstracts)
-* [Macros](http://haxe.org/manual/macros), and [Compiler Macros](http://haxe.org/manual/macros_compiler)
-* [Tips and Tricks](http://haxe.org/manual/tips_and_tricks)
-
-
-Finally, please join us on [the mailing list](https://groups.google.com/forum/#!forum/haxelang), on IRC [#haxe on
-freenode](http://webchat.freenode.net/), or on
-[Google+](https://plus.google.com/communities/103302587329918132234).
+* [Abstract types](https://haxe.org/manual/types-abstract.html)
+* [Macros](https://haxe.org/manual/macro.html)
+* [Compiler Features](https://haxe.org/manual/cr-features.html)
+Finally, please join us on [the Haxe forum](https://community.haxe.org/),
+on IRC [#haxe on
+freenode](http://webchat.freenode.net/), or on the
+[Haxe Gitter chat](https://gitter.im/HaxeFoundation/haxe).
diff --git a/hdl.html.markdown b/hdl.html.markdown
new file mode 100644
index 00000000..cad07817
--- /dev/null
+++ b/hdl.html.markdown
@@ -0,0 +1,231 @@
+---
+language: hdl
+filename: learnhdl.hdl
+contributors:
+ - ["Jack Smith", "https://github.com/JSmithTech2019"]
+---
+
+HDL (hardware description language) is a specialized language used to describe the structure/behavior of real world circuits.
+
+It is used by circuit designers to simulate circuits and logic prior to wiring and fabricating a hardware circuit.
+
+HDL allows circuit designers to simulate circuits at a high level without being connected to specific components.
+
+## Basic building blocks & introduction to the language---
+This programming language is built by simulating hardware chips and wiring. Normal programming functions are replaced with specialized chips that are added to the current wiring desing. Every base chip must be written as it's own file and imported to be used in the current chip, though they may be reused as often as desired.
+
+```verilog
+// Single line comments start with two forward slashes.
+
+/*
+ * Multiline comments can be written using '/*' and 'star/'.
+ * These are often used as comments.
+ *
+ * Note that they cannot be nested and will end at the first 'star/'.
+ */
+
+////////////////////////////////////////////////////
+// 1. Chips & Components
+////////////////////////////////////////////////////
+/*
+ * Unlike other languages HDL creates an individual chip (function) per file
+ * These are defined with a name, input arguments, output arguments
+ * and finally the parts/logic of that specific chip.
+ */
+
+// Note CHIP is capitalized, the chip name does not need to be.
+CHIP Ex {
+ IN a, // Single bit (0 or 1) variable.
+ c[16]; // 16 bit variable bus of single bit values.
+
+ OUT out[16], // 16 bit variable bus output.
+ carry; // Single bit output variable
+
+ PARTS:
+ // The functional components of the chip.
+}
+
+// Lines are ended with semicolons but can be continued using commas. The
+// whitespace is ignored.
+
+
+
+////////////////////////////////////////////////////
+// 2. Inputs, Outputs, & Variables
+////////////////////////////////////////////////////
+/*
+ * Variables and IO are treated as pins/wires and can carry a single bit
+ * of data (0 or 1).
+ */
+
+// Hardware works on low level 0's and 1's, in order to use a constant
+// high or low we use the terms true and false.
+a=false; // This is a 0 value.
+b=true; // This is a 1 value.
+
+// Inputs and outputs can be defined as single bits
+IN a, b; // Creates two single bit inputs
+
+// They can also be defined as busses act as arrays where each
+// index can contain a single bit value.
+OUT c[16]; // Creates a 16 bit output array.
+
+// Bussed values can be accessed using brackets
+a[0] // The first indexed value in the bus a.
+a[0..3] // The first 4 values in the a bus.
+// Values can also be passed in entirety. For example if the function
+// foo() takes an 8 bit input bus and outputs a 2 bit bus:
+foo(in=a[0..7], out=c); // C is now a 2 bit internal bus
+
+
+// Note that internally defined busses cannot be subbussed!
+// To access these elements, output or input them seperately:
+foo(in[0]=false, in[1..7]=a[0..6], out[0]=out1, out[1]=out2);
+// out1 and out2 can then be passed into other circuits within the design.
+
+
+
+////////////////////////////////////////////////////
+// Combining Subsystems
+////////////////////////////////////////////////////
+/*
+ * HDL relies heavily on using smaller "building block" chips to then be
+ * added into larger and more complex designs. Creating the smaller components
+ * and then adding them to the larger circuit allows for fewer lines of code
+ * as well as reduction in total rewriting of code.
+ */
+
+// We are writing the function AND that checks if inputs I and K are both one.
+// To implement this chip we will use the built in NAND gate as well as design
+// a custom NOT gate to invert a single input.
+
+// First we construct the Negation (not) chip. We will use the logically
+// complete gate NAND that is built in for this task.
+CHIP Not {
+ IN i; // Not gates only take one single bit input.
+ OUT o; // The negated value of a.
+
+ PARTS:
+ // Add the input to the built in chip, which then sends output to the NOT
+ // output. This effectively negates the given value.
+ Nand(a=i, b=i, out=o);
+}
+
+// By using the built in NAND gate we were able to construct a NOT gate
+// that works like a real world hardware logic chip. Now we must construct
+// the AND gate using these two gate primitives.
+
+// We define a two input, single output AND gate:
+CHIP And {
+ IN i, k; // Two single bit inputs.
+ OUT o; // One single bit output.
+
+ PARTS:
+ // Insert I and K into the nand gate and store the output in an internal
+ // wire called notOut.
+ Nand(a=i,b=b,out=notOut);
+
+ // Use the not gate we constructed to invert notOut and send to the AND
+ // output.
+ Not(in=notOut,out=o);
+}
+
+// Easy! Now we can use Nand, And, and Not gates in higher level circuits.
+// Many of these low level components are built in to HDL but any chip can
+// be written as a submodule and used in larger designs.
+```
+
+## Test Files
+When working with the nand2tetris hardware simulator chips written using HDL will
+then be processed against test and comparison files to test functionality of the
+simulated chip versus the expected output. To do this a test file will be loaded
+into the hardware simulator and run against the simulated hardware.
+
+```verilog
+// First the chip the test file is written for is loaded
+load <chip name>.hdl
+
+// We set the output file for the simulated chip output as well as the comparison
+// file that it will be tested against. We also specify what the output is
+// expected to look like. In this case there will be two output columns, each
+// will be buffered by a single space on either side and 4 binary values in
+// the center of each column.
+output-file <chip name>.out,
+compare-to <chip name>.cmp,
+output-list in%B1.4.1 out%B1.4.1;
+
+// Then we set initial values for inputs to the chip. For example
+set enable1 1, // set input enable1 to 1
+set enable2 0, // set input enable2 to 0
+
+// The clock is also controlled in the test file using tick and tock. Tick is a
+// positive pulse and tock takes the clock back to 0. Clock cycles can be run
+// multiple times in a row with no other changes to inputs or outputs.
+tick,
+tock,
+
+// Finally we output the first expected value (from the test file) which is then
+// compared with the first line of real output from our HDL circuit. This output
+// can be viewed in the <chip name>.out file.
+output;
+
+// An example of <chip name>, a chip that takes in a 4 bit value as input and
+// adds 1 to that value could have the following as test code:
+
+// Set the input value to 0000, clock pulse, compare output from cmp file to actual out.
+set in %B0000,
+tick,
+tock,
+output;
+
+// Set the input value to 0110, clock pulse, compare output from cmp file to actual out.
+set in %B0110,
+tick,
+tock,
+output;
+
+// The expected output for case 1 should be 0001 and case 2 expects 0111, lets
+// learn a little more about comparison files before finalizing our lesson.
+```
+
+## Comparison Files
+Now lets take a look at comparison files, the files that hold what the test file
+compares with the actual output of an HDL chip in the hardware simulator!
+
+```verilog
+// Like the <chip name> example above, the structure of the comparison file
+// would look something like this
+| in | out |
+| 0000 | 0001 |
+| 0110 | 0111 |
+
+// Notice how the input values specified in the test case are equivalent to the
+// `in` column of the comparison file, and that the space buffer is 1 on either side.
+
+// If the output from the HDL code we not this, such as the output below, then the
+// test will fail and the user will know that the simulated chip is not correctly designed.
+| in | out |
+| 0000 | 0001 |
+| 0110 | 0110 | // Error! The chip did not add 1 here, something went wrong.
+
+
+```
+
+This is incredibly useful as it allows designers to simulate chip logic prior to
+fabricating real life hardware and identify problems in their designs. Be warned that
+errors in the test or comparison files can lead to both false positives and also
+the more damaging false negatives so ensure that the logic is sound behind the test
+creation.
+
+
+Good luck and happy coding!
+
+## Resources
+
+* [From Nand To Tetris](https://www.nand2tetris.org)
+
+## Further Reading
+
+* [Hardware Description Language](https://en.wikipedia.org/wiki/Hardware_description_language)
+
+* [HDL Programming Fundamentals](https://www.electronicdesign.com/products/hdl-programming-fundamentals) \ No newline at end of file
diff --git a/hq9+.html.markdown b/hq9+.html.markdown
new file mode 100644
index 00000000..3f0c5fba
--- /dev/null
+++ b/hq9+.html.markdown
@@ -0,0 +1,39 @@
+---
+language: HQ9+
+filename: hq9+.html
+contributors:
+ - ["Alexey Nazaroff", "https://github.com/rogaven"]
+---
+
+HQ9+ is a joke programming language created by Cliff Biffle. It has only four commands and it isn't Turing-complete.
+
+```
+There is only 4 commands, represented by next characters
+H: print "Hello, world!"
+Q: print the program's source code (a Quine)
+9: print the lyrics to "99 Bottles of Beer"
++: add one to the accumulator (the value of the accumulator cannot be accessed)
+Any other character is ignored.
+
+Ok. Let's write some program:
+ HQ9
+
+Result:
+ Hello world!
+ HQ9
+
+HQ9+ is very simple, but allows you to do some things that are very difficult
+in other languages. For example, here is a program that creates three copies of
+itself on the screen:
+ QQQ
+
+This produces:
+ QQQ
+ QQQ
+ QQQ
+```
+
+And that's all. There are a lot of interpreters for HQ9+. Below you can find one of them
+
++ [One of online interpreters](https://almnet.de/esolang/hq9plus.php)
++ [HQ9+ official website](http://cliffle.com/esoterica/hq9plus.html)
diff --git a/hre.csv b/hre.csv
new file mode 100644
index 00000000..eab43cc4
--- /dev/null
+++ b/hre.csv
@@ -0,0 +1 @@
+Ix,Dynasty,Name,Birth,Death,Coronation 1,Coronation 2,Ceased to be Emperor N/A,Carolingian,Charles I,2 April 742,28 January 814,25 December 800,N/A,28 January 814 N/A,Carolingian,Louis I,778,20 June 840,11 September 813,5 October 816,20 June 840 N/A,Carolingian,Lothair I,795,29 September 855,5 April 823,N/A,29 September 855 N/A,Carolingian,Louis II,825,12 August 875,15 June 844,18 May 872,12 August 875 N/A,Carolingian,Charles II,13 June 823,6 October 877,29 December 875,N/A,6 October 877 N/A,Carolingian,Charles III,13 June 839,13 January 888,12 February 881,N/A,11 November 887 N/A,Widonid,Guy III,835,12 December 894,21 February 891,N/A,12 December 894 N/A,Widonid,Lambert I,880,15 October 898,30 April 892,N/A,15 October 898 N/A,Carolingian,Arnulph,850,8 December 899,22 February 896,N/A,8 December 899 N/A,Bosonid,Louis III,880,5 June 928,22 February 901,N/A,21 July 905 N/A,Unruoching,Berengar I,845,7 April 924,December 915,N/A,7 April 924 1,Ottonian,Otto I,23 November 912,7 May 973,2 February 962,N/A,7 May 973 2,Ottonian,Otto II,955,7 December 983,25 December 967,N/A,7 December 983 3,Ottonian,Otto III,980,23 January 1002,21 May 996,N/A,23 January 1002 4,Ottonian,Henry II,6 May 973,13 July 1024,14 February 1014,N/A,13 July 1024 5,Salian,Conrad II,990,4 June 1039,26 March 1027,N/A,4 June 1039 6,Salian,Henry III,29 October 1017,5 October 1056,25 December 1046,N/A,5 October 1056 7,Salian,Henry IV,11 November 1050,7 August 1106,31 March 1084,N/A,December 1105 8,Salian,Henry V,8 November 1086,23 May 1125,13 April 1111,N/A,23 May 1125 9,Supplinburg,Lothair III,9 June 1075,4 December 1137,4 June 1133,N/A,4 December 1137 10,Staufen,Frederick I,1122,10 June 1190,18 June 1155,N/A,10 June 1190 11,Staufen,Henry VI,November 1165,28 September 1197,14 April 1191,N/A,28 September 1197 12,Welf,Otto IV,1175,19 May 1218,4 October 1209,N/A,1215 13,Staufen,Frederick II,26 December 1194,13 December 1250,22 November 1220,N/A,13 December 1250 14,Luxembourg,Henry VII,1275,24 August 1313,29 June 1312,N/A,24 August 1313 15,Wittelsbach,Louis IV,1 April 1282,11 October 1347,17 January 1328,N/A,11 October 1347 16,Luxembourg,Charles IV,14 May 1316,29 November 1378,5 April 1355,N/A,29 November 1378 17,Luxembourg,Sigismund,14 February 1368,9 December 1437,31 May 1433,N/A,9 December 1437 18,Habsburg,Frederick III,21 September 1415,19 August 1493,19 March 1452,N/A,19 August 1493 19,Habsburg,Maximilian I,22 March 1459,12 January 1519,N/A,N/A,12 January 1519 20,Habsburg,Charles V,24 February 1500,21 September 1558,February 1530,N/A,16 January 1556 21,Habsburg,Ferdinand I,10 March 1503,25 July 1564,N/A,N/A,25 July 1564 22,Habsburg,Maximilian II,31 July 1527,12 October 1576,N/A,N/A,12 October 1576 23,Habsburg,Rudolph II,18 July 1552,20 January 1612,30 June 1575,N/A,20 January 1612 24,Habsburg,Matthias,24 February 1557,20 March 1619,23 January 1612,N/A,20 March 1619 25,Habsburg,Ferdinand II,9 July 1578,15 February 1637,10 March 1619,N/A,15 February 1637 26,Habsburg,Ferdinand III,13 July 1608,2 April 1657,18 November 1637,N/A,2 April 1657 27,Habsburg,Leopold I,9 June 1640,5 May 1705,6 March 1657,N/A,5 May 1705 28,Habsburg,Joseph I,26 July 1678,17 April 1711,1 May 1705,N/A,17 April 1711 29,Habsburg,Charles VI,1 October 1685,20 October 1740,22 December 1711,N/A,20 October 1740 30,Wittelsbach,Charles VII,6 August 1697,20 January 1745,12 February 1742,N/A,20 January 1745 31,Lorraine,Francis I,8 December 1708,18 August 1765,N/A,N/A,18 August 1765 32,Habsburg-Lorraine,Joseph II,13 March 1741,20 February 1790,19 August 1765,N/A,20 February 1790 33,Habsburg-Lorraine,Leopold II,5 May 1747,1 March 1792,N/A,N/A,1 March 1792 34,Habsburg-Lorraine,Francis II,12 February 1768,2 March 1835,4 March 1792,N/A,6 August 1806 \ No newline at end of file
diff --git a/html.html.markdown b/html.html.markdown
index b64cec33..b8212776 100644
--- a/html.html.markdown
+++ b/html.html.markdown
@@ -1,31 +1,48 @@
---
language: html
-filename: learnhtml.html
+filename: learnhtml.txt
contributors:
- ["Christophe THOMAS", "https://github.com/WinChris"]
translators:
- ["Robert Steed", "https://github.com/robochat"]
+ - ["Dimitri Kokkonis", "https://github.com/kokkonisd"]
---
-HTML stands for HyperText Markup Language.
+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.
-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.
-Like other computer languages, HTML has many versions. Here we will talk about HTML5.
+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. Like other computer languages, HTML
+has many versions. Here we will talk about HTML5.
-**NOTE :** You can test the different tags and elements as you progress through the tutorial on a site like [codepen](http://codepen.io/pen/) in order to see their effects, understand how they work and familiarise yourself with the language.
-This article is concerned principally with HTML syntax and some useful tips.
+**NOTE :** You can test the different tags and elements as you progress through
+the tutorial on a site like [codepen](http://codepen.io/pen/) in order to see
+their effects, understand how they work and familiarise yourself with the
+language. This article is concerned principally with HTML syntax and some
+useful tips.
```html
<!-- Comments are enclosed like this line! -->
+<!--
+ Comments
+ can
+ span
+ multiple
+ lines!
+-->
+
<!-- #################### The Tags #################### -->
-
+
<!-- Here is an example HTML file that we are going to analyse. -->
+
<!doctype html>
<html>
<head>
@@ -33,7 +50,9 @@ This article is concerned principally with HTML syntax and some useful tips.
</head>
<body>
<h1>Hello, world!</h1>
- <a href = "http://codepen.io/anon/pen/xwjLbZ">Come look at what this shows</a>
+ <a href="http://codepen.io/anon/pen/xwjLbZ">
+ Come look at what this shows
+ </a>
<p>This is a paragraph.</p>
<p>This is another paragraph.</p>
<ul>
@@ -44,7 +63,9 @@ This article is concerned principally with HTML syntax and some useful tips.
</body>
</html>
-<!-- An HTML file always starts by indicating to the browser that the page is HTML. -->
+<!--
+ An HTML file always starts by indicating to the browser that the page is HTML.
+-->
<!doctype html>
<!-- After this, it starts by opening an <html> tag. -->
@@ -58,10 +79,17 @@ This article is concerned principally with HTML syntax and some useful tips.
<!-- Inside (between the opening and closing tags <html></html>), we find: -->
<!-- A header defined by <head> (it must be closed with </head>). -->
-<!-- The header contains some description and additional information which are not displayed; this is metadata. -->
+<!--
+ The header contains some description and additional information which are not
+ displayed; this is metadata.
+-->
<head>
- <title>My Site</title><!-- The tag <title> indicates to the browser the title to show in browser window's title bar and tab name. -->
+ <!--
+ The tag <title> indicates to the browser the title to show in browser
+ window's title bar and tab name.
+ -->
+ <title>My Site</title>
</head>
<!-- After the <head> section, we find the tag - <body> -->
@@ -69,13 +97,28 @@ This article is concerned principally with HTML syntax and some useful tips.
<!-- We must fill the body with the content to be displayed. -->
<body>
- <h1>Hello, world!</h1> <!-- The h1 tag creates a title. -->
- <!-- There are also subtitles to <h1> from the most important (h2) to the most precise (h6). -->
- <a href = "http://codepen.io/anon/pen/xwjLbZ">Come look at what this shows</a> <!-- a hyperlink to the url given by the attribute href="" -->
- <p>This is a paragraph.</p> <!-- The tag <p> lets us include text in the html page. -->
+ <!-- The h1 tag creates a title. -->
+ <h1>Hello, world!</h1>
+ <!--
+ There are also subtitles to <h1> from the most important (h2) to the most
+ precise (h6).
+ -->
+
+ <!-- a hyperlink to the url given by the attribute href="" -->
+ <a href="http://codepen.io/anon/pen/xwjLbZ">
+ Come look at what this shows
+ </a>
+
+ <!-- The tag <p> lets us include text in the html page. -->
+ <p>This is a paragraph.</p>
<p>This is another paragraph.</p>
- <ul> <!-- The tag <ul> creates a bullet list. -->
- <!-- To have a numbered list instead we would use <ol> giving 1. for the first element, 2. for the second, etc. -->
+
+ <!-- The tag <ul> creates a bullet list. -->
+ <!--
+ To have a numbered list instead we would use <ol> giving 1. for the first
+ element, 2. for the second, etc.
+ -->
+ <ul>
<li>This is an item in a non-enumerated list (bullet list)</li>
<li>This is another item</li>
<li>And this is the last item on the list</li>
@@ -86,21 +129,33 @@ This article is concerned principally with HTML syntax and some useful tips.
<!-- But it is possible to add many additional types of HTML tags. -->
-<!-- To insert an image. -->
-<img src="http://i.imgur.com/XWG0O.gif"/> <!-- The source of the image is indicated using the attribute src="" -->
-<!-- The source can be an URL or even path to a file on your computer. -->
+<!-- The <img /> tag is used to insert an image. -->
+<!--
+ The source of the image is indicated using the attribute src=""
+ The source can be an URL or even path to a file on your computer.
+-->
+<img src="http://i.imgur.com/XWG0O.gif"/>
<!-- It is also possible to create a table. -->
-<table> <!-- We open a <table> element. -->
- <tr> <!-- <tr> allows us to create a row. -->
- <th>First Header</th> <!-- <th> allows us to give a title to a table column. -->
+<!-- We open a <table> element. -->
+<table>
+
+ <!-- <tr> allows us to create a row. -->
+ <tr>
+
+ <!-- <th> allows us to give a title to a table column. -->
+ <th>First Header</th>
<th>Second Header</th>
</tr>
+
<tr>
- <td>first row, first column</td> <!-- <td> allows us to create a table cell. -->
+
+ <!-- <td> allows us to create a table cell. -->
+ <td>first row, first column</td>
<td>first row, second column</td>
</tr>
+
<tr>
<td>second row, first column</td>
<td>second row, second column</td>
@@ -111,9 +166,10 @@ This article is concerned principally with HTML syntax and some useful tips.
## Usage
-HTML is written in files ending with `.html`.
-
-## To Learn More
+HTML is written in files ending with `.html` or `.htm`. The mime type is
+`text/html`.
+**HTML is NOT a programming language**
+## To Learn More
* [wikipedia](https://en.wikipedia.org/wiki/HTML)
* [HTML tutorial](https://developer.mozilla.org/en-US/docs/Web/HTML)
diff --git a/hu-hu/pythonlegacy-hu.html.markdown b/hu-hu/pythonlegacy-hu.html.markdown
new file mode 100644
index 00000000..b5922766
--- /dev/null
+++ b/hu-hu/pythonlegacy-hu.html.markdown
@@ -0,0 +1,816 @@
+---
+language: Python 2 (legacy)
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+ - ["Amin Bandali", "https://aminb.org"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+ - ["evuez", "http://github.com/evuez"]
+ - ["asyne", "https://github.com/justblah"]
+ - ["habi", "http://github.com/habi"]
+translators:
+ - ["Tamás Diószegi", "https://github.com/ditam"]
+filename: learnpythonlegacy-hu.py
+lang: hu-hu
+---
+
+A Python nyelvet Guido Van Rossum alkotta meg a 90-es évek elején. Manapság az
+egyik legnépszerűbb programozási nyelv. Én a tiszta szintaxisa miatt szerettem
+bele. Tulajdonképpen futtatható pszeudokód.
+
+Szívesen fogadok visszajelzéseket! Elérsz itt: [@louiedinh](http://twitter.com/louiedinh)
+vagy pedig a louiedinh [kukac] [google email szolgáltatása] címen.
+
+Figyelem: ez a leírás a Python 2.7 verziójára vonatkozok, illetve
+általánosságban a 2.x verziókra. A Python 2.7 azonban már csak 2020-ig lesz
+támogatva, ezért kezdőknek ajánlott, hogy a Python 3-mal kezdjék az
+ismerkedést. A Python 3.x verzióihoz a [Python 3 bemutató](http://learnxinyminutes.com/docs/python/)
+ajánlott.
+
+Lehetséges olyan Python kódot írni, ami egyszerre kompatibilis a 2.7 és a 3.x
+verziókkal is, a Python [`__future__` imports](https://docs.python.org/2/library/__future__.html) használatával.
+A `__future__` import használata esetén Python 3-ban írhatod a kódot, ami
+Python 2 alatt is futni fog, így ismét a fenti Python 3 bemutató ajánlott.
+
+```python
+
+# Az egysoros kommentek kettőskereszttel kezdődnek
+
+""" Többsoros stringeket három darab " közé
+ fogva lehet írni, ezeket gyakran használják
+ több soros kommentként.
+"""
+
+####################################################
+# 1. Egyszerű adattípusok és operátorok
+####################################################
+
+# Használhatsz számokat
+3 # => 3
+
+# Az alapműveletek meglepetésektől mentesek
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7
+
+# Az osztás kicsit trükkös. Egész osztást végez, és a hányados alsó egész része
+# lesz az eredmény
+5 / 2 # => 2
+
+# Az osztás kijavításához a (lebegőpontos) float típust kell használnunk
+2.0 # Ez egy float
+11.0 / 4.0 # => 2.75 áh... máris jobb
+
+# Az egész osztás a negatív számok esetén is az alsó egész részt eredményezi
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # floatok esetén is
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
+
+# Ha importáljuk a division modult (ld. 6. Modulok rész),
+# akkor a '/' jellel pontos osztást tudunk végezni.
+from __future__ import division
+
+11 / 4 # => 2.75 ...sima osztás
+11 // 4 # => 2 ...egész osztás
+
+# Modulo művelet
+7 % 3 # => 1
+
+# Hatványozás (x az y. hatványra)
+2 ** 4 # => 16
+
+# A precedencia zárójelekkel befolyásolható
+(1 + 3) * 2 # => 8
+
+# Logikai operátorok
+# Megjegyzés: az "and" és "or" csak kisbetűkkel helyes
+True and False # => False
+False or True # => True
+
+# A logikai operátorok egészeken is használhatóak
+0 and 2 # => 0
+-5 or 0 # => -5
+0 == False # => True
+2 == True # => False
+1 == True # => True
+
+# Negálni a not kulcsszóval lehet
+not True # => False
+not False # => True
+
+# Egyenlőségvizsgálat ==
+1 == 1 # => True
+2 == 1 # => False
+
+# Egyenlőtlenség !=
+1 != 1 # => False
+2 != 1 # => True
+
+# További összehasonlítások
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# Az összehasonlítások láncolhatóak!
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# Stringeket " vagy ' jelek közt lehet megadni
+"Ez egy string."
+'Ez egy másik string.'
+
+# A stringek összeadhatóak!
+"Hello " + "world!" # => "Hello world!"
+# '+' jel nélkül is összeadhatóak
+"Hello " "world!" # => "Hello world!"
+
+# ... illetve szorozhatóak
+"Hello" * 3 # => "HelloHelloHello"
+
+# Kezelhető karakterek indexelhető listájaként
+"This is a string"[0] # => 'T'
+
+# A string hosszát a len függvény adja meg
+len("This is a string") # => 16
+
+# String formázáshoz a % jel használható
+# A Python 3.1-gyel a % már deprecated jelölésű, és később eltávolításra fog
+# kerülni, de azért jó tudni, hogyan működik.
+x = 'alma'
+y = 'citrom'
+z = "A kosárban levő elemek: %s és %s" % (x, y)
+
+# A string formázás újabb módja a format metódus használatával történik.
+# Jelenleg ez a javasolt megoldás.
+"{} egy {} szöveg".format("Ez", "helytartó")
+"A {0} pedig {1}".format("string", "formázható")
+# Ha nem akarsz számolgatni, nevesíthetőek a pozíciók.
+"{name} kedvence a {food}".format(name="Bob", food="lasagna")
+
+# None egy objektum
+None # => None
+
+# A None-nal való összehasonlításhoz ne használd a "==" jelet,
+# használd az "is" kulcsszót helyette
+"etc" is None # => False
+None is None # => True
+
+# Az 'is' operátor objektum egyezést vizsgál.
+# Primitív típusok esetén ez nem túl hasznos,
+# objektumok esetén azonban annál inkább.
+
+# Bármilyen objektum használható logikai kontextusban.
+# A következő értékek hamis-ra értékelődnek ki (ún. "falsey" értékek):
+# - None
+# - bármelyik szám típus 0 értéke (pl. 0, 0L, 0.0, 0j)
+# - üres sorozatok (pl. '', (), [])
+# - üres konténerek (pl., {}, set())
+# - egyes felhasználó által definiált osztályok példányai bizonyos szabályok szerint,
+# ld: https://docs.python.org/2/reference/datamodel.html#object.__nonzero__
+#
+# Minden egyéb érték "truthy" (a bool() függvénynek átadva igazra értékelődnek ki)
+bool(0) # => False
+bool("") # => False
+
+
+####################################################
+# 2. Változók és kollekciók
+####################################################
+
+# Létezik egy print utasítás
+print "I'm Python. Nice to meet you!" # => I'm Python. Nice to meet you!
+
+# Így lehet egyszerűen bemenetet kérni a konzolról:
+input_string_var = raw_input(
+ "Enter some data: ") # Visszatér a megadott stringgel
+input_var = input("Enter some data: ") # Kiértékeli a bemenetet python kódként
+# Vigyázat: a fentiek miatt az input() metódust körültekintően kell használni
+# Megjegyzés: Python 3-ban az input() már deprecated, és a raw_input() lett input()-ra átnevezve
+
+# A változókat nem szükséges a használat előtt deklarálni
+some_var = 5 # Konvenció szerint a névben kisbetu_es_alulvonas
+some_var # => 5
+
+# Érték nélküli változóra hivatkozás hibát dob.
+# Lásd a Control Flow szekciót a kivételkezelésről.
+some_other_var # name error hibát dob
+
+# az if használható kifejezésként
+# a C nyelv '?:' ternáris operátorával egyenértékűen
+"yahoo!" if 3 > 2 else 2 # => "yahoo!"
+
+# A listákban sorozatok tárolhatóak
+li = []
+# Már inicializáláskor megadhatóak elemek
+other_li = [4, 5, 6]
+
+# A lista végére az append metódus rak új elemet
+li.append(1) # li jelenleg [1]
+li.append(2) # li jelenleg [1, 2]
+li.append(4) # li jelenleg [1, 2, 4]
+li.append(3) # li jelenleg [1, 2, 4, 3]
+# A végéről a pop metódus távolít el elemet
+li.pop() # => 3 és li jelenleg [1, 2, 4]
+# Rakjuk vissza
+li.append(3) # li jelenleg [1, 2, 4, 3], újra.
+
+# A lista elemeket tömb indexeléssel lehet hivatkozni
+li[0] # => 1
+# A már inicializált értékekhez a = jellel lehet új értéket rendelni
+li[0] = 42
+li[0] # => 42
+li[0] = 1 # csak visszaállítjuk az eredeti értékére
+# Így is lehet az utolsó elemre hivatkozni
+li[-1] # => 3
+
+# A túlindexelés eredménye IndexError
+li[4] # IndexError hibát dob
+
+# A lista részeit a slice szintaxissal lehet kimetszeni
+# (Matekosoknak ez egy zárt/nyitott intervallum.)
+li[1:3] # => [2, 4]
+# A lista eleje kihagyható így
+li[2:] # => [4, 3]
+# Kihagyható a vége
+li[:3] # => [1, 2, 4]
+# Minden második elem kiválasztása
+li[::2] # =>[1, 4]
+# A lista egy másolata, fordított sorrendben
+li[::-1] # => [3, 4, 2, 1]
+# A fentiek kombinációival bonyolultabb slice parancsok is képezhetőek
+# li[start:end:step]
+
+# Listaelemek a "del" paranccsal törölhetőek
+del li[2] # li jelenleg [1, 2, 3]
+
+# A listák összeadhatóak
+li + other_li # => [1, 2, 3, 4, 5, 6]
+# Megjegyzés: az eredeti li és other_li értékei változatlanok
+
+# Összefőzhetőek (konkatenálhatóak) az "extend()" paranccsal
+li.extend(other_li) # li jelenleg [1, 2, 3, 4, 5, 6]
+
+# Egy elem első előfordulásának eltávolítása
+li.remove(2) # li jelenleg [1, 3, 4, 5, 6]
+li.remove(2) # ValueError hibát dob, mivel a 2 nem szerepel már a listában
+
+# Elemek beszúrhatóak tetszőleges helyre
+li.insert(1, 2) # li jelenleg [1, 2, 3, 4, 5, 6], ismét
+
+# Egy elem első előfordulási helye
+li.index(2) # => 1
+li.index(7) # ValueError hibát dob, mivel a 7 nem szerepel a listában
+
+# Egy listában egy elem előfordulása az "in" szóval ellenőrizhető
+1 in li # => True
+
+# A lista hossza a "len()" függvénnyel
+len(li) # => 6
+
+# Az N-esek ("tuple") hasonlítanak a listákhoz, de nem módosíthatóak
+tup = (1, 2, 3)
+tup[0] # => 1
+tup[0] = 3 # TypeError hibát dob
+
+# Az összes lista-műveletet ezeken is használható
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# Az N-esek (és listák) kicsomagolhatóak külön változókba
+a, b, c = (1, 2, 3) # az a így 1, a b 2 és a c pedig 3
+d, e, f = 4, 5, 6 # a zárójel elhagyható
+# Ha elhagyod a zárójeleket, alapértelmezés szerint tuple képződik
+g = 4, 5, 6 # => (4, 5, 6)
+# Nézd, milyen egyszerű két értéket megcserélni
+e, d = d, e # d most már 5 és az e 4
+
+# A Dictionary típusokban hozzárendelések (kulcs-érték párok) tárolhatók
+empty_dict = {}
+# Ez pedig rögtön értékekkel van inicializálva
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Egy dictionary értékei [] jelek közt indexelhetőek
+filled_dict["one"] # => 1
+
+# A "keys()" metódus visszatér a kulcsok listájával
+filled_dict.keys() # => ["three", "two", "one"]
+# Megjegyzés: egy dictionary párjainak sorrendje nem garantált
+# Lehet, hogy már a fenti példán is más sorrendben kaptad meg az elemeket.
+
+# Az értékek listája a "values()" metódussal kérhető le
+filled_dict.values() # => [3, 2, 1]
+# ld. a fenti megjegyzést az elemek sorrendjéről.
+
+# Az összes kulcs-érték pár megkapható N-esek listájaként az "items()" metódussal
+filled_dict.items() # => [("one", 1), ("two", 2), ("three", 3)]
+
+# Az "in" kulcssszóval ellenőrizhető, hogy egy kulcs szerepel-e a dictionary-ben
+"one" in filled_dict # => True
+1 in filled_dict # => False
+
+# Nem létező kulcs hivatkozása KeyError hibát dob
+filled_dict["four"] # KeyError
+
+# A "get()" metódus használatával elkerülhető a KeyError
+filled_dict.get("one") # => 1
+filled_dict.get("four") # => None
+# A metódusnak megadható egy alapértelmezett visszatérési érték is, hiányzó értékek esetén
+filled_dict.get("one", 4) # => 1
+filled_dict.get("four", 4) # => 4
+# Megjegyzés: ettől még filled_dict.get("four") => None
+# (vagyis a get nem állítja be az alapértelmezett értéket a dictionary-ben)
+
+# A kulcsokhoz értékek a listákhoz hasonló szintaxissal rendelhetőek:
+filled_dict["four"] = 4 # ez után filled_dict["four"] => 4
+
+# A "setdefault()" metódus csak akkor állít be egy értéket, ha az adott kulcshoz még nem volt más megadva
+filled_dict.setdefault("five", 5) # filled_dict["five"] beállítva 5-re
+filled_dict.setdefault("five", 6) # filled_dict["five"] még mindig 5
+
+# Egy halmaz ("set") olyan, mint egy lista, de egy elemet csak egyszer tárolhat
+empty_set = set()
+# Inicializáljuk ezt a halmazt néhány elemmel
+some_set = set([1, 2, 2, 3, 4]) # some_set jelenleg set([1, 2, 3, 4])
+
+# A sorrend itt sem garantált, még ha néha rendezettnek is tűnhet
+another_set = set([4, 3, 2, 2, 1]) # another_set jelenleg set([1, 2, 3, 4])
+
+# Python 2.7 óta már {} jelek közt is lehet halmazt definiálni
+filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
+
+# Új halmaz-elemek hozzáadása
+filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
+
+# Halmaz metszés a & operátorral
+other_set = {3, 4, 5, 6}
+filled_set & other_set # => {3, 4, 5}
+
+# Halmaz unió | operátorral
+filled_set | other_set # => {1, 2, 3, 4, 5, 6}
+
+# Halmaz különbség -
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+
+# Szimmetrikus differencia ^
+{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5}
+
+# Vizsgáljuk, hogy a bal oldali halmaz magában foglalja-e a jobb oldalit
+{1, 2} >= {1, 2, 3} # => False
+
+# Vizsgáljuk, hogy a bal oldali halmaz részhalmaza-e a jobb oldalinak
+{1, 2} <= {1, 2, 3} # => True
+
+# Halmazbeli elemek jelenléte az in kulcssszóval vizsgálható
+2 in filled_set # => True
+10 in filled_set # => False
+
+
+####################################################
+# 3. Control Flow
+####################################################
+
+# Legyen egy változónk
+some_var = 5
+
+# Ez egy if elágazás. A behúzás mértéke (az indentáció) jelentéssel bír a nyelvben!
+# Ez a kód ezt fogja kiírni: "some_var kisebb 10-nél"
+if some_var > 10:
+ print "some_var nagyobb, mint 10."
+elif some_var < 10: # Az elif kifejezés nem kötelező az if szerkezetben.
+ print "some_var kisebb 10-nél"
+else: # Ez sem kötelező.
+ print "some_var kereken 10."
+
+"""
+For ciklusokkal végigiterálhatunk listákon
+a kimenet:
+ A(z) kutya emlős
+ A(z) macska emlős
+ A(z) egér emlős
+"""
+for animal in ["kutya", "macska", "egér"]:
+ # A {0} kifejezéssel formázzuk a stringet, ld. korábban.
+ print "A(z) {0} emlős".format(animal)
+
+"""
+"range(number)" visszatér számok listájával 0-től number-ig
+a kimenet:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+"range(lower, upper)" visszatér a lower és upper közti számok listájával
+a kimenet:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print i
+
+"""
+A while ciklus a feltétel hamissá válásáig fut.
+a kimenet:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # Rövidítés az x = x + 1 kifejezésre
+
+# A kivételek try/except blokkokkal kezelhetőek
+
+# Python 2.6-tól felfele:
+try:
+ # A "raise" szóval lehet hibát dobni
+ raise IndexError("Ez egy index error")
+except IndexError as e:
+ pass # A pass egy üres helytartó művelet. Itt hívnánk a hibakezelő kódunkat.
+except (TypeError, NameError):
+ pass # Ha szükséges, egyszerre több hiba típus is kezelhető
+else: # Az except blokk után opcionálisan megadható
+ print "Minden rendben!" # Csak akkor fut le, ha fentebb nem voltak hibák
+finally: # Mindenképpen lefut
+ print "Itt felszabadíthatjuk az erőforrásokat például"
+
+# Az erőforrások felszabadításához try/finally helyett a with használható
+with open("myfile.txt") as f:
+ for line in f:
+ print line
+
+
+####################################################
+# 4. Függvények
+####################################################
+
+# A "def" szóval hozhatunk létre új függvényt
+def add(x, y):
+ print "x is {0} and y is {1}".format(x, y)
+ return x + y # A return szóval tudunk értékeket visszaadni
+
+
+# Így hívunk függvényt paraméterekkel
+add(5, 6) # => a konzol kimenet "x is 5 and y is 6", a visszatérési érték 11
+
+# Nevesített paraméterekkel (ún. "keyword arguments") is hívhatunk egy függvényt
+add(y=6, x=5) # Ez esetben a sorrendjük nem számít
+
+
+# Változó számú paramétert fogadó függvény így definiálható.
+# A * használatával a paramétereket egy N-esként kapjuk meg.
+def varargs(*args):
+ return args
+
+
+varargs(1, 2, 3) # => (1, 2, 3)
+
+
+# Változó számú nevesített paramétert fogadó függvény is megadható,
+# a ** használatával a paramétereket egy dictionary-ként kapjuk meg
+def keyword_args(**kwargs):
+ return kwargs
+
+
+# Nézzük meg, mi történik
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
+
+
+# A két módszer egyszerre is használható
+def all_the_args(*args, **kwargs):
+ print args
+ print kwargs
+
+
+"""
+all_the_args(1, 2, a=3, b=4) kimenete:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Függvények hívásakor a fenti args és kwargs módszerek inverze használható
+# A * karakter kifejt egy listát külön paraméterekbe, a ** egy dictionary-t nevesített paraméterekbe.
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # egyenértékű: foo(1, 2, 3, 4)
+all_the_args(**kwargs) # egyenértékű: foo(a=3, b=4)
+all_the_args(*args, **kwargs) # egyenértékű: foo(1, 2, 3, 4, a=3, b=4)
+
+
+# A fenti arg és kwarg paraméterek továbbadhatóak egyéb függvényeknek,
+# a * illetve ** operátorokkal kifejtve
+def pass_all_the_args(*args, **kwargs):
+ all_the_args(*args, **kwargs)
+ print varargs(*args)
+ print keyword_args(**kwargs)
+
+
+# Függvény scope
+x = 5
+
+
+def set_x(num):
+ # A lokális x változó nem ugyanaz, mint a globális x
+ x = num # => 43
+ print x # => 43
+
+
+def set_global_x(num):
+ global x
+ print x # => 5
+ x = num # a globális x-et 6-ra állítjuk
+ print x # => 6
+
+
+set_x(43)
+set_global_x(6)
+
+
+# A pythonban a függvény elsőrendű (ún. "first class") típus
+def create_adder(x):
+ def adder(y):
+ return x + y
+
+ return adder
+
+
+add_10 = create_adder(10)
+add_10(3) # => 13
+
+# Névtelen függvények is definiálhatóak
+(lambda x: x > 2)(3) # => True
+(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
+
+# Léteznek beépített magasabb rendű függvények
+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]
+
+# A listaképző kifejezések ("list comprehensions") jól használhatóak a map és filter függvényekkel
+[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]
+
+# halmaz és dictionary képzők is léteznek
+{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. Osztályok
+####################################################
+
+# Az object osztály egy alosztályát képezzük
+class Human(object):
+ # Osztály szintű mező: az osztály összes példányában azonos
+ species = "H. sapiens"
+
+ # Ez a függvény meghívódik az osztály példányosításakor.
+ # Megjegyzés: a dupla aláhúzás a név előtt és után egy konvenció a python
+ # előre definiált, a nyelv által belsőleg használt, de a felhasználó által
+ # is látható objektumok és mezők neveire.
+ # Ne vezessünk be új, ilyen elnevezési sémát használó neveket!
+ def __init__(self, name):
+ # A paramétert értékül adjuk a példány name attribútumának
+ self.name = name
+
+ # Inicializálunk egy mezőt
+ self.age = 0
+
+ # Példány metódus. Minden metódus első paramétere a "self", a példány maga
+ def say(self, msg):
+ return "{0}: {1}".format(self.name, msg)
+
+ # Egy osztálymetódus az osztály összes példány közt meg van osztva.
+ # Hívásukkor az első paraméter mindig a hívó osztály.
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Egy statikus metódus osztály és példányreferencia nélkül hívódik
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+ # Egy property jelölésű függvény olyan, mint egy getter.
+ # Használatával az age mező egy csak-olvasható attribútummá válik.
+ @property
+ def age(self):
+ return self._age
+
+ # Így lehet settert megadni egy mezőhöz
+ @age.setter
+ def age(self, age):
+ self._age = age
+
+ # Így lehet egy mező törlését engedélyezni
+ @age.deleter
+ def age(self):
+ del self._age
+
+
+# Példányosítsuk az osztályt
+i = Human(name="Ian")
+print i.say("hi") # kimenet: "Ian: hi"
+
+j = Human("Joel")
+print j.say("hello") # kimenet: "Joel: hello"
+
+# Hívjuk az osztály metódusunkat
+i.get_species() # => "H. sapiens"
+
+# Változtassuk meg az osztály szintű attribútumot
+Human.species = "H. neanderthalensis"
+i.get_species() # => "H. neanderthalensis"
+j.get_species() # => "H. neanderthalensis"
+
+# Hívjuk meg a statikus metódust
+Human.grunt() # => "*grunt*"
+
+# Adjunk új értéket a mezőnek
+i.age = 42
+
+# Kérjük le a mező értékét
+i.age # => 42
+
+# Töröljük a mezőt
+del i.age
+i.age # => AttributeError hibát dob
+
+####################################################
+# 6. Modulok
+####################################################
+
+# Modulokat így lehet importálni
+import math
+
+print math.sqrt(16) # => 4.0
+
+# Lehetséges csak bizonyos függvényeket importálni egy modulból
+from math import ceil, floor
+
+print ceil(3.7) # => 4.0
+print floor(3.7) # => 3.0
+
+# Egy modul összes függvénye is importálható
+# Vigyázat: ez nem ajánlott.
+from math import *
+
+# A modulok nevei lerövidíthetőek
+import math as m
+
+math.sqrt(16) == m.sqrt(16) # => True
+# Meggyőződhetünk róla, hogy a függvények valóban azonosak
+from math import sqrt
+
+math.sqrt == m.sqrt == sqrt # => True
+
+# A Python modulok egyszerű fájlok.
+# Írhatsz sajátot és importálhatod is.
+# A modul neve azonos a tartalmazó fájl nevével.
+
+# Így lehet megtekinteni, milyen mezőket és függvényeket definiál egy modul.
+import math
+
+dir(math)
+
+
+# Ha van egy math.py nevű Python scripted a jelenleg futó scripttel azonos
+# mappában, a math.py fájl lesz betöltve a beépített Python modul helyett.
+# A lokális mappa prioritást élvez a beépített könyvtárak felett.
+
+
+####################################################
+# 7. Haladóknak
+####################################################
+
+# Generátorok
+# Egy generátor értékeket "generál" amikor kérik, a helyett, hogy előre eltárolná őket.
+
+# A következő metódus (ez még NEM egy generátor) megduplázza a kapott iterable elemeit,
+# és eltárolja őket. Nagy méretű iterable esetén ez nagyon sok helyet foglalhat!
+def double_numbers(iterable):
+ double_arr = []
+ for i in iterable:
+ double_arr.append(i + i)
+ return double_arr
+
+
+# A következő kód futtatásakor az összes szám kétszeresét kiszámítanánk, és visszaadnánk
+# ezt a nagy listát a ciklus vezérléséhez.
+for value in double_numbers(range(1000000)): # `test_non_generator`
+ print value
+ if value > 5:
+ break
+
+
+# Használjunk inkább egy generátort, ami "legenerálja" a soron következő elemet,
+# amikor azt kérik tőle
+def double_numbers_generator(iterable):
+ for i in iterable:
+ yield i + i
+
+
+# A lenti kód mindig csak a soron következő számot generálja a logikai vizsgálat előtt.
+# Így amikor az érték eléri a > 5 határt, megszakítjuk a ciklust, és a lista számainak
+# nagy részénél megspóroltuk a duplázás műveletet (ez sokkal gyorsabb így!).
+for value in double_numbers_generator(xrange(1000000)): # `test_generator`
+ print value
+ if value > 5:
+ break
+
+# Feltűnt, hogy a `test_non_generator` esetén `range`, a `test_generator` esetén
+# pedig `xrange` volt a segédfüggvény neve? Ahogy `double_numbers_generator` a
+# generátor változata a `double_numbers` függvénynek, úgy az `xrange` a `range`
+# generátor megfelelője, csak akkor generálja le a következő számot, amikor kérjük
+# - esetünkben a ciklus következő iterációjakor
+
+# A lista képzéshez hasonlóan generátor képzőket is használhatunk
+# ("generator comprehensions").
+values = (-x for x in [1, 2, 3, 4, 5])
+for x in values:
+ print(x) # kimenet: -1 -2 -3 -4 -5
+
+# Egy generátor összes generált elemét listaként is elkérhetjük:
+values = (-x for x in [1, 2, 3, 4, 5])
+gen_to_list = list(values)
+print(gen_to_list) # => [-1, -2, -3, -4, -5]
+
+# Dekorátorok
+# A dekorátor egy magasabb rendű függvény, aminek bemenete és kimenete is egy függvény.
+# A lenti egyszerű példában az add_apples dekorátor a dekorált get_fruits függvény
+# kimenetébe beszúrja az 'Apple' elemet.
+def add_apples(func):
+ def get_fruits():
+ fruits = func()
+ fruits.append('Apple')
+ return fruits
+ return get_fruits
+
+@add_apples
+def get_fruits():
+ return ['Banana', 'Mango', 'Orange']
+
+# A kimenet tartalmazza az 'Apple' elemet:
+# Banana, Mango, Orange, Apple
+print ', '.join(get_fruits())
+
+# Ebben a példában a beg dekorátorral látjuk el a say függvényt.
+# Beg meghívja say-t. Ha a say_please paraméter igaz, akkor
+# megváltoztatja az eredmény mondatot.
+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 :(
+```
+
+## Még több érdekel?
+
+### Ingyenes online tartalmak
+
+* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
+* [LearnPython](http://www.learnpython.org/)
+* [Fullstack Python](https://www.fullstackpython.com/)
+
+### Könyvek
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
diff --git a/hu-hu/yaml-hu.html.markdown b/hu-hu/yaml-hu.html.markdown
index 37ce4cb2..3fb8b87f 100644
--- a/hu-hu/yaml-hu.html.markdown
+++ b/hu-hu/yaml-hu.html.markdown
@@ -2,7 +2,7 @@
language: yaml
filename: learnyaml-hu.yaml
contributors:
- - ["Adam Brenecki", "https://github.com/adambrenecki"]
+ - ["Leigh Brenecki", "https://github.com/adambrenecki"]
translators:
- ["Tamás Diószegi", "https://github.com/ditam"]
lang: hu-hu
diff --git a/hy.html.markdown b/hy.html.markdown
index 79c16c23..1287095f 100644
--- a/hy.html.markdown
+++ b/hy.html.markdown
@@ -102,7 +102,7 @@ True ; => True
(apply something-fancy ["My horse" "amazing"] { "mane" "spectacular" })
; anonymous functions are created using `fn' or `lambda' constructs
-; which are similiar to `defn'
+; which are similar to `defn'
(map (fn [x] (* x x)) [1 2 3 4]) ;=> [1 4 9 16]
;; Sequence operations
diff --git a/id-id/asciidoc-id.html.markdown b/id-id/asciidoc-id.html.markdown
index 8da8af38..ceb56b92 100644
--- a/id-id/asciidoc-id.html.markdown
+++ b/id-id/asciidoc-id.html.markdown
@@ -84,10 +84,6 @@ Judul bagian
===== Level 4 <h5>
-====== Level 5 <h6>
-
-======= Level 6 <h7>
-
```
Daftar
diff --git a/id-id/bf-id.html.markdown b/id-id/bf-id.html.markdown
new file mode 100644
index 00000000..bf2f6a09
--- /dev/null
+++ b/id-id/bf-id.html.markdown
@@ -0,0 +1,86 @@
+---
+language: bf
+filename: brainfuck-id.bf
+contributors:
+ - ["Prajit Ramachandran", "http://prajitr.github.io/"]
+ - ["Mathias Bynens", "http://mathiasbynens.be/"]
+translators:
+ - ["Muhammad Rifqi Fatchurrahman", "http://muhrifqii.github.io/"]
+lang: id-id
+---
+
+Brainfuck (tidak dalam huruf kapital kecuali pada awal kalimat) adalah sebuah
+bahasa pemrograman Turing-complete yang sangat minim yang hanya memiliki 8 perintah.
+
+Anda bisa mencoba brainfuck pada browser dengan menggunakan [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/).
+
+```bf
+Karakter apapun selain "><+-.,[]" (tanda kutip tidak termasuk) diabaikan.
+
+Brainfuck direpresentasikan dengan sebuah array yang memiliki 30,000 cell yang
+diinisialisasi dengan nol dan pointer data yang menunjuk ke current cell.
+
+Terdapat delapan perintah:
++ : Menaikkan nilai pada current cell sebesar satu.
+- : Menurunkan nilai pada current cell sebesar satu.
+> : Menggeser pointer data ke cell selanjutnya (cell sebelah kanan).
+< : Menggeser pointer data ke cell sebelumnya (cell sebelah kiri).
+. : Mencetak nilai ASCII pada current cell (misal 65 = 'A').
+, : Membaca sebuah karakter masukan tunggal ke dalam current cell.
+[ : Jika nilai pada current cell bernilai nol, lewati hingga mencapai ] yang sesuai.
+ Jika tidak, pindah ke instruksi berikutnya.
+] : Jika nilai pada current cell bernilai nol, pindah ke instruksi berikutnya.
+ Jika tidak, mundur pada instruksi hingga mencapai [ yang sesuai.
+
+[ dan ] membentuk sebuah rekursi while. Tentu saja mereka harus seimbang.
+
+Mari kita lihat beberapa program brainfuck dasar.
+
+++++++ [ > ++++++++++ < - ] > +++++ .
+
+Program ini mencetak huruf 'A'. Mula-mula, cell #1 dinaikkan ke 6.
+Cell #1 akan digunakan untuk rekursi. Lalu, masuk ke rekursi ([) dan pindah
+ke cell #2. Cell #2 dinaikkan 10 kali, mundur ke cell #1, dan menurunkan
+cell #1. Rekursi ini berlangsung 6 kali (melakukan 6 penurunan nilai untuk
+cell #1 hingga mencapai 0, di titik mana dia melewati hingga mencapai ] dan
+terus berlanjut).
+
+Pada titik ini, kita berada pada cell #1, yang memiliki nilai 0, sedangkan cell #2
+memiliki sebuah nilai 60. Kita berpindah ke cell #2, menaikkan nilai 5 kali, memunculkan
+nilai 65, lalu cetak nilai pada cell #2. 65 adalah 'A' pada ASCII, jadi 'A'
+dicetak ke terminal.
+
+, [ > + < - ] > .
+
+Program ini membaca sebuah karakter dari masukan user dan menyalin karakternya ke
+cell #1. Setelah itu rekursi dimulai. Geser ke cell #2, menaikkan nilai pada cell #2,
+mundur ke cell #1, dan menurunkan nilai pada cell #1. Hal ini berlanjut sampai cell #1
+bernilai 0, dan cell #2 menyimpan nilai lama dari cell #1. Karena kita berada di cell #1
+saat ujung rekursi, geser ke cell #2, lalu cetak nilai dalam bentuk ASCII.
+
+Perlu diingat bahwa spasi itu murni untuk memudahkan membaca. Anda bisa
+menuliskannya dengan mudah seperti:
+
+,[>+<-]>.
+
+Coba dan cari tahu apa yang program ini lakukan:
+
+,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >>
+
+Program ini menerima dua buah angka sebagai input, lalu mengalikannya.
+
+Intinya adalah membaca dua masukan. Lalu mulai pada rekursi terluar yang
+kondisinya pada cell #1. Lalu pindah ke cell #2, dan mulai rekursi terdalam
+yang kondisinya ada pada cell #2, menaikkan nilai pada cell #3. Namun,
+ada suatu masalah: Pada akhir dari rekursi terdalam, cell #2 bernilai nol.
+Pada kasus tersebut, rekursi terdalam tidak dapat bekerja lagi mulai setelah ini.
+Untuk menyelesaikan masalah tersebut, kita juga menaikkan cell #4, dan menyalin
+ulang cell #4 ke cell #2. Maka cell #3 adalah hasilnya.
+```
+
+Dan itulah brainfuck. Tidak terlalu sulit kan? Hanya untuk iseng-iseng, anda
+bisa menuliskan porgram brainfuck anda sendiri, atau anda bisa menuliskan interpreter
+brainfuck pada bahasa lain. Interpreternya tidak begitu sulit untuk diimplementasikan,
+tapi jika anda seorang masokis, cobalah menulis sebuah interpreter brainfuck... dalam
+brainfuck.
+
diff --git a/id-id/hq9+-id.html.markdown b/id-id/hq9+-id.html.markdown
new file mode 100644
index 00000000..46abcf42
--- /dev/null
+++ b/id-id/hq9+-id.html.markdown
@@ -0,0 +1,45 @@
+---
+language: HQ9+
+filename: hq9+-id.html
+contributors:
+ - ["Alexey Nazaroff", "https://github.com/rogaven"]
+translators:
+ - ["Haydar Ali Ismail", "http://github.com/haydarai"]
+lang: id-id
+---
+
+HQ9+ adalah bahasa pemrograman gurauan yang dibuat oleh Cliff Biffle. Bahasa
+ini hanya memiliki empat perintah dan tidak memenuhi Turing-complete.
+
+```
+Hanya ada 4 perintah, masing-masing direpresentasikan oleh karakter berikut
+H: mencetak "Hello, world!"
+Q: mencetak kode sumber dari program ini (Quine)
+9: mencetak lirik dari lagu "99 Bottles of Beer"
++: menambah nilai satu ke akumulator (nilai dari akumulator tidak dapat
+ diakses)
+Karakter lain akan dihiraukan.
+
+Ok. Mari kita menulis beberapa program:
+ HQ9
+
+Hasil:
+ Hello world!
+ HQ9
+
+HQ9+ sangat sederhana, tetapi membuat anda bisa melakukan hal yang sangat sulit
+dilakukan di bahasa lain. Sebagai contoh, berikut sebuah program yang
+menciptakan tiga salinan dirinya sendiri ke layar:
+ QQQ
+
+Ini menghasilakn:
+ QQQ
+ QQQ
+ QQQ
+```
+
+Dan itu semuanya. Ada banyak interpreters untuk HQ9+. Kamu bisa menemukannya di
+bawah
+
++ [Salah satu interpreter online](https://almnet.de/esolang/hq9plus.php)
++ [Website resmi HQ9+](http://cliffle.com/esoterica/hq9plus.html)
diff --git a/id-id/markdown.html.markdown b/id-id/markdown.html.markdown
index 06ad1092..1ff1963b 100644
--- a/id-id/markdown.html.markdown
+++ b/id-id/markdown.html.markdown
@@ -13,7 +13,7 @@ Markdown dibuat oleh John Gruber pada tahun 2004. Tujuannya untuk menjadi syntax
Beri masukan sebanyak-banyaknya! / Jangan sungkan untuk melakukan fork dan pull request!
-```markdown
+```md
<!-- Markdown adalah superset dari HTML, jadi setiap berkas HTML adalah markdown yang
valid, ini berarti kita dapat menggunakan elemen HTML dalam markdown, seperti elemen
komentar, dan ia tidak akan terpengaruh parser markdown. Namun, jika Anda membuat
diff --git a/id-id/rst-id.html.markdown b/id-id/rst-id.html.markdown
new file mode 100644
index 00000000..06d80089
--- /dev/null
+++ b/id-id/rst-id.html.markdown
@@ -0,0 +1,122 @@
+---
+language: restructured text (RST)
+filename: rst-id.html
+contributors:
+ - ["DamienVGN", "https://github.com/martin-damien"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+translators:
+ - ["Haydar Ali Ismail", "https://github.com/haydarai"]
+lang: id-id
+---
+
+RST adalah sebual format file yang dibuat oleh komunitas Python untuk menulis
+dokumentasi (dan menjadi bagian dari Docutils).
+
+File-file RST adalah sebuah file-file teks simpel dengan sintaks yang ringan
+(dibandingkan dengan HTML).
+
+
+## Pemasangan
+
+Untuk menggunakan RST, anda harus memasang [Python](http://www.python.org) dan
+paket `docutils` terlebih dahulu.
+
+`docutils` bisa dipasang menggunakan command berikut:
+
+```bash
+$ easy_install docutils
+```
+
+Jika sistem anda sudah mempunyai `pip`, anda bisa menggunakannya juga:
+
+```bash
+$ pip install docutils
+```
+
+
+## Sintaks file
+
+Sebuah contoh sederhana dari sintaks file:
+
+```
+.. Baris yang dimulai dengan dua titik adalah perintah spesial. Tetapi jika
+perintah tidak ditemukan, maka baris tersebut akan dianggap sebagai komentar
+
+===============================================================================
+Judul utama ditulis menggunakan rentetan tanda sama dengan di atas dan bawahnya
+===============================================================================
+
+Ingat bahwa jumlah tanda sama dengan harus sama panjangnya dengan total
+karakter judul
+
+Judul juga digarisbawahi dengan tanda sama dengan juga
+======================================================
+
+Sub-judul dengan menggunakan dash
+---------------------------------
+
+Dan sub-sub-judul dengan menggunakan tilde
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Anda bisa menulis teks dalam *italik* atau *tebal*, anda bisa "menandai" teks
+sebagai kode dengan menggunakan backquote ganda ``: ``print()``.
+
+Membuat daftar semudah seperti dalam Markdown:
+
+- Barang pertama
+- Barang kedua
+ - Sub barang
+
+atau
+
+* Barang pertama
+* Barang kedua
+ * Sub barang
+
+Tabel sangat mudah untuk ditulis:
+
+=========== ========
+Negara Ibu Kota
+=========== ========
+Prancis Paris
+Jepang Tokyo
+=========== ========
+
+Tabel yang lebih kompleks bisa dibuat dengan mudah (kolom tergabung atau/dan
+baris) tetapi saya menyarankan anda untuk membaca dokumentasi lengkap tentang
+ini :)
+
+Ada berbagai macam cara untuk membuat tautan:
+
+- Dengan menambahkan garis bawah setelah sebuah huruf : Github_ dan dengan
+menambahkan URL target setelah teks (cara ini mempunyai kelebihan dengan tidak
+memasukkan URL yang tidak penting ke dalam teks yang bisa dibaca).
+- Dengan mengetik URL lengkap yang dapat dipahami : https://github.com (akan
+otomatis diubah menjadi sebuah link)
+- Dengan membuat link seperti di Markdown: `Github <https://github.com/>`_ .
+
+.. _Github https://github.com/
+
+```
+
+
+## Bagaimana Cara Menggunakannya
+
+RST hadir dengan docutils di mana anda mempunyai `rst2html`, sebagai contoh:
+
+```bash
+$ rst2html fileku.rst hasil.html
+```
+
+*Catatan : Di beberapa sistem, perintah tersebut bisa menjadi rst2html.py*
+
+Tetapi ada beberapa aplikasi kompleks yang menggunakan format RST:
+
+- [Pelican](http://blog.getpelican.com/), Generator web statik
+- [Sphinx](http://sphinx-doc.org/), Generator dokumnetasi
+- dan masih banyak lainnya
+
+
+## Bacaan
+
+- [Referensi singkat resmi](http://docutils.sourceforge.net/docs/user/rst/quickref.html)
diff --git a/it-it/asciidoc-it.html.markdown b/it-it/asciidoc-it.html.markdown
new file mode 100644
index 00000000..47a57349
--- /dev/null
+++ b/it-it/asciidoc-it.html.markdown
@@ -0,0 +1,135 @@
+---
+language: asciidoc
+contributors:
+ - ["Ryan Mavilia", "http://unoriginality.rocks/"]
+ - ["Abel Salgado Romero", "https://twitter.com/abelsromero"]
+translators:
+ - ["Ale46", "https://github.com/ale46"]
+lang: it-it
+filename: asciidoc-it.md
+---
+
+AsciiDoc è un linguaggio di markup simile a Markdown e può essere usato per qualsiasi cosa, dai libri ai blog. Creato nel 2002 da Stuart Rackman, questo linguaggio è semplice ma permette un buon numero di personalizzazioni.
+
+Intestazione Documento
+
+Le intestazioni sono opzionali e possono contenere linee vuote. Deve avere almeno una linea vuota rispetto al contenuto.
+
+Solo titolo
+
+```
+= Titolo documento
+
+Prima frase del documento.
+```
+
+Titolo ed Autore
+
+```
+= Titolo documento
+Primo Ultimo <first.last@learnxinyminutes.com>
+
+Inizio del documento
+```
+
+Autori multipli
+
+```
+= Titolo Documento
+John Doe <john@go.com>; Jane Doe<jane@yo.com>; Black Beard <beardy@pirate.com>
+
+Inizio di un documento con autori multipli.
+```
+
+Linea di revisione (richiede una linea autore)
+
+```
+= Titolo documento V1
+Potato Man <chip@crunchy.com>
+v1.0, 2016-01-13
+
+Questo articolo sulle patatine sarà divertente.
+```
+
+Paragrafi
+
+```
+Non hai bisogno di nulla di speciale per i paragrafi.
+
+Aggiungi una riga vuota tra i paragrafi per separarli.
+
+Per creare una riga vuota aggiungi un +
+e riceverai una interruzione di linea!
+```
+
+Formattazione Testo
+
+```
+_underscore crea corsivo_
+*asterischi per il grassetto*
+*_combinali per maggiore divertimento_*
+`usa i ticks per indicare il monospazio`
+`*spaziatura fissa in grassetto*`
+```
+
+Titoli di sezione
+
+```
+= Livello 0 (può essere utilizzato solo nell'intestazione del documento)
+
+== Livello 1 <h2>
+
+=== Livello 2 <h3>
+
+==== Livello 3 <h4>
+
+===== Livello 4 <h5>
+
+```
+
+Liste
+
+Per creare un elenco puntato, utilizzare gli asterischi.
+
+```
+* foo
+* bar
+* baz
+```
+
+Per creare un elenco numerato usa i periodi.
+
+```
+. item 1
+. item 2
+. item 3
+```
+
+È possibile nidificare elenchi aggiungendo asterischi o periodi aggiuntivi fino a cinque volte.
+
+```
+* foo 1
+** foo 2
+*** foo 3
+**** foo 4
+***** foo 5
+
+. foo 1
+.. foo 2
+... foo 3
+.... foo 4
+..... foo 5
+```
+
+## Ulteriori letture
+
+Esistono due strumenti per elaborare i documenti AsciiDoc:
+
+1. [AsciiDoc](http://asciidoc.org/): implementazione Python originale, disponibile nelle principali distribuzioni Linux. Stabile e attualmente in modalità di manutenzione.
+2. [Asciidoctor](http://asciidoctor.org/): implementazione alternativa di Ruby, utilizzabile anche da Java e JavaScript. In fase di sviluppo attivo, mira ad estendere la sintassi AsciiDoc con nuove funzionalità e formati di output.
+
+I seguenti collegamenti sono relativi all'implementazione di `Asciidoctor`:
+
+* [Markdown - AsciiDoc comparazione sintassi](http://asciidoctor.org/docs/user-manual/#comparison-by-example): confronto affiancato di elementi di Markdown e AsciiDoc comuni.
+* [Per iniziare](http://asciidoctor.org/docs/#get-started-with-asciidoctor): installazione e guide rapide per il rendering di documenti semplici.
+* [Asciidoctor Manuale Utente](http://asciidoctor.org/docs/user-manual/): manuale completo con riferimento alla sintassi, esempi, strumenti di rendering, tra gli altri.
diff --git a/it-it/bash-it.html.markdown b/it-it/bash-it.html.markdown
index efc47969..cfe58f30 100644
--- a/it-it/bash-it.html.markdown
+++ b/it-it/bash-it.html.markdown
@@ -63,7 +63,7 @@ echo ${Variabile}
# Sotto ci sono altri esempi che analizzano l'uso dell'espansione dei parametri.
# Sostituzione di stringhe nelle variabili
-echo ${Variabile/Una/A}
+echo ${Variabile/Una/La}
# Questo sostituirà la prima occorrenza di "Una" con "La"
# Sottostringa di una variabile
@@ -140,6 +140,25 @@ then
echo "Questo verrà eseguito se $Nome è Daniya O Zach."
fi
+# C'è anche l'operatore `=~`, che serve per confrontare una stringa con un'espressione regolare:
+Email=me@example.com
+if [[ "$Email" =~ [a-z]+@[a-z]{2,}\.(com|net|org) ]]
+then
+ echo "Email valida!"
+fi
+# L'operatore =~ funziona solo dentro alle doppie parentesi quadre [[ ]],
+# che hanno un comportamento leggermente diverso rispetto alle singole [ ].
+# Se vuoi approfondire, visita questo link (in inglese):
+# http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs
+
+# Usando `alias`, puoi definire nuovi comandi o modificare quelli già esistenti.
+# Ad esempio, così puoi ridefinire il comando ping per inviare solo 5 pacchetti
+alias ping='ping -c 5'
+# "Scavalca" l'alias e usa il comando vero, utilizzando il backslash
+\ping 192.168.1.1
+# Stampa la lista di tutti gli alias
+alias -p
+
# Le espressioni sono nel seguente formato:
echo $(( 10 + 5 ))
diff --git a/it-it/bf-it.html.markdown b/it-it/bf-it.html.markdown
index a79710d0..97e5b88e 100644
--- a/it-it/bf-it.html.markdown
+++ b/it-it/bf-it.html.markdown
@@ -1,5 +1,6 @@
---
language: bf
+filename: learnbf-it.bf
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
diff --git a/it-it/c++-it.html.markdown b/it-it/c++-it.html.markdown
index 4af30176..449aebfb 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_.
@@ -1130,7 +1130,6 @@ compl 4 // Effettua il NOT bit-a-bit
```
Letture consigliate:
-Un riferimento aggiornato del linguaggio può essere trovato qui
-<http://cppreference.com/w/cpp>
-
-Risorse addizionali possono essere trovate qui <http://cplusplus.com>
+* Un riferimento aggiornato del linguaggio può essere trovato qui [CPP Reference](http://cppreference.com/w/cpp).
+* Risorse addizionali possono essere trovate qui [CPlusPlus](http://cplusplus.com).
+* Un tutorial che copre le basi del linguaggio e l'impostazione dell'ambiente di codifica è disponibile su [TheChernoProject - C ++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb).
diff --git a/it-it/dynamic-programming-it.html.markdown b/it-it/dynamic-programming-it.html.markdown
new file mode 100644
index 00000000..9c7bd9b6
--- /dev/null
+++ b/it-it/dynamic-programming-it.html.markdown
@@ -0,0 +1,55 @@
+---
+category: Algorithms & Data Structures
+name: Dynamic Programming
+contributors:
+ - ["Akashdeep Goel", "http://github.com/akashdeepgoel"]
+translators:
+ - ["Ale46", "https://github.com/ale46"]
+lang: it-it
+---
+
+# Programmazione dinamica
+
+## Introduzione
+
+La programmazione dinamica è una tecnica potente utilizzata per risolvere una particolare classe di problemi, come vedremo. L'idea è molto semplice, se hai risolto un problema con l'input dato, salva il risultato come riferimento futuro, in modo da evitare di risolvere nuovamente lo stesso problema.
+
+Ricordate sempre!
+"Chi non ricorda il passato è condannato a ripeterlo"
+
+## Modi per risolvere questi problemi
+
+1. *Top-Down* : Inizia a risolvere il problema specifico suddividendolo. Se vedi che il problema è già stato risolto, rispondi semplicemente con la risposta già salvata. Se non è stato risolto, risolvilo e salva la risposta. Di solito è facile da pensare e molto intuitivo. Questo è indicato come Memoization.
+
+2. *Bottom-Up* : Analizza il problema e vedi l'ordine in cui i sotto-problemi sono risolti e inizia a risolvere dal sottoproblema banale, verso il problema dato. In questo processo, è garantito che i sottoproblemi vengono risolti prima di risolvere il problema. Si parla di programmazione dinamica.
+
+## Esempio di programmazione dinamica
+
+Il problema di "Longest Increasing Subsequence" consiste nel trovare la sottosequenza crescente più lunga di una determinata sequenza. Data una sequenza `S= {a1 , a2 , a3, a4, ............., an-1, an }` dobbiamo trovare il sottoinsieme più lungo tale che per tutti gli `j` e gli `i`, `j<i` nel sotto-insieme `aj<ai`.
+Prima di tutto dobbiamo trovare il valore delle sottosequenze più lunghe (LSi) ad ogni indice i con l'ultimo elemento della sequenza che è ai. Quindi il più grande LSi sarebbe la sottosequenza più lunga nella sequenza data. Per iniziare LSi viene inizializzato ad 1, dato che ai è un element della sequenza (Ultimo elemento). Quindi per tutti gli `j` tale che `j<i` e `aj<ai`, troviamo il più grande LSj e lo aggiungiamo a LSi. Quindi l'algoritmo richiede un tempo di *O(n2)*.
+
+Pseudo-codice per trovare la lunghezza della sottosequenza crescente più lunga:
+Questa complessità degli algoritmi potrebbe essere ridotta usando una migliore struttura dei dati piuttosto che una matrice. La memorizzazione dell'array predecessore e della variabile come `largest_sequences_so_far` e il suo indice farebbero risparmiare molto tempo.
+
+Un concetto simile potrebbe essere applicato nel trovare il percorso più lungo nel grafico aciclico diretto.
+
+```python
+for i=0 to n-1
+ LS[i]=1
+ for j=0 to i-1
+ if (a[i] > a[j] and LS[i]<LS[j])
+ LS[i] = LS[j]+1
+for i=0 to n-1
+ if (largest < LS[i])
+```
+
+### Alcuni famosi problemi DP
+
+- Floyd Warshall Algorithm - Tutorial e Codice sorgente in C del programma: [http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code]()
+- Integer Knapsack Problem - Tutorial e Codice sorgente in C del programma: [http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem]()
+- Longest Common Subsequence - Tutorial e Codice sorgente in C del programma: [http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence]()
+
+
+## Risorse online
+
+* [codechef](https://www.codechef.com/wiki/tutorial-dynamic-programming)
diff --git a/it-it/elixir-it.html.markdown b/it-it/elixir-it.html.markdown
index 60301b1a..48afe0c8 100644
--- a/it-it/elixir-it.html.markdown
+++ b/it-it/elixir-it.html.markdown
@@ -24,7 +24,7 @@ e molte altre funzionalità.
# Per usare la shell di elixir usa il comando `iex`.
# Compila i tuoi moduli con il comando `elixirc`.
-# Entrambi i comandi dovrebbero già essere nel tuo PATH se hai installato
+# Entrambi i comandi dovrebbero già essere nel tuo PATH se hai installato
# elixir correttamente.
## ---------------------------
@@ -65,7 +65,7 @@ coda #=> [2,3]
# le tuple hanno dimensione differente.
# {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
-# Ci sono anche i binari
+# Ci sono anche i binari
<<1,2,3>> # binari (Binary)
# Stringhe e liste di caratteri
@@ -80,7 +80,7 @@ multi-linea.
#=> "Sono una stringa\nmulti-linea.\n"
# Le stringhe sono tutte codificate in UTF-8:
-"cìaò"
+"cìaò"
#=> "cìaò"
# le stringhe in realtà sono dei binari, e le liste di caratteri sono liste.
@@ -124,10 +124,11 @@ rem(10, 3) #=> 1
# Questi operatori si aspettano un booleano come primo argomento.
true and true #=> true
false or true #=> true
-# 1 and true #=> ** (ArgumentError) argument error
+# 1 and true
+#=> ** (BadBooleanError) expected a boolean on left-side of "and", got: 1
# Elixir fornisce anche `||`, `&&` e `!` che accettano argomenti
-# di qualsiasi tipo.
+# di qualsiasi tipo.
# Tutti i valori tranne `false` e `nil` saranno valutati come true.
1 || true #=> 1
false && 1 #=> false
@@ -147,7 +148,7 @@ nil && 20 #=> nil
1 < :ciao #=> true
# L'ordine generale è definito sotto:
-# numeri < atomi < riferimenti < funzioni < porte < pid < tuple < liste
+# numeri < atomi < riferimenti < funzioni < porte < pid < tuple < liste
# < stringhe di bit
# Per citare Joe Armstrong su questo: "L'ordine non è importante,
@@ -171,7 +172,7 @@ else
"Questo sì"
end
-# Ti ricordi il pattern matching?
+# Ti ricordi il pattern matching?
# Moltre strutture di controllo di flusso in elixir si basano su di esso.
# `case` ci permette di confrontare un valore a diversi pattern:
@@ -214,7 +215,7 @@ cond do
"Questa sì! (essenzialmente funziona come un else)"
end
-# `try/catch` si usa per gestire i valori lanciati (throw),
+# `try/catch` si usa per gestire i valori lanciati (throw),
# Supporta anche una clausola `after` che è invocata in ogni caso.
try do
throw(:ciao)
@@ -235,7 +236,7 @@ quadrato = fn(x) -> x * x end
quadrato.(5) #=> 25
# Accettano anche guardie e condizioni multiple.
-# le guardie ti permettono di perfezionare il tuo pattern matching,
+# le guardie ti permettono di perfezionare il tuo pattern matching,
# sono indicate dalla parola chiave `when`:
f = fn
x, y when x > 0 -> x + y
@@ -265,13 +266,13 @@ end
Matematica.somma(1, 2) #=> 3
Matematica.quadrato(3) #=> 9
-# Per compilare il modulo 'Matematica' salvalo come `matematica.ex` e usa
+# Per compilare il modulo 'Matematica' salvalo come `matematica.ex` e usa
# `elixirc`.
# nel tuo terminale: elixirc matematica.ex
# All'interno di un modulo possiamo definire le funzioni con `def` e funzioni
# private con `defp`.
-# Una funzione definita con `def` è disponibile per essere invocata anche da
+# Una funzione definita con `def` è disponibile per essere invocata anche da
# altri moduli, una funziona privata può essere invocata solo localmente.
defmodule MatematicaPrivata do
def somma(a, b) do
@@ -286,7 +287,11 @@ end
MatematicaPrivata.somma(1, 2) #=> 3
# MatematicaPrivata.esegui_somma(1, 2) #=> ** (UndefinedFunctionError)
-# Anche le dichiarazioni di funzione supportano guardie e condizioni multiple:
+# Anche le dichiarazioni di funzione supportano guardie e condizioni multiple.
+# Quando viene chiamata una funzione dichiarata con più match, solo la prima
+# che matcha viene effettivamente invocata.
+# Ad esempio: chiamando area({:cerchio, 3}) vedrà invocata la seconda definizione
+# di area mostrata sotto, non la prima:
defmodule Geometria do
def area({:rettangolo, w, h}) do
w * h
@@ -322,16 +327,25 @@ defmodule Modulo do
Questo è un attributo incorporato in un modulo di esempio.
"""
- @miei_dati 100 # Questo è un attributo personalizzato .
+ @miei_dati 100 # Questo è un attributo personalizzato.
IO.inspect(@miei_dati) #=> 100
end
+# L'operatore pipe |> permette di passare l'output di una espressione
+# come primo parametro di una funzione.
+# Questo facilita operazioni quali pipeline di operazioni, composizione di
+# funzioni, ecc.
+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]
+
## ---------------------------
## -- Strutture ed Eccezioni
## ---------------------------
-# Le Strutture (Structs) sono estensioni alle mappe che portano
+# Le Strutture (Structs) sono estensioni alle mappe che portano
# valori di default, garanzia alla compilazione e polimorfismo in Elixir.
defmodule Persona do
defstruct nome: nil, eta: 0, altezza: 0
@@ -367,7 +381,7 @@ end
## -- Concorrenza
## ---------------------------
-# Elixir si basa sul modello degli attori per la concorrenza.
+# Elixir si basa sul modello degli attori per la concorrenza.
# Tutto ciò di cui abbiamo bisogno per scrivere programmi concorrenti in elixir
# sono tre primitive: creare processi, inviare messaggi e ricevere messaggi.
@@ -379,12 +393,12 @@ spawn(f) #=> #PID<0.40.0>
# `spawn` restituisce un pid (identificatore di processo). Puoi usare questo
# pid per inviare messaggi al processo.
# Per passare messaggi si usa l'operatore `send`.
-# Perché tutto questo sia utile dobbiamo essere capaci di ricevere messaggi,
+# Perché tutto questo sia utile dobbiamo essere capaci di ricevere messaggi,
# oltre ad inviarli. Questo è realizzabile con `receive`:
# Il blocco `receive do` viene usato per mettersi in ascolto di messaggi
# ed elaborarli quando vengono ricevuti. Un blocco `receive do` elabora
-# un solo messaggio ricevuto: per fare elaborazione multipla di messaggi,
+# un solo messaggio ricevuto: per fare elaborazione multipla di messaggi,
# una funzione con un blocco `receive do` al suo intero dovrà chiamare
# ricorsivamente sé stessa per entrare di nuovo nel blocco `receive do`.
defmodule Geometria do
@@ -405,7 +419,7 @@ pid = spawn(fn -> Geometria.calcolo_area() end) #=> #PID<0.40.0>
# Alternativamente
pid = spawn(Geometria, :calcolo_area, [])
-# Invia un messaggio a `pid` che farà match su un pattern nel blocco in receive
+# Invia un messaggio a `pid` che farà match su un pattern nel blocco in receive
send pid, {:rettangolo, 2, 3}
#=> Area = 6
# {:rettangolo,2,3}
@@ -421,7 +435,7 @@ self() #=> #PID<0.27.0>
## Referenze
* [Getting started guide](http://elixir-lang.org/getting_started/1.html) dalla [pagina web ufficiale di elixir](http://elixir-lang.org)
-* [Documentazione Elixir](http://elixir-lang.org/docs/master/)
+* [Documentazione Elixir](https://elixir-lang.org/docs.html)
* ["Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) di Dave Thomas
* [Elixir Cheat Sheet](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf)
* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) di Fred Hebert
diff --git a/it-it/go-it.html.markdown b/it-it/go-it.html.markdown
index e005f2dc..797f6b0b 100644
--- a/it-it/go-it.html.markdown
+++ b/it-it/go-it.html.markdown
@@ -26,14 +26,14 @@ Aggiunge la concorrenza in maniera diretta e semplice da capire, per far
forza sulle CPU multi-core di oggigiorno. Presenta caratteristiche utili
per la programmazione in larga scala.
-Go comes with a great standard library and an enthusiastic community.
+Go include un'ottima libreria standard e ha una community entusiasta.
```go
// Commento su riga singola
/* Commento
su riga multipla */
-// In cima a ogni file è necessario specificare il package.
+// In cima ad ogni file è necessario specificare il package.
// Main è un package speciale che identifica un eseguibile anziché una libreria.
package main
@@ -65,19 +65,19 @@ func oltreIlCiaoMondo() {
x = 3 // Assegnazione di una variabile.
// E' possibile la dichiarazione "rapida" := per inferire il tipo, dichiarare e assegnare contemporaneamente.
y := 4
- // Una funzione che ritorna due valori.
- somma, prod := imparaMoltepliciValoriDiRitorno(x, y)
+ // Una funzione che restituisce due valori.
+ somma, prod := imparaMoltepliciValoriRestituiti(x, y)
fmt.Println("somma:", somma, "prodotto:", prod) // Semplice output.
imparaTipi() // < y minuti, devi imparare ancora!
}
/* <- commento su righe multiple
-Le funzioni possono avere parametri e ritornare (molteplici!) valori.
-Qua, x e y sono gli argomenti, mentre somma e prod sono i valori ritornati.
+Le funzioni possono avere parametri e restituire (molteplici!) valori.
+In questo esempio, x e y sono gli argomenti, mentre somma e prod sono i valori restituiti.
Da notare il fatto che x e somma vengono dichiarati come interi.
*/
-func imparaMoltepliciValoriDiRitorno(x, y int) (somma, prod int) {
- return x + y, x * y // Ritorna due valori.
+func imparaMoltepliciValoriRestituiti(x, y int) (somma, prod int) {
+ return x + y, x * y // Restituisce due valori.
}
// Ecco alcuni tipi presenti in Go
@@ -86,7 +86,7 @@ func imparaTipi() {
str := "Impara il Go!" // Tipo stringa.
s2 := `Una stringa letterale
-puo' includere andata a capo.` // Sempre di tipo stringa.
+può includere andata a capo.` // Sempre di tipo stringa.
// Stringa letterale non ASCII. I sorgenti Go sono in UTF-8.
g := 'Σ' // Il tipo runa, alias per int32, è costituito da un code point unicode.
@@ -144,20 +144,20 @@ puo' includere andata a capo.` // Sempre di tipo stringa.
imparaControlloDiFlusso() // Torniamo in carreggiata.
}
-// In Go è possibile associare dei nomi ai valori di ritorno di una funzione.
-// Assegnare un nome al tipo di dato ritornato permette di fare return in vari
+// In Go è possibile associare dei nomi ai valori restituiti da una funzione.
+// Assegnare un nome al tipo di dato restituito permette di fare return in vari
// punti all'interno del corpo della funzione, ma anche di usare return senza
-// specificare in modo esplicito che cosa ritornare.
-func imparaValoriDiRitornoConNome(x, y int) (z int) {
+// specificare in modo esplicito che cosa restituire.
+func imparaValoriRestituitiConNome(x, y int) (z int) {
z = x * y
return // z è implicito, perchè compare nella definizione di funzione.
}
// Go è dotato di garbage collection. Ha i puntatori, ma non l'aritmetica dei
-// puntatori. Puoi fare errori coi puntatori a nil, ma non puoi direttamente
-// incrementare un puntatore.
+// puntatori. Puoi commettere errori a causa di puntatori nulli, ma non puoi
+// incrementare un puntatore direttamente.
func imparaLaMemoria() (p, q *int) {
- // I valori di ritorno (con nome) p e q sono puntatori a int.
+ // I valori restituiti (con nome) p e q sono puntatori a int.
p = new(int) // La funzione new si occupa di allocare memoria.
// L'int allocato viene inizializzato a 0, dunque p non è più nil.
s := make([]int, 20) // Alloca 20 int come un singolo blocco di memoria.
@@ -207,14 +207,14 @@ func imparaControlloDiFlusso() {
}
// x == 42 qua.
- // Il for è l'unica istruzione per ciclare in Go, ma ha varie forme.
+ // Il for è l'unica istruzione per i loop in Go, ma ha varie forme.
for { // Ciclo infinito.
break // Scherzavo.
continue // Non si arriva qua.
}
- // Puoi usare range per ciclare su un vettore, slice, stringa, mappa o canale.
- // range ritorna uno (per i canali) o due valori (vettore, slice, stringa, mappa).
+ // Puoi usare range per iterare lungo un vettore, slice, stringa, mappa o canale.
+ // range restituisce uno (per i canali) o due valori (vettore, slice, stringa, mappa).
for chiave, valore := range map[string]int{"uno": 1, "due": 2, "tre": 3} {
// per ogni coppia dentro la mappa, stampa chiave e valore
fmt.Printf("chiave=%s, valore=%d\n", chiave, valore)
@@ -236,7 +236,7 @@ func imparaControlloDiFlusso() {
// Inoltre le funzioni letterali possono essere definite e chiamate
// inline, col ruolo di parametri di funzione, a patto che:
// a) la funzione letterale venga chiamata subito (),
- // b) il valore ritornato è in accordo con il tipo dell'argomento.
+ // b) il valore restituito è in accordo con il tipo dell'argomento.
fmt.Println("Somma e raddoppia due numeri: ",
func(a, b int) int {
return (a + b) * 2
@@ -247,7 +247,7 @@ func imparaControlloDiFlusso() {
goto amore
amore:
- imparaFabbricaDiFunzioni() // Una funzione che ritorna un'altra funzione è divertente!
+ imparaFabbricaDiFunzioni() // Una funzione che restituisce un'altra funzione è divertente!
imparaDefer() // Un tour veloce di una parola chiave importante.
imparaInterfacce() // Arriva la roba buona!
}
@@ -270,12 +270,13 @@ func fabbricaDiFrasi(miaStringa string) func(prima, dopo string) string {
}
func imparaDefer() (ok bool) {
- // Le istruzioni dette "deferred" (rinviate) sono eseguite
- // appena prima che la funzione ritorni.
+ // La parola chiave "defer" inserisce una funzione in una lista.
+ // La lista contenente tutte le chiamate a funzione viene eseguita DOPO
+ // il return finale della funzione che le circonda.
defer fmt.Println("le istruzioni 'deferred' sono eseguite in ordine inverso (LIFO).")
defer fmt.Println("\nQuesta riga viene stampata per prima perché")
// defer viene usato di solito per chiudere un file, così la funzione che
- // chiude il file viene messa vicino a quella che lo apre.
+ // chiude il file, preceduta da "defer", viene messa vicino a quella che lo apre.
return true
}
diff --git a/it-it/html-it.html.markdown b/it-it/html-it.html.markdown
new file mode 100644
index 00000000..8f7391a2
--- /dev/null
+++ b/it-it/html-it.html.markdown
@@ -0,0 +1,121 @@
+---
+language: html
+filename: learnhtml-it.txt
+contributors:
+ - ["Christophe THOMAS", "https://github.com/WinChris"]
+translators:
+ - ["Ale46", "http://github.com/Ale46/"]
+lang: it-it
+---
+
+HTML sta per HyperText Markup Language (linguaggio a marcatori per ipertesti).
+È un linguaggio che consente di scrivere pagine web per il world wide web.
+È un linguaggio di markup, che permette di scrivere pagine web usando del codice che indica come il testo ed i dati devono essere mostrati.
+Infatti, i files html sono semplici file di testo.
+Cos'è il markup? È un metodo per organizzare i dati della pagina circondandoli con tag di apertura e tag di chiusura.
+Questo markup serve a dare significato al testo che racchiude.
+Come altri linguaggi di programmazione, HTML ha molte versioni. Qui discuteremo di HTML5.
+
+**NOTA :** Puoi testare i differenti tags ed elementi man mano che prosegui nel tutorial in un sito come [codepen](http://codepen.io/pen/) per vedere i loro effetti, capire come lavorano e familiarizzare con il linguaggio.
+Questo articolo riguarda principalmente la sintassi HTML ed alcuni suggerimenti utili.
+
+
+```html
+<!-- I commenti sono racchiusi come in questa riga! -->
+
+<!-- #################### I Tags #################### -->
+
+<!-- Ecco un esempio di file HTML che andremo ad analizzare. -->
+
+<!doctype html>
+ <html>
+ <head>
+ <title>Il mio sito</title>
+ </head>
+ <body>
+ <h1>Ciao, mondo!</h1>
+ <a href = "http://codepen.io/anon/pen/xwjLbZ">Vieni a vedere ciò che mostra</a>
+ <p>Questo è un paragrafo.</p>
+ <p>Questo è un altro paragrafo.</p>
+ <ul>
+ <li>Questo è un elemento di un elenco non numerato (elenco puntato)</li>
+ <li>Questo è un altro elemento</li>
+ <li>E questo è l'ultimo elemento dell'elenco</li>
+ </ul>
+ </body>
+ </html>
+
+<!-- Un file HTML inizia sempre indicando al browser che la pagina è HTML. -->
+<!doctype html>
+
+<!-- Dopo questo, inizia aprendo un tag <html>. -->
+<html>
+
+<!-- che sarà chiuso alla fine del file con </html>. -->
+</html>
+
+<!-- Nulla dovrebbe apparire dopo questo tag finale. -->
+
+<!-- All'interno (tra i tag di apertura e chiusura <html> </html>) troviamo: -->
+
+<!-- Un'intestazione definita da <head> (deve essere chiusa con </head>). -->
+<!-- L'intestazione contiene alcune descrizioni e informazioni aggiuntive non visualizzate; questi sono i metadati. -->
+
+<head>
+ <title>Il mio sito</title> <!-- Il tag <title> indica al browser il titolo da mostrare nella barra del titolo della finestra del browser e nel nome della scheda. -->
+</head>
+
+<!-- Dopo la sezione <head>, troviamo il tag - <body> -->
+<!-- Fino a questo punto, niente di ciò che abbiamo descritto verrà visualizzato nella finestra del browser. -->
+<!-- Dobbiamo riempire il corpo con il contenuto da visualizzare. -->
+
+<body>
+ <h1>Ciao, mondo!</h1> <!-- Il tag h1 crea un titolo. -->
+ <!-- Ci sono anche sottotitoli a <h1> dal più importante (h2) al più preciso (h6). -->
+ <a href = "http://codepen.io/anon/pen/xwjLbZ">Vieni a vedere ciò che mostra</a> <!-- un collegamento ipertestuale all'URL fornito dall'attributo href="" -->
+ <p>Questo è un paragrafo.</p> <!-- Il tag <p> ci permette di includere del testo nella pagina html. -->
+ <p>Questo è un altro paragrafo.</p>
+ <ul> <!-- Il tag <ul> crea un elenco puntato. -->
+ <!-- Per avere un elenco numerato, invece, usiamo <ol> che restituisce 1. per il primo elemento, 2. per il secondo, etc. -->
+ <li>Questo è un elemento in un elenco non elencato (elenco puntato)</li>
+ <li>Questo è un altro elemento</li>
+ <li>E questo è l'ultimo elemento dell'elenco</li>
+ </ul>
+</body>
+
+<!-- E questo è tutto, creare un file HTML può essere molto semplice. -->
+
+<!-- Ma è possibile aggiungere molti altri tipi di tag HTML. -->
+
+<!-- Per inserire un'immagine. -->
+<img src="http://i.imgur.com/XWG0O.gif"/> <!-- La fonte dell'immagine viene indicata usando l'attributo src="" -->
+<!-- La fonte può essere un URL o persino un percorso di un file sul tuo computer. -->
+
+<!-- È anche possibile creare una tabella. -->
+
+<table> <!-- Apriamo un elemento <table>. -->
+ <tr> <!-- <tr> ci permette di creare una riga. -->
+ <th>Prima intestazione</th> <!-- <th> ci permette di dare un titolo ad una colonna della tabella. -->
+ <th>Seconda intestazione</th>
+ </tr>
+ <tr>
+ <td>prima riga, prima colonna</td> <!-- <td> ci permette di creare una cella della tabella. -->
+ <td>prima riga, seconda colonna</td>
+ </tr>
+ <tr>
+ <td>seconda riga, prima colonna</td>
+ <td>seconda riga, seconda colonna</td>
+ </tr>
+</table>
+
+```
+
+## Uso
+
+HTML è scritto in files che finiscono con `.html` o `.htm`. Il "MIME type" è `text/html`.
+
+## Per saperne di più
+
+* [wikipedia](https://it.wikipedia.org/wiki/HTML)
+* [HTML tutorial](https://developer.mozilla.org/it/docs/Web/HTML)
+* [W3School](http://www.w3schools.com/html/html_intro.asp)
diff --git a/it-it/java-it.html.markdown b/it-it/java-it.html.markdown
index 54602cff..1669816e 100644
--- a/it-it/java-it.html.markdown
+++ b/it-it/java-it.html.markdown
@@ -17,14 +17,14 @@ concorrente, basato su classi e adatto a svariati scopi.
```java
// I commenti su singola linea incominciano con //
/*
-I commenti su piu' linee invece sono cosi'
+I commenti su più linee invece sono così
*/
/**
-I commenti per la documentazione JavaDoc si fanno cosi'.
+I commenti per la documentazione JavaDoc si fanno così.
Vengono usati per descrivere una classe o alcuni suoi attributi.
*/
-// Per importare la classe ArrayList conenuta nel package java.util
+// Per importare la classe ArrayList contenuta nel package java.util
import java.util.ArrayList;
// Per importare tutte le classi contenute nel package java.security
import java.security.*;
@@ -48,7 +48,7 @@ public class LearnJava {
System.out.print("Ciao ");
System.out.print("Mondo ");
- // Per stampare del testo formattato, si puo' usare System.out.printf
+ // Per stampare del testo formattato, si può usare System.out.printf
System.out.printf("pi greco = %.5f", Math.PI); // => pi greco = 3.14159
///////////////////////////////////////
@@ -60,7 +60,7 @@ public class LearnJava {
*/
// Per dichiarare una variabile basta fare <tipoDato> <nomeVariabile>
int fooInt;
- // Per dichiarare piu' di una variabile dello lo stesso tipo si usa:
+ // Per dichiarare più di una variabile dello lo stesso tipo si usa:
// <tipoDato> <nomeVariabile1>, <nomeVariabile2>, <nomeVariabile3>
int fooInt1, fooInt2, fooInt3;
@@ -71,7 +71,7 @@ public class LearnJava {
// Per inizializzare una variabile si usa
// <tipoDato> <nomeVariabile> = <valore>
int fooInt = 1;
- // Per inizializzare piu' di una variabile dello lo stesso tipo
+ // Per inizializzare più di una variabile dello lo stesso tipo
// si usa <tipoDato> <nomeVariabile1>, <nomeVariabile2>, <nomeVariabile3> = <valore>
int fooInt1, fooInt2, fooInt3;
fooInt1 = fooInt2 = fooInt3 = 1;
@@ -94,7 +94,7 @@ public class LearnJava {
// Long - intero con segno a 64 bit (in complemento a 2)
// (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
long fooLong = 100000L;
- // L viene usato per indicare che il valore e' di tipo Long;
+ // L viene usato per indicare che il valore è di tipo Long;
// altrimenti il valore viene considerato come intero.
// Nota: Java non dispone di interi senza segno.
@@ -102,14 +102,14 @@ public class LearnJava {
// Float - Numero in virgola mobile a 32 bit con precisione singola (IEEE 754)
// 2^-149 <= float <= (2-2^-23) * 2^127
float fooFloat = 234.5f;
- // f o F indicano the la variabile e' di tipo float;
+ // f o F indicano the la variabile è di tipo float;
// altrimenti il valore viene considerato come double.
// Double - Numero in virgola mobile a 64 bit con precisione doppia (IEEE 754)
// 2^-1074 <= x <= (2-2^-52) * 2^1023
double fooDouble = 123.4;
- // Boolean - Puo' assumere il valore vero (true) o falso (false)
+ // Boolean - Può assumere il valore vero (true) o falso (false)
boolean fooBoolean = true;
boolean barBoolean = false;
@@ -118,26 +118,26 @@ public class LearnJava {
// Le variabili precedute da final possono essere inizializzate una volta sola,
final int HOURS_I_WORK_PER_WEEK = 9001;
- // pero' e' possibile dichiararle e poi inizializzarle in un secondo momento.
+ // però è possibile dichiararle e poi inizializzarle in un secondo momento.
final double E;
E = 2.71828;
// BigInteger - Interi a precisione arbitraria
//
- // BigInteger e' un tipo di dato che permette ai programmatori di
- // gestire interi piu' grandi di 64 bit. Internamente, le variabili
+ // BigInteger è un tipo di dato che permette ai programmatori di
+ // gestire interi più grandi di 64 bit. Internamente, le variabili
// di tipo BigInteger vengono memorizzate come un vettore di byte e
// vengono manipolate usando funzioni dentro la classe BigInteger.
//
- // Una variabile di tipo BigInteger puo' essere inizializzata usando
+ // Una variabile di tipo BigInteger può essere inizializzata usando
// un array di byte oppure una stringa.
BigInteger fooBigInteger = new BigDecimal(fooByteArray);
// BigDecimal - Numero con segno, immutabile, a precisione arbitraria
//
- // Una variabile di tipo BigDecimal e' composta da due parti: un intero
+ // Una variabile di tipo BigDecimal è composta da due parti: un intero
// a precisione arbitraria detto 'non scalato', e un intero a 32 bit
// che rappresenta la 'scala', ovvero la potenza di 10 con cui
// moltiplicare l'intero non scalato.
@@ -158,9 +158,9 @@ public class LearnJava {
// Stringhe
String fooString = "Questa e' la mia stringa!";
- // \n e' un carattere di escape che rappresenta l'andare a capo
+ // \n è un carattere di escape che rappresenta l'andare a capo
String barString = "Stampare su una nuova riga?\nNessun problema!";
- // \t e' un carattere di escape che aggiunge un tab
+ // \t è un carattere di escape che aggiunge un tab
String bazString = "Vuoi aggiungere un tab?\tNessun problema!";
System.out.println(fooString);
System.out.println(barString);
@@ -168,7 +168,7 @@ public class LearnJava {
// Vettori
// La dimensione di un array deve essere decisa in fase di
- // istanziazione. Per dichiarare un array si puo' fare in due modi:
+ // istanziazione. Per dichiarare un array si può fare in due modi:
// <tipoDato>[] <nomeVariabile> = new <tipoDato>[<dimensioneArray>];
// <tipoDato> <nomeVariabile>[] = new <tipoDato>[<dimensioneArray>];
int[] intArray = new int[10];
@@ -189,8 +189,8 @@ public class LearnJava {
System.out.println("intArray @ 1: " + intArray[1]); // => 1
// Ci sono altri tipo di dato interessanti.
- // ArrayList - Simili ai vettori, pero' offrono altre funzionalita',
- // e la loro dimensione puo' essere modificata.
+ // ArrayList - Simili ai vettori, però offrono altre funzionalità,
+ // e la loro dimensione può essere modificata.
// LinkedList - Si tratta di una lista linkata doppia, e come tale
// implementa tutte le operazioni del caso.
// Map - Un insieme di oggetti che fa corrispondere delle chiavi
@@ -207,7 +207,7 @@ public class LearnJava {
int i1 = 1, i2 = 2; // Dichiarazone multipla in contemporanea
- // L'aritmetica e' lineare.
+ // L'aritmetica è lineare.
System.out.println("1+2 = " + (i1 + i2)); // => 3
System.out.println("2-1 = " + (i2 - i1)); // => 1
System.out.println("2*1 = " + (i2 * i1)); // => 2
@@ -253,7 +253,7 @@ public class LearnJava {
///////////////////////////////////////
System.out.println("\n->Strutture di controllo");
- // La dichiarazione dell'If e'' C-like.
+ // La dichiarazione dell'If è C-like.
int j = 10;
if (j == 10){
System.out.println("Io vengo stampato");
@@ -328,18 +328,18 @@ public class LearnJava {
System.out.println("Risultato del costrutto switch: " + stringaMese);
// Condizioni brevi
- // Si puo' usare l'operatore '?' per un rapido assegnamento
+ // Si può usare l'operatore '?' per un rapido assegnamento
// o per operazioni logiche.
// Si legge:
- // Se (condizione) e' vera, usa <primo valore>, altrimenti usa <secondo valore>
+ // Se (condizione) è vera, usa <primo valore>, altrimenti usa <secondo valore>
int foo = 5;
String bar = (foo < 10) ? "A" : "B";
System.out.println("Se la condizione e' vera stampa A: "+bar);
- // Stampa A, perche' la condizione e' vera.
+ // Stampa A, perché la condizione è vera.
/////////////////////////////////////////
- // Convertire i tipi di tati e Typcasting
+ // Convertire i tipi di dati e Typecasting
/////////////////////////////////////////
// Convertire tipi di dati
@@ -397,16 +397,16 @@ class Bicicletta {
// Variabili della bicicletta
public int cadenza;
- // Public: Puo' essere richiamato da qualsiasi classe
+ // Public: Può essere richiamato da qualsiasi classe
private int velocita;
- // Private: e'' accessibile solo dalla classe dove e'' stato inizializzato
+ // Private: è accessibile solo dalla classe dove è stato inizializzato
protected int ingranaggi;
- // Protected: e'' visto sia dalla classe che dalle sottoclassi
+ // Protected: è visto sia dalla classe che dalle sottoclassi
String nome;
- // default: e'' accessibile sono all'interno dello stesso package
+ // default: è accessibile sono all'interno dello stesso package
// I costruttori vengono usati per creare variabili
- // Questo e'' un costruttore
+ // Questo è un costruttore
public Bicicletta() {
ingranaggi = 1;
cadenza = 50;
@@ -414,7 +414,7 @@ class Bicicletta {
nome = "Bontrager";
}
- // Questo e'' un costruttore che richiede parametri
+ // Questo è un costruttore che richiede parametri
public Bicicletta(int cadenza, int velocita, int ingranaggi, String nome) {
this.ingranaggi = ingranaggi;
this.cadenza = cadenza;
@@ -469,7 +469,7 @@ class Bicicletta {
}
} // Fine classe bicicletta
-// PennyFarthing e'' una sottoclasse della bicicletta
+// PennyFarthing è una sottoclasse della bicicletta
class PennyFarthing extends Bicicletta {
// (Sono quelle biciclette con un unica ruota enorme
// Non hanno ingranaggi.)
@@ -481,7 +481,7 @@ class PennyFarthing extends Bicicletta {
// Bisogna contrassegnre un medodo che si sta riscrivendo
// con una @annotazione
- // Per saperne di piu' sulle annotazioni
+ // Per saperne di più sulle annotazioni
// Vedi la guida: http://docs.oracle.com/javase/tutorial/java/annotations/
@Override
public void setIngranaggi(int ingranaggi) {
@@ -518,8 +518,8 @@ class Frutta implements Commestibile, Digestibile {
}
}
-//In Java si puo' estendere solo una classe, ma si possono implementare
-//piu' interfaccie, per esempio:
+//In Java si può estendere solo una classe, ma si possono implementare
+//più interfaccie, per esempio:
class ClasseEsempio extends AltraClasse implements PrimaInterfaccia, SecondaInterfaccia {
public void MetodoPrimaInterfaccia() {
diff --git a/it-it/javascript-it.html.markdown b/it-it/javascript-it.html.markdown
new file mode 100644
index 00000000..1d776535
--- /dev/null
+++ b/it-it/javascript-it.html.markdown
@@ -0,0 +1,617 @@
+---
+language: javascript
+contributors:
+ - ["Leigh Brenecki", "https://leigh.net.au"]
+ - ["Ariel Krakowski", "http://www.learneroo.com"]
+translators:
+ - ["vinniec", "https://github.com/vinniec"]
+filename: javascript-it.js
+lang: it-it
+---
+
+JavaScript è stato creato da Netscape di Brendan Eich nel 1995. È stato originariamente pensato come un semplice linguaggio di scripting per i siti web, complementare all'uso di java per applicazioni più complesse ma la sua stretta integrazione con le pagine Web e il supporto integrato con esse ha causato il suo divenire più comune di Java per i frontend web.
+
+Tuttavia JavaScript non è semplicemente limitato ai web browser: Node.js è un progetto che fornisce una runtime standalone dell'engine JavaScript V8 per Google Chrome, sta diventando sempre più popolare.
+
+JavaScript ha una sintassi C-like, quindi se usate linguaggi come C o Java, molta della sintassi di base sarà già familiare. A dispetto di questo, e a dispetto del nome similare, il modello a oggetti di JavaScript è significativamente diverso da quello di Java.
+
+```js
+// I commenti a singola linea iniziano con due slash.
+/* I commenti multilinea cominciano con uno slash e un asterisco,
+ e terminano con un asterisco e uno slash */
+
+// Le istruzioni possono essere terminate con ;
+doStuff();
+
+// ... ma non devono esserci per forza, i punti e virgola vengono automaticamente inseriti
+// dove c'è un newline, ad eccezione di alcuni casi.
+doStuff()
+
+// Poiché questi casi possono causare risultati inaspettati, noi continueremo ad usare
+// i punti e virgola in questa guida.
+
+///////////////////////////////////
+// 1. Numeri, Stringe e Operatori
+
+// JavaScript ha un tipo numero (che è a 64-bit IEEE 754 double).
+// Double ha una mantissa di 52-bit che è abbastanza per memorizzare interi
+// fino a 9x10¹⁵ per essere precisi.
+3; // = 3
+1.5; // = 1.5
+
+// Alcuni lavori aritmetici di base come ci si può aspettare.
+1 + 1; // = 2
+0.1 + 0.2; // = 0.30000000000000004
+8 - 1; // = 7
+10 * 2; // = 20
+35 / 5; // = 7
+
+// inclusa la divisione con la virgola.
+5 / 2; // = 2.5
+
+// E il modulo.
+10 % 2; // = 0
+30 % 4; // = 2
+18.5 % 7; // = 4.5
+
+// Anche le operazioni binarie funzionano; quando effettuate una operazione binaria il vostro numero decimale
+// è convertito in un intero con segno *fino a* 32 bit..
+1 << 2; // = 4
+
+// Le precedenza è subordinata dalle parentesi.
+(1 + 3) * 2; // = 8
+
+// Ci sono tre valori speciali che non sono numeri reali:
+Infinity; // ad esempio il risultato di 1/0
+-Infinity; // ad esempio il risultato di -1/0
+NaN; // ad esempio il risultato di 0/0, sta per 'Not a Number'
+
+// Ci sono anche i tipi booleani.
+true;
+false;
+
+// Le stringe sono create con ' oppure ".
+'abc';
+"Hello, world";
+
+// La negazione usa il ! simbolo
+!true; // = false
+!false; // = true
+
+// L'uguaglianza è ===
+1 === 1; // = true
+2 === 1; // = false
+
+// L'inuguaglianza è !==
+1 !== 1; // = false
+2 !== 1; // = true
+
+// Altre comparazioni
+1 < 10; // = true
+1 > 10; // = false
+2 <= 2; // = true
+2 >= 2; // = true
+
+// Le stringhe si concatenano con il +
+"Hello " + "world!"; // = "Hello world!"
+
+// ... che funziona con qualcosa in più delle semplici stringhe
+"1, 2, " + 3; // = "1, 2, 3"
+"Hello " + ["world", "!"]; // = "Hello world,!"
+
+// e sono comparate con < e >
+"a" < "b"; // = true
+
+// La comparazione con conversione implicita si fa con il doppio uguale...
+"5" == 5; // = true
+null == undefined; // = true
+
+// ...ammenoché non si usi ===
+"5" === 5; // = false
+null === undefined; // = false
+
+// ...che può provocare strani comportamenti...
+13 + !0; // 14
+"13" + !0; // '13true'
+
+// Si può accedere ai caratteri di una stringa con `charAt`
+"This is a string".charAt(0); // = 'T'
+
+// ...o usando le `substring` per ottenere una parte.
+"Hello world".substring(0, 5); // = "Hello"
+
+// `length` è una proprietà, quindi non usate le ().
+"Hello".length; // = 5
+
+// Ci sono anche `null` e `undefined`.
+null; // usato per indicato deliberatamente un non-valore
+undefined; // usato per indicare un valore che attualmente non è presente (sebbene
+ // `undefined` sia un valore a sua stessa volta)
+
+// false, null, undefined, NaN, 0 e "" sono falsi; tutto il resto è vero.
+// Notare che 0 è falso e "0" è vero, nonostante 0 == "0".
+
+///////////////////////////////////
+// 2. Variabili, Array e Oggetti
+
+// Le variabili sono dichiarate con la parola chiave `var`. JavaScript è tipato
+// dinamicamente, quindi non serve specificare il tipo. L'assegnamento usa un carattere `=`
+// singolo.
+var someVar = 5;
+
+// Se si toglie la parola chiave var non si otterrà un errore...
+someOtherVar = 10;
+
+// ...ma la tua variabile sarà creata con visibilità globale e non
+// nel blocco dove la si è definita.
+
+// Le variabili dichiarate senza essere definite vengono impostate come undefined.
+var someThirdVar; // = undefined
+
+// Se si vuole dichiarare una coppia di variabili, lo si può fare usando una virgola
+// come separatore
+var someFourthVar = 2, someFifthVar = 4;
+
+// C'è una scorciatoia per effettuare operazioni matematiche sulle variabili:
+someVar += 5; // equivalente di someVar = someVar + 5; someVar vale 10 ora
+someVar *= 10; // ora someVar è 100
+
+// e un ulteriore scorciatoia per aggiungere o sottrarre 1
+someVar++; // ora someVar è 101
+someVar--; // di nuovo 100
+
+// Gli array sono liste ordinati di valori, di qualsiasi tipo.
+var myArray = ["Hello", 45, true];
+
+// Si può accedere ai loro membri usando la sintassi sottoscritta con le parentesi quadra.
+// Gli indici degli array iniziano a zero.
+myArray[1]; // = 45
+
+// Gli Array sono mutabili e di dimensione variabile.
+myArray.push("World");
+myArray.length; // = 4
+
+// Aggiungere/Modificare in un indice preciso
+myArray[3] = "Hello";
+
+// Aggiungere e rimovere un elemento dall'inizio o dalla fine di un array
+myArray.unshift(3); // Aggiungere come primo elemento
+someVar = myArray.shift(); // Rimuovere il primo elemento e restituirlo
+myArray.push(3); // Aggiungere come ultimo elemento
+someVar = myArray.pop(); // Rimuovere l'ultimo elemento e restituirlo
+
+// Unire tutti gli elementi di un array con un punto e virgola
+var myArray0 = [32,false,"js",12,56,90];
+myArray0.join(";") // = "32;false;js;12;56;90"
+
+// Ottenere un subarray di elementi dall'indice 1 (incluso) al 4 (escluso)
+myArray0.slice(1,4); // = [false,"js",12]
+
+// Rimuovere 4 elementi partendo dall'indice 2 e inserirci delle stringhe
+// "hi","wr" e "ld"; restituiscono i subarray rimossi
+myArray0.splice(2,4,"hi","wr","ld"); // = ["js",12,56,90]
+// myArray0 === [32,false,"hi","wr","ld"]
+
+// Gli oggetti di JavaScript sono equivalenti ai "dizionari" o "mappe" in altri
+// linguaggi: una collezione non ordinata di coppie di chiave-valore.
+var myObj = {key1: "Hello", key2: "World"};
+
+// Le chiavi sono stringhe, ma non è necessario quotarle se sono identificatori
+// JavaScript validi. I valori possono essere di ogni tipo.
+var myObj = {myKey: "myValue", "my other key": 4};
+
+// Gli attributi degli oggetti possono essere acceduti usando la sintassi "subscript",
+myObj["my other key"]; // = 4
+
+// ... o usando la notazione puntata fornendo una chiave che sia un identificatore valido.
+myObj.myKey; // = "myValue"
+
+// Gli oggetti sono mutabilil; i valori possono essere cambiati e nuove chiavi possono essere aggiunte.
+myObj.myThirdKey = true;
+
+// se si prova ad accedere ad un valore che non è stato ancora impostato, si otterrà undefined.
+myObj.myFourthKey; // = undefined
+
+///////////////////////////////////
+// 3. Strutture logiche e di controllo.
+
+// La struttura `if` funziona come ci si aspetta.
+var count = 1;
+if (count == 3){
+ // eseguito se count vale 3
+} else if (count == 4){
+ // eseguito se count vale 4
+} else {
+ // eseguito se count non è né 3 e né 4
+}
+
+// Così come il `while`.
+while (true){
+ // Un ciclo infinito!
+}
+
+// I cicli do-while sono come i cicli while ad eccezione che loro iterano almeno una volta.
+var input;
+do {
+ input = getInput();
+} while (!isValid(input));
+
+// Il ciclo `for` è lo stesso di C e di Java:
+// inizializzazione, condizione di proseguimento; iterazione.
+for (var i = 0; i < 5; i++){
+ // verrà eseguito 5 volte
+}
+
+// Uscire forzatamente da un un ciclo etichettato è simile a java:
+outer:
+for (var i = 0; i < 10; i++) {
+ for (var j = 0; j < 10; j++) {
+ if (i == 5 && j ==5) {
+ break outer;
+ // esce fuori dal ciclo outer invece che solo da quello più interno
+ }
+ }
+}
+
+// L'istruzione for/in permette l'iterazione sulle proprietà di un oggetto.
+var description = "";
+var person = {fname:"Paul", lname:"Ken", age:18};
+for (var x in person){
+ description += person[x] + " ";
+} // description = 'Paul Ken 18 '
+
+// L'istruzione for/of permette l'iterazione su oggetti iterabili (inclusi i built-in String,
+// Array, es. gli argomenti Array-like o gli oggetti NodeList, TypedArray, Map e Set,
+// e gli iterabili decisi dall'utente).
+var myPets = "";
+var pets = ["cat", "dog", "hamster", "hedgehog"];
+for (var pet of pets){
+ myPets += pet + " ";
+} // myPets = 'cat dog hamster hedgehog '
+
+// && è la congiunzione logica, || è la disgiunione logica
+if (house.size == "big" && house.colour == "blue"){
+ house.contains = "bear";
+}
+if (colour == "red" || colour == "blue"){
+ // i colori sono sia rossi che blu
+}
+
+// && e || "short circuit", utili per impostare i valori di default.
+var name = otherName || "default";
+
+// L'istruzione `switch` controlla l'uguaglianza con `===`.
+// Usare 'break' dopo ogni caso
+// oppure i casi dopo quello corretto verranno eseguiti comunque.
+grade = 'B';
+switch (grade) {
+ case 'A':
+ console.log("Great job");
+ break;
+ case 'B':
+ console.log("OK job");
+ break;
+ case 'C':
+ console.log("You can do better");
+ break;
+ default:
+ console.log("Oy vey");
+ break;
+}
+
+
+///////////////////////////////////
+// 4. Funzioni, Visibilità e Closure
+
+// Le funzioni di JavaScript sono dichiarate con la parolachiave `function`.
+function myFunction(thing){
+ return thing.toUpperCase();
+}
+myFunction("foo"); // = "FOO"
+
+// Nota che il valore da restituire deve iniziare nella stessa riga della
+// keyword `return`, altrimenti verrà sempre restituito `undefined` per via due to
+// dell'inserimento automatico dei punti e virgola. Fare attenzione a questo quando si usa lo stile Allman.
+function myFunction(){
+ return // <- punto e virgola automaticamente inserito qui
+ {thisIsAn: 'object literal'};
+}
+myFunction(); // = undefined
+
+// Le funzioni di JavaScript sono oggetti di prima classe, quindi possono essere riassegnate
+// a diversi nomi di variabili e passate ad altre funzioni come argomenti - per esempio,
+// mentre si fornisce un gestore di eventi:
+function myFunction(){
+ // questo codice sarà chiamato in 5 secondi
+}
+setTimeout(myFunction, 5000);
+// Nota: setTimeout non è parte del linguaggio JS, ma è fornito dai browser
+// e da Node.js.
+
+// Un altra funzione fornita dai browser è setInterval
+function myFunction(){
+ // questo codice verrà chiamato ogni 5 secondi
+}
+setInterval(myFunction, 5000);
+
+// Gli oggetti funzione non devono essere dichiarati con un nome - potete scrivere
+// la definizione di una funzione anonima direttamente come argomento di un'altra.
+setTimeout(function(){
+ // questo codice sarà chiamato in 5 secondi
+}, 5000);
+
+// In JavaScript le funzioni hanno una propria visibilità; le funzioni hanno
+// il loro scope ma gli altri blocchi no.
+if (true){
+ var i = 5;
+}
+i; // = 5 - non è undefined come ci si potrebbe aspettare in un linguaggio con una propria visibilità per blocco
+
+// Questo ha portato ad un pattern comune di "esecuzione immediata di funzioni
+// anonime", che previene alle variabili temporanee di finire nella
+// visibilità globale.
+(function(){
+ var temporary = 5;
+ // Noi possiamo accedere alla visibilità globale assegnando all' "oggetto globale", che
+ // in un browser web è sempre `windows`. L'oggetto globale potrebbe avere
+ // nomi differenti in ambienti diverso dal browser come Node.js.
+ window.permanent = 10;
+})();
+temporary; // solleva ReferenceError
+permanent; // = 10
+
+// Una delle più potenti caratteristiche di javascript sono le closure. Se una funzione è
+// definita dentro un'altra funzione, la funzione interna ha accesso a le variabili
+// della funzione esterna, anche dopo essere uscita dalla funzione esterna.
+function sayHelloInFiveSeconds(name){
+ var prompt = "Hello, " + name + "!";
+ // Le funzioni interne sono messe nella visibilità locale in modo predefinito, anche se vengono
+ // dichiarate con `var`.
+ function inner(){
+ alert(prompt);
+ }
+ setTimeout(inner, 5000);
+ // setTimeout è asincrono, quindi la funzione sayHelloInFiveSeconds
+ // esce immediatamente e setTimeout chiamera inner successivamente. Tuttavia,
+ // poiché inner è "chiuso prima" di sayHelloInFiveSeconds, inner ha ancora
+ // accesso alla variabile `prompt` quando viene finalmente richiamato.
+}
+sayHelloInFiveSeconds("Adam"); // aprirà un popup con "Hello, Adam!" in 5s
+
+///////////////////////////////////
+// 5. Di più sugli oggetti, costruttori e prototipi.
+
+// Gli oggetti possono contenere funzioni.
+var myObj = {
+ myFunc: function(){
+ return "Hello world!";
+ }
+};
+myObj.myFunc(); // = "Hello world!"
+
+// Quando una funzione contenuta in un oggetto viene chiamata, essa può accedere a questo oggetto
+// possono farlo usando la parola chiave `this`.
+myObj = {
+ myString: "Hello world!",
+ myFunc: function(){
+ return this.myString;
+ }
+};
+myObj.myFunc(); // = "Hello world!"
+
+// Questo ha a che fare con come la funzione è chiamata, non con dove
+// è definita. Quindi, la nostra funzione non funziona se non è chiamata
+// nel contesto dell'oggetto.
+var myFunc = myObj.myFunc;
+myFunc(); // = undefined
+
+// Al contrario, una funzione può essere assegnata ad un oggetto e poi accedere ad esso
+// attraverso `this`, anche se non è stata inserita durante la definizione.
+var myOtherFunc = function(){
+ return this.myString.toUpperCase();
+};
+myObj.myOtherFunc = myOtherFunc;
+myObj.myOtherFunc(); // = "HELLO WORLD!"
+
+// Possiamo anche specificare un contesto per una funzione da eseguire quando la invochiamo
+// usando `call` o `apply`.
+
+
+var anotherFunc = function(s){
+ return this.myString + s;
+};
+anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!"
+
+// La funzione `apply` è quasi identica, ma prende un array come lista
+// di argomenti.
+
+anotherFunc.apply(myObj, [" And Hello Sun!"]); // = "Hello World! And Hello Sun!"
+
+// Questo è utile quanso si lavora con una funzione che accetta una sequenza di
+// argomenti e si vuole passare un array.
+
+Math.min(42, 6, 27); // = 6
+Math.min([42, 6, 27]); // = NaN (uh-oh!)
+Math.min.apply(Math, [42, 6, 27]); // = 6
+
+// Ma, `call` e `apply` sono solo temporanei. Quando vogliamo incollarli, possiamo
+// usare `bind`
+
+var boundFunc = anotherFunc.bind(myObj);
+boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!"
+
+// `bind` può essere anche usato per applicare parzialmente (curry) una funzione.
+
+var product = function(a, b){ return a * b; };
+var doubler = product.bind(this, 2);
+doubler(8); // = 16
+
+// Quando si chiama una funzione con la parola chiave `new`, un nuovo oggetto viene creato
+// e reso disponibile alla funzione attraverso la parola chiave `this`. Le funzioni progettate per essere
+// invocate in questo modo sono chiamate costruttrici.
+
+var MyConstructor = function(){
+ this.myNumber = 5;
+};
+myNewObj = new MyConstructor(); // = {myNumber: 5}
+myNewObj.myNumber; // = 5
+
+// Diversamente dalla molti degli altri linguaggi orientati agli oggetti, Javascript non ha
+// il concetto di 'istanze' create sull'impronta di una 'classe'; invece Javascript
+// combina l'instanziamento e l'ereditarietà in un singolo concetto: il 'prototipo'.
+
+// Ogni oggetto Javascript ha un 'prototipo'. Quando si cerca di accedere a una proprietà
+// su un oggetto che non la contiene, l'interprete
+// guarderà i suoi prototipi.
+
+// Alcune implementazioni di JS faranno accedere al propotipo di un oggetto con la proprietà
+// magica `__proto__`: Anche se questo è utile per spiegare i prototipi, non è
+// parte dello standard; capiremo più avanti come usare i prototipi in modo standard.
+var myObj = {
+ myString: "Hello world!"
+};
+var myPrototype = {
+ meaningOfLife: 42,
+ myFunc: function(){
+ return this.myString.toLowerCase();
+ }
+};
+
+myObj.__proto__ = myPrototype;
+myObj.meaningOfLife; // = 42
+
+// Questo funziona anche per le funzioni.
+myObj.myFunc(); // = "hello world!"
+
+// Ovviamente, se la proprietà non è nel prototipo, il prototipo
+// del prototipo viene ricercato, e così via.
+myPrototype.__proto__ = {
+ myBoolean: true
+};
+myObj.myBoolean; // = true
+
+// Non c'è nessuna copia coinvolta qui; ogni oggetto mantiene una referenza al suo
+// prototipo. Questo significa che possiamo modificare il prototipo e i nostri cambiamenti
+// si rifletteranno da ogni parte.
+myPrototype.meaningOfLife = 43;
+myObj.meaningOfLife; // = 43
+
+// L'istruzione for/in permette di iterare sulle proprietà di un oggetto,
+// risalendo la catena dei prototipi finché non trova un prototipo null.
+for (var x in myObj){
+ console.log(myObj[x]);
+}
+///stampa:
+// Hello world!
+// 43
+// [Function: myFunc]
+// true
+
+// Per considerare solamente le proprietà inserite nell'oggetto stesso
+// e non i loro prototipi, usare il check `hasOwnProperty()`.
+for (var x in myObj){
+ if (myObj.hasOwnProperty(x)){
+ console.log(myObj[x]);
+ }
+}
+///stampa:
+// Hello world!
+
+// Abbiamo menzionato che `__proto__` non è standard, e non c'è nessun modo standard per
+// cambiare il prototipo di un oggetto esistente. Tuttavia, ci sono due strade per
+// creare un nuovo oggetto con un dato prototipo.
+
+// La prima è Object.create, che è una recente aggiunta a JS, e che quindi
+// non è disponibile ancora in tutte le implementazioni.
+var myObj = Object.create(myPrototype);
+myObj.meaningOfLife; // = 43
+
+// La seconda strada, che funziona ovunque, ha a che fare con i costruttori.
+// I costruttori hanno una proprietà chiamata prototype. Questo *non* è il prototipo del
+// costruttore della stessa funzione; invece è il prototipo del nuovo oggetto
+// che gli viene conferito alla creazione con quel costruttore e la parola chiave new.
+MyConstructor.prototype = {
+ myNumber: 5,
+ getMyNumber: function(){
+ return this.myNumber;
+ }
+};
+var myNewObj2 = new MyConstructor();
+myNewObj2.getMyNumber(); // = 5
+myNewObj2.myNumber = 6;
+myNewObj2.getMyNumber(); // = 6
+
+// I tipi built-in come stringhe e numeri hanno anche costruttori che creano
+// oggetti wrapper equivalenti.
+var myNumber = 12;
+var myNumberObj = new Number(12);
+myNumber == myNumberObj; // = true
+
+// Eccezione, loro non sono esattamente equivalenti.
+typeof myNumber; // = 'number'
+typeof myNumberObj; // = 'object'
+myNumber === myNumberObj; // = false
+if (0){
+ // Questo codice non verrà eseguito perchè 0 è falso.
+}
+if (new Number(0)){
+ // Questo codice verrà eseguito poiché i numeri wrappati sono oggetti e gli oggetti
+ // sono sempre veri.
+}
+
+// Tuttavia, gli oggetti wrapper e i regolari built-in condividono un prototipo, quindi
+// si possono aggiungere funzionalità ad una stringa, per esempio.
+String.prototype.firstCharacter = function(){
+ return this.charAt(0);
+};
+"abc".firstCharacter(); // = "a"
+
+// Questa caratteristica viene spesso usata nel "polyfilling", che implementa nuovi
+// aspetti in un vecchio sottoinsieme di JavaScript, in modo che si possano
+// usare in vecchi ambienti come browser non aggiornati.
+
+// Per esempio, abbiamo menzionato che Object.create non è disponibile in tutte le
+// implementazioni, ma possiamo ancora usarlo con questo polyfill:
+if (Object.create === undefined){ // non lo sovrascrive se esiste già
+ Object.create = function(proto){
+ // crea un costruttore temporaneo con il giusto prototipo
+ var Constructor = function(){};
+ Constructor.prototype = proto;
+ // quindi lo usa per creare un nuovo, propriamente-prototipato oggetto
+ return new Constructor();
+ };
+}
+```
+
+## Approfondimenti
+
+Il [Mozilla Developer Networ][1] fornisce una documentazione eccellente su come Javascript è utilizzato nei browsers. In più è un wiki, quindi si può imparare di più aiutando gli altri condividendo la propria conoscenza.
+
+MDN's [A re-introduction to JavaScript][2] copre molti dei concetti qui trattati in maggiore dettaglio. Questa guida ha deliberatamente coperto solamente il linguaggio JavaScript; se volete sapere di più su come usare JavaScript in una pagina web, iniziate leggendo il [Document Object Model][3].
+
+[Learn Javascript by Example and with Challenges][4] è una variante di questo referenziario con integrate delle sfide.
+
+[Javascript Garden][5] è una guida approfondita di tutte le parti controintuitive del linguaggio.
+
+[JavaScript: The Definitive Guide][6] è una guida classica e referenziario.
+
+[Eloqunt Javascript][8] di Marijn Haverbeke è un ottimo libro/ebook JS con terminale annesso
+
+[Javascript: The Right Way][10] è una guida dedicata all'introduzione dei nuovi sviluppatori a JavaScript e come aiuto agli sviluppatori esperti per imparare di più sulle best practice.
+
+[Javascript:info][11] è un moderno tutorial su javascript che copre le basi (linguaggio principale e lavorazione con un browser) come anche argomenti avanzati con spiegazioni concise.
+
+
+In aggiunta ai contributori di questo articolo, alcuni contenuti sono adattati dal Louie Dinh's Python tutorial su questo sito, e da [JS Tutorial][7] sul Mozilla Developer Network.
+
+
+[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript
+[2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
+[3]: https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core
+[4]: http://www.learneroo.com/modules/64/nodes/350
+[5]: http://bonsaiden.github.io/JavaScript-Garden/
+[6]: http://www.amazon.com/gp/product/0596805527/
+[7]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
+[8]: http://eloquentjavascript.net/
+[10]: http://jstherightway.org/
+[11]: https://javascript.info/
diff --git a/it-it/jquery-it.html.markdown b/it-it/jquery-it.html.markdown
new file mode 100644
index 00000000..811c5c3a
--- /dev/null
+++ b/it-it/jquery-it.html.markdown
@@ -0,0 +1,131 @@
+---
+category: tool
+tool: jquery
+contributors:
+ - ["Sawyer Charles", "https://github.com/xssc"]
+filename: jquery-it.js
+translators:
+ - ["Ale46", "https://github.com/ale46"]
+lang: it-it
+---
+
+jQuery è una libreria JavaScript che ti aiuta a "fare di più, scrivendo meno". Rende molte attività comuni di JavaScript più facili da scrivere. jQuery è utilizzato da molte grandi aziende e sviluppatori in tutto il mondo. Rende AJAX, gestione degli eventi, manipolazione dei documenti e molto altro, più facile e veloce.
+
+Visto che jQuery è una libreria JavaScript dovresti prima [imparare JavaScript](https://learnxinyminutes.com/docs/javascript/)
+
+```js
+
+
+///////////////////////////////////
+// 1. Selettori
+
+// I selettori in jQuery vengono utilizzati per selezionare un elemento
+var page = $(window); // Seleziona l'intera finestra
+
+// I selettori possono anche essere selettori CSS
+var paragraph = $('p'); // Seleziona tutti gli elementi del paragrafo
+var table1 = $('#table1'); // Seleziona elemento con id 'table1'
+var squares = $('.square'); // Seleziona tutti gli elementi con la classe 'square'
+var square_p = $('p.square') // Seleziona i paragrafi con la classe 'square'
+
+
+///////////////////////////////////
+// 2. Eventi ed effetti
+// jQuery è molto bravo a gestire ciò che accade quando un evento viene attivato
+// Un evento molto comune è l'evento "pronto" sul documento
+// Puoi usare il metodo 'ready' per aspettare che l'elemento abbia finito di caricare
+$(document).ready(function(){
+ // Il codice non verrà eseguito fino a quando il documento non verrà caricato
+});
+// Puoi anche usare funzioni definite
+function onAction() {
+ // Questo viene eseguito quando l'evento viene attivato
+}
+$('#btn').click(onAction); // Invoca onAction al click
+
+// Alcuni altri eventi comuni sono:
+$('#btn').dblclick(onAction); // Doppio click
+$('#btn').hover(onAction); // Al passaggio del mouse
+$('#btn').focus(onAction); // Al focus
+$('#btn').blur(onAction); // Focus perso
+$('#btn').submit(onAction); // Al submit
+$('#btn').select(onAction); // Quando un elemento è selezionato
+$('#btn').keydown(onAction); // Quando un tasto è premuto (ma non rilasciato)
+$('#btn').keyup(onAction); // Quando viene rilasciato un tasto
+$('#btn').keypress(onAction); // Quando viene premuto un tasto
+$('#btn').mousemove(onAction); // Quando il mouse viene spostato
+$('#btn').mouseenter(onAction); // Il mouse entra nell'elemento
+$('#btn').mouseleave(onAction); // Il mouse lascia l'elemento
+
+
+// Questi possono anche innescare l'evento invece di gestirlo
+// semplicemente non passando alcun parametro
+$('#btn').dblclick(); // Innesca il doppio click sull'elemento
+
+// Puoi gestire più eventi mentre usi il selettore solo una volta
+$('#btn').on(
+ {dblclick: myFunction1} // Attivato con doppio clic
+ {blur: myFunction1} // Attivato al blur
+);
+
+// Puoi spostare e nascondere elementi con alcuni metodi di effetto
+$('.table').hide(); // Nascondi gli elementi
+
+// Nota: chiamare una funzione in questi metodi nasconderà comunque l'elemento
+$('.table').hide(function(){
+ // Elemento nascosto quindi funzione eseguita
+});
+
+// È possibile memorizzare selettori in variabili
+var tables = $('.table');
+
+// Alcuni metodi di manipolazione dei documenti di base sono:
+tables.hide(); // Nascondi elementi
+tables.show(); // Mostra elementi
+tables.toggle(); // Cambia lo stato nascondi/mostra
+tables.fadeOut(); // Fades out
+tables.fadeIn(); // Fades in
+tables.fadeToggle(); // Fades in o out
+tables.fadeTo(0.5); // Dissolve in opacità (tra 0 e 1)
+tables.slideUp(); // Scorre verso l'alto
+tables.slideDown(); // Scorre verso il basso
+tables.slideToggle(); // Scorre su o giù
+
+// Tutti i precedenti prendono una velocità (millisecondi) e la funzione di callback
+tables.hide(1000, myFunction); // nasconde l'animazione per 1 secondo quindi esegue la funzione
+
+// fadeTo ha un'opacità richiesta come secondo parametro
+tables.fadeTo(2000, 0.1, myFunction); // esegue in 2 sec. il fade sino ad una opacità di 0.1 opacity e poi la funzione
+
+// Puoi ottenere un effetti più avanzati con il metodo animate
+tables.animate({margin-top:"+=50", height: "100px"}, 500, myFunction);
+// Il metodo animate accetta un oggetto di css e valori con cui terminare,
+// parametri opzionali per affinare l'animazione,
+// e naturalmente la funzione di callback
+
+///////////////////////////////////
+// 3. Manipolazione
+
+// Questi sono simili agli effetti ma possono fare di più
+$('div').addClass('taming-slim-20'); // Aggiunge la classe taming-slim-20 a tutti i div
+
+// Metodi di manipolazione comuni
+$('p').append('Hello world'); // Aggiunge alla fine dell'elemento
+$('p').attr('class'); // Ottiene l'attributo
+$('p').attr('class', 'content'); // Imposta l'attributo
+$('p').hasClass('taming-slim-20'); // Restituisce vero se ha la classe
+$('p').height(); // Ottiene l'altezza dell'elemento o imposta l'altezza
+
+
+// Per molti metodi di manipolazione, ottenere informazioni su un elemento
+// restituirà SOLO il primo elemento corrispondente
+$('p').height(); // Ottiene solo la prima altezza del tag 'p'
+
+// È possibile utilizzare each per scorrere tutti gli elementi
+var heights = [];
+$('p').each(function() {
+ heights.push($(this).height()); // Aggiunge tutte le altezze del tag 'p' all'array
+});
+
+
+```
diff --git a/it-it/json-it.html.markdown b/it-it/json-it.html.markdown
index 379bad73..e1e16c42 100644
--- a/it-it/json-it.html.markdown
+++ b/it-it/json-it.html.markdown
@@ -1,5 +1,6 @@
---
language: json
+filename: learnjson-it.json
contributors:
- ["Anna Harren", "https://github.com/iirelu"]
- ["Marco Scannadinari", "https://github.com/marcoms"]
diff --git a/it-it/logtalk-it.html.markdown b/it-it/logtalk-it.html.markdown
new file mode 100644
index 00000000..5cc53e6f
--- /dev/null
+++ b/it-it/logtalk-it.html.markdown
@@ -0,0 +1,553 @@
+---
+language: Logtalk
+filename: learnlogtalk-it.lgt
+contributors:
+ - ["Paulo Moura", "http://github.com/pmoura"]
+translators:
+ - ["Ugo Chirico", "https://github.com/ugochirico"]
+lang: it-it
+---
+
+Logtalk è un linguaggio di programmazione logica orientata agli oggetti che estende il linguaggio Prolog con le moderne tecniche di Object-Oriented Programming quali incapsulamento, ereditarietà e riutilizzo del codice, senza compromettere le caratteristiche di programmazione dichiarativa del Prolog. Logtalk è implementato in codice altamente portabile e utilizza i più moderni standard di conformità del Prolog rispetto al compilatore backend.
+
+Per mantenere una dimensione ragionevole, questo tutorial presuppone necessariamente che il lettore abbia una conoscenza del linguaggio Prolog ed è inoltre focalizzato esclusivamente sulla descrizione delle caratteristiche object-oriented di Logtalk.
+
+# Sintassi
+
+Logtalk utilizza la sintassi standard del linguaggio Prolog con l'aggiunta di un paio di operatori e di alcune direttive per una curva di apprendimento morbida e per assicurare ampia portabilità. Una conseguenza importante è che il codice Prolog può essere facilmente incapsulato in oggetti con poche o nessuna modifica. Inoltre, Logtalk può interpretare come oggetti Logtalk, in modo trasparente, la maggior parte dei moduli Prolog già esistenti.
+
+I principali operatori sono:
+
+* `::/2` - per inviare un messaggio ad un oggetto
+* `::/1` - per inviare un messaggio a se stesso _self_ (cioè all'oggetto che riceverà il messaggio)
+* `^^/1` - _super_ per chiamare un predicato ereditato o importato
+
+Alcune delle più importanti entità e direttive saranno introdotte nelle sezioni successive.
+
+# Entità e Ruoli
+
+Logtalk tratta gli oggetti, i protocolli e le categorie come entità di prima classe. I rapporti tra le entità definiscono i _patterns of code reuse_ ossia i modelli di riutilizzo del codice e i _roles_ ossia i ruoli svolti da tali entità. Ad esempio, quando un oggetto istanzia un altro oggetto, il primo oggetto assume il ruolo di istanza e il secondo oggetto assume il ruolo di classe. Una relazione di tipo _extends_ tra due oggetti implica che entrambi gli oggetti svolgano il ruolo di prototipi, in cui uno di loro estende l'altro, che diventa quindi suo prototipo padre.
+
+# Definizione di un oggetto
+
+Un oggetto incapsula le dichiarazioni e le definizioni dei predicati. Gli oggetti possono essere creati in modo dinamico, ma di solito sono dichiarati come statici e definiti nel codice sorgente. Un singolo file sorgente può contenere un qualsiasi numero di definizioni di entità. Ecco un semplice oggetto `list` che definisce un membro pubblico `member/2`:
+
+```logtalk
+:- object(list).
+
+ :- public(member/2).
+ member(Head, [Head| _]).
+ member(Head, [_| Tail]) :-
+ member(Head, Tail).
+
+:- end_object.
+```
+
+# Compilazione e il caricamento dei file sorgenti
+
+Supponendo che il codice di cui sopra per l'oggetto `list` venga salvato in un file` list.lgt`, esso può essere compilato e caricato utilizzando il predicato predefiniti `logtalk_load/1` o la sua abbreviazione `{}/1`, con il percorso del file come argomento (l'estensione può essere omessa):
+
+```logtalk
+?- {list}.
+yes
+```
+
+In generale, le entità potrebbero avere dipendenze sulle entità definite in altri file di origine (ad esempio le entità di biblioteca). Per caricare un file e tutte le sue dipendenze, la soluzione consigliata consiste nel definire un file _loader_ che carica tutti i file necessari per un'applicazione. Un file loader è semplicemente un file di origine, in genere denominato `loader.lgt`, che effettua chiamate ai predicati built-in `logtalk_load/1-2`, di solito
+da una direttiva `initialization/1` per la portabilità e conformità agli standard. Caricatore file vengono forniti per tutte le librerie, strumenti ed esempi.
+
+# Inviare un messaggio ad un oggetto
+
+L'operatore infisso `::/2` è usato per inviare messaggi ad un oggetto. Analogamente al Prolog, è possibile fare backtracking per le soluzioni alternative:
+
+```logtalk
+?- list::member(X, [1,2,3]).
+X = 1 ;
+X = 2 ;
+X = 3
+yes
+```
+
+Analogamente alla programmazione object-oriented, logtalk consente anche l'Incapsulamento.
+Un predicato può essere dichiarata pubblico, protetto o privato. Può anche essere _local_ quando non esiste una direttiva specifica per esso all'interno dello scope. Per esempio:
+
+```logtalk
+:- object(scopes).
+
+ :- private(bar/0).
+ bar.
+
+ local.
+
+:- end_object.
+```
+
+Assumendo che l'oggetto è salvato nel file `scopes.lgt`:
+
+```logtalk
+?- {scopes}.
+yes
+
+?- catch(scopes::bar, Error, true).
+Error = error(
+ permission_error(access, private_predicate, bar/0),
+ logtalk(scopes::bar, user)
+)
+yes
+
+?- catch(scopes::local, Error, true).
+Error = error(
+ existence_error(predicate_declaration, local/0),
+ logtalk(scopes::local, user)
+)
+yes
+```
+
+Quando il predicato in un messaggio non è noto per l'oggetto (il ruolo dell'oggetto determina le procedure di ricerca), si ha un errore.
+Per esempio:
+
+```logtalk
+?- catch(scopes::unknown, Error, true).
+Error = error(
+ existence_error(predicate_declaration, unknown/0),
+ logtalk(scopes::unknown, user)
+)
+yes
+```
+
+Un punto fondamentale da capire è che le direttive che specificano il predicato nello scope specificano la semantica di chiamata (_calling_) del predicato, e non la semantica di definizione (_definition_). Ad esempio, se un oggetto ha il ruolo di una classe e dichiara un predicato privato, tale predicato può essere definito nelle sue sottoclassi e nelle istanze * ma * può essere chiamato solo nelle sue istanza (_from_) dalla classe.
+
+# Definizione e implementazione di un protocollo
+
+Un Protocollo contiene le dichiarazioni dei predicati che possono essere implementati da un qualsivoglia numero di oggetti e categorie:
+
+```logtalk
+:- protocol(listp).
+
+ :- public(member/2).
+
+:- end_protocol.
+
+:- object(list,
+ implements(listp)).
+
+ member(Head, [Head| _]).
+ member(Head, [_| Tail]) :-
+ member(Head, Tail).
+
+:- end_object.
+```
+
+Lo scope dei predicati di un protocollo può essere ristretto usando implementazioni protected e private. Ad esempio:
+
+```logtalk
+:- object(stack,
+ implements(private::listp)).
+
+:- end_object.
+```
+
+Difatti, tutte le relazioni tra entità (nella direttiva di apertura di un entità) possono essere definite come public (default), protected, o private.
+
+# Prototipi
+
+Un oggetto senza una istanza o senza una relazione di specializzazione con un altro oggetto interpreta il ruolo di prototipo. Un prototipo può estendere un altro oggetto, il suo prototipo genitore.
+
+```logtalk
+% clyde, our prototypical elephant
+:- object(clyde).
+
+ :- public(color/1).
+ color(grey).
+
+ :- public(number_of_legs/1).
+ number_of_legs(4).
+
+:- end_object.
+
+% fred, another elephant, is like clyde, except that he's white
+:- object(fred,
+ extends(clyde)).
+
+ color(white).
+
+:- end_object.
+```
+
+Per rispondere ad un messaggio inviato ad un oggetto che ha il ruolo di prototipo, si cerca prima una risposta nel prototipo stesso e se il prototipo non sa rispondere si passa all'eventuale prototipo genitore (se esiste):
+
+```logtalk
+?- fred::number_of_legs(N).
+N = 4
+yes
+
+?- fred::color(C).
+C = white
+yes
+```
+
+Un messaggio è valido se il relativo predicato è dichiarato in un oggetto (e se il mittente è nel campo di applicazione), ma fallirà, piuttosto che lanciare un errore, se il predicato non è definito. Questa è chiamata la _closed-world assumption_. Ad esempio, si consideri il seguente oggetto, salvato in un file `foo.lgt`:
+
+```logtalk
+:- object(foo).
+
+ :- public(bar/0).
+
+:- end_object.
+```
+
+Caricando il file e cercando di chiamare il predicato `bar/0` questo fallisce come previsto. Si noti che ciò è diverso dal chiamare un predicato sconosciuto _unknown_, che invece genera un errore:
+
+```logtalk
+?- {foo}.
+yes
+
+?- foo::bar.
+no
+
+?- catch(foo::baz, Error, true).
+Error = error(
+ existence_error(predicate_declaration, baz/0),
+ logtalk(foo::baz, user)
+)
+yes
+```
+
+# Classi e istanze
+
+Per definire gli oggetti nei ruoli di classi e/o istanze, un oggetto deve avere almeno un istanziazione o una relazione di specializzazione con un altro oggetto. Gli oggetti che hanno il ruolo di meta-classi possono essere utilizzati quando abbiamo bisogno di usare una classe come se fosse un'istanza. Il seguente esempio mostra come creare dinamicamente nuovi oggetti in fase di esecuzione:
+
+```logtalk
+% a simple, generic, metaclass defining a new/2 predicate for its instances
+:- object(metaclass,
+ instantiates(metaclass)).
+
+ :- public(new/2).
+ new(Instance, Clauses) :-
+ self(Class),
+ create_object(Instance, [instantiates(Class)], [], Clauses).
+
+:- end_object.
+
+% a simple class defining age/1 and name/1 predicate for its instances
+:- object(person,
+ instantiates(metaclass)).
+
+ :- public([
+ age/1, name/1
+ ]).
+
+ % a default value for age/1
+ age(42).
+
+:- end_object.
+
+% a static instance of the class person
+:- object(john,
+ instantiates(person)).
+
+ name(john).
+ age(12).
+
+:- end_object.
+```
+
+Nel rispondere ad un messaggio inviato ad un oggetto ha assunto il ruolo di istanza, tal messaggio viene convalidato partendo dalla sua classe e andando a ritroso nella gerarchia, se necessario, fino alle sue superclassi. Supponendo che il messaggio sia valido, allora si cerca una risposta a partire dall'istanza stessa:
+
+```logtalk
+?- person::new(Instance, [name(paulo)]).
+Instance = o1
+yes
+
+?- o1::name(Name).
+Name = paulo
+yes
+
+?- o1::age(Age).
+Age = 42
+yes
+
+?- john::age(Age).
+Age = 12
+yes
+```
+
+# Categorie
+
+Una categoria è un'unità atomica di codice riutilizzabile. Una categoria è usata per incapsulare una insieme coesivo (_cohesive_) di dichiarazioni e di definizioni di predicato ed è atta ad implementare una singola (_single_) funzionalità che può essere importata in qualsiasi oggetto. Una categoria può quindi essere concepita come il concetto duale di protocollo. Nel seguente esempio, si definiscono prima le categorie che rappresentano i motori di auto e poi si importano tali categorie negli oggetti auto:
+
+```logtalk
+% a protocol describing engine characteristics
+:- protocol(carenginep).
+
+ :- public([
+ reference/1,
+ capacity/1,
+ cylinders/1,
+ horsepower_rpm/2,
+ bore_stroke/2,
+ fuel/1
+ ]).
+
+:- end_protocol.
+
+% a typical engine defined as a category
+:- category(classic,
+ implements(carenginep)).
+
+ reference('M180.940').
+ capacity(2195).
+ cylinders(6).
+ horsepower_rpm(94, 4800).
+ bore_stroke(80, 72.8).
+ fuel(gasoline).
+
+:- end_category.
+
+% a souped up version of the previous engine
+:- category(sport,
+ extends(classic)).
+
+ reference('M180.941').
+ horsepower_rpm(HP, RPM) :-
+ ^^horsepower_rpm(ClassicHP, ClassicRPM), % "super" call
+ HP is truncate(ClassicHP*1.23),
+ RPM is truncate(ClassicRPM*0.762).
+
+:- end_category.
+
+% with engines (and other components), we may start "assembling" some cars
+:- object(sedan,
+ imports(classic)).
+
+:- end_object.
+
+:- object(coupe,
+ imports(sport)).
+
+:- end_object.
+```
+
+Le Categorie sono compilate in modo indipendente e, quindi, consentono l'importazione di oggetti da aggiornare mediante il semplice aggiornamento delle categorie importate, senza richiedere pertanto la ricompilazione dell'oggetto. Le Categorie forniscono anche la _runtime transparency_, cioè il protocollo della categoria si aggiunge al protocollo degli oggetti che importano tale categoria:
+
+```logtalk
+?- sedan::current_predicate(Predicate).
+Predicate = reference/1 ;
+Predicate = capacity/1 ;
+Predicate = cylinders/1 ;
+Predicate = horsepower_rpm/2 ;
+Predicate = bore_stroke/2 ;
+Predicate = fuel/1
+yes
+```
+
+# Hot patching
+
+Le categorie possono essere anche usate per modificare gli oggetti al volo (_hot-patch_). Una categoria può aggiungere nuovi predicati ad un oggetto e/o sostituire le definizioni dei predicati dell'oggetto. Ad esempio, si consideri il seguente oggetto:
+
+```logtalk
+:- object(buggy).
+
+ :- public(p/0).
+ p :- write(foo).
+
+:- end_object.
+```
+
+Si supponga che l'oggetto stampi la stringa sbagliata quando riceve il messaggio `p/0`:
+
+```logtalk
+?- {buggy}.
+yes
+
+?- buggy::p.
+foo
+yes
+```
+
+Se il codice sorgente dell'oggetto non è disponibile e bisogna correggere l'applicazione che sta eseguendo il codice dell'oggetto, si può semplicemente definire una categoria che corregge il predicato non corretto:
+
+```logtalk
+:- category(patch,
+ complements(buggy)).
+
+ % fixed p/0 def
+ p :- write(bar).
+
+:- end_category.
+```
+
+Dopo la compilazione e il caricamento della categoria nell'applicazione in esecuzione si ottiene:
+
+```logtalk
+?- {patch}.
+yes
+
+?- buggy::p.
+bar
+yes
+```
+
+Poiché l'hot-patching pregiudica forzatamente l'incapsulamento, un apposito flag di compilazione `complementary` può essere impostato (a livello globale o per un singolo oggetto) per consentire, limitare o prevenire l'hot-patching.
+
+# Oggetti Parametrici e Categorie
+
+Gli oggetti e le categorie possono essere parametrizzati utilizzando come identificativo un compound-term al posto di un atomo. Oggetti e parametri di una categoria sono variabili logiche _logical variables_ condivise con tutti i predicati incapsulati. Ecco un esempio con cerchi geometrici:
+
+```logtalk
+:- object(circle(_Radius, _Color)).
+
+ :- public([
+ area/1, perimeter/1
+ ]).
+
+ area(Area) :-
+ parameter(1, Radius),
+ Area is pi*Radius*Radius.
+
+ perimeter(Perimeter) :-
+ parameter(1, Radius),
+ Perimeter is 2*pi*Radius.
+
+:- end_object.
+```
+
+Oggetti parametrici possono essere utilizzati come qualsiasi altro oggetto e di solito forniscono i valori da assegnare ai parametri quando si invia un messaggio:
+
+```logtalk
+?- circle(1.23, blue)::area(Area).
+Area = 4.75291
+yes
+```
+
+Gli oggetti parametrici forniscono anche un modo semplice per associare un insieme di predicati con un semplice predicato Prolog. Fatti Prolog possono essere interpretati come oggetti proxy parametrici ( _parametric object proxies_) quando hanno lo stesso funtore e arietà degli identificatori di oggetti parametrici. Per lavorare con i proxy viene fornita una sintassi maneggevole. Per esempio, si prendano le seguenti clausole per il predicato `circle/2`:
+
+```logtalk
+circle(1.23, blue).
+circle(3.71, yellow).
+circle(0.39, green).
+circle(5.74, black).
+circle(8.32, cyan).
+```
+
+Con queste clausole, si può facilmente calcolare, ad esempio, un elenco con le aree di tutti i cerchi:
+
+```logtalk
+?- findall(Area, {circle(_, _)}::area(Area), Areas).
+Areas = [4.75291, 43.2412, 0.477836, 103.508, 217.468]
+yes
+```
+
+In pratica, il costrutto `{Goal}::Message` prova il goal `Goal`, instanziando le variabili interne e inviando un messaggio `Message` al termine risultante.
+
+# Eventi and monitor
+
+Logtalk supporta l'_event-driven programming_ mediante la definizione di eventi e di monitor. Un evento è semplicemente l'invio di un messaggio ad un oggetto. Un monitor è un gestore di un evento. L'evento (con l'invio di un messaggio) è un'attività atomica, ed è preceduta da un evento _before_ e da un evento _after_. Il monitor gestisce tali eventi mediante i predicati, `before/3` e `after/3`, che sono chiamati rispettivamente prima e dopo il verificarsi dell'evento. Un monitor può inoltre interrogare, registrare e cancellare un evento nel registro eventi a livello di sistema il quale che associa gli eventi con i monitor. Ad esempio, un semplice tracer per ogni messaggio inviato utilizzando il costrutto `::/2` può essere definito come:
+
+```logtalk
+:- object(tracer,
+ implements(monitoring)). % built-in protocol for event handlers
+
+ :- initialization(define_events(_, _, _, _, tracer)).
+
+ before(Object, Message, Sender) :-
+ write('call: '), writeq(Object), write(' <-- '), writeq(Message),
+ write(' from '), writeq(Sender), nl.
+
+ after(Object, Message, Sender) :-
+ write('exit: '), writeq(Object), write(' <-- '), writeq(Message),
+ write(' from '), writeq(Sender), nl.
+
+:- end_object.
+```
+
+Supponendo che l'oggetto `tracer` e l'oggetto `list` definito in precedenza siano stati già compilati e caricati, si possono osservare i gestori di eventi in azione durante l'invio di un messaggio:
+
+```logtalk
+?- list::member(X, [1,2,3]).
+
+call: list <-- member(X, [1,2,3]) from user
+exit: list <-- member(1, [1,2,3]) from user
+X = 1 ;
+exit: list <-- member(2, [1,2,3]) from user
+X = 2 ;
+exit: list <-- member(3, [1,2,3]) from user
+X = 3
+yes
+```
+
+Gli eventi possono essere impostati e cancellati dinamicamente in fase di esecuzione chiamando i predicati predefiniti `define_events/5` e` abolish_events/5` .
+
+La programmazione event-driven può essere vista come una forma di _computational reflection_. Si noti però che gli eventi sono generati solo quando si utilizza il costrutto di controllo per l'invio di messaggi `::/2`.
+
+# Espressioni lambda
+
+Logtalk supporta anche le espressioni lambda. I parametri della espressioni lambda sono rappresentati mediante una lista con l'operatore infisso `(>>)/2` che collega i parametri alla relativa lambda espressione. Ecco alcuni semplici esempi di che usano i meta-predicati.
+
+
+```logtalk
+?- {library(metapredicates_loader)}.
+yes
+
+?- meta::map([X,Y]>>(Y is 2*X), [1,2,3], Ys).
+Ys = [2,4,6]
+yes
+```
+
+Logtalk supporta anche il _currying_:
+
+```logtalk
+?- meta::map([X]>>([Y]>>(Y is 2*X)), [1,2,3], Ys).
+Ys = [2,4,6]
+yes
+```
+
+Infine, le variabili libere Lambda possono essere espresso usando la sintassi estesa `{Free1, ...}/[Parameter1, ...]>>Lambda`.
+
+# Macro
+
+I Termini e goal nel file sorgente possono essere _estesi_ al momento della compilazione specificando una hook ad un oggetto (_hook object_) che definisce le regole di riscrittura dei termini e riscrittura dei quesiti. Ad esempio, si consideri il seguente oggetto semplice, salvato nel file `source.lgt`:
+
+```logtalk
+:- object(source).
+
+ :- public(bar/1).
+ bar(X) :- foo(X).
+
+ foo(a). foo(b). foo(c).
+
+:- end_object.
+```
+
+Si supponga il seguente hook all'oggetto, salvato nel file `my_macros.lgt`, che estende le clausole e chiama il predicato locale `foo/1`:
+
+```logtalk
+:- object(my_macros,
+ implements(expanding)). % built-in protocol for expanding predicates
+
+ term_expansion(foo(Char), baz(Code)) :-
+ char_code(Char, Code). % standard built-in predicate
+
+ goal_expansion(foo(X), baz(X)).
+
+:- end_object.
+```
+
+Dopo aver caricato il file contenente la macro, si può espandere il nostro file sorgente usando il flag del compilatore `hook`:
+
+```logtalk
+?- logtalk_load(my_macros), logtalk_load(source, [hook(my_macros)]).
+yes
+
+?- source::bar(X).
+X = 97 ;
+X = 98 ;
+X = 99
+true
+```
+
+La libreria Logtalk fornisce infine il supporto per combinare hook agli oggetti utilizzando diversi modi (ad esempio, definendo una pipeline di espansioni).
+
+
+# Maggiori informazioni
+
+Visita il [Sito web di Logtalk (en)](http://logtalk.org) per maggiori informazioni.
diff --git a/it-it/markdown.html.markdown b/it-it/markdown.html.markdown
index b006dbb4..b0a123f1 100644
--- a/it-it/markdown.html.markdown
+++ b/it-it/markdown.html.markdown
@@ -2,41 +2,65 @@
language: markdown
contributors:
- ["Dan Turkel", "http://danturkel.com/"]
+ - ["Jacob Ward", "http://github.com/JacobCWard/"]
translators:
- ["Jacopo Andrea Giola", "http://geekpanda.net"]
+ - ["Ale46", "https://github.com/Ale46"]
filename: markdown-it.md
lang: it-it
---
Markdown è stato creato da John Gruber nel 2004. Il suo scopo è quello di essere una sintassi facile da leggere e scrivere, e che può essere convertita in HTML (ad oggi anche in molti altri formati).
-Mandate tutto il feedback che volete! / Sentitevi liberi di forkare o di mandare pull request!
-
+Markdown varia nelle sue implementazioni da un parser all'altro. Questa guida cercherà di chiarire quali caratteristiche esistono a livello globale o quando sono disponibili solo per un determinato parser.
+
+- [Elementi HTML](#elementi-html)
+- [Titoli](#titoli)
+- [Stili di testo semplici](#stili-di-testo-semplici)
+- [Paragrafi](#paragrafi)
+- [Liste](#liste)
+- [Estratti di codice](#estratti-di-codice)
+- [Linea orizzontale](#linea-orizzontale)
+- [Links](#links)
+- [Immagini](#immagini)
+- [Miscellanea](#miscellanea)
+
+## Elementi HTML
+Markdown è un superset di HTML, quindi ogni file HTML è a sua volta un file Markdown valido.
+
+```md
+<!-- Questo significa che possiamo usare elementi di HTML in Markdown, come per esempio i commenti,
+e questi non saranno modificati dal parser di Markdown. State attenti però,
+se inserite un elemento HTML nel vostro file Markdown, non potrete usare la sua sintassi
+all'interno del contenuto dell'elemento. -->
+```
-```markdown
-<!-- Markdown è un superset di HTML, quindi ogni file HTML è a sua volta un file Markdown valido. Questo significa che possiamo usare elementi di HTML in Markdown, come per esempio i commenti, e questi non saranno modificati dal parser di Markdown. State attenti però, se inserite un elemento HTML nel vostro file Markdown, non potrete usare la sua sintassi all'interno del contenuto dell'elemento. -->
+## Titoli
-<!-- L'implementazione di Markdown inoltre cambia da parser a parser. In questa guida cercheremo di indicare quando una feature è universale e quando sono specifiche ad un certo parser. -->
+Potete creare gli elementi HTML da `<h1>` a `<h6>` facilmente, basta che inseriate un egual numero di caratteri cancelletto (#) prima del testo che volete all'interno dell'elemento
-<!-- Titoli -->
-<!-- Potete creare gli elementi HTML da <h1> ad <h6> facilmente, basta che inseriate un egual numero di caratteri cancelletto (#) prima del testo che volete all'interno dell'elemento -->
+```md
# Questo è un <h1>
## Questo è un <h2>
### Questo è un <h3>
#### Questo è un <h4>
##### Questo è un <h5>
###### Questo è un <h6>
+```
+Markdown inoltre fornisce due alternative per indicare gli elementi h1 e h2
-<!-- Markdown inoltre fornisce due alternative per indicare gli elementi h1 e h2 -->
+```md
Questo è un h1
==============
Questo è un h2
--------------
+```
-<!-- Stili di testo semplici -->
-<!-- Il testo può essere stilizzato in corsivo o grassetto usando markdown -->
+## Stili di testo semplici
+Il testo può essere stilizzato in corsivo o grassetto usando markdown
+```md
*Questo testo è in corsivo.*
_Come pure questo._
@@ -46,30 +70,38 @@ __Come pure questo.__
***Questo testo è stilizzato in entrabmi i modi.***
**_Come questo!_**
*__E questo!__*
+```
-<!-- In Github Flavored Markdown, che è utilizzato per renderizzare i file markdown su
-Github, è presente anche lo stile barrato -->
+In Github Flavored Markdown, che è utilizzato per renderizzare i file markdown su Github, è presente anche lo stile barrato:
+```md
~~Questo testo è barrato.~~
+```
+## Paragrafi
-<!-- I paragrafi sono uno o più linee di testo addiacenti separate da una o più righe vuote. -->
+```md
+I paragrafi sono una o più linee di testo adiacenti separate da una o più righe vuote.
-Qeusto è un paragrafo. Sto scrivendo in un paragrafo, non è divertente?
+Questo è un paragrafo. Sto scrivendo in un paragrafo, non è divertente?
Ora sono nel paragrafo 2.
Anche questa linea è nel paragrafo 2!
Qui siamo nel paragrafo 3!
+```
-<!-- Se volete inserire l'elemento HTML <br />, potete terminare la linea con due o più spazi e poi iniziare un nuovo paragrafo. -->
+Se volete inserire l'elemento HTML `<br />`, potete terminare la linea con due o più spazi e poi iniziare un nuovo paragrafo.
+```md
Questa frase finisce con due spazi (evidenziatemi per vederli).
C'è un <br /> sopra di me!
+```
-<!-- Le citazioni sono semplici da inserire, basta usare il carattere >. -->
+Le citazioni sono semplici da inserire, basta usare il carattere >.
+```md
> Questa è una citazione. Potete
> mandare a capo manualmente le linee e inserire un `>` prima di ognuna, oppure potete usare una sola linea e lasciare che vada a capo automaticamente.
> Non c'è alcuna differenza, basta che iniziate ogni riga con `>`.
@@ -78,9 +110,12 @@ C'è un <br /> sopra di me!
>> di indentazione!
> Quanto è comodo?
-<!-- Liste -->
-<!-- Le liste non ordinate possono essere inserite usando gli asterischi, il simbolo più o dei trattini -->
+```
+## Liste
+Le liste non ordinate possono essere inserite usando gli asterischi, il simbolo più o dei trattini
+
+```md
* Oggetto
* Oggetto
* Altro oggetto
@@ -96,149 +131,180 @@ oppure
- Oggetto
- Oggetto
- Un ultimo oggetto
+```
-<!-- Le liste ordinate invece, sono inserite con un numero seguito da un punto. -->
+Le liste ordinate invece, sono inserite con un numero seguito da un punto.
+```md
1. Primo oggetto
2. Secondo oggetto
3. Terzo oggetto
+```
-<!-- Non dovete nemmeno mettere i numeri nell'ordine giusto, markdown li visualizzerà comunque nell'ordine corretto, anche se potrebbe non essere una buona idea. -->
+Non dovete nemmeno mettere i numeri nell'ordine giusto, markdown li visualizzerà comunque nell'ordine corretto, anche se potrebbe non essere una buona idea.
+```md
1. Primo oggetto
1. Secondo oggetto
1. Terzo oggetto
-<!-- (Questa lista verrà visualizzata esattamente come quella dell'esempio prima) -->
+```
+(Questa lista verrà visualizzata esattamente come quella dell'esempio prima)
-<!-- Potete inserire anche sotto liste -->
+Potete inserire anche sotto liste
+```md
1. Primo oggetto
2. Secondo oggetto
3. Terzo oggetto
* Sotto-oggetto
* Sotto-oggetto
4. Quarto oggetto
+```
-<!-- Sono presenti anche le task list. In questo modo è possibile creare checkbox in HTML. -->
+Sono presenti anche le task list. In questo modo è possibile creare checkbox in HTML.
+```md
I box senza la 'x' sono checkbox HTML ancora da completare.
- [ ] Primo task da completare.
- [ ] Secondo task che deve essere completato.
Il box subito sotto è una checkbox HTML spuntata.
- [x] Questo task è stato completato.
+```
+## Estratti di codice
-<!-- Estratti di codice -->
-<!-- Potete inserire un estratto di codice (che utilizza l'elemento <code>) indentando una linea con quattro spazi oppure con un carattere tab -->
+Potete inserire un estratto di codice (che utilizza l'elemento `<code>`) indentando una linea con quattro spazi oppure con un carattere tab.
+```md
Questa è una linea di codice
Come questa
+```
-<!-- Potete inoltre inserire un altro tab (o altri quattro spazi) per indentare il vostro codice -->
+Potete inoltre inserire un altro tab (o altri quattro spazi) per indentare il vostro codice
+```md
my_array.each do |item|
puts item
end
+```
-<!-- Codice inline può essere inserito usando il carattere backtick ` -->
+Codice inline può essere inserito usando il carattere backtick `
+```md
Giovanni non sapeva neppure a cosa servisse la funzione `go_to()`!
+```
-<!-- In Github Flavored Markdown, potete inoltre usare una sintassi speciale per il codice -->
-
-\`\`\`ruby <!-- In realtà dovete rimuovere i backslash, usate solo ```ruby ! -->
+In Github Flavored Markdown, potete inoltre usare una sintassi speciale per il codice
+<pre>
+<code class="highlight">&#x60;&#x60;&#x60;ruby
def foobar
puts "Hello world!"
end
-\`\`\` <!-- Anche qui, niente backslash, solamente ``` -->
-
-<!-- Se usate questa sintassi, il testo non richiederà di essere indentanto, inoltre Github userà la syntax highlighting del linguaggio specificato dopo i ``` iniziali -->
+&#x60;&#x60;&#x60;</code></pre>
+Se usate questa sintassi, il testo non richiederà di essere indentato, inoltre Github userà l'evidenziazione della sintassi del linguaggio specificato dopo i \`\`\` iniziali
-<!-- Linea orizzontale (<hr />) -->
-<!-- Le linee orizzontali sono inserite facilemtne usanto tre o più asterischi o trattini senza spazi consecutivi e senza spazi. -->
+## Linea orizzontale
+Le linee orizzontali (`<hr/>`) sono inserite facilmente usanto tre o più asterischi o trattini, con o senza spazi.
+```md
***
---
- - -
****************
+```
-<!-- Link -->
-<!-- Una delle funzionalità migliori di markdown è la facilità con cui si possono inserire i link. Mettete il testo da visualizzare fra parentesi quadre [] seguite dall'url messo fra parentesi tonde () -->
+## Links
+Una delle funzionalità migliori di markdown è la facilità con cui si possono inserire i link. Mettete il testo da visualizzare fra parentesi quadre [] seguite dall'url messo fra parentesi tonde ()
+```md
[Cliccami!](http://test.com/)
+```
-<!-- Potete inoltre aggiungere al link un titolo mettendolo fra doppie apici dopo il link -->
+Potete inoltre aggiungere al link un titolo mettendolo fra doppi apici dopo il link
+```md
[Cliccami!](http://test.com/ "Link a Test.com")
+```
-<!-- La sintassi funziona anche i path relativi. -->
+La sintassi funziona anche con i path relativi.
+```md
[Vai a musica](/music/).
+```
-<!-- Markdown supporta inoltre anche la possibilità di aggiungere i link facendo riferimento ad altri punti del testo -->
-
+Markdown supporta inoltre anche la possibilità di aggiungere i link facendo riferimento ad altri punti del testo.
+```md
[Apri questo link][link1] per più informazioni!
[Guarda anche questo link][foobar] se ti va.
[link1]: http://test.com/ "Bello!"
[foobar]: http://foobar.biz/ "Va bene!"
+```
+l titolo può anche essere inserito in apici singoli o in parentesi, oppure omesso interamente. Il riferimento può essere inserito in un punto qualsiasi del vostro documento e l'identificativo del riferimento può essere lungo a piacere a patto che sia univoco.
-<!-- Il titolo può anche essere inserito in apici singoli o in parentesi, oppure omesso interamente. Il riferimento può essere inserito in un punto qualsiasi del vostro documento e l'identificativo del riferimento può essere lungo a piacere a patto che sia univoco. -->
-
-<!-- Esiste anche un "identificativo implicito" che vi permette di usare il testo del link come id -->
-
+Esiste anche un "identificativo implicito" che vi permette di usare il testo del link come id.
+```md
[Questo][] è un link.
[Questo]: http://thisisalink.com/
+```
+Ma non è comunemente usato.
-<!-- Ma non è comunemente usato. -->
-
-<!-- Immagini -->
-<!-- Le immagini sono inserite come i link ma con un punto esclamativo inserito prima delle parentesi quadre! -->
+## Immagini
+Le immagini sono inserite come i link ma con un punto esclamativo inserito prima delle parentesi quadre!
+```md
![Qeusto è il testo alternativo per l'immagine](http://imgur.com/myimage.jpg "Il titolo opzionale")
+```
-<!-- E la modalità a riferimento funziona esattamente come ci si aspetta -->
+E la modalità a riferimento funziona esattamente come ci si aspetta
+```md
![Questo è il testo alternativo.][myimage]
[myimage]: relative/urls/cool/image.jpg "Se vi serve un titolo, lo mettete qui"
+```
+## Miscellanea
+### Auto link
-<!-- Miscellanea -->
-<!-- Auto link -->
-
+```md
<http://testwebsite.com/> è equivalente ad
[http://testwebsite.com/](http://testwebsite.com/)
+```
+### Auto link per le email
-<!-- Auto link per le email -->
-
+```md
<foo@bar.com>
+```
+### Caratteri di escaping
-<!-- Caratteri di escaping -->
-
+```md
Voglio inserire *questo testo circondato da asterischi* ma non voglio che venga renderizzato in corsivo, quindi lo inserirò così: \*questo testo è circondato da asterischi\*.
+```
-<!-- Combinazioni di tasti -->
-<!-- In Github Flavored Markdown, potete utilizzare il tag <kbd> per raffigurare i tasti della tastiera -->
+### Combinazioni di tasti
+In Github Flavored Markdown, potete utilizzare il tag `<kbd>` per raffigurare i tasti della tastiera.
+```md
Il tuo computer è crashato? Prova a premere
<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Canc</kbd>
+```
-<!-- Tabelle -->
-<!-- Le tabelle sono disponibili solo in Github Flavored Markdown e sono leggeremente complesse, ma se proprio volete inserirle fate come segue: -->
+### Tabelle
+Le tabelle sono disponibili solo in Github Flavored Markdown e sono leggeremente complesse, ma se proprio volete inserirle fate come segue:
+```md
| Col1 | Col2 | Col3 |
| :------------------- | :------: | -----------------: |
| Allineato a sinistra | Centrato | Allineato a destra |
| blah | blah | blah |
+```
+oppure, per lo stesso risultato
-<!-- oppure, per lo stesso risultato -->
-
+```md
Col 1 | Col2 | Col3
:-- | :-: | --:
È una cosa orrenda | fatela | finire in fretta
-
-<!-- Finito! -->
-
```
+---
Per altre informazioni, leggete il post ufficiale di John Gruber sulla sintassi [qui](http://daringfireball.net/projects/markdown/syntax) e il magnifico cheatsheet di Adam Pritchard [qui](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).
diff --git a/it-it/matlab-it.html.markdown b/it-it/matlab-it.html.markdown
index aeb42658..38be8848 100644
--- a/it-it/matlab-it.html.markdown
+++ b/it-it/matlab-it.html.markdown
@@ -199,8 +199,7 @@ size(A) % ans = 3 3
A(1, :) =[] % Rimuove la prima riga della matrice
A(:, 1) =[] % Rimuove la prima colonna della matrice
-transpose(A) % Traspone la matrice, equivale a:
-A one
+transpose(A) % Traspone la matrice, equivale a: A.'
ctranspose(A) % Trasposizione hermitiana della matrice
% (ovvero il complesso coniugato di ogni elemento della matrice trasposta)
@@ -217,7 +216,7 @@ A .* B % Moltiplica ogni elemento di A per il corrispondente elemento di B
% l'altra (il cui nome termina con m) agisce sull'intera matrice.
exp(A) % Calcola l'esponenziale di ogni elemento
expm(A) % Calcola la matrice esponenziale
-sqrt(A) % Calcola la radice quadrata di ogni elementotake the square root of each element
+sqrt(A) % Calcola la radice quadrata di ogni elemento
sqrtm(A) % Trova la matrice di cui A nè è la matrice quadrata
diff --git a/it-it/pcre-it.html.markdown b/it-it/pcre-it.html.markdown
new file mode 100644
index 00000000..704392ef
--- /dev/null
+++ b/it-it/pcre-it.html.markdown
@@ -0,0 +1,85 @@
+---
+language: PCRE
+filename: pcre-it.txt
+contributors:
+ - ["Sachin Divekar", "http://github.com/ssd532"]
+translators:
+ - ["Christian Grasso", "https://grasso.io"]
+lang: it-it
+---
+
+Un'espressione regolare (regex o regexp in breve) è una speciale stringa
+utilizzata per definire un pattern, ad esempio per cercare una sequenza di
+caratteri; ad esempio, `/^[a-z]+:/` può essere usato per estrarre `http:`
+dall'URL `http://github.com/`.
+
+PCRE (Perl Compatible Regular Expressions) è una libreria per i regex in C.
+La sintassi utilizzata per le espressioni è molto simile a quella di Perl, da
+cui il nome. Si tratta di una delle sintassi più diffuse per la scrittura di
+regex.
+
+Esistono due tipi di metacaratteri (caratteri con una funzione speciale):
+
+* Caratteri riconosciuti ovunque tranne che nelle parentesi quadre
+
+```
+ \ carattere di escape
+ ^ cerca all'inizio della stringa (o della riga, in modalità multiline)
+ $ cerca alla fine della stringa (o della riga, in modalità multiline)
+ . qualsiasi carattere eccetto le newline
+ [ inizio classe di caratteri
+ | separatore condizioni alternative
+ ( inizio subpattern
+ ) fine subpattern
+ ? quantificatore "0 o 1"
+ * quantificatore "0 o più"
+ + quantificatore "1 o più"
+ { inizio quantificatore numerico
+```
+
+* Caratteri riconosciuti nelle parentesi quadre
+
+```
+ \ carattere di escape
+ ^ nega la classe se è il primo carattere
+ - indica una serie di caratteri
+ [ classe caratteri POSIX (se seguita dalla sintassi POSIX)
+ ] termina la classe caratteri
+```
+
+PCRE fornisce inoltre delle classi di caratteri predefinite:
+
+```
+ \d cifra decimale
+ \D NON cifra decimale
+ \h spazio vuoto orizzontale
+ \H NON spazio vuoto orizzontale
+ \s spazio
+ \S NON spazio
+ \v spazio vuoto verticale
+ \V NON spazio vuoto verticale
+ \w parola
+ \W "NON parola"
+```
+
+## Esempi
+
+Utilizzeremo la seguente stringa per i nostri test:
+
+```
+66.249.64.13 - - [18/Sep/2004:11:07:48 +1000] "GET /robots.txt HTTP/1.0" 200 468 "-" "Googlebot/2.1"
+```
+
+Si tratta di una riga di log del web server Apache.
+
+| Regex | Risultato | Commento |
+| :---- | :-------------- | :------ |
+| `GET` | GET | Cerca esattamente la stringa "GET" (case sensitive) |
+| `\d+.\d+.\d+.\d+` | 66.249.64.13 | `\d+` identifica uno o più (quantificatore `+`) numeri [0-9], `\.` identifica il carattere `.` |
+| `(\d+\.){3}\d+` | 66.249.64.13 | `(\d+\.){3}` cerca il gruppo (`\d+\.`) esattamente 3 volte. |
+| `\[.+\]` | [18/Sep/2004:11:07:48 +1000] | `.+` identifica qualsiasi carattere, eccetto le newline; `.` indica un carattere qualsiasi |
+| `^\S+` | 66.249.64.13 | `^` cerca all'inizio della stringa, `\S+` identifica la prima stringa di caratteri diversi dallo spazio |
+| `\+[0-9]+` | +1000 | `\+` identifica il carattere `+`. `[0-9]` indica una cifra da 0 a 9. L'espressione è equivalente a `\+\d+` |
+
+## Altre risorse
+[Regex101](https://regex101.com/) - tester per le espressioni regolari
diff --git a/it-it/pyqt-it.html.markdown b/it-it/pyqt-it.html.markdown
new file mode 100644
index 00000000..7238dd7b
--- /dev/null
+++ b/it-it/pyqt-it.html.markdown
@@ -0,0 +1,85 @@
+---
+category: tool
+tool: PyQT
+filename: learnpyqt-it.py
+contributors:
+ - ["Nathan Hughes", "https://github.com/sirsharpest"]
+translators:
+ - ["Ale46", "https://github.com/ale46"]
+lang: it-it
+---
+
+**Qt** è un framework ampiamente conosciuto per lo sviluppo di software multipiattaforma che può essere eseguito su varie piattaforme software e hardware con modifiche minime o nulle nel codice, pur avendo la potenza e la velocità delle applicazioni native. Sebbene **Qt** sia stato originariamente scritto in *C++*.
+
+
+Questo è un adattamento sull'introduzione di C ++ a QT di [Aleksey Kholovchuk] (https://github.com/vortexxx192
+), alcuni degli esempi di codice dovrebbero avere la stessa funzionalità
+che avrebbero se fossero fatte usando pyqt!
+
+```python
+import sys
+from PyQt4 import QtGui
+
+def window():
+ # Crea un oggetto applicazione
+ app = QtGui.QApplication(sys.argv)
+ # Crea un widget in cui verrà inserita la nostra etichetta
+ w = QtGui.QWidget()
+ # Aggiungi un'etichetta al widget
+ b = QtGui.QLabel(w)
+ # Imposta del testo per l'etichetta
+ b.setText("Ciao Mondo!")
+ # Fornisce informazioni su dimensioni e posizionamento
+ w.setGeometry(100, 100, 200, 50)
+ b.move(50, 20)
+ # Dai alla nostra finestra un bel titolo
+ w.setWindowTitle("PyQt")
+ # Visualizza tutto
+ w.show()
+ # Esegui ciò che abbiamo chiesto, una volta che tutto è stato configurato
+ sys.exit(app.exec_())
+
+if __name__ == '__main__':
+ window()
+
+```
+
+Per ottenere alcune delle funzionalità più avanzate in **pyqt**, dobbiamo iniziare a cercare di creare elementi aggiuntivi.
+Qui mostriamo come creare una finestra popup di dialogo, utile per chiedere all'utente di confermare una decisione o fornire informazioni
+
+```Python
+import sys
+from PyQt4.QtGui import *
+from PyQt4.QtCore import *
+
+
+def window():
+ app = QApplication(sys.argv)
+ w = QWidget()
+ # Crea un pulsante e allegalo al widget w
+ b = QPushButton(w)
+ b.setText("Premimi")
+ b.move(50, 50)
+ # Indica a b di chiamare questa funzione quando si fa clic
+    # notare la mancanza di "()" sulla chiamata di funzione
+ b.clicked.connect(showdialog)
+ w.setWindowTitle("PyQt Dialog")
+ w.show()
+ sys.exit(app.exec_())
+
+# Questa funzione dovrebbe creare una finestra di dialogo con un pulsante
+# che aspetta di essere cliccato e quindi esce dal programma
+def showdialog():
+ d = QDialog()
+ b1 = QPushButton("ok", d)
+ b1.move(50, 50)
+ d.setWindowTitle("Dialog")
+ # Questa modalità dice al popup di bloccare il genitore, mentre è attivo
+ d.setWindowModality(Qt.ApplicationModal)
+ # Al click vorrei che l'intero processo finisse
+ b1.clicked.connect(sys.exit)
+ d.exec_()
+
+if __name__ == '__main__':
+ window()
+```
diff --git a/it-it/python-it.html.markdown b/it-it/python-it.html.markdown
index 71f6dc1c..de7bb0ed 100644
--- a/it-it/python-it.html.markdown
+++ b/it-it/python-it.html.markdown
@@ -1,98 +1,89 @@
---
-language: python
+language: Python
+filename: learnpython-it.py
contributors:
- - ["Louie Dinh", "http://ldinh.ca"]
- - ["Amin Bandali", "http://aminbandali.com"]
+ - ["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"]
-filename: learnpython.py
+ - ["Rommel Martinez", "https://ebzzry.io"]
translators:
+ - ["Draio", "http://github.com/Draio/"]
- ["Ale46", "http://github.com/Ale46/"]
- ["Tommaso Pifferi", "http://github.com/neslinesli93/"]
-lang: it-it
+lang: it-it
---
-Python è stato creato da Guido Van Rossum agli inizi degli anni 90. Oggi è uno dei più popolari
-linguaggi esistenti. Mi sono innamorato di Python per la sua chiarezza sintattica. E' sostanzialmente
-pseudocodice eseguibile.
-Feedback sono altamente apprezzati! Potete contattarmi su [@louiedinh](http://twitter.com/louiedinh) oppure [at] [google's email service]
+Python è stato creato da Guido Van Rossum agli inizi degli anni 90. Oggi è uno dei più popolari linguaggi esistenti. Mi sono innamorato di Python per la sua chiarezza sintattica. E' sostanzialmente pseudocodice eseguibile.
-Nota: questo articolo è riferito a Python 2.7 in modo specifico, ma dovrebbe andar
-bene anche per Python 2.x. Python 2.7 sta raggiungendo il "fine vita", ovvero non sarà
-più supportato nel 2020. Quindi è consigliato imparare Python utilizzando Python 3.
-Per maggiori informazioni su Python 3.x, dai un'occhiata al [tutorial di Python 3](http://learnxinyminutes.com/docs/python3/).
+Feedback sono altamente apprezzati! Potete contattarmi su [@louiedinh](http://twitter.com/louiedinh) oppure [at] [google's email service]
-E' possibile anche scrivere codice compatibile sia con Python 2.7 che con Python 3.x,
-utilizzando [il modulo `__future__`](https://docs.python.org/2/library/__future__.html) di Python.
-Il modulo `__future__` permette di scrivere codice in Python 3, che può essere eseguito
-utilizzando Python 2: cosa aspetti a vedere il tutorial di Python 3?
+Nota: Questo articolo è riferito a Python 3 in modo specifico. Se volete avete la necessità di utilizzare Python 2.7 potete consultarla [qui](https://learnxinyminutes.com/docs/it-it/python-it/)
```python
# I commenti su una sola linea iniziano con un cancelletto
+
""" Più stringhe possono essere scritte
usando tre ", e sono spesso usate
- come commenti
+ come documentazione
"""
####################################################
## 1. Tipi di dati primitivi ed Operatori
####################################################
-# Hai i numeri
+# Ci sono i numeri
3 # => 3
# La matematica è quello che vi aspettereste
-1 + 1 # => 2
-8 - 1 # => 7
+1 + 1 # => 2
+8 - 1 # => 7
10 * 2 # => 20
-35 / 5 # => 7
-
-# La divisione è un po' complicata. E' una divisione fra interi in cui viene
-# restituito in automatico il risultato intero.
-5 / 2 # => 2
-
-# Per le divisioni con la virgola abbiamo bisogno di parlare delle variabili floats.
-2.0 # Questo è un float
-11.0 / 4.0 # => 2.75 ahhh...molto meglio
+35 / 5 # => 7.0
-# Il risultato di una divisione fra interi troncati positivi e negativi
-5 // 3 # => 1
-5.0 // 3.0 # => 1.0 # funziona anche per i floats
--5 // 3 # => -2
--5.0 // 3.0 # => -2.0
+# Risultato della divisione intera troncata sia in positivo che in negativo
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # works on floats too
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
-# E' possibile importare il modulo "division" (vedi la sezione 6 di questa guida, Moduli)
-# per effettuare la divisione normale usando solo '/'.
-from __future__ import division
-11/4 # => 2.75 ...divisione normale
-11//4 # => 2 ...divisione troncata
+# Il risultato di una divisione è sempre un numero decimale (float)
+10.0 / 3 # => 3.3333333333333335
# Operazione Modulo
-7 % 3 # => 1
+7 % 3 # => 1
# Elevamento a potenza (x alla y-esima potenza)
-2**4 # => 16
+2**3 # => 8
# Forzare le precedenze con le parentesi
(1 + 3) * 2 # => 8
+# I valori booleani sono primitive del linguaggio (nota la maiuscola)
+True
+False
+
+# nega con not
+not True # => False
+not False # => True
+
# Operatori Booleani
# Nota "and" e "or" sono case-sensitive
-True and False #=> False
-False or True #=> True
+True and False # => False
+False or True # => True
# Note sull'uso di operatori Bool con interi
-0 and 2 #=> 0
--5 or 0 #=> -5
-0 == False #=> True
-2 == True #=> False
-1 == True #=> True
-
-# nega con not
-not True # => False
-not False # => True
+# False è 0 e True è 1
+# Non confonderti tra bool(ints) e le operazioni bitwise and/or (&,|)
+0 and 2 # => 0
+-5 or 0 # => -5
+0 == False # => True
+2 == True # => False
+1 == True # => True
+-5 != False != True #=> True
# Uguaglianza è ==
1 == 1 # => True
@@ -112,37 +103,46 @@ not False # => True
1 < 2 < 3 # => True
2 < 3 < 2 # => False
+# ('is' vs. '==')
+# 'is' controlla se due variabili si riferiscono allo stesso oggetto
+# '==' controlla se gli oggetti puntati hanno lo stesso valore.
+a = [1, 2, 3, 4] # a punta ad una nuova lista [1, 2, 3, 4]
+b = a # b punta a ciò a cui punta a
+b is a # => True, a e b puntano allo stesso oggeto
+b == a # => True, gli oggetti di a e b sono uguali
+b = [1, 2, 3, 4] # b punta ad una nuova lista [1, 2, 3, 4]
+b is a # => False, a e b non puntano allo stesso oggetto
+b == a # => True, gli oggetti di a e b sono uguali
+
# Le stringhe sono create con " o '
"Questa è una stringa."
'Anche questa è una stringa.'
-# Anche le stringhe possono essere sommate!
-"Ciao " + "mondo!" # => Ciao mondo!"
-# Le stringhe possono essere sommate anche senza '+'
-"Ciao " "mondo!" # => Ciao mondo!"
-
-# ... oppure moltiplicate
-"Hello" * 3 # => "HelloHelloHello"
+# Anche le stringhe possono essere sommate! Ma cerca di non farlo.
+"Hello " + "world!" # => "Hello world!"
+# Le stringhe (ma non le variabili contenenti stringhe) possono essere
+# sommate anche senza '+'
+"Hello " "world!" # => "Hello world!"
# Una stringa può essere considerata come una lista di caratteri
"Questa è una stringa"[0] # => 'Q'
-# Per sapere la lunghezza di una stringa
+# Puoi conoscere la lunghezza di una stringa
len("Questa è una stringa") # => 20
-# Formattazione delle stringhe con %
-# Anche se l'operatore % per le stringe sarà deprecato con Python 3.1, e verrà rimosso
-# successivamente, può comunque essere utile sapere come funziona
-x = 'mela'
-y = 'limone'
-z = "La cesta contiene una %s e un %s" % (x,y)
+# .format può essere usato per formattare le stringhe, in questo modo:
+"{} possono essere {}".format("Le stringhe", "interpolate") # => "Le stringhe possono essere interpolate"
+
+# Puoi ripetere gli argomenti di formattazione per risparmiare un po' di codice
+"{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"
-# Un nuovo modo per fomattare le stringhe è il metodo format.
-# Questo metodo è quello consigliato
-"{} è un {}".format("Questo", "test")
-"{0} possono essere {1}".format("le stringhe", "formattate")
-# Puoi usare delle parole chiave se non vuoi contare
-"{nome} vuole mangiare {cibo}".format(nome="Bob", cibo="lasagna")
+# Puoi usare dei nomi se non vuoi contare gli argomenti
+"{nome} vuole mangiare {cibo}".format(nome="Bob", cibo="le lasagne") # => "Bob vuole mangiare le lasagne"
+
+# Se il tuo codice Python 3 necessita di eseguire codice Python 2.x puoi ancora
+# utilizzare il vecchio stile di formattazione:
+"%s possono essere %s nel %s modo" % ("Le stringhe", "interpolate", "vecchio") # => "Le stringhe possono essere interpolate nel vecchio modo"
# None è un oggetto
None # => None
@@ -150,57 +150,54 @@ None # => None
# Non usare il simbolo di uguaglianza "==" per comparare oggetti a None
# Usa "is" invece
"etc" is None # => False
-None is None # => True
-
-# L'operatore 'is' testa l'identità di un oggetto. Questo non è
-# molto utile quando non hai a che fare con valori primitivi, ma lo è
-# quando hai a che fare con oggetti.
-
-# Qualunque oggetto può essere usato nei test booleani
-# I seguenti valori sono considerati falsi:
-# - None
-# - Lo zero, come qualunque tipo numerico (quindi 0, 0L, 0.0, 0.j)
-# - Sequenze vuote (come '', (), [])
-# - Contenitori vuoti (tipo {}, set())
-# - Istanze di classi definite dall'utente, che soddisfano certi criteri
-# vedi: https://docs.python.org/2/reference/datamodel.html#object.__nonzero__
-#
-# Tutti gli altri valori sono considerati veri: la funzione bool() usata su di loro, ritorna True.
-bool(0) # => False
-bool("") # => False
+None is None # => True
+# None, 0, e stringhe/liste/dizionari/tuple vuoti vengono considerati
+# falsi (False). Tutti gli altri valori sono considerati veri (True).
+bool(0) # => False
+bool("") # => False
+bool([]) # => False
+bool({}) # => False
+bool(()) # => False
####################################################
## 2. Variabili e Collections
####################################################
-# Python ha una funzione di stampa
-print "Sono Python. Piacere di conoscerti!" # => Sono Python. Piacere di conoscerti!
+# Python ha una funzione per scrivere (sul tuo schermo)
+print("Sono Python. Piacere di conoscerti!") # => Sono Python. Piacere di conoscerti!
+
+# Di default la funzione print() scrive e va a capo aggiungendo un carattere
+# newline alla fine della stringa. È possibile utilizzare l'argomento opzionale
+# end per cambiare quest'ultimo carattere aggiunto.
+print("Hello, World", end="!") # => Hello, World!
# Un modo semplice per ricevere dati in input dalla riga di comando
-variabile_stringa_input = raw_input("Inserisci del testo: ") # Ritorna i dati letti come stringa
-variabile_input = input("Inserisci del testo: ") # Interpreta i dati letti come codice python
-# Attenzione: bisogna stare attenti quando si usa input()
-# Nota: In python 3, input() è deprecato, e raw_input() si chiama input()
+variabile_stringa_input = input("Inserisci del testo: ") # Restituisce i dati letti come stringa
+# Nota: Nelle precedenti vesioni di Python, il metodo input()
+# era chiamato raw_input()
# Non c'è bisogno di dichiarare una variabile per assegnarle un valore
-una_variabile = 5 # Convenzionalmente si usa caratteri_minuscoli_con_underscores
-una_variabile # => 5
+# Come convenzione, per i nomi delle variabili, si utilizzano i caratteri
+# minuscoli separati, se necessario, da underscore
+some_var = 5
+some_var # => 5
# Accedendo ad una variabile non precedentemente assegnata genera un'eccezione.
-# Dai un'occhiata al Control Flow per imparare di più su come gestire le eccezioni.
-un_altra_variabile # Genera un errore di nome
+# Dai un'occhiata al Control Flow per imparare di più su come gestire
+# le eccezioni.
+some_unknown_var # Genera un errore di nome
# if può essere usato come un'espressione
-# E' l'equivalente dell'operatore ternario in C
+# È l'equivalente dell'operatore ternario in C
"yahoo!" if 3 > 2 else 2 # => "yahoo!"
-# Liste immagazzinano sequenze
+# Le liste immagazzinano sequenze
li = []
# Puoi partire con una lista pre-riempita
-altra_li = [4, 5, 6]
+other_li = [4, 5, 6]
-# Aggiungi cose alla fine di una lista con append
+# Aggiungere alla fine di una lista con append
li.append(1) # li ora è [1]
li.append(2) # li ora è [1, 2]
li.append(4) # li ora è [1, 2, 4]
@@ -212,14 +209,10 @@ li.append(3) # li ora è [1, 2, 4, 3] di nuovo.
# Accedi ad una lista come faresti con un array
li[0] # => 1
-# Assegna nuovo valore agli indici che sono già stati inizializzati con =
-li[0] = 42
-li[0] # => 42
-li[0] = 1 # Nota: è resettato al valore iniziale
# Guarda l'ultimo elemento
li[-1] # => 3
-# Guardare al di fuori dei limiti è un IndexError
+# Guardare al di fuori dei limiti genera un IndexError
li[4] # Genera IndexError
# Puoi guardare gli intervalli con la sintassi slice (a fetta).
@@ -236,14 +229,11 @@ li[::-1] # => [3, 4, 2, 1]
# Usa combinazioni per fare slices avanzate
# li[inizio:fine:passo]
+# Crea una copia (one layer deep copy) usando la sintassi slices
+li2 = li[:] # => li2 = [1, 2, 4, 3] ma (li2 is li) risulterà falso.
+
# Rimuovi arbitrariamente elementi da una lista con "del"
del li[2] # li è ora [1, 2, 3]
-# Puoi sommare le liste
-li + altra_li # => [1, 2, 3, 4, 5, 6]
-# Nota: i valori per li ed altra_li non sono modificati.
-
-# Concatena liste con "extend()"
-li.extend(altra_li) # Ora li è [1, 2, 3, 4, 5, 6]
# Rimuove la prima occorrenza di un elemento
li.remove(2) # Ora li è [1, 3, 4, 5, 6]
@@ -252,10 +242,17 @@ li.remove(2) # Emette un ValueError, poichè 2 non è contenuto nella lista
# Inserisce un elemento all'indice specificato
li.insert(1, 2) # li è di nuovo [1, 2, 3, 4, 5, 6]
-# Ritorna l'indice della prima occorrenza dell'elemento fornito
+ Ritorna l'indice della prima occorrenza dell'elemento fornito
li.index(2) # => 1
li.index(7) # Emette un ValueError, poichè 7 non è contenuto nella lista
+# Puoi sommare le liste
+# Nota: i valori per li e per other_li non vengono modificati.
+li + other_li # => [1, 2, 3, 4, 5, 6]
+
+# Concatena le liste con "extend()"
+li.extend(other_li) # Adesso li è [1, 2, 3, 4, 5, 6]
+
# Controlla l'esistenza di un valore in una lista con "in"
1 in li # => True
@@ -263,93 +260,112 @@ li.index(7) # Emette un ValueError, poichè 7 non è contenuto nella lista
len(li) # => 6
-# Tuple sono come le liste ma immutabili.
+# Le tuple sono come le liste ma immutabili.
tup = (1, 2, 3)
-tup[0] # => 1
+tup[0] # => 1
tup[0] = 3 # Genera un TypeError
+# Note that a tuple of length one has to have a comma after the last element but
+# tuples of other lengths, even zero, do not.
+type((1)) # => <class 'int'>
+type((1,)) # => <class 'tuple'>
+type(()) # => <class 'tuple'>
+
# Puoi fare tutte queste cose da lista anche sulle tuple
-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
# Puoi scompattare le tuple (o liste) in variabili
-a, b, c = (1, 2, 3) # a è ora 1, b è ora 2 and c è ora 3
+a, b, c = (1, 2, 3) # a è ora 1, b è ora 2 e c è ora 3
d, e, f = 4, 5, 6 # puoi anche omettere le parentesi
# Le tuple sono create di default se non usi le parentesi
g = 4, 5, 6 # => (4, 5, 6)
# Guarda come è facile scambiare due valori
-e, d = d, e # d è ora 5 ed e è ora 4
-
+e, d = d, e # d è ora 5 ed e è ora 4
-# Dizionari immagazzinano mappature
-empty_dict = {}
-# Questo è un dizionario pre-riempito
+# I dizionari memorizzano insiemi di dati indicizzati da nomi arbitrari (chiavi)
+empty_dict= {}
+# Questo è un dizionario pre-caricato
filled_dict = {"uno": 1, "due": 2, "tre": 3}
-# Accedi ai valori con []
+# Nota: le chiavi dei dizionari devono essere di tipo immutabile. Questo per
+# assicurare che le chiavi possano essere convertite in calori hash costanti
+# per un risposta più veloce.
+invalid_dict = {[1,2,3]: "123"} # => Emette un TypeError: unhashable type: 'list'
+valid_dict = {(1,2,3):[1,2,3]} # I valori, invece, possono essere di qualunque tipo
+
+# Accedi ai valori indicando la chiave tra []
filled_dict["uno"] # => 1
-# Ottieni tutte le chiavi come una lista con "keys()"
-filled_dict.keys() # => ["tre", "due", "uno"]
+# Puoi ottenere tutte le chiavi di un dizionario con "keys()"
+# (come oggetto iterabile). Per averle in formato lista è necessario
+# utilizzare list().
# Nota - Nei dizionari l'ordine delle chiavi non è garantito.
# Il tuo risultato potrebbe non essere uguale a questo.
+list(filled_dict.keys()) # => ["tre", "due", "uno"]
-# Ottieni tutt i valori come una lista con "values()"
-filled_dict.values() # => [3, 2, 1]
-# Nota - Come sopra riguardo l'ordinamento delle chiavi.
-# Ottieni tutte le coppie chiave-valore, sotto forma di lista di tuple, utilizzando "items()"
-filled_dicts.items() # => [("uno", 1), ("due", 2), ("tre", 3)]
+# Puoi ottenere tutti i valori di un dizionario con "values()"
+# (come oggetto iterabile).
+# Anche in questo caso, er averle in formato lista, è necessario utilizzare list()
+# Anche in questo caso, come per le chiavi, l'ordine non è garantito
+list(filled_dict.values()) # => [3, 2, 1]
# Controlla l'esistenza delle chiavi in un dizionario con "in"
"uno" in filled_dict # => True
-1 in filled_dict # => False
+1 in filled_dict # => False
-# Cercando una chiave non esistente è un KeyError
+# Cercando una chiave non esistente genera un KeyError
filled_dict["quattro"] # KeyError
# Usa il metodo "get()" per evitare KeyError
-filled_dict.get("uno") # => 1
-filled_dict.get("quattro") # => None
+filled_dict.get("uno") # => 1
+filled_dict.get("quattro") # => None
# Il metodo get supporta un argomento di default quando il valore è mancante
filled_dict.get("uno", 4) # => 1
filled_dict.get("quattro", 4) # => 4
-# nota che filled_dict.get("quattro") è ancora => None
-# (get non imposta il valore nel dizionario)
-# imposta il valore di una chiave con una sintassi simile alle liste
-filled_dict["quattro"] = 4 # ora, filled_dict["quattro"] => 4
-# "setdefault()" aggiunge al dizionario solo se la chiave data non è presente
-filled_dict.setdefault("five", 5) # filled_dict["five"] è impostato a 5
-filled_dict.setdefault("five", 6) # filled_dict["five"] è ancora 5
+# "setdefault()" inserisce un valore per una chiave in un dizionario
+# solo se la chiave data non è già presente
+filled_dict.setdefault("cinque", 5) # filled_dict["cinque"] viene impostato a 5
+filled_dict.setdefault("cinque", 6) # filled_dict["cinque"] rimane 5
+# Aggiungere una coppia chiave->valore a un dizionario
+filled_dict.update({"quattro":4}) # => {"uno": 1, "due": 2, "tre": 3, "quattro": 4}
+filled_dict["quattro"] = 4 # un altro modo pe aggiungere a un dizionario
-# Sets immagazzina ... sets (che sono come le liste, ma non possono contenere doppioni)
-empty_set = set()
-# Inizializza un "set()" con un po' di valori
-some_set = set([1, 2, 2, 3, 4]) # some_set è ora set([1, 2, 3, 4])
+# Rimuovi una chiave da un dizionario con del
+del filled_dict["uno"] # Rimuove la chiave "uno" dal dizionario
-# l'ordine non è garantito, anche se a volta può sembrare ordinato
-another_set = set([4, 3, 2, 2, 1]) # another_set è ora set([1, 2, 3, 4])
+# Da Python 3.5 puoi anche usare ulteriori opzioni di spacchettamento
+{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2}
+{'a': 1, **{'a': 2}} # => {'a': 2}
-# Da Python 2.7, {} può essere usato per dichiarare un set
-filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
+# I set sono come le liste ma non possono contenere doppioni
+empty_set = set()
+# Inizializza un "set()" con un dei valori. Sì, sembra un dizionario.
+some_set = {1, 1, 2, 2, 3, 4} # set_nuovo è {1, 2, 3, 4}
+
+# Come le chiavi di un dizionario, gli elementi di un set devono essere
+# di tipo immutabile
+invalid_set = {[1], 1} # => Genera un "TypeError: unhashable type: 'list'""
+valid_set = {(1,), 1}
-# Aggiungere elementi ad un set
-filled_set.add(5) # filled_set è ora {1, 2, 3, 4, 5}
+# Aggiungere uno o più elementi ad un set
+some_set.add(5) # some_set ora è {1, 2, 3, 4, 5}
# Fai intersezioni su un set con &
other_set = {3, 4, 5, 6}
-filled_set & other_set # => {3, 4, 5}
+some_set & other_set # => {3, 4, 5}
# Fai unioni su set con |
-filled_set | other_set # => {1, 2, 3, 4, 5, 6}
+some_set | other_set # => {1, 2, 3, 4, 5, 6}
# Fai differenze su set con -
-{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
# Effettua la differenza simmetrica con ^
{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5}
@@ -361,65 +377,77 @@ filled_set | other_set # => {1, 2, 3, 4, 5, 6}
{1, 2} <= {1, 2, 3} # => True
# Controlla l'esistenza in un set con in
-2 in filled_set # => True
-10 in filled_set # => False
+2 in some_set # => True
+10 in some_set # => False
+
####################################################
-## 3. Control Flow
+## 3. Control Flow e oggetti Iterabili
####################################################
-# Dichiariamo una variabile
+# Dichiariamo una variabile
some_var = 5
# Questo è un controllo if. L'indentazione è molto importante in python!
-# stampa "some_var è più piccola di 10"
+# Come convenzione si utilizzano quattro spazi, non la tabulazione.
+# Il seguente codice stampa "some_var è minore di 10"
if some_var > 10:
- print "some_var è decisamente più grande di 10."
-elif some_var < 10: # Questa clausola elif è opzionale.
- print "some_var è più piccola di 10."
-else: # Anche questo è opzionale.
- print "some_var è precisamente 10."
-
+ print("some_var è maggiore di 10")
+elif some_var < 10: # La clausolo elif è opzionale
+ print("some_var è minore di 10")
+else: # Anche else è opzionale
+ print("some_var è 10.")
"""
-I cicli for iterano sulle liste
-stampa:
+I cicli for iterano sulle liste, cioè ripetono un codice per ogni elemento
+di una lista.
+Il seguente codice scriverà:
cane è un mammifero
gatto è un mammifero
topo è un mammifero
"""
for animale in ["cane", "gatto", "topo"]:
- # Puoi usare {0} per interpolare le stringhe formattate. (Vedi di seguito.)
- print "{0} è un mammifero".format(animale)
+ # Puoi usare format() per interpolare le stringhe formattate.
+ print("{} è un mammifero".format(animale))
"""
-"range(numero)" restituisce una lista di numeri
-da zero al numero dato
-stampa:
+"range(numero)" restituisce una lista di numeri da zero al numero dato
+Il seguente codice scriverà:
0
1
2
3
"""
for i in range(4):
- print i
+ print(i)
"""
-"range(lower, upper)" restituisce una lista di numeri
-dal più piccolo (lower) al più grande (upper)
-stampa:
+"range(lower, upper)" restituisce una lista di numeri dal più piccolo (lower)
+al più grande (upper).
+Il seguente codice scriverà:
4
5
6
7
"""
for i in range(4, 8):
- print i
+ print(i)
"""
+"range(lower, upper, step)" rrestituisce una lista di numeri dal più piccolo
+(lower) al più grande (upper), incrementando del valore step.
+Se step non è indicato, avrà come valore di default 1.
+Il seguente codice scriverà:
+ 4
+ 6
+"""
+for i in range(4, 8, 2):
+ print(i)
+"""
+
I cicli while vengono eseguiti finchè una condizione viene a mancare
-stampa:
+Il seguente codice scriverà:
0
1
2
@@ -427,28 +455,62 @@ stampa:
"""
x = 0
while x < 4:
- print x
+ print(x)
x += 1 # Forma compatta per x = x + 1
-# Gestisci le eccezioni con un blocco try/except
-
-# Funziona da Python 2.6 in su:
+# Gestione delle eccezioni con un blocco try/except
try:
# Usa "raise" per generare un errore
- raise IndexError("Questo è un errore di indice")
+ raise IndexError("Questo è un IndexError")
except IndexError as e:
- pass # Pass è solo una non-operazione. Solitamente vorrai fare un recupero.
+ pass # Pass è solo una non-operazione. Solitamente vorrai rimediare all'errore.
except (TypeError, NameError):
pass # Eccezioni multiple possono essere gestite tutte insieme, se necessario.
-else: # Clausola opzionale al blocco try/except. Deve seguire tutti i blocchi except
- print "Tutto ok!" # Viene eseguita solo se il codice dentro try non genera eccezioni
+else: # Clausola opzionale al blocco try/except. Deve essere dopo tutti i blocchi except
+ print("Tutto ok!") # Viene eseguita solo se il codice dentro try non genera eccezioni
finally: # Eseguito sempre
- print "Possiamo liberare risorse qui"
+ print("Possiamo liberare risorse qui")
-# Invece di try/finally per liberare risorse puoi usare il metodo with
+# Se ti serve solo un try/finally, per liberare risorse, puoi usare il metodo with
with open("myfile.txt") as f:
for line in f:
- print line
+ print(line)
+
+# In Python qualunque oggetto in grado di essere trattato come una
+# sequenza è definito un oggetto Iterable (itarabile).
+# L'oggetto restituito da una funzione range è un iterabile.
+
+filled_dict = {"uno": 1, "due": 2, "tre": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) # => dict_keys(['uno', 'due', 'tre']).
+# Questo è un oggetto che implementa la nostra interfaccia Iterable.
+
+# È possibile utilizzarlo con i loop:
+for i in our_iterable:
+ print(i) # Scrive uno, due, tre
+
+# Tuttavia non possiamo recuperarne i valori tramite indice.
+our_iterable[1] # Genera un TypeError
+
+# Un oggetto iterabile è in grado di generare un iteratore
+our_iterator = iter(our_iterable)
+
+# L'iteratore è un oggetto che ricorda il suo stato mentro lo si "attraversa"
+# Possiamo accedere al successivo elemento con "next()".
+next(our_iterator) # => "uno"
+
+# Mantiene il suo stato mentro eseguiamo l'iterazione
+next(our_iterator) # => "due"
+next(our_iterator) # => "tre"
+
+# Dopo che un iteratore ha restituito tutti i suoi dati, genera
+# un'eccezione StopIteration
+next(our_iterator) # Raises StopIteration
+
+# Puoi prendere tutti gli elementi di un iteratore utilizzando list().
+list(filled_dict.keys()) # => Returns ["one", "two", "three"]
+
+
####################################################
## 4. Funzioni
@@ -456,23 +518,20 @@ with open("myfile.txt") as f:
# Usa "def" per creare nuove funzioni
def aggiungi(x, y):
- print "x è {0} e y è {1}".format(x, y)
- return x + y # Restituisce valori con il metodo return
+ print("x è {} e y è {}".format(x, y)) // Scrive i valori formattati in una stringa
+ return x + y # Restituisce la somma dei valori con il metodo return
# Chiamare funzioni con parametri
-aggiungi(5, 6) # => stampa "x è 5 e y è 6" e restituisce 11
+aggiungi(5, 6) # => scrive "x è 5 e y è 6" e restituisce 11
# Un altro modo per chiamare funzioni è con parole chiave come argomenti
-aggiungi(y=6, x=5) # Le parole chiave come argomenti possono arrivare in ogni ordine.
+aggiungi(y=6, x=5) # In questo modo non è necessario rispettare l'ordine degli argomenti
-
-# Puoi definire funzioni che accettano un numero variabile di argomenti posizionali
-# che verranno interpretati come tuple usando il *
+# Puoi definire funzioni che accettano un numero non definito di argomenti
def varargs(*args):
return args
-varargs(1, 2, 3) # => (1, 2, 3)
-
+varargs(1, 2, 3) # => (1, 2, 3)
# Puoi definire funzioni che accettano un numero variabile di parole chiave
# come argomento, che saranno interpretati come un dizionario usando **
@@ -485,8 +544,8 @@ keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
# Puoi farle entrambi in una volta, se ti va
def all_the_args(*args, **kwargs):
- print args
- print kwargs
+ print(args)
+ print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) stampa:
(1, 2)
@@ -494,38 +553,44 @@ all_the_args(1, 2, a=3, b=4) stampa:
"""
# Quando chiami funzioni, puoi fare l'opposto di args/kwargs!
-# Usa * per sviluppare gli argomenti posizionale ed usa ** per espandere gli argomenti parola chiave
+# Usa * per sviluppare gli argomenti posizionale ed usa ** per
+# espandere gli argomenti parola chiave
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # equivalente a foo(1, 2, 3, 4)
-all_the_args(**kwargs) # equivalente a foo(a=3, b=4)
-all_the_args(*args, **kwargs) # equivalente a foo(1, 2, 3, 4, a=3, b=4)
-
-# puoi passare args e kwargs insieme alle altre funzioni che accettano args/kwargs
-# sviluppandoli, rispettivamente, con * e **
-def pass_all_the_args(*args, **kwargs):
- all_the_args(*args, **kwargs)
- print varargs(*args)
- print keyword_args(**kwargs)
-
-# Funzioni Scope
+all_the_args(*args) # equivalente a foo(1, 2, 3, 4)
+all_the_args(**kwargs) # equivalente a foo(a=3, b=4)
+all_the_args(*args, **kwargs) # equivalente a foo(1, 2, 3, 4, a=3, b=4)
+
+
+# Restituire valori multipli (with tuple assignments)
+def swap(x, y):
+ return y, x # Restituisce valori multipli come tupla senza parentesi
+ # (Nota: le parentesi sono state escluse ma possono essere messe)
+
+x = 1
+y = 2
+x, y = swap(x, y) # => x = 2, y = 1
+# (x, y) = swap(x,y) # Le parentesi sono state escluse ma possono essere incluse.
+
+# Funzioni - Visibilità delle variabili (variable scope)
x = 5
def set_x(num):
- # La variabile locale x non è uguale alla variabile globale x
- x = num # => 43
- print x # => 43
+ # La variabile locale x non è la variabile globale x
+ x = num # => 43
+ print(x) # => 43
def set_global_x(num):
global x
- print x # => 5
- x = num # la variabile globable x è ora 6
- print x # => 6
+ print(x) # => 5
+ x = num # la variabile globable x è ora 6
+ print(x) # => 6
set_x(43)
set_global_x(6)
-# Python ha funzioni di prima classe
+
+# Python ha "first class functions"
def create_adder(x):
def adder(y):
return x + y
@@ -535,204 +600,381 @@ add_10 = create_adder(10)
add_10(3) # => 13
# Ci sono anche funzioni anonime
-(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
-# Esse sono incluse in funzioni di alto livello
-map(add_10, [1, 2, 3]) # => [11, 12, 13]
-map(max, [1, 2, 3], [4, 2, 1]) # => [4, 2, 3]
+# È possibile creare "mappe" e "filtri"
+list(map(add_10, [1, 2, 3])) # => [11, 12, 13]
+list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7]
-# Possiamo usare la comprensione delle liste per mappe e filtri
-[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]
+# Possiamo usare le "list comprehensions" per mappe e filtri
+# Le "list comprehensions" memorizzano l'output come una lista che può essere
+# di per sé una lista annidata
+[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]
# Puoi fare anche la comprensione di set e dizionari
-{x for x in 'abcddeef' if x in 'abc'} # => {'d', 'e', 'f'}
+{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. Classi
+## 5. Modules
+####################################################
+
+# Puoi importare moduli
+import math
+print(math.sqrt(16)) # => 4.0
+
+# Puoi ottenere specifiche funzione da un modulo
+from math import ceil, floor
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
+
+# Puoi importare tutte le funzioni da un modulo
+# Attenzione: questo non è raccomandato
+from math import *
+
+# Puoi abbreviare i nomi dei moduli
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
+
+
+# I moduli di Python sono normali file python. Ne puoi
+# scrivere di tuoi ed importarli. Il nome del modulo
+# è lo stesso del nome del file.
+
+# Potete scoprire quali funzioni e attributi
+# sono definiti in un modulo
+import math
+dir(math)
+
+# Se nella cartella corrente hai uno script chiamato math.py,
+# Python caricherà quello invece del modulo math.
+# Questo succede perchè la cartella corrente ha priorità
+# sulle librerie standard di Python
+
+# Se hai uno script Python chiamato math.py nella stessa
+# cartella del tua script, Python caricherà quello al posto del
+# comune modulo math.
+# Questo accade perché la cartella locale ha la priorità
+# sulle librerie built-in di Python.
+
+
+####################################################
+## 6. Classes
####################################################
-# Usiamo una sottoclasse da un oggetto per avere una classe.
-class Human(object):
+# Usiamo l'istruzione "class" per creare una classe
+class Human:
- # Un attributo della classe. E' condiviso da tutte le istanze delle classe
+ # Un attributo della classe. E' condiviso tra tutte le istanze delle classe
species = "H. sapiens"
- # Costruttore base, richiamato quando la classe viene inizializzata.
- # Si noti che il doppio leading e gli underscore finali denotano oggetti
- # o attributi che sono usati da python ma che vivono nello spazio dei nome controllato
- # dall'utente. Non dovresti usare nomi di questo genere.
+ # Si noti che i doppi underscore iniziali e finali denotano gli oggetti o
+ # attributi utilizzati da Python ma che vivono nel namespace controllato
+ # dall'utente
+ # Metodi, oggetti o attributi come: __init__, __str__, __repr__, etc. sono
+ # chiamati metodi speciali (o talvolta chiamati "dunder methods").
+ # Non dovresti inventare tali nomi da solo.
+
def __init__(self, name):
# Assegna l'argomento all'attributo name dell'istanza
self.name = name
# Inizializza una proprietà
- self.age = 0
+ self._age = 0
# Un metodo dell'istanza. Tutti i metodi prendo "self" come primo argomento
def say(self, msg):
- return "{0}: {1}".format(self.name, msg)
+ print("{name}: {message}".format(name=self.name, message=msg))
+
+ # Un altro metodo dell'istanza
+ def sing(self):
+ return 'yo... yo... microphone check... one two... one two...'
# Un metodo della classe è condiviso fra tutte le istanze
- # Sono chiamate con la classe chiamante come primo argomento
+ # Sono chiamati con la classe chiamante come primo argomento
@classmethod
def get_species(cls):
return cls.species
- # Un metodo statico è chiamato senza una classe od una istanza di riferimento
+ # Un metodo statico è chiamato senza classe o istanza di riferimento
@staticmethod
def grunt():
return "*grunt*"
- # Una proprietà è come un metodo getter.
- # Trasforma il metodo age() in un attributo in sola lettura, che ha lo stesso nome
+ # Una property è come un metodo getter.
+ # Trasforma il metodo age() in un attributo in sola lettura, che ha
+ # lo stesso nome
+ # In Python non c'è bisogno di scrivere futili getter e setter.
@property
def age(self):
return self._age
- # Questo metodo permette di modificare la proprietà
+ # Questo metodo permette di modificare una property
@age.setter
def age(self, age):
self._age = age
- # Questo metodo permette di cancellare la proprietà
+ # Questo metodo permette di cancellare una property
@age.deleter
def age(self):
del self._age
-# Instanziare una classe
-i = Human(name="Ian")
-print i.say("hi") # stampa "Ian: hi"
+# Quando l'interprete Python legge un sorgente esegue tutto il suo codice.
+# Questo controllo su __name__ assicura che questo blocco di codice venga
+# eseguito solo quando questo modulo è il programma principale.
+
+if __name__ == '__main__':
+ # Crea un'istanza della classe
+ i = Human(name="Ian")
+ i.say("hi") # "Ian: hi"
+ j = Human("Joel")
+ j.say("hello") # "Joel: hello"
+ # i e j sono istanze del tipo Human, o in altre parole sono oggetti Human
+
+ # Chiama un metodo della classe
+ i.say(i.get_species()) # "Ian: H. sapiens"
+ # Cambia l'attributo condiviso
+ Human.species = "H. neanderthalensis"
+ i.say(i.get_species()) # => "Ian: H. neanderthalensis"
+ j.say(j.get_species()) # => "Joel: H. neanderthalensis"
+
+ # Chiama un metodo statico
+ print(Human.grunt()) # => "*grunt*"
+
+ # Non è possibile chiamare il metodo statico con l'istanza dell'oggetto
+ # poiché i.grunt() metterà automaticamente "self" (l'oggetto i)
+ # come argomento
+ print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
+
+ # Aggiorna la property (age) di questa istanza
+ i.age = 42
+ # Leggi la property
+ i.say(i.age) # => "Ian: 42"
+ j.say(j.age) # => "Joel: 0"
+ # Cancella la property
+ del i.age
+ i.age # => questo genererà un AttributeError
-j = Human("Joel")
-print j.say("hello") # stampa "Joel: hello"
-# Chiamare metodi della classe
-i.get_species() # => "H. sapiens"
+####################################################
+## 6.1 Ereditarietà (Inheritance)
+####################################################
-# Cambiare l'attributo condiviso
-Human.species = "H. neanderthalensis"
-i.get_species() # => "H. neanderthalensis"
-j.get_species() # => "H. neanderthalensis"
+# L'ereditarietà consente di definire nuove classi figlio che ereditano metodi e
+# variabili dalla loro classe genitore.
-# Chiamare il metodo condiviso
-Human.grunt() # => "*grunt*"
+# Usando la classe Human definita sopra come classe base o genitore, possiamo
+# definire una classe figlia, Superhero, che erediterà le variabili di classe
+# come "species", "name" e "age", così come i metodi, come "sing" e "grunt",
+# dalla classe Human, ma potrà anche avere le sue proprietà uniche.
-# Aggiorna la proprietà
-i.age = 42
+# Per importare le funzioni da altri file usa il seguente formato
+# from "nomefile-senza-estensione" import "funzione-o-classe"
-# Ritorna il valore della proprietà
-i.age # => 42
+from human import Human
-# Cancella la proprietà
-del i.age
-i.age # => Emette un AttributeError
+# Specificare le classi genitore come parametri della definizione della classe
+class Superhero(Human):
+ # Se la classe figlio deve ereditare tutte le definizioni del genitore
+ # senza alcuna modifica, puoi semplicemente usare la parola chiave "pass"
+ # (e nient'altro)
-####################################################
-## 6. Moduli
-####################################################
+ #Le classi figlio possono sovrascrivere gli attributi dei loro genitori
+ species = 'Superhuman'
-# Puoi importare moduli
-import math
-print math.sqrt(16) # => 4
+ # Le classi figlie ereditano automaticamente il costruttore della classe
+ # genitore, inclusi i suoi argomenti, ma possono anche definire ulteriori
+ # argomenti o definizioni e sovrascrivere i suoi metodi (compreso il
+ # costruttore della classe).
+ # Questo costruttore eredita l'argomento "nome" dalla classe "Human" e
+ # aggiunge gli argomenti "superpowers" e "movie":
-# Puoi ottenere specifiche funzione da un modulo
-from math import ceil, floor
-print ceil(3.7) # => 4.0
-print floor(3.7) # => 3.0
+ def __init__(self, name, movie=False,
+ superpowers=["super strength", "bulletproofing"]):
-# Puoi importare tutte le funzioni da un modulo
-# Attenzione: questo non è raccomandato
-from math import *
+ # aggiungi ulteriori attributi della classe
+ self.fictional = True
+ self.movie = movie
+ self.superpowers = superpowers
-# Puoi abbreviare i nomi dei moduli
-import math as m
-math.sqrt(16) == m.sqrt(16) # => True
-# puoi anche verificare che le funzioni sono equivalenti
-from math import sqrt
-math.sqrt == m.sqrt == sqrt # => True
+ # La funzione "super" ti consente di accedere ai metodi della classe
+ # genitore che sono stati sovrascritti dalla classe figlia,
+ # in questo caso il metodo __init__.
+ # Il seguente codice esegue il costruttore della classe genitore:
+ super().__init__(name)
-# I moduli di Python sono normali file python. Ne puoi
-# scrivere di tuoi ed importarli. Il nome del modulo
-# è lo stesso del nome del file.
+ # Sovrascrivere il metodo "sing"
+ def sing(self):
+ return 'Dun, dun, DUN!'
-# Potete scoprire quali funzioni e attributi
-# definiscono un modulo
-import math
-dir(math)
+ # Aggiungi un ulteriore metodo dell'istanza
+ def boast(self):
+ for power in self.superpowers:
+ print("I wield the power of {pow}!".format(pow=power))
-# Se nella cartella corrente hai uno script chiamato math.py,
-# Python caricherà quello invece del modulo math.
-# Questo succede perchè la cartella corrente ha priorità
-# sulle librerie standard di Python
+if __name__ == '__main__':
+ sup = Superhero(name="Tick")
+
+ # Controllo del tipo di istanza
+ if isinstance(sup, Human):
+ print('I am human')
+ if type(sup) is Superhero:
+ print('I am a superhero')
+
+ # Ottieni il "Method Resolution search Order" usato sia da getattr ()
+ # che da super (). Questo attributo è dinamico e può essere aggiornato
+ print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
+ # => <class 'human.Human'>, <class 'object'>)
+
+ # Esegui il metodo principale ma utilizza il proprio attributo di classe
+ print(sup.get_species()) # => Superhuman
+
+ # Esegui un metodo che è stato sovrascritto
+ print(sup.sing()) # => Dun, dun, DUN!
+
+ # Esegui un metodo di Human
+ sup.say('Spoon') # => Tick: Spoon
+
+ # Esegui un metodo che esiste solo in Superhero
+ sup.boast() # => I wield the power of super strength!
+ # => I wield the power of bulletproofing!
+
+ # Attributo di classe ereditato
+ sup.age = 31
+ print(sup.age) # => 31
+
+ # Attributo che esiste solo in Superhero
+ print('Am I Oscar eligible? ' + str(sup.movie))
####################################################
-## 7. Avanzate
+## 6.2 Ereditarietà multipla
####################################################
-# Generatori
-# Un generatore appunto "genera" valori solo quando vengono richiesti,
-# invece di memorizzarli tutti subito fin dall'inizio
+# Un'altra definizione di classe
+# bat.py
+class Bat:
-# Il metodo seguente (che NON è un generatore) raddoppia tutti i valori e li memorizza
-# dentro `double_arr`. Se gli oggetti iterabili sono grandi, il vettore risultato
-# potrebbe diventare enorme!
-def double_numbers(iterable):
- double_arr = []
- for i in iterable:
- double_arr.append(i + i)
+ species = 'Baty'
-# Eseguendo il seguente codice, noi andiamo a raddoppiare prima tutti i valori, e poi
-# li ritorniamo tutti e andiamo a controllare la condizione
-for value in double_numbers(range(1000000)): # `test_senza_generatore`
- print value
- if value > 5:
- break
+ def __init__(self, can_fly=True):
+ self.fly = can_fly
+
+ # Questa classe ha anche un metodo "say"
+ def say(self, msg):
+ msg = '... ... ...'
+ return msg
+
+ # E anche un suo metodo personale
+ def sonar(self):
+ return '))) ... ((('
+
+if __name__ == '__main__':
+ b = Bat()
+ print(b.say('hello'))
+ print(b.fly)
+
+# Definizione di classe che eredita da Superhero e Bat
+# superhero.py
+from superhero import Superhero
+from bat import Bat
+
+# Definisci Batman come classe figlia che eredita sia da Superhero che da Bat
+class Batman(Superhero, Bat):
+
+ def __init__(self, *args, **kwargs):
+ # In genere per ereditare gli attributi devi chiamare super:
+ # super(Batman, self).__init__(*args, **kwargs)
+ # Ma qui abbiamo a che fare con l'ereditarietà multipla, e super()
+ # funziona solo con la successiva classe nell'elenco MRO.
+ # Quindi, invece, chiamiamo esplicitamente __init__ per tutti gli
+ # antenati. L'uso di *args e **kwargs consente di passare in modo
+ # pulito gli argomenti, con ciascun genitore che "sbuccia un
+ # livello della cipolla".
+ Superhero.__init__(self, 'anonymous', movie=True,
+ superpowers=['Wealthy'], *args, **kwargs)
+ Bat.__init__(self, *args, can_fly=False, **kwargs)
+ # sovrascrivere il valore per l'attributo name
+ self.name = 'Sad Affleck'
-# Invece, potremmo usare un generatore per "generare" il valore raddoppiato non
-# appena viene richiesto
-def double_numbers_generator(iterable):
+ def sing(self):
+ return 'nan nan nan nan nan batman!'
+
+
+if __name__ == '__main__':
+ sup = Batman()
+
+ # Ottieni il "Method Resolution search Order" utilizzato da getattr() e super().
+ # Questo attributo è dinamico e può essere aggiornato
+ print(Batman.__mro__) # => (<class '__main__.Batman'>,
+ # => <class 'superhero.Superhero'>,
+ # => <class 'human.Human'>,
+ # => <class 'bat.Bat'>, <class 'object'>)
+
+ # Esegui il metodo del genitore ma utilizza il proprio attributo di classe
+ print(sup.get_species()) # => Superhuman
+
+ # Esegui un metodo che è stato sovrascritto
+ print(sup.sing()) # => nan nan nan nan nan batman!
+
+ # Esegui un metodo da Human, perché l'ordine di ereditarietà è importante
+ sup.say('I agree') # => Sad Affleck: I agree
+
+ # Esegui un metodo che esiste solo nel 2o antenato
+ print(sup.sonar()) # => ))) ... (((
+
+ # Attributo di classe ereditato
+ sup.age = 100
+ print(sup.age) # => 100
+
+ # Attributo ereditato dal secondo antenato il cui valore predefinito
+ # è stato ignorato.
+ print('Can I fly? ' + str(sup.fly)) # => Can I fly? False
+
+
+
+####################################################
+## 7. Advanced
+####################################################
+
+# I generatori ti aiutano a creare codice pigro (lazy code).
+# Codice che darà un risultato solo quando sarà "valutato"
+def double_numbers(iterable):
for i in iterable:
yield i + i
-# Utilizzando lo stesso test di prima, stavolta però con un generatore, ci permette
-# di iterare sui valori e raddoppiarli uno alla volta, non appena vengono richiesti dalla
-# logica del programma. Per questo, non appena troviamo un valore > 5, usciamo dal ciclo senza
-# bisogno di raddoppiare la maggior parte dei valori del range (MOLTO PIU VELOCE!)
-for value in double_numbers_generator(xrange(1000000)): # `test_generatore`
- print value
- if value > 5:
+# I generatori sono efficienti in termini di memoria perché caricano
+# solo i dati necessari per elaborare il valore successivo nell'iterabile.
+# Ciò consente loro di eseguire operazioni su intervalli di valori
+# altrimenti proibitivi.
+# NOTA: `range` sostituisce` xrange` in Python 3.
+for i in double_numbers(range(1, 900000000)): # `range` is a generator.
+ print(i)
+ if i >= 30:
break
-# Nota: hai notato l'uso di `range` in `test_senza_generatore` e `xrange` in `test_generatore`?
-# Proprio come `double_numbers_generator` è la versione col generatore di `double_numbers`
-# Abbiamo `xrange` come versione col generatore di `range`
-# `range` ritorna un array di 1000000 elementi
-# `xrange` invece genera 1000000 valori quando lo richiediamo/iteriamo su di essi
-
-# Allo stesso modo della comprensione delle liste, puoi creare la comprensione
-# dei generatori.
+# Proprio come è possibile creare una "list comprehension", è possibile
+# creare anche delle "generator comprehensions".
values = (-x for x in [1,2,3,4,5])
for x in values:
- print(x) # stampa -1 -2 -3 -4 -5
+ print(x) # prints -1 -2 -3 -4 -5 to console/terminal
-# Puoi anche fare il cast diretto di una comprensione di generatori ad una lista.
+# Puoi anche trasmettere una "generator comprehensions" direttamente
+# ad un elenco.
values = (-x for x in [1,2,3,4,5])
gen_to_list = list(values)
print(gen_to_list) # => [-1, -2, -3, -4, -5]
# Decoratori
-# in questo esempio beg include say
-# Beg chiamerà say. Se say_please è True allora cambierà il messaggio
-# ritornato
+# In questo esempio "beg" avvolge/wrappa "say".
+# Se say_please è True, cambierà il messaggio restituito.
from functools import wraps
def beg(target_function):
@@ -752,8 +994,8 @@ def say(say_please=False):
return msg, say_please
-print say() # Puoi comprarmi una birra?
-print say(say_please=True) # Puoi comprarmi una birra? Per favore! Sono povero :(
+print(say()) # Puoi comprarmi una birra?
+print(say(say_please=True)) # Puoi comprarmi una birra? Per favore! Sono povero :(
```
## Pronto per qualcosa di più?
@@ -761,18 +1003,14 @@ print say(say_please=True) # Puoi comprarmi una birra? Per favore! Sono povero
### Gratis Online
* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
-* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
-* [Dive Into Python](http://www.diveintopython.net/)
-* [The Official Docs](http://docs.python.org/2/)
+* [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 Module of the Week](http://pymotw.com/2/)
-* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+* [Python Course](http://www.python-course.eu/index.php)
* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
-* [LearnPython](http://www.learnpython.org/)
-* [Fullstack Python](https://www.fullstackpython.com/)
-
-### Libri cartacei
-
-* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
-* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
-* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+* [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/it-it/pythonlegacy-it.html.markdown b/it-it/pythonlegacy-it.html.markdown
new file mode 100644
index 00000000..4c8b2a17
--- /dev/null
+++ b/it-it/pythonlegacy-it.html.markdown
@@ -0,0 +1,778 @@
+---
+language: Python 2 (legacy)
+filename: learnpythonlegacy-it.py
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+ - ["Amin Bandali", "http://aminbandali.com"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+ - ["evuez", "http://github.com/evuez"]
+translators:
+ - ["Ale46", "http://github.com/Ale46/"]
+ - ["Tommaso Pifferi", "http://github.com/neslinesli93/"]
+lang: it-it
+---
+Python è stato creato da Guido Van Rossum agli inizi degli anni 90. Oggi è uno dei più popolari
+linguaggi esistenti. Mi sono innamorato di Python per la sua chiarezza sintattica. E' sostanzialmente
+pseudocodice eseguibile.
+
+Feedback sono altamente apprezzati! Potete contattarmi su [@louiedinh](http://twitter.com/louiedinh) oppure [at] [google's email service]
+
+Nota: questo articolo è riferito a Python 2.7 in modo specifico, ma dovrebbe andar
+bene anche per Python 2.x. Python 2.7 sta raggiungendo il "fine vita", ovvero non sarà
+più supportato nel 2020. Quindi è consigliato imparare Python utilizzando Python 3.
+Per maggiori informazioni su Python 3.x, dai un'occhiata al [tutorial di Python 3](http://learnxinyminutes.com/docs/python/).
+
+E' possibile anche scrivere codice compatibile sia con Python 2.7 che con Python 3.x,
+utilizzando [il modulo `__future__`](https://docs.python.org/2/library/__future__.html) di Python.
+Il modulo `__future__` permette di scrivere codice in Python 3, che può essere eseguito
+utilizzando Python 2: cosa aspetti a vedere il tutorial di Python 3?
+
+```python
+
+# I commenti su una sola linea iniziano con un cancelletto
+
+""" Più stringhe possono essere scritte
+ usando tre ", e sono spesso usate
+ come commenti
+"""
+
+####################################################
+## 1. Tipi di dati primitivi ed Operatori
+####################################################
+
+# Hai i numeri
+3 # => 3
+
+# La matematica è quello che vi aspettereste
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7
+
+# La divisione è un po' complicata. E' una divisione fra interi in cui viene
+# restituito in automatico il risultato intero.
+5 / 2 # => 2
+
+# Per le divisioni con la virgola abbiamo bisogno di parlare delle variabili floats.
+2.0 # Questo è un float
+11.0 / 4.0 # => 2.75 ahhh...molto meglio
+
+# Il risultato di una divisione fra interi troncati positivi e negativi
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # funziona anche per i floats
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
+
+# E' possibile importare il modulo "division" (vedi la sezione 6 di questa guida, Moduli)
+# per effettuare la divisione normale usando solo '/'.
+from __future__ import division
+11/4 # => 2.75 ...divisione normale
+11//4 # => 2 ...divisione troncata
+
+# Operazione Modulo
+7 % 3 # => 1
+
+# Elevamento a potenza (x alla y-esima potenza)
+2**4 # => 16
+
+# Forzare le precedenze con le parentesi
+(1 + 3) * 2 # => 8
+
+# Operatori Booleani
+# Nota "and" e "or" sono case-sensitive
+True and False #=> False
+False or True #=> True
+
+# Note sull'uso di operatori Bool con interi
+0 and 2 #=> 0
+-5 or 0 #=> -5
+0 == False #=> True
+2 == True #=> False
+1 == True #=> True
+
+# nega con not
+not True # => False
+not False # => True
+
+# Uguaglianza è ==
+1 == 1 # => True
+2 == 1 # => False
+
+# Disuguaglianza è !=
+1 != 1 # => False
+2 != 1 # => True
+
+# Altri confronti
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# I confronti possono essere concatenati!
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# Le stringhe sono create con " o '
+"Questa è una stringa."
+'Anche questa è una stringa.'
+
+# Anche le stringhe possono essere sommate!
+"Ciao " + "mondo!" # => Ciao mondo!"
+# Le stringhe possono essere sommate anche senza '+'
+"Ciao " "mondo!" # => Ciao mondo!"
+
+# ... oppure moltiplicate
+"Hello" * 3 # => "HelloHelloHello"
+
+# Una stringa può essere considerata come una lista di caratteri
+"Questa è una stringa"[0] # => 'Q'
+
+# Per sapere la lunghezza di una stringa
+len("Questa è una stringa") # => 20
+
+# Formattazione delle stringhe con %
+# Anche se l'operatore % per le stringe sarà deprecato con Python 3.1, e verrà rimosso
+# successivamente, può comunque essere utile sapere come funziona
+x = 'mela'
+y = 'limone'
+z = "La cesta contiene una %s e un %s" % (x,y)
+
+# Un nuovo modo per fomattare le stringhe è il metodo format.
+# Questo metodo è quello consigliato
+"{} è un {}".format("Questo", "test")
+"{0} possono essere {1}".format("le stringhe", "formattate")
+# Puoi usare delle parole chiave se non vuoi contare
+"{nome} vuole mangiare {cibo}".format(nome="Bob", cibo="lasagna")
+
+# None è un oggetto
+None # => None
+
+# Non usare il simbolo di uguaglianza "==" per comparare oggetti a None
+# Usa "is" invece
+"etc" is None # => False
+None is None # => True
+
+# L'operatore 'is' testa l'identità di un oggetto. Questo non è
+# molto utile quando non hai a che fare con valori primitivi, ma lo è
+# quando hai a che fare con oggetti.
+
+# Qualunque oggetto può essere usato nei test booleani
+# I seguenti valori sono considerati falsi:
+# - None
+# - Lo zero, come qualunque tipo numerico (quindi 0, 0L, 0.0, 0.j)
+# - Sequenze vuote (come '', (), [])
+# - Contenitori vuoti (tipo {}, set())
+# - Istanze di classi definite dall'utente, che soddisfano certi criteri
+# vedi: https://docs.python.org/2/reference/datamodel.html#object.__nonzero__
+#
+# Tutti gli altri valori sono considerati veri: la funzione bool() usata su di loro, ritorna True.
+bool(0) # => False
+bool("") # => False
+
+
+####################################################
+## 2. Variabili e Collections
+####################################################
+
+# Python ha una funzione di stampa
+print "Sono Python. Piacere di conoscerti!" # => Sono Python. Piacere di conoscerti!
+
+# Un modo semplice per ricevere dati in input dalla riga di comando
+variabile_stringa_input = raw_input("Inserisci del testo: ") # Ritorna i dati letti come stringa
+variabile_input = input("Inserisci del testo: ") # Interpreta i dati letti come codice python
+# Attenzione: bisogna stare attenti quando si usa input()
+# Nota: In python 3, input() è deprecato, e raw_input() si chiama input()
+
+# Non c'è bisogno di dichiarare una variabile per assegnarle un valore
+una_variabile = 5 # Convenzionalmente si usa caratteri_minuscoli_con_underscores
+una_variabile # => 5
+
+# Accedendo ad una variabile non precedentemente assegnata genera un'eccezione.
+# Dai un'occhiata al Control Flow per imparare di più su come gestire le eccezioni.
+un_altra_variabile # Genera un errore di nome
+
+# if può essere usato come un'espressione
+# E' l'equivalente dell'operatore ternario in C
+"yahoo!" if 3 > 2 else 2 # => "yahoo!"
+
+# Liste immagazzinano sequenze
+li = []
+# Puoi partire con una lista pre-riempita
+altra_li = [4, 5, 6]
+
+# Aggiungi cose alla fine di una lista con append
+li.append(1) # li ora è [1]
+li.append(2) # li ora è [1, 2]
+li.append(4) # li ora è [1, 2, 4]
+li.append(3) # li ora è [1, 2, 4, 3]
+# Rimuovi dalla fine della lista con pop
+li.pop() # => 3 e li ora è [1, 2, 4]
+# Rimettiamolo a posto
+li.append(3) # li ora è [1, 2, 4, 3] di nuovo.
+
+# Accedi ad una lista come faresti con un array
+li[0] # => 1
+# Assegna nuovo valore agli indici che sono già stati inizializzati con =
+li[0] = 42
+li[0] # => 42
+li[0] = 1 # Nota: è resettato al valore iniziale
+# Guarda l'ultimo elemento
+li[-1] # => 3
+
+# Guardare al di fuori dei limiti è un IndexError
+li[4] # Genera IndexError
+
+# Puoi guardare gli intervalli con la sintassi slice (a fetta).
+# (E' un intervallo chiuso/aperto per voi tipi matematici.)
+li[1:3] # => [2, 4]
+# Ometti l'inizio
+li[2:] # => [4, 3]
+# Ometti la fine
+li[:3] # => [1, 2, 4]
+# Seleziona ogni seconda voce
+li[::2] # =>[1, 4]
+# Copia al contrario della lista
+li[::-1] # => [3, 4, 2, 1]
+# Usa combinazioni per fare slices avanzate
+# li[inizio:fine:passo]
+
+# Rimuovi arbitrariamente elementi da una lista con "del"
+del li[2] # li è ora [1, 2, 3]
+# Puoi sommare le liste
+li + altra_li # => [1, 2, 3, 4, 5, 6]
+# Nota: i valori per li ed altra_li non sono modificati.
+
+# Concatena liste con "extend()"
+li.extend(altra_li) # Ora li è [1, 2, 3, 4, 5, 6]
+
+# Rimuove la prima occorrenza di un elemento
+li.remove(2) # Ora li è [1, 3, 4, 5, 6]
+li.remove(2) # Emette un ValueError, poichè 2 non è contenuto nella lista
+
+# Inserisce un elemento all'indice specificato
+li.insert(1, 2) # li è di nuovo [1, 2, 3, 4, 5, 6]
+
+# Ritorna l'indice della prima occorrenza dell'elemento fornito
+li.index(2) # => 1
+li.index(7) # Emette un ValueError, poichè 7 non è contenuto nella lista
+
+# Controlla l'esistenza di un valore in una lista con "in"
+1 in li # => True
+
+# Esamina la lunghezza con "len()"
+len(li) # => 6
+
+
+# Tuple sono come le liste ma immutabili.
+tup = (1, 2, 3)
+tup[0] # => 1
+tup[0] = 3 # Genera un TypeError
+
+# Puoi fare tutte queste cose da lista anche sulle tuple
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# Puoi scompattare le tuple (o liste) in variabili
+a, b, c = (1, 2, 3) # a è ora 1, b è ora 2 and c è ora 3
+d, e, f = 4, 5, 6 # puoi anche omettere le parentesi
+# Le tuple sono create di default se non usi le parentesi
+g = 4, 5, 6 # => (4, 5, 6)
+# Guarda come è facile scambiare due valori
+e, d = d, e # d è ora 5 ed e è ora 4
+
+
+# Dizionari immagazzinano mappature
+empty_dict = {}
+# Questo è un dizionario pre-riempito
+filled_dict = {"uno": 1, "due": 2, "tre": 3}
+
+# Accedi ai valori con []
+filled_dict["uno"] # => 1
+
+# Ottieni tutte le chiavi come una lista con "keys()"
+filled_dict.keys() # => ["tre", "due", "uno"]
+# Nota - Nei dizionari l'ordine delle chiavi non è garantito.
+# Il tuo risultato potrebbe non essere uguale a questo.
+
+# Ottieni tutt i valori come una lista con "values()"
+filled_dict.values() # => [3, 2, 1]
+# Nota - Come sopra riguardo l'ordinamento delle chiavi.
+
+# Ottieni tutte le coppie chiave-valore, sotto forma di lista di tuple, utilizzando "items()"
+filled_dicts.items() # => [("uno", 1), ("due", 2), ("tre", 3)]
+
+# Controlla l'esistenza delle chiavi in un dizionario con "in"
+"uno" in filled_dict # => True
+1 in filled_dict # => False
+
+# Cercando una chiave non esistente è un KeyError
+filled_dict["quattro"] # KeyError
+
+# Usa il metodo "get()" per evitare KeyError
+filled_dict.get("uno") # => 1
+filled_dict.get("quattro") # => None
+# Il metodo get supporta un argomento di default quando il valore è mancante
+filled_dict.get("uno", 4) # => 1
+filled_dict.get("quattro", 4) # => 4
+# nota che filled_dict.get("quattro") è ancora => None
+# (get non imposta il valore nel dizionario)
+
+# imposta il valore di una chiave con una sintassi simile alle liste
+filled_dict["quattro"] = 4 # ora, filled_dict["quattro"] => 4
+
+# "setdefault()" aggiunge al dizionario solo se la chiave data non è presente
+filled_dict.setdefault("five", 5) # filled_dict["five"] è impostato a 5
+filled_dict.setdefault("five", 6) # filled_dict["five"] è ancora 5
+
+
+# Sets immagazzina ... sets (che sono come le liste, ma non possono contenere doppioni)
+empty_set = set()
+# Inizializza un "set()" con un po' di valori
+some_set = set([1, 2, 2, 3, 4]) # some_set è ora set([1, 2, 3, 4])
+
+# l'ordine non è garantito, anche se a volta può sembrare ordinato
+another_set = set([4, 3, 2, 2, 1]) # another_set è ora set([1, 2, 3, 4])
+
+# Da Python 2.7, {} può essere usato per dichiarare un set
+filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
+
+# Aggiungere elementi ad un set
+filled_set.add(5) # filled_set è ora {1, 2, 3, 4, 5}
+
+# Fai intersezioni su un set con &
+other_set = {3, 4, 5, 6}
+filled_set & other_set # => {3, 4, 5}
+
+# Fai unioni su set con |
+filled_set | other_set # => {1, 2, 3, 4, 5, 6}
+
+# Fai differenze su set con -
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+
+# Effettua la differenza simmetrica con ^
+{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5}
+
+# Controlla se il set a sinistra contiene quello a destra
+{1, 2} >= {1, 2, 3} # => False
+
+# Controlla se il set a sinistra è un sottoinsieme di quello a destra
+{1, 2} <= {1, 2, 3} # => True
+
+# Controlla l'esistenza in un set con in
+2 in filled_set # => True
+10 in filled_set # => False
+
+
+####################################################
+## 3. Control Flow
+####################################################
+
+# Dichiariamo una variabile
+some_var = 5
+
+# Questo è un controllo if. L'indentazione è molto importante in python!
+# stampa "some_var è più piccola di 10"
+if some_var > 10:
+ print "some_var è decisamente più grande di 10."
+elif some_var < 10: # Questa clausola elif è opzionale.
+ print "some_var è più piccola di 10."
+else: # Anche questo è opzionale.
+ print "some_var è precisamente 10."
+
+
+"""
+I cicli for iterano sulle liste
+stampa:
+ cane è un mammifero
+ gatto è un mammifero
+ topo è un mammifero
+"""
+for animale in ["cane", "gatto", "topo"]:
+ # Puoi usare {0} per interpolare le stringhe formattate. (Vedi di seguito.)
+ print "{0} è un mammifero".format(animale)
+
+"""
+"range(numero)" restituisce una lista di numeri
+da zero al numero dato
+stampa:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+"range(lower, upper)" restituisce una lista di numeri
+dal più piccolo (lower) al più grande (upper)
+stampa:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print i
+
+"""
+I cicli while vengono eseguiti finchè una condizione viene a mancare
+stampa:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # Forma compatta per x = x + 1
+
+# Gestisci le eccezioni con un blocco try/except
+
+# Funziona da Python 2.6 in su:
+try:
+ # Usa "raise" per generare un errore
+ raise IndexError("Questo è un errore di indice")
+except IndexError as e:
+ pass # Pass è solo una non-operazione. Solitamente vorrai fare un recupero.
+except (TypeError, NameError):
+ pass # Eccezioni multiple possono essere gestite tutte insieme, se necessario.
+else: # Clausola opzionale al blocco try/except. Deve seguire tutti i blocchi except
+ print "Tutto ok!" # Viene eseguita solo se il codice dentro try non genera eccezioni
+finally: # Eseguito sempre
+ print "Possiamo liberare risorse qui"
+
+# Invece di try/finally per liberare risorse puoi usare il metodo with
+with open("myfile.txt") as f:
+ for line in f:
+ print line
+
+####################################################
+## 4. Funzioni
+####################################################
+
+# Usa "def" per creare nuove funzioni
+def aggiungi(x, y):
+ print "x è {0} e y è {1}".format(x, y)
+ return x + y # Restituisce valori con il metodo return
+
+# Chiamare funzioni con parametri
+aggiungi(5, 6) # => stampa "x è 5 e y è 6" e restituisce 11
+
+# Un altro modo per chiamare funzioni è con parole chiave come argomenti
+aggiungi(y=6, x=5) # Le parole chiave come argomenti possono arrivare in ogni ordine.
+
+
+# Puoi definire funzioni che accettano un numero variabile di argomenti posizionali
+# che verranno interpretati come tuple usando il *
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) # => (1, 2, 3)
+
+
+# Puoi definire funzioni che accettano un numero variabile di parole chiave
+# come argomento, che saranno interpretati come un dizionario usando **
+def keyword_args(**kwargs):
+ return kwargs
+
+# Chiamiamola per vedere cosa succede
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
+
+
+# Puoi farle entrambi in una volta, se ti va
+def all_the_args(*args, **kwargs):
+ print args
+ print kwargs
+"""
+all_the_args(1, 2, a=3, b=4) stampa:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Quando chiami funzioni, puoi fare l'opposto di args/kwargs!
+# Usa * per sviluppare gli argomenti posizionale ed usa ** per espandere gli argomenti parola chiave
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # equivalente a foo(1, 2, 3, 4)
+all_the_args(**kwargs) # equivalente a foo(a=3, b=4)
+all_the_args(*args, **kwargs) # equivalente a foo(1, 2, 3, 4, a=3, b=4)
+
+# puoi passare args e kwargs insieme alle altre funzioni che accettano args/kwargs
+# sviluppandoli, rispettivamente, con * e **
+def pass_all_the_args(*args, **kwargs):
+ all_the_args(*args, **kwargs)
+ print varargs(*args)
+ print keyword_args(**kwargs)
+
+# Funzioni Scope
+x = 5
+
+def set_x(num):
+ # La variabile locale x non è uguale alla variabile globale x
+ x = num # => 43
+ print x # => 43
+
+def set_global_x(num):
+ global x
+ print x # => 5
+ x = num # la variabile globable x è ora 6
+ print x # => 6
+
+set_x(43)
+set_global_x(6)
+
+# Python ha funzioni di prima classe
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) # => 13
+
+# Ci sono anche funzioni anonime
+(lambda x: x > 2)(3) # => True
+(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
+
+# Esse sono incluse in funzioni di alto livello
+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]
+
+# Possiamo usare la comprensione delle liste per mappe e filtri
+[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]
+
+# Puoi fare anche la comprensione di set e dizionari
+{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}
+
+
+####################################################
+## 5. Classi
+####################################################
+
+# Usiamo una sottoclasse da un oggetto per avere una classe.
+class Human(object):
+
+ # Un attributo della classe. E' condiviso da tutte le istanze delle classe
+ species = "H. sapiens"
+
+ # Costruttore base, richiamato quando la classe viene inizializzata.
+ # Si noti che il doppio leading e gli underscore finali denotano oggetti
+ # o attributi che sono usati da python ma che vivono nello spazio dei nome controllato
+ # dall'utente. Non dovresti usare nomi di questo genere.
+ def __init__(self, name):
+ # Assegna l'argomento all'attributo name dell'istanza
+ self.name = name
+
+ # Inizializza una proprietà
+ self.age = 0
+
+ # Un metodo dell'istanza. Tutti i metodi prendo "self" come primo argomento
+ def say(self, msg):
+ return "{0}: {1}".format(self.name, msg)
+
+ # Un metodo della classe è condiviso fra tutte le istanze
+ # Sono chiamate con la classe chiamante come primo argomento
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Un metodo statico è chiamato senza una classe od una istanza di riferimento
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+ # Una proprietà è come un metodo getter.
+ # Trasforma il metodo age() in un attributo in sola lettura, che ha lo stesso nome
+ @property
+ def age(self):
+ return self._age
+
+ # Questo metodo permette di modificare la proprietà
+ @age.setter
+ def age(self, age):
+ self._age = age
+
+ # Questo metodo permette di cancellare la proprietà
+ @age.deleter
+ def age(self):
+ del self._age
+
+# Instanziare una classe
+i = Human(name="Ian")
+print i.say("hi") # stampa "Ian: hi"
+
+j = Human("Joel")
+print j.say("hello") # stampa "Joel: hello"
+
+# Chiamare metodi della classe
+i.get_species() # => "H. sapiens"
+
+# Cambiare l'attributo condiviso
+Human.species = "H. neanderthalensis"
+i.get_species() # => "H. neanderthalensis"
+j.get_species() # => "H. neanderthalensis"
+
+# Chiamare il metodo condiviso
+Human.grunt() # => "*grunt*"
+
+# Aggiorna la proprietà
+i.age = 42
+
+# Ritorna il valore della proprietà
+i.age # => 42
+
+# Cancella la proprietà
+del i.age
+i.age # => Emette un AttributeError
+
+
+####################################################
+## 6. Moduli
+####################################################
+
+# Puoi importare moduli
+import math
+print math.sqrt(16) # => 4.0
+
+# Puoi ottenere specifiche funzione da un modulo
+from math import ceil, floor
+print ceil(3.7) # => 4.0
+print floor(3.7) # => 3.0
+
+# Puoi importare tutte le funzioni da un modulo
+# Attenzione: questo non è raccomandato
+from math import *
+
+# Puoi abbreviare i nomi dei moduli
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
+# puoi anche verificare che le funzioni sono equivalenti
+from math import sqrt
+math.sqrt == m.sqrt == sqrt # => True
+
+# I moduli di Python sono normali file python. Ne puoi
+# scrivere di tuoi ed importarli. Il nome del modulo
+# è lo stesso del nome del file.
+
+# Potete scoprire quali funzioni e attributi
+# definiscono un modulo
+import math
+dir(math)
+
+# Se nella cartella corrente hai uno script chiamato math.py,
+# Python caricherà quello invece del modulo math.
+# Questo succede perchè la cartella corrente ha priorità
+# sulle librerie standard di Python
+
+
+####################################################
+## 7. Avanzate
+####################################################
+
+# Generatori
+# Un generatore appunto "genera" valori solo quando vengono richiesti,
+# invece di memorizzarli tutti subito fin dall'inizio
+
+# Il metodo seguente (che NON è un generatore) raddoppia tutti i valori e li memorizza
+# dentro `double_arr`. Se gli oggetti iterabili sono grandi, il vettore risultato
+# potrebbe diventare enorme!
+def double_numbers(iterable):
+ double_arr = []
+ for i in iterable:
+ double_arr.append(i + i)
+
+# Eseguendo il seguente codice, noi andiamo a raddoppiare prima tutti i valori, e poi
+# li ritorniamo tutti e andiamo a controllare la condizione
+for value in double_numbers(range(1000000)): # `test_senza_generatore`
+ print value
+ if value > 5:
+ break
+
+# Invece, potremmo usare un generatore per "generare" il valore raddoppiato non
+# appena viene richiesto
+def double_numbers_generator(iterable):
+ for i in iterable:
+ yield i + i
+
+# Utilizzando lo stesso test di prima, stavolta però con un generatore, ci permette
+# di iterare sui valori e raddoppiarli uno alla volta, non appena vengono richiesti dalla
+# logica del programma. Per questo, non appena troviamo un valore > 5, usciamo dal ciclo senza
+# bisogno di raddoppiare la maggior parte dei valori del range (MOLTO PIU VELOCE!)
+for value in double_numbers_generator(xrange(1000000)): # `test_generatore`
+ print value
+ if value > 5:
+ break
+
+# Nota: hai notato l'uso di `range` in `test_senza_generatore` e `xrange` in `test_generatore`?
+# Proprio come `double_numbers_generator` è la versione col generatore di `double_numbers`
+# Abbiamo `xrange` come versione col generatore di `range`
+# `range` ritorna un array di 1000000 elementi
+# `xrange` invece genera 1000000 valori quando lo richiediamo/iteriamo su di essi
+
+# Allo stesso modo della comprensione delle liste, puoi creare la comprensione
+# dei generatori.
+values = (-x for x in [1,2,3,4,5])
+for x in values:
+ print(x) # stampa -1 -2 -3 -4 -5
+
+# Puoi anche fare il cast diretto di una comprensione di generatori ad una lista.
+values = (-x for x in [1,2,3,4,5])
+gen_to_list = list(values)
+print(gen_to_list) # => [-1, -2, -3, -4, -5]
+
+
+# Decoratori
+# in questo esempio beg include say
+# Beg chiamerà say. Se say_please è True allora cambierà il messaggio
+# ritornato
+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, "Per favore! Sono povero :(")
+ return msg
+
+ return wrapper
+
+
+@beg
+def say(say_please=False):
+ msg = "Puoi comprarmi una birra?"
+ return msg, say_please
+
+
+print say() # Puoi comprarmi una birra?
+print say(say_please=True) # Puoi comprarmi una birra? Per favore! Sono povero :(
+```
+
+## Pronto per qualcosa di più?
+
+### Gratis Online
+
+* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
+* [LearnPython](http://www.learnpython.org/)
+* [Fullstack Python](https://www.fullstackpython.com/)
+
+### Libri cartacei
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
diff --git a/it-it/qt-it.html.markdown b/it-it/qt-it.html.markdown
new file mode 100644
index 00000000..d7469f67
--- /dev/null
+++ b/it-it/qt-it.html.markdown
@@ -0,0 +1,161 @@
+---
+category: tool
+tool: Qt Framework
+language: c++
+filename: learnqt-it.cpp
+contributors:
+ - ["Aleksey Kholovchuk", "https://github.com/vortexxx192"]
+translators:
+ - ["Ale46", "https://gihub.com/ale46"]
+lang: it-it
+---
+
+**Qt** è un framework ampiamente conosciuto per lo sviluppo di software multipiattaforma che può essere eseguito su varie piattaforme software e hardware con modifiche minime o nulle nel codice, pur avendo la potenza e la velocità delle applicazioni native. Sebbene **Qt** sia stato originariamente scritto in *C++*, ci sono diversi porting in altri linguaggi: *[PyQt](https://learnxinyminutes.com/docs/pyqt/)*, *QtRuby*, *PHP-Qt*, etc.
+
+**Qt** è ottimo per la creazione di applicazioni con interfaccia utente grafica (GUI). Questo tutorial descrive come farlo in *C++*.
+
+```c++
+/*
+ * Iniziamo classicamente
+ */
+
+// tutte le intestazioni dal framework Qt iniziano con la lettera maiuscola 'Q'
+#include <QApplication>
+#include <QLineEdit>
+
+int main(int argc, char *argv[]) {
+ // crea un oggetto per gestire le risorse a livello di applicazione
+ QApplication app(argc, argv);
+
+ // crea un widget di campo di testo e lo mostra sullo schermo
+ QLineEdit lineEdit("Hello world!");
+ lineEdit.show();
+
+ // avvia il ciclo degli eventi dell'applicazione
+ return app.exec();
+}
+```
+
+La parte relativa alla GUI di **Qt** riguarda esclusivamente *widget* e le loro *connessioni*.
+
+[LEGGI DI PIÙ SUI WIDGET](http://doc.qt.io/qt-5/qtwidgets-index.html)
+
+```c++
+/*
+ * Creiamo un'etichetta e un pulsante.
+ * Un'etichetta dovrebbe apparire quando si preme un pulsante.
+ *
+ * Il codice Qt parla da solo.
+ */
+
+#include <QApplication>
+#include <QDialog>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QLabel>
+
+int main(int argc, char *argv[]) {
+ QApplication app(argc, argv);
+
+ QDialog dialogWindow;
+ dialogWindow.show();
+
+ // add vertical layout
+ QVBoxLayout layout;
+ dialogWindow.setLayout(&layout);
+
+ QLabel textLabel("Grazie per aver premuto quel pulsante");
+ layout.addWidget(&textLabel);
+ textLabel.hide();
+
+ QPushButton button("Premimi");
+ layout.addWidget(&button);
+
+ // mostra l'etichetta nascosta quando viene premuto il pulsante
+ QObject::connect(&button, &QPushButton::pressed,
+ &textLabel, &QLabel::show);
+
+ return app.exec();
+}
+```
+
+Si noti la parte relativa a *QObject::connect*. Questo metodo viene utilizzato per connettere *SEGNALI* di un oggetto agli *SLOTS* di un altro.
+
+**I SEGNALI** vengono emessi quando certe cose accadono agli oggetti, come il segnale *premuto* che viene emesso quando l'utente preme sull'oggetto QPushButton.
+
+**Gli slot** sono *azioni* che potrebbero essere eseguite in risposta ai segnali ricevuti.
+
+[LEGGI DI PIÙ SU SLOT E SEGNALI](http://doc.qt.io/qt-5/signalsandslots.html)
+
+
+Successivamente, impariamo che non possiamo solo usare i widget standard, ma estendere il loro comportamento usando l'ereditarietà. Creiamo un pulsante e contiamo quante volte è stato premuto. A tale scopo definiamo la nostra classe *CounterLabel*. Deve essere dichiarato in un file separato a causa dell'architettura Qt specifica.
+
+```c++
+// counterlabel.hpp
+
+#ifndef COUNTERLABEL
+#define COUNTERLABEL
+
+#include <QLabel>
+
+class CounterLabel : public QLabel {
+ Q_OBJECT // Macro definite da Qt che devono essere presenti in ogni widget personalizzato
+
+public:
+ CounterLabel() : counter(0) {
+ setText("Il contatore non è stato ancora aumentato"); // metodo di QLabel
+ }
+
+public slots:
+ // azione che verrà chiamata in risposta alla pressione del pulsante
+ void increaseCounter() {
+ setText(QString("Valore contatore: %1").arg(QString::number(++counter)));
+ }
+
+private:
+ int counter;
+};
+
+#endif // COUNTERLABEL
+```
+
+```c++
+// main.cpp
+// Quasi uguale all'esempio precedente
+
+#include <QApplication>
+#include <QDialog>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QString>
+#include "counterlabel.hpp"
+
+int main(int argc, char *argv[]) {
+ QApplication app(argc, argv);
+
+ QDialog dialogWindow;
+ dialogWindow.show();
+
+ QVBoxLayout layout;
+ dialogWindow.setLayout(&layout);
+
+ CounterLabel counterLabel;
+ layout.addWidget(&counterLabel);
+
+ QPushButton button("Premimi ancora una volta");
+ layout.addWidget(&button);
+ QObject::connect(&button, &QPushButton::pressed,
+ &counterLabel, &CounterLabel::increaseCounter);
+
+ return app.exec();
+}
+```
+
+Questo è tutto! Ovviamente, il framework Qt è molto più grande della parte che è stata trattata in questo tutorial, quindi preparatevi a leggere e fare pratica.
+
+## Ulteriori letture
+
+- [Qt 4.8 tutorials](http://doc.qt.io/qt-4.8/tutorials.html)
+- [Qt 5 tutorials](http://doc.qt.io/qt-5/qtexamplesandtutorials.html)
+
+Buona fortuna e buon divertimento!
diff --git a/it-it/rst-it.html.markdown b/it-it/rst-it.html.markdown
new file mode 100644
index 00000000..a834e899
--- /dev/null
+++ b/it-it/rst-it.html.markdown
@@ -0,0 +1,111 @@
+---
+language: restructured text (RST)
+filename: restructuredtext-it.rst
+contributors:
+ - ["DamienVGN", "https://github.com/martin-damien"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+translators:
+ - ["Ale46", "https://github.com/Ale46"]
+ - ["Chris54721", "https://chris54721.net"]
+lang: it-it
+---
+
+RST (Restructured Text) è un formato di file inizialmente creato dalla comunità Python
+per la documentazione (per questo motivo appartiene a Docutils).
+
+I file RST sono semplici file di testo con una sintassi leggera (in confronto all'HTML).
+
+## Installazione
+
+Per usare Restructured Text, sarà necessario installare [Python](http://www.python.org) ed il pacchetto `docutils`.
+
+`docutils` può essere installato da riga di comando:
+
+```bash
+$ easy_install docutils
+```
+
+Oppure, se hai `pip` installato sul tuo sistema:
+
+```bash
+$ pip install docutils
+```
+
+
+## Sintassi del file
+
+Ecco un semplice esempio della sintassi RST:
+
+```
+.. Le righe che iniziano con due punti sono comandi speciali. Ma se non è possibile trovare alcun comando, la riga viene considerata come un commento
+
+===============================================================================
+I titoli principali sono scritti utilizzando caratteri di uguale, sopra e sotto
+===============================================================================
+
+Si noti che devono esserci tanti caratteri di uguale quanti caratteri del titolo.
+
+Anche i titoli normali usano caratteri di uguale, ma solo sotto
+===============================================================
+
+I sottotitoli usano i trattini
+------------------------------
+
+E i sotto-sottotitoli le tildi
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Puoi inserire il testo in *corsivo* o in **grassetto**, puoi "contrassegnare" il testo come codice con un doppio apice ``: `` print () ``.
+
+Le liste sono semplici come in Markdown:
+
+- primo articolo
+- Secondo elemento
+     - Sottoelemento
+
+oppure
+
+* Primo elemento
+* Secondo elemento
+     * Sottoelemento
+
+Le tabelle sono molto semplici da inserire:
+
+=========== ========
+Stato Capitale
+=========== ========
+Francia Parigi
+Giappone Tokio
+=========== ========
+
+Anche le tabelle più complesse possono essere inserite facilmente (colonne e/o righe unite) ma ti suggerisco di leggere la documentazione completa per questo :)
+
+Esistono diversi modi per creare collegamenti:
+
+- Aggiungendo un underscore dopo una parola: Github_ e aggiungendo l'URL di destinazione dopo il testo (questo metodo ha il vantaggio di non inserire URL non necessari all'interno del testo leggibile).
+- Digitando un URL completo: https://github.com/ (verrà automaticamente convertito in un collegamento)
+- Utilizzando una sintassi simile a Markdown: `Github <https://github.com/>`_ .
+
+.. _Github https://github.com/
+
+```
+
+## Come usarlo
+
+RST viene fornito con docutils, che dispone di `rst2html`, per esempio:
+
+```bash
+$ rst2html miofile.rst output.html
+```
+
+*Nota : In alcuni sistemi il comando potrebbe essere rst2html.py*
+
+Ma ci sono applicazioni più complesse che utilizzano il formato RST:
+
+- [Pelican](http://blog.getpelican.com/), un generatore di siti statici
+- [Sphinx](http://sphinx-doc.org/), un generatore di documentazione
+- e molti altri
+
+
+## Letture
+
+- [Riferimento ufficiale rapido](http://docutils.sourceforge.net/docs/user/rst/quickref.html)
diff --git a/it-it/ruby-it.html.markdown b/it-it/ruby-it.html.markdown
new file mode 100644
index 00000000..295bf28a
--- /dev/null
+++ b/it-it/ruby-it.html.markdown
@@ -0,0 +1,653 @@
+---
+language: ruby
+filename: learnruby-it.rb
+contributors:
+ - ["David Underwood", "http://theflyingdeveloper.com"]
+ - ["Joel Walden", "http://joelwalden.net"]
+ - ["Luke Holder", "http://twitter.com/lukeholder"]
+ - ["Tristan Hume", "http://thume.ca/"]
+ - ["Nick LaMuro", "https://github.com/NickLaMuro"]
+ - ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"]
+ - ["Ariel Krakowski", "http://www.learneroo.com"]
+ - ["Dzianis Dashkevich", "https://github.com/dskecse"]
+ - ["Levi Bostian", "https://github.com/levibostian"]
+ - ["Rahil Momin", "https://github.com/iamrahil"]
+ - ["Gabriel Halley", "https://github.com/ghalley"]
+ - ["Persa Zula", "http://persazula.com"]
+ - ["Jake Faris", "https://github.com/farisj"]
+ - ["Corey Ward", "https://github.com/coreyward"]
+translators:
+ - ["abonte", "https://github.com/abonte"]
+lang: it-it
+---
+
+```ruby
+# Questo è un commento
+
+# In Ruby, (quasi) tutto è un oggetto.
+# Questo include i numeri...
+3.class #=> Integer
+
+# ...stringhe...
+"Hello".class #=> String
+
+# ...e anche i metodi!
+"Hello".method(:class).class #=> Method
+
+# Qualche operazione aritmetica di base
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+2 ** 5 #=> 32
+5 % 3 #=> 2
+
+# Bitwise operators
+3 & 5 #=> 1
+3 | 5 #=> 7
+3 ^ 5 #=> 6
+
+# L'aritmetica è solo zucchero sintattico
+# per chiamare il metodo di un oggetto
+1.+(3) #=> 4
+10.* 5 #=> 50
+100.methods.include?(:/) #=> true
+
+# I valori speciali sono oggetti
+nil # equivalente a null in altri linguaggi
+true # vero
+false # falso
+
+nil.class #=> NilClass
+true.class #=> TrueClass
+false.class #=> FalseClass
+
+# Uguaglianza
+1 == 1 #=> true
+2 == 1 #=> false
+
+# Disuguaglianza
+1 != 1 #=> false
+2 != 1 #=> true
+
+# nil è l'unico valore, oltre a false, che è considerato 'falso'
+!!nil #=> false
+!!false #=> false
+!!0 #=> true
+!!"" #=> true
+
+# Altri confronti
+1 < 10 #=> true
+1 > 10 #=> false
+2 <= 2 #=> true
+2 >= 2 #=> true
+
+# Operatori di confronto combinati (ritorna '1' quando il primo argomento è più
+# grande, '-1' quando il secondo argomento è più grande, altrimenti '0')
+1 <=> 10 #=> -1
+10 <=> 1 #=> 1
+1 <=> 1 #=> 0
+
+# Operatori logici
+true && false #=> false
+true || false #=> true
+
+# Ci sono versioni alternative degli operatori logici con meno precedenza.
+# Sono usati come costrutti per il controllo di flusso per concatenare
+# insieme statement finché uno di essi ritorna true o false.
+
+# `do_something_else` chiamato solo se `do_something` ha successo.
+do_something() and do_something_else()
+# `log_error` è chiamato solo se `do_something` fallisce.
+do_something() or log_error()
+
+# Interpolazione di stringhe
+
+placeholder = 'usare l\'interpolazione di stringhe'
+"Per #{placeholder} si usano stringhe con i doppi apici"
+#=> "Per usare l'interpolazione di stringhe si usano stringhe con i doppi apici"
+
+# E' possibile combinare le stringhe usando `+`, ma non con gli altri tipi
+'hello ' + 'world' #=> "hello world"
+'hello ' + 3 #=> TypeError: can't convert Fixnum into String
+'hello ' + 3.to_s #=> "hello 3"
+"hello #{3}" #=> "hello 3"
+
+# ...oppure combinare stringhe e operatori
+'ciao ' * 3 #=> "ciao ciao ciao "
+
+# ...oppure aggiungere alla stringa
+'ciao' << ' mondo' #=> "ciao mondo"
+
+# Per stampare a schermo e andare a capo
+puts "Sto stampando!"
+#=> Sto stampando!
+#=> nil
+
+# Per stampare a schermo senza andare a capo
+print "Sto stampando!"
+#=> Sto stampando! => nil
+
+# Variabili
+x = 25 #=> 25
+x #=> 25
+
+# Notare che l'assegnamento ritorna il valore assegnato.
+# Questo significa che è possibile effettuare assegnamenti multipli:
+x = y = 10 #=> 10
+x #=> 10
+y #=> 10
+
+# Per convenzione si usa lo snake_case per i nomi delle variabili
+snake_case = true
+
+# Usare nomi delle variabili descrittivi
+path_to_project_root = '/buon/nome/'
+m = '/nome/scadente/'
+
+# I simboli sono immutabili, costanti riusabili rappresentati internamente da
+# un valore intero. Sono spesso usati al posto delle stringhe per comunicare
+# specifici e significativi valori.
+
+:pendente.class #=> Symbol
+
+stato = :pendente
+
+stato == :pendente #=> true
+
+stato == 'pendente' #=> false
+
+stato == :approvato #=> false
+
+# Le stringhe possono essere convertite in simboli e viceversa:
+status.to_s #=> "pendente"
+"argon".to_sym #=> :argon
+
+# Arrays
+
+# Questo è un array
+array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
+
+# Gli array possono contenere diversi tipi di elementi
+[1, 'hello', false] #=> [1, "hello", false]
+
+# Gli array possono essere indicizzati
+# Dall'inizio...
+array[0] #=> 1
+array.first #=> 1
+array[12] #=> nil
+
+
+# ...o dalla fine...
+array[-1] #=> 5
+array.last #=> 5
+
+# With a start index and length
+# ...o con un indice di inzio e la lunghezza...
+array[2, 3] #=> [3, 4, 5]
+
+# ...oppure con un intervallo.
+array[1..3] #=> [2, 3, 4]
+
+# Invertire l'ordine degli elementi di un array
+a = [1,2,3]
+a.reverse! #=> [3,2,1]
+
+# Come per l'aritmetica, l'accesso tramite [var]
+# è solo zucchero sintattico
+# per chiamare il metodo '[]'' di un oggetto
+array.[] 0 #=> 1
+array.[] 12 #=> nil
+
+# Si può aggiungere un elemento all'array così
+array << 6 #=> [1, 2, 3, 4, 5, 6]
+# oppure così
+array.push(6) #=> [1, 2, 3, 4, 5, 6]
+
+# Controllare se un elemento esiste in un array
+array.include?(1) #=> true
+
+# Hash è un dizionario con coppie di chiave e valore
+# Un hash è denotato da parentesi graffe:
+hash = { 'colore' => 'verde', 'numero' => 5 }
+
+hash.keys #=> ['colore', 'numero']
+
+# E' possibile accedere all'hash tramite chiave:
+hash['colore'] #=> 'verde'
+hash['numero'] #=> 5
+
+# Accedere all'hash con una chiave che non esiste ritorna nil:
+hash['nothing here'] #=> nil
+
+# Quando si usano simboli come chiavi di un hash, si possono utilizzare
+# queste sintassi:
+
+hash = { :defcon => 3, :action => true }
+hash.keys #=> [:defcon, :action]
+# oppure
+hash = { defcon: 3, action: true }
+hash.keys #=> [:defcon, :action]
+
+# Controllare l'esistenza di una chiave o di un valore in un hash
+new_hash.key?(:defcon) #=> true
+new_hash.value?(3) #=> true
+
+# Suggerimento: sia gli array che gli hash sono enumerabili!
+# Entrambi possiedono metodi utili come each, map, count e altri.
+
+# Strutture di controllo
+
+#Condizionali
+if true
+ 'if statement'
+elsif false
+ 'else if, opzionale'
+else
+ 'else, opzionale'
+end
+
+#Cicli
+# In Ruby, i tradizionali cicli `for` non sono molto comuni. Questi semplici
+# cicli, invece, sono implementati con un enumerable, usando `each`:
+(1..5).each do |contatore|
+ puts "iterazione #{contatore}"
+end
+
+# Esso è equivalente a questo ciclo, il quale è inusuale da vedere in Ruby:
+for contatore in 1..5
+ puts "iterazione #{contatore}"
+end
+
+# Il costrutto `do |variable| ... end` è chiamato 'blocco'. I blocchi
+# sono simili alle lambda, funzioni anonime o closure che si trovano in altri
+# linguaggi di programmazione. Essi possono essere passati come oggetti,
+# chiamati o allegati come metodi.
+#
+# Il metodo 'each' di un intervallo (range) esegue il blocco una volta
+# per ogni elemento dell'intervallo.
+# Al blocco è passato un contatore come parametro.
+
+# E' possibile inglobare il blocco fra le parentesi graffe
+(1..5).each { |contatore| puts "iterazione #{contatore}" }
+
+# Il contenuto delle strutture dati può essere iterato usando "each".
+array.each do |elemento|
+ puts "#{elemento} è parte dell'array"
+end
+hash.each do |chiave, valore|
+ puts "#{chiave} è #{valore}"
+end
+
+# If you still need an index you can use 'each_with_index' and define an index
+# variable
+# Se comunque si vuole un indice, si può usare "each_with_index" e definire
+# una variabile che contiene l'indice
+array.each_with_index do |elemento, indice|
+ puts "#{elemento} è il numero #{index} nell'array"
+end
+
+contatore = 1
+while contatore <= 5 do
+ puts "iterazione #{contatore}"
+ contatore += 1
+end
+#=> iterazione 1
+#=> iterazione 2
+#=> iterazione 3
+#=> iterazione 4
+#=> iterazione 5
+
+# Esistono in Ruby ulteriori funzioni per fare i cicli,
+# come per esempio 'map', 'reduce', 'inject' e altri.
+# Nel caso di 'map', esso prende l'array sul quale si sta iterando, esegue
+# le istruzioni definite nel blocco, e ritorna un array completamente nuovo.
+array = [1,2,3,4,5]
+doubled = array.map do |elemento|
+ elemento * 2
+end
+puts doubled
+#=> [2,4,6,8,10]
+puts array
+#=> [1,2,3,4,5]
+
+# Costrutto "case"
+grade = 'B'
+
+case grade
+when 'A'
+ puts 'Way to go kiddo'
+when 'B'
+ puts 'Better luck next time'
+when 'C'
+ puts 'You can do better'
+when 'D'
+ puts 'Scraping through'
+when 'F'
+ puts 'You failed!'
+else
+ puts 'Alternative grading system, eh?'
+end
+#=> "Better luck next time"
+
+# 'case' può usare anche gli intervalli
+grade = 82
+case grade
+when 90..100
+ puts 'Hooray!'
+when 80...90
+ puts 'OK job'
+else
+ puts 'You failed!'
+end
+#=> "OK job"
+
+# Gestione delle eccezioni
+begin
+ # codice che può sollevare un eccezione
+ raise NoMemoryError, 'Esaurita la memoria.'
+rescue NoMemoryError => exception_variable
+ puts 'NoMemoryError è stato sollevato.', exception_variable
+rescue RuntimeError => other_exception_variable
+ puts 'RuntimeError è stato sollvato.'
+else
+ puts 'Questo viene eseguito se nessuna eccezione è stata sollevata.'
+ensure
+ puts 'Questo codice viene sempre eseguito a prescindere.'
+end
+
+# Metodi
+
+def double(x)
+ x * 2
+end
+
+# Metodi (e blocchi) ritornano implicitamente il valore dell'ultima istruzione
+double(2) #=> 4
+
+# Le parentesi sono opzionali dove l'interpolazione è inequivocabile
+double 3 #=> 6
+
+double double 3 #=> 12
+
+def sum(x, y)
+ x + y
+end
+
+# Gli argomenit dei metodi sono separati dalla virgola
+sum 3, 4 #=> 7
+
+sum sum(3, 4), 5 #=> 12
+
+# yield
+# Tutti i metodi hanno un implicito e opzionale parametro del blocco.
+# Esso può essere chiamato con la parola chiave 'yield'.
+
+def surround
+ puts '{'
+ yield
+ puts '}'
+end
+
+surround { puts 'hello world' }
+
+# {
+# hello world
+# }
+
+# I blocchi possono essere convertiti in 'proc', il quale racchiude il blocco
+# e gli permette di essere passato ad un altro metodo, legato ad uno scope
+# differente o modificato. Questo è molto comune nella lista parametri del
+# metodo, dove è frequente vedere il parametro '&block' in coda. Esso accetta
+# il blocco, se ne è stato passato uno, e lo converte in un 'Proc'.
+# Qui la denominazione è una convenzione; funzionerebbe anche con '&ananas'.
+def guests(&block)
+ block.class #=> Proc
+ block.call(4)
+end
+
+# Il metodo 'call' del Proc è simile allo 'yield' quando è presente un blocco.
+# Gli argomenti passati a 'call' sono inoltrati al blocco come argomenti:
+
+guests { |n| "You have #{n} guests." }
+# => "You have 4 guests."
+
+# L'operatore splat ("*") converte una lista di argomenti in un array
+def guests(*array)
+ array.each { |guest| puts guest }
+end
+
+# Destrutturazione
+
+# Ruby destruttura automaticamente gli array in assegnamento
+# a variabili multiple:
+a, b, c = [1, 2, 3]
+a #=> 1
+b #=> 2
+c #=> 3
+
+# In alcuni casi si usa l'operatore splat ("*") per destrutturare
+# un array in una lista.
+classifica_concorrenti = ["John", "Sally", "Dingus", "Moe", "Marcy"]
+
+def migliore(primo, secondo, terzo)
+ puts "I vincitori sono #{primo}, #{secondo}, e #{terzo}."
+end
+
+migliore *classifica_concorrenti.first(3)
+#=> I vincitori sono John, Sally, e Dingus.
+
+# The splat operator can also be used in parameters:
+def migliore(primo, secondo, terzo, *altri)
+ puts "I vincitori sono #{primo}, #{secondo}, e #{terzo}."
+ puts "C'erano altri #{altri.count} partecipanti."
+end
+
+migliore *classifica_concorrenti
+#=> I vincitori sono John, Sally, e Dingus.
+#=> C'erano altri 2 partecipanti.
+
+# Per convenzione, tutti i metodi che ritornano un booleano terminano
+# con un punto interrogativo
+5.even? #=> false
+5.odd? #=> true
+
+# Per convenzione, se il nome di un metodo termina con un punto esclamativo,
+# esso esegue qualcosa di distruttivo. Molti metodi hanno una versione con '!'
+# per effettuare una modifiche, e una versione senza '!' che ritorna
+# una versione modificata.
+nome_azienda = "Dunder Mifflin"
+nome_azienda.upcase #=> "DUNDER MIFFLIN"
+nome_azienda #=> "Dunder Mifflin"
+# Questa volta modifichiamo nome_azienda
+nome_azienda.upcase! #=> "DUNDER MIFFLIN"
+nome_azienda #=> "DUNDER MIFFLIN"
+
+# Classi
+
+# Definire una classe con la parola chiave class
+class Umano
+
+ # Una variabile di classe. E' condivisa da tutte le istance di questa classe.
+ @@specie = 'H. sapiens'
+
+ # Inizializzatore di base
+ def initialize(nome, eta = 0)
+ # Assegna il valore dell'argomento alla variabile dell'istanza "nome"
+ @nome = nome
+ # Se l'età non è fornita, verrà assegnato il valore di default indicato
+ # nella lista degli argomenti
+ @eta = eta
+ end
+
+ # Metodo setter di base
+ def nome=(nome)
+ @nome = nome
+ end
+
+ # Metodo getter di base
+ def nome
+ @nome
+ end
+
+ # Le funzionalità di cui sopra posso essere incapsulate usando
+ # il metodo attr_accessor come segue
+ attr_accessor :nome
+
+ # Getter/setter possono anche essere creati individualmente
+ attr_reader :nome
+ attr_writer :nome
+
+ # Un metodo della classe usa 'self' per distinguersi dai metodi dell'istanza.
+ # Può essere richimato solo dalla classe, non dall'istanza.
+ def self.say(msg)
+ puts msg
+ end
+
+ def specie
+ @@specie
+ end
+end
+
+
+# Instanziare una classe
+jim = Umano.new('Jim Halpert')
+
+dwight = Umano.new('Dwight K. Schrute')
+
+# Chiamiamo qualche metodo
+jim.specie #=> "H. sapiens"
+jim.nome #=> "Jim Halpert"
+jim.nome = "Jim Halpert II" #=> "Jim Halpert II"
+jim.nome #=> "Jim Halpert II"
+dwight.specie #=> "H. sapiens"
+dwight.nome #=> "Dwight K. Schrute"
+
+# Chiamare un metodo della classe
+Umano.say('Ciao') #=> "Ciao"
+
+# La visibilità della variabile (variable's scope) è determinata dal modo
+# in cui le viene assegnato il nome.
+# Variabili che iniziano con $ hanno uno scope globale
+$var = "Sono una variabile globale"
+defined? $var #=> "global-variable"
+
+# Variabili che inziano con @ hanno a livello dell'istanza
+@var = "Sono una variabile dell'istanza"
+defined? @var #=> "instance-variable"
+
+# Variabili che iniziano con @@ hanno una visibilità a livello della classe
+@@var = "Sono una variabile della classe"
+defined? @@var #=> "class variable"
+
+# Variabili che iniziano con una lettera maiuscola sono costanti
+Var = "Sono una costante"
+defined? Var #=> "constant"
+
+# Anche una classe è un oggetto in ruby. Quindi la classe può avere
+# una variabile dell'istanza. Le variabili della classe sono condivise
+# fra la classe e tutti i suoi discendenti.
+
+# Classe base
+class Umano
+ @@foo = 0
+
+ def self.foo
+ @@foo
+ end
+
+ def self.foo=(value)
+ @@foo = value
+ end
+end
+
+# Classe derivata
+class Lavoratore < Umano
+end
+
+Umano.foo #=> 0
+Lavoratore.foo #=> 0
+
+Umano.foo = 2 #=> 2
+Lavoratore.foo #=> 2
+
+# La variabile dell'istanza della classe non è condivisa dai discendenti.
+
+class Umano
+ @bar = 0
+
+ def self.bar
+ @bar
+ end
+
+ def self.bar=(value)
+ @bar = value
+ end
+end
+
+class Dottore < Umano
+end
+
+Umano.bar #=> 0
+Dottore.bar #=> nil
+
+module EsempioModulo
+ def foo
+ 'foo'
+ end
+end
+
+# Includere moduli vincola i suoi metodi all'istanza della classe.
+# Estendere moduli vincola i suoi metodi alla classe stessa.
+class Persona
+ include EsempioModulo
+end
+
+class Libro
+ extend EsempioModulo
+end
+
+Persona.foo #=> NoMethodError: undefined method `foo' for Person:Class
+Persona.new.foo #=> 'foo'
+Libro.foo #=> 'foo'
+Libro.new.foo #=> NoMethodError: undefined method `foo'
+
+# Callbacks sono eseguiti quand si include o estende un modulo
+module ConcernExample
+ def self.included(base)
+ base.extend(ClassMethods)
+ base.send(:include, InstanceMethods)
+ end
+
+ module ClassMethods
+ def bar
+ 'bar'
+ end
+ end
+
+ module InstanceMethods
+ def qux
+ 'qux'
+ end
+ end
+end
+
+class Something
+ include ConcernExample
+end
+
+Something.bar #=> 'bar'
+Something.qux #=> NoMethodError: undefined method `qux'
+Something.new.bar #=> NoMethodError: undefined method `bar'
+Something.new.qux #=> 'qux'
+```
+
+## Ulteriori risorse
+
+- [Learn Ruby by Example with Challenges](http://www.learneroo.com/modules/61/nodes/338) - Una variante di questa guida con esercizi nel browser.
+- [An Interactive Tutorial for Ruby](https://rubymonk.com/) - Imparare Ruby attraverso una serie di tutorial interattivi.
+- [Official Documentation](http://ruby-doc.org/core)
+- [Ruby from other languages](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/)
+- [Programming Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - Una passata [edizione libera](http://ruby-doc.com/docs/ProgrammingRuby/) è disponibile online.
+- [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) - A community-driven Ruby coding style guide.
+- [Try Ruby](http://tryruby.org) - Imparare le basi del linguaggio di programmazion Ruby, interattivamente nel browser.
diff --git a/it-it/rust-it.html.markdown b/it-it/rust-it.html.markdown
index 6b379f93..e4b7c33f 100644
--- a/it-it/rust-it.html.markdown
+++ b/it-it/rust-it.html.markdown
@@ -130,14 +130,14 @@ fn main() {
/////////////
// Strutture
- struct Point {
+ struct Punto {
x: i32,
y: i32,
}
let origine: Punto = Punto { x: 0, y: 0 };
- // Ana struct con campi senza nome, chiamata ‘tuple struct’
+ // Una struct con campi senza nome, chiamata ‘tuple struct’
struct Punto2(i32, i32);
let origine2 = Punto2(0, 0);
diff --git a/it-it/sql-it.html.markdown b/it-it/sql-it.html.markdown
new file mode 100644
index 00000000..7db2eec1
--- /dev/null
+++ b/it-it/sql-it.html.markdown
@@ -0,0 +1,112 @@
+---
+language: SQL
+filename: learnsql-it.sql
+contributors:
+ - ["Bob DuCharme", "http://bobdc.com/"]
+translators:
+ - ["Christian Grasso", "https://grasso.io"]
+lang: it-it
+---
+
+Structured Query Language (SQL) è un linguaggio standard ISO per la creazione e la gestione
+di database organizzati in un insieme di tabelle. Le diverse implementazioni aggiungono
+spesso le proprie estensioni al linguaggio base ([confronto tra le diverse implementazioni](http://troels.arvin.dk/db/rdbms/))
+
+Le diverse implementazioni forniscono inoltre un prompt per inserire in modo interattivo i comandi
+o eseguire il contenuto di uno script.
+
+I comandi di seguito lavorano sul [database di esempio MySQL](https://dev.mysql.com/doc/employee/en/)
+disponibile su [GitHub](https://github.com/datacharmer/test_db). I file .sql contengono liste di comandi
+simili a quelli mostrati di seguito, che creano e riempiono delle tabelle con dati di un'azienda fittizia.
+Il comando per eseguire questi script può variare in base all'implementazione in uso.
+
+
+```sql
+-- I commenti iniziano con due trattini. Ogni comando va terminato con il punto e virgola
+
+-- SQL è case-insensitive per quanto riguarda i comandi; in genere si
+-- preferisce scriverli in maiuscolo per distinguerli dai nomi di
+-- database, tabelle e colonne
+
+-- Crea ed elimina un database. I nomi di database e tabelle sono case-sensitive
+CREATE DATABASE someDatabase;
+DROP DATABASE someDatabase;
+
+-- Lista dei database disponibili
+SHOW DATABASES;
+
+-- Attiva uno specifico database
+USE employees;
+
+-- Seleziona tutte le righe e le colonne dalla tabella departments
+SELECT * FROM departments;
+
+-- Seleziona tutte le righe della tabella departments,
+-- ma solo le colonne dept_no e dept_name.
+-- È possibile suddividere i comandi su più righe.
+SELECT dept_no,
+ dept_name FROM departments;
+
+-- Seleziona solo le prime 5 righe della tabella departments.
+SELECT * FROM departments LIMIT 5;
+
+-- Ottiene la colonna dept_name della tabella departments
+-- solo per le righe il cui valore di dept_name contiene 'en'.
+SELECT dept_name FROM departments WHERE dept_name LIKE '%en%';
+
+-- Ottiene tutte le colonne della tabella departments
+-- solo per le righe che hanno un dept_name formato da una 'S'
+-- seguita esattamente da altri 4 caratteri
+SELECT * FROM departments WHERE dept_name LIKE 'S____';
+
+-- Seleziona i valori di title dalla tabella titles eliminando i duplicati
+SELECT DISTINCT title FROM titles;
+
+-- Come sopra, ma i valori sono ordinati alfabeticamente
+SELECT DISTINCT title FROM titles ORDER BY title;
+
+-- Mostra il numero di righe della tabella departments
+SELECT COUNT(*) FROM departments;
+
+-- Mostra il numero di righe della tabella departments
+-- il cui valore di dept_name contiene 'en'.
+SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%';
+
+-- Un JOIN tra più tabelle: la tabella titles contiene gli
+-- incarichi lavorativi associati ad un certo numero di impiegato.
+-- Con il JOIN utilizziamo il numero di impiegato per ottenere
+-- le informazioni ad esso associate nella tabella employees.
+-- (Inoltre selezioniamo solo le prime 10 righe)
+
+SELECT employees.first_name, employees.last_name,
+ titles.title, titles.from_date, titles.to_date
+FROM titles INNER JOIN employees ON
+ employees.emp_no = titles.emp_no LIMIT 10;
+
+-- Mostra tutte le tabelle di tutti i database.
+-- Spesso le implementazioni forniscono degli shortcut per questo comando
+SELECT * FROM INFORMATION_SCHEMA.TABLES
+WHERE TABLE_TYPE='BASE TABLE';
+
+-- Crea una tabella tablename1, con due colonne, per il database in uso.
+-- Per le colonne specifichiamo il tipo di dato (stringa di max 20 caratteri)
+CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20));
+
+-- Inserisce una riga nella tabella tablename1. I valori devono essere
+-- appropriati per la definizione della tabella
+INSERT INTO tablename1 VALUES('Richard','Mutt');
+
+-- In tablename1, modifica il valore di fname a 'John'
+-- in tutte le righe che hanno come lname 'Mutt'.
+UPDATE tablename1 SET fname='John' WHERE lname='Mutt';
+
+-- Elimina tutte le righe di tablename1
+-- il cui lname inizia per 'M'.
+DELETE FROM tablename1 WHERE lname like 'M%';
+
+-- Elimina tutte le righe della tabella tablename1
+DELETE FROM tablename1;
+
+-- Elimina la tabella tablename1
+DROP TABLE tablename1;
+```
diff --git a/it-it/toml-it.html.markdown b/it-it/toml-it.html.markdown
new file mode 100644
index 00000000..99082048
--- /dev/null
+++ b/it-it/toml-it.html.markdown
@@ -0,0 +1,276 @@
+---
+language: toml
+filename: learntoml-it.toml
+contributors:
+ - ["Alois de Gouvello", "https://github.com/aloisdg"]
+translators:
+ - ["Christian Grasso", "https://grasso.io"]
+lang: it-it
+---
+
+TOML è l'acronimo di _Tom's Obvious, Minimal Language_. È un linguaggio per la
+serializzazione di dati, progettato per i file di configurazione.
+
+È un'alternativa a linguaggi come YAML e JSON, che punta ad essere più leggibile
+per le persone. Allo stesso tempo, TOML può essere utilizzato in modo abbastanza
+semplice nella maggior parte dei linguaggi di programmazione, in quanto è
+progettato per essere tradotto senza ambiguità in una hash table.
+
+Tieni presente che TOML è ancora in fase di sviluppo, e la sua specifica non è
+ancora stabile. Questo documento utilizza TOML 0.4.0.
+
+```toml
+# I commenti in TOML sono fatti così.
+
+################
+# TIPI SCALARI #
+################
+
+# Il nostro oggetto root (corrispondente all'intero documento) sarà una mappa,
+# anche chiamata dizionario, hash o oggetto in altri linguaggi.
+
+# La key, il simbolo di uguale e il valore devono trovarsi sulla stessa riga,
+# eccetto per alcuni tipi di valori.
+key = "value"
+stringa = "ciao"
+numero = 42
+float = 3.14
+boolean = true
+data = 1979-05-27T07:32:00-08:00
+notazScientifica = 1e+12
+"puoi utilizzare le virgolette per la key" = true # Puoi usare " oppure '
+"la key può contenere" = "lettere, numeri, underscore e trattini"
+
+############
+# Stringhe #
+############
+
+# Le stringhe possono contenere solo caratteri UTF-8 validi.
+# Possiamo effettuare l'escape dei caratteri, e alcuni hanno delle sequenze
+# di escape compatte. Ad esempio, \t corrisponde al TAB.
+stringaSemplice = "Racchiusa tra virgolette. \"Usa il backslash per l'escape\"."
+
+stringaMultiriga = """
+Racchiusa da tre virgolette doppie all'inizio e
+alla fine - consente di andare a capo."""
+
+stringaLiteral = 'Virgolette singole. Non consente di effettuare escape.'
+
+stringaMultirigaLiteral = '''
+Racchiusa da tre virgolette singole all'inizio e
+alla fine - consente di andare a capo.
+Anche in questo caso non si può fare escape.
+Il primo ritorno a capo viene eliminato.
+ Tutti gli altri spazi aggiuntivi
+ vengono mantenuti.
+'''
+
+# Per i dati binari è consigliabile utilizzare Base64 e
+# gestirli manualmente dall'applicazione.
+
+##########
+# Interi #
+##########
+
+## Gli interi possono avere o meno un segno (+, -).
+## Non si possono inserire zero superflui all'inizio.
+## Non è possibile inoltre utilizzare valori numerici
+## non rappresentabili con una sequenza di cifre.
+int1 = +42
+int2 = 0
+int3 = -21
+
+## Puoi utilizzare gli underscore per migliorare la leggibilità.
+## Fai attenzione a non inserirne due di seguito.
+int4 = 5_349_221
+int5 = 1_2_3_4_5 # VALIDO, ma da evitare
+
+#########
+# Float #
+#########
+
+# I float permettono di rappresentare numeri decimali.
+flt1 = 3.1415
+flt2 = -5e6
+flt3 = 6.626E-34
+
+###########
+# Boolean #
+###########
+
+# I valori boolean (true/false) devono essere scritti in minuscolo.
+bool1 = true
+bool2 = false
+
+############
+# Data/ora #
+############
+
+data1 = 1979-05-27T07:32:00Z # Specifica RFC 3339/ISO 8601 (UTC)
+data2 = 1979-05-26T15:32:00+08:00 # RFC 3339/ISO 8601 con offset
+
+######################
+# TIPI DI COLLECTION #
+######################
+
+#########
+# Array #
+#########
+
+array1 = [ 1, 2, 3 ]
+array2 = [ "Le", "virgole", "sono", "delimitatori" ]
+array3 = [ "Non", "unire", "tipi", "diversi" ]
+array4 = [ "tutte", 'le stringhe', """hanno lo stesso""", '''tipo''' ]
+array5 = [
+ "Gli spazi vuoti", "sono", "ignorati"
+]
+
+###########
+# Tabelle #
+###########
+
+# Le tabelle (o hash table o dizionari) sono collection di coppie key/value.
+# Iniziano con un nome tra parentesi quadre su una linea separata.
+# Le tabelle vuote (senza alcun valore) sono valide.
+[tabella]
+
+# Tutti i valori che si trovano sotto il nome della tabella
+# appartengono alla tabella stessa (finchè non ne viene creata un'altra).
+# L'ordine di questi valori non è garantito.
+[tabella-1]
+key1 = "una stringa"
+key2 = 123
+
+[tabella-2]
+key1 = "un'altra stringa"
+key2 = 456
+
+# Utilizzando i punti è possibile creare delle sottotabelle.
+# Ogni parte suddivisa dai punti segue le regole delle key per il nome.
+[tabella-3."sotto.tabella"]
+key1 = "prova"
+
+# Ecco l'equivalente JSON della tabella precedente:
+# { "tabella-3": { "sotto.tabella": { "key1": "prova" } } }
+
+# Gli spazi non vengono considerati, ma è consigliabile
+# evitare di usare spazi superflui.
+[a.b.c] # consigliato
+[ d.e.f ] # identico a [d.e.f]
+
+# Non c'è bisogno di creare le tabelle superiori per creare una sottotabella.
+# [x] queste
+# [x.y] non
+# [x.y.z] servono
+[x.y.z.w] # per creare questa tabella
+
+# Se non è stata già creata prima, puoi anche creare
+# una tabella superiore più avanti.
+[a.b]
+c = 1
+
+[a]
+d = 2
+
+# Non puoi definire una key o una tabella più di una volta.
+
+# ERRORE
+[a]
+b = 1
+
+[a]
+c = 2
+
+# ERRORE
+[a]
+b = 1
+
+[a.b]
+c = 2
+
+# I nomi delle tabelle non possono essere vuoti.
+[] # NON VALIDO
+[a.] # NON VALIDO
+[a..b] # NON VALIDO
+[.b] # NON VALIDO
+[.] # NON VALIDO
+
+##################
+# Tabelle inline #
+##################
+
+tabelleInline = { racchiuseData = "{ e }", rigaSingola = true }
+punto = { x = 1, y = 2 }
+
+####################
+# Array di tabelle #
+####################
+
+# Un array di tabelle può essere creato utilizzando due parentesi quadre.
+# Tutte le tabelle con questo nome saranno elementi dell'array.
+# Gli elementi vengono inseriti nell'ordine in cui si trovano.
+
+[[prodotti]]
+nome = "array di tabelle"
+sku = 738594937
+tabelleVuoteValide = true
+
+[[prodotti]]
+
+[[prodotti]]
+nome = "un altro item"
+sku = 284758393
+colore = "grigio"
+
+# Puoi anche creare array di tabelle nested. Le sottotabelle con doppie
+# parentesi quadre apparterranno alla tabella più vicina sopra di esse.
+
+[[frutta]]
+ nome = "mela"
+
+ [frutto.geometria]
+ forma = "sferica"
+ nota = "Sono una proprietà del frutto"
+
+ [[frutto.colore]]
+ nome = "rosso"
+ nota = "Sono un oggetto di un array dentro mela"
+
+ [[frutto.colore]]
+ nome = "verde"
+ nota = "Sono nello stesso array di rosso"
+
+[[frutta]]
+ nome = "banana"
+
+ [[frutto.colore]]
+ nome = "giallo"
+ nota = "Anche io sono un oggetto di un array, ma dentro banana"
+```
+
+Ecco l'equivalente JSON dell'ultima tabella:
+
+```json
+{
+ "frutta": [
+ {
+ "nome": "mela",
+ "geometria": { "forma": "sferica", "nota": "..."},
+ "colore": [
+ { "nome": "rosso", "nota": "..." },
+ { "nome": "verde", "nota": "..." }
+ ]
+ },
+ {
+ "nome": "banana",
+ "colore": [
+ { "nome": "giallo", "nota": "..." }
+ ]
+ }
+ ]
+}
+```
+
+### Altre risorse
+
++ [Repository ufficiale di TOML](https://github.com/toml-lang/toml)
diff --git a/it-it/typescript-it.html.markdown b/it-it/typescript-it.html.markdown
new file mode 100644
index 00000000..b78705c5
--- /dev/null
+++ b/it-it/typescript-it.html.markdown
@@ -0,0 +1,227 @@
+---
+language: TypeScript
+contributors:
+ - ["Philippe Vlérick", "https://github.com/pvlerick"]
+translators:
+ - ["Christian Grasso", "https://grasso.io"]
+filename: learntypescript-it.ts
+lang: it-it
+---
+
+TypeScript è un linguaggio basato su JavaScript che punta a rendere il codice
+più scalabile introducendo concetti quali le classi, i moduli, le interface,
+e i generics.
+Poichè TypeScript è un superset di JavaScript, è possibile sfruttare le sue
+funzionalità anche in progetti esistenti: il codice JavaScript valido è anche
+valido in TypeScript. Il compilatore di TypeScript genera codice JavaScript.
+
+Questo articolo si concentrerà solo sulle funzionalità aggiuntive di TypeScript.
+
+Per testare il compilatore, puoi utilizzare il
+[Playground](http://www.typescriptlang.org/Playground), dove potrai scrivere
+codice TypeScript e visualizzare l'output in JavaScript.
+
+```ts
+// TypeScript ha tre tipi di base
+let completato: boolean = false;
+let righe: number = 42;
+let nome: string = "Andrea";
+
+// Il tipo può essere omesso se è presente un assegnamento a scalari/literal
+let completato = false;
+let righe = 42;
+let nome = "Andrea";
+
+// Il tipo "any" indica che la variabile può essere di qualsiasi tipo
+let qualsiasi: any = 4;
+qualsiasi = "oppure una stringa";
+qualsiasi = false; // o magari un boolean
+
+// Usa la keyword "const" per le costanti
+const numeroViteGatti = 9;
+numeroViteGatti = 1; // Errore
+
+// Per gli array, puoi usare l'apposito tipo o la versione con i generics
+let lista: number[] = [1, 2, 3];
+let lista: Array<number> = [1, 2, 3];
+
+// Per le enumerazioni:
+enum Colore { Rosso, Verde, Blu };
+let c: Colore = Colore.Verde;
+
+// Infine, "void" viene utilizzato per le funzioni che non restituiscono valori
+function avviso(): void {
+ alert("Sono un piccolo avviso fastidioso!");
+}
+
+// Le funzioni supportano la sintassi "a freccia" (lambda) e supportano la type
+// inference, cioè per scalari/literal non c'è bisogno di specificare il tipo
+
+// Tutte le seguenti funzioni sono equivalenti, e il compilatore genererà
+// lo stesso codice JavaScript per ognuna di esse
+let f1 = function (i: number): number { return i * i; }
+// Type inference
+let f2 = function (i: number) { return i * i; }
+// Sintassi lambda
+let f3 = (i: number): number => { return i * i; }
+// Sintassi lambda + type inference
+let f4 = (i: number) => { return i * i; }
+// Sintassi lambda + type inference + sintassi abbreviata (senza return)
+let f5 = (i: number) => i * i;
+
+// Le interfacce sono strutturali, e qualunque oggetto con le stesse proprietà
+// di un'interfaccia è compatibile con essa
+interface Persona {
+ nome: string;
+ // Proprietà opzionale, indicata con "?"
+ anni?: number;
+ // Funzioni
+ saluta(): void;
+}
+
+// Oggetto che implementa l'interfaccia Persona
+// È una Persona valida poichè implementa tutta le proprietà non opzionali
+let p: Persona = { nome: "Bobby", saluta: () => { } };
+// Naturalmente può avere anche le proprietà opzionali:
+let pValida: Persona = { nome: "Bobby", anni: 42, saluta: () => { } };
+// Questa invece NON è una Persona, poichè il tipo di "anni" è sbagliato
+let pNonValida: Persona = { nome: "Bobby", anni: true };
+
+// Le interfacce possono anche descrivere una funzione
+interface SearchFunc {
+ (source: string, subString: string): boolean;
+}
+// I nomi dei parametri non sono rilevanti: vengono controllati solo i tipi
+let ricerca: SearchFunc;
+ricerca = function (src: string, sub: string) {
+ return src.search(sub) != -1;
+}
+
+// Classi - i membri sono pubblici di default
+class Punto {
+ // Proprietà
+ x: number;
+
+ // Costruttore - in questo caso la keyword "public" può generare in automatico
+ // il codice per l'inizializzazione di una variabile.
+ // In questo esempio, verrà creata la variabile y in modo identico alla x, ma
+ // con meno codice. Sono supportati anche i valori di default.
+ constructor(x: number, public y: number = 0) {
+ this.x = x;
+ }
+
+ // Funzioni
+ dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
+
+ // Membri statici
+ static origine = new Point(0, 0);
+}
+
+// Le classi possono anche implementare esplicitamente delle interfacce.
+// Il compilatore restituirà un errore nel caso in cui manchino delle proprietà.
+class PersonaDiRiferimento implements Persona {
+ nome: string
+ saluta() {}
+}
+
+let p1 = new Punto(10, 20);
+let p2 = new Punto(25); // y = 0
+
+// Inheritance
+class Punto3D extends Punto {
+ constructor(x: number, y: number, public z: number = 0) {
+ super(x, y); // La chiamata esplicita a super è obbligatoria
+ }
+
+ // Sovrascrittura
+ dist() {
+ let d = super.dist();
+ return Math.sqrt(d * d + this.z * this.z);
+ }
+}
+
+// Moduli - "." può essere usato come separatore per i sottomoduli
+module Geometria {
+ export class Quadrato {
+ constructor(public lato: number = 0) { }
+
+ area() {
+ return Math.pow(this.lato, 2);
+ }
+ }
+}
+
+let s1 = new Geometria.Quadrato(5);
+
+// Alias locale per un modulo
+import G = Geometria;
+
+let s2 = new G.Quadrato(10);
+
+// Generics
+// Classi
+class Tuple<T1, T2> {
+ constructor(public item1: T1, public item2: T2) {
+ }
+}
+
+// Interfacce
+interface Pair<T> {
+ item1: T;
+ item2: T;
+}
+
+// E funzioni
+let pairToTuple = function <T>(p: Pair<T>) {
+ return new Tuple(p.item1, p.item2);
+};
+
+let tuple = pairToTuple({ item1: "hello", item2: "world" });
+
+// Interpolazione con le template string (definite con i backtick)
+let nome = 'Tyrone';
+let saluto = `Ciao ${name}, come stai?`
+// Possono anche estendersi su più righe
+let multiriga = `Questo è un esempio
+di stringa multiriga.`;
+
+// La keyword "readonly" rende un membro di sola lettura
+interface Persona {
+ readonly nome: string;
+ readonly anni: number;
+}
+
+var p1: Persona = { nome: "Tyrone", anni: 42 };
+p1.anni = 25; // Errore, p1.anni è readonly
+
+var p2 = { nome: "John", anni: 60 };
+var p3: Person = p2; // Ok, abbiamo creato una versione readonly di p2
+p3.anni = 35; // Errore, p3.anni è readonly
+p2.anni = 45; // Compila, ma cambia anche p3.anni per via dell'aliasing!
+
+class Macchina {
+ readonly marca: string;
+ readonly modello: string;
+ readonly anno = 2018;
+
+ constructor() {
+ // Possiamo anche assegnare nel constructor
+ this.marca = "Marca sconosciuta";
+ this.modello = "Modello sconosciuto";
+ }
+}
+
+let numeri: Array<number> = [0, 1, 2, 3, 4];
+let altriNumeri: ReadonlyArray<number> = numbers;
+altriNumeri[5] = 5; // Errore, gli elementi sono readonly
+altriNumeri.push(5); // Errore, il metodo push non esiste (modifica l'array)
+altriNumeri.length = 3; // Errore, length è readonly
+numeri = altriNumeri; // Errore, i metodi di modifica non esistono
+```
+
+## Altre risorse
+ * [Sito ufficiale di TypeScript](http://www.typescriptlang.org/)
+ * [Specifica di TypeScript](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)
+ * [Anders Hejlsberg - Introducing TypeScript su Channel 9](http://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript)
+ * [TypeScript su GitHub](https://github.com/Microsoft/TypeScript)
+ * [Definitely Typed - definizioni per le librerie](http://definitelytyped.org/)
diff --git a/it-it/zfs-it.html.markdown b/it-it/zfs-it.html.markdown
new file mode 100644
index 00000000..c1307e67
--- /dev/null
+++ b/it-it/zfs-it.html.markdown
@@ -0,0 +1,361 @@
+---
+category: tool
+tool: zfs
+contributors:
+ - ["sarlalian", "http://github.com/sarlalian"]
+translators:
+ - ["Christian Grasso","https://grasso.io"]
+filename: LearnZfs-it.txt
+lang: it-it
+---
+
+
+[ZFS](http://open-zfs.org/wiki/Main_Page) è un sistema di storage che combina file system
+tradizionali e volume manager in un unico strumento. ZFS utilizza della terminologia
+specifica, diversa da quella usata da altri sistemi di storage, ma le sue funzioni lo
+rendono un ottimo tool per gli amministratori di sistema.
+
+
+## Concetti base di ZFS
+
+### Virtual Device
+
+Un VDEV è simile a un dispositivo gestito da una scheda RAID. Esistono diversi tipi di
+VDEV che offrono diversi vantaggi, tra cui ridondanza e velocità. In generale,
+i VDEV offrono una maggiore affidabilità rispetto alle schede RAID. Si sconsiglia di
+utilizzare ZFS insieme a RAID, poichè ZFS è fatto per gestire direttamente i dischi fisici.
+
+Tipi di VDEV:
+
+* stripe (disco singolo, senza ridondanza)
+* mirror (mirror su più dischi)
+* raidz
+ * raidz1 (parity a 1 disco, simile a RAID 5)
+ * raidz2 (parity a 2 dischi, simile a RAID 6)
+ * raidz3 (parity a 3 dischi)
+* disk
+* file (non consigliato in production poichè aggiunge un ulteriore filesystem)
+
+I dati vengono distribuiti tra tutti i VDEV presenti nella Storage Pool, per cui un maggior
+numero di VDEV aumenta le operazioni al secondo (IOPS).
+
+### Storage Pool
+
+Le Storage Pool di ZFS sono un'astrazione del livello inferiore (VDEV) e consentono di
+separare il filesystem visibile agli utenti dal layout reale dei dischi.
+
+### Dataset
+
+I dataset sono simili ai filesystem tradizionali, ma con molte più funzioni che rendono
+vantaggioso l'utilizzo di ZFS. I dataset supportano il [Copy on Write](https://en.wikipedia.org/wiki/Copy-on-write)
+gli snapshot, la gestione delle quota, compressione e deduplicazione.
+
+
+### Limiti
+
+Una directory può contenere fino a 2^48 file, ognuno dei quali di 16 exabyte.
+Una storage pool può contenere fino a 256 zettabyte (2^78), e può essere distribuita
+tra 2^64 dispositivi. Un singolo host può avere fino a 2^64 storage pool.
+
+
+## Comandi
+
+### Storage Pool
+
+Azioni:
+
+* List (lista delle pool)
+* Status (stato)
+* Destroy (rimozione)
+* Get/Set (lettura/modifica proprietà)
+
+Lista delle zpool
+
+```bash
+# Crea una zpool raidz
+$ zpool create bucket raidz1 gpt/zfs0 gpt/zfs1 gpt/zfs2
+
+# Lista delle zpool
+$ zpool list
+NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
+zroot 141G 106G 35.2G - 43% 75% 1.00x ONLINE -
+
+# Informazioni dettagliate su una zpool
+$ zpool list -v zroot
+NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
+zroot 141G 106G 35.2G - 43% 75% 1.00x ONLINE -
+ gptid/c92a5ccf-a5bb-11e4-a77d-001b2172c655 141G 106G 35.2G - 43% 75%
+```
+
+Stato delle zpool
+
+```bash
+# Informazioni sullo stato delle zpool
+$ zpool status
+ pool: zroot
+ state: ONLINE
+ scan: scrub repaired 0 in 2h51m with 0 errors on Thu Oct 1 07:08:31 2015
+config:
+
+ NAME STATE READ WRITE CKSUM
+ zroot ONLINE 0 0 0
+ gptid/c92a5ccf-a5bb-11e4-a77d-001b2172c655 ONLINE 0 0 0
+
+errors: No known data errors
+
+# "Scrubbing" (correzione degli errori)
+$ zpool scrub zroot
+$ zpool status -v zroot
+ pool: zroot
+ state: ONLINE
+ scan: scrub in progress since Thu Oct 15 16:59:14 2015
+ 39.1M scanned out of 106G at 1.45M/s, 20h47m to go
+ 0 repaired, 0.04% done
+config:
+
+ NAME STATE READ WRITE CKSUM
+ zroot ONLINE 0 0 0
+ gptid/c92a5ccf-a5bb-11e4-a77d-001b2172c655 ONLINE 0 0 0
+
+errors: No known data errors
+```
+
+Proprietà delle zpool
+
+```bash
+
+# Proprietà di una zpool (gestite dal sistema o dall'utente)
+$ zpool get all zroot
+NAME PROPERTY VALUE SOURCE
+zroot size 141G -
+zroot capacity 75% -
+zroot altroot - default
+zroot health ONLINE -
+...
+
+# Modifica di una proprietà
+$ zpool set comment="Dati" zroot
+$ zpool get comment
+NAME PROPERTY VALUE SOURCE
+tank comment - default
+zroot comment Dati local
+```
+
+Rimozione di una zpool
+
+```bash
+$ zpool destroy test
+```
+
+
+### Dataset
+
+Azioni:
+
+* Create
+* List
+* Rename
+* Delete
+* Get/Set (proprietà)
+
+Creazione dataset
+
+```bash
+# Crea un dataset
+$ zfs create tank/root/data
+$ mount | grep data
+tank/root/data on /data (zfs, local, nfsv4acls)
+
+# Crea un sottodataset
+$ zfs create tank/root/data/stuff
+$ mount | grep data
+tank/root/data on /data (zfs, local, nfsv4acls)
+tank/root/data/stuff on /data/stuff (zfs, local, nfsv4acls)
+
+
+# Crea un volume
+$ zfs create -V zroot/win_vm
+$ zfs list zroot/win_vm
+NAME USED AVAIL REFER MOUNTPOINT
+tank/win_vm 4.13G 17.9G 64K -
+```
+
+Lista dei dataset
+
+```bash
+# Lista dei dataset
+$ zfs list
+NAME USED AVAIL REFER MOUNTPOINT
+zroot 106G 30.8G 144K none
+zroot/ROOT 18.5G 30.8G 144K none
+zroot/ROOT/10.1 8K 30.8G 9.63G /
+zroot/ROOT/default 18.5G 30.8G 11.2G /
+zroot/backup 5.23G 30.8G 144K none
+zroot/home 288K 30.8G 144K none
+...
+
+# Informazioni su un dataset
+$ zfs list zroot/home
+NAME USED AVAIL REFER MOUNTPOINT
+zroot/home 288K 30.8G 144K none
+
+# Lista degli snapshot
+$ zfs list -t snapshot
+zroot@daily-2015-10-15 0 - 144K -
+zroot/ROOT@daily-2015-10-15 0 - 144K -
+zroot/ROOT/default@daily-2015-10-15 0 - 24.2G -
+zroot/tmp@daily-2015-10-15 124K - 708M -
+zroot/usr@daily-2015-10-15 0 - 144K -
+zroot/home@daily-2015-10-15 0 - 11.9G -
+zroot/var@daily-2015-10-15 704K - 1.42G -
+zroot/var/log@daily-2015-10-15 192K - 828K -
+zroot/var/tmp@daily-2015-10-15 0 - 152K -
+```
+
+Rinominare un dataset
+
+```bash
+$ zfs rename tank/root/home tank/root/old_home
+$ zfs rename tank/root/new_home tank/root/home
+```
+
+Eliminare un dataset
+
+```bash
+# I dataset non possono essere eliminati se hanno degli snapshot
+$ zfs destroy tank/root/home
+```
+
+Lettura/modifica proprietà
+
+```bash
+# Tutte le proprietà di un dataset
+$ zfs get all zroot/usr/home │157 # Create Volume
+NAME PROPERTY VALUE SOURCE │158 $ zfs create -V zroot/win_vm
+zroot/home type filesystem - │159 $ zfs list zroot/win_vm
+zroot/home creation Mon Oct 20 14:44 2014 - │160 NAME USED AVAIL REFER MOUNTPOINT
+zroot/home used 11.9G - │161 tank/win_vm 4.13G 17.9G 64K -
+zroot/home available 94.1G - │162 ```
+zroot/home referenced 11.9G - │163
+zroot/home mounted yes -
+...
+
+# Proprietà specifica
+$ zfs get compression zroot/usr/home
+NAME PROPERTY VALUE SOURCE
+zroot/home compression off default
+
+# Modifica di una proprietà
+$ zfs set compression=gzip-9 mypool/lamb
+
+# Specifiche proprietà per tutti i dataset
+$ zfs list -o name,quota,reservation
+NAME QUOTA RESERV
+zroot none none
+zroot/ROOT none none
+zroot/ROOT/default none none
+zroot/tmp none none
+zroot/usr none none
+zroot/home none none
+zroot/var none none
+...
+```
+
+
+### Snapshot
+
+Gli snapshot sono una delle funzioni più importanti di ZFS:
+
+* Lo spazio occupato è la differenza tra il filesystem e l'ultimo snapshot
+* Il tempo di creazione è di pochi secondi
+* Possono essere ripristinati alla velocità di scrittura del disco
+* Possono essere automatizzati molto semplicemente
+
+Azioni:
+
+* Create
+* Delete
+* Rename
+* Access
+* Send / Receive
+* Clone
+
+
+Creazione di uno snapshot
+
+```bash
+# Crea uno snapshot di un singolo dataset
+zfs snapshot tank/home/sarlalian@now
+
+# Crea uno snapshot di un dataset e dei suoi sottodataset
+$ zfs snapshot -r tank/home@now
+$ zfs list -t snapshot
+NAME USED AVAIL REFER MOUNTPOINT
+tank/home@now 0 - 26K -
+tank/home/sarlalian@now 0 - 259M -
+tank/home/alice@now 0 - 156M -
+tank/home/bob@now 0 - 156M -
+...
+```
+
+Eliminazione di uno snapshot
+
+```bash
+# Elimina uno snapshot
+$ zfs destroy tank/home/sarlalian@now
+
+# Elimina uno snapshot ricorsivamente
+$ zfs destroy -r tank/home/sarlalian@now
+
+```
+
+Rinominare uno snapshot
+
+```bash
+$ zfs rename tank/home/sarlalian@now tank/home/sarlalian@today
+$ zfs rename tank/home/sarlalian@now today
+
+$ zfs rename -r tank/home@now @yesterday
+```
+
+Accedere ad uno snapshot
+
+```bash
+# Utilizzare il comando cd come per una directory
+$ cd /home/.zfs/snapshot/
+```
+
+Invio e ricezione
+
+```bash
+# Backup di uno snapshot su un file
+$ zfs send tank/home/sarlalian@now | gzip > backup_file.gz
+
+# Invia uno snapshot ad un altro dataset
+$ zfs send tank/home/sarlalian@now | zfs recv backups/home/sarlalian
+
+# Invia uno snapshot ad un host remoto
+$ zfs send tank/home/sarlalian@now | ssh root@backup_server 'zfs recv tank/home/sarlalian'
+
+# Invia l'intero dataset e i suoi snapshot ad un host remoto
+$ zfs send -v -R tank/home@now | ssh root@backup_server 'zfs recv tank/home'
+```
+
+Clonare gli snapshot
+
+```bash
+# Clona uno snapshot
+$ zfs clone tank/home/sarlalian@now tank/home/sarlalian_new
+
+# Rende il clone indipendente dallo snapshot originale
+$ zfs promote tank/home/sarlalian_new
+```
+
+### Letture aggiuntive (in inglese)
+
+* [BSDNow's Crash Course on ZFS](http://www.bsdnow.tv/tutorials/zfs)
+* [FreeBSD Handbook on ZFS](https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/zfs.html)
+* [BSDNow's Crash Course on ZFS](http://www.bsdnow.tv/tutorials/zfs)
+* [Oracle's Tuning Guide](http://www.oracle.com/technetwork/articles/servers-storage-admin/sto-recommended-zfs-settings-1951715.html)
+* [OpenZFS Tuning Guide](http://open-zfs.org/wiki/Performance_tuning)
+* [FreeBSD ZFS Tuning Guide](https://wiki.freebsd.org/ZFSTuningGuide)
diff --git a/ja-jp/asciidoc.html.markdown b/ja-jp/asciidoc.html.markdown
new file mode 100644
index 00000000..7347589a
--- /dev/null
+++ b/ja-jp/asciidoc.html.markdown
@@ -0,0 +1,135 @@
+---
+language: asciidoc
+contributors:
+ - ["Ryan Mavilia", "http://unoriginality.rocks/"]
+ - ["Abel Salgado Romero", "https://twitter.com/abelsromero"]
+translators:
+ - ["Ryota Kayanuma", "https://github.com/PicoSushi"]
+filename: asciidoc-ja.md
+lang: ja-jp
+---
+
+AsciiDocはMarkdownに似たマークアップ言語で、書籍の執筆からブログを書くことまでなんでも使うことができます。2002年、Stuart RackhamによりAsciiDocは作成され、シンプルでありつつも沢山のカスタマイズを可能にしています。
+
+文書のヘッダー
+
+ヘッダーはオプションで、空行を含むことはできません。本文から1行以上の改行を開ける必要があります。
+
+タイトルのみの例
+
+```
+= 文章タイトル
+
+文書の最初の行
+```
+
+タイトルと著者
+
+```
+= 文書タイトル
+文書 太郎 <first.last@learnxinyminutes.com>
+
+文書の開始
+```
+
+複数の著者
+
+```
+= 文書タイトル
+John Doe <john@go.com>; Jane Doe<jane@yo.com>; Black Beard <beardy@pirate.com>
+
+複数の著者による文書の始まり。
+```
+
+版(著者の行を必要とします)
+
+```
+= 第一版のタイトル
+芋男 <chip@crunchy.com>
+v1.0, 2016-01-13
+
+このポテトについての文書は面白いです。
+```
+
+段落
+
+```
+段落は特別なことは不要です。
+
+空行を段落の間に入れることで、段落を分けることができます。
+
+折り返しをしたい場合、+
+を書くことで折り返せます!
+```
+
+文書の整形
+
+```
+_アンダースコアで斜体になります。_
+*アスタリスクで太字になります。*
+*_組み合わせると楽しい_*
+`バッククォートで固定幅になります。`
+`*太字の固定幅*`
+```
+
+節タイトル
+
+```
+= Level 0 (文書のヘッダーにのみ使用してください)
+
+== Level 1 <h2>
+
+=== Level 2 <h3>
+
+==== Level 3 <h4>
+
+===== Level 4 <h5>
+
+```
+
+リスト
+
+箇条書きリストを作るには、アスタリスクを使用してください。
+
+```
+* foo
+* bar
+* baz
+```
+
+番号付きリストを作るには、ピリオドを使用してください。
+
+```
+. item 1
+. item 2
+. item 3
+```
+
+リストはアスタリスクやピリオドを追加することで5段階まで入れ子にできます。
+
+```
+* foo 1
+** foo 2
+*** foo 3
+**** foo 4
+***** foo 5
+
+. foo 1
+.. foo 2
+... foo 3
+.... foo 4
+..... foo 5
+```
+
+## 補足資料
+
+AsciiDocの文書を処理するツールは2種類あります。
+
+1. [AsciiDoc](http://asciidoc.org/): オリジナルのPython実装で、Linuxで利用可能です。現在は開発されておらず、メンテナンスのみの状態です。
+2. [Asciidoctor](http://asciidoctor.org/): Rubyによる別実装で、JavaやJavascriptでも利用可能です。AsciiDocに新しい機能や出力形式を追加するため、現在活発に開発されています。
+
+以下のリンクは `AsciiDoctor` 実装関連のものです。
+
+* [Markdown - AsciiDoc syntax comparison](http://asciidoctor.org/docs/user-manual/#comparison-by-example): Common MarkdownとAsciidocの要素を並べて比較しています。
+* [Getting started](http://asciidoctor.org/docs/#get-started-with-asciidoctor): インストールから簡潔な文書を作るための簡単なガイドです。
+* [Asciidoctor User Manual](http://asciidoctor.org/docs/user-manual/): 文法のリファレンス、例、描画ツール、その他を含む完全なドキュメントです。
diff --git a/ja-jp/php-jp.html.markdown b/ja-jp/php-jp.html.markdown
index 112916f4..a02ae56a 100644
--- a/ja-jp/php-jp.html.markdown
+++ b/ja-jp/php-jp.html.markdown
@@ -119,7 +119,7 @@ echo 'Multiple', 'Parameters', 'Valid';
define("FOO", "something");
// 定義した名前をそのまま($はつけずに)使用することで、定数にアクセスできます
-// access to a constant is possible by direct using the choosen name
+// access to a constant is possible by direct using the chosen name
echo 'This outputs '.FOO;
diff --git a/ja-jp/python-jp.html.markdown b/ja-jp/python-jp.html.markdown
new file mode 100644
index 00000000..18e7d1b8
--- /dev/null
+++ b/ja-jp/python-jp.html.markdown
@@ -0,0 +1,1008 @@
+---
+language: Python
+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"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
+ - ["Roberto Fernandez Diaz", "https://github.com/robertofd1995"]
+translators:
+ - ["kakakaya", "https://github.com/kakakaya"]
+ - ["Ryota Kayanuma", "https://github.com/PicoSushi"]
+filename: learnpython-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/pythonlegacy/) をご確認下さい。
+
+```python
+# 1行のコメントは番号記号(#)から始まります。
+
+""" 複数行の文字は、"を3つ繋げることで
+ 書くことができます。
+ また、これはドキュメントとしてもよく使われます。
+"""
+
+####################################################
+# 1. プリミティブ型と演算子
+####################################################
+
+# 数字です
+3 # => 3
+
+# 四則演算はあなたの期待通りに動きます。
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7.0
+
+# 整数除算の結果は、正負に関わらず小数の切り捨てが行われます。
+5 // 3 # => 1
+-5 // 3 # => -2
+5.0 // 3.0 # => 1.0 # 浮動小数点でも同様に動作します。
+-5.0 // 3.0 # => -2.0
+
+# 除算の結果は常に浮動小数点になります。
+10.0 / 3 # => 3.3333333333333335
+
+# 剰余の計算
+7 % 3 # => 1
+
+# 冪乗 (x**y, x の y 乗)
+2**3 # => 8
+
+# 括弧により、計算の順番を優先させられます。
+(1 + 3) * 2 # => 8
+
+# 真偽値はプリミティブ型です(大文字から始まっていることに注意!)
+True
+False
+
+# not で真偽を反転させられます。
+not True # => False
+not False # => True
+
+# ブール演算
+# 注意: "and" と "or" は小文字です。
+True and False # => False
+False or True # => True
+
+# TrueとFalseは実際には1と0になるキーワードです。
+True + True # => 2
+True * 8 # => 8
+False - 5 # => -5
+
+# 比較演算子はTrueとFalseを数値として扱います。
+0 == False # => True
+1 == True # => True
+2 == True # => False
+-5 != True # => True
+
+# bool論理演算子を整数に対して使うことで整数を真偽値に変換して評価できますが、キャストされていない値が
+# bool(int)とビット演算子(& や |)を混同しないようにうにしましょう。
+bool(0) # => False
+bool(4) # => True
+bool(-6) # => True
+0 and 2 # => 0
+-5 or 0 # => -5
+
+# 値が等しいか確認するには ==
+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 and 2 < 3 # => True
+2 < 3 and 3 < 2 # => False
+
+# 連結させるともっと見やすくなります。
+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"
+
+# Python3.6以上では、f-stringsやフォーマット文字列を使ってフォーマットすることもできます。
+name = "Reiko"
+f"She said her name is {name}." # => "She said her name is Reiko"
+
+# 基本的に、任意のPythonの文を中括弧に書くことができ、それは文字列で出力されます。
+f"{name} is {len(name)} characters long." # => "Reiko is 5 characters long."
+
+# 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() という名前で存在します。
+
+# Pythonでは変数の宣言は存在せず、代入のみです。
+# 慣例的に、小文字でアンダースコア区切り ( 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 # 4、5、6がそれぞれd、 e、 fに代入されます。
+# 2つの変数を交換するのがどれほど簡単か見てみましょう。
+e, d = d, e # d は 5、 e は 4 になります。
+
+
+# 辞書はマップ(キーと値の組み合わせ)を保存できます。
+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: Python3.7未満では、辞書のキーの順番は考慮されていません。実行した結果がこれと異なる場合があります。
+# しかし、Python3.7以降ではキーの挿入順を保つようになりました。
+list(filled_dict.keys()) # => ["three", "two", "one"] in Python <3.7
+list(filled_dict.keys()) # => ["one", "two", "three"] in Python 3.7+
+
+
+# "values()"により、全ての値を反復可能な形式で取り出せます。
+# 前と同じように、これをリストにするために、"list()"で囲んでいます。
+# Note: 辞書の値の順番は考慮されていません。実行した結果がこれと異なる場合があります。
+list(filled_dict.values()) # => [3, 2, 1] in Python <3.7
+list(filled_dict.values()) # => [1, 2, 3] in Python 3.7+
+
+# "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} になりました。
+# 集合は重複した要素を持ちません。
+filled_set.add(5) # 以前の {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ではインデントが特徴的ですね!
+# 規約ではタブではなく4つのスペースでインデントすることが推奨されています。
+# 以下の例では"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) # all_the_args(1, 2, 3, 4) と等しいです。
+all_the_args(**kwargs) # all_the_args(a=3, b=4) と等しいです。
+all_the_args(*args, **kwargs) # all_the_args(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__ のようなメソッド(やオブジェクト、属性)は、
+ # special 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() メソッドを同名の読取専用属性に変換します。
+ # Pythonではわざわざgetterやsetterを書く必要はありません。
+ @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*"
+
+ # スタティックメソッドはインスタンスから呼ぶことはできません。
+ # なぜならば、 i.grunt() は自動的に"self" ( i オブジェクト ) を引数として渡してしまうからです。
+ print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
+
+ # インスタンスのプロパティを更新してみましょう。
+ i.age = 42
+ # プロパティを取得してみましょう。
+ i.say(i.age) # => "Ian: 42"
+ j.say(j.age) # => "Joel: 0"
+ # プロパティを削除してみましょう。
+ del i.age
+ # i.age # => AttributeError が発生します。
+
+
+####################################################
+# 6.1 継承
+####################################################
+# 継承を行うことで、親クラスからメソッドと変数を継承する新しい子クラスを定義できます。
+
+# 上記で定義されたHumanクラスを親クラス(基底クラス)として使い、Superheroという子クラスを定義します。
+# これは"species"、"name"や"age"といった変数や、"sing"や"grunt"のようなメソッドをHumanから継承しますが、
+# Superhero独自のプロパティを持つこともできます。
+
+# ファイルを分割してモジュール化の利点を活用するために、上記のHumanクラスを独自のファイル、ここでは human.py に記述ましょう。
+
+# 別のファイルから関数をインポートするには次の形式を利用してください:
+# from "拡張子なしのファイル名" import "関数やクラス"
+
+from human import Human
+
+
+# 親クラスを子クラスのパラメータとして指定します。
+class Superhero(Human):
+
+ # もし子クラスが親クラスの全ての定義を変更なしで継承する場合、"pass"キーワードのみを書くだけで良いです。
+ # しかし、今回は親クラスとは異なる子クラスを作成するので、今回は以下の通りコメントアウトしています。
+ # pass
+
+ # 子クラスは親クラスの属性を上書きできます。
+ species = 'Superhuman'
+
+ # 子クラスは親クラスのコンストラクタを引数含めて自動的に継承しますが、
+ # 追加の引数や定義を行ってコンストラクタのようなメソッドを上書きすることもできます。
+ # このコンストラクタは"name"引数を"Human"クラスから継承し、"superpower"と"movie"という引数を追加します。
+ def __init__(self, name, movie=False,
+ superpowers=["super strength", "bulletproofing"]):
+
+ # 追加のクラス属性を作成する
+ self.fictional = True
+ self.movie = movie
+ # デフォルト値は共有されるので、可変のデフォルト値には注意してください。
+ self.superpowers = superpowers
+
+ # "super"関数を使うと子クラスに上書きされた親クラスのメソッド(今回は "__init__")にアクセスできます。
+ # これで、親クラスのコンストラクタを呼んでいます。
+ super().__init__(name)
+
+ # singメソッドを上書きし、
+ def sing(self):
+ return 'Dun, dun, DUN!'
+
+ # 追加のインスタンスメソッドを作成します。
+ def boast(self):
+ for power in self.superpowers:
+ print("I wield the power of {pow}!".format(pow=power))
+
+
+if __name__ == '__main__':
+ sup = Superhero(name="Tick")
+
+ # インスタンスの型を調べる
+ if isinstance(sup, Human):
+ print('I am human')
+ if type(sup) is Superhero:
+ print('I am a superhero')
+
+ # getattr()とsuper()で使われるメソッドの解決順序を調べてみます。
+ # この属性は動的であり、変更可能です。
+ print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
+ # => <class 'human.Human'>, <class 'object'>)
+
+ # 親のメソッドを呼びだすものの、独自のクラス属性を参照します。
+ print(sup.get_species()) # => Superhuman
+
+ # 上書きされたメソッドを呼ぶ
+ print(sup.sing()) # => Dun, dun, DUN!
+
+ # Humanのメソッドを呼ぶ
+ sup.say('Spoon') # => Tick: Spoon
+
+ # Superhero限定のメソッドを呼ぶ
+ sup.boast() # => I wield the power of super strength!
+ # => I wield the power of bulletproofing!
+
+ # 継承されたクラス属性
+ sup.age = 31
+ print(sup.age) # => 31
+
+ # Superhero限定の属性
+ print('Am I Oscar eligible? ' + str(sup.movie))
+
+
+
+####################################################
+# 6.2 多重継承
+####################################################
+
+# 別のクラスを定義します。
+# bat.py
+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)
+
+# superhero.py
+from superhero import Superhero
+from bat import Bat
+
+# BatmanをSuperheroとBatの両方を継承した子クラスとして定義します。
+class Batman(Superhero, Bat):
+
+ def __init__(self, *args, **kwargs):
+ # 通常、属性を継承するにはsuper()を呼び出します。
+ # super(Batman, self).__init__(*args, **kwargs)
+ # しかし、ここでは多重継承を行っているので、 super() はMRO(メソッド解決順序)の次の基本クラスにのみ動作します。
+ # なので、全ての祖先に対して明示的に __init__ を呼ぶことにします。
+ # *args と **kwargs を使うことで、それぞれの継承元が
+ # たまねぎの皮を剥がすごとく、引数を用いることができます。
+ Superhero.__init__(self, 'anonymous', movie=True,
+ superpowers=['Wealthy'], *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()
+
+ # getattr() や super() の両方で使われるMROを取得します。
+ # この属性は動的であり、更新が可能です。
+ print(Batman.__mro__) # => (<class '__main__.Batman'>,
+ # => <class 'superhero.Superhero'>,
+ # => <class 'human.Human'>,
+ # => <class 'bat.Bat'>, <class 'object'>)
+
+
+ # 親メソッドを呼び出しますが、独自のクラス属性を参照します。
+ print(sup.get_species()) # => Superhuman
+
+ # 上書きされたメソッドを呼び出します。
+ 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) # => 100
+
+ # デフォルト値が上書きされて、2番目の先祖から継承された属性
+ print('Can I fly? ' + str(sup.fly)) # => Can I fly? False
+
+
+####################################################
+# 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/janet.html.markdown b/janet.html.markdown
new file mode 100644
index 00000000..ec53b018
--- /dev/null
+++ b/janet.html.markdown
@@ -0,0 +1,328 @@
+---
+language: Janet
+filename: learnJanet.janet
+contributors:
+ - ["John Gabriele", "http://www.unexpected-vortices.com/"]
+---
+
+[Janet](https://janet-lang.org/) is a Lisp-like (Clojure-like),
+lexically-scoped, dynamically-typed, garbage-collected, C-based, high-level
+language. The entire language (core library, interpreter, compiler, assembler,
+PEG) is about 300-500 kB and should run on many constrained systems.
+
+I encourage you to try out the code snippets below in the Janet
+repl (either by [installing Janet](https://janet-lang.org/docs/index.html),
+or else by using the repl embedded in the Janet homepage).
+
+As we only have a scant *y* minutes, we'll survey the basics here and
+leave the remaining details for the manual. So please, keep your arms and
+legs inside the vehicle at all times, and on with the scenic tour!
+
+```janet
+# A comment.
+
+# Some literal values.
+true
+false
+nil
+
+# Typical style for symbols (identifiers-for / names-of things).
+do-stuff
+pants-on-fire!
+foo->bar # Evidently for converting foos to bars.
+fully-charged?
+_ # Usually used as a dummy variable.
+
+# Keywords are like symbols that start with a colon, are treated like
+# constants, and are typically used as map keys or pieces of syntax in
+# macros.
+:a
+:some-val
+
+# Numbers #####################################################################
+5
+1e3 # => 1000
+1_000 # => 1000
+2e-03 # => 0.002
+0xff # => 255
+
+# You can specify a radix (base) like so:
+16rff # => 255 (same as 0xff)
+2r1101 # => 13
+
+# Some numbers in the math library:
+math/pi # => 3.14159
+math/e # => 2.71828
+
+# Strings #####################################################################
+"hello"
+"hey\tthere" # contains a tab
+
+# For multi-line strings, use one or more backticks. No escapes allowed.
+``a long
+multi-line
+string`` # => "a long\nmulti-line\nstring"
+
+# Strings and data structures in Janet come in two varieties: mutable and
+# immutable. The literal for the mutable variety is written with a `@` in
+# front of it.
+
+# A mutable string (aka "buffer").
+@"this"
+@`a multi-line
+one here`
+
+(string "con" "cat" "enate") # => "concatenate"
+
+# To get a substring:
+(string/slice "abcdefgh" 2 5) # => "cde"
+# To find a substring:
+(string/find "de" "abcdefgh") # => 3
+
+# See the string library for more (splitting, replacement, etc.)
+
+# Arrays and Tuples ###########################################################
+# Arrays are mutable, tuples are immutable.
+
+# Arrays (mutable)
+@(4 5 6)
+@[4 5 6]
+
+# Tuples (immutable)
+# Note that an open paren usually indicates a function call, so if you want a
+# literal tuple with parens, you need to "quote" it (with a starting single
+# quote mark).
+'(4 5 6)
+[4 5 6] # ... or just use square brackets.
+
+# Tables and Structs (AKA: "maps", "hashmaps", "dictionaries")
+@{:a 1 :b 2 :c 3} # table (mutable)
+{:a 1 :b 2 :c 3} # struct (immutable)
+
+# More about how to work with arrays/tuples and tables/structs below.
+
+# Bindings ####################################################################
+# ... or "Name Some Things!" (that is, bind a value to a symbol)
+(def x 4.7) # Define a constant, `x`.
+x # => 4.7
+(quote x) # => x (the symbol x)
+'x # => x (the symbol x (shorthand))
+(print x) # prints 4.7
+
+# Since we used `def`, can't change to what `x` refers:
+(set x 5.6) # Error, `x` is a constant.
+
+(var y 10)
+(set y 12) # Works, since `y` was made var.
+
+# Note that bindings are local to the scope they're called in. `let`
+# creates a local scope and makes some bindings all in one shot:
+(let [a 2
+ b 3]
+ (print "Hello from inside this local scope.")
+ (* a b)) # => 6
+
+# Destructuring is supported, both for arrays/tuples ...
+(def a ["foos" "bars" "moos"])
+(let [[s1 _ s2] a]
+ (print s1 s2)) # foosmoos
+
+# ... and for tables/structs.
+(def t {:a "ayy" :b "bee" :c "sea"})
+(let [{:a a :b b} t]
+ (print a b)) # ayybee
+
+# You can even destructure right in a `def`:
+(def [aa1 aa2] a)
+aa1 # => foos
+aa2 # => bars
+
+(def {:c body-of-water :b insect-friend} t)
+body-of-water # => sea
+insect-friend # => bee
+
+# Note that keywords evaluate to themselves, whereas symbols evaluate
+# to whatever value they're bound to (unless you quote them).
+
+# Operators ###################################################################
+# Janet supports the usual ensemble of operators.
+# +, -, *, /, and so on. Note:
+(/ 5 3) # => 1.66667
+(% 5 3) # => 2 (remainder)
+(- 5) # => -5 (or you can just write `-5`)
+
+(++ i) # increments
+(-- i) # decrements
+(+= i 3) # add 3 to `i`
+(*= i 3) # triple `i`
+# ... and so on for the other operations on numbers.
+
+# Comparison
+# = < > not= <= >=
+(< 2 7 12) # => true
+
+# Functions ###################################################################
+# Call them:
+(- 5 3) # => 2 (Yes, operators and functions work the same.)
+(math/sin (/ math/pi 2)) # => 1
+(range 5) # => @[0 1 2 3 4]
+
+# Create them:
+(defn mult-by-2
+ ``First line of docstring.
+
+ Some more of the docstring.
+
+ Possibly more!``
+ [x]
+ (print "Hi.")
+ (print "Will compute using: " x)
+ (* 2 x))
+
+(print (mult-by-2 6)) # => 12 (after printing "Hi" and so forth)
+
+# If you have a function named "main" in your file, `janet` will automatically
+# call it for you when you run the file.
+
+# Interactively read a function's docs from within the repl:
+(doc mult-by-2)
+
+# Note, functions have to be defined before they can be used in a function,
+# so if you design top-down, you'll need to write your functions from the
+# bottom of the file up.
+
+# You can make anonymous functions as well:
+(fn [x] (+ x x))
+(fn my-func [x] (+ x x)) # This one's less anonymous.
+
+# Use `do` to make some side-effecting calls and then evaluate to
+# the last form in the `do`:
+(def n (do
+ (print "hi")
+ (do-some-side-effecting 42)
+ 3))
+n # => 3
+
+# You might say that function bodies provide an "implicit do".
+
+# Operations on data structures ###############################################
+# (Making all these mutable so we can ... mutate them.)
+(def s @"Hello, World!")
+(def a @[:a :b :c :d :e])
+(def t @{:a 1 :b 2})
+
+(length s) # => 13
+(length a) # => 5
+(length t) # => 2
+
+# Getting values:
+(s 7) # => 87 (which is the code point for "W")
+(a 1) # => :b
+(t :a) # => 1
+(keys t) # => @[:a :b]
+(values t) # => @[1 2]
+
+# Changing values (for mutable data structures):
+(put s 2 87) # @"HeWlo, World!"
+(put a 2 :x) # @[:a :b :x :d :e]
+(put t :b 42) # @{:a 1 :b 42}
+
+# Adding & removing values (again, for mutable data structures):
+(buffer/push-string s "??") # @"HeWlo, World!??"
+(array/push a :f) # @[:a :b :x :d :e :f]
+(array/pop a) # => :f, and it's also removed from `a`.
+(put t :x 88) # @{:a 1 :b 42 :x 88}
+
+# See the manual for a wide variety of functions for working with
+# buffers/strings, arrays/tuples, and tables/struct.
+
+# Flow control ################################################################
+(if some-condition
+ 42
+ 38)
+
+# Only `nil` and `false` are falsey. Everything else is truthy.
+
+(if got-it?
+ 71) # No false-branch value. Returns `nil` if `got-it?` is falsey.
+
+(var i 10)
+(while (pos? i)
+ (print "... " i)
+ (-- i))
+# Now `i` is 0.
+
+# `case` compares the dispatch value to each of the options.
+(var x 2)
+(case x
+ 1 "won"
+ 2 "too"
+ 3 "tree"
+ "unknown") # => "too"
+
+# `cond` evaluates conditions until it gets a `true`.
+(set x 8)
+(cond
+ (= x 1) "won"
+ (= x 2) "too"
+ (< x 10) "tree"
+ "oof!") # => "tree"
+
+(when (avoided-wipeout?)
+ (do-side-effecty-thing 88)
+ (smell-the-roses)
+ (paint-fencepost-error))
+
+# Pattern matching.
+# `match` is like a high-powered switch expression. If you switch on a data
+# structure, it can look inside to try and match on its contents. For example,
+# matching on a table or struct:
+(def t {:a 1 :b 2 :c 3})
+(match t
+ {:yar v} (print "matches key :yar! " v)
+ {:moo v} (print "matches key :moo! " v)
+ {:c v} (print "matches key :c! " v)
+ _ (print "no match")) # => prints "matches key :c! 3"
+
+# Iterating ###################################################################
+# Iterate over an integer range:
+(for i 0 5
+ (print i)) # prints 0, 1, 2, 3, 4
+
+# There's also the more general `loop`:
+(loop [i :range [0 10] :when (even? i)]
+ (print i))
+
+# Loop over an array/tuple:
+(def words ["foo" "bar" "baz"])
+(each word words
+ (print word))
+
+# Loop over a table/struct:
+(def t {:a 1 :b 2})
+(eachp [k v] t # Loop over each pair in `t`.
+ (print k " --> " v))
+
+# Can also use `eachk` to loop over keys in a table or struct.
+
+# Functional programming ######################################################
+# You'll find many familiar old friends here.
+(filter even?
+ (map (fn [x]
+ (* x x))
+ (range 10))) # => @[0 4 16 36 64]
+
+(reduce + 0 (range 5)) # => 10
+
+# ...and lots more (see the API docs).
+
+# Errata ######################################################################
+(type a) # => the type of `a` (as a keyword)
+(describe a) # => a human-readable description of `a`
+(string/format "%j" a) # => Janet values, nicely-formatted
+```
+
+This tour didn't cover a number of other features such as modules, fibers,
+PEGs, macros, etc., but should give you a taste of what Janet is like. See
+the [Janet manual](https://janet-lang.org/docs/index.html) and the [Janet API
+docs](https://janet-lang.org/api/index.html) for more info.
diff --git a/java.html.markdown b/java.html.markdown
index 12de0c73..79769352 100644
--- a/java.html.markdown
+++ b/java.html.markdown
@@ -10,6 +10,8 @@ contributors:
- ["Rachel Stiyer", "https://github.com/rstiyer"]
- ["Michael Dähnert", "https://github.com/JaXt0r"]
- ["Rob Rose", "https://github.com/RobRoseKnows"]
+ - ["Sean Nam", "https://github.com/seannam"]
+ - ["Shawn M. Hanes", "https://github.com/smhanes15"]
filename: LearnJava.java
---
@@ -29,13 +31,13 @@ Multi-line comments look like this.
* attributes of a Class.
* Main attributes:
*
- * @author Name (and contact information such as email) of author(s).
- * @version Current version of the program.
- * @since When this part of the program was first added.
- * @param For describing the different parameters for a method.
- * @return For describing what the method returns.
+ * @author Name (and contact information such as email) of author(s).
+ * @version Current version of the program.
+ * @since When this part of the program was first added.
+ * @param For describing the different parameters for a method.
+ * @return For describing what the method returns.
* @deprecated For showing the code is outdated or shouldn't be used.
- * @see Links to another part of documentation.
+ * @see Links to another part of documentation.
*/
// Import ArrayList class inside of the java.util package
@@ -43,13 +45,19 @@ import java.util.ArrayList;
// Import all classes inside of java.security package
import java.security.*;
-// Each .java file contains one outer-level public class, with the same name
-// as the file.
public class LearnJava {
- // In order to run a java program, it must have a main method as an entry
+ // In order to run a java program, it must have a main method as an entry
// point.
- public static void main (String[] args) {
+ public static void main(String[] args) {
+
+ ///////////////////////////////////////
+ // Input/Output
+ ///////////////////////////////////////
+
+ /*
+ * Output
+ */
// Use System.out.println() to print lines.
System.out.println("Hello World!");
@@ -65,6 +73,32 @@ public class LearnJava {
// Use System.out.printf() for easy formatted printing.
System.out.printf("pi = %.5f", Math.PI); // => pi = 3.14159
+ /*
+ * Input
+ */
+
+ // use Scanner to read input
+ // must import java.util.Scanner;
+ Scanner scanner = new Scanner(System.in);
+
+ // read string input
+ String name = scanner.next();
+
+ // read byte input
+ byte numByte = scanner.nextByte();
+
+ // read int input
+ int numInt = scanner.nextInt();
+
+ // read long input
+ float numFloat = scanner.nextFloat();
+
+ // read double input
+ double numDouble = scanner.nextDouble();
+
+ // read boolean input
+ boolean bool = scanner.nextBoolean();
+
///////////////////////////////////////
// Variables
///////////////////////////////////////
@@ -74,7 +108,7 @@ public class LearnJava {
*/
// Declare a variable using <type> <name>
int fooInt;
- // Declare multiple variables of the same
+ // Declare multiple variables of the same
// type <type> <name1>, <name2>, <name3>
int fooInt1, fooInt2, fooInt3;
@@ -83,11 +117,12 @@ public class LearnJava {
*/
// Initialize a variable using <type> <name> = <val>
- int fooInt = 1;
- // Initialize multiple variables of same type with same
- // value <type> <name1>, <name2>, <name3> = <val>
- int fooInt1, fooInt2, fooInt3;
- fooInt1 = fooInt2 = fooInt3 = 1;
+ int barInt = 1;
+ // Initialize multiple variables of same type with same
+ // value <type> <name1>, <name2>, <name3>
+ // <name1> = <name2> = <name3> = <val>
+ int barInt1, barInt2, barInt3;
+ barInt1 = barInt2 = barInt3 = 1;
/*
* Variable types
@@ -95,7 +130,7 @@ public class LearnJava {
// Byte - 8-bit signed two's complement integer
// (-128 <= byte <= 127)
byte fooByte = 100;
-
+
// If you would like to interpret a byte as an unsigned integer
// then this simple operation can help
int unsignedIntLessThan256 = 0xff & fooByte;
@@ -137,7 +172,7 @@ public class LearnJava {
// Char - A single 16-bit Unicode character
char fooChar = 'A';
- // final variables can't be reassigned to another object,
+ // final variables can't be reassigned,
final int HOURS_I_WORK_PER_WEEK = 9001;
// but they can be initialized later.
final double E;
@@ -149,12 +184,12 @@ public class LearnJava {
// integers longer than 64-bits. Integers are stored as an array of
// of bytes and are manipulated using functions built into BigInteger
//
- // BigInteger can be initialized using an array of bytes or a string.
+ // BigInteger can be initialized using an array of bytes or a string.
BigInteger fooBigInteger = new BigInteger(fooByteArray);
// BigDecimal - Immutable, arbitrary-precision signed decimal number
//
- // A BigDecimal takes two parts: an arbitrary precision integer
+ // A BigDecimal takes two parts: an arbitrary precision integer
// unscaled value and a 32-bit integer scale
//
// BigDecimal allows the programmer complete control over decimal
@@ -164,7 +199,7 @@ public class LearnJava {
// BigDecimal can be initialized with an int, long, double or String
// or by initializing the unscaled value (BigInteger) and scale (int).
BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt);
-
+
// Be wary of the constructor that takes a float or double as
// the inaccuracy of the float/double will be copied in BigDecimal.
// Prefer the String constructor when you need an exact value.
@@ -196,13 +231,13 @@ public class LearnJava {
builderConcatenated.append("You ");
builderConcatenated.append("can use ");
builderConcatenated.append("the StringBuilder class.");
- System.out.println(builderConcatenated.toString()); // only now is the string built
+ System.out.println(builderConcatenated.toString()); // only now is the string built
// Output: You can use the StringBuilder class.
-
+
// StringBuilder is efficient when the fully constructed String is not required until the end of some processing.
StringBuilder stringBuilder = new StringBuilder();
String inefficientString = "";
- for(int i = 0 ; i < 10; i++){
+ for (int i = 0 ; i < 10; i++) {
stringBuilder.append(i).append(" ");
inefficientString += i + " ";
}
@@ -211,12 +246,12 @@ public class LearnJava {
// inefficientString requires a lot more work to produce, as it generates a String on every loop iteration.
// Simple concatenation with + is compiled to a StringBuilder and toString()
// Avoid string concatenation in loops.
-
+
// #3 - with String formatter
// Another alternative way to create strings. Fast and readable.
String.format("%s may prefer %s.", "Or you", "String.format()");
// Output: Or you may prefer String.format().
-
+
// Arrays
// The array size must be decided upon instantiation
// The following formats work for declaring an array
@@ -244,7 +279,7 @@ public class LearnJava {
// LinkedLists - Implementation of doubly-linked list. All of the
// operations perform as could be expected for a
// doubly-linked list.
- // Maps - A set of objects that map keys to values. Map is
+ // Maps - A mapping of key Objects to value Objects. Map is
// an interface and therefore cannot be instantiated.
// The type of keys and values contained in a Map must
// be specified upon instantiation of the implementing
@@ -253,10 +288,16 @@ public class LearnJava {
// HashMaps - This class uses a hashtable to implement the Map
// interface. This allows the execution time of basic
// operations, such as get and insert element, to remain
- // constant even for large sets.
- // TreeMap - This class is a sorted tree structure. It implements a red
- // black tree and sorts the entries based on the key value or
- // the comparator provided while creating the object
+ // constant-amortized even for large sets.
+ // TreeMap - A Map that is sorted by its keys. Each modification
+ // maintains the sorting defined by either a Comparator
+ // supplied at instantiation, or comparisons of each Object
+ // if they implement the Comparable interface.
+ // Failure of keys to implement Comparable combined with failure to
+ // supply a Comparator will throw ClassCastExceptions.
+ // Insertion and removal operations take O(log(n)) time
+ // so avoid using this data structure unless you are taking
+ // advantage of the sorting.
///////////////////////////////////////
// Operators
@@ -270,7 +311,7 @@ public class LearnJava {
System.out.println("2-1 = " + (i2 - i1)); // => 1
System.out.println("2*1 = " + (i2 * i1)); // => 2
System.out.println("1/2 = " + (i1 / i2)); // => 0 (int/int returns int)
- System.out.println("1/2 = " + (i1 / (double)i2)); // => 0.5
+ System.out.println("1/2.0 = " + (i1 / (double)i2)); // => 0.5
// Modulo
System.out.println("11%3 = "+(11 % 3)); // => 2
@@ -340,7 +381,7 @@ public class LearnJava {
do {
System.out.println(fooDoWhile);
// Increment the counter
- // Iterated 99 times, fooDoWhile 0->99
+ // Iterated 100 times, fooDoWhile 0->99
fooDoWhile++;
} while(fooDoWhile < 100);
System.out.println("fooDoWhile Value: " + fooDoWhile);
@@ -352,7 +393,7 @@ public class LearnJava {
// Iterated 10 times, fooFor 0->9
}
System.out.println("fooFor Value: " + fooFor);
-
+
// Nested For Loop Exit with Label
outer:
for (int i = 0; i < 10; i++) {
@@ -363,7 +404,7 @@ public class LearnJava {
}
}
}
-
+
// For Each Loop
// The for loop is also able to iterate over arrays as well as objects
// that implement the Iterable interface.
@@ -381,6 +422,9 @@ public class LearnJava {
// It also works with enumerated types (discussed in Enum Types), the
// String class, and a few special classes that wrap primitive types:
// Character, Byte, Short, and Integer.
+ // Starting in Java 7 and above, we can also use the String type.
+ // Note: Do remember that, not adding "break" at end any particular case ends up in
+ // executing the very next case(given it satisfies the condition provided) as well.
int month = 3;
String monthString;
switch (month) {
@@ -394,38 +438,21 @@ public class LearnJava {
break;
}
System.out.println("Switch Case Result: " + monthString);
-
- // Starting in Java 7 and above, switching Strings works like this:
- String myAnswer = "maybe";
- switch(myAnswer) {
- case "yes":
- System.out.println("You answered yes.");
- break;
- case "no":
- System.out.println("You answered no.");
- break;
- case "maybe":
- System.out.println("You answered maybe.");
- break;
- default:
- System.out.println("You answered " + myAnswer);
- break;
- }
-
-
+
+
// Try-with-resources (Java 7+)
// Try-catch-finally statements work as expected in Java but in Java 7+
// the try-with-resources statement is also available. Try-with-resources
- // simplifies try-catch-finally statements be closing resources
+ // simplifies try-catch-finally statements by closing resources
// automatically.
-
- // In order to use a try-with-resources, include a an instance of a class
+
+ // In order to use a try-with-resources, include an instance of a class
// in the try statement. The class must implement java.lang.AutoCloseable.
- try(BufferedReader br = new BufferedReader(new FileReader("foo.txt"))) {
+ try (BufferedReader br = new BufferedReader(new FileReader("foo.txt"))) {
// You can attempt to do something that could throw an exception.
System.out.println(br.readLine());
// In Java 7, the resource will always be closed, even if it throws
- // an Exception.
+ // an Exception.
} catch (Exception ex) {
//The resource will be closed before the catch statement executes.
System.out.println("readLine() failed.");
@@ -435,18 +462,22 @@ public class LearnJava {
// a finally statement might not be called.
// To learn more:
// https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
-
-
+
+
// Conditional Shorthand
// You can use the '?' operator for quick assignments or logic forks.
// Reads as "If (statement) is true, use <first value>, otherwise, use
// <second value>"
int foo = 5;
String bar = (foo < 10) ? "A" : "B";
- System.out.println(bar); // Prints A, because the statement is true
+ System.out.println("bar : " + bar); // Prints "bar : A", because the
+ // statement is true.
+ // Or simply
+ System.out.println("bar : " + (foo < 10 ? "A" : "B"));
+
////////////////////////////////////////
- // Converting Data Types And Typecasting
+ // Converting Data Types
////////////////////////////////////////
// Converting data
@@ -462,11 +493,6 @@ public class LearnJava {
// Long
// String
- // Typecasting
- // You can also cast Java objects, there's a lot of details and deals
- // with some more intermediate concepts. Feel free to check it out here:
- // https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
-
///////////////////////////////////////
// Classes And Functions
///////////////////////////////////////
@@ -531,10 +557,10 @@ class Bicycle {
String name; // default: Only accessible from within this package
static String className; // Static class variable
- // Static block
+ // Static block
// Java has no implementation of static constructors, but
- // has a static block that can be used to initialize class variables
- // (static variables).
+ // has a static block that can be used to initialize class variables
+ // (static variables).
// This block will be called when the class is loaded.
static {
className = "Bicycle";
@@ -617,6 +643,14 @@ class PennyFarthing extends Bicycle {
}
}
+// Object casting
+// Since the PennyFarthing class is extending the Bicycle class, we can say
+// a PennyFarthing is a Bicycle and write :
+// Bicycle bicycle = new PennyFarthing();
+// This is called object casting where an object is taken for another one. There
+// are lots of details and deals with some more intermediate concepts here:
+// https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
+
// Interfaces
// Interface declaration syntax
// <access-level> interface <interface-name> extends <super-interfaces> {
@@ -632,10 +666,10 @@ public interface Edible {
public interface Digestible {
public void digest();
- // In Java 8, interfaces can have default method.
- // public void digest() {
- // System.out.println("digesting ...");
- // }
+ // Since Java 8, interfaces can have default method.
+ public default void defaultMethod() {
+ System.out.println("Hi from default method ...");
+ }
}
// We can now create a class that implements both of these interfaces.
@@ -668,20 +702,27 @@ public class ExampleClass extends ExampleClassParent implements InterfaceOne,
// Abstract Classes
// Abstract Class declaration syntax
-// <access-level> abstract <abstract-class-name> extends <super-abstract-classes> {
+// <access-level> abstract class <abstract-class-name> extends
+// <super-abstract-classes> {
// // Constants and variables
// // Method declarations
// }
-// Marking a class as abstract means that it contains abstract methods that
-// must be defined in a child class. Similar to interfaces, abstract classes
-// cannot be instantiated, but instead must be extended and the abstract
-// methods defined. Different from interfaces, abstract classes can contain a
-// concrete and abstract methods. Methods in an interface cannot have a body,
-// mixture of unless the method is static, and variables are final by default,
-// unlike an abstract class. Also abstract classes CAN have the "main" method.
+// Abstract Classes cannot be instantiated.
+// Abstract classes may define abstract methods.
+// Abstract methods have no body and are marked abstract
+// Non-abstract child classes must @Override all abstract methods
+// from their super-classes.
+// Abstract classes can be useful when combining repetitive logic
+// with customised behavior, but as Abstract classes require
+// inheritance, they violate "Composition over inheritance"
+// so consider other approaches using composition.
+// https://en.wikipedia.org/wiki/Composition_over_inheritance
+
public abstract class Animal
{
+ private int age;
+
public abstract void makeSound();
// Method can have a body
@@ -692,17 +733,12 @@ public abstract class Animal
age = 30;
}
- // No need to initialize, however in an interface
- // a variable is implicitly final and hence has
- // to be initialized.
- protected int age;
-
public void printAge()
{
- System.out.println(age);
+ System.out.println(age);
}
- // Abstract classes can have main function.
+ // Abstract classes can have main method.
public static void main(String[] args)
{
System.out.println("I am abstract");
@@ -717,7 +753,7 @@ class Dog extends Animal
public void makeSound()
{
System.out.println("Bark");
- // age = 30; ==> ERROR! age is private to Animal
+ // age = 30; ==> ERROR! age is private to Animal
}
// NOTE: You will get an error if you used the
@@ -781,18 +817,18 @@ public abstract class Mammal()
// you would specify a days-of-the-week enum type as:
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
- THURSDAY, FRIDAY, SATURDAY
+ THURSDAY, FRIDAY, SATURDAY
}
// We can use our enum Day like that:
public class EnumTest {
// Variable Enum
Day day;
-
+
public EnumTest(Day day) {
this.day = day;
}
-
+
public void tellItLikeItIs() {
switch (day) {
case MONDAY:
@@ -800,17 +836,17 @@ public class EnumTest {
break;
case FRIDAY:
System.out.println("Fridays are better.");
- break;
- case SATURDAY:
+ break;
+ case SATURDAY:
case SUNDAY:
System.out.println("Weekends are best.");
- break;
+ break;
default:
System.out.println("Midweek days are so-so.");
break;
}
}
-
+
public static void main(String[] args) {
EnumTest firstDay = new EnumTest(Day.MONDAY);
firstDay.tellItLikeItIs(); // => Mondays are bad.
@@ -819,10 +855,112 @@ public class EnumTest {
}
}
-// Enum types are much more powerful than we show above.
+// Enum types are much more powerful than we show above.
// The enum body can include methods and other fields.
// You can see more at https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
+// Getting Started with Lambda Expressions
+//
+// New to Java version 8 are lambda expressions. Lambdas are more commonly found
+// in functional programming languages, which means they are methods which can
+// be created without belonging to a class, passed around as if it were itself
+// an object, and executed on demand.
+//
+// Final note, lambdas must implement a functional interface. A functional
+// interface is one which has only a single abstract method declared. It can
+// have any number of default methods. Lambda expressions can be used as an
+// instance of that functional interface. Any interface meeting the requirements
+// is treated as a functional interface. You can read more about interfaces
+// above.
+//
+import java.util.Map;
+import java.util.HashMap;
+import java.util.function.*;
+import java.security.SecureRandom;
+
+public class Lambdas {
+ public static void main(String[] args) {
+ // Lambda declaration syntax:
+ // <zero or more parameters> -> <expression body or statement block>
+
+ // We will use this hashmap in our examples below.
+ Map<String, String> planets = new HashMap<>();
+ planets.put("Mercury", "87.969");
+ planets.put("Venus", "224.7");
+ planets.put("Earth", "365.2564");
+ planets.put("Mars", "687");
+ planets.put("Jupiter", "4,332.59");
+ planets.put("Saturn", "10,759");
+ planets.put("Uranus", "30,688.5");
+ planets.put("Neptune", "60,182");
+
+ // Lambda with zero parameters using the Supplier functional interface
+ // from java.util.function.Supplier. The actual lambda expression is
+ // what comes after numPlanets =.
+ Supplier<String> numPlanets = () -> Integer.toString(planets.size());
+ System.out.format("Number of Planets: %s\n\n", numPlanets.get());
+
+ // Lambda with one parameter and using the Consumer functional interface
+ // from java.util.function.Consumer. This is because planets is a Map,
+ // which implements both Collection and Iterable. The forEach used here,
+ // found in Iterable, applies the lambda expression to each member of
+ // the Collection. The default implementation of forEach behaves as if:
+ /*
+ for (T t : this)
+ action.accept(t);
+ */
+
+ // The actual lambda expression is the parameter passed to forEach.
+ planets.keySet().forEach((p) -> System.out.format("%s\n", p));
+
+ // If you are only passing a single argument, then the above can also be
+ // written as (note absent parentheses around p):
+ planets.keySet().forEach(p -> System.out.format("%s\n", p));
+
+ // Tracing the above, we see that planets is a HashMap, keySet() returns
+ // a Set of its keys, forEach applies each element as the lambda
+ // expression of: (parameter p) -> System.out.format("%s\n", p). Each
+ // time, the element is said to be "consumed" and the statement(s)
+ // referred to in the lambda body is applied. Remember the lambda body
+ // is what comes after the ->.
+
+ // The above without use of lambdas would look more traditionally like:
+ for (String planet : planets.keySet()) {
+ System.out.format("%s\n", planet);
+ }
+
+ // This example differs from the above in that a different forEach
+ // implementation is used: the forEach found in the HashMap class
+ // implementing the Map interface. This forEach accepts a BiConsumer,
+ // which generically speaking is a fancy way of saying it handles
+ // the Set of each Key -> Value pairs. This default implementation
+ // behaves as if:
+ /*
+ for (Map.Entry<K, V> entry : map.entrySet())
+ action.accept(entry.getKey(), entry.getValue());
+ */
+
+ // The actual lambda expression is the parameter passed to forEach.
+ String orbits = "%s orbits the Sun in %s Earth days.\n";
+ planets.forEach((K, V) -> System.out.format(orbits, K, V));
+
+ // The above without use of lambdas would look more traditionally like:
+ for (String planet : planets.keySet()) {
+ System.out.format(orbits, planet, planets.get(planet));
+ }
+
+ // Or, if following more closely the specification provided by the
+ // default implementation:
+ for (Map.Entry<String, String> planet : planets.entrySet()) {
+ System.out.format(orbits, planet.getKey(), planet.getValue());
+ }
+
+ // These examples cover only the very basic use of lambdas. It might not
+ // seem like much or even very useful, but remember that a lambda can be
+ // created as an object that can later be passed as parameters to other
+ // methods.
+ }
+}
```
## Further Reading
@@ -858,6 +996,10 @@ The links provided here below are just to get an understanding of the topic, fee
* [Codingbat.com](http://codingbat.com/java)
+* [Codewars - Java Katas](https://www.codewars.com/?language=java)
+
+* [University of Helsinki - Object-Oriented programming with Java](http://moocfi.github.io/courses/2013/programming-part-1/)
+
**Books**:
* [Head First Java](http://www.headfirstlabs.com/books/hfjava/)
diff --git a/javascript.html.markdown b/javascript.html.markdown
index 38119864..3c0e6d4f 100644
--- a/javascript.html.markdown
+++ b/javascript.html.markdown
@@ -1,7 +1,7 @@
---
language: javascript
contributors:
- - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Leigh Brenecki", "https://leigh.net.au"]
- ["Ariel Krakowski", "http://www.learneroo.com"]
filename: javascript.js
---
@@ -103,7 +103,7 @@ false;
// ... which works with more than just strings
"1, 2, " + 3; // = "1, 2, 3"
-"Hello " + ["world", "!"] // = "Hello world,!"
+"Hello " + ["world", "!"]; // = "Hello world,!"
// and are compared with < and >
"a" < "b"; // = true
@@ -180,6 +180,24 @@ myArray.length; // = 4
// Add/Modify at specific index
myArray[3] = "Hello";
+// Add and remove element from front or back end of an array
+myArray.unshift(3); // Add as the first element
+someVar = myArray.shift(); // Remove first element and return it
+myArray.push(3); // Add as the last element
+someVar = myArray.pop(); // Remove last element and return it
+
+// Join all elements of an array with semicolon
+var myArray0 = [32,false,"js",12,56,90];
+myArray0.join(";"); // = "32;false;js;12;56;90"
+
+// Get subarray of elements from index 1 (include) to 4 (exclude)
+myArray0.slice(1,4); // = [false,"js",12]
+
+// Remove 4 elements starting from index 2, and insert there strings
+// "hi","wr" and "ld"; return removed subarray
+myArray0.splice(2,4,"hi","wr","ld"); // = ["js",12,56,90]
+// myArray0 === [32,false,"hi","wr","ld"]
+
// JavaScript's objects are equivalent to "dictionaries" or "maps" in other
// languages: an unordered collection of key-value pairs.
var myObj = {key1: "Hello", key2: "World"};
@@ -222,10 +240,10 @@ while (true){
var input;
do {
input = getInput();
-} while (!isValid(input))
+} while (!isValid(input));
// The `for` loop is the same as C and Java:
-// initialisation; continue condition; iteration.
+// initialization; continue condition; iteration.
for (var i = 0; i < 5; i++){
// will run 5 times
}
@@ -241,26 +259,21 @@ for (var i = 0; i < 10; i++) {
}
}
-// The for/in statement iterates over every property across the entire prototype chain.
+// The for/in statement allows iteration over properties of an object.
var description = "";
var person = {fname:"Paul", lname:"Ken", age:18};
for (var x in person){
description += person[x] + " ";
-}
-
-// To only consider properties attached to the object itself
-// and not its prototypes, use the `hasOwnProperty()` check.
-var description = "";
-var person = {fname:"Paul", lname:"Ken", age:18};
-for (var x in person){
- if (person.hasOwnProperty(x)){
- description += person[x] + " ";
- }
-}
+} // description = 'Paul Ken 18 '
-// For/in should not be used to iterate over an Array where the index order
-// is important, as there is no guarantee that for/in will return the indexes
-// in any particular order.
+// The for/of statement allows iteration over iterable objects (including the built-in String,
+// Array, e.g. the Array-like arguments or NodeList objects, TypedArray, Map and Set,
+// and user-defined iterables).
+var myPets = "";
+var pets = ["cat", "dog", "hamster", "hedgehog"];
+for (var pet of pets){
+ myPets += pet + " ";
+} // myPets = 'cat dog hamster hedgehog '
// && is logical and, || is logical or
if (house.size == "big" && house.colour == "blue"){
@@ -273,7 +286,6 @@ if (colour == "red" || colour == "blue"){
// && and || "short circuit", which is useful for setting default values.
var name = otherName || "default";
-
// The `switch` statement checks for equality with `===`.
// Use 'break' after each case
// or the cases after the correct one will be executed too.
@@ -308,7 +320,7 @@ myFunction("foo"); // = "FOO"
// automatic semicolon insertion. Watch out for this when using Allman style.
function myFunction(){
return // <- semicolon automatically inserted here
- {thisIsAn: 'object literal'}
+ {thisIsAn: 'object literal'};
}
myFunction(); // = undefined
@@ -403,7 +415,7 @@ myFunc(); // = undefined
// through `this`, even if it wasn't attached when it was defined.
var myOtherFunc = function(){
return this.myString.toUpperCase();
-}
+};
myObj.myOtherFunc = myOtherFunc;
myObj.myOtherFunc(); // = "HELLO WORLD!"
@@ -412,7 +424,7 @@ myObj.myOtherFunc(); // = "HELLO WORLD!"
var anotherFunc = function(s){
return this.myString + s;
-}
+};
anotherFunc.call(myObj, " And Hello Moon!"); // = "Hello World! And Hello Moon!"
// The `apply` function is nearly identical, but takes an array for an argument
@@ -435,7 +447,7 @@ boundFunc(" And Hello Saturn!"); // = "Hello World! And Hello Saturn!"
// `bind` can also be used to partially apply (curry) a function.
-var product = function(a, b){ return a * b; }
+var product = function(a, b){ return a * b; };
var doubler = product.bind(this, 2);
doubler(8); // = 16
@@ -445,10 +457,14 @@ doubler(8); // = 16
var MyConstructor = function(){
this.myNumber = 5;
-}
+};
myNewObj = new MyConstructor(); // = {myNumber: 5}
myNewObj.myNumber; // = 5
+// Unlike most other popular object-oriented languages, JavaScript has no
+// concept of 'instances' created from 'class' blueprints; instead, JavaScript
+// combines instantiation and inheritance into a single concept: a 'prototype'.
+
// Every JavaScript object has a 'prototype'. When you go to access a property
// on an object that doesn't exist on the actual object, the interpreter will
// look at its prototype.
@@ -462,7 +478,7 @@ var myObj = {
var myPrototype = {
meaningOfLife: 42,
myFunc: function(){
- return this.myString.toLowerCase()
+ return this.myString.toLowerCase();
}
};
@@ -485,6 +501,27 @@ myObj.myBoolean; // = true
myPrototype.meaningOfLife = 43;
myObj.meaningOfLife; // = 43
+// The for/in statement allows iteration over properties of an object,
+// walking up the prototype chain until it sees a null prototype.
+for (var x in myObj){
+ console.log(myObj[x]);
+}
+///prints:
+// Hello world!
+// 43
+// [Function: myFunc]
+// true
+
+// To only consider properties attached to the object itself
+// and not its prototypes, use the `hasOwnProperty()` check.
+for (var x in myObj){
+ if (myObj.hasOwnProperty(x)){
+ console.log(myObj[x]);
+ }
+}
+///prints:
+// Hello world!
+
// We mentioned that `__proto__` was non-standard, and there's no standard way to
// change the prototype of an existing object. However, there are two ways to
// create a new object with a given prototype.
@@ -506,7 +543,7 @@ MyConstructor.prototype = {
};
var myNewObj2 = new MyConstructor();
myNewObj2.getMyNumber(); // = 5
-myNewObj2.myNumber = 6
+myNewObj2.myNumber = 6;
myNewObj2.getMyNumber(); // = 6
// Built-in types like strings and numbers also have constructors that create
@@ -531,7 +568,7 @@ if (new Number(0)){
// you can actually add functionality to a string, for instance.
String.prototype.firstCharacter = function(){
return this.charAt(0);
-}
+};
"abc".firstCharacter(); // = "a"
// This fact is often used in "polyfilling", which is implementing newer
@@ -547,8 +584,50 @@ if (Object.create === undefined){ // don't overwrite it if it exists
Constructor.prototype = proto;
// then use it to create a new, appropriately-prototyped object
return new Constructor();
- }
+ };
}
+
+// ES6 Additions
+
+// The "let" keyword allows you to define variables in a lexical scope,
+// as opposed to a block scope like the var keyword does.
+let name = "Billy";
+
+// Variables defined with let can be reassigned new values.
+name = "William";
+
+// The "const" keyword allows you to define a variable in a lexical scope
+// like with let, but you cannot reassign the value once one has been assigned.
+
+const pi = 3.14;
+
+pi = 4.13; // You cannot do this.
+
+// There is a new syntax for functions in ES6 known as "lambda syntax".
+// This allows functions to be defined in a lexical scope like with variables
+// defined by const and let.
+
+const isEven = (number) => {
+ return number % 2 === 0;
+};
+
+isEven(7); // false
+
+// The "equivalent" of this function in the traditional syntax would look like this:
+
+function isEven(number) {
+ return number % 2 === 0;
+};
+
+// I put the word "equivalent" in double quotes because a function defined
+// using the lambda syntax cannnot be called before the definition.
+// The following is an example of invalid usage:
+
+add(1, 8);
+
+const add = (firstNumber, secondNumber) => {
+ return firstNumber + secondNumber;
+};
```
## Further Reading
@@ -570,11 +649,14 @@ of the language.
[JavaScript: The Definitive Guide][6] is a classic guide and reference book.
-[Eloquent Javascript][8] by Marijn Haverbeke is an excellent JS book/ebook with attached terminal
+[Eloquent Javascript][8] by Marijn Haverbeke is an excellent JS book/ebook with
+attached terminal
-[Eloquent Javascript - The Annotated Version][9] by Gordon Zhu is also a great derivative of Eloquent Javascript with extra explanations and clarifications for some of the more complicated examples.
+[Javascript: The Right Way][10] is a guide intended to introduce new developers
+to JavaScript and help experienced developers learn more about its best practices.
-[Javascript: The Right Way][10] is a guide intended to introduce new developers to JavaScript and help experienced developers learn more about its best practices.
+[Javascript:Info][11] is a modern javascript tutorial covering the basics (core language and working with a browser)
+as well as advanced topics with concise explanations.
In addition to direct contributors to this article, some content is adapted from
@@ -590,5 +672,5 @@ Mozilla Developer Network.
[6]: http://www.amazon.com/gp/product/0596805527/
[7]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
[8]: http://eloquentjavascript.net/
-[9]: http://watchandcode.com/courses/eloquent-javascript-the-annotated-version
[10]: http://jstherightway.org/
+[11]: https://javascript.info/
diff --git a/jquery.html.markdown b/jquery.html.markdown
index d498733d..18077dca 100644
--- a/jquery.html.markdown
+++ b/jquery.html.markdown
@@ -3,6 +3,7 @@ category: tool
tool: jquery
contributors:
- ["Sawyer Charles", "https://github.com/xssc"]
+ - ["Devansh Patil", "https://github.com/subtra3t"]
filename: jquery.js
---
@@ -10,6 +11,7 @@ jQuery is a JavaScript library that helps you "do more, write less". It makes ma
Because jQuery is a JavaScript library you should [learn JavaScript first](https://learnxinyminutes.com/docs/javascript/)
+**NOTE**: jQuery has fallen out of the limelight in recent years, since you can achieve the same thing with the vanilla DOM (Document Object Model) API. So the only thing it is used for is a couple of handy features, such as the [jQuery date picker](https://api.jqueryui.com/datepicker) (which actually has a standard, unlike the `<input type="date">` HTML element), and the obvious decrease in the code length.
```js
@@ -104,7 +106,7 @@ tables.animate({margin-top:"+=50", height: "100px"}, 500, myFunction);
// 3. Manipulation
// These are similar to effects but can do more
-$('div').addClass('taming-slim-20'); // Adds class taming-slim-20 to all div
+$('div').addClass('taming-slim-20'); // Adds class taming-slim-20 to all div
// Common manipulation methods
$('p').append('Hello world'); // Adds to end of element
@@ -125,4 +127,8 @@ $('p').each(function() {
});
-``
+```
+
+## Further Reading
+
+* [Codecademy - jQuery](https://www.codecademy.com/learn/learn-jquery) A good introduction to jQuery in a "learn by doing it" format.
diff --git a/json.html.markdown b/json.html.markdown
index a612cffe..1ccdb5cf 100644
--- a/json.html.markdown
+++ b/json.html.markdown
@@ -6,14 +6,15 @@ contributors:
- ["Marco Scannadinari", "https://github.com/marcoms"]
- ["himanshu", "https://github.com/himanshu81494"]
- ["Michael Neth", "https://github.com/infernocloud"]
+ - ["Athanasios Emmanouilidis", "https://github.com/athanasiosem"]
---
-JSON is an extremely simple data-interchange format. As [json.org](http://json.org) says, it is easy for humans to read and write and for machines to parse and generate.
+JSON is an extremely simple data-interchange format. As [json.org](https://json.org) says, it is easy for humans to read and write and for machines to parse and generate.
A piece of JSON must represent either:
+
* A collection of name/value pairs (`{ }`). In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
* An ordered list of values (`[ ]`). In various languages, this is realized as an array, vector, list, or sequence.
- an array/list/sequence (`[ ]`) or a dictionary/object/associated array (`{ }`).
JSON in its purest form has no actual comments, but most parsers will accept C-style (`//`, `/* */`) comments. Some parsers also tolerate a trailing comma (i.e. a comma after the last element of an array or the after the last property of an object), but they should be avoided for better compatibility.
@@ -79,4 +80,5 @@ Supported data types:
## Further Reading
-* [JSON.org](http://json.org) All of JSON beautifully explained using flowchart-like graphics.
+* [JSON.org](https://json.org) All of JSON beautifully explained using flowchart-like graphics.
+* [JSON Tutorial](https://www.youtube.com/watch?v=wI1CWzNtE-M) A concise introduction to JSON.
diff --git a/jsonnet.html.markdown b/jsonnet.html.markdown
new file mode 100644
index 00000000..241caf5f
--- /dev/null
+++ b/jsonnet.html.markdown
@@ -0,0 +1,139 @@
+---
+language: jsonnet
+filename: learnjsonnet.jsonnet
+contributors:
+ - ["Huan Wang", "https://github.com/fredwangwang"]
+---
+
+Jsonnet is a powerful templating language for JSON. Any valid JSON
+document is a valid Jsonnet object. For an interactive demo/tutorial,
+click [here](https://jsonnet.org/learning/tutorial.html)
+
+```python
+// single line comment
+
+/*
+ multiline comment
+*/
+
+# as well as python style comment
+
+# define a variable.
+# Variables have no effect in the generated JSON without being used.
+local num1 = 1;
+local num2 = 1 + 1;
+local num3 = 5 - 2;
+local num4 = 9 % 5;
+local num5 = 10 / 2.0;
+# jsonnet is a lazy language, if a variable is not used, it is not evaluated.
+local num_runtime_error = 1 / 0;
+
+# fields are valid identifiers without quotes
+local obj1 = { a: 'letter a', B: 'letter B' };
+
+local arr1 = ['a', 'b', 'c'];
+
+# string literals use " or '.
+local str1 = 'a' + 'B';
+# multiline text literal in between |||
+# Each line must start with a white space.
+local str_multiline = |||
+ this is a
+ multiline string
+|||;
+# Python-compatible string formatting is available via %
+# When combined with ||| this can be used for templating text files.
+local str_templating = |||
+ %(f1)0.3f
+||| % { f1: 1.2345678 };
+assert str_templating == '1.235\n';
+
+# if b then e else e. The else branch is optional and defaults to null
+local var1 = if 3 < 2 then "YES";
+assert var1 == null;
+
+local obj2 = {
+ # variable defined inside the object ends with ','
+ local var_in_obj = 0,
+
+ local vowels = ['a', 'e', 'i', 'o', 'u'],
+ local numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
+
+ # [num] to look up an array element
+ first_vowel: vowels[0],
+ # can also slice the array like in Python
+ even_numbers: numbers[1::2],
+
+ # python-style list and object comprehensions are also supported
+ double_numbers: [x * 2 for x in numbers],
+ even_numbers_map: {
+ # [ ] syntax in field name is to compute the field name dynamically
+ [x + '_is_even']: true for x in numbers if x % 2 == 0
+ },
+
+ nested: {
+ nested_field1: 'some-value',
+ # self refers to the current object
+ # ["field-name"] or .field-name can be used to look up a field
+ nested_field2: self.nested_field1,
+ nested_field3: self.nested_field1,
+ # $ refers to outer-most object
+ nested_field4: $.first_vowel,
+
+ assert self.nested_field1 == self.nested_field2,
+ assert self.nested_field1 == self.nested_field3,
+ },
+
+ special_field: 'EVERYTHING FEELS BAD',
+};
+
+local obj3 = {
+ local var_in_obj = 1.234,
+ local var_in_obj2 = { a: { b: 'c' } },
+
+ concat_array: [1, 2, 3] + [4],
+ # strings can be concat with +,
+ # which implicitly converts one operand to string if needed.
+ concat_string: '123' + 4,
+
+ # == tests deep equality
+ equals: { a: { b: 'c', d: {} } } == var_in_obj2,
+
+ special_field: 'this feels good',
+};
+
+# objects can be merged with + where the right-hand side wins field conflicts
+local obj4 = obj2 + obj3;
+assert obj4.special_field == 'this feels good';
+
+# define a function
+# functions have positional parameters, named parameters, and default arguments
+local my_function(x, y, z=1) = x + y - z;
+local num6 = my_function(7, 8, 9);
+local num7 = my_function(8, z=10, y=9);
+local num8 = my_function(4, 5);
+# inline anonymous function
+local num9 = (function(x) x * x)(3);
+
+local obj5 = {
+ # define a method
+ # fields defined with :: are hidden, which does not apper in generated JSON
+ # function cannot be serialized so need to be hidden
+ # if the object is used in the generated JSON.
+ is_odd(x):: x % 2 == 1,
+};
+assert obj5 == {};
+
+# a jsonnet document has to evaluate to something
+# be it an object, list, number or just string literal
+"FIN"
+
+```
+
+## Further Reading
+There are a few but important concepts that are not touched in this exmaple, including:
+
+- Passing variables from command line: [Parameterize Entire Config](https://jsonnet.org/learning/tutorial.html#parameterize-entire-config)
+- Import other jsonnet libraries/files: [Imports](https://jsonnet.org/learning/tutorial.html#imports)
+- In depth example of OOP aspect of Jsonnet: [Object-Orientation](https://jsonnet.org/learning/tutorial.html#Object-Orientation)
+- Useful standard library: [Stdlib](https://jsonnet.org/ref/stdlib.html)
diff --git a/julia.html.markdown b/julia.html.markdown
index 5b3f6fd8..4d8eb497 100644
--- a/julia.html.markdown
+++ b/julia.html.markdown
@@ -2,17 +2,18 @@
language: Julia
contributors:
- ["Leah Hanson", "http://leahhanson.us"]
- - ["Pranit Bauva", "http://github.com/pranitbauva1997"]
+ - ["Pranit Bauva", "https://github.com/pranitbauva1997"]
+ - ["Daniel YC Lin", "https://github.com/dlintw"]
filename: learnjulia.jl
---
Julia is a new homoiconic functional language focused on technical computing.
-While having the full power of homoiconic macros, first-class functions, and low-level control, Julia is as easy to learn and use as Python.
+While having the full power of homoiconic macros, first-class functions,
+and low-level control, Julia is as easy to learn and use as Python.
-This is based on Julia 0.4.
-
-```ruby
+This is based on Julia version 1.0.0.
+```julia
# Single line comments start with a hash (pound) symbol.
#= Multiline comments can be written
by putting '#=' before the text and '=#'
@@ -26,38 +27,45 @@ This is based on Julia 0.4.
# Everything in Julia is an expression.
# There are several basic types of numbers.
-3 # => 3 (Int64)
-3.2 # => 3.2 (Float64)
-2 + 1im # => 2 + 1im (Complex{Int64})
-2//3 # => 2//3 (Rational{Int64})
+typeof(3) # => Int64
+typeof(3.2) # => Float64
+typeof(2 + 1im) # => Complex{Int64}
+typeof(2 // 3) # => Rational{Int64}
# All of the normal infix operators are available.
-1 + 1 # => 2
-8 - 1 # => 7
-10 * 2 # => 20
-35 / 5 # => 7.0
-5 / 2 # => 2.5 # dividing an Int by an Int always results in a Float
-div(5, 2) # => 2 # for a truncated result, use div
-5 \ 35 # => 7.0
-2 ^ 2 # => 4 # power, not bitwise xor
-12 % 10 # => 2
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7.0
+10 / 2 # => 5.0 # dividing integers always results in a Float64
+div(5, 2) # => 2 # for a truncated result, use div
+5 \ 35 # => 7.0
+2^2 # => 4 # power, not bitwise xor
+12 % 10 # => 2
# Enforce precedence with parentheses
-(1 + 3) * 2 # => 8
+(1 + 3) * 2 # => 8
+
+# Julia (unlike Python for instance) has integer under/overflow
+10^19 # => -8446744073709551616
+# use bigint or floating point to avoid this
+big(10)^19 # => 10000000000000000000
+1e19 # => 1.0e19
+10.0^19 # => 1.0e19
# Bitwise Operators
-~2 # => -3 # bitwise not
-3 & 5 # => 1 # bitwise and
-2 | 4 # => 6 # bitwise or
-2 $ 4 # => 6 # bitwise xor
-2 >>> 1 # => 1 # logical shift right
-2 >> 1 # => 1 # arithmetic shift right
-2 << 1 # => 4 # logical/arithmetic shift left
-
-# You can use the bits function to see the binary representation of a number.
-bits(12345)
+~2 # => -3 # bitwise not
+3 & 5 # => 1 # bitwise and
+2 | 4 # => 6 # bitwise or
+xor(2, 4) # => 6 # bitwise xor
+2 >>> 1 # => 1 # logical shift right
+2 >> 1 # => 1 # arithmetic shift right
+2 << 1 # => 4 # logical/arithmetic shift left
+
+# Use the bitstring function to see the binary representation of a number.
+bitstring(12345)
# => "0000000000000000000000000000000000000000000000000011000000111001"
-bits(12345.0)
+bitstring(12345.0)
# => "0100000011001000000111001000000000000000000000000000000000000000"
# Boolean values are primitives
@@ -65,72 +73,75 @@ true
false
# Boolean operators
-!true # => false
-!false # => true
-1 == 1 # => true
-2 == 1 # => false
-1 != 1 # => false
-2 != 1 # => true
-1 < 10 # => true
-1 > 10 # => false
-2 <= 2 # => true
-2 >= 2 # => true
-# Comparisons can be chained
-1 < 2 < 3 # => true
-2 < 3 < 2 # => false
+!true # => false
+!false # => true
+1 == 1 # => true
+2 == 1 # => false
+1 != 1 # => false
+2 != 1 # => true
+1 < 10 # => true
+1 > 10 # => false
+2 <= 2 # => true
+2 >= 2 # => true
+# Comparisons can be chained, like in Python but unlike many other languages
+1 < 2 < 3 # => true
+2 < 3 < 2 # => false
# Strings are created with "
"This is a string."
-# Julia has several types of strings, including ASCIIString and UTF8String.
-# More on this in the Types section.
-
# Character literals are written with '
'a'
-# Some strings can be indexed like an array of characters
-"This is a string"[1] # => 'T' # Julia indexes from 1
-# However, this is will not work well for UTF8 strings,
-# so iterating over strings is recommended (map, for loops, etc).
+# Strings are UTF8 encoded, so strings like "π" or "☃" are not directly equivalent
+# to an array of single characters.
+# Only if they contain only ASCII characters can they be safely indexed.
+ascii("This is a string")[1] # => 'T'
+# => 'T': ASCII/Unicode U+0054 (category Lu: Letter, uppercase)
+# Beware, Julia indexes everything from 1 (like MATLAB), not 0 (like most languages).
+# Otherwise, iterating over strings is recommended (map, for loops, etc).
-# $ can be used for string interpolation:
+# String can be compared lexicographically, in dictionnary order:
+"good" > "bye" # => true
+"good" == "good" # => true
+"1 + 2 = 3" == "1 + 2 = $(1 + 2)" # => true
+
+# $(..) can be used for string interpolation:
"2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
# You can put any Julia expression inside the parentheses.
-# Another way to format strings is the printf macro.
-@printf "%d is less than %f" 4.5 5.3 # 5 is less than 5.300000
-
# Printing is easy
-println("I'm Julia. Nice to meet you!")
+println("I'm Julia. Nice to meet you!") # => I'm Julia. Nice to meet you!
+
+# Another way to format strings is the printf macro from the stdlib Printf.
+using Printf # this is how you load (or import) a module
+@printf "%d is less than %f\n" 4.5 5.3 # => 5 is less than 5.300000
-# String can be compared lexicographically
-"good" > "bye" # => true
-"good" == "good" # => true
-"1 + 2 = 3" == "1 + 2 = $(1+2)" # => true
####################################################
## 2. Variables and Collections
####################################################
# You don't declare variables before assigning to them.
-some_var = 5 # => 5
-some_var # => 5
+someVar = 5 # => 5
+someVar # => 5
# Accessing a previously unassigned variable is an error
try
- some_other_var # => ERROR: some_other_var not defined
+ someOtherVar # => ERROR: UndefVarError: someOtherVar not defined
catch e
println(e)
end
# Variable names start with a letter or underscore.
# After that, you can use letters, digits, underscores, and exclamation points.
-SomeOtherVar123! = 6 # => 6
+SomeOtherVar123! = 6 # => 6
# You can also use certain unicode characters
-☃ = 8 # => 8
-# These are especially handy for mathematical notation
-2 * π # => 6.283185307179586
+# here ☃ is a Unicode 'snowman' characters, see http://emojipedia.org/%E2%98%83%EF%B8%8F if it displays wrongly here
+☃ = 8 # => 8
+# These are especially handy for mathematical notation, like the constant π
+2 * π # => 6.283185307179586
# A note on naming conventions in Julia:
#
@@ -147,250 +158,283 @@ SomeOtherVar123! = 6 # => 6
# functions are sometimes called mutating functions or in-place functions.
# Arrays store a sequence of values indexed by integers 1 through n:
-a = Int64[] # => 0-element Int64 Array
+a = Int64[] # => 0-element Array{Int64,1}
# 1-dimensional array literals can be written with comma-separated values.
-b = [4, 5, 6] # => 3-element Int64 Array: [4, 5, 6]
-b = [4; 5; 6] # => 3-element Int64 Array: [4, 5, 6]
-b[1] # => 4
-b[end] # => 6
+b = [4, 5, 6] # => 3-element Array{Int64,1}: [4, 5, 6]
+b = [4; 5; 6] # => 3-element Array{Int64,1}: [4, 5, 6]
+b[1] # => 4
+b[end] # => 6
# 2-dimensional arrays use space-separated values and semicolon-separated rows.
-matrix = [1 2; 3 4] # => 2x2 Int64 Array: [1 2; 3 4]
+matrix = [1 2; 3 4] # => 2×2 Array{Int64,2}: [1 2; 3 4]
-# Arrays of a particular Type
-b = Int8[4, 5, 6] # => 3-element Int8 Array: [4, 5, 6]
+# Arrays of a particular type
+b = Int8[4, 5, 6] # => 3-element Array{Int8,1}: [4, 5, 6]
# Add stuff to the end of a list with push! and append!
-push!(a,1) # => [1]
-push!(a,2) # => [1,2]
-push!(a,4) # => [1,2,4]
-push!(a,3) # => [1,2,4,3]
-append!(a,b) # => [1,2,4,3,4,5,6]
+# By convention, the exclamation mark '!' is appended to names of functions
+# that modify their arguments
+push!(a, 1) # => [1]
+push!(a, 2) # => [1,2]
+push!(a, 4) # => [1,2,4]
+push!(a, 3) # => [1,2,4,3]
+append!(a, b) # => [1,2,4,3,4,5,6]
# Remove from the end with pop
-pop!(b) # => 6 and b is now [4,5]
+pop!(b) # => 6
+b # => [4,5]
# Let's put it back
-push!(b,6) # b is now [4,5,6] again.
+push!(b, 6) # => [4,5,6]
+b # => [4,5,6]
-a[1] # => 1 # remember that Julia indexes from 1, not 0!
+a[1] # => 1 # remember that Julia indexes from 1, not 0!
# end is a shorthand for the last index. It can be used in any
# indexing expression
-a[end] # => 6
+a[end] # => 6
-# we also have shift and unshift
-shift!(a) # => 1 and a is now [2,4,3,4,5,6]
-unshift!(a,7) # => [7,2,4,3,4,5,6]
+# we also have popfirst! and pushfirst!
+popfirst!(a) # => 1
+a # => [2,4,3,4,5,6]
+pushfirst!(a, 7) # => [7,2,4,3,4,5,6]
+a # => [7,2,4,3,4,5,6]
# Function names that end in exclamations points indicate that they modify
# their argument.
-arr = [5,4,6] # => 3-element Int64 Array: [5,4,6]
-sort(arr) # => [4,5,6]; arr is still [5,4,6]
-sort!(arr) # => [4,5,6]; arr is now [4,5,6]
+arr = [5,4,6] # => 3-element Array{Int64,1}: [5,4,6]
+sort(arr) # => [4,5,6]
+arr # => [5,4,6]
+sort!(arr) # => [4,5,6]
+arr # => [4,5,6]
# Looking out of bounds is a BoundsError
try
- a[0] # => ERROR: BoundsError() in getindex at array.jl:270
- a[end+1] # => ERROR: BoundsError() in getindex at array.jl:270
+ a[0]
+ # => ERROR: BoundsError: attempt to access 7-element Array{Int64,1} at
+ # index [0]
+ # => Stacktrace:
+ # => [1] getindex(::Array{Int64,1}, ::Int64) at .\array.jl:731
+ # => [2] top-level scope at none:0
+ # => [3] ...
+ # => in expression starting at ...\LearnJulia.jl:180
+ a[end + 1]
+ # => ERROR: BoundsError: attempt to access 7-element Array{Int64,1} at
+ # index [8]
+ # => Stacktrace:
+ # => [1] getindex(::Array{Int64,1}, ::Int64) at .\array.jl:731
+ # => [2] top-level scope at none:0
+ # => [3] ...
+ # => in expression starting at ...\LearnJulia.jl:188
catch e
println(e)
end
# Errors list the line and file they came from, even if it's in the standard
-# library. If you built Julia from source, you can look in the folder base
-# inside the julia folder to find these files.
+# library. You can look in the folder share/julia inside the julia folder to
+# find these files.
# You can initialize arrays from ranges
-a = [1:5;] # => 5-element Int64 Array: [1,2,3,4,5]
+a = [1:5;] # => 5-element Array{Int64,1}: [1,2,3,4,5]
+a2 = [1:5] # => 1-element Array{UnitRange{Int64},1}: [1:5]
# You can look at ranges with slice syntax.
-a[1:3] # => [1, 2, 3]
-a[2:end] # => [2, 3, 4, 5]
+a[1:3] # => [1, 2, 3]
+a[2:end] # => [2, 3, 4, 5]
# Remove elements from an array by index with splice!
arr = [3,4,5]
-splice!(arr,2) # => 4 ; arr is now [3,5]
+splice!(arr, 2) # => 4
+arr # => [3,5]
# Concatenate lists with append!
b = [1,2,3]
-append!(a,b) # Now a is [1, 2, 3, 4, 5, 1, 2, 3]
+append!(a, b) # => [1, 2, 3, 4, 5, 1, 2, 3]
+a # => [1, 2, 3, 4, 5, 1, 2, 3]
# Check for existence in a list with in
-in(1, a) # => true
+in(1, a) # => true
# Examine the length with length
-length(a) # => 8
+length(a) # => 8
# Tuples are immutable.
-tup = (1, 2, 3) # => (1,2,3) # an (Int64,Int64,Int64) tuple.
+tup = (1, 2, 3) # => (1,2,3)
+typeof(tup) # => Tuple{Int64,Int64,Int64}
tup[1] # => 1
-try:
- tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64)
+try
+ tup[1] = 3
+ # => ERROR: MethodError: no method matching
+ # setindex!(::Tuple{Int64,Int64,Int64}, ::Int64, ::Int64)
catch e
println(e)
end
-# Many list functions also work on tuples
+# Many array functions also work on tuples
length(tup) # => 3
-tup[1:2] # => (1,2)
-in(2, tup) # => true
+tup[1:2] # => (1,2)
+in(2, tup) # => true
# You can unpack tuples into variables
-a, b, c = (1, 2, 3) # => (1,2,3) # a is now 1, b is now 2 and c is now 3
+a, b, c = (1, 2, 3) # => (1,2,3)
+a # => 1
+b # => 2
+c # => 3
# Tuples are created even if you leave out the parentheses
-d, e, f = 4, 5, 6 # => (4,5,6)
+d, e, f = 4, 5, 6 # => (4,5,6)
+d # => 4
+e # => 5
+f # => 6
# A 1-element tuple is distinct from the value it contains
(1,) == 1 # => false
-(1) == 1 # => true
+(1) == 1 # => true
# Look how easy it is to swap two values
-e, d = d, e # => (5,4) # d is now 5 and e is now 4
-
+e, d = d, e # => (5,4)
+d # => 5
+e # => 4
# Dictionaries store mappings
-empty_dict = Dict() # => Dict{Any,Any}()
+emptyDict = Dict() # => Dict{Any,Any} with 0 entries
# You can create a dictionary using a literal
-filled_dict = Dict("one"=> 1, "two"=> 2, "three"=> 3)
-# => Dict{ASCIIString,Int64}
+filledDict = Dict("one" => 1, "two" => 2, "three" => 3)
+# => Dict{String,Int64} with 3 entries:
+# => "two" => 2, "one" => 1, "three" => 3
# Look up values with []
-filled_dict["one"] # => 1
+filledDict["one"] # => 1
# Get all keys
-keys(filled_dict)
-# => KeyIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
+keys(filledDict)
+# => Base.KeySet for a Dict{String,Int64} with 3 entries. Keys:
+# => "two", "one", "three"
# Note - dictionary keys are not sorted or in the order you inserted them.
# Get all values
-values(filled_dict)
-# => ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
+values(filledDict)
+# => Base.ValueIterator for a Dict{String,Int64} with 3 entries. Values:
+# => 2, 1, 3
# Note - Same as above regarding key ordering.
# Check for existence of keys in a dictionary with in, haskey
-in(("one" => 1), filled_dict) # => true
-in(("two" => 3), filled_dict) # => false
-haskey(filled_dict, "one") # => true
-haskey(filled_dict, 1) # => false
+in(("one" => 1), filledDict) # => true
+in(("two" => 3), filledDict) # => false
+haskey(filledDict, "one") # => true
+haskey(filledDict, 1) # => false
# Trying to look up a non-existent key will raise an error
try
- filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489
+ filledDict["four"] # => ERROR: KeyError: key "four" not found
catch e
println(e)
end
# Use the get method to avoid that error by providing a default value
-# get(dictionary,key,default_value)
-get(filled_dict,"one",4) # => 1
-get(filled_dict,"four",4) # => 4
+# get(dictionary, key, defaultValue)
+get(filledDict, "one", 4) # => 1
+get(filledDict, "four", 4) # => 4
# Use Sets to represent collections of unordered, unique values
-empty_set = Set() # => Set{Any}()
+emptySet = Set() # => Set(Any[])
# Initialize a set with values
-filled_set = Set([1,2,2,3,4]) # => Set{Int64}(1,2,3,4)
+filledSet = Set([1, 2, 2, 3, 4]) # => Set([4, 2, 3, 1])
# Add more values to a set
-push!(filled_set,5) # => Set{Int64}(5,4,2,3,1)
+push!(filledSet, 5) # => Set([4, 2, 3, 5, 1])
# Check if the values are in the set
-in(2, filled_set) # => true
-in(10, filled_set) # => false
+in(2, filledSet) # => true
+in(10, filledSet) # => false
# There are functions for set intersection, union, and difference.
-other_set = Set([3, 4, 5, 6]) # => Set{Int64}(6,4,5,3)
-intersect(filled_set, other_set) # => Set{Int64}(3,4,5)
-union(filled_set, other_set) # => Set{Int64}(1,2,3,4,5,6)
-setdiff(Set([1,2,3,4]),Set([2,3,5])) # => Set{Int64}(1,4)
-
+otherSet = Set([3, 4, 5, 6]) # => Set([4, 3, 5, 6])
+intersect(filledSet, otherSet) # => Set([4, 3, 5])
+union(filledSet, otherSet) # => Set([4, 2, 3, 5, 6, 1])
+setdiff(Set([1,2,3,4]), Set([2,3,5])) # => Set([4, 1])
####################################################
## 3. Control Flow
####################################################
# Let's make a variable
-some_var = 5
+someVar = 5
# Here is an if statement. Indentation is not meaningful in Julia.
-if some_var > 10
- println("some_var is totally bigger than 10.")
-elseif some_var < 10 # This elseif clause is optional.
- println("some_var is smaller than 10.")
+if someVar > 10
+ println("someVar is totally bigger than 10.")
+elseif someVar < 10 # This elseif clause is optional.
+ println("someVar is smaller than 10.")
else # The else clause is optional too.
- println("some_var is indeed 10.")
+ println("someVar is indeed 10.")
end
# => prints "some var is smaller than 10"
-
# For loops iterate over iterables.
# Iterable types include Range, Array, Set, Dict, and AbstractString.
-for animal=["dog", "cat", "mouse"]
+for animal = ["dog", "cat", "mouse"]
println("$animal is a mammal")
- # You can use $ to interpolate variables or expression into strings
+ # You can use $ to interpolate variables or expression into strings.
+ # In this special case, no need for parenthesis: $animal and $(animal) give the same
end
-# prints:
-# dog is a mammal
-# cat is a mammal
-# mouse is a mammal
+# => dog is a mammal
+# => cat is a mammal
+# => mouse is a mammal
# You can use 'in' instead of '='.
for animal in ["dog", "cat", "mouse"]
println("$animal is a mammal")
end
-# prints:
-# dog is a mammal
-# cat is a mammal
-# mouse is a mammal
+# => dog is a mammal
+# => cat is a mammal
+# => mouse is a mammal
-for a in Dict("dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal")
- println("$(a[1]) is a $(a[2])")
+for pair in Dict("dog" => "mammal", "cat" => "mammal", "mouse" => "mammal")
+ from, to = pair
+ println("$from is a $to")
end
-# prints:
-# dog is a mammal
-# cat is a mammal
-# mouse is a mammal
+# => mouse is a mammal
+# => cat is a mammal
+# => dog is a mammal
-for (k,v) in Dict("dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal")
+for (k, v) in Dict("dog" => "mammal", "cat" => "mammal", "mouse" => "mammal")
println("$k is a $v")
end
-# prints:
-# dog is a mammal
-# cat is a mammal
-# mouse is a mammal
+# => mouse is a mammal
+# => cat is a mammal
+# => dog is a mammal
# While loops loop while a condition is true
-x = 0
-while x < 4
- println(x)
- x += 1 # Shorthand for x = x + 1
+let x = 0
+ while x < 4
+ println(x)
+ x += 1 # Shorthand for in place increment: x = x + 1
+ end
end
-# prints:
-# 0
-# 1
-# 2
-# 3
+# => 0
+# => 1
+# => 2
+# => 3
# Handle exceptions with a try/catch block
try
- error("help")
+ error("help")
catch e
- println("caught it $e")
+ println("caught it $e")
end
# => caught it ErrorException("help")
-
####################################################
## 4. Functions
####################################################
# The keyword 'function' creates new functions
-#function name(arglist)
-# body...
-#end
+# function name(arglist)
+# body...
+# end
function add(x, y)
println("x is $x and y is $y")
@@ -398,15 +442,17 @@ function add(x, y)
x + y
end
-add(5, 6) # => 11 after printing out "x is 5 and y is 6"
+add(5, 6)
+# => x is 5 and y is 6
+# => 11
# Compact assignment of functions
-f_add(x, y) = x + y # => "f (generic function with 1 method)"
-f_add(3, 4) # => 7
+f_add(x, y) = x + y # => f_add (generic function with 1 method)
+f_add(3, 4) # => 7
# Function can also return multiple values as tuple
-f(x, y) = x + y, x - y
-f(3, 4) # => (7, -1)
+fn(x, y) = x + y, x - y # => fn (generic function with 1 method)
+fn(3, 4) # => (7, -1)
# You can define functions that take a variable number of
# positional arguments
@@ -416,54 +462,56 @@ function varargs(args...)
end
# => varargs (generic function with 1 method)
-varargs(1,2,3) # => (1,2,3)
+varargs(1, 2, 3) # => (1,2,3)
# The ... is called a splat.
# We just used it in a function definition.
# It can also be used in a function call,
# where it will splat an Array or Tuple's contents into the argument list.
-add([5,6]...) # this is equivalent to add(5,6)
+add([5,6]...) # this is equivalent to add(5,6)
-x = (5,6) # => (5,6)
-add(x...) # this is equivalent to add(5,6)
+x = (5, 6) # => (5,6)
+add(x...) # this is equivalent to add(5,6)
# You can define functions with optional positional arguments
-function defaults(a,b,x=5,y=6)
+function defaults(a, b, x=5, y=6)
return "$a $b and $x $y"
end
+# => defaults (generic function with 3 methods)
-defaults('h','g') # => "h g and 5 6"
-defaults('h','g','j') # => "h g and j 6"
-defaults('h','g','j','k') # => "h g and j k"
+defaults('h', 'g') # => "h g and 5 6"
+defaults('h', 'g', 'j') # => "h g and j 6"
+defaults('h', 'g', 'j', 'k') # => "h g and j k"
try
- defaults('h') # => ERROR: no method defaults(Char,)
- defaults() # => ERROR: no methods defaults()
+ defaults('h') # => ERROR: MethodError: no method matching defaults(::Char)
+ defaults() # => ERROR: MethodError: no method matching defaults()
catch e
println(e)
end
# You can define functions that take keyword arguments
-function keyword_args(;k1=4,name2="hello") # note the ;
- return Dict("k1"=>k1,"name2"=>name2)
+function keyword_args(;k1=4, name2="hello") # note the ;
+ return Dict("k1" => k1, "name2" => name2)
end
+# => keyword_args (generic function with 1 method)
-keyword_args(name2="ness") # => ["name2"=>"ness","k1"=>4]
-keyword_args(k1="mine") # => ["k1"=>"mine","name2"=>"hello"]
-keyword_args() # => ["name2"=>"hello","k1"=>4]
+keyword_args(name2="ness") # => ["name2"=>"ness", "k1"=>4]
+keyword_args(k1="mine") # => ["name2"=>"hello", "k1"=>"mine"]
+keyword_args() # => ["name2"=>"hello", "k1"=>4]
# You can combine all kinds of arguments in the same function
-function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo")
- println("normal arg: $normal_arg")
- println("optional arg: $optional_positional_arg")
- println("keyword arg: $keyword_arg")
+function all_the_args(normalArg, optionalPositionalArg=2; keywordArg="foo")
+ println("normal arg: $normalArg")
+ println("optional arg: $optionalPositionalArg")
+ println("keyword arg: $keywordArg")
end
+# => all_the_args (generic function with 2 methods)
-all_the_args(1, 3, keyword_arg=4)
-# prints:
-# normal arg: 1
-# optional arg: 3
-# keyword arg: 4
+all_the_args(1, 3, keywordArg=4)
+# => normal arg: 1
+# => optional arg: 3
+# => keyword arg: 4
# Julia has first class functions
function create_adder(x)
@@ -472,14 +520,16 @@ function create_adder(x)
end
return adder
end
+# => create_adder (generic function with 1 method)
# This is "stabby lambda syntax" for creating anonymous functions
-(x -> x > 2)(3) # => true
+(x -> x > 2)(3) # => true
# This function is identical to create_adder implementation above.
function create_adder(x)
y -> x + y
end
+# => create_adder (generic function with 1 method)
# You can also name the internal function, if you want
function create_adder(x)
@@ -488,18 +538,21 @@ function create_adder(x)
end
adder
end
+# => create_adder (generic function with 1 method)
-add_10 = create_adder(10)
+add_10 = create_adder(10) # => (::getfield(Main, Symbol("#adder#11")){Int64})
+ # (generic function with 1 method)
add_10(3) # => 13
# There are built-in higher order functions
-map(add_10, [1,2,3]) # => [11, 12, 13]
-filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+map(add_10, [1,2,3]) # => [11, 12, 13]
+filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
-# We can use list comprehensions for nicer maps
-[add_10(i) for i=[1, 2, 3]] # => [11, 12, 13]
-[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+# We can use list comprehensions
+[add_10(i) for i = [1, 2, 3]] # => [11, 12, 13]
+[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
####################################################
## 5. Types
@@ -508,11 +561,11 @@ filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
# Julia has a type system.
# Every value has a type; variables do not have types themselves.
# You can use the `typeof` function to get the type of a value.
-typeof(5) # => Int64
+typeof(5) # => Int64
# Types are first-class values
-typeof(Int64) # => DataType
-typeof(DataType) # => DataType
+typeof(Int64) # => DataType
+typeof(DataType) # => DataType
# DataType is the type that represents types, including itself.
# Types are used for documentation, optimizations, and dispatch.
@@ -520,80 +573,76 @@ typeof(DataType) # => DataType
# Users can define types
# They are like records or structs in other languages.
-# New types are defined using the `type` keyword.
+# New types are defined using the `struct` keyword.
-# type Name
+# struct Name
# field::OptionalType
# ...
# end
-type Tiger
- taillength::Float64
- coatcolor # not including a type annotation is the same as `::Any`
+struct Tiger
+ taillength::Float64
+ coatcolor # not including a type annotation is the same as `::Any`
end
# The default constructor's arguments are the properties
# of the type, in the order they are listed in the definition
-tigger = Tiger(3.5,"orange") # => Tiger(3.5,"orange")
+tigger = Tiger(3.5, "orange") # => Tiger(3.5,"orange")
# The type doubles as the constructor function for values of that type
-sherekhan = typeof(tigger)(5.6,"fire") # => Tiger(5.6,"fire")
+sherekhan = typeof(tigger)(5.6, "fire") # => Tiger(5.6,"fire")
# These struct-style types are called concrete types
# They can be instantiated, but cannot have subtypes.
# The other kind of types is abstract types.
# abstract Name
-abstract Cat # just a name and point in the type hierarchy
+abstract type Cat end # just a name and point in the type hierarchy
# Abstract types cannot be instantiated, but can have subtypes.
# For example, Number is an abstract type
-subtypes(Number) # => 2-element Array{Any,1}:
- # Complex{T<:Real}
- # Real
-subtypes(Cat) # => 0-element Array{Any,1}
+subtypes(Number) # => 2-element Array{Any,1}:
+ # => Complex
+ # => Real
+subtypes(Cat) # => 0-element Array{Any,1}
# AbstractString, as the name implies, is also an abstract type
-subtypes(AbstractString) # 8-element Array{Any,1}:
- # Base.SubstitutionString{T<:AbstractString}
- # DirectIndexString
- # RepString
- # RevString{T<:AbstractString}
- # RopeString
- # SubString{T<:AbstractString}
- # UTF16String
- # UTF8String
-
-# Every type has a super type; use the `super` function to get it.
+subtypes(AbstractString) # => 4-element Array{Any,1}:
+ # => String
+ # => SubString
+ # => SubstitutionString
+ # => Test.GenericString
+
+# Every type has a super type; use the `supertype` function to get it.
typeof(5) # => Int64
-super(Int64) # => Signed
-super(Signed) # => Integer
-super(Integer) # => Real
-super(Real) # => Number
-super(Number) # => Any
-super(super(Signed)) # => Real
-super(Any) # => Any
+supertype(Int64) # => Signed
+supertype(Signed) # => Integer
+supertype(Integer) # => Real
+supertype(Real) # => Number
+supertype(Number) # => Any
+supertype(supertype(Signed)) # => Real
+supertype(Any) # => Any
# All of these type, except for Int64, are abstract.
-typeof("fire") # => ASCIIString
-super(ASCIIString) # => DirectIndexString
-super(DirectIndexString) # => AbstractString
-# Likewise here with ASCIIString
+typeof("fire") # => String
+supertype(String) # => AbstractString
+# Likewise here with String
+supertype(SubString) # => AbstractString
# <: is the subtyping operator
-type Lion <: Cat # Lion is a subtype of Cat
- mane_color
- roar::AbstractString
+struct Lion <: Cat # Lion is a subtype of Cat
+ maneColor
+ roar::AbstractString
end
# You can define more constructors for your type
# Just define a function of the same name as the type
# and call an existing constructor to get a value of the correct type
-Lion(roar::AbstractString) = Lion("green",roar)
+Lion(roar::AbstractString) = Lion("green", roar)
# This is an outer constructor because it's outside the type definition
-type Panther <: Cat # Panther is also a subtype of Cat
- eye_color
- Panther() = new("green")
- # Panthers will only have this constructor, and no default constructor.
+struct Panther <: Cat # Panther is also a subtype of Cat
+ eyeColor
+ Panther() = new("green")
+ # Panthers will only have this constructor, and no default constructor.
end
# Using inner constructors, like Panther does, gives you control
# over how values of the type can be created.
@@ -611,35 +660,36 @@ end
# Definitions for Lion, Panther, Tiger
function meow(animal::Lion)
- animal.roar # access type properties using dot notation
+ animal.roar # access type properties using dot notation
end
function meow(animal::Panther)
- "grrr"
+ "grrr"
end
function meow(animal::Tiger)
- "rawwwr"
+ "rawwwr"
end
# Testing the meow function
-meow(tigger) # => "rawwr"
-meow(Lion("brown","ROAAR")) # => "ROAAR"
+meow(tigger) # => "rawwwr"
+meow(Lion("brown", "ROAAR")) # => "ROAAR"
meow(Panther()) # => "grrr"
# Review the local type hierarchy
-issubtype(Tiger,Cat) # => false
-issubtype(Lion,Cat) # => true
-issubtype(Panther,Cat) # => true
+Tiger <: Cat # => false
+Lion <: Cat # => true
+Panther <: Cat # => true
# Defining a function that takes Cats
function pet_cat(cat::Cat)
- println("The cat says $(meow(cat))")
+ println("The cat says $(meow(cat))")
end
+# => pet_cat (generic function with 1 method)
-pet_cat(Lion("42")) # => prints "The cat says 42"
+pet_cat(Lion("42")) # => The cat says 42
try
- pet_cat(tigger) # => ERROR: no method pet_cat(Tiger,)
+ pet_cat(tigger) # => ERROR: MethodError: no method matching pet_cat(::Tiger)
catch e
println(e)
end
@@ -649,130 +699,179 @@ end
# In Julia, all of the argument types contribute to selecting the best method.
# Let's define a function with more arguments, so we can see the difference
-function fight(t::Tiger,c::Cat)
- println("The $(t.coatcolor) tiger wins!")
+function fight(t::Tiger, c::Cat)
+ println("The $(t.coatcolor) tiger wins!")
end
# => fight (generic function with 1 method)
-fight(tigger,Panther()) # => prints The orange tiger wins!
-fight(tigger,Lion("ROAR")) # => prints The orange tiger wins!
+fight(tigger, Panther()) # => The orange tiger wins!
+fight(tigger, Lion("ROAR")) # => The orange tiger wins!
# Let's change the behavior when the Cat is specifically a Lion
-fight(t::Tiger,l::Lion) = println("The $(l.mane_color)-maned lion wins!")
+fight(t::Tiger, l::Lion) = println("The $(l.maneColor)-maned lion wins!")
# => fight (generic function with 2 methods)
-fight(tigger,Panther()) # => prints The orange tiger wins!
-fight(tigger,Lion("ROAR")) # => prints The green-maned lion wins!
+fight(tigger, Panther()) # => The orange tiger wins!
+fight(tigger, Lion("ROAR")) # => The green-maned lion wins!
# We don't need a Tiger in order to fight
-fight(l::Lion,c::Cat) = println("The victorious cat says $(meow(c))")
+fight(l::Lion, c::Cat) = println("The victorious cat says $(meow(c))")
# => fight (generic function with 3 methods)
-fight(Lion("balooga!"),Panther()) # => prints The victorious cat says grrr
+fight(Lion("balooga!"), Panther()) # => The victorious cat says grrr
try
- fight(Panther(),Lion("RAWR")) # => ERROR: no method fight(Panther,Lion)
-catch
+ fight(Panther(), Lion("RAWR"))
+ # => ERROR: MethodError: no method matching fight(::Panther, ::Lion)
+ # => Closest candidates are:
+ # => fight(::Tiger, ::Lion) at ...
+ # => fight(::Tiger, ::Cat) at ...
+ # => fight(::Lion, ::Cat) at ...
+ # => ...
+catch e
+ println(e)
end
# Also let the cat go first
-fight(c::Cat,l::Lion) = println("The cat beats the Lion")
-# => Warning: New definition
-# fight(Cat,Lion) at none:1
-# is ambiguous with
-# fight(Lion,Cat) at none:2.
-# Make sure
-# fight(Lion,Lion)
-# is defined first.
-#fight (generic function with 4 methods)
+fight(c::Cat, l::Lion) = println("The cat beats the Lion")
+# => fight (generic function with 4 methods)
# This warning is because it's unclear which fight will be called in:
-fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The victorious cat says rarrr
+try
+ fight(Lion("RAR"), Lion("brown", "rarrr"))
+ # => ERROR: MethodError: fight(::Lion, ::Lion) is ambiguous. Candidates:
+ # => fight(c::Cat, l::Lion) in Main at ...
+ # => fight(l::Lion, c::Cat) in Main at ...
+ # => Possible fix, define
+ # => fight(::Lion, ::Lion)
+ # => ...
+catch e
+ println(e)
+end
# The result may be different in other versions of Julia
-fight(l::Lion,l2::Lion) = println("The lions come to a tie")
-fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The lions come to a tie
+fight(l::Lion, l2::Lion) = println("The lions come to a tie")
+# => fight (generic function with 5 methods)
+fight(Lion("RAR"), Lion("brown", "rarrr")) # => The lions come to a tie
# Under the hood
# You can take a look at the llvm and the assembly code generated.
-square_area(l) = l * l # square_area (generic function with 1 method)
+square_area(l) = l * l # square_area (generic function with 1 method)
-square_area(5) #25
+square_area(5) # => 25
# What happens when we feed square_area an integer?
-code_native(square_area, (Int32,))
- # .section __TEXT,__text,regular,pure_instructions
- # Filename: none
- # Source line: 1 # Prologue
- # push RBP
- # mov RBP, RSP
- # Source line: 1
- # movsxd RAX, EDI # Fetch l from memory?
- # imul RAX, RAX # Square l and store the result in RAX
- # pop RBP # Restore old base pointer
- # ret # Result will still be in RAX
-
-code_native(square_area, (Float32,))
- # .section __TEXT,__text,regular,pure_instructions
- # Filename: none
- # Source line: 1
- # push RBP
- # mov RBP, RSP
- # Source line: 1
- # vmulss XMM0, XMM0, XMM0 # Scalar single precision multiply (AVX)
- # pop RBP
- # ret
-
-code_native(square_area, (Float64,))
- # .section __TEXT,__text,regular,pure_instructions
- # Filename: none
- # Source line: 1
- # push RBP
- # mov RBP, RSP
- # Source line: 1
- # vmulsd XMM0, XMM0, XMM0 # Scalar double precision multiply (AVX)
- # pop RBP
- # ret
- #
+code_native(square_area, (Int32,), syntax = :intel)
+ # .text
+ # ; Function square_area {
+ # ; Location: REPL[116]:1 # Prologue
+ # push rbp
+ # mov rbp, rsp
+ # ; Function *; {
+ # ; Location: int.jl:54
+ # imul ecx, ecx # Square l and store the result in ECX
+ # ;}
+ # mov eax, ecx
+ # pop rbp # Restore old base pointer
+ # ret # Result will still be in EAX
+ # nop dword ptr [rax + rax]
+ # ;}
+
+code_native(square_area, (Float32,), syntax = :intel)
+ # .text
+ # ; Function square_area {
+ # ; Location: REPL[116]:1
+ # push rbp
+ # mov rbp, rsp
+ # ; Function *; {
+ # ; Location: float.jl:398
+ # vmulss xmm0, xmm0, xmm0 # Scalar single precision multiply (AVX)
+ # ;}
+ # pop rbp
+ # ret
+ # nop word ptr [rax + rax]
+ # ;}
+
+code_native(square_area, (Float64,), syntax = :intel)
+ # .text
+ # ; Function square_area {
+ # ; Location: REPL[116]:1
+ # push rbp
+ # mov rbp, rsp
+ # ; Function *; {
+ # ; Location: float.jl:399
+ # vmulsd xmm0, xmm0, xmm0 # Scalar double precision multiply (AVX)
+ # ;}
+ # pop rbp
+ # ret
+ # nop word ptr [rax + rax]
+ # ;}
+
# Note that julia will use floating point instructions if any of the
# arguments are floats.
# Let's calculate the area of a circle
circle_area(r) = pi * r * r # circle_area (generic function with 1 method)
-circle_area(5) # 78.53981633974483
-
-code_native(circle_area, (Int32,))
- # .section __TEXT,__text,regular,pure_instructions
- # Filename: none
- # Source line: 1
- # push RBP
- # mov RBP, RSP
- # Source line: 1
- # vcvtsi2sd XMM0, XMM0, EDI # Load integer (r) from memory
- # movabs RAX, 4593140240 # Load pi
- # vmulsd XMM1, XMM0, QWORD PTR [RAX] # pi * r
- # vmulsd XMM0, XMM0, XMM1 # (pi * r) * r
- # pop RBP
- # ret
- #
-
-code_native(circle_area, (Float64,))
- # .section __TEXT,__text,regular,pure_instructions
- # Filename: none
- # Source line: 1
- # push RBP
- # mov RBP, RSP
- # movabs RAX, 4593140496
- # Source line: 1
- # vmulsd XMM1, XMM0, QWORD PTR [RAX]
- # vmulsd XMM0, XMM1, XMM0
- # pop RBP
- # ret
- #
+circle_area(5) # 78.53981633974483
+
+code_native(circle_area, (Int32,), syntax = :intel)
+ # .text
+ # ; Function circle_area {
+ # ; Location: REPL[121]:1
+ # push rbp
+ # mov rbp, rsp
+ # ; Function *; {
+ # ; Location: operators.jl:502
+ # ; Function *; {
+ # ; Location: promotion.jl:314
+ # ; Function promote; {
+ # ; Location: promotion.jl:284
+ # ; Function _promote; {
+ # ; Location: promotion.jl:261
+ # ; Function convert; {
+ # ; Location: number.jl:7
+ # ; Function Type; {
+ # ; Location: float.jl:60
+ # vcvtsi2sd xmm0, xmm0, ecx # Load integer (r) from memory
+ # movabs rax, 497710928 # Load pi
+ # ;}}}}}
+ # ; Function *; {
+ # ; Location: float.jl:399
+ # vmulsd xmm1, xmm0, qword ptr [rax] # pi * r
+ # vmulsd xmm0, xmm1, xmm0 # (pi * r) * r
+ # ;}}
+ # pop rbp
+ # ret
+ # nop dword ptr [rax]
+ # ;}
+
+code_native(circle_area, (Float64,), syntax = :intel)
+ # .text
+ # ; Function circle_area {
+ # ; Location: REPL[121]:1
+ # push rbp
+ # mov rbp, rsp
+ # movabs rax, 497711048
+ # ; Function *; {
+ # ; Location: operators.jl:502
+ # ; Function *; {
+ # ; Location: promotion.jl:314
+ # ; Function *; {
+ # ; Location: float.jl:399
+ # vmulsd xmm1, xmm0, qword ptr [rax]
+ # ;}}}
+ # ; Function *; {
+ # ; Location: float.jl:399
+ # vmulsd xmm0, xmm1, xmm0
+ # ;}
+ # pop rbp
+ # ret
+ # nop dword ptr [rax + rax]
+ # ;}
```
## 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 Documentation](https://docs.julialang.org/)
-The best place to get help with Julia is the (very friendly) [mailing list](https://groups.google.com/forum/#!forum/julia-users).
+The best place to get help with Julia is the (very friendly) [Discourse forum](https://discourse.julialang.org/).
diff --git a/kdb+.html.markdown b/kdb+.html.markdown
index 772c8a47..680c01c1 100644
--- a/kdb+.html.markdown
+++ b/kdb+.html.markdown
@@ -2,11 +2,11 @@
language: kdb+
contributors:
- ["Matt Doherty", "https://github.com/picodoc"]
- - ["Jonny Press", "jonny.press@aquaq.co.uk"]
+ - ["Jonny Press", "https://github.com/jonnypress"]
filename: learnkdb.q
---
-The q langauge and its database component kdb+ were developed by Arthur Whitney
+The q language and its database component kdb+ were developed by Arthur Whitney
and released by Kx systems in 2003. q is a descendant of APL and as such is
very terse and a little strange looking for anyone from a "C heritage" language
background. Its expressiveness and vector oriented nature make it well suited
@@ -26,6 +26,8 @@ separable so this distinction is not really useful.
All Feedback welcome! You can reach me at matt.doherty@aquaq.co.uk, or Jonny
at jonny.press@aquaq.co.uk
+To learn more about kdb+ you can join the [Personal kdb+](https://groups.google.com/forum/#!forum/personal-kdbplus) or [TorQ kdb+](https://groups.google.com/forum/#!forum/kdbtorq) group.
+
```
/ Single line comments start with a forward-slash
/ These can also be used in-line, so long as at least one whitespace character
@@ -74,7 +76,7 @@ floor 3.14159 / => 3
/ ...getting the absolute value...
abs -3.14159 / => 3.14159
/ ...and many other things
-/ see http://code.kx.com/wiki/Reference for more
+/ see http://code.kx.com/q/ref/card/ for more
/ q has no operator precedence, everything is evaluated right to left
/ so results like this might take some getting used to
@@ -172,7 +174,7 @@ t - 00:10:00.000 / => 00:50:00.000
d.year / => 2015i
d.mm / => 12i
d.dd / => 25i
-/ see http://code.kx.com/wiki/JB:QforMortals2/atoms#Temporal_Data for more
+/ see http://code.kx.com/q4m3/2_Basic_Data_Types_Atoms/#25-temporal-data for more
/ q also has an infinity value so div by zero will not throw an error
1%0 / => 0w
@@ -181,7 +183,7 @@ d.dd / => 25i
/ And null types for representing missing values
0N / => null int
0n / => null float
-/ see http://code.kx.com/wiki/JB:QforMortals2/atoms#Null_Values for more
+/ see http://code.kx.com/q4m3/2_Basic_Data_Types_Atoms/#27-nulls for more
/ q has standard control structures
/ if is as you might expect (; separates the condition and instructions)
@@ -299,7 +301,7 @@ l:1+til 9 / til is a useful shortcut for generating ranges
-5#l / => 5 6 7 8 9
/ drop the last 5
-5_l / => 1 2 3 4
-/ find the first occurance of 4
+/ find the first occurrence of 4
l?4 / => 3
l[3] / => 4
@@ -314,7 +316,7 @@ key d / => `a`b`c
/ and value the second
value d / => 1 2 3
-/ Indexing is indentical to lists
+/ Indexing is identical to lists
/ with the first list as a key instead of the position
d[`a] / => 1
d[`b] / => 2
@@ -404,7 +406,7 @@ k!t
/ We can also use this shortcut for defining keyed tables
kt:([id:1 2 3]c1:1 2 3;c2:4 5 6;c3:7 8 9)
-/ Records can then be retreived based on this key
+/ Records can then be retrieved based on this key
kt[1]
/ => c1| 1
/ => c2| 4
@@ -426,7 +428,7 @@ kt[`id!1]
f:{x+x}
f[2] / => 4
-/ Functions can be annonymous and called at point of definition
+/ Functions can be anonymous and called at point of definition
{x+x}[2] / => 4
/ By default the last expression is returned
@@ -438,7 +440,7 @@ f[2] / => 4
/ Function arguments can be specified explicitly (separated by ;)
{[arg1;arg2] arg1+arg2}[1;2] / => 3
-/ or if ommited will default to x, y and z
+/ or if omitted will default to x, y and z
{x+y+z}[1;2;3] / => 6
/ Built in functions are no different, and can be called the same way (with [])
@@ -470,7 +472,7 @@ a / => 1
/ Functions cannot see nested scopes (only local and global)
{local:1;{:local}[]}[] / throws error as local is not defined in inner function
-/ A function can have one or more of it's arguments fixed (projection)
+/ A function can have one or more of its arguments fixed (projection)
f:+[4]
f[4] / => 8
f[5] / => 9
@@ -481,7 +483,7 @@ f[6] / => 10
////////// q-sql //////////
////////////////////////////////////
-/ q has it's own syntax for manipulating tables, similar to standard SQL
+/ q has its own syntax for manipulating tables, similar to standard SQL
/ This contains the usual suspects of select, insert, update etc.
/ and some new functionality not typically available
/ q-sql has two significant differences (other than syntax) to normal SQL:
@@ -640,7 +642,7 @@ kt upsert ([]name:`Thomas`Chester;age:33 58;height:175 179;sex:`f`m)
/ => Thomas 32 175 m
/ Most of the standard SQL joins are present in q-sql, plus a few new friends
-/ see http://code.kx.com/wiki/JB:QforMortals2/queries_q_sql#Joins
+/ see http://code.kx.com/q4m3/9_Queries_q-sql/#99-joins
/ the two most important (commonly used) are lj and aj
/ lj is basically the same as SQL LEFT JOIN
@@ -667,7 +669,7 @@ aj[`time`sym;trades;quotes]
/ => 10:01:04 ge 150
/ for each row in the trade table, the last (prevailing) quote (px) for that sym
/ is joined on.
-/ see http://code.kx.com/wiki/JB:QforMortals2/queries_q_sql#Asof_Join
+/ see http://code.kx.com/q4m3/9_Queries_q-sql/#998-as-of-joins
////////////////////////////////////
///// Extra/Advanced //////
@@ -680,21 +682,21 @@ aj[`time`sym;trades;quotes]
/ where possible functionality should be vectorized (i.e. operations on lists)
/ adverbs supplement this, modifying the behaviour of functions
/ and providing loop type functionality when required
-/ (in q functions are sometimes refered to as verbs, hence adverbs)
+/ (in q functions are sometimes referred to as verbs, hence adverbs)
/ the "each" adverb modifies a function to treat a list as individual variables
first each (1 2 3;4 5 6;7 8 9)
/ => 1 4 7
/ each-left (\:) and each-right (/:) modify a two-argument function
/ to treat one of the arguments and individual variables instead of a list
-1 2 3 +\: 1 2 3
-/ => 2 3 4
-/ => 3 4 5
-/ => 4 5 6
-1 2 3 +/: 1 2 3
-/ => 2 3 4
-/ => 3 4 5
-/ => 4 5 6
+1 2 3 +\: 11 22 33
+/ => 12 23 34
+/ => 13 24 35
+/ => 14 25 36
+1 2 3 +/: 11 22 33
+/ => 12 13 14
+/ => 23 24 25
+/ => 34 35 36
/ The true alternatives to loops in q are the adverbs scan (\) and over (/)
/ their behaviour differs based on the number of arguments the function they
@@ -714,7 +716,7 @@ first each (1 2 3;4 5 6;7 8 9)
{x + y}/[1 2 3 4 5] / => 15 (only the final result)
/ There are other adverbs and uses, this is only intended as quick overview
-/ http://code.kx.com/wiki/JB:QforMortals2/functions#Adverbs
+/ http://code.kx.com/q4m3/6_Functions/#67-adverbs
////// Scripts //////
/ q scripts can be loaded from a q session using the "\l" command
@@ -754,21 +756,21 @@ select from splayed / (the columns are read from disk on request)
/ => 1 1
/ => 2 2
/ => 3 3
-/ see http://code.kx.com/wiki/JB:KdbplusForMortals/contents for more
+/ see http://code.kx.com/q4m3/14_Introduction_to_Kdb+/ for more
////// Frameworks //////
/ kdb+ is typically used for data capture and analysis.
/ This involves using an architecture with multiple processes
/ working together. kdb+ frameworks are available to streamline the setup
-/ and configuration of this architecuture and add additional functionality
+/ and configuration of this architecture and add additional functionality
/ such as disaster recovery, logging, access, load balancing etc.
/ https://github.com/AquaQAnalytics/TorQ
```
## Want to know more?
-* [*q for mortals* q language tutorial](http://code.kx.com/wiki/JB:QforMortals2/contents)
-* [*kdb for mortals* on disk data tutorial](http://code.kx.com/wiki/JB:KdbplusForMortals/contents)
-* [q language reference](http://code.kx.com/wiki/Reference)
+* [*q for mortals* q language tutorial](http://code.kx.com/q4m3/)
+* [*Introduction to Kdb+* on disk data tutorial](http://code.kx.com/q4m3/14_Introduction_to_Kdb+/)
+* [q language reference](https://code.kx.com/q/ref/)
* [Online training courses](http://training.aquaq.co.uk/)
* [TorQ production framework](https://github.com/AquaQAnalytics/TorQ)
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/bf-kr.html.markdown b/ko-kr/bf-kr.html.markdown
index 3d366d7c..5849d2fd 100644
--- a/ko-kr/bf-kr.html.markdown
+++ b/ko-kr/bf-kr.html.markdown
@@ -1,5 +1,6 @@
---
language: bf
+filename: learnbf-kr.bf
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
diff --git a/ko-kr/javascript-kr.html.markdown b/ko-kr/javascript-kr.html.markdown
index 9561e80c..619d8104 100644
--- a/ko-kr/javascript-kr.html.markdown
+++ b/ko-kr/javascript-kr.html.markdown
@@ -2,7 +2,7 @@
language: javascript
category: language
contributors:
- - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Leigh Brenecki", "https://leigh.net.au"]
translators:
- ["wikibook", "http://wikibook.co.kr"]
filename: javascript-kr.js
@@ -18,8 +18,8 @@ lang: ko-kr
그렇지만 자바스크립트는 웹 브라우저에만 국한되지 않습니다. 구글 크롬의 V8 자바스크립트
엔진을 위한 독립형 런타임을 제공하는 Node.js는 점점 인기를 얻고 있습니다.
-피드백 주시면 대단히 감사하겠습니다! [@adambrenecki](https://twitter.com/adambrenecki)나
-[adam@brenecki.id.au](mailto:adam@brenecki.id.au)를 통해 저와 만나실 수 있습니다.
+피드백 주시면 대단히 감사하겠습니다! [@ExcitedLeigh](https://twitter.com/ExcitedLeigh)나
+[l@leigh.net.au](mailto:l@leigh.net.au)를 통해 저와 만나실 수 있습니다.
```js
// 주석은 C와 비슷합니다. 한 줄짜리 주석은 두 개의 슬래시로 시작하고,
diff --git a/ko-kr/kotlin-kr.html.markdown b/ko-kr/kotlin-kr.html.markdown
new file mode 100644
index 00000000..2df4195d
--- /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 fooMutableData = MutableDataClassExample(7, 4, 9)
+ with (fooMutableData) {
+ x -= 2
+ y += 2
+ z--
+ }
+ println(fooMutableData) // => 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/markdown-kr.html.markdown b/ko-kr/markdown-kr.html.markdown
index bfa2a877..397e9f30 100644
--- a/ko-kr/markdown-kr.html.markdown
+++ b/ko-kr/markdown-kr.html.markdown
@@ -25,7 +25,7 @@ lang: ko-kr
## HTML 요소
HTML은 마크다운의 수퍼셋입니다. 모든 HTML 파일은 유효한 마크다운이라는 것입니다.
-```markdown
+```md
<!--따라서 주석과 같은 HTML 요소들을 마크다운에 사용할 수 있으며, 마크다운 파서에 영향을
받지 않을 것입니다. 하지만 마크다운 파일에서 HTML 요소를 만든다면 그 요소의 안에서는
마크다운 문법을 사용할 수 없습니다.-->
@@ -34,7 +34,7 @@ HTML은 마크다운의 수퍼셋입니다. 모든 HTML 파일은 유효한 마
텍스트 앞에 붙이는 우물 정 기호(#)의 갯수에 따라 `<h1>`부터 `<h6>`까지의 HTML 요소를
손쉽게 작성할 수 있습니다.
-```markdown
+```md
# <h1>입니다.
## <h2>입니다.
### <h3>입니다.
@@ -43,7 +43,7 @@ HTML은 마크다운의 수퍼셋입니다. 모든 HTML 파일은 유효한 마
###### <h6>입니다.
```
또한 h1과 h2를 나타내는 다른 방법이 있습니다.
-```markdown
+```md
h1입니다.
=============
@@ -53,7 +53,7 @@ h2입니다.
## 간단한 텍스트 꾸미기
마크다운으로 쉽게 텍스트를 기울이거나 굵게 할 수 있습니다.
-```markdown
+```md
*기울인 텍스트입니다.*
_이 텍스트도 같습니다._
@@ -65,14 +65,14 @@ __이 텍스트도 같습니다.__
*__이것도 같습니다.__*
```
깃헙 전용 마크다운에는 취소선도 있습니다.
-```markdown
+```md
~~이 텍스트에는 취소선이 그려집니다.~~
```
## 문단
문단은 하나 이상의 빈 줄로 구분되는, 한 줄 이상의 인접한 텍스트입니다.
-```markdown
+```md
문단입니다. 문단에 글을 쓰다니 재밌지 않나요?
이제 두 번째 문단입니다.
@@ -83,7 +83,7 @@ __이 텍스트도 같습니다.__
HTML `<br />` 태그를 삽입하고 싶으시다면, 두 개 이상의 띄어쓰기로 문단을 끝내고
새 문단을 시작할 수 있습니다.
-```markdown
+```md
띄어쓰기 두 개로 끝나는 문단 (마우스로 긁어 보세요).
이 위에는 `<br />` 태그가 있습니다.
@@ -91,7 +91,7 @@ HTML `<br />` 태그를 삽입하고 싶으시다면, 두 개 이상의 띄어
인용문은 > 문자로 쉽게 쓸 수 있습니다.
-```markdown
+```md
> 인용문입니다. 수동으로 개행하고서
> 줄마다 `>`를 칠 수도 있고 줄을 길게 쓴 다음에 저절로 개행되게 내버려 둘 수도 있습니다.
> `>`로 시작하기만 한다면 차이가 없습니다.
@@ -103,7 +103,7 @@ HTML `<br />` 태그를 삽입하고 싶으시다면, 두 개 이상의 띄어
## 목록
순서가 없는 목록은 별표, 더하기, 하이픈을 이용해 만들 수 있습니다.
-```markdown
+```md
* 이거
* 저거
* 그거
@@ -111,7 +111,7 @@ HTML `<br />` 태그를 삽입하고 싶으시다면, 두 개 이상의 띄어
또는
-```markdown
+```md
+ 이거
+ 저거
+ 그거
@@ -119,7 +119,7 @@ HTML `<br />` 태그를 삽입하고 싶으시다면, 두 개 이상의 띄어
또는
-```markdown
+```md
- 이거
- 저거
- 그거
@@ -127,7 +127,7 @@ HTML `<br />` 태그를 삽입하고 싶으시다면, 두 개 이상의 띄어
순서가 있는 목록은 숫자와 마침표입니다.
-```markdown
+```md
1. 하나
2. 둘
3. 셋
@@ -135,7 +135,7 @@ HTML `<br />` 태그를 삽입하고 싶으시다면, 두 개 이상의 띄어
숫자를 정확히 붙이지 않더라도 제대로 된 순서로 보여주겠지만, 좋은 생각은 아닙니다.
-```markdown
+```md
1. 하나
1. 둘
1. 셋
@@ -144,7 +144,7 @@ HTML `<br />` 태그를 삽입하고 싶으시다면, 두 개 이상의 띄어
목록 안에 목록이 올 수도 있습니다.
-```markdown
+```md
1. 하나
2. 둘
3. 셋
@@ -155,7 +155,7 @@ HTML `<br />` 태그를 삽입하고 싶으시다면, 두 개 이상의 띄어
심지어 할 일 목록도 있습니다. HTML 체크박스가 만들어집니다.
-```markdown
+```md
x가 없는 박스들은 체크되지 않은 HTML 체크박스입니다.
- [ ] 첫 번째 할 일
- [ ] 두 번째 할 일
@@ -168,13 +168,13 @@ x가 없는 박스들은 체크되지 않은 HTML 체크박스입니다.
띄어쓰기 네 개 혹은 탭 한 개로 줄을 들여씀으로서 (`<code> 요소를 사용하여`) 코드를
나타낼 수 있습니다.
-```markdown
+```md
puts "Hello, world!"
```
탭을 더 치거나 띄어쓰기를 네 번 더 함으로써 코드를 들여쓸 수 있습니다.
-```markdown
+```md
my_array.each do |item|
puts item
end
@@ -182,7 +182,7 @@ x가 없는 박스들은 체크되지 않은 HTML 체크박스입니다.
인라인 코드는 백틱 문자를 이용하여 나타냅니다. `
-```markdown
+```md
철수는 `go_to()` 함수가 뭘 했는지도 몰랐어!
```
@@ -202,7 +202,7 @@ end
수평선(`<hr/>`)은 셋 이상의 별표나 하이픈을 이용해 쉽게 나타낼 수 있습니다.
띄어쓰기가 포함될 수 있습니다.
-```markdown
+```md
***
---
- - -
@@ -213,19 +213,19 @@ end
마크다운의 장점 중 하나는 링크를 만들기 쉽다는 것입니다. 대괄호 안에 나타낼 텍스트를 쓰고
괄호 안에 URL을 쓰면 됩니다.
-```markdown
+```md
[클릭](http://test.com/)
```
괄호 안에 따옴표를 이용해 링크에 제목을 달 수도 있습니다.
-```markdown
+```md
[클릭](http://test.com/ "test.com으로 가기")
```
상대 경로도 유효합니다.
-```markdown
+```md
[music으로 가기](/music/).
```
@@ -251,7 +251,7 @@ end
## 이미지
이미지는 링크와 같지만 앞에 느낌표가 붙습니다.
-```markdown
+```md
![이미지의 alt 속성](http://imgur.com/myimage.jpg "제목")
```
@@ -264,18 +264,18 @@ end
## 기타
### 자동 링크
-```markdown
+```md
<http://testwebsite.com/>와
[http://testwebsite.com/](http://testwebsite.com/)는 동일합니다.
```
### 이메일 자동 링크
-```markdown
+```md
<foo@bar.com>
```
### 탈출 문자
-```markdown
+```md
*별표 사이에 이 텍스트*를 치고 싶지만 기울이고 싶지는 않다면
이렇게 하시면 됩니다. \*별표 사이에 이 텍스트\*.
```
@@ -284,7 +284,7 @@ end
깃헙 전용 마크다운에서는 `<kbd>` 태그를 이용해 키보드 키를 나타낼 수 있습니다.
-```markdown
+```md
컴퓨터가 멈췄다면 눌러보세요.
<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd>
```
@@ -292,14 +292,14 @@ end
### 표
표는 깃헙 전용 마크다운에서만 쓸 수 있고 다소 복잡하지만, 정말 쓰고 싶으시다면
-```markdown
+```md
| 1열 | 2열 | 3열 |
| :--------| :-------: | --------: |
| 왼쪽 정렬 | 가운데 정렬 | 오른쪽 정렬 |
| 머시기 | 머시기 | 머시기 |
```
혹은
-```markdown
+```md
1열 | 2열 | 3열
:-- | :-: | --:
으악 너무 못생겼어 | 그만 | 둬
diff --git a/ko-kr/python-kr.html.markdown b/ko-kr/pythonlegacy-kr.html.markdown
index ed377a99..978a9f33 100644
--- a/ko-kr/python-kr.html.markdown
+++ b/ko-kr/pythonlegacy-kr.html.markdown
@@ -1,9 +1,9 @@
---
-language: python
+language: Python 2 (legacy)
category: language
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
-filename: learnpython-ko.py
+filename: learnpythonlegacy-ko.py
translators:
- ["wikibook", "http://wikibook.co.kr"]
lang: ko-kr
@@ -441,7 +441,7 @@ Human.grunt() #=> "*grunt*"
# 다음과 같이 모듈을 임포트할 수 있습니다.
import math
-print math.sqrt(16) #=> 4
+print math.sqrt(16) #=> 4.0
# 모듈의 특정 함수를 호출할 수 있습니다.
from math import ceil, floor
diff --git a/ko-kr/vim-kr.html.markdown b/ko-kr/vim-kr.html.markdown
new file mode 100644
index 00000000..76063143
--- /dev/null
+++ b/ko-kr/vim-kr.html.markdown
@@ -0,0 +1,269 @@
+---
+category: tool
+tool: vim
+contributors:
+ - ["RadhikaG", "https://github.com/RadhikaG"]
+translators:
+ - ["Wooseop Kim", "https://github.com/linterpreteur"]
+ - ["Yeongjae Jang", "https://github.com/Liberatedwinner"]
+filename: LearnVim-kr.txt
+lang: ko-kr
+---
+
+[Vim](http://www.vim.org)
+(Vi IMproved)은 유닉스에서 인기 있는 vi 에디터의 클론입니다. Vim은 속도와 생산성을 위해
+설계된 텍스트 에디터로, 대부분의 유닉스 기반 시스템에 내장되어 있습니다. 다양한 단축 키를 통해
+파일 안에서 빠르게 이동하고 편집할 수 있습니다.
+
+## Vim 조작의 기본
+
+```
+ vim <filename> # vim으로 <filename> 열기
+ :help <topic> # (존재하는 경우에) <topic>에 대한, 내장된 도움말 문서 열기
+ :q # vim 종료
+ :w # 현재 파일 저장
+ :wq # 파일 저장 후 종료
+ ZZ # 파일 저장 후 종료
+ :q! # 저장하지 않고 종료
+ # ! *강제로* :q를 실행하여, 저장 없이 종료
+ :x # 파일 저장 후 종료 (:wq의 축약)
+
+ u # 동작 취소
+ CTRL+R # 되돌리기
+
+ h # 한 글자 왼쪽으로 이동
+ j # 한 줄 아래로 이동
+ k # 한 줄 위로 이동
+ l # 한 글자 오른쪽으로 이동
+
+ # 줄 안에서의 이동
+
+ 0 # 줄 시작으로 이동
+ $ # 줄 끝으로 이동
+ ^ # 줄의 공백이 아닌 첫 문자로 이동
+
+ Ctrl+B # 한 화면 뒤로 이동
+ Ctrl+F # 한 화면 앞으로 이동
+ Ctrl+D # 반 화면 앞으로 이동
+ Ctrl+U # 반 화면 뒤로 이동
+
+ # 텍스트 검색
+
+ /word # 커서 뒤에 나타나는 해당 단어를 모두 하이라이트
+ ?word # 커서 앞에 나타나는 해당 단어를 모두 하이라이트
+ n # 해당 단어를 검색 후 다음으로 나타나는 위치로 이동
+ N # 이전에 나타나는 위치로 이동
+
+ :%s/foo/bar/g # 파일 모든 줄에 있는 'foo'를 'bar'로 치환
+ :s/foo/bar/g # 현재 줄에 있는 'foo'를 'bar'로 치환
+ :%s/foo/bar/gc # 사용자에게 확인을 요구하는, 모든 줄에 있는 'foo'를 'bar'로 치환
+ :%s/\n/\r/g # 한 종류의 개행 문자에서 다른 종류의 것으로 치환 (\n에서 \r로)
+
+ # 문자로 이동
+
+ f<character> # <character>로 건너뛰기
+ t<character> # <character>의 바로 뒤로 건너뛰기
+
+ # 예를 들어,
+ f< # <로 건너뛰기
+ t< # <의 바로 뒤로 건너뛰기
+
+ # 단어 단위로 이동
+
+ w # 한 단어 오른쪽으로 이동
+ b # 한 단어 왼쪽으로 이동
+ e # 현재 단어의 끝으로 이동
+
+ # 기타 이동 명령어
+
+ gg # 파일 맨 위로 이동
+ G # 파일 맨 아래로 이동
+ :NUM # 줄 수 NUM(숫자)로 가기
+ H # 화면 꼭대기로 이동
+ M # 화면 중간으로 이동
+ L # 화면 바닥으로 이동
+```
+
+## 도움말 문서
+
+Vim은 `:help <topic>` 명령을 통해 접근할 수 있는 도움말 문서를 내장하고 있습니다.
+예를 들어, `:help navigation` 은 당신의 작업 공간을 탐색하는 방법에 대한 문서를 표시합니다!
+
+`:help`는 옵션 없이도 사용할 수 있습니다. 이는 기본 도움말 대화 상자를 표시합니다.
+이 대화 상자는 Vim을 시작하는 것이 보다 용이하도록 도와줍니다.
+
+## 모드
+
+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 % # 현재 파일을 루트 권한으로 저장
+ :set syntax=c # 문법 강조를 'C'의 것으로 설정
+ :sort # 모든 줄을 정렬
+ :sort! # 모든 줄을 역순으로 정렬
+ :sort u # 모든 줄을 정렬하고, 중복되는 것을 삭제
+ ~ # 선택된 텍스트의 대/소문자 토글
+ u # 선택된 텍스트를 소문자로 바꾸기
+ U # 선택된 텍스트를 대문자로 바꾸기
+
+ # 텍스트 폴딩
+ zf # 선택된 텍스트 위치에서 폴딩 만들기
+ zo # 현재 폴딩 펴기
+ zc # 현재 폴딩 접기
+ zR # 모든 폴딩 펴기
+ zM # 모든 폴딩 접기
+ zi # 폴딩 접기/펴기 토글
+ zd # 접은 폴딩 삭제
+```
+
+## 매크로
+
+매크로는 기본적으로 녹화할 수 있는 동작을 말합니다.
+매크로를 녹화하기 시작하면, 끝날 때까지 **모든** 동작과 명령어가 녹화됩니다.
+매크로를 호출하면 선택한 텍스트에 대해 정확히 같은 순서의 동작과 명령어가 실행됩니다.
+
+```
+ 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/ko-kr/yaml-kr.html.markdown b/ko-kr/yaml-kr.html.markdown
index b6d1de41..4b1b29d2 100644
--- a/ko-kr/yaml-kr.html.markdown
+++ b/ko-kr/yaml-kr.html.markdown
@@ -2,7 +2,7 @@
language: yaml
filename: learnyaml-kr.yaml
contributors:
- - ["Adam Brenecki", "https://github.com/adambrenecki"]
+ - ["Leigh Brenecki", "https://github.com/adambrenecki"]
- ["Suhas SG", "https://github.com/jargnar"]
translators:
- ["Wooseop Kim", "https://github.com/linterpreteur"]
diff --git a/kotlin.html.markdown b/kotlin.html.markdown
index d1f1aae6..12008074 100644
--- a/kotlin.html.markdown
+++ b/kotlin.html.markdown
@@ -20,7 +20,9 @@ package com.learnxinyminutes.kotlin
/*
The entry point to a Kotlin program is a function named "main".
-The function is passed an array containing any command line arguments.
+The function is passed an array containing any command-line arguments.
+Since Kotlin 1.3 the "main" function can also be defined without
+any parameters.
*/
fun main(args: Array<String>) {
/*
@@ -36,7 +38,7 @@ fun main(args: Array<String>) {
so we don't have to explicitly specify it every time.
We can explicitly declare the type of a variable like so:
*/
- val foo : Int = 7
+ val foo: Int = 7
/*
Strings can be represented in a similar way as in Java.
@@ -65,7 +67,7 @@ fun helloWorld(val name : String) {
A template expression starts with a dollar sign ($).
*/
val fooTemplateString = "$fooString has ${fooString.length} characters"
- println(fooTemplateString)
+ println(fooTemplateString) // => My String Is Here! has 18 characters
/*
For a variable to hold null it must be explicitly specified as nullable.
@@ -107,7 +109,7 @@ fun helloWorld(val name : String) {
/*
When a function consists of a single expression then the curly brackets can
- be omitted. The body is specified after a = symbol.
+ be omitted. The body is specified after the = symbol.
*/
fun odd(x: Int): Boolean = x % 2 == 1
println(odd(6)) // => false
@@ -175,12 +177,12 @@ fun helloWorld(val name : String) {
// Objects can be destructured into multiple variables.
val (a, b, c) = fooCopy
println("$a $b $c") // => 1 100 4
-
+
// destructuring in "for" loop
for ((a, b, c) in listOf(fooData)) {
- println("$a $b $c") // => 1 100 4
+ println("$a $b $c") // => 1 2 4
}
-
+
val mapData = mapOf("a" to 1, "b" to 2)
// Map.Entry is destructurable as well
for ((key, value) in mapData) {
@@ -189,13 +191,13 @@ fun helloWorld(val name : String) {
// The "with" function is similar to the JavaScript "with" statement.
data class MutableDataClassExample (var x: Int, var y: Int, var z: Int)
- val fooMutableDate = MutableDataClassExample(7, 4, 9)
- with (fooMutableDate) {
+ val fooMutableData = MutableDataClassExample(7, 4, 9)
+ with (fooMutableData) {
x -= 2
y += 2
z--
}
- println(fooMutableDate) // => MutableDataClassExample(x=5, y=6, z=8)
+ println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8)
/*
We can create a list using the "listOf" function.
@@ -304,7 +306,7 @@ fun helloWorld(val name : String) {
println(result)
/*
- We can check if an object is a particular type by using the "is" operator.
+ We can check if an object is of a particular type by using the "is" operator.
If an object passes a type check then it can be used as that type without
explicitly casting it.
*/
@@ -344,15 +346,25 @@ fun helloWorld(val name : String) {
return this.filter {it != c}
}
println("Hello, world!".remove('l')) // => Heo, word!
-
- println(EnumExample.A) // => A
- println(ObjectExample.hello()) // => hello
}
// Enum classes are similar to Java enum types.
enum class EnumExample {
- A, B, C
+ A, B, C // Enum constants are separated with commas.
}
+fun printEnum() = println(EnumExample.A) // => A
+
+// Since each enum is an instance of the enum class, they can be initialized as:
+enum class EnumExample(val value: Int) {
+ A(value = 1),
+ B(value = 2),
+ C(value = 3)
+}
+fun printProperty() = println(EnumExample.A.value) // => 1
+
+// Every enum has properties to obtain its name and ordinal(position) in the enum class declaration:
+fun printName() = println(EnumExample.A.name) // => A
+fun printPosition() = println(EnumExample.A.ordinal) // => 0
/*
The "object" keyword can be used to create singleton objects.
@@ -363,17 +375,80 @@ object ObjectExample {
fun hello(): String {
return "hello"
}
+
+ override fun toString(): String {
+ return "Hello, it's me, ${ObjectExample::class.simpleName}"
+ }
}
-fun useObject() {
- ObjectExample.hello()
- val someRef: Any = ObjectExample // we use objects name just as is
+
+fun useSingletonObject() {
+ println(ObjectExample.hello()) // => hello
+ // In Kotlin, "Any" is the root of the class hierarchy, just like "Object" is in Java
+ val someRef: Any = ObjectExample
+ println(someRef) // => Hello, it's me, ObjectExample
}
+
+/* The not-null assertion operator (!!) converts any value to a non-null type and
+throws an exception if the value is null.
+*/
+var b: String? = "abc"
+val l = b!!.length
+
+data class Counter(var value: Int) {
+ // overload Counter += Int
+ operator fun plusAssign(increment: Int) {
+ this.value += increment
+ }
+
+ // overload Counter++ and ++Counter
+ operator fun inc() = Counter(value + 1)
+
+ // overload Counter + Counter
+ operator fun plus(other: Counter) = Counter(this.value + other.value)
+
+ // overload Counter * Counter
+ operator fun times(other: Counter) = Counter(this.value * other.value)
+
+ // overload Counter * Int
+ operator fun times(value: Int) = Counter(this.value * value)
+
+ // overload Counter in Counter
+ operator fun contains(other: Counter) = other.value == this.value
+
+ // overload Counter[Int] = Int
+ operator fun set(index: Int, value: Int) {
+ this.value = index + value
+ }
+
+ // overload Counter instance invocation
+ operator fun invoke() = println("The value of the counter is $value")
+
+}
+/* You can also overload operators through extension methods */
+// overload -Counter
+operator fun Counter.unaryMinus() = Counter(-this.value)
+
+fun operatorOverloadingDemo() {
+ var counter1 = Counter(0)
+ var counter2 = Counter(5)
+ counter1 += 7
+ println(counter1) // => Counter(value=7)
+ println(counter1 + counter2) // => Counter(value=12)
+ println(counter1 * counter2) // => Counter(value=35)
+ println(counter2 * 2) // => Counter(value=10)
+ println(counter1 in Counter(5)) // => false
+ println(counter1 in Counter(7)) // => true
+ counter1[26] = 10
+ println(counter1) // => Counter(value=36)
+ counter1() // => The value of the counter is 36
+ println(-counter2) // => Counter(value=-5)
+}
```
### Further Reading
* [Kotlin tutorials](https://kotlinlang.org/docs/tutorials/)
-* [Try Kotlin in your browser](http://try.kotlinlang.org/)
+* [Try Kotlin in your browser](https://play.kotlinlang.org/)
* [A list of Kotlin resources](http://kotlin.link/)
diff --git a/lambda-calculus.html.markdown b/lambda-calculus.html.markdown
new file mode 100644
index 00000000..53a7a7cd
--- /dev/null
+++ b/lambda-calculus.html.markdown
@@ -0,0 +1,219 @@
+---
+category: Algorithms & Data Structures
+name: Lambda Calculus
+contributors:
+ - ["Max Sun", "http://github.com/maxsun"]
+ - ["Yan Hui Hang", "http://github.com/yanhh0"]
+---
+
+# Lambda Calculus
+
+Lambda calculus (λ-calculus), originally created by
+[Alonzo Church](https://en.wikipedia.org/wiki/Alonzo_Church),
+is the world's smallest programming language.
+Despite not having numbers, strings, booleans, or any non-function datatype,
+lambda calculus can be used to represent any Turing Machine!
+
+Lambda calculus is composed of 3 elements: **variables**, **functions**, and
+**applications**.
+
+
+| Name | Syntax | Example | Explanation |
+|-------------|------------------------------------|-----------|-----------------------------------------------|
+| Variable | `<name>` | `x` | a variable named "x" |
+| Function | `λ<parameters>.<body>` | `λx.x` | a function with parameter "x" and body "x" |
+| Application | `<function><variable or function>` | `(λx.x)a` | calling the function "λx.x" with argument "a" |
+
+The most basic function is the identity function: `λx.x` which is equivalent to
+`f(x) = x`. The first "x" is the function's argument, and the second is the
+body of the function.
+
+## Free vs. Bound Variables:
+
+- In the function `λx.x`, "x" is called a bound variable because it is both in
+the body of the function and a parameter.
+- In `λx.y`, "y" is called a free variable because it is never declared before hand.
+
+## Evaluation:
+
+Evaluation is done via
+[β-Reduction](https://en.wikipedia.org/wiki/Lambda_calculus#Beta_reduction),
+which is essentially lexically-scoped substitution.
+
+When evaluating the
+expression `(λx.x)a`, we replace all occurences of "x" in the function's body
+with "a".
+
+- `(λx.x)a` evaluates to: `a`
+- `(λx.y)a` evaluates to: `y`
+
+You can even create higher-order functions:
+
+- `(λx.(λy.x))a` evaluates to: `λy.a`
+
+Although lambda calculus traditionally supports only single parameter
+functions, we can create multi-parameter functions using a technique called
+[currying](https://en.wikipedia.org/wiki/Currying).
+
+- `(λx.λy.λz.xyz)` is equivalent to `f(x, y, z) = ((x y) z)`
+
+Sometimes `λxy.<body>` is used interchangeably with: `λx.λy.<body>`
+
+----
+
+It's important to recognize that traditional **lambda calculus doesn't have
+numbers, characters, or any non-function datatype!**
+
+## Boolean Logic:
+
+There is no "True" or "False" in lambda calculus. There isn't even a 1 or 0.
+
+Instead:
+
+`T` is represented by: `λx.λy.x`
+
+`F` is represented by: `λx.λy.y`
+
+First, we can define an "if" function `λbtf` that
+returns `t` if `b` is True and `f` if `b` is False
+
+`IF` is equivalent to: `λb.λt.λf.b t f`
+
+Using `IF`, we can define the basic boolean logic operators:
+
+`a AND b` is equivalent to: `λab.IF a b F`
+
+`a OR b` is equivalent to: `λab.IF a T b`
+
+`NOT a` is equivalent to: `λa.IF a F T`
+
+*Note: `IF a b c` is essentially saying: `IF((a b) c)`*
+
+## Numbers:
+
+Although there are no numbers in lambda calculus, we can encode numbers using
+[Church numerals](https://en.wikipedia.org/wiki/Church_encoding).
+
+For any number n: <code>n = λf.f<sup>n</sup></code> so:
+
+`0 = λf.λx.x`
+
+`1 = λf.λx.f x`
+
+`2 = λf.λx.f(f x)`
+
+`3 = λf.λx.f(f(f x))`
+
+To increment a Church numeral,
+we use the successor function `S(n) = n + 1` which is:
+
+`S = λn.λf.λx.f((n f) x)`
+
+Using successor, we can define add:
+
+`ADD = λab.(a S)b`
+
+**Challenge:** try defining your own multiplication function!
+
+## Get even smaller: SKI, SK and Iota
+
+### SKI Combinator Calculus
+
+Let S, K, I be the following functions:
+
+`I x = x`
+
+`K x y = x`
+
+`S x y z = x z (y z)`
+
+We can convert an expression in the lambda calculus to an expression
+in the SKI combinator calculus:
+
+1. `λx.x = I`
+2. `λx.c = Kc`
+3. `λx.(y z) = S (λx.y) (λx.z)`
+
+Take the church number 2 for example:
+
+`2 = λf.λx.f(f x)`
+
+For the inner part `λx.f(f x)`:
+
+```
+ λx.f(f x)
+= S (λx.f) (λx.(f x)) (case 3)
+= S (K f) (S (λx.f) (λx.x)) (case 2, 3)
+= S (K f) (S (K f) I) (case 2, 1)
+```
+
+So:
+
+```
+ 2
+= λf.λx.f(f x)
+= λf.(S (K f) (S (K f) I))
+= λf.((S (K f)) (S (K f) I))
+= S (λf.(S (K f))) (λf.(S (K f) I)) (case 3)
+```
+
+For the first argument `λf.(S (K f))`:
+
+```
+ λf.(S (K f))
+= S (λf.S) (λf.(K f)) (case 3)
+= S (K S) (S (λf.K) (λf.f)) (case 2, 3)
+= S (K S) (S (K K) I) (case 2, 3)
+```
+
+For the second argument `λf.(S (K f) I)`:
+
+```
+ λf.(S (K f) I)
+= λf.((S (K f)) I)
+= S (λf.(S (K f))) (λf.I) (case 3)
+= S (S (λf.S) (λf.(K f))) (K I) (case 2, 3)
+= S (S (K S) (S (λf.K) (λf.f))) (K I) (case 1, 3)
+= S (S (K S) (S (K K) I)) (K I) (case 1, 2)
+```
+
+Merging them up:
+
+```
+ 2
+= S (λf.(S (K f))) (λf.(S (K f) I))
+= S (S (K S) (S (K K) I)) (S (S (K S) (S (K K) I)) (K I))
+```
+
+Expanding this, we would end up with the same expression for the
+church number 2 again.
+
+### SK Combinator Calculus
+
+The SKI combinator calculus can still be reduced further. We can
+remove the I combinator by noting that `I = SKK`. We can substitute
+all `I`'s with `SKK`.
+
+### Iota Combinator
+
+The SK combinator calculus is still not minimal. Defining:
+
+```
+ι = λf.((f S) K)
+```
+
+We have:
+
+```
+I = ιι
+K = ι(ιI) = ι(ι(ιι))
+S = ι(K) = ι(ι(ι(ιι)))
+```
+
+## For more advanced reading:
+
+1. [A Tutorial Introduction to the Lambda Calculus](http://www.inf.fu-berlin.de/lehre/WS03/alpi/lambda.pdf)
+2. [Cornell CS 312 Recitation 26: The Lambda Calculus](http://www.cs.cornell.edu/courses/cs3110/2008fa/recitations/rec26.html)
+3. [Wikipedia - Lambda Calculus](https://en.wikipedia.org/wiki/Lambda_calculus)
+4. [Wikipedia - SKI combinator calculus](https://en.wikipedia.org/wiki/SKI_combinator_calculus)
+5. [Wikipedia - Iota and Jot](https://en.wikipedia.org/wiki/Iota_and_Jot)
diff --git a/latex.html.markdown b/latex.html.markdown
index a3866892..29a9f638 100644
--- a/latex.html.markdown
+++ b/latex.html.markdown
@@ -2,10 +2,11 @@
language: latex
contributors:
- ["Chaitanya Krishna Ande", "http://icymist.github.io"]
- - ["Colton Kohnke", "http://github.com/voltnor"]
+ - ["Colton Kohnke", "https://github.com/voltnor"]
- ["Sricharan Chiruvolu", "http://sricharan.xyz"]
- ["Ramanan Balakrishnan", "https://github.com/ramananbalakrishnan"]
- ["Svetlana Golubeva", "https://attillax.github.io/"]
+ - ["Oliver Kopp", "http://orcid.org/0000-0001-6962-4290"]
filename: learn-latex.tex
---
@@ -26,8 +27,8 @@ filename: learn-latex.tex
% Next we define the packages the document uses.
% If you want to include graphics, colored text, or
-% source code from another language file into your document,
-% you need to enhance the capabilities of LaTeX. This is done by adding packages.
+% source code from another language file into your document,
+% you need to enhance the capabilities of LaTeX. This is done by adding packages.
% I'm going to include the float and caption packages for figures
% and hyperref package for hyperlinks
\usepackage{caption}
@@ -38,18 +39,18 @@ filename: learn-latex.tex
\author{Chaitanya Krishna Ande, Colton Kohnke, Sricharan Chiruvolu \& \\
Svetlana Golubeva}
\date{\today}
-\title{Learn \LaTeX \hspace{1pt} in Y Minutes!}
+\title{Learn \LaTeX{} in Y Minutes!}
% Now we're ready to begin the document
% Everything before this line is called "The Preamble"
-\begin{document}
-% if we set the author, date, title fields, we can have LaTeX
+\begin{document}
+% if we set the author, date, title fields, we can have LaTeX
% create a title page for us.
\maketitle
% If we have sections, we can create table of contents. We have to compile our
% document twice to make it appear in right order.
-% It is a good practice to separate the table of contents form the body of the
+% It is a good practice to separate the table of contents form the body of the
% document. To do so we use \newpage command
\newpage
\tableofcontents
@@ -58,14 +59,14 @@ Svetlana Golubeva}
% Most research papers have abstract, you can use the predefined commands for this.
% This should appear in its logical order, therefore, after the top matter,
-% but before the main sections of the body.
+% but before the main sections of the body.
% This command is available in the document classes article and report.
\begin{abstract}
- \LaTeX \hspace{1pt} documentation written as \LaTeX! How novel and totally not
+ \LaTeX{} documentation written as \LaTeX! How novel and totally not
my idea!
\end{abstract}
-% Section commands are intuitive.
+% Section commands are intuitive.
% All the titles of the sections are added automatically to the table of contents.
\section{Introduction}
Hello, my name is Colton and together we're going to explore \LaTeX!
@@ -74,23 +75,28 @@ Hello, my name is Colton and together we're going to explore \LaTeX!
This is the text for another section. I think it needs a subsection.
\subsection{This is a subsection} % Subsections are also intuitive.
-I think we need another one
+I think we need another one.
\subsubsection{Pythagoras}
Much better now.
\label{subsec:pythagoras}
% By using the asterisk we can suppress LaTeX's inbuilt numbering.
-% This works for other LaTeX commands as well.
-\section*{This is an unnumbered section}
+% This works for other LaTeX commands as well.
+\section*{This is an unnumbered section}
However not all sections have to be numbered!
\section{Some Text notes}
%\section{Spacing} % Need to add more information about space intervals
-\LaTeX \hspace{1pt} is generally pretty good about placing text where it should
-go. If
-a line \\ needs \\ to \\ break \\ you add \textbackslash\textbackslash
-\hspace{1pt} to the source code. \\
+\LaTeX{} is generally pretty good about placing text where it should
+go. If
+a line \\ needs \\ to \\ break \\ you add \textbackslash\textbackslash{}
+to the source code.
+
+Separate paragraphs by empty lines.
+
+You need to add a backslash after abbreviations (if not followed by a comma), because otherwise the spacing after the dot is too large:
+E.g., i.e., etc.\ are are such abbreviations.
\section{Lists}
Lists are one of the easiest things to create in \LaTeX! I need to go shopping
@@ -109,18 +115,18 @@ tomorrow, so let's make a grocery list.
\section{Math}
-One of the primary uses for \LaTeX \hspace{1pt} is to produce academic articles
-or technical papers. Usually in the realm of math and science. As such,
-we need to be able to add special symbols to our paper! \\
+One of the primary uses for \LaTeX{} is to produce academic articles
+or technical papers. Usually in the realm of math and science. As such,
+we need to be able to add special symbols to our paper!
Math has many symbols, far beyond what you can find on a keyboard;
-Set and relation symbols, arrows, operators, and Greek letters to name a few.\\
+Set and relation symbols, arrows, operators, and Greek letters to name a few.
Sets and relations play a vital role in many mathematical research papers.
-Here's how you state all x that belong to X, $\forall$ x $\in$ X. \\
-% Notice how I needed to add $ signs before and after the symbols. This is
-% because when writing, we are in text-mode.
-% However, the math symbols only exist in math-mode.
+Here's how you state all x that belong to X, $\forall x \in X$.
+% Notice how I needed to add $ signs before and after the symbols. This is
+% because when writing, we are in text-mode.
+% However, the math symbols only exist in math-mode.
% We can enter math-mode from text mode with the $ signs.
% The opposite also holds true. Variable can also be rendered in math-mode.
% We can also enter math mode with \[\]
@@ -128,16 +134,16 @@ Here's how you state all x that belong to X, $\forall$ x $\in$ X. \\
\[a^2 + b^2 = c^2 \]
My favorite Greek letter is $\xi$. I also like $\beta$, $\gamma$ and $\sigma$.
-I haven't found a Greek letter yet that \LaTeX \hspace{1pt} doesn't know
-about! \\
+I haven't found a Greek letter yet that \LaTeX{} doesn't know
+about!
-Operators are essential parts of a mathematical document:
-trigonometric functions ($\sin$, $\cos$, $\tan$),
-logarithms and exponentials ($\log$, $\exp$),
-limits ($\lim$), etc.
-have per-defined LaTeX commands.
-Let's write an equation to see how it's done:
-$\cos(2\theta) = \cos^{2}(\theta) - \sin^{2}(\theta)$ \\
+Operators are essential parts of a mathematical document:
+trigonometric functions ($\sin$, $\cos$, $\tan$),
+logarithms and exponentials ($\log$, $\exp$),
+limits ($\lim$), etc.\
+have pre-defined LaTeX commands.
+Let's write an equation to see how it's done:
+$\cos(2\theta) = \cos^{2}(\theta) - \sin^{2}(\theta)$
Fractions (Numerator-denominators) can be written in these forms:
@@ -146,7 +152,7 @@ $$ ^{10}/_{7} $$
% Relatively complex fractions can be written as
% \frac{numerator}{denominator}
-$$ \frac{n!}{k!(n - k)!} $$ \\
+$$ \frac{n!}{k!(n - k)!} $$
We can also insert equations in an ``equation environment''.
@@ -156,31 +162,33 @@ We can also insert equations in an ``equation environment''.
\label{eq:pythagoras} % for referencing
\end{equation} % all \begin statements must have an end statement
-We can then reference our new equation!
+We can then reference our new equation!
Eqn.~\ref{eq:pythagoras} is also known as the Pythagoras Theorem which is also
-the subject of Sec.~\ref{subsec:pythagoras}. A lot of things can be labeled:
+the subject of Sec.~\ref{subsec:pythagoras}. A lot of things can be labeled:
figures, equations, sections, etc.
Summations and Integrals are written with sum and int commands:
% Some LaTeX compilers will complain if there are blank lines
% In an equation environment.
-\begin{equation}
+\begin{equation}
\sum_{i=0}^{5} f_{i}
-\end{equation}
-\begin{equation}
+\end{equation}
+\begin{equation}
\int_{0}^{\infty} \mathrm{e}^{-x} \mathrm{d}x
-\end{equation}
+\end{equation}
\section{Figures}
-Let's insert a Figure. Figure placement can get a little tricky.
+Let's insert a figure. Figure placement can get a little tricky.
+Basic options are [t] for top, [b] for bottom, [h] for here (approximately).
I definitely have to lookup the placement options each time.
+% See https://en.wikibooks.org/wiki/LaTeX/Floats,_Figures_and_Captions for more details
-\begin{figure}[H] % H here denoted the placement option.
+\begin{figure}[H] % H here denoted the placement option.
\centering % centers the figure on the page
% Inserts a figure scaled to 0.8 the width of the page.
- %\includegraphics[width=0.8\linewidth]{right-triangle.png}
+ %\includegraphics[width=0.8\linewidth]{right-triangle.png}
% Commented out for compilation purposes. Please use your imagination.
\caption{Right triangle with sides $a$, $b$, $c$}
\label{fig:right-triangle}
@@ -192,51 +200,62 @@ We can also insert Tables in the same way as figures.
\begin{table}[H]
\caption{Caption for the Table.}
% the {} arguments below describe how each row of the table is drawn.
- % Again, I have to look these up. Each. And. Every. Time.
- \begin{tabular}{c|cc}
+ % The basic is simple: one letter for each column, to control alignment:
+ % basic options are: c, l, r and p for centered, left, right and paragraph
+ % optionnally, you can add a | for a vertical line
+ % See https://en.wikibooks.org/wiki/LaTeX/Tables for more details
+ \begin{tabular}{c|cc} % here it means "centered | vertical line, centered centered"
Number & Last Name & First Name \\ % Column rows are separated by &
\hline % a horizontal line
1 & Biggus & Dickus \\
2 & Monty & Python
\end{tabular}
+ % it will approximately be displayed like this
+ % Number | Last Name First Name
+ % -------|--------------------------- % because of \hline
+ % 1 | Biggus Dickus
+ % 2 | Monty Python
\end{table}
-\section{Getting \LaTeX \hspace{1pt} to not compile something (i.e. Source Code)}
-Let's say we want to include some code into our \LaTeX \hspace{1pt} document,
-we would then need \LaTeX \hspace{1pt} to not try and interpret that text and
-instead just print it to the document. We do this with a verbatim
-environment.
+\section{Getting \LaTeX{} to not compile something (i.e.\ Source Code)}
+Let's say we want to include some code into our \LaTeX{} document,
+we would then need \LaTeX{} to not try and interpret that text and
+instead just print it to the document. We do this with a verbatim
+environment.
% There are other packages that exist (i.e. minty, lstlisting, etc.)
% but verbatim is the bare-bones basic one.
-\begin{verbatim}
+\begin{verbatim}
print("Hello World!")
- a%b; % look! We can use % signs in verbatim.
- random = 4; #decided by fair random dice roll
+ a%b; % look! We can use % signs in verbatim.
+ random = 4; #decided by fair random dice roll, https://www.xkcd.com/221/
+ See https://www.explainxkcd.com/wiki/index.php/221:_Random_Number
\end{verbatim}
-\section{Compiling}
+\section{Compiling}
+
+By now you're probably wondering how to compile this fabulous document
+and look at the glorious glory that is a \LaTeX{} pdf.
+(yes, this document actually does compile).
-By now you're probably wondering how to compile this fabulous document
-and look at the glorious glory that is a \LaTeX \hspace{1pt} pdf.
-(yes, this document actually does compile). \\
-Getting to the final document using \LaTeX \hspace{1pt} consists of the following
+Getting to the final document using \LaTeX{} consists of the following
steps:
\begin{enumerate}
\item Write the document in plain text (the ``source code'').
- \item Compile source code to produce a pdf.
+ \item Compile source code to produce a pdf.
The compilation step looks like this (in Linux): \\
- \begin{verbatim}
+ \begin{verbatim}
> pdflatex learn-latex.tex
\end{verbatim}
\end{enumerate}
-A number of \LaTeX \hspace{1pt}editors combine both Step 1 and Step 2 in the
+A number of \LaTeX{} editors combine both Step 1 and Step 2 in the
same piece of software. So, you get to see Step 1, but not Step 2 completely.
Step 2 is still happening behind the scenes\footnote{In cases, where you use
references (like Eqn.~\ref{eq:pythagoras}), you may need to run Step 2
multiple times, to generate an intermediary *.aux file.}.
% Also, this is how you add footnotes to your document!
+% with a simple \footnote{...} command. They are numbered ¹, ², ... by default.
You write all your formatting information in plain text in Step 1.
The compilation part in Step 2 takes care of producing the document in the
@@ -245,19 +264,40 @@ format you defined in Step 1.
\section{Hyperlinks}
We can also insert hyperlinks in our document. To do so we need to include the
package hyperref into preamble with the command:
-\begin{verbatim}
+\begin{verbatim}
\usepackage{hyperref}
\end{verbatim}
There exists two main types of links: visible URL \\
-\url{https://learnxinyminutes.com/docs/latex/}, or
+\url{https://learnxinyminutes.com/docs/latex/}, or
\href{https://learnxinyminutes.com/docs/latex/}{shadowed by text}
-% You can not add extra-spaces or special symbols into shadowing text since it
+% You can not add extra-spaces or special symbols into shadowing text since it
% will cause mistakes during the compilation
-This package also produces list of tumbnails in the output pdf document and
+This package also produces list of thumbnails in the output pdf document and
active links in the table of contents.
+\section{Writing in ASCII or other encodings}
+
+By default, historically LaTeX accepts inputs which are pure ASCII (128),
+not even extened ASCII, meaning without accents (à, è etc.) and non-Latin symbols.
+
+It is easy to insert accents and basic Latin symbols, with backslash shortcuts
+Like \,c, \'e, \`A, \ae and \oe etc. % for ç, é, À, etc
+% See https://en.wikibooks.org/wiki/LaTeX/Special_Characters#Escaped_codes for more
+
+To write directly in UTF-8, when compiling with pdflatex, use
+\begin{verbatim}
+ \usepackage[utf8]{inputenc}
+\end{verbatim}
+The selected font has to support the glyphs used for your document, you have to add
+\begin{verbatim}
+ \usepackage[T1]{fontenc}
+\end{verbatim}
+
+Not that there also exists LuaTeX and XeLaTeX that were designed to have builtin
+support for UTF-8 and case ease your life if you don't write in a latin alphabet.
+
\section{End}
That's all for now!
@@ -267,9 +307,8 @@ That's all for now!
\begin{thebibliography}{1}
% similar to other lists, the \bibitem command can be used to list items
% each entry can then be cited directly in the body of the text
- \bibitem{latexwiki} The amazing \LaTeX \hspace{1pt} wikibook: {\em
-https://en.wikibooks.org/wiki/LaTeX}
- \bibitem{latextutorial} An actual tutorial: {\em http://www.latex-tutorial.com}
+ \bibitem{latexwiki} The amazing \LaTeX{} wikibook: \emph{https://en.wikibooks.org/wiki/LaTeX}
+ \bibitem{latextutorial} An actual tutorial: \emph{http://www.latex-tutorial.com}
\end{thebibliography}
% end the document
@@ -280,3 +319,4 @@ https://en.wikibooks.org/wiki/LaTeX}
* The amazing LaTeX wikibook: [https://en.wikibooks.org/wiki/LaTeX](https://en.wikibooks.org/wiki/LaTeX)
* An actual tutorial: [http://www.latex-tutorial.com/](http://www.latex-tutorial.com/)
+* A quick guide for learning LaTeX: [Learn LaTeX in 30 minutes](https://www.overleaf.com/learn/latex/Learn_LaTeX_in_30_minutes)
diff --git a/lbstanza.html.markdown b/lbstanza.html.markdown
new file mode 100644
index 00000000..19dc7db7
--- /dev/null
+++ b/lbstanza.html.markdown
@@ -0,0 +1,282 @@
+---
+language: LB Stanza
+filename: learn-stanza.stanza
+contributors:
+ - ["Mike Hilgendorf", "https://github.com/m-hilgendorf"]
+---
+
+LB Stanza (or Stanza for short) is a new optionally-typed general purpose programming language from the University of California, Berkeley. Stanza was designed to help programmers tackle the complexity of architecting large programs and significantly increase the productivity of application programmers across the entire software development life cycle.
+
+
+```stanza
+; this is a comment
+;<A>
+This is a block comment
+ ;<B>
+ block comments can be nested with optional tags.
+ ;<B>
+;<A>
+defpackage learn-stanza-in-y:
+ import core
+ import collections
+
+;==============================================================================
+; The basics, things you'd find in most programming languages
+;==============================================================================
+
+
+; Variables can be mutable (var) or immutable (val)
+val immutable = "this string can't be changed"
+var mutable = "this one can be"
+mutable = "like this"
+
+; The basic data types (annotations are optional)
+val an-int: Int = 12345
+val a-long: Long = 12345L
+val a-float: Float = 1.2345f
+val a-double: Double = 3.14159
+val a-string: String = "this is a string"
+val a-multiline-string = \<tag>
+ this is a "raw" string literal
+\<tag>
+
+; Print a formatted string with println and "..." % [...]
+println("this is a formatted string %_ %_" % [mutable, immutable])
+
+; Stanza is optionally typed, and has a ? (any) type.
+var anything:? = 0
+anything = 3.14159
+anything = "a string"
+
+; Stanza has basic collections like Tuples, Arrays, Vectors and HashTables
+val tuple: Tuple<?> = [mutable, immutable]
+
+val array = Array<?>(3)
+array[0] = "string"
+array[1] = 1
+array[2] = 1.23455
+; array[3] = "out-of-bounds" ; arrays are bounds-checked
+
+val vector = Vector<?>()
+vector[0] = "string"
+vector[1] = 1
+vector[2] = 3.14159
+
+val hash-table = HashTable<String, ?>()
+hash-table["0"] = 0
+hash-table["1"] = 1
+hash-table["2"] = 1
+
+
+;==============================================================================
+; Functions
+;==============================================================================
+; Functions are declared with the `defn` keyword
+defn my-function (arg:?) : ; note the space between identifier and arg list
+ println("called my-function with %_" % [arg])
+
+my-function("arg") ; note the lack of a space to call the function
+
+; Functions can be declared inside another function and capture variables from
+; the surrounding environment.
+defn outer (arg):
+ defn inner ():
+ println("outer had arg: %_" % [arg])
+ inner()
+
+outer("something")
+
+; functions are "first-class" in stanza, meaning you can assign variables
+; to functions and pass functions as arguments to other functions.
+val a-function = outer
+defn do-n-times (arg, func, n:Int):
+ for i in 0 to n do :
+ func(arg)
+do-n-times("argument", a-function, 3)
+
+; sometimes you want to define a function inline, or use an anonymous function.
+; for this you can use the syntax:
+; fn (args):
+; ...
+do-n-times("hello", fn (arg): println(arg), 2)
+
+; there is a shorthand for writing anonymous functions
+do-n-times("hello", { println(_) }, 2)
+
+; the short hand works for multiple arguments as well.
+val multi-lambda = { println(_ + 2 * _) }
+multi-lambda(1, 2)
+
+;==============================================================================
+; User defined types
+;==============================================================================
+; Structs are declared with the `defstruct` keyword
+defstruct MyStruct:
+ field
+
+; constructors are derived automatically
+val my-struct = MyStruct("field:value")
+
+; fields are accessed using function-call syntax
+println(field(my-struct))
+
+; Stanza supports subtyping with a "multimethod" system based on method
+; overloading.
+deftype MyType
+defmulti a-method (m:MyType)
+
+defstruct Foo <: MyType
+defstruct Bar <: MyType
+defmethod a-method (a-foo: Foo):
+ println("called a-method on a Foo")
+
+defmethod a-method (a-foo: Bar):
+ println("called a-method on a Bar")
+
+;==============================================================================
+; The Type System
+;==============================================================================
+; True and Falseare types with a single value.
+val a-true: True = true
+val a-false: False = false
+
+; You can declare a union type, or a value that is one of a set of types
+val a-boolean: True|False = true
+val another-boolean: True|False = false
+
+; You can pattern match on types
+match(a-boolean):
+ (t:True): println("is true")
+ (f:False): println("is false")
+
+; You can match against a single possible type
+match(a-boolean:True):
+ println("is still true")
+else:
+ println("is not true")
+
+; You can compose program logic around the type of a variable
+if anything is Float :
+ println("anything is a float")
+else if anything is-not String :
+ println("anything is not an int")
+else :
+ println("I don't know what anything is")
+
+;==============================================================================
+; Control Flow
+;==============================================================================
+; stanza has the standard basic control flow
+val condition = [false, false]
+if condition[0] :
+ ; do something
+ false
+else if condition[1] :
+ ; do another thing
+ false
+else :
+ ; whatever else
+ false
+
+; there is also a switch statement, which can be used to pattern match
+; on values (as opposed to types)
+switch(anything):
+ "this": false
+ "that": false
+ "the-other-thing": false
+ else: false
+
+; for and while loops are supported
+while condition[0]:
+ println("do stuff")
+
+for i in 0 to 10 do:
+ vector[i] = i
+
+; stanza also supports named labels which can functin as break or return
+; statements
+defn another-fn ():
+ label<False> return:
+ label<False> break:
+ while true:
+ if condition[0] is False:
+ break(false)
+ return(false)
+
+; For a comprehensive guide on Stanza's advanced control flow, check out
+; this page: http://lbstanza.org/chapter9.html from Stanza-by-Example
+
+;==============================================================================
+; Sequences
+;==============================================================================
+; for "loops" are sugar for a more powerful syntax.
+val xs = [1, 2, 3]
+val ys = ['a', 'b', 'c']
+val zs = ["foo", "bar", "baz"]
+
+for (x in xs, y in ys, z in zs) do :
+ println("x:%_, y:%_, z:%_" % [x, y, z])
+
+
+;xs, ys, and zs are all "Seqable" meaing they are Seq types (sequences).
+; the `do` identifier is a special function that just applies the body of
+; the for loop to each element of the sequence.
+;
+; A common sequence task is concatenating sequences. This is accomplished
+; using the `seq-cat` function. This is analogous to "flattening" iterateors
+val concat = to-tuple $
+ for sequence in [xs, ys, zs] seq-cat:
+ sequence
+
+; we can also use a variation to interleave the elements of multiple sequences
+val interleaved = to-tuple $
+ for (x in xs, y in ys, z in zs) seq-cat :
+ [x, y, z]
+
+println("[%,] [%,]" % [concat, interleaved])
+
+; Another common task is mapping a sequence to another, for example multiplying
+; all the elements of a list of numbers by a constant. To do this we use `seq`.
+var numbers = [1.0, 2.0, 3.0, 4.0]
+numbers = to-tuple $
+ for n in numbers seq :
+ 2.0 * n
+println("%," % [numbers])
+
+if find({_ == 2.0}, numbers) is-not False :
+ println("found it!")
+
+; or maybe we just want to know if there's something in a sequence
+var is-there =
+ for n in numbers any? :
+ n == 2.0
+
+; since this is "syntactic sugar" we can write it explicitly using an
+; anonymous function
+is-there = any?({_ == 2.0}, numbers)
+
+; a detailed reference of the sequence library and various adaptors can
+; be found here: http://lbstanza.org/reference.html#anchor439
+
+
+=========================================================================
+; Documentation
+;=========================================================================
+;
+; Top level statements can be prefixed with the "doc" field which takes
+; a string value and is used to autogenerate documentation for the package.
+doc: \<doc>
+ # Document Strings
+
+ ```stanza
+ val you-can = "include code snippets, too"
+ ```
+
+ To render documentation as markdown (compatible with mdbook)
+
+ ```bash
+ stanza doc source.stanza -o docs
+ ```
+\<doc>
+defn docfn () : false
+``` \ No newline at end of file
diff --git a/ldpl.html.markdown b/ldpl.html.markdown
new file mode 100644
index 00000000..86603d94
--- /dev/null
+++ b/ldpl.html.markdown
@@ -0,0 +1,170 @@
+---
+language: LDPL
+filename: learnLDPL.ldpl
+contributors:
+ - ["Martín del Río", "https://github.com/lartu"]
+---
+
+**LDPL** is a powerful, C++ transpiled, open-source programming language designed
+from the ground up to be excessively expressive, readable, fast and easy to learn.
+It mimics plain English, in the likeness of older programming languages like COBOL,
+with the desire that it can be understood by anybody. It's very portable and runs on a
+plethora of different architectures and operating systems and it even supports UTF-8
+out of the box.
+
+[Read more here.](https://github.com/lartu/ldpl)
+
+```coffeescript
+# This is a single line comment in LDPL.
+# LDPL doesn't have multi-line comments.
+
+# LDPL is a case-insensitive language: dIsPlaY and DISPLAY are the same
+# statement, and foo and FOO name the same variable.
+
+# An LDPL source file is divided in two sections, the DATA section and
+# the PROCEDURE section.
+
+DATA:
+# Within the DATA section, variables are declared.
+
+myNumber is number # Defines a real number.
+myString is text # Defines a string.
+myList is number list # Defines a list of numbers.
+myMap is number map # Defines a map of numbers.
+
+# LDPL understands four data types: two scalar types (NUMBER, TEXT)
+# and two container types (LISTs and MAPs).
+# LISTs can be TEXT LISTs or NUMBER LISTs, while MAPs can be
+# TEXT MAPs and NUMBER MAPs. You can also chain many containers
+# to create larger data types:
+textListList is text list list
+myMulticontainer is number list list map
+# Defines a map of lists of lists of numbers.
+
+PROCEDURE:
+# Within the PROCEDURE section, your code is written.
+
+store -19.2 in myNumber # Use the STORE statement to assign values
+store "Hi there" in myString # to variables.
+push 890 to myList # Use PUSH - TO to append values to lists.
+push 100 to myList
+push 500 to myList
+store 45 in myMap:"someIndex" # Use the : operator to index containers.
+
+push list to textListList # Push an empty list into a list of lists.
+push "LDPL is nice!" to textListList:0 #Push text to the pushed list.
+
+display "Hello World!" # Use the DISPLAY statement to print values.
+# The display statement can receive multiple values separated by spaces.
+display crlf "How are you today?" myNumber myString crlf
+# CRLF is the standard line break value in LDPL.
+display textListList:0:0 " Isn't it?" crlf
+
+# IF statements in LDPL are extremely verbose:
+if myNumber is equal to -19.2 and myList:0 is less than 900 then
+ display "Yes!" crlf
+else if myMap:"someIndex" is not equal to 45 then
+ display "This is an else if!" crlf
+else
+ display "Else!" crlf
+end if
+# Valid LDPL comparisson operators are
+# - IS EQUAL TO
+# - IS NOT EQUAL TO
+# - IS LESS THAN
+# - IS GREATER THAN
+# - IS LESS THAN OR EQUAL TO
+# - IS GREATER THAN OR EQUAL TO
+if "Hi there!" is not equal to "Bye bye!" then
+ display "Yep, those weren't equal." crlf
+end if
+# LDPL normally doesn't understand inline expressions, so you
+# cannot do stuff like:
+# if myNumber - 9 * 2 is equal to 10 then
+# LDPL will set your computer on fire and burst your screen if you do so.
+
+# WHILE loops follow the same rules
+store 0 in myNumber
+while myNumber is less than 10 do
+ display "Loop number " myNumber "..." crlf
+ in myNumber solve myNumber + 1 # You can do math like this.
+repeat
+# You can use 'break' and 'continue' inside loops just like any other language.
+
+# LDPL also has FOR loops and FOR EACH loops
+for myNumber from 0 to 100 step 2 do
+ display myNumber crlf
+repeat
+
+for each myNumber in myList do
+ display myNumber
+repeat
+
+display "Enter your name: "
+accept myString # Use ACCEPT to let the user input values.
+display "Hi there, " myString crlf
+display "How old are you?: "
+accept myNumber
+if myNumber is greater than 200 then
+ display "Woah, you are so old!" crlf
+end if
+
+wait 1000 milliseconds # Pause the program for a whole second.
+
+# Let's do some math
+store 1.2 in myNumber
+in myNumber solve myNumber * (10 / 7.2) # Operators are separated by spaces.
+floor myNumber
+display myNumber crlf
+get random in myNumber # get a random number between 0 and 1
+ # and store it in myNumber
+
+# Functions in LDPL are called sub-procedures. Sub-procedures, like source
+# files, are divided in sections. The sections found in sub-procedures are
+# the PARAMETERS section, the LOCAL DATA section and the PROCEDURE section.
+# All sections except the PROCEDURE section can be skipped if they aren't
+# used. If no PARAMTERS nor LOCAL DATA sections are used, the PROCEDURE
+# keyword may be omited.
+sub myFunction
+ parameters:
+ a is number # LDPL is pass by reference
+ b is number
+ result is number # Thus you can return values through a parameter.
+ local data:
+ c is number
+ procedure:
+ get random in c
+ in result solve a + b * c
+end sub
+
+sub sayHello
+ display "Hi there!" crlf
+ return
+ display "This won't be displayed :("
+end sub
+
+call myFunction with 1 2 myNumber
+display myNumber crlf
+call sayHello
+call sayBye # sub-procedures may be called before they are declared
+
+sub sayBye
+ display "Bye!"
+end sub
+
+# One of the greatest features of LDPL is the ability to create your
+# own statements.
+
+create statement "say hi" executing sayHello
+say hi
+
+create statement "random add $ and $ in $" executing myFunction
+random add 1 and 2 in myNumber
+display myNumber crlf
+
+exit
+```
+
+## Further Reading
+
+ * [LDPL Docs](https://docs.ldpl-lang.org)
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/lfe.html.markdown b/lfe.html.markdown
new file mode 100644
index 00000000..413de36e
--- /dev/null
+++ b/lfe.html.markdown
@@ -0,0 +1,459 @@
+---
+
+language: "Lisp Flavoured Erlang(LFE)"
+filename: lispflavourederlang.lfe
+contributors:
+ - ["Pratik Karki", "https://github.com/prertik"]
+---
+
+Lisp Flavoured Erlang(LFE) is a functional, concurrent, general-purpose programming
+language and Lisp dialect(Lisp-2) built on top of Core Erlang and the Erlang Virtual Machine(BEAM).
+
+LFE can be obtained from [LFE](https://github.com/rvirding/lfe)
+
+The classic starting point is [LFE DOCS.](http://docs.lfe.io)
+
+Another new site is being built to replace it.[LFE DEV.](http://docs.lfe.io/dev)
+
+
+
+```lisp
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; 0. Syntax
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; General form.
+
+;; Lisp comprises of two syntax called: the ATOM and the S-expression.
+;; `forms` are known as grouped S-expressions.
+
+8 ; an atom; it evaluates to itself
+
+:ERLANG ;Atom; evaluates to the symbol :ERLANG.
+
+t ; another atom which denotes true.
+
+(* 2 21) ; an S- expression
+
+'(8 :foo t) ;another one
+
+
+;;; Comments
+
+;; Single line comments start with a semicolon; use two for normal
+;; comments, three for section comments, and four fo file-level
+;; comments.
+
+;; Block Comment
+
+ #| comment text |#
+
+;;; Environment
+
+;; LFE is the de-facto standard.
+
+;; Libraries can be used directly from the Erlang ecosystem. Rebar3 is the build tool.
+
+;; LFE is usually developed with a text editor(preferably Emacs) and a REPL
+;; (Read Evaluate Print Loop) running at the same time. The REPL
+;; allows for interactive exploration of the program as it is "live"
+;; in the system.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; 1. Literals and Special Syntactic Rules
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Integers
+
+1234 -123 ; Regular decimal notation
+#b0 #b10101 ; Binary notation
+#0 #10101 ; Binary notation (alternative form)
+#o377 #o-111 ; Octal notation
+#d123456789 #d+123 ; Explicitly decimal notation
+#xc0ffe 0x-01 ; Hexadecimal notation
+#2r1010 #8r377 ;Notation with explicit base (up to 36)
+#\a #$ #\ä #\🐭 ;Character notation (the value is the Unicode code point of the character)
+#\x1f42d; ;Character notation with the value in hexadecimal
+
+;;; Floating point numbers
+1.0 +2.0 -1.5 1.0e10 1.111e-10
+
+;;; Strings
+
+"any text between double quotes where \" and other special characters like \n can be escaped".
+; List String
+"Cat: \x1f639;" ; writing unicode in string for regular font ending with semicolon.
+
+#"This is a binary string \n with some \"escaped\" and quoted (\x1f639;) characters"
+; Binary strings are just strings but function different in the VM.
+; Other ways of writing it are: #B("a"), #"a", and #B(97).
+
+
+;;; Character escaping
+
+\b ; => Backspace
+\t ; => Tab
+\n ; => Newline
+\v ; => Vertical tab
+\f ; => Form Feed
+\r ; => Carriage Return
+\e ; => Escape
+\s ; => Space
+\d ; => Delete
+
+;;; Binaries
+;; It is used to create binaries with any contents.
+#B((#"a" binary) (#"b" binary)) ; #"ab" (Evaluated form)
+
+;;; Lists are: () or (foo bar baz)
+
+;;; Tuples are written in: #(value1 value2 ...). Empty tuple #() is also valid.
+
+;;; Maps are written as: #M(key1 value1 key2 value2 ...). Empty map #M() is also valid.
+
+;;; Symbols: Things that cannot be parsed. Eg: foo, Foo, foo-bar, :foo
+| foo | ; explicit construction of symbol by wrapping vertical bars.
+
+;;; Evaluation
+
+;; #.(... some expression ...). E.g. '#.(+ 1 1) will evaluate the (+ 1 1) while it ;; reads the expression and then be effectively '2.
+
+;; List comprehension in LFE REPL
+
+lfe> (list-comp
+ ((<- x '(0 1 2 3)))
+ (trunc (math:pow 3 x)))
+ (1 3 9 27)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 2. Core forms
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; These forms are same as those found at Common Lisp and Scheme.
+
+(quote e)
+(cons head tail)
+(car e)
+(cdr e)
+(list e ... )
+(tuple e ... )
+(binary seg ... )
+(map key val ...), (map-get m k), (map-set m k v ...), (map-update m k v ...)
+
+(lambda (arg ...) ...)
+ (match-lambda
+ ((arg ... ) {{(when e ...)}} ...) ; Matches clauses
+ ... )
+(let ((pat {{(when e ...)}} e)
+ ...)
+ ... )
+(let-function ((name lambda|match-lambda) ; Only define local
+ ... ) ; functions
+ ... )
+(letrec-function ((name lambda|match-lambda) ; Only define local
+ ... ) ; functions
+ ... )
+(let-macro ((name lambda-match-lambda) ; Only define local
+ ...) ; macros
+ ...)
+(progn ... )
+(if test true-expr {{false-expr}})
+(case e
+ (pat {{(when e ...)}} ...)
+ ... ))
+(receive
+ (pat {{(when e ...)}} ... )
+ ...
+ (after timeout ... ))
+(catch ... )
+(try
+ e
+ {{(case ((pat {{(when e ...)}} ... )
+ ... ))}}
+ {{(catch
+ ; Next must be tuple of length 3!
+ (((tuple type value ignore) {{(when e ...)}}
+ ... )
+ ... )}}
+ {{(after ... )}})
+
+(funcall func arg ... )
+(call mod func arg ... ) - Call to Erlang Mod:Func(Arg, ... )
+(define-module name declaration ... )
+(extend-module declaration ... ) - Define/extend module and declarations.
+(define-function name lambda|match-lambda)
+(define-macro name lambda|match-lambda) - Define functions/macros at top-level.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 3. Macros
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Macros are part of the language to allow you to create abstractions
+;; on top of the core language and standard library that move you closer
+;; toward being able to directly express the things you want to express.
+
+;; Top-level function
+
+(defun name (arg ...) ...)
+
+;; Adding comments in functions
+
+(defun name
+ "Toplevel function with pattern-matching arguments"
+ ((argpat ...) ...)
+ ...)
+
+;; Top-level macro
+
+(defmacro name (arg ...) ...)
+(defmacro name arg ...)
+
+;; Top-level macro with pattern matching arguments
+
+(defmacro name
+ ((argpat ...) ...)
+ ...)
+
+;; Top-level macro using Scheme inspired syntax-rules format
+
+(defsyntax name
+ (pat exp)
+ ...)
+
+;;; Local macros in macro or syntax-rule format
+
+(macrolet ((name (arg ... ) ... )
+ ... )
+ ... )
+
+(syntaxlet ((name (pat exp) ...)
+ ...)
+ ...)
+
+;; Like CLISP
+
+(prog1 ...)
+(prog2 ...)
+
+;; Erlang LFE module
+
+(defmodule name ...)
+
+;; Erlang LFE record
+
+(defrecord name ...)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 4. Patterns and Guards
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Using patterns in LFE compared to that of Erlang
+
+;; Erlang ;; LFE
+;; {ok, X} (tuple 'ok x)
+;; error 'error
+;; {yes, [X|Xs]} (tuple 'yes (cons x xs))
+;; <<34,F/float>> (binary 34 (f float))
+;; [P|Ps]=All (= (cons p ps) all)
+
+ _ ; => is don't care while pattern matching
+
+ (= pattern1 pattern2) ; => easier, better version of pattern matching
+
+;; Guards
+
+;; Whenever pattern occurs(let, case, receive, lc, etc) it can be followed by an optional
+;; guard which has the form (when test ...).
+
+(progn gtest ...) ;; => Sequence of guard tests
+(if gexpr gexpr gexpr)
+(type-test e)
+(guard-bif ...) ;; => Guard BIFs, arithmetic, boolean and comparison operators
+
+;;; REPL
+
+lfe>(set (tuple len status msg) #(8 ok "Trillian"))
+ #(8 ok "Trillian")
+lfe>msg
+ "Trillian"
+
+;;; Program illustrating use of Guards
+
+(defun right-number?
+ ((x) (when (orelse (== x 42) (== x 276709)))
+ 'true)
+ ((_) 'false))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 5. Functions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; A simple function using if.
+
+(defun max (x y)
+ "The max function."
+ (if (>= x y) x y))
+
+;; Same function using more clause
+
+(defun max
+ "The max function."
+ ((x y) (when (>= x y)) x)
+ ((x y) y))
+
+;; Same function using similar style but using local functions defined by flet or fletrec
+
+(defun foo (x y)
+ "The max function."
+ (flet ((m (a b) "Local comment."
+ (if (>= a b) a b)))
+ (m x y)))
+
+;; LFE being Lisp-2 has separate namespaces for variables and functions
+;; Both variables and function/macros are lexically scoped.
+;; Variables are bound by lambda, match-lambda and let.
+;; Functions are bound by top-level defun, flet and fletrec.
+;; Macros are bound by top-level defmacro/defsyntax and by macrolet/syntaxlet.
+
+;; (funcall func arg ...) like CL to call lambdas/match-lambdas
+;; (funs) bound to variables are used.
+
+;; separate bindings and special for apply.
+apply _F (...),
+apply _F/3 ( a1, a2, a3 )
+
+;; Cons'ing in function heads
+(defun sum (l) (sum l 0))
+ (defun sum
+ (('() total) total)
+ (((cons h t) total) (sum t (+ h total))))
+
+;; ``cons`` literal instead of constructor form
+ (defun sum (l) (sum l 0))
+ (defun sum
+ (('() total) total)
+ ((`(,h . ,t) total) (sum t (+ h total))))
+
+;; Matching records in function heads
+
+(defun handle_info
+ (('ping (= (match-state remote-pid 'undefined) state))
+ (gen_server:cast (self) 'ping)
+ `#(noreply ,state))
+ (('ping state)
+ `#(noreply ,state)))
+
+;; Receiving Messages
+ (defun universal-server ()
+ (receive
+ ((tuple 'become func)
+ (funcall func))))
+
+;; another way for receiving messages
+
+ (defun universal-server ()
+ (receive
+ (`#(become ,func)
+ (funcall func))))
+
+;; Composing a complete function for specific tasks
+
+(defun compose (f g)
+ (lambda (x)
+ (funcall f
+ (funcall g x))))
+
+(defun check ()
+ (let* ((sin-asin (compose #'sin/1 #'asin/1))
+ (expected (sin (asin 0.5)))
+ (compose-result (funcall sin-asin 0.5)))
+ (io:format "Expected answer: ~p~n" (list expected))
+ (io:format "Answer with compose: ~p~n" (list compose-result))))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; 6. Concurrency
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Message passing as done by Erlang's light-weight "processes".
+
+(defmodule messenger-back
+ (export (print-result 0) (send-message 2)))
+
+(defun print-result ()
+ (receive
+ ((tuple pid msg)
+ (io:format "Received message: '~s'~n" (list msg))
+ (io:format "Sending message to process ~p ...~n" (list pid))
+ (! pid (tuple msg))
+ (print-result))))
+
+(defun send-message (calling-pid msg)
+ (let ((spawned-pid (spawn 'messenger-back 'print-result ())))
+ (! spawned-pid (tuple calling-pid msg))))
+
+;; Multiple simultaneous HTTP Requests:
+
+(defun parse-args (flag)
+ "Given one or more command-line arguments, extract the passed values.
+
+ For example, if the following was passed via the command line:
+
+ $ erl -my-flag my-value-1 -my-flag my-value-2
+
+ One could then extract it in an LFE program by calling this function:
+
+ (let ((args (parse-args 'my-flag)))
+ ...
+ )
+ In this example, the value assigned to the arg variable would be a list
+ containing the values my-value-1 and my-value-2."
+ (let ((`#(ok ,data) (init:get_argument flag)))
+ (lists:merge data)))
+
+(defun get-pages ()
+ "With no argument, assume 'url parameter was passed via command line."
+ (let ((urls (parse-args 'url)))
+ (get-pages urls)))
+
+(defun get-pages (urls)
+ "Start inets and make (potentially many) HTTP requests."
+ (inets:start)
+ (plists:map
+ (lambda (x)
+ (get-page x)) urls))
+
+(defun get-page (url)
+ "Make a single HTTP request."
+ (let* ((method 'get)
+ (headers '())
+ (request-data `#(,url ,headers))
+ (http-options ())
+ (request-options '(#(sync false))))
+ (httpc:request method request-data http-options request-options)
+ (receive
+ (`#(http #(,request-id #(error ,reason)))
+ (io:format "Error: ~p~n" `(,reason)))
+ (`#(http #(,request-id ,result))
+ (io:format "Result: ~p~n" `(,result))))))
+
+
+;; Check out Erlang's documentation for more concurrency and OTP docs.
+```
+
+## Further Reading
+
+* [LFE DOCS](http://docs.lfe.io)
+* [LFE GitBook](https://lfe.gitbooks.io/reference-guide/index.html)
+* [LFE Wiki](https://en.wikipedia.org/wiki/LFE_(programming_language))
+
+## Extra Info
+* [LFE PDF](http://www.erlang-factory.com/upload/presentations/61/Robertvirding-LispFlavouredErlang.pdf)
+* [LFE mail](https://groups.google.com/d/msg/lisp-flavoured-erlang/XA5HeLbQQDk/TUHabZCHXB0J)
+
+## Credits
+
+Lots of thanks to Robert Virding for creating LFE, Duncan McGreggor for documenting it and other LFE contributors who made LFE awesome.
+
diff --git a/linker.html.markdown b/linker.html.markdown
new file mode 100644
index 00000000..42839e05
--- /dev/null
+++ b/linker.html.markdown
@@ -0,0 +1,9 @@
+---
+category: tool
+tool: linker
+contributors:
+ - ["Alexander Kovalchuk", "https://github.com/Zamuhrishka"]
+---
+
+This article is available in [Russian](https://learnxinyminutes.com/docs/ru-ru/linker-ru/).
+
diff --git a/logtalk.html.markdown b/logtalk.html.markdown
index 385e38f9..ce907ee3 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).
@@ -40,20 +40,25 @@ An object encapsulates predicate declarations and definitions. Objects can be cr
:- end_object.
```
-# Compiling source files
+# Compiling and loading source files
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
```
+In general, entities may have dependencies on entities defined in other source files (e.g. library entities). To load a file and all its dependencies, the advised solution is to define a
+_loader_ file that loads all the necessary files for an application. A loader file is simply a source file, typically named `loader.lgt`, that makes calls to the `logtalk_load/1-2`
+built-in predicates, usually from an `initialization/1` directive for portability and
+standards compliance. Loader files are provided for all libraries, tools, and examples.
+
# Sending a message to an object
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 +68,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 +81,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 +102,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),
@@ -106,13 +111,13 @@ Error = error(
yes
```
-A subtle point is that predicate scope directives specify predicate _calling_ semantics, not _definitions_ semantics. For example, if an object playing the role of a class declares a predicate private, the predicate can be defined in subclasses and instances *but* can only be called in its instances _from_ the class.
+A subtle point is that predicate scope directives specify predicate _calling_ semantics, not _definition_ semantics. For example, if an object playing the role of a class declares a predicate private, the predicate can be defined in subclasses and instances *but* can only be called in its instances _from_ the class.
# Defining and implementing a protocol
Protocols contain predicate declarations that can be implemented by any number of objects and categories:
-```
+```logtalk
:- protocol(listp).
:- public(member/2).
@@ -131,7 +136,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 +149,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 +172,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,17 +184,17 @@ 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).
+ :- public(bar/0).
:- end_object.
```
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 +213,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 +250,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 +272,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 +326,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 +341,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 +352,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 +363,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 +375,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 +390,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 +410,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 +418,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 +428,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 +440,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 +459,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 +480,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 +491,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 +503,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 +516,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 +530,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/lsf/lambda-calculus-lsf.html.markdown b/lsf/lambda-calculus-lsf.html.markdown
new file mode 100644
index 00000000..88bb638f
--- /dev/null
+++ b/lsf/lambda-calculus-lsf.html.markdown
@@ -0,0 +1,91 @@
+---
+category: Algorithms & Data Structures
+name: Lambda Calculus
+contributors:
+ - ["Max Sun", "http://github.com/maxsun"]
+translators:
+ - ["Victore Leve", "https://github.com/AcProIL"]
+lang: lsf
+---
+
+# Calculo λ
+
+Calculo lambda, creato principto per Alonzo Church, es lingua de programmatura
+computatro maximo parvo. Quamquam non habe numero, serie de charactere vel ullo
+typo de data non functionale, id pote repraesenta omne machina de Turing.
+
+Tres elemento compone calculo lambda: **quantitate variabile** (q.v.),
+**functione** et **applicatione**.
+
+| Elemento | Syntaxe | Exemplo |
+|----------------------|-----------------------------------|-----------|
+| Quantitate variabile | `<nomine>` | `x` |
+| Functione | `λ<parametro>.<corpore>` | `λx.x` |
+| Applicatione | `<functione><q.v. aut functione>` | `(λx.x)a` |
+
+Functione fundamentale es identitate: `λx.x` cum argumento primo `x` et cum
+corpore secundo `x`. In mathematica, nos scribe `id: x↦x`.
+
+## Quantitate variabile libero et ligato
+
+* In functione praecedente, `x` es q.v. ligato nam id es et in copore et
+ argumento.
+* In `λx.y`, `y` es q.v. libero nam non es declarato ante.
+
+## Valutatione
+
+Valutatione es facto per reductione beta (reductione β) que es essentialiter
+substitutione lexicale.
+
+Dum valutatione de formula `(λx.x)a`, nos substitue omne evento de `x` in
+corpore de functione pro `a`.
+
+* `(λx.x)a` vale `a`
+* `(λx.y)a` vale `y`
+
+Pote etiam crea functione de ordine supero: `(λx.(λy.x))a` vale `λy.a`.
+
+Etsi calculo lambda solo tracta functione de uno parametro, nos pote crea
+functione cum plure argumento utente methodo de Curry: `λx.(λy.(λz.xyz))`
+es scriptura informatica de formula mathematico `f: x, y, z ↦ x(y(z)))`.
+
+Ergo, interdum, nos ute `λxy.<corpore>` pro `λx.λy.<corpore>`.
+
+## Arithmetica
+
+### Logica de Boole
+
+Es nec numero nec booleano in calculo lambda.
+
+* «vero» es `v = λx.λy.x`
+* «falso» es `f = λx.λy.y`
+
+Primo, nos pote defini functione «si t tunc a alio b» per `si = λtab.tab`.
+Si `t` es vero, valutatione da `(λxy.x) a b` id es `a`. Similiter si `t` es
+falso, nos obtine `b`.
+
+Secundo, nos pote defini operatore de logica:
+
+* «a et b» es `et = λa.λb.si a b f`
+* «a vel b» es `vel = λa.λb.si a t b`
+* «non a» es `non = λa.si a f t`
+
+### Numeros
+
+Nos pone:
+
+* `0 = λf.λx.x` (`0: f↦id`)
+* `1 = λf.λx.f x` (`1: f↦f`)
+* `2 = λf.λx.f(f x)` (`2: f↦f⚬f`)
+
+Cum mente generale, successore de numero `n` es `S n = λf.λx.f((n f) x)`
+(`n+1: f↦f⚬fⁿ`). Id es **`n` est functione que da `fⁿ` ex functione `f`**.
+
+Postremo additione es `λab.(a S)b`
+
+## Ut progrede
+
+### In lingua anglo
+
+1. [A Tutorial Introduction to the Lambda Calculus](http://www.inf.fu-berlin.de/lehre/WS03/alpi/lambda.pdf) per Raúl Roja
+2. [The Lambda Calculus](http://www.cs.cornell.edu/courses/cs3110/2008fa/recitations/rec26.html), CS 312 Recitation 26
diff --git a/lsf/latex-lsf.html.markdown b/lsf/latex-lsf.html.markdown
new file mode 100644
index 00000000..18c2e62b
--- /dev/null
+++ b/lsf/latex-lsf.html.markdown
@@ -0,0 +1,146 @@
+---
+language: latex
+lang: lsf
+contributors:
+ - ["Chaitanya Krishna Ande", "http://icymist.github.io"]
+ - ["Colton Kohnke", "http://github.com/voltnor"]
+ - ["Sricharan Chiruvolu", "http://sricharan.xyz"]
+translators:
+ - ["Victore Leve", "https://github.com/AcProIL"]
+filename: learn-latex-lsf.tex
+---
+
+```tex
+% Solo existe commentario monolinea, illo incipe cum charactere %
+
+% LaTeX non es sicut MS Word aut OpenOffice: que scribe non es que obtine.
+% Primo, scribe imperio (que semper incipe cum \) et secundo programma crea
+% lima.
+
+% Nos defini typo de document (id es articulo aut libro aut libello etc.).
+% Optione muta quomodo programma age, per exemplo altore de littera.
+\documentclass[12pt]{article}
+
+% Deinde nos lista paccettos que nos vol ute. Es classe de imperio que alio
+% utatore e scribe. Pote muta funda, geometria de pagina, etc. vel adde
+% functionnalitate.
+\usepackage{euler}
+\usepackage{graphicx}
+
+% Ultimo statione ante scribe documento es metadata id es titulo, auctore et
+% tempore. Charactere ~ es spatio que non pote es secato.
+\title{Disce LaTeX in~Y Minutos!}
+\author{Chaitanya Krishna Ande, Colton Kohnke \& Sricharan Chiruvolu}
+\date{\today}
+
+% Principio de documento
+\begin{document}
+ \maketitle % Nos vol adfige metadata.
+
+ % Saepe nos adde breviario us describe texto.
+ \begin{abstract}
+ Hic es exmplo de documento sibre cum lingua de LaTeX.
+ \end{abstract}
+
+ % \section crea sectione cum titulo dato sicut sperato
+ \section{Introductione}
+
+ Traductione de hic cursu es importante.
+
+ \subsection{Methodo}
+ Iste parte non es utile.
+
+ \subsubsection{Methodo peculiare}
+ % \label da nomine ad parte ut post ute imperio de referentia \ref.
+ \label{subsec:metpec}
+
+ % Cum asteritco nos indice que nos non vol numero ante titulo de sectione.
+ \section*{Me non aestima numero…}
+
+ …sed de Peano aut de Church.
+
+ \section{Listas}
+
+ Que me debe scribe:
+
+ \begin{enumerate} % `enumerate` designa lista cum numeros contra `itemize`.
+ \item articulo,
+ \item libro,
+ \item cursu.
+ \end{enumerate}
+
+ \section{Mathematica}
+
+ Methematicas ute multo programma LaTeX ut communica suo decooperito.
+ Illo necessita symbolo multo instar de logica vel sagitta vel littera cum
+ accento.
+
+ % Fornula es in linea si nos scribe inter \( et \) (aut duo $) sed magno si
+ % nos ute \[ et \].
+ \(\forall n\in N_0\) % pro omne n in classe N₀
+ \[^{3}/_{4} = \frac{3}{4} < 1\] % ¾ < 1
+
+ Alphabeta graeco contine littera $\alpha$.
+
+ % Ut scribe equatione cum numero et nomine, existe circumiecto `equation`.
+ \begin{equation}
+ c^2 = a^2 + b^2
+ \label{eq:pythagoras}
+ \end{equation}
+
+ \begin{equation}
+ % Summa ab 1 ad n de numeros dimidio de n(n+1)
+ \sum_{i=1}^n i = \frac{n(n+1)}{2}
+ \end{equation}
+
+ \section{Figura}
+
+ % Nos adde imagine `right-triangle.png` cum latitudo de quinque centimetro,
+ % horizontaliter in centro et cum capite «Triangulo recto».
+ \begin{figure}
+ \centering
+ \includegraphics[width=5cm]{right-triangle.png}
+ \caption{Triangulo recto}
+ \label{fig:right-triangle}
+ \end{figure}
+
+ \subsection{Tabula}
+
+ \begin{table}
+ \caption{Título para la tabla.}
+ % Argumento de `tabular` es lineamente de columna.
+ % c: centro, l: sinistra, r: destra, | linea verticale
+ \begin{tabular}{c|cc}
+ Numero & B & C \\
+ \hline % linea horizontale
+ 1 & et & aut \\
+ 2 & atque & vel
+ \end{tabular}
+ \end{table}
+
+ \section{Stylo}
+
+ Texto pote es \textbf{crasso} et \textit{italico}!
+
+ \section{Texto puro}
+
+ % Circumiecto `verbatim` ignora imperio, nos saepe ute id pro monstra
+ % programma.
+ \begin{verbatim}
+from math import tau, e
+print(e ** tau)
+ \end{verbatim}
+
+ \section{Et plus!}
+ LaTeX habe facultate crea bibliographia, paritura, scaccarip… cum paccetto
+ dedicato.
+\end{document}
+```
+
+Imperio ut conge documento es `pdflatex documento` in terminale.
+
+## Ut progrede
+
+### In lingua anglo
+
+* [LaTeX tutorial](http://www.latex-tutorial.com/) per Claudio Vellage
diff --git a/lt-lt/tmux-lt.html.markdown b/lt-lt/tmux-lt.html.markdown
new file mode 100644
index 00000000..f05f55e2
--- /dev/null
+++ b/lt-lt/tmux-lt.html.markdown
@@ -0,0 +1,255 @@
+---
+category: tool
+tool: tmux
+filename: tmux-lt.json
+contributors:
+ - ["mdln", "https://github.com/mdln"]
+translators:
+ - ["Zygimantus", "https://github.com/zygimantus"]
+lang: lt-lt
+
+---
+
+
+[tmux](http://tmux.sourceforge.net)
+yra terminalo daugintuvas: jis leidžia vienu metu sukurti, turėti
+ir valdyti kelis terminalus viename ekrane. tmux gali būti atjungtas
+nuo ekrano ir veikti fone, o vėliau gali būti vėl prijungtas.
+
+
+```
+
+ tmux [komanda] # Vykdyti komandą
+ # 'tmux' be komandų sukurs naują sesiją
+
+ new # Sukurti naują sesiją
+ -s "Session" # Sukurti pavadintą sesiją
+ -n "Window" # Sukurti pavadintą langą
+ -c "/dir" # Pradėti nurodytoje direktorijoje
+
+ attach # Priskirti paskutinę/prienamą sesiją
+ -t "#" # Priskirti nurodytą sesiją
+ -d # Atjungti sesiją nuo kitų langų
+
+ ls # Aktyvių sesijų sąrašas
+ -a # Visų aktyvių sesijų sąrašas
+
+ lsw # Langų sąrašas
+ -a # Visų langų sąrašas
+ -s # Visų langų sesijoje sąrašas
+
+ lsp # Skydelių sąrašas
+ -a # Visų skydelių sąrašas
+ -s # Visų skydelių sesijoje sąrašas
+ -t # Visų skydelių taikinyje sąrašas
+
+ kill-window # Užbaigti dabartinį langą
+ -t "#" # Užbaigti nurodytą langą
+ -a # Užbaigti visus langus
+ -a -t "#" # Užbaigti visus langus, bet ne taikinį
+
+ kill-session # Užbaigti dabartinę sesiją
+ -t "#" # Užbaigti nurodytą sesiją
+ -a # Užbaigti visas sesijas
+ -a -t "#" # Užbaigti visas sesijas, bet ne taikinį
+
+```
+
+
+### Klavišai
+
+Priskirta tmux sesija yra valdoma klavišų kompinacijomis.
+
+```
+----------------------------------------------------------------------
+ (C-b) = Ctrl + b # Kombinacija reikalinga norint naudoti klavišus
+
+ (M-1) = Meta + 1 -or- Alt + 1
+----------------------------------------------------------------------
+
+ ? # Rodo visų klavišų kombinacijų sąrašą
+ : # Įjungiama tmux komandinė eilutė
+ r # Priverstinai perpiešiamas prijungtas klientas
+ c # Sukurti naują langą
+
+ ! # Iškelia esamą skydelį iš lango.
+ % # Perskelia esamą skydelį į du, kairįjį ir dešinį
+ " # Perskelia esamą skydelį į du, viršutinį ir apatinį
+
+ n # Pakeičia į kitą langą
+ p # Pakeičia į buvusį langą
+ { # Apkeičia dabartinį skydėlį su buvusiu
+ } # Apkeičia dabartinį skydėlį su sekančiu
+
+ s # Pasirinkti naują sesiją prijungtam klientui interaktyviai
+ w # Pasirinkti dabartinį langą interaktyviai
+ 0 to 9 # Pasirinkti langą nuo 0 iki 9
+
+ d # Atjungti dabartinį klientą
+ D # Pasirinkti klientą, kurį atjungti
+
+ & # Užbaigti dabartinį langą
+ x # Užbaigti dabartinį skydelį
+
+ Up, Down # Pakeisti į skydelį viršuje, apačioje, kairėje arba
+ dešinėje
+ Left, Right
+
+ M-1 to M-5 # Rikiuoti skydelius:
+ # 1) even-horizontal
+ # 2) even-vertical
+ # 3) main-horizontal
+ # 4) main-vertical
+ # 5) tiled
+
+ C-Up, C-Down # Keisti esamo skydelio dydį vienos ląstelės žingsniu
+ C-Left, C-Right
+
+ M-Up, M-Down # Keisti esamo skydelio dydį penkių ląstelių žingsniu
+ M-Left, M-Right
+
+```
+
+
+### Configuring ~/.tmux.conf
+
+tmux.conf gali būti nustatytas automatiškai paleidimo metu, panašiai kaip ir
+.vimrc arba init.el.
+
+```
+# Pavyzdys tmux.conf
+# 2014.10
+
+
+### General
+###########################################################################
+
+# Enable UTF-8
+setw -g utf8 on
+set-option -g status-utf8 on
+
+# Scrollback/History limit
+set -g history-limit 2048
+
+# Index Start
+set -g base-index 1
+
+# Mouse
+set-option -g mouse-select-pane on
+
+# Force reload of config file
+unbind r
+bind r source-file ~/.tmux.conf
+
+
+### Keybinds
+###########################################################################
+
+# Unbind C-b as the default prefix
+unbind C-b
+
+# Set new default prefix
+set-option -g prefix `
+
+# Return to previous window when prefix is pressed twice
+bind C-a last-window
+bind ` last-window
+
+# Allow swapping C-a and ` using F11/F12
+bind F11 set-option -g prefix C-a
+bind F12 set-option -g prefix `
+
+# Keybind preference
+setw -g mode-keys vi
+set-option -g status-keys vi
+
+# Moving between panes with vim movement keys
+bind h select-pane -L
+bind j select-pane -D
+bind k select-pane -U
+bind l select-pane -R
+
+# Window Cycle/Swap
+bind e previous-window
+bind f next-window
+bind E swap-window -t -1
+bind F swap-window -t +1
+
+# Easy split pane commands
+bind = split-window -h
+bind - split-window -v
+unbind '"'
+unbind %
+
+# Activate inner-most session (when nesting tmux) to send commands
+bind a send-prefix
+
+
+### Theme
+###########################################################################
+
+# Statusbar Color Palatte
+set-option -g status-justify left
+set-option -g status-bg black
+set-option -g status-fg white
+set-option -g status-left-length 40
+set-option -g status-right-length 80
+
+# Pane Border Color Palette
+set-option -g pane-active-border-fg green
+set-option -g pane-active-border-bg black
+set-option -g pane-border-fg white
+set-option -g pane-border-bg black
+
+# Message Color Palette
+set-option -g message-fg black
+set-option -g message-bg green
+
+# Window Status Color Palette
+setw -g window-status-bg black
+setw -g window-status-current-fg green
+setw -g window-status-bell-attr default
+setw -g window-status-bell-fg red
+setw -g window-status-content-attr default
+setw -g window-status-content-fg yellow
+setw -g window-status-activity-attr default
+setw -g window-status-activity-fg yellow
+
+
+### UI
+###########################################################################
+
+# Notification
+setw -g monitor-activity on
+set -g visual-activity on
+set-option -g bell-action any
+set-option -g visual-bell off
+
+# Automatically set window titles
+set-option -g set-titles on
+set-option -g set-titles-string '#H:#S.#I.#P #W #T' # window number,program name,active (or not)
+
+# Statusbar Adjustments
+set -g status-left "#[fg=red] #H#[fg=green]:#[fg=white]#S#[fg=green] |#[default]"
+
+# Show performance counters in statusbar
+# Requires https://github.com/thewtex/tmux-mem-cpu-load/
+set -g status-interval 4
+set -g status-right "#[fg=green] | #[fg=white]#(tmux-mem-cpu-load)#[fg=green] | #[fg=cyan]%H:%M #[default]"
+
+```
+
+
+### Šaltiniai
+
+[Tmux | Home](http://tmux.sourceforge.net)
+
+[Tmux Manual page](http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/tmux.1?query=tmux)
+
+[Gentoo Wiki](http://wiki.gentoo.org/wiki/Tmux)
+
+[Archlinux Wiki](https://wiki.archlinux.org/index.php/Tmux)
+
+[Display CPU/MEM % in statusbar](https://stackoverflow.com/questions/11558907/is-there-a-better-way-to-display-cpu-usage-in-tmux)
+
+[tmuxinator - Manage complex tmux sessions](https://github.com/tmuxinator/tmuxinator)
diff --git a/lua.html.markdown b/lua.html.markdown
index 1e2d4366..4a470623 100644
--- a/lua.html.markdown
+++ b/lua.html.markdown
@@ -12,13 +12,15 @@ filename: learnlua.lua
Adding two ['s and ]'s makes it a
multi-line comment.
--]]
---------------------------------------------------------------------------------
+
+----------------------------------------------------
-- 1. Variables and flow control.
---------------------------------------------------------------------------------
+----------------------------------------------------
num = 42 -- All numbers are doubles.
--- Don't freak out, 64-bit doubles have 52 bits for storing exact int
--- values; machine precision is not a problem for ints that need < 52 bits.
+-- Don't freak out, 64-bit doubles have 52 bits for
+-- storing exact int values; machine precision is
+-- not a problem for ints that need < 52 bits.
s = 'walternate' -- Immutable strings like Python.
t = "double-quotes are also fine"
@@ -58,8 +60,8 @@ aBoolValue = false
-- Only nil and false are falsy; 0 and '' are true!
if not aBoolValue then print('twas false') end
--- 'or' and 'and' are short-circuited. This is similar to the a?b:c operator
--- in C/js:
+-- 'or' and 'and' are short-circuited.
+-- This is similar to the a?b:c operator in C/js:
ans = aBoolValue and 'yes' or 'no' --> 'no'
karlSum = 0
@@ -79,19 +81,20 @@ repeat
num = num - 1
until num == 0
---------------------------------------------------------------------------------
+
+----------------------------------------------------
-- 2. Functions.
---------------------------------------------------------------------------------
+----------------------------------------------------
function fib(n)
- if n < 2 then return n end
+ if n < 2 then return 1 end
return fib(n - 2) + fib(n - 1)
end
-- Closures and anonymous functions are ok:
function adder(x)
- -- The returned function is created when adder is called, and remembers the
- -- value of x:
+ -- The returned function is created when adder is
+ -- called, and remembers the value of x:
return function (y) return x + y end
end
a1 = adder(9)
@@ -99,9 +102,10 @@ a2 = adder(36)
print(a1(16)) --> 25
print(a2(64)) --> 100
--- Returns, func calls, and assignments all work with lists that may be
--- mismatched in length. Unmatched receivers are nil; unmatched senders are
--- discarded.
+-- Returns, func calls, and assignments all work
+-- with lists that may be mismatched in length.
+-- Unmatched receivers are nil;
+-- unmatched senders are discarded.
x, y, z = 1, 2, 3, 4
-- Now x = 1, y = 2, z = 3, and 4 is thrown away.
@@ -112,17 +116,15 @@ function bar(a, b, c)
end
x, y = bar('zaphod') --> prints "zaphod nil nil"
--- Now x = 4, y = 8, values 15..42 are discarded.
+-- Now x = 4, y = 8, values 15...42 are discarded.
--- Functions are first-class, may be local/global. These are the same:
+-- Functions are first-class, may be local/global.
+-- These are the same:
function f(x) return x * x end
f = function (x) return x * x end
-- And so are these:
local function g(x) return math.sin(x) end
-local g = function(x) return math.sin(x) end
--- Equivalent to local function g(x)..., except referring to g in the function
--- body won't work as expected.
local g; g = function (x) return math.sin(x) end
-- the 'local g' decl makes g-self-references ok.
@@ -131,16 +133,15 @@ local g; g = function (x) return math.sin(x) end
-- Calls with one string param don't need parens:
print 'hello' -- Works fine.
--- Calls with one table param don't need parens either (more on tables below):
-print {} -- Works fine too.
---------------------------------------------------------------------------------
+----------------------------------------------------
-- 3. Tables.
---------------------------------------------------------------------------------
+----------------------------------------------------
--- Tables = Lua's only compound data structure; they are associative arrays.
--- Similar to php arrays or js objects, they are hash-lookup dicts that can
--- also be used as lists.
+-- Tables = Lua's only compound data structure;
+-- they are associative arrays.
+-- Similar to php arrays or js objects, they are
+-- hash-lookup dicts that can also be used as lists.
-- Using tables as dictionaries / maps:
@@ -156,13 +157,14 @@ t.key2 = nil -- Removes key2 from the table.
u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
print(u[6.28]) -- prints "tau"
--- Key matching is basically by value for numbers and strings, but by identity
--- for tables.
+-- Key matching is basically by value for numbers
+-- and strings, but by identity for tables.
a = u['@!#'] -- Now a = 'qbert'.
b = u[{}] -- We might expect 1729, but it's nil:
--- b = nil since the lookup fails. It fails because the key we used is not the
--- same object as the one used to store the original value. So strings &
--- numbers are more portable keys.
+-- b = nil since the lookup fails. It fails
+-- because the key we used is not the same object
+-- as the one used to store the original value. So
+-- strings & numbers are more portable keys.
-- A one-table-param function call needs no parens:
function h(x) print(x.key1) end
@@ -182,15 +184,16 @@ v = {'value1', 'value2', 1.21, 'gigawatts'}
for i = 1, #v do -- #v is the size of v for lists.
print(v[i]) -- Indices start at 1 !! SO CRAZY!
end
--- A 'list' is not a real type. v is just a table with consecutive integer
--- keys, treated as a list.
+-- A 'list' is not a real type. v is just a table
+-- with consecutive integer keys, treated as a list.
---------------------------------------------------------------------------------
+----------------------------------------------------
-- 3.1 Metatables and metamethods.
---------------------------------------------------------------------------------
+----------------------------------------------------
--- A table can have a metatable that gives the table operator-overloadish
--- behaviour. Later we'll see how metatables support js-prototype behaviour.
+-- A table can have a metatable that gives the table
+-- operator-overloadish behavior. Later we'll see
+-- how metatables support js-prototypey behavior.
f1 = {a = 1, b = 2} -- Represents the fraction a/b.
f2 = {a = 2, b = 3}
@@ -200,7 +203,7 @@ f2 = {a = 2, b = 3}
metafraction = {}
function metafraction.__add(f1, f2)
- local sum = {}
+ sum = {}
sum.b = f1.b * f2.b
sum.a = f1.a * f2.b + f2.a * f1.b
return sum
@@ -211,9 +214,10 @@ setmetatable(f2, metafraction)
s = f1 + f2 -- call __add(f1, f2) on f1's metatable
--- f1, f2 have no key for their metatable, unlike prototypes in js, so you must
--- retrieve it as in getmetatable(f1). The metatable is a normal table with
--- keys that Lua knows about, like __add.
+-- f1, f2 have no key for their metatable, unlike
+-- prototypes in js, so you must retrieve it as in
+-- getmetatable(f1). The metatable is a normal table
+-- with keys that Lua knows about, like __add.
-- But the next line fails since s has no metatable:
-- t = s + s
@@ -225,12 +229,11 @@ myFavs = {food = 'pizza'}
setmetatable(myFavs, {__index = defaultFavs})
eatenBy = myFavs.animal -- works! thanks, metatable
---------------------------------------------------------------------------------
--- Direct table lookups that fail will retry using the metatable's __index
--- value, and this recurses.
+-- Direct table lookups that fail will retry using
+-- the metatable's __index value, and this recurses.
--- An __index value can also be a function(tbl, key) for more customized
--- lookups.
+-- An __index value can also be a function(tbl, key)
+-- for more customized lookups.
-- Values of __index,add, .. are called metamethods.
-- Full list. Here a is a table with the metamethod.
@@ -251,19 +254,19 @@ eatenBy = myFavs.animal -- works! thanks, metatable
-- __newindex(a, b, c) for a.b = c
-- __call(a, ...) for a(...)
---------------------------------------------------------------------------------
+----------------------------------------------------
-- 3.2 Class-like tables and inheritance.
---------------------------------------------------------------------------------
+----------------------------------------------------
--- Classes aren't built in; there are different ways to make them using
--- tables and metatables.
+-- Classes aren't built in; there are different ways
+-- to make them using tables and metatables.
-- Explanation for this example is below it.
Dog = {} -- 1.
function Dog:new() -- 2.
- local newObj = {sound = 'woof'} -- 3.
+ newObj = {sound = 'woof'} -- 3.
self.__index = self -- 4.
return setmetatable(newObj, self) -- 5.
end
@@ -276,59 +279,62 @@ mrDog = Dog:new() -- 7.
mrDog:makeSound() -- 'I say woof' -- 8.
-- 1. Dog acts like a class; it's really a table.
--- 2. "function tablename:fn(...)" is the same as
--- "function tablename.fn(self, ...)", The : just adds a first arg called
--- self. Read 7 & 8 below for how self gets its value.
+-- 2. function tablename:fn(...) is the same as
+-- function tablename.fn(self, ...)
+-- The : just adds a first arg called self.
+-- Read 7 & 8 below for how self gets its value.
-- 3. newObj will be an instance of class Dog.
--- 4. "self" is the class being instantiated. Often self = Dog, but inheritance
--- can change it. newObj gets self's functions when we set both newObj's
--- metatable and self's __index to self.
+-- 4. self = the class being instantiated. Often
+-- self = Dog, but inheritance can change it.
+-- newObj gets self's functions when we set both
+-- newObj's metatable and self's __index to self.
-- 5. Reminder: setmetatable returns its first arg.
--- 6. The : works as in 2, but this time we expect self to be an instance
--- instead of a class.
+-- 6. The : works as in 2, but this time we expect
+-- self to be an instance instead of a class.
-- 7. Same as Dog.new(Dog), so self = Dog in new().
-- 8. Same as mrDog.makeSound(mrDog); self = mrDog.
---------------------------------------------------------------------------------
+----------------------------------------------------
-- Inheritance example:
LoudDog = Dog:new() -- 1.
function LoudDog:makeSound()
- local s = self.sound .. ' ' -- 2.
+ s = self.sound .. ' ' -- 2.
print(s .. s .. s)
end
seymour = LoudDog:new() -- 3.
seymour:makeSound() -- 'woof woof woof' -- 4.
---------------------------------------------------------------------------------
-- 1. LoudDog gets Dog's methods and variables.
-- 2. self has a 'sound' key from new(), see 3.
--- 3. Same as "LoudDog.new(LoudDog)", and converted to "Dog.new(LoudDog)" as
--- LoudDog has no 'new' key, but does have "__index = Dog" on its metatable.
--- Result: seymour's metatable is LoudDog, and "LoudDog.__index = Dog". So
--- seymour.key will equal seymour.key, LoudDog.key, Dog.key, whichever
+-- 3. Same as LoudDog.new(LoudDog), and converted to
+-- Dog.new(LoudDog) as LoudDog has no 'new' key,
+-- but does have __index = Dog on its metatable.
+-- Result: seymour's metatable is LoudDog, and
+-- LoudDog.__index = LoudDog. So seymour.key will
+-- = seymour.key, LoudDog.key, Dog.key, whichever
-- table is the first with the given key.
--- 4. The 'makeSound' key is found in LoudDog; this is the same as
--- "LoudDog.makeSound(seymour)".
+-- 4. The 'makeSound' key is found in LoudDog; this
+-- is the same as LoudDog.makeSound(seymour).
-- If needed, a subclass's new() is like the base's:
function LoudDog:new()
- local newObj = {}
+ newObj = {}
-- set up newObj
self.__index = self
return setmetatable(newObj, self)
end
---------------------------------------------------------------------------------
+----------------------------------------------------
-- 4. Modules.
---------------------------------------------------------------------------------
+----------------------------------------------------
---[[ I'm commenting out this section so the rest of this script remains
--- runnable.
+--[[ I'm commenting out this section so the rest of
+-- this script remains runnable.
```
```lua
@@ -354,8 +360,8 @@ local mod = require('mod') -- Run the file mod.lua.
local mod = (function ()
<contents of mod.lua>
end)()
--- It's like mod.lua is a function body, so that locals inside mod.lua are
--- invisible outside it.
+-- It's like mod.lua is a function body, so that
+-- locals inside mod.lua are invisible outside it.
-- This works because mod here = M in mod.lua:
mod.sayHello() -- Says hello to Hrunkner.
@@ -363,19 +369,19 @@ mod.sayHello() -- Says hello to Hrunkner.
-- This is wrong; sayMyName only exists in mod.lua:
mod.sayMyName() -- error
--- require's return values are cached so a file is run at most once, even when
--- require'd many times.
+-- require's return values are cached so a file is
+-- run at most once, even when require'd many times.
-- Suppose mod2.lua contains "print('Hi!')".
local a = require('mod2') -- Prints Hi!
local b = require('mod2') -- Doesn't print; a=b.
-- dofile is like require without caching:
-dofile('mod2') --> Hi!
-dofile('mod2') --> Hi! (runs again, unlike require)
+dofile('mod2.lua') --> Hi!
+dofile('mod2.lua') --> Hi! (runs it again)
-- loadfile loads a lua file but doesn't run it yet.
-f = loadfile('mod2') -- Calling f() runs mod2.lua.
+f = loadfile('mod2.lua') -- Call f() to run it.
-- loadstring is loadfile for strings.
g = loadstring('print(343)') -- Returns a function.
@@ -389,7 +395,7 @@ g() -- Prints out 343; nothing printed before now.
I was excited to learn Lua so I could make games
with the <a href="http://love2d.org/">Love 2D game engine</a>. That's the why.
-I started with <a href="http://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/">BlackBulletIV's Lua for programmers</a>.
+I started with <a href="https://ebens.me/post/lua-for-programmers-part-1/">BlackBulletIV's Lua for programmers</a>.
Next I read the official <a href="http://www.lua.org/pil/contents.html">Programming in Lua</a> book.
That's the how.
diff --git a/m.html.markdown b/m.html.markdown
new file mode 100644
index 00000000..96828ae5
--- /dev/null
+++ b/m.html.markdown
@@ -0,0 +1,370 @@
+---
+language: M (MUMPS)
+contributors:
+ - ["Fred Turkington", "http://z3ugma.github.io"]
+filename: LEARNM.m
+---
+
+M, or MUMPS (Massachusetts General Hospital Utility Multi-Programming System) is
+a procedural language with a built-in NoSQL database. Or, it’s a database with
+an integrated language optimized for accessing and manipulating that database.
+A key feature of M is that accessing local variables in memory and persistent
+storage use the same basic syntax, so there's no separate query
+language to remember. This makes it fast to program with, especially for
+beginners. M's syntax was designed to be concise in an era where
+computer memory was expensive and limited. This concise style means that a lot
+more fits on one screen without scrolling.
+
+The M database is a hierarchical key-value store designed for high-throughput
+transaction processing. The database is organized into tree structures called
+"globals", which are sparse data structures with parallels to modern formats
+like JSON.
+
+Originally designed in 1966 for the healthcare applications, M continues to be
+used widely by healthcare systems and financial institutions for high-throughput
+real-time applications.
+
+### Example
+
+Here's an example M program to calculate the Fibonacci series:
+
+```
+fib ; compute the first few Fibonacci terms
+ new i,a,b,sum
+ set (a,b)=1 ; Initial conditions
+ for i=1:1 do quit:sum>1000
+ . set sum=a+b
+ . write !,sum
+ . set a=b,b=sum
+```
+
+### Comments
+
+```
+; Comments start with a semicolon (;)
+```
+### Data Types
+
+M has two data types:
+
+```
+; Numbers - no commas, leading and trailing 0 removed.
+; Scientific notation with 'E'.
+; Floats with IEEE 754 double-precision values (15 digits of precision)
+; Examples: 20, 1e3 (stored as 1000), 0500.20 (stored as 500.2)
+; Strings - Characters enclosed in double quotes.
+; "" is the null string. Use "" within a string for "
+; Examples: "hello", "Scrooge said, ""Bah, Humbug!"""
+```
+### Commands
+
+Commands are case insensitive, and have a shortened abbreviation, often the first letter. Commands have zero or more arguments,depending on the command. M is whitespace-aware. Spaces are treated as a delimiter between commands and arguments. Each command is separated from its arguments by 1 space. Commands with zero arguments are followed by 2 spaces.
+
+#### W(rite)
+
+Print data to the current device.
+
+```
+WRITE !,"hello world"
+```
+
+! is syntax for a new line. Multiple statements can be provided as additional arguments:
+
+```
+w !,"foo bar"," ","baz"
+```
+
+#### R(ead)
+
+Retrieve input from the user
+
+```
+READ var
+r !,"Wherefore art thou Romeo? ",why
+```
+Multiple arguments can be passed to a read command. Constants are outputted. Variables are retrieved from the user. The terminal waits for the user to enter the first variable before displaying the second prompt.
+
+```
+r !,"Better one, or two? ",lorem," Better two, or three? ",ipsum
+```
+
+#### S(et)
+
+Assign a value to a variable
+
+```
+SET name="Benjamin Franklin"
+s centi=0.01,micro=10E-6
+w !,centi,!,micro
+
+;.01
+;.00001
+```
+#### K(ill)
+
+Remove a variable from memory or remove a database entry from disk.
+
+```
+KILL centi
+k micro
+```
+### Globals and Arrays
+
+In addition to local variables, M has persistent variables stored to disk called _globals_. Global names must start with a __caret__ (__^__). Globals are the built-in database of M.
+
+Any variable can be an array with the assignment of a _subscript_. Arrays are sparse and do not have a predefined size. Arrays should be visualized like trees, where subscripts are branches and assigned values are leaves. Not all nodes in an array need to have a value.
+
+```
+s ^cars=20
+s ^cars("Tesla",1,"Name")="Model 3"
+s ^cars("Tesla",2,"Name")="Model X"
+s ^cars("Tesla",2,"Doors")=5
+
+w !,^cars
+; 20
+w !,^cars("Tesla")
+; null value - there's no value assigned to this node but it has children
+w !,^cars("Tesla",1,"Name")
+; Model 3
+```
+
+Arrays are automatically sorted in order. Take advantage of the built-in sorting by setting your value of interest as the last child subscript of an array rather than its value.
+
+```
+; A log of temperatures by date and time
+s ^TEMPS("11/12","0600",32)=""
+s ^TEMPS("11/12","1030",48)=""
+s ^TEMPS("11/12","1400",49)=""
+s ^TEMPS("11/12","1700",43)=""
+```
+### Operators
+```jinja
+; Assignment: =
+; Unary: + Convert a string value into a numeric value.
+; Arthmetic:
+; + addition
+­; - subtraction
+; * multiplication
+; / floating-point division
+; \ integer division
+; # modulo
+; ** exponentiation
+; Logical:
+; & and
+; ! or
+; ' not
+; Comparison:
+; = equal
+; '= not equal
+; > greater than
+; < less than
+; '> not greater / less than or equal to
+; '< not less / greater than or equal to
+; String operators:
+; _ concatenate
+; [ contains ­ a contains b
+; ]] sorts after ­ a comes after b
+; '[ does not contain
+; ']] does not sort after
+```
+
+#### Order of operations
+
+Operations in M are _strictly_ evaluated left to right. No operator has precedence over any other.
+You should use parentheses to group expressions.
+
+```
+w 5+3*20
+;160
+;You probably wanted 65
+w 5+(3*20)
+```
+
+### Flow Control, Blocks, & Code Structure
+
+A single M file is called a _routine_. Within a given routine, you can break your code up into smaller chunks with _tags_. The tag starts in column 1 and the commands pertaining to that tag are indented.
+
+A tag can accept parameters and return a value, this is a function. A function is called with '$$':
+
+```
+; Execute the 'tag' function, which has two parameters, and write the result.
+w !,$$tag^routine(a,b)
+```
+
+M has an execution stack. When all levels of the stack have returned, the program ends. Levels are added to the stack with _do_ commands and removed with _quit_ commands.
+
+#### D(o)
+
+With an argument: execute a block of code & add a level to the stack.
+
+```
+d ^routine ;run a routine from the begining.
+; ;routines are identified by a caret.
+d tag ;run a tag in the current routine
+d tag^routine ;run a tag in different routine
+```
+
+Argumentless do: used to create blocks of code. The block is indented with a period for each level of the block:
+
+```
+set a=1
+if a=1 do
+. write !,a
+. read b
+. if b > 10 d
+. . w !, b
+w "hello"
+```
+
+#### Q(uit)
+Stop executing this block and return to the previous stack level.
+Quit can return a value.
+
+#### N(ew)
+Clear a given variable's value _for just this stack level_. Useful for preventing side effects.
+
+Putting all this together, we can create a full example of an M routine:
+
+```
+; RECTANGLE - a routine to deal with rectangle math
+ q ; quit if a specific tag is not called
+
+main
+ n length,width ; New length and width so any previous value doesn't persist
+ w !,"Welcome to RECTANGLE. Enter the dimensions of your rectangle."
+ r !,"Length? ",length,!,"Width? ",width
+ d area(length,width) ;Do a tag
+ s per=$$perimeter(length,width) ;Get the value of a function
+ w !,"Perimeter: ",per
+ q
+
+area(length,width) ; This is a tag that accepts parameters.
+ ; It's not a function since it quits with no value.
+ w !, "Area: ",length*width
+ q ; Quit: return to the previous level of the stack.
+
+perimeter(length,width)
+ q 2*(length+width) ; Quits with a value; thus a function
+```
+
+### Conditionals, Looping and $Order()
+
+F(or) loops can follow a few different patterns:
+
+```jinja
+;Finite loop with counter
+;f var=start:increment:stop
+
+f i=0:5:25 w i," " ;0 5 10 15 20 25
+
+; Infinite loop with counter
+; The counter will keep incrementing forever. Use a conditional with Quit to get out of the loop.
+;f var=start:increment
+
+f j=1:1 w j," " i j>1E3 q ; Print 1-1000 separated by a space
+
+;Argumentless for - infinite loop. Use a conditional with Quit.
+; Also read as "forever" - f or for followed by two spaces.
+s var=""
+f s var=var_"%" w !,var i var="%%%%%%%%%%" q
+; %
+; %%
+; %%%
+; %%%%
+; %%%%%
+; %%%%%%
+; %%%%%%%
+; %%%%%%%%
+; %%%%%%%%%
+; %%%%%%%%%%
+
+```
+
+#### I(f), E(lse), Postconditionals
+
+M has an if/else construct for conditional evaluation, but any command can be conditionally executed without an extra if statement using a _postconditional_. This is a condition that occurs immediately after the command, separated with a colon (:).
+
+```jinja
+; Conditional using traditional if/else
+r "Enter a number: ",num
+i num>100 w !,"huge"
+e i num>10 w !,"big"
+e w !,"small"
+
+; Postconditionals are especially useful in a for loop.
+; This is the dominant for loop construct:
+; a 'for' statement
+; that tests for a 'quit' condition with a postconditional
+; then 'do'es an indented block for each iteration
+
+s var=""
+f s var=var_"%" q:var="%%%%%%%%%%" d ;Read as "Quit if var equals "%%%%%%%%%%"
+. w !,var
+
+;Bonus points - the $L(ength) built-in function makes this even terser
+
+s var=""
+f s var=var_"%" q:$L(var)>10 d ;
+. w !,var
+
+```
+#### Array Looping - $Order
+As we saw in the previous example, M has built-in functions called with a single $, compared to user-defined functions called with $$. These functions have shortened abbreviations, like commands.
+One of the most useful is __$Order()__ / $O(). When given an array subscript, $O returns the next subscript in that array. When it reaches the last subscript, it returns "".
+
+```jinja
+;Let's call back to our ^TEMPS global from earlier:
+; A log of temperatures by date and time
+s ^TEMPS("11/12","0600",32)=""
+s ^TEMPS("11/12","0600",48)=""
+s ^TEMPS("11/12","1400",49)=""
+s ^TEMPS("11/12","1700",43)=""
+; Some more
+s ^TEMPS("11/16","0300",27)=""
+s ^TEMPS("11/16","1130",32)=""
+s ^TEMPS("11/16","1300",47)=""
+
+;Here's a loop to print out all the dates we have temperatures for:
+n date,time ; Initialize these variables with ""
+
+; This line reads: forever; set date as the next date in ^TEMPS.
+; If date was set to "", it means we're at the end, so quit.
+; Do the block below
+f s date=$ORDER(^TEMPS(date)) q:date="" d
+. w !,date
+
+; Add in times too:
+f s date=$ORDER(^TEMPS(date)) q:date="" d
+. w !,"Date: ",date
+. f s time=$O(^TEMPS(date,time)) q:time="" d
+. . w !,"Time: ",time
+
+; Build an index that sorts first by temperature -
+; what dates and times had a given temperature?
+n date,time,temp
+f s date=$ORDER(^TEMPS(date)) q:date="" d
+. f s time=$O(^TEMPS(date,time)) q:time="" d
+. . f s temp=$O(^TEMPS(date,time,temp)) q:temp="" d
+. . . s ^TEMPINDEX(temp,date,time)=""
+
+;This will produce a global like
+^TEMPINDEX(27,"11/16","0300")
+^TEMPINDEX(32,"11/12","0600")
+^TEMPINDEX(32,"11/16","1130")
+```
+
+## Further Reading
+
+There's lots more to learn about M. A great short tutorial comes from the University of Northern Iowa and Professor Kevin O'Kane's [Introduction to the MUMPS Language][1] presentation.
+
+To install an M interpreter / database on your computer, try a [YottaDB Docker image][2].
+
+YottaDB and its precursor, GT.M, have thorough documentation on all the language features including database transactions, locking, and replication:
+
+* [YottaDB Programmer's Guide][3]
+* [GT.M Programmer's Guide][4]
+
+[1]: https://www.cs.uni.edu/~okane/source/MUMPS-MDH/MumpsTutorial.pdf
+[2]: https://yottadb.com/product/get-started/
+[3]: https://docs.yottadb.com/ProgrammersGuide/langfeat.html
+[4]: http://tinco.pair.com/bhaskar/gtm/doc/books/pg/UNIX_manual/index.html
diff --git a/make.html.markdown b/make.html.markdown
index ab128475..eecc96bf 100644
--- a/make.html.markdown
+++ b/make.html.markdown
@@ -1,7 +1,9 @@
---
-language: make
+category: tool
+tool: make
contributors:
- ["Robert Steed", "https://github.com/robochat"]
+ - ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
filename: Makefile
---
@@ -11,7 +13,7 @@ target to the most recent version of the source. Famously written over a
weekend by Stuart Feldman in 1976, it is still widely used (particularly
on Unix and Linux) despite many competitors and criticisms.
-There are many varieties of make in existence, however this article
+There are many varieties of make in existence, however this article
assumes that we are using GNU make which is the standard on Linux.
```make
@@ -168,9 +170,9 @@ echo: name2 = Sara # True within the matching rule
# Some variables defined automatically by make.
echo_inbuilt:
echo $(CC)
- echo ${CXX)}
+ echo ${CXX}
echo $(FC)
- echo ${CFLAGS)}
+ echo ${CFLAGS}
echo $(CPPFLAGS)
echo ${CXXFLAGS}
echo $(LDFLAGS)
diff --git a/markdown.html.markdown b/markdown.html.markdown
index a1f5173b..cf4286e2 100644
--- a/markdown.html.markdown
+++ b/markdown.html.markdown
@@ -29,7 +29,7 @@ specific to a certain parser.
## HTML Elements
Markdown is a superset of HTML, so any HTML file is valid Markdown.
-```markdown
+```md
<!--This means we can use HTML elements in Markdown, such as the comment
element, and they won't be affected by a markdown parser. However, if you
create an HTML element in your markdown file, you cannot use markdown syntax
@@ -41,7 +41,7 @@ within that element's contents.-->
You can create HTML elements `<h1>` through `<h6>` easily by prepending the
text you want to be in that element by a number of hashes (#).
-```markdown
+```md
# This is an <h1>
## This is an <h2>
### This is an <h3>
@@ -51,7 +51,7 @@ text you want to be in that element by a number of hashes (#).
```
Markdown also provides us with two alternative ways of indicating h1 and h2.
-```markdown
+```md
This is an h1
=============
@@ -63,7 +63,7 @@ This is an h2
Text can be easily styled as italic or bold using markdown.
-```markdown
+```md
*This text is in italics.*
_And so is this text._
@@ -78,7 +78,7 @@ __And so is this text.__
In GitHub Flavored Markdown, which is used to render markdown files on
GitHub, we also have strikethrough:
-```markdown
+```md
~~This text is rendered with strikethrough.~~
```
## Paragraphs
@@ -86,7 +86,7 @@ GitHub, we also have strikethrough:
Paragraphs are a one or multiple adjacent lines of text separated by one or
multiple blank lines.
-```markdown
+```md
This is a paragraph. I'm typing in a paragraph isn't this fun?
Now I'm in paragraph 2.
@@ -99,7 +99,7 @@ I'm in paragraph three!
Should you ever want to insert an HTML `<br />` tag, you can end a paragraph
with two or more spaces and then begin a new paragraph.
-```markdown
+```md
I end with two spaces (highlight me to see them).
There's a <br /> above me!
@@ -107,7 +107,7 @@ There's a <br /> above me!
Block quotes are easy and done with the > character.
-```markdown
+```md
> This is a block quote. You can either
> manually wrap your lines and put a `>` before every line or you can let your lines get really long and wrap on their own.
> It doesn't make a difference so long as they start with a `>`.
@@ -121,7 +121,7 @@ Block quotes are easy and done with the > character.
## Lists
Unordered lists can be made using asterisks, pluses, or hyphens.
-```markdown
+```md
* Item
* Item
* Another item
@@ -141,7 +141,7 @@ or
Ordered lists are done with a number followed by a period.
-```markdown
+```md
1. Item one
2. Item two
3. Item three
@@ -150,7 +150,7 @@ Ordered lists are done with a number followed by a period.
You don't even have to label the items correctly and Markdown will still
render the numbers in order, but this may not be a good idea.
-```markdown
+```md
1. Item one
1. Item two
1. Item three
@@ -159,7 +159,7 @@ render the numbers in order, but this may not be a good idea.
You can also use sublists
-```markdown
+```md
1. Item one
2. Item two
3. Item three
@@ -170,7 +170,7 @@ You can also use sublists
There are even task lists. This creates HTML checkboxes.
-```markdown
+```md
Boxes below without the 'x' are unchecked HTML checkboxes.
- [ ] First task to complete.
- [ ] Second task that needs done
@@ -183,7 +183,7 @@ This checkbox below will be a checked HTML checkbox.
You can indicate a code block (which uses the `<code>` element) by indenting
a line with four spaces or a tab.
-```markdown
+```md
This is code
So is this
```
@@ -191,15 +191,15 @@ a line with four spaces or a tab.
You can also re-tab (or add an additional four spaces) for indentation
inside your code
-```markdown
+```md
my_array.each do |item|
puts item
end
```
-Inline code can be created using the backtick character `
+Inline code can be created using the backtick character `` ` ``
-```markdown
+```md
John didn't even know what the `go_to()` function did!
```
@@ -220,7 +220,7 @@ highlighting of the language you specify after the \`\`\`
Horizontal rules (`<hr/>`) are easily added with three or more asterisks or
hyphens, with or without spaces.
-```markdown
+```md
***
---
- - -
@@ -232,17 +232,17 @@ hyphens, with or without spaces.
One of the best things about markdown is how easy it is to make links. Put
the text to display in hard brackets [] followed by the url in parentheses ()
-```markdown
+```md
[Click me!](http://test.com/)
```
You can also add a link title using quotes inside the parentheses.
-```markdown
+```md
[Click me!](http://test.com/ "Link to Test.com")
```
Relative paths work too.
-```markdown
+```md
[Go to music](/music/).
```
@@ -269,7 +269,7 @@ But it's not that commonly used.
## Images
Images are done the same way as links but with an exclamation point in front!
-```markdown
+```md
![This is the alt-attribute for my image](http://imgur.com/myimage.jpg "An optional title")
```
@@ -281,20 +281,20 @@ And reference style works as expected.
## Miscellany
### Auto-links
-```markdown
+```md
<http://testwebsite.com/> is equivalent to
[http://testwebsite.com/](http://testwebsite.com/)
```
### Auto-links for emails
-```markdown
+```md
<foo@bar.com>
```
### Escaping characters
-```markdown
+```md
I want to type *this text surrounded by asterisks* but I don't want it to be
in italics, so I do this: \*this text surrounded by asterisks\*.
```
@@ -304,7 +304,7 @@ in italics, so I do this: \*this text surrounded by asterisks\*.
In GitHub Flavored Markdown, you can use a `<kbd>` tag to represent keyboard
keys.
-```markdown
+```md
Your computer crashed? Try sending a
<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd>
```
@@ -313,7 +313,7 @@ Your computer crashed? Try sending a
Tables are only available in GitHub Flavored Markdown and are slightly
cumbersome, but if you really want it:
-```markdown
+```md
| Col1 | Col2 | Col3 |
| :----------- | :------: | ------------: |
| Left-aligned | Centered | Right-aligned |
@@ -321,7 +321,7 @@ cumbersome, but if you really want it:
```
or, for the same results
-```markdown
+```md
Col 1 | Col2 | Col3
:-- | :-: | --:
Ugh this is so ugly | make it | stop
diff --git a/matlab.html.markdown b/matlab.html.markdown
index 86b116c6..4ca31857 100644
--- a/matlab.html.markdown
+++ b/matlab.html.markdown
@@ -221,11 +221,11 @@ A(1, :) =[] % Delete the first row of the matrix
A(:, 1) =[] % Delete the first column of the matrix
transpose(A) % Transpose the matrix, which is the same as:
-A one
-ctranspose(A) % Hermitian transpose the matrix
-% (the transpose, followed by taking complex conjugate of each element)
-A' % Concise version of complex transpose
A.' % Concise version of transpose (without taking complex conjugate)
+ctranspose(A) % Hermitian transpose the matrix, which is the same as:
+A' % Concise version of complex transpose
+ % (the transpose, followed by taking complex conjugate of each element)
+
@@ -234,7 +234,7 @@ A.' % Concise version of transpose (without taking complex conjugate)
% On their own, the arithmetic operators act on whole matrices. When preceded
% by a period, they act on each element instead. For example:
A * B % Matrix multiplication
-A .* B % Multiple each element in A by its corresponding element in B
+A .* B % Multiply each element in A by its corresponding element in B
% There are several pairs of functions, where one acts on each element, and
% the other (whose name ends in m) acts on the whole matrix.
@@ -353,7 +353,7 @@ double_input(6) % ans = 12
% anonymous function. Useful when quickly defining a function to pass to
% another function (eg. plot with fplot, evaluate an indefinite integral
% with quad, find roots with fzero, or find minimum with fminsearch).
-% Example that returns the square of it's input, assigned to the handle sqr:
+% Example that returns the square of its input, assigned to the handle sqr:
sqr = @(x) x.^2;
sqr(10) % ans = 100
doc function_handle % find out more
@@ -374,8 +374,8 @@ disp('Hello World') % Print out a string
fprintf % Print to Command Window with more control
% Conditional statements (the parentheses are optional, but good style)
-if (a > 15)
- disp('Greater than 15')
+if (a > 23)
+ disp('Greater than 23')
elseif (a == 23)
disp('a is 23')
else
@@ -545,7 +545,7 @@ ans = multiplyLatBy(a,3)
% The method can also be called using dot notation. In this case, the object
% does not need to be passed to the method.
-ans = a.multiplyLatBy(a,1/3)
+ans = a.multiplyLatBy(1/3)
% Matlab functions can be overloaded to handle objects.
% In the method above, we have overloaded how Matlab handles
diff --git a/mercurial.html.markdown b/mercurial.html.markdown
new file mode 100644
index 00000000..98658f83
--- /dev/null
+++ b/mercurial.html.markdown
@@ -0,0 +1,355 @@
+---
+category: tool
+tool: Mercurial
+contributors:
+ - ["Will L. Fife", "http://github.com/sarlalian"]
+filename: LearnMercurial.txt
+---
+
+Mercurial is a free, distributed source control management tool. It offers
+you the power to efficiently handle projects of any size while using an
+intuitive interface. It is easy to use and hard to break, making it ideal for
+anyone working with versioned files.
+
+## Versioning Concepts
+
+### What is version control?
+
+Version control is a system that keeps track fo changes to a set of file(s)
+and/or directorie(s) over time.
+
+### Why use Mercurial?
+
+* Distributed Architecture - Traditionally version control systems such as CVS
+and Subversion are a client server architecture with a central server to
+store the revsion history of a project. Mercurial however is a truly
+distributed architecture, giving each devloper a full local copy of the
+entire development history. It works independently of a central server.
+* Fast - Traditionally version control systems such as CVS and Subversion are a
+client server architecture with a central server to store the revsion history
+of a project. Mercurial however is a truly distributed architecture, giving
+each devloper a full local copy of the entire development history. It works
+independently of a central server.
+* Platform Independent - Mercurial was written to be highly platform
+independent. Much of Mercurial is written in Python, with small performance
+critical parts written in portable C. Binary releases are available for all
+major platforms.
+* Extensible - The functionality of Mercurial can be increased with extensions,
+either by activating the official ones which are shipped with Mercurial or
+downloading some [from the wiki](https://www.mercurial-scm.org/wiki/UsingExtensions) or by [writing your own](https://www.mercurial-scm.org/wiki/WritingExtensions). Extensions are written in
+Python and can change the workings of the basic commands, add new commands and
+access all the core functions of Mercurial.
+* Easy to use - The Mercurial command set is consistent with what subversion
+users would expect, so they are likely to feel right at home. Most dangerous
+actions are part of extensions that need to be enabled to be used.
+* Open Source - Mercurial is free software licensed under the terms of the [GNU
+General Public License Version 2](http://www.gnu.org/licenses/gpl-2.0.txt) or
+any later version.
+
+## Terminology
+
+| Term | Definition |
+| ------------- | ---------------------------------- |
+| Repository | A repository is a collection of revisions |
+| hgrc | A configuration file which stores the defaults for a repository. |
+| revision | A committed changeset: has a REV number |
+| changeset | Set of changes saved as diffs |
+| diff | Changes between file(s) |
+| tag | A named named revision |
+| parent(s) | Immediate ancestor(s) of a revison |
+| branch | A child of a revision |
+| head | A head is a changeset with no child changesets |
+| merge | The process of merging two HEADS |
+| tip | The latest revision in any branch |
+| patch | All of the diffs between two revisions |
+| bundle | Patch with permis­sions and rename support |
+
+## Commands
+
+### init
+
+Create a new repository in the given directory, the settings and stored
+information are in a directory named `.hg`.
+
+```bash
+$ hg init
+```
+
+### help
+
+Will give you access to a very detailed description of each command.
+
+```bash
+# Quickly check what commands are available
+$ hg help
+
+# Get help on a specific command
+# hg help <command>
+$ hg help add
+$ hg help commit
+$ hg help init
+```
+
+### status
+
+Show the differences between what is on disk and what is committed to the current
+branch or tag.
+
+```bash
+# Will display the status of files
+$ hg status
+
+# Get help on the status subcommand
+$ hg help status
+```
+
+### add
+
+Will add the specified files to the repository on the next commit.
+
+```bash
+# Add a file in the current directory
+$ hg add filename.rb
+
+# Add a file in a sub directory
+$ hg add foo/bar/filename.rb
+
+# Add files by pattern
+$ hg add *.rb
+```
+
+### branch
+
+Set or show the current branch name.
+
+*Branch names are permanent and global. Use 'hg bookmark' to create a
+light-weight bookmark instead. See 'hg help glossary' for more information
+about named branches and bookmarks.*
+
+```bash
+# With no argument it shows the current branch name
+$ hg branch
+
+# With a name argument it will change the current branch.
+$ hg branch new_branch
+marked working directory as branch new_branch
+(branches are permanent and global, did you want a bookmark?)
+```
+
+### tag
+
+Add one or more tags for the current or given revision.
+
+Tags are used to name particular revisions of the repository and are very
+useful to compare different revisions, to go back to significant earlier
+versions or to mark branch points as releases, etc. Changing an existing tag
+is normally disallowed; use -f/--force to override.
+
+```bash
+# List tags
+$ hg tags
+tip 2:efc8222cd1fb
+v1.0 0:37e9b57123b3
+
+# Create a new tag on the current revision
+$ hg tag v1.1
+
+# Create a tag on a specific revision
+$ hg tag -r efc8222cd1fb v1.1.1
+```
+
+### clone
+
+Create a copy of an existing repository in a new directory.
+
+If no destination directory name is specified, it defaults to the basename of
+the source.
+
+```bash
+# Clone a remote repo to a local directory
+$ hg clone https://some-mercurial-server.example.com/reponame
+
+# Clone a local repo to a remote server
+$ hg clone . ssh://username@some-mercurial-server.example.com/newrepo
+
+# Clone a local repo to a local repo
+$ hg clone . /tmp/some_backup_dir
+```
+
+### commit / ci
+
+Commit changes to the given files into the repository.
+
+```bash
+# Commit with a message
+$ hg commit -m 'This is a commit message'
+
+# Commit all added / removed files in the currrent tree
+$ hg commit -A 'Adding and removing all existing files in the tree'
+
+# amend the parent of the working directory with a new commit that contains the
+# changes in the parent in addition to those currently reported by 'hg status',
+$ hg commit --amend -m "Correct message"
+```
+
+### diff
+
+Show differences between revisions for the specified files using the unified
+diff format.
+
+```bash
+# Show the diff between the current directory and a previous revision
+$ hg diff -r 10
+
+# Show the diff between two previous revisions
+$ hg diff -r 30 -r 20
+```
+
+### grep
+
+Search revision history for a pattern in specified files.
+
+```bash
+# Search files for a specific phrase
+$ hg grep "TODO:"
+```
+
+### log / history
+
+Show revision history of entire repository or files. If no revision range is
+specified, the default is "tip:0" unless --follow is set, in which case the
+working directory parent is used as the starting revision.
+
+```bash
+# Show the history of the entire repository
+$ hg log
+
+# Show the history of a single file
+$ hg log myfile.rb
+
+# Show the revision changes as an ASCII art DAG with the most recent changeset
+# at the top.
+$ hg log -G
+```
+
+### merge
+
+Merge another revision into working directory.
+
+```bash
+# Merge changesets to local repository
+$ hg merge
+
+# Merge from a named branch or revision into the current local branch
+$ hg merge branchname_or_revision
+
+# After successful merge, commit the changes
+hg commit
+```
+
+### move / mv / rename
+
+Rename files; equivalent of copy + remove. Mark dest as copies of sources;
+mark sources for deletion. If dest is a directory, copies are put in that
+directory. If dest is a file, there can only be one source.
+
+```bash
+# Rename a single file
+$ hg mv foo.txt bar.txt
+
+# Rename a directory
+$ hg mv some_directory new_directory
+```
+
+### pull
+
+Pull changes from a remote repository to a local one.
+
+```bash
+# List remote paths
+$ hg paths
+remote1 = http://path/to/remote1
+remote2 = http://path/to/remote2
+
+# Pull from remote 1
+$ hg pull remote1
+
+# Pull from remote 2
+$ hg pull remote2
+```
+
+### push
+
+Push changesets from the local repository to the specified destination.
+
+```bash
+# List remote paths
+$ hg paths
+remote1 = http://path/to/remote1
+remote2 = http://path/to/remote2
+
+# Pull from remote 1
+$ hg push remote1
+
+# Pull from remote 2
+$ hg push remote2
+```
+
+### rebase
+
+Move changeset (and descendants) to a different branch.
+
+Rebase uses repeated merging to graft changesets from one part of history
+(the source) onto another (the destination). This can be useful for
+linearizing *local* changes relative to a master development tree.
+
+* Draft the commits back to the source revision.
+* -s is the source, ie. what you are rebasing.
+* -d is the destination, which is where you are sending it.
+
+```bash
+# Put the commits into draft status
+# This will draft all subsequent commits on the relevant branch
+$ hg phase --draft --force -r 1206
+
+# Rebase from from revision 102 over revision 208
+$ hg rebase -s 102 -d 208
+```
+
+### revert
+
+Restore files to their checkout state. With no revision specified, revert the
+specified files or directories to the contents they had in the parent of the
+working directory. This restores the contents of files to an unmodified state
+and unschedules adds, removes, copies, and renames. If the working directory
+has two parents, you must explicitly specify a revision.
+
+```bash
+# Reset a specific file to its checked out state
+$ hg revert oops_i_did_it_again.txt
+
+# Revert a specific file to its checked out state without leaving a .orig file
+# around
+$ hg revert -C oops_i_did_it_again.txt
+
+# Revert all changes
+$ hg revert -a
+```
+
+### rm / remove
+
+Remove the specified files on the next commit.
+
+```bash
+# Remove a spcific file
+$ hg remove go_away.txt
+
+# Remove a group of files by pattern
+$ hg remove *.txt
+```
+
+## Further information
+
+* [Learning Mercurial in Workflows](https://www.mercurial-scm.org/guide)
+* [Mercurial Quick Start](https://www.mercurial-scm.org/wiki/QuickStart)
+* [Mercurial: The Definitive Guide by Bryan O'Sullivan](http://hgbook.red-bean.com/)
diff --git a/mercury.html.markdown b/mercury.html.markdown
new file mode 100644
index 00000000..f749bac4
--- /dev/null
+++ b/mercury.html.markdown
@@ -0,0 +1,263 @@
+---
+language: mercury
+contributors:
+ - ["Julian Fondren", "https://mercury-in.space/"]
+---
+
+Mercury is a strict, pure functional/logic programming language, with
+influences from Prolog, ML, and Haskell.
+
+```prolog
+% Percent sign starts a one-line comment.
+
+ % foo(Bar, Baz)
+ %
+ % Documentation comments are indented before what they describe.
+:- pred foo(bar::in, baz::out) is det.
+
+% All toplevel syntax elements end with a '.' -- a full stop.
+
+% Mercury terminology comes from predicate logic. Very roughly:
+
+% | Mercury | C |
+% | | |
+% | Goal | statement |
+% | expression | expression |
+% | predicate rule | void function |
+% | function rule | function |
+% | head (of a rule) | function name and parameters |
+% | body (of a rule) | function body |
+% | fact | (rule without a body) |
+% | pred/func declaration | function signature |
+% | A, B (conjunction) | A && B |
+% | A ; B (disjunction) | if (A) {} else if (B) {} |
+
+% some facts:
+man(socrates). % "it is a fact that Socrates is a man"
+man(plato).
+man(aristotle).
+
+% a rule:
+mortal(X) :- man(X). % "It is a rule that X is a mortal if X is a man."
+% ^^^^^^-- the body of the rule
+% ^^-- an arrow <--, pointing to the head from the body
+%^^^^^^^^-- the head of the rule
+% this is also a single clause that defines the rule.
+
+% that X is capitalized is how you know it's a variable.
+% that socrates is uncapitalized is how you know it's a term.
+
+% it's an error for 'socrates' to be undefined. It must have a type:
+
+% declarations begin with ':-'
+:- type people
+ ---> socrates
+ ; plato
+ ; aristotle
+ ; hermes.
+ %<--first tab stop (using 4-space tabs)
+ %<--third tab stop (first after --->)
+
+:- pred man(people). % rules and facts also require types
+
+% a rule's modes tell you how it can be used.
+:- mode man(in) is semidet. % man(plato) succeeds. man(hermes) fails.
+:- mode man(out) is multi. % man(X) binds X to one of socrates ; plato ; aristotle
+
+% a semidet predicate is like a test. It doesn't return a value, but
+% it can succeed or fail, triggering backtracking or the other side of
+% a disjunction or conditional.
+
+% 'is semidet' provides the determinism of a mode. Other determinisms:
+% | Can fail? | 0 solutions | 1 | more than 1 |
+% | | | | |
+% | no | erroneous | det | multi |
+% | yes | failure | semidet | nondet |
+
+:- pred mortal(people::in) is semidet. % type/mode in one declaration
+
+% this rule's body consists of two conjunctions: A, B, C
+% this rule is true if A, B, and C are all true.
+% if age(P) returns 16, it fails.
+% if alive(P) fails, it fails.
+:- type voter(people::in) is semidet.
+voter(P) :-
+ alive(P),
+ registered(P, locale(P)),
+ age(P) >= 18. % age/1 is a function; int.>= is a function used as an operator
+
+% "a P is a voter if it is alive, is registered in P's locale, and if
+% P's age is 18 or older."
+
+% the >= used here is provided by the 'int' module, which isn't
+% imported by default. Mercury has a very small 'Prelude' (the
+% 'builtin' module). You even need to import the 'list' module if
+% you're going to use list literals.
+```
+
+Complete runnable example. File in 'types.m'; compile with 'mmc --make types'.
+
+```prolog
+:- module types.
+:- interface.
+:- import_module io. % required for io.io types in...
+% main/2 is usually 'det'. threading and exceptions require 'cc_multi'
+:- pred main(io::di, io::uo) is cc_multi. % program entry point
+:- implementation.
+:- import_module int, float, string, list, bool, map, exception.
+
+% enum.
+:- type days
+ ---> sunday
+ ; monday
+ ; tuesday
+ ; wednesday
+ ; thursday
+ ; friday
+ ; saturday.
+
+% discriminated union, like datatype in ML.
+:- type payment_method
+ ---> cash(int)
+ ; credit_card(
+ name :: string, % named fields
+ cc_number :: string,
+ cvv :: int,
+ expiration :: string
+ )
+ ; crypto(coin_type, wallet, amount).
+
+:- type coin_type
+ ---> etherium
+ ; monero. % "other coins are available"
+
+% type aliases.
+:- type wallet == string.
+:- type amount == int.
+
+% !IO is the pair of io.io arguments
+% pass it to anything doing I/O, in order to perform I/O.
+% many otherwise-impure functions can 'attach to the I/O state' by taking !IO
+main(!IO) :-
+ Ints = [
+ 3,
+ 1 + 1,
+ 8 - 1,
+ 10 * 2,
+ 35 / 5,
+ 5 / 2, % truncating division
+ int.div(5, 2), % floored division
+ div(5, 2), % (module is unambiguous due to types)
+ 5 `div` 2, % (any binary function can be an operator with ``)
+ 7 `mod` 3, % modulo of floored division
+ 7 `rem` 3, % remainder of truncating division
+ 2 `pow` 4, % 2 to the 4th power
+ (1 + 3) * 2, % parens have their usual meaning
+
+ 2 >> 3, % bitwise right shift
+ 128 << 3, % bitwise left shift
+ \ 0, % bitwise complement
+ 5 /\ 1, % bitwise and
+ 5 \/ 1, % bitwise or
+ 5 `xor` 3, % bitwise xor
+
+ max_int,
+ min_int,
+
+ 5 `min` 3, % ( if 5 > 3 then 3 else 5 )
+ 5 `max` 3
+ ],
+ Bools = [
+ yes,
+ no
+ % bools are much less important in Mercury because control flow goes by
+ % semidet goals instead of boolean expressions.
+ ],
+ Strings = [
+ "this is a string",
+ "strings can have "" embedded doublequotes via doubling",
+ "strings support \u4F60\u597D the usual escapes\n",
+ % no implicit concatenation of strings: "concat:" "together"
+ "but you can " ++ " use the string.++ operator",
+
+ % second param is a list(string.poly_type)
+ % s/1 is a function that takes a string and returns a poly_type
+ % i/1 takes an int. f/1 takes a float. c/1 takes a char.
+ string.format("Hello, %d'th %s\n", [i(45), s("World")])
+ ],
+
+ % start with purely functional types like 'map' and 'list'!
+ % arrays and hash tables are available too, but using them
+ % requires knowing a lot more about Mercury
+ get_map1(Map1),
+ get_map2(Map2),
+
+ % list.foldl has *many* variations
+ % this one calls io.print_line(X, !IO) for each X of the list
+ foldl(io.print_line, Ints, !IO),
+ foldl(io.print_line, Bools, !IO),
+ foldl(io.print_line, Strings, !IO),
+ io.print_line(Map1, !IO),
+ % ( if Cond then ThenGoal else ElseGoal )
+ % I/O not allowed in Cond: I/O isn't allowed to fail!
+ ( if Map2^elem(42) = Elem then
+ io.print_line(Elem, !IO)
+ else % always required
+ true % do nothing, successfully (vs. 'fail')
+ ),
+
+ % exception handling:
+ ( try [io(!IO)] ( % io/1 param required or no I/O allowed here
+ io.print_line(received(cash(1234)), !IO),
+ io.print_line(received(crypto(monero, "invalid", 123)), !IO)
+ ) then
+ io.write_string("all payments accepted\n", !IO) % never reached
+ catch "monero not yet supported" -> % extremely specific catch!
+ io.write_string("monero payment failed\n", !IO)
+ ).
+
+:- pred get_map1(map(string, int)::out) is det.
+get_map1(!:Map) :- % !:Map in the head is the final (free, unbound) Map
+ !:Map = init, % !:Map in the body is the next Map
+ det_insert("hello", 1, !Map), % pair of Map vars
+ det_insert("world", 2, !Map),
+
+ % debug print of current (bound) Map
+ % other [Params] can make it optional per runtime or compiletime flags
+ trace [io(!IO)] (io.print_line(!.Map, !IO)),
+
+ det_insert_from_corresponding_lists(K, V, !Map),
+ % this code is reordered so that K and V and defined prior to their use
+ K = ["more", "words", "here"],
+ V = [3, 4, 5].
+
+:- pred get_map2(map(int, bool)::out) is det.
+get_map2(Map) :-
+ det_insert(42, yes, map.init, Map).
+
+:- func received(payment_method) = string.
+received(cash(N)) = string.format("received %d dollars", [i(N)]).
+received(credit_card(_, _, _, _)) = "received credit card". % _ is throwaway
+received(crypto(Type, _Wallet, Amount)) = S :- % _Wallet is named throwaway
+ ( % case/switch structure
+ Type = etherium,
+ S = string.format("receiving %d ETH", [i(Amount)])
+ ;
+ Type = monero,
+ throw("monero not yet supported") % exception with string as payload
+ ).
+```
+
+## That was quick! Want more?
+
+### More Tutorials
+
+* [Mercury Tutorial](https://mercurylang.org/documentation/papers/book.pdf) (pdf link) - a more traditional tutorial with a more relaxed pace
+* [Mercury Crash Course](https://mercury-in.space/crash.html) - a dense example-driven tutorial with Q&A format
+* [Github Wiki Tutorial](https://github.com/Mercury-Language/mercury/wiki/Tutorial)
+* [Getting Started with Mercury](https://bluishcoder.co.nz/2019/06/23/getting-started-with-mercury.html) - installation and your first steps
+
+### Documentation
+
+* Language manual, user's guide, and library reference are all at
+ [mercurylang.org](https://mercurylang.org/documentation/documentation.html)
diff --git a/meteor.html.markdown b/meteor.html.markdown
deleted file mode 100644
index 1685e0be..00000000
--- a/meteor.html.markdown
+++ /dev/null
@@ -1,567 +0,0 @@
----
-category: tool
-tool: meteor.js
-Filename: meteor.html.markdown
-contributors:
- - ["Mohammed Rafy", "https://github.com/IamRafy/"]
----
-
-
-
-Meteor is an ultra-simple environment for building modern websites. What once took weeks, even with the best tools, now takes hours with Meteor.
-
-The web was originally designed to work in the same way that mainframes worked in the 70s. The application server rendered a screen and sent it over the network to a dumb terminal. Whenever the user did anything, that server rerendered a whole new screen. This model served the Web well for over a decade. It gave rise to LAMP, Rails, Django, PHP.
-
-But the best teams, with the biggest budgets and the longest schedules, now build applications in JavaScript that run on the client. These apps have stellar interfaces. They don't reload pages. They are reactive: changes from any client immediately appear on everyone's screen.
-
-They've built them the hard way. Meteor makes it an order of magnitude simpler, and a lot more fun. You can build a complete application in a weekend, or a sufficiently caffeinated hackathon. No longer do you need to provision server resources, or deploy API endpoints in the cloud, or manage a database, or wrangle an ORM layer, or swap back and forth between JavaScript and Ruby, or broadcast data invalidations to clients.
-Meteor Supports OS X, Windows, and Linux. // https://github.com/meteor/meteor/wiki/Supported-Platforms
-On Windows? https://install.meteor.com/windows
-On OS X or Linux? Install the latest official Meteor release from your terminal:
-$ curl https://install.meteor.com/ | sh
-The Windows installer supports Windows 7, Windows 8.1, Windows Server 2008, and Windows Server 2012. The command line installer supports Mac OS X 10.7 (Lion) and above, and Linux on x86 and x86_64 architectures.
-
-Once you've installed Meteor, create a project:
-meteor create myapp
-Run it locally:
-
-cd myapp
-meteor
-# Meteor server running on: http://localhost:3000/
-
-Then, open a new terminal tab and unleash it on the world (on a free server we provide):
-
-meteor deploy myapp.meteor.com
-
-Principles of Meteor
-
-* Data on the Wire. Meteor doesn't send HTML over the network. The server sends data and lets the client render it.
-
-* One Language. Meteor lets you write both the client and the server parts of your application in JavaScript.
-
-* Database Everywhere. You can use the same methods to access your database from the client or the server.
-
-* Latency Compensation. On the client, Meteor prefetches data and simulates models to make it look like server method calls return instantly.
-
-* Full Stack Reactivity. In Meteor, realtime is the default. All layers, from database to template, update themselves automatically when necessary.
-
-* Embrace the Ecosystem. Meteor is open source and integrates with existing open source tools and frameworks.
-
-* Simplicity Equals Productivity. The best way to make something seem simple is to have it actually be simple. Meteor's main functionality has clean, classically beautiful APIs.
-
-Developer Resources
--------------------
-
-If anything in Meteor catches your interest, we hope you'll get involved with the project!
-
-TUTORIAL
-Get started fast with the official Meteor tutorial! https://www.meteor.com/install
-
-STACK OVERFLOW
-The best place to ask (and answer!) technical questions is on Stack Overflow. Be sure to add the meteor tag to your question.
-http://stackoverflow.com/questions/tagged/meteor
-
-FORUMS
-Visit the Meteor discussion forumsto announce projects, get help, talk about the community, or discuss changes to core.
-https://forums.meteor.com/
-
-GITHUB
-The core code is on GitHub. If you're able to write code or file issues, we'd love to have your help. Please read Contributing to Meteor for how to get started. https://github.com/meteor/meteor
-
-THE METEOR MANUAL
-In-depth articles about the core components of Meteor can be found on the Meteor Manual. The first article is about Tracker, our transparent reactivity framework. More articles (covering topics like Blaze, Unibuild, and DDP) are coming soon! http://manual.meteor.com/
-
-What is Meteor?
----------------
-
-Meteor is two things:
-
-A library of packages: pre-written, self-contained modules that you might need in your app.
-
-There are about a dozen core Meteor packages that most any app will use. Two examples: webapp, which handles incoming HTTP connections, and templating, which lets you make HTML templates that automatically update live as data changes. Then there are optional packages like email, which lets your app send emails, or the Meteor Accounts series (accounts-password, accounts-facebook, accounts-ui, and others) which provide a full-featured user account system that you can drop right into your app. In addition to these "core" packages, there are thousands of community-written packages in Atmosphere, one of which might do just what you need.
-
-A command-line tool called meteor.
-
-meteor is a build tool analogous to make, rake, or the non-visual parts of Visual Studio. It gathers up all of the source files and assets in your application, carries out any necessary build steps (such as compiling CoffeeScript, minifying CSS, building npm modules, or generating source maps), fetches the packages used by your app, and outputs a standalone, ready-to-run application bundle. In development mode it can do all of this interactively, so that whenever you change a file you immediately see the changes in your browser. It's super easy to use out of the box, but it's also extensible: you can add support for new languages and compilers by adding build plugin packages to your app.
-
-The key idea in the Meteor package system is that everything should work identically in the browser and on the server (wherever it makes sense, of course: browsers can't send email and servers can't capture mouse events). Our whole ecosystem has been built from the ground up to support this.
-
-Structuring your application
-----------------------------
-
-A Meteor application is a mix of client-side JavaScript that runs inside a web browser or PhoneGap mobile app, server-side JavaScript that runs on the Meteor server inside a Node.js container, and all the supporting HTML templates, CSS rules, and static assets. Meteor automates the packaging and transmission of these different components, and it is quite flexible about how you choose to structure those components in your file tree.
-
-Special Directories
--------------------
-
-By default, any JavaScript files in your Meteor folder are bundled and sent to the client and the server. However, the names of the files and directories inside your project can affect their load order, where they are loaded, and some other characteristics. Here is a list of file and directory names that are treated specially by Meteor:
-
-client
-
-Any directory named client is not loaded on the server. Similar to wrapping your code in if (Meteor.isClient) { ... }. All files loaded on the client are automatically concatenated and minified when in production mode. In development mode, JavaScript and CSS files are not minified, to make debugging easier. (CSS files are still combined into a single file for consistency between production and development, because changing the CSS file's URL affects how URLs in it are processed.)
-
-HTML files in a Meteor application are treated quite a bit differently from a server-side framework. Meteor scans all the HTML files in your directory for three top-level elements: <head>, <body>, and <template>. The head and body sections are separately concatenated into a single head and body, which are transmitted to the client on initial page load.
-
-server
-Any directory named server is not loaded on the client. Similar to wrapping your code in if (Meteor.isServer) { ... }, except the client never even receives the code. Any sensitive code that you don't want served to the client, such as code containing passwords or authentication mechanisms, should be kept in the server directory.
-
-Meteor gathers all your JavaScript files, excluding anything under the client, public, and private subdirectories, and loads them into a Node.js server instance. In Meteor, your server code runs in a single thread per request, not in the asynchronous callback style typical of Node. We find the linear execution model a better fit for the typical server code in a Meteor application.
-
-public
-
-All files inside a top-level directory called public are served as-is to the client. When referencing these assets, do not include public/ in the URL, write the URL as if they were all in the top level. For example, reference public/bg.png as <img src='/bg.png' />. This is the best place for favicon.ico, robots.txt, and similar files.
-
-private
-
-All files inside a top-level directory called private are only accessible from server code and can be loaded via the Assets API. This can be used for private data files and any files that are in your project directory that you don't want to be accessible from the outside.
-
-client/compatibility
-
-This folder is for compatibility JavaScript libraries that rely on variables declared with var at the top level being exported as globals. Files in this directory are executed without being wrapped in a new variable scope. These files are executed before other client-side JavaScript files.
-tests
-
-Any directory named tests is not loaded anywhere. Use this for any local test code.
-
-node_modules
-
-For compatibility with node.js tools used alongside Meteor, any directory named node_modules is not loaded anywhere. node.js packages installed into node_modules directories will not be available to your Meteor code. Use Npm.depends in your package package.js file for that.
-
-Files outside special directories
----------------------------------
-
-All JavaScript files outside special directories are loaded on both the client and the server. That's the place for model definitions and other functions. Meteor provides the variables Meteor.isClient and Meteor.isServer (http://docs.meteor.com/#/full/meteor_isserver)so that your code can alter its behavior depending on whether it's running on the client or the server.
-
-CSS and HTML files outside special directories are loaded on the client only, and cannot be used from server code.
-
-Example File Structure
-
-The file structure of your Meteor app is very flexible. Here is an example layout that takes advantage of some of the special folders mentioned above.
-
-lib/ # common code like collections and utilities
-lib/methods.js # Meteor.methods definitions
-lib/constants.js # constants used in the rest of the code
-
-client/compatibility # legacy libraries that expect to be global
-client/lib/ # code for the client to be loaded first
-client/lib/helpers.js # useful helpers for your client code
-client/body.html # content that goes in the <body> of your HTML
-client/head.html # content for <head> of your HTML: <meta> tags, etc
-client/style.css # some CSS code
-client/<feature>.html # HTML templates related to a certain feature
-client/<feature>.js # JavaScript code related to a certain feature
-
-server/lib/permissions.js # sensitive permissions code used by your server
-server/publications.js # Meteor.publish definitions
-
-public/favicon.ico # app icon
-settings.json # configuration data to be passed to meteor --settings
-mobile-config.js # define icons and metadata for Android/iOS
-
-You can also model your directory structure after the example apps. Run meteor create --example todos and explore the directories to see where all the files in a real app could go.
-
-File Load Order
----------------
-
-It is best to write your application in such a way that it is insensitive to the order in which files are loaded, for example by using Meteor.startup (http://docs.meteor.com/#/full/meteor_startup) , or by moving load order sensitive code into packages (http://docs.meteor.com/#/full/usingpackages) , which can explicitly control both the load order of their contents and their load order with respect to other packages. However, sometimes load order dependencies in your application are unavoidable.
-
-There are several load ordering rules. They are applied sequentially to all applicable files in the application, in the priority given below:
-
-HTML template files are always loaded before everything else
-Files beginning with main. are loaded last
-Files inside any lib/ directory are loaded next
-Files with deeper paths are loaded next
-Files are then loaded in alphabetical order of the entire path
-nav.html
-main.html
-client/lib/methods.js
-client/lib/styles.js
-lib/feature/styles.js
-lib/collections.js
-client/feature-y.js
-feature-x.js
-client/main.js
-For example, the files above are arranged in the correct load order. main.html is loaded second because HTML templates are always loaded first, even if it begins with main., since rule 1 has priority over rule 2. However, it will be loaded after nav.html because rule 2 has priority over rule 5.
-
-client/lib/styles.js and lib/feature/styles.js have identical load order up to rule 4; however, since client comes before lib alphabetically, it will be loaded first.
-
-Organizing Your Project
------------------------
-
-There are three main ways to organize your files into features or components. Let's say we have two types of objects in our project: apples and oranges.
-
-Method 1: Root-Level Folders
-Since the special client, server, and lib directories work if they are anywhere in the path, you can use top-level folders to organize code into modules:
-
-apples/lib/ # code for apple-related features
-apples/client/
-apples/server/
-
-oranges/lib/ # code for orange-related features
-oranges/client/
-oranges/server/
-
-Method 2: Folders inside client/ and server/
-
-lib/apples/ # common code for apples
-lib/oranges/ # and oranges
-
-client/apples/ # client code for apples
-client/oranges/ # and oranges
-
-server/apples/ # server code for apples
-server/oranges/ # and oranges
-
-Method 3: Packages
-
-This is the ultimate in code separation, modularity, and reusability. If you put the code for each feature in a separate package, the code for one feature won't be able to access the code for the other feature except through exports, making every dependency explicit. This also allows for the easiest independent testing of features. You can also publish the packages and use them in multiple apps with meteor add.
-
-packages/apples/package.js # files, dependencies, exports for apple feature
-packages/apples/<anything>.js # file loading is controlled by package.js
-
-packages/oranges/package.js # files, dependencies, exports for orange feature
-packages/oranges/<anything>.js # file loading is controlled by package.js
-
-Data and security
------------------
-
-Meteor makes writing distributed client code as simple as talking to a local database. It's a clean, simple, and secure approach that removes the need to implement individual RPC endpoints, manually cache data on the client to avoid slow roundtrips to the server, and carefully orchestrate invalidation messages to every client as data changes.
-
-In Meteor, the client and server share the same database API. The same exact application code — like validators and computed properties — can often run in both places. But while code running on the server has direct access to the database, code running on the client does not. This distinction is the basis for Meteor's data security model.
-
-By default, a new Meteor app includes the autopublish and insecure packages, which together mimic the effect of each client having full read/write access to the server's database. These are useful prototyping tools, but typically not appropriate for production applications. When you're ready, just remove the packages.
-
-Every Meteor client includes an in-memory database cache. To manage the client cache, the server publishes sets of JSON documents, and the client subscribes to those sets. As documents in a set change, the server patches each client's cache.
-
-Today most Meteor apps use MongoDB as their database because it is the best supported, though support for other databases is coming in the future. The Mongo.Collection class is used to declare Mongo collections and to manipulate them. Thanks to minimongo, Meteor's client-side Mongo emulator, Mongo.Collection can be used from both client and server code.
-
-// declare collections
-// this code should be included in both the client and the server
-Rooms = new Mongo.Collection("rooms");
-Messages = new Mongo.Collection("messages");
-Parties = new Mongo.Collection("parties");
-
-// server: populate collections with some initial documents
-Rooms.insert({name: "Conference Room A"});
-var myRooms = Rooms.find({}).fetch();
-Messages.insert({text: "Hello world", room: myRooms[0]._id});
-Parties.insert({name: "Super Bowl Party"});
-Each document set is defined by a publish function on the server. The publish function runs each time a new client subscribes to a document set. The data in a document set can come from anywhere, but the common case is to publish a database query.
-
-// server: publish all room documents
-Meteor.publish("all-rooms", function () {
- return Rooms.find(); // everything
-});
-
-// server: publish all messages for a given room
-Meteor.publish("messages", function (roomId) {
- check(roomId, String);
- return Messages.find({room: roomId});
-});
-
-// server: publish the set of parties the logged-in user can see.
-Meteor.publish("parties", function () {
- return Parties.find({$or: [{"public": true},
- {invited: this.userId},
- {owner: this.userId}]});
-});
-Publish functions can provide different results to each client. In the last example, a logged in user can only see Party documents that are public, that the user owns, or that the user has been invited to.
-
-Once subscribed, the client uses its cache as a fast local database, dramatically simplifying client code. Reads never require a costly round trip to the server. And they're limited to the contents of the cache: a query for every document in a collection on a client will only return documents the server is publishing to that client.
-
-// client: start a parties subscription
-Meteor.subscribe("parties");
-
-// client: return array of Parties this client can read
-return Parties.find().fetch(); // synchronous!
-Sophisticated clients can turn subscriptions on and off to control how much data is kept in the cache and manage network traffic. When a subscription is turned off, all its documents are removed from the cache unless the same document is also provided by another active subscription.
-
-When the client changes one or more documents, it sends a message to the server requesting the change. The server checks the proposed change against a set of allow/deny rules you write as JavaScript functions. The server only accepts the change if all the rules pass.
-
-// server: don't allow client to insert a party
-Parties.allow({
- insert: function (userId, party) {
- return false;
- }
-});
-
-// client: this will fail
-var party = { ... };
-Parties.insert(party);
-If the server accepts the change, it applies the change to the database and automatically propagates the change to other clients subscribed to the affected documents. If not, the update fails, the server's database remains untouched, and no other client sees the update.
-
-Meteor has a cute trick, though. When a client issues a write to the server, it also updates its local cache immediately, without waiting for the server's response. This means the screen will redraw right away. If the server accepted the update — what ought to happen most of the time in a properly behaving client — then the client got a jump on the change and didn't have to wait for the round trip to update its own screen. If the server rejects the change, Meteor patches up the client's cache with the server's result.
-
-Putting it all together, these techniques accomplish latency compensation. Clients hold a fresh copy of the data they need, and never need to wait for a roundtrip to the server. And when clients modify data, those modifications can run locally without waiting for the confirmation from the server, while still giving the server final say over the requested change.
-
-The current release of Meteor supports MongoDB, the popular document database, and the examples in this section use the MongoDB API. Future releases will include support for other databases.
-
-Authentication and user accounts
---------------------------------
-
-Meteor includes Meteor Accounts, a state-of-the-art authentication system. It features secure password login using the bcrypt algorithm, and integration with external services including Facebook, GitHub, Google, Meetup, Twitter, and Weibo. Meteor Accounts defines a Meteor.users collection where developers can store application-specific user data.
-
-Meteor also includes pre-built forms for common tasks like login, signup, password change, and password reset emails. You can add Accounts UI to your app with just one line of code. The accounts-ui package even provides a configuration wizard that walks you through the steps to set up the external login services you're using in your app.
-
-Input validation
-----------------
-
-Meteor allows your methods and publish functions to take arguments of any JSON type. (In fact, Meteor's wire protocol supports EJSON, an extension of JSON which also supports other common types like dates and binary buffers.) JavaScript's dynamic typing means you don't need to declare precise types of every variable in your app, but it's usually helpful to ensure that the arguments that clients are passing to your methods and publish functions are of the type that you expect.
-
-Meteor provides a lightweight library for checking that arguments and other values are the type you expect them to be. Simply start your functions with statements like check(username, String) or check(office, {building: String, room: Number}). The check call will throw an error if its argument is of an unexpected type.
-
-Meteor also provides an easy way to make sure that all of your methods and publish functions validate all of their arguments. Just run meteor add audit-argument-checks and any method or publish function which skips checking any of its arguments will fail with an exception.
-
-Reactivity
-----------
-
-Meteor embraces the concept of reactive programming (https://en.wikipedia.org/wiki/Reactive_programming). This means that you can write your code in a simple imperative style, and the result will be automatically recalculated whenever data changes that your code depends on.
-
-Tracker.autorun(function () {
- Meteor.subscribe("messages", Session.get("currentRoomId"));
-});
-This example (taken from a chat room client) sets up a data subscription based on the session variable currentRoomId. If the value of Session.get("currentRoomId") changes for any reason, the function will be automatically re-run, setting up a new subscription that replaces the old one.
-
-This automatic recomputation is achieved by a cooperation between Session and Tracker.autorun. Tracker.autorun performs an arbitrary "reactive computation" inside of which data dependencies are tracked, and it will re-run its function argument as necessary. Data providers like Session, on the other hand, make note of the computation they are called from and what data was requested, and they are prepared to send an invalidation signal to the computation when the data changes.
-
-This simple pattern (reactive computation + reactive data source) has wide applicability. Above, the programmer is saved from writing unsubscribe/resubscribe calls and making sure they are called at the right time. In general, Meteor can eliminate whole classes of data propagation code which would otherwise clog up your application with error-prone logic.
-
-These Meteor functions run your code as a reactive computation:
-
-Templates
-Tracker.autorun
-Template.autorun
-Blaze.render and Blaze.renderWithData
-And the reactive data sources that can trigger changes are:
-
-Session variables
-Database queries on Collections
-Meteor.status
-The ready() method on a subscription handle
-Meteor.user
-Meteor.userId
-Meteor.loggingIn
-In addition, the following functions which return an object with a stop method, if called from a reactive computation, are stopped when the computation is rerun or stopped:
-
-Tracker.autorun (nested)
-Meteor.subscribe
-observe() and observeChanges() on cursors
-Meteor's implementation is a package called Tracker that is fairly short and straightforward. You can use it yourself to implement new reactive data sources.
-
-Live HTML templates
--------------------
-
-HTML templating is central to web applications. With Blaze, Meteor's live page update technology, you can render your HTML reactively, meaning that it will update automatically to track changes in the data used to generate it.
-
-Meteor makes it easy to use your favorite HTML templating language along with Meteor's live page update technology. Just write your template as you normally would, and Meteor will take care of making it update in realtime.
-
-Meteor ships with a templating language called Spacebars (https://github.com/meteor/meteor/blob/master/packages/spacebars/README.md), inspired by Handlebars (http://handlebarsjs.com/). It shares some of the spirit and syntax of Handlebars, but it has been tailored to produce reactive Meteor templates when compiled.
-
-Today, the only templating system that ships with Meteor is Spacebars, though our community has created packages for other languages such as Jade.
-
-To define templates, create a file in your project with the .html extension. In the file, make a <template> tag and give it a name attribute. Put the template contents inside the tag. Meteor will precompile the template, ship it down to the client, and make it available as on the global Template object.
-
-When your app is loaded, it automatically renders the special template called <body>, which is written using the <body> element instead of a <template>. You insert a template inside another template by using the {{> inclusion}} operator.
-
-The easiest way to get data into templates is by defining helper functions in JavaScript. Define helpers with the Template.templateName.helpers({ ... }) function. Putting it all together:
-
-<!-- in myapp.html -->
-<body>
- <h1>Today's weather!</h1>
- {{> forecast}}
-</body>
-
-<template name="forecast">
- <div>It'll be {{prediction}} tonight</div>
-</template>
-// in client/myapp.js: reactive helper function
-Template.forecast.helpers({
- prediction: function () {
- return Session.get("weather");
- }
-});
-// in the JavaScript console
-> Session.set("weather", "cloudy");
-> document.body.innerHTML
- => "<h1>Today's weather!</h1> <div>It'll be cloudy tonight</div>"
-
-> Session.set("weather", "cool and dry");
-> document.body.innerHTML
- => "<h1>Today's weather!</h1> <div>It'll be cool and dry tonight</div>"
-To iterate over an array or database cursor, use {{#each}}:
-
-<!-- in myapp.html -->
-<template name="players">
- {{#each topScorers}}
- <div>{{name}}</div>
- {{/each}}
-</template>
-// in myapp.js
-Template.players.helpers({
- topScorers: function () {
- return Users.find({score: {$gt: 100}}, {sort: {score: -1}});
- }
-});
-In this case, the data is coming from a database query. When the database cursor is passed to {{#each}}, it will wire up all of the machinery to efficiently add and move DOM nodes as new results enter the query.
-
-Helpers can take arguments, and they receive the current template context data in this. Note that some block helpers change the current context (notably {{#each}} and {{#with}}):
-
-// in a JavaScript file
-Template.players.helpers({
- leagueIs: function (league) {
- return this.league === league;
- }
-});
-<!-- in a HTML file -->
-<template name="players">
- {{#each topScorers}}
- {{#if leagueIs "junior"}}
- <div>Junior: {{name}}</div>
- {{/if}}
- {{#if leagueIs "senior"}}
- <div>Senior: {{name}}</div>
- {{/if}}
- {{/each}}
-</template>
-Helpers can also be used to pass in constant data.
-
-// Works fine with {{#each sections}}
-Template.report.helpers({
- sections: ["Situation", "Complication", "Resolution"]
-});
-Finally, you can use the events function on a template to attach event handlers. The object passed into events is documented at Event Maps. The this argument to the event handler will be the data context of the element that triggered the event.
-
-<!-- myapp.html -->
-<template name="scores">
- {{#each player}}
- {{> playerScore}}
- {{/each}}
-</template>
-
-<template name="playerScore">
- <div>{{name}}: {{score}}
- <span class="give-points">Give points</span>
- </div>
-</template>
-// myapp.js
-Template.playerScore.events({
- 'click .give-points': function () {
- Users.update(this._id, {$inc: {score: 2}});
- }
-});
-For more details about Spacebars, read the Spacebars README. (https://github.com/meteor/meteor/blob/master/packages/spacebars/README.md)
-
-Using packages
---------------
-
-All of the functionality you've read about so far is implemented in standard Meteor packages. This is possible thanks to Meteor's unusually powerful isomorphic package and build system. Isomorphic means the same packages work in the web browser, in mobile apps, and on the server. Packages can also contain plugins that extend the build process, such as coffeescript (CoffeeScript compilation : http://coffeescript.org/) or templating (compiling HTML templates).
-
-Anyone can publish a Meteor package, and thousands of community-written packages have been published to date. The easiest way to browse these packages is Atmosphere, by Percolate Studio. You can also use the meteor search and meteor show commands.
-
-You can add packages to your project with meteor add and remove them with meteor remove. Additionally, meteor list will tell you what packages your project is using, and meteor update will update them to the newest versions when possible.
-
-By default all apps include the meteor-base package. This pulls in the packages that make up the core of the Meteor stack. Most apps will have this package.
-
-All new apps also start with a set of packages that allow a friendly development experience. For more information about these packages, check out the comments in the packages file.
-
-Meteor uses a single-loading packaging system, meaning that it loads just one version of every package. Before adding or upgrading to a particular version of a package, Meteor uses a constraint solver to check if doing so will cause other packages to break. By default, Meteor will choose conservatively. When adding transitive dependencies (packages that other packages, but not the application itself) depend on, Meteor will try to choose the earlier version.
-
-In addition to the packages in the official Meteor release being used by your app, meteor list and meteor add also search the packages directory at the top of your app. You can also use the packages directory to break your app into subpackages for your convenience, or to test packages that you might want to publish. See Writing Packages (http://docs.meteor.com/#/full/writingpackages) . If you wish to add packages outside of your app's folder structure, set the environment variable PACKAGE_DIRS to a colon-delimited list of paths.
-
-Namespacing
------------
-
-Meteor's namespacing support makes it easy to write large applications in JavaScript. Each package that you use in your app exists in its own separate namespace, meaning that it sees only its own global variables and any variables provided by the packages that it specifically uses. Here's how it works.
-
-When you declare a top-level variable, you have a choice. You can make the variable File Scope or Package Scope.
-
-// File Scope. This variable will be visible only inside this
-// one file. Other files in this app or package won't see it.
-var alicePerson = {name: "alice"};
-
-// Package Scope. This variable is visible to every file inside
-// of this package or app. The difference is that 'var' is
-// omitted.
-bobPerson = {name: "bob"};
-Notice that this is just the normal JavaScript syntax for declaring a variable that is local or global. Meteor scans your source code for global variable assignments and generates a wrapper that makes sure that your globals don't escape their appropriate namespace.
-
-In addition to File Scope and Package Scope, there are also Exports. An export is a variable that a package makes available to you when you use it. For example, the email package exports the Email variable. If your app uses the email package (and only if it uses the email package!) then your app can see Email and you can call Email.send. Most packages have only one export, but some packages might have two or three (for example, a package that provides several classes that work together).
-
-You see only the exports of the packages that you use directly. If you use package A, and package A uses package B, then you only see package A's exports. Package B's exports don't "leak" into your namespace just because you used package A. This keeps each namespace nice and tidy. Each app or package only sees their own globals plus the APIs of the packages that they specifically asked for.
-
-When debugging your app, your browser's JavaScript console behaves as if it were attached to your app's namespace. You see your app's globals and the exports of the packages that your app uses directly. You don't see the variables from inside those packages, and you don't see the exports of your transitive dependencies (packages that aren't used directly by your app, but that are used by packages that are used by your app).
-
-If you want to look inside packages from inside your in-browser debugger, you've got two options:
-
-Set a breakpoint inside package code. While stopped on that breakpoint, the console will be in the package's namespace. You'll see the package's package-scope variables, imports, and also any file-scope variables for the file you're stopped in.
-
-If a package foo is included in your app, regardless of whether your app uses it directly, its exports are available in Package.foo. For example, if the email package is loaded, then you can access Package.email.Email.send even from namespaces that don't use the email package directly.
-
-When declaring functions, keep in mind that function x () {} is just shorthand for var x = function x () {} in JavaScript. Consider these examples:
-
-// This is the same as 'var x = function x () ...'. So x() is
-// file-scope and can be called only from within this one file.
-function x () { ... }
-
-// No 'var', so x() is package-scope and can be called from
-// any file inside this app or package.
-x = function () { ... }
-Technically speaking, globals in an app (as opposed to in a package) are actually true globals. They can't be captured in a scope that is private to the app code, because that would mean that they wouldn't be visible in the console during debugging! This means that app globals actually end up being visible in packages. That should never be a problem for properly written package code (since the app globals will still be properly shadowed by declarations in the packages). You certainly shouldn't depend on this quirk, and in the future Meteor may check for it and throw an error if you do.
-
-Deploying
----------
-
-Meteor is a full application server. We include everything you need to deploy your application on the internet: you just provide the JavaScript, HTML, and CSS.
-
-Running on Meteor's infrastructure
-----------------------------------
-
-The easiest way to deploy your application is to use meteor
-deploy. We provide it because it's what, personally, we've always wanted: an easy way to take an app idea, flesh it out over a weekend, and put it out there for the world to use, with nothing getting in the way of creativity.
-
-meteor deploy myapp.meteor.com
-Your application is now available at myapp.meteor.com. If this is the first time deploying to this hostname, Meteor creates a fresh empty database for your application. If you want to deploy an update, Meteor will preserve the existing data and just refresh the code.
-
-You can also deploy to your own domain. Just set up the hostname you want to use as a CNAME to origin.meteor.com, then deploy to that name.
-
-meteor deploy www.myapp.com
-We provide this as a free service so you can try Meteor. It is also helpful for quickly putting up internal betas, demos, and so on. For more information, see meteor deploy.
-
-Running on your own infrastructure
-----------------------------------
-
-You can also run your application on your own infrastructure or any hosting provider that can run Node.js apps.
-
-To get started, run
-
-meteor build my_directory
-This command will generate a fully-contained Node.js application in the form of a tarball. To run this application, you need to provide Node.js 0.10 and a MongoDB server. (The current release of Meteor has been tested with Node 0.10.40.) You can then run the application by invoking node, specifying the HTTP port for the application to listen on, and the MongoDB endpoint.
-
-cd my_directory
-(cd programs/server && npm install)
-env PORT=3000 MONGO_URL=mongodb://localhost:27017/myapp node main.js
-Some packages might require other environment variables. For example, the email package requires a MAIL_URL environment variable.
-
-Writing packages
-----------------
-
-Writing Meteor packages is easy. To initialize a meteor package, run meteor create --package username:packagename, where username is your Meteor Developer username. This will create a package from scratch and prefill the directory with a package.js control file and some javascript. By default, Meteor will take the package name from the name of the directory that contains the package.js file. Don't forget to run meteor add [packagename], even if the package is internal to the app, in order to use it.
-
-Meteor promises repeatable builds for both packages and applications. This means that, if you built your package on a machine, then checked the code into a repository and checked it out elsewhere, you should get the same result. In your package directory, you will find an automatically generated .versions file. This file specifies the versions of all packages used to build your package and is part of the source. Check it into version control to ensure repeatable builds across machines.
-
-Sometimes, packages do not just stand on their own, but function in the context of an app (specifically, packages in the packages directory of an app). In that case, the app's context will take precedence. Rather than using the .versions file as a guide, we will build the package with the same dependencies as used by the app (we think that, in practice, it would be confusing to find your local packages built with different versions of things).
-
-Meteor uses extended semver versioning for its packages: that means that the version number has three parts separated by dots: major version, minor version and patch version (for example: 1.2.3) with an optional pre-release version. You can read more about it on semver.org. Additionally, because some meteor packages wrap external libraries, Meteor supports the convention of using _ to denote a wrap number.
-
-You can read more about package.js (http://docs.meteor.com/#/full/packagejs) files in the API section.
-
-A word on testing: since testing is an important part of the development process, there are two common ways to test a package:
-
-Integration tests (putting a package directly into an application, and writing tests against the application) is the most common way to test a package. After creating your package, add it to your app's /packages directory and run meteor add. This will add your package to your app as a local package. You can then test and run your app as usual. Meteor will detect and respond to changes to your local package, just as it does to your app files.
-
-Unit tests are run with the command meteor test-packages package-name. As described in the package.js section, you can use the package.js file to specify where your unit tests are located. If you have a repository that contains only the package source, you can test your package by specifying the path to the package directory (which must contain a slash), such as meteor test-packages ./.
-
-To publish a package, run meteor publish from the package directory. There are some extra restrictions on published packages: they must contain a version (Meteor packages are versioned using strict semver versioning) and their names must be prefixed with the username of the author and a colon, like so: iron:router. This namespacing allows for more descriptive and on-topic package names.
-
-
-
-
diff --git a/mips.html.markdown b/mips.html.markdown
new file mode 100644
index 00000000..33d4f87c
--- /dev/null
+++ b/mips.html.markdown
@@ -0,0 +1,377 @@
+---
+language: "MIPS Assembly"
+filename: MIPS.asm
+contributors:
+ - ["Stanley Lim", "https://github.com/Spiderpig86"]
+---
+
+The MIPS (Microprocessor without Interlocked Pipeline Stages) Assembly language
+is designed to work with the MIPS microprocessor paradigm designed by J. L.
+Hennessy in 1981. These RISC processors are used in embedded systems such as
+gateways and routers.
+
+[Read More](https://en.wikipedia.org/wiki/MIPS_architecture)
+
+```asm
+# Comments are denoted with a '#'
+
+# Everything that occurs after a '#' will be ignored by the assembler's lexer.
+
+# Programs typically contain a .data and .text sections
+
+.data # Section where data is stored in memory (allocated in RAM), similar to
+ # variables in higher-level languages
+
+ # Declarations follow a ( label: .type value(s) ) form of declaration
+ hello_world: .asciiz "Hello World\n" # Declare a null terminated string
+ num1: .word 42 # Integers are referred to as words
+ # (32-bit value)
+
+ arr1: .word 1, 2, 3, 4, 5 # Array of words
+ arr2: .byte 'a', 'b' # Array of chars (1 byte each)
+ buffer: .space 60 # Allocates space in the RAM
+ # (not cleared to 0)
+
+ # Datatype sizes
+ _byte: .byte 'a' # 1 byte
+ _halfword: .half 53 # 2 bytes
+ _word: .word 3 # 4 bytes
+ _float: .float 3.14 # 4 bytes
+ _double: .double 7.0 # 8 bytes
+
+ .align 2 # Memory alignment of data, where
+ # number indicates byte alignment
+ # in powers of 2. (.align 2
+ # represents word alignment since
+ # 2^2 = 4 bytes)
+
+.text # Section that contains
+ # instructions and program logic
+.globl _main # Declares an instruction label as
+ # global, making it accessible to
+ # other files
+
+ _main: # MIPS programs execute
+ # instructions sequentially, where
+ # the code under this label will be
+ # executed first
+
+ # Let's print "hello world"
+ la $a0, hello_world # Load address of string stored
+ # in memory
+ li $v0, 4 # Load the syscall value (number
+ # indicating which syscall to make)
+ syscall # Perform the specified syscall
+ # with the given argument ($a0)
+
+ # Registers (used to hold data during program execution)
+ # $t0 - $t9 # Temporary registers used for
+ # intermediate calculations inside
+ # subroutines (not saved across
+ # function calls)
+
+ # $s0 - $s7 # Saved registers where values are
+ # saved across subroutine calls.
+ # Typically saved in stack
+
+ # $a0 - $a3 # Argument registers for passing in
+ # arguments for subroutines
+ # $v0 - $v1 # Return registers for returning
+ # values to caller function
+
+ # Types of load/store instructions
+ la $t0, label # Copy the address of a value in
+ # memory specified by the label
+ # into register $t0
+ lw $t0, label # Copy a word value from memory
+ lw $t1, 4($s0) # Copy a word value from an address
+ # stored in a register with an
+ # offset of 4 bytes (addr + 4)
+ lb $t2, label # Copy a byte value to the
+ # lower order portion of
+ # the register $t2
+ lb $t2, 0($s0) # Copy a byte value from the source
+ # address in $s0 with offset 0
+ # Same idea with 'lh' for halfwords
+
+ sw $t0, label # Store word value into
+ # memory address mapped by label
+ sw $t0, 8($s0) # Store word value into address
+ # specified in $s0 and offset of
+ # 8 bytes
+ # Same idea using 'sb' and 'sh' for bytes and halfwords. 'sa' does not exist
+
+### Math ###
+ _math:
+ # Remember to load your values into a register
+ lw $t0, num # From the data section
+ li $t0, 5 # Or from an immediate (constant)
+ li $t1, 6
+ add $t2, $t0, $t1 # $t2 = $t0 + $t1
+ sub $t2, $t0, $t1 # $t2 = $t0 - $t1
+ mul $t2, $t0, $t1 # $t2 = $t0 * $t1
+ div $t2, $t0, $t1 # $t2 = $t0 / $t1 (Might not be
+ # supported in some versons of MARS)
+ div $t0, $t1 # Performs $t0 / $t1. Get the
+ # quotient using 'mflo' and
+ # remainder using 'mfhi'
+
+ # Bitwise Shifting
+ sll $t0, $t0, 2 # Bitwise shift to the left with
+ # immediate (constant value) of 2
+ sllv $t0, $t1, $t2 # Shift left by a variable amount
+ # in register
+ srl $t0, $t0, 5 # Bitwise shift to the right (does
+ # not sign preserve, sign-extends
+ # with 0)
+ srlv $t0, $t1, $t2 # Shift right by a variable amount
+ # in a register
+ sra $t0, $t0, 7 # Bitwise arithmetic shift to
+ # the right (preserves sign)
+ srav $t0, $t1, $t2 # Shift right by a variable amount
+ # in a register
+
+ # Bitwise operators
+ and $t0, $t1, $t2 # Bitwise AND
+ andi $t0, $t1, 0xFFF # Bitwise AND with immediate
+ or $t0, $t1, $t2 # Bitwise OR
+ ori $t0, $t1, 0xFFF # Bitwise OR with immediate
+ xor $t0, $t1, $t2 # Bitwise XOR
+ xori $t0, $t1, 0xFFF # Bitwise XOR with immediate
+ nor $t0, $t1, $t2 # Bitwise NOR
+
+## BRANCHING ##
+ _branching:
+ # The basic format of these branching instructions typically follow <instr>
+ # <reg1> <reg2> <label> where label is the label we want to jump to if the
+ # given conditional evaluates to true
+ # Sometimes it is easier to write the conditional logic backward, as seen
+ # in the simple if statement example below
+
+ beq $t0, $t1, reg_eq # Will branch to reg_eq if
+ # $t0 == $t1, otherwise
+ # execute the next line
+ bne $t0, $t1, reg_neq # Branches when $t0 != $t1
+ b branch_target # Unconditional branch, will
+ # always execute
+ beqz $t0, req_eq_zero # Branches when $t0 == 0
+ bnez $t0, req_neq_zero # Branches when $t0 != 0
+ bgt $t0, $t1, t0_gt_t1 # Branches when $t0 > $t1
+ bge $t0, $t1, t0_gte_t1 # Branches when $t0 >= $t1
+ bgtz $t0, t0_gt0 # Branches when $t0 > 0
+ blt $t0, $t1, t0_gt_t1 # Branches when $t0 < $t1
+ ble $t0, $t1, t0_gte_t1 # Branches when $t0 <= $t1
+ bltz $t0, t0_lt0 # Branches when $t0 < 0
+ slt $s0, $t0, $t1 # Instruction that sends a signal
+ # when $t0 < $t1 with result in $s0
+ # (1 for true)
+
+ # Simple if statement
+ # if (i == j)
+ # f = g + h;
+ # f = f - i;
+
+ # Let $s0 = f, $s1 = g, $s2 = h, $s3 = i, $s4 = j
+ bne $s3, $s4, L1 # if (i !=j)
+ add $s0, $s1, $s2 # f = g + h
+
+ L1:
+ sub $s0, $s0, $s3 # f = f - i
+
+ # Below is an example of finding the max of 3 numbers
+ # A direct translation in Java from MIPS logic:
+ # if (a > b)
+ # if (a > c)
+ # max = a;
+ # else
+ # max = c;
+ # else
+ # max = b;
+ # else
+ # max = c;
+
+ # Let $s0 = a, $s1 = b, $s2 = c, $v0 = return register
+ ble $s0, $s1, a_LTE_b # if(a <= b) branch(a_LTE_b)
+ ble $s0, $s2, max_C # if(a > b && a <=c) branch(max_C)
+ move $v0, $s1 # else [a > b && a > c] max = a
+ j done # Jump to the end of the program
+
+ a_LTE_b: # Label for when a <= b
+ ble $s1, $s2, max_C # if(a <= b && b <= c) branch(max_C)
+ move $v0, $s1 # if(a <= b && b > c) max = b
+ j done # Jump to done
+
+ max_C:
+ move $v0, $s2 # max = c
+
+ done: # End of program
+
+## LOOPS ##
+ _loops:
+ # The basic structure of loops is having an exit condition and a jump
+ # instruction to continue its execution
+ li $t0, 0
+ while:
+ bgt $t0, 10, end_while # While $t0 is less than 10,
+ # keep iterating
+ addi $t0, $t0, 1 # Increment the value
+ j while # Jump back to the beginning of
+ # the loop
+ end_while:
+
+ # 2D Matrix Traversal
+ # Assume that $a0 stores the address of an integer matrix which is 3 x 3
+ li $t0, 0 # Counter for i
+ li $t1, 0 # Counter for j
+ matrix_row:
+ bgt $t0, 3, matrix_row_end
+
+ matrix_col:
+ bgt $t1, 3, matrix_col_end
+
+ # Do stuff
+
+ addi $t1, $t1, 1 # Increment the col counter
+ matrix_col_end:
+
+ # Do stuff
+
+ addi $t0, $t0, 1
+ matrix_row_end:
+
+## FUNCTIONS ##
+ _functions:
+ # Functions are callable procedures that can accept arguments and return
+ values all denoted with labels, like above
+
+ main: # Programs begin with main func
+ jal return_1 # jal will store the current PC in $ra
+ # and then jump to return_1
+
+ # What if we want to pass in args?
+ # First we must pass in our parameters to the argument registers
+ li $a0, 1
+ li $a1, 2
+ jal sum # Now we can call the function
+
+ # How about recursion?
+ # This is a bit more work since we need to make sure we save and restore
+ # the previous PC in $ra since jal will automatically overwrite
+ # on each call
+ li $a0, 3
+ jal fact
+
+ li $v0, 10
+ syscall
+
+ # This function returns 1
+ return_1:
+ li $v0, 1 # Load val in return register $v0
+ jr $ra # Jump back to old PC to continue exec
+
+
+ # Function with 2 args
+ sum:
+ add $v0, $a0, $a1
+ jr $ra # Return
+
+ # Recursive function to find factorial
+ fact:
+ addi $sp, $sp, -8 # Allocate space in stack
+ sw $s0, ($sp) # Store reg that holds current num
+ sw $ra, 4($sp) # Store previous PC
+
+ li $v0, 1 # Init return value
+ beq $a0, 0, fact_done # Finish if param is 0
+
+ # Otherwise, continue recursion
+ move $s0, $a0 # Copy $a0 to $s0
+ sub $a0, $a0, 1
+ jal fact
+
+ mul $v0, $s0, $v0 # Multiplication is done
+
+ fact_done:
+ lw $s0, ($sp)
+ lw $ra, ($sp) # Restore the PC
+ addi $sp, $sp, 8
+
+ jr $ra
+
+## MACROS ##
+ _macros:
+ # Macros are extremely useful for substituting repeated code blocks with a
+ # single label for better readability
+ # These are in no means substitutes for functions
+ # These must be declared before it is used
+
+ # Macro for printing newlines (since these can be very repetitive)
+ .macro println()
+ la $a0, newline # New line string stored here
+ li $v0, 4
+ syscall
+ .end_macro
+
+ println() # Assembler will copy that block of
+ # code here before running
+
+ # Parameters can be passed in through macros.
+ # These are denoted by a '%' sign with any name you choose
+ .macro print_int(%num)
+ li $v0, 1
+ lw $a0, %num
+ syscall
+ .end_macro
+
+ li $t0, 1
+ print_int($t0)
+
+ # We can also pass in immediates for macros
+ .macro immediates(%a, %b)
+ add $t0, %a, %b
+ .end_macro
+
+ immediates(3, 5)
+
+ # Along with passing in labels
+ .macro print(%string)
+ la $a0, %string
+ li $v0, 4
+ syscall
+ .end_macro
+
+ print(hello_world)
+
+## ARRAYS ##
+.data
+ list: .word 3, 0, 1, 2, 6 # This is an array of words
+ char_arr: .asciiz "hello" # This is a char array
+ buffer: .space 128 # Allocates a block in memory, does
+ # not automatically clear
+ # These blocks of memory are aligned
+ # next to each other
+
+.text
+ la $s0, list # Load address of list
+ li $t0, 0 # Counter
+ li $t1, 5 # Length of the list
+
+ loop:
+ bgt $t0, $t1, end_loop
+
+ lw $a0, ($s0)
+ li $v0, 1
+ syscall # Print the number
+
+ addi $s0, $s0, 4 # Size of a word is 4 bytes
+ addi $t0, $t0, 1 # Increment
+ j loop
+ end_loop:
+
+## INCLUDE ##
+# You do this to import external files into your program (behind the scenes,
+# it really just takes whatever code that is in that file and places it where
+# the include statement is)
+.include "somefile.asm"
+
+```
diff --git a/montilang.html.markdown b/montilang.html.markdown
new file mode 100644
index 00000000..cceb7aa1
--- /dev/null
+++ b/montilang.html.markdown
@@ -0,0 +1,233 @@
+---
+language: "montilang"
+filename: montilang.ml
+contributors:
+ - ["Leo Whitehead", "https://github.com/lduck11007"]
+---
+
+MontiLang is a Stack-Oriented concatenative imperative programming language. Its syntax
+is roughly based off of forth with similar style for doing arithmetic in [reverse polish notation.](https://en.wikipedia.org/wiki/Reverse_Polish_notation)
+
+A good way to start with MontiLang is to read the documentation and examples at [montilang.ml](http://montilang.ml),
+then download MontiLang or build from source code with the instructions provided.
+
+```
+/# Monti Reference sheet #/
+/#
+Comments are multiline
+Nested comments are not supported
+#/
+/# Whitespace is all arbitrary, indentation is optional #/
+/# All programming in Monti is done by manipulating the parameter stack
+arithmetic and stack operations in MontiLang are similar to FORTH
+https://en.wikipedia.org/wiki/Forth_(programming_language)
+#/
+
+/# in Monti, everything is either a string or a number. Operations treat all numbers
+similarly to floats, but anything without a remainder is treated as type int #/
+
+/# numbers and strings are added to the stack from left to right #/
+
+/# Arithmetic works by manipulating data on the stack #/
+
+5 3 + PRINT . /# 8 #/
+
+/# 5 and 3 are pushed onto the stack
+ '+' replaces top 2 items on stack with sum of top 2 items
+ 'PRINT' prints out the top item on the stack
+ '.' pops the top item from the stack.
+ #/
+
+6 7 * PRINT . /# 42 #/
+1360 23 - PRINT . /# 1337 #/
+12 12 / PRINT . /# 1 #/
+13 2 % PRINT . /# 1 #/
+
+37 NEG PRINT . /# -37 #/
+-12 ABS PRINT . /# 12 #/
+52 23 MAX PRINT . /# 52 #/
+52 23 MIN PRINT . /# 23 #/
+
+/# 'PSTACK' command prints the entire stack, 'CLEAR' clears the entire stack #/
+
+3 6 8 PSTACK CLEAR /# [3, 6, 8] #/
+
+/# Monti comes with some tools for stack manipulation #/
+
+2 DUP PSTACK CLEAR /# [2, 2] - Duplicate the top item on the stack#/
+2 6 SWAP PSTACK CLEAR /# [6, 2] - Swap top 2 items on stack #/
+1 2 3 ROT PSTACK CLEAR /# [2, 3, 1] - Rotate top 3 items on stack #/
+2 3 NIP PSTACK CLEAR /# [3] - delete second item from the top of the stack #/
+4 5 6 TRIM PSTACK CLEAR /# [5, 6] - Deletes first item on stack #/
+/# variables are assigned with the syntax 'VAR [name]'#/
+/# When assigned, the variable will take the value of the top item of the stack #/
+
+6 VAR six . /# assigns var 'six' to be equal to 6 #/
+3 6 + VAR a . /# assigns var 'a' to be equal to 9 #/
+
+/# the length of the stack can be calculated with the statement 'STKLEN' #/
+1 2 3 4 STKLEN PRINT CLEAR /# 4 #/
+
+/# strings are defined with | | #/
+
+|Hello World!| VAR world . /# sets variable 'world' equal to string 'Hello world! #/
+
+/# variables can be called by typing its name. when called, the value of the variable is pushed
+to the top of the stack #/
+world PRINT .
+
+/# with the OUT statement, the top item on the stack can be printed without a newline #/
+
+|world!| |Hello, | OUT SWAP PRINT CLEAR
+
+/# Data types can be converted between strings and integers with the commands 'TOINT' and 'TOSTR'#/
+|5| TOINT PSTACK . /# [5] #/
+45 TOSTR PSTACK . /# ['45'] #/
+
+/# User input is taken with INPUT and pushed to the stack. If the top item of the stack is a string,
+the string is used as an input prompt #/
+
+|What is your name? | INPUT NIP
+|Hello, | OUT SWAP PRINT CLEAR
+
+
+/# FOR loops have the syntax 'FOR [condition] [commands] ENDFOR' At the moment, [condition] can
+only have the value of an integer. Either by using an integer, or a variable call to an integer.
+[commands] will be interpereted the amount of time specified in [condition] #/
+/# E.G: this prints out 1 to 10 #/
+
+1 VAR a .
+FOR 10
+ a PRINT 1 + VAR a
+ENDFOR
+
+/# the syntax for while loops are similar. A number is evaluated as true if it is larger than
+0. a string is true if its length > 0. Infinite loops can be used by using literals.
+#/
+10 var loop .
+WHILE loop
+ loop print
+ 1 - var loop
+ENDWHILE
+/#
+this loop would count down from 10.
+
+IF statements are pretty much the same, but only are executed once.
+#/
+IF loop
+ loop PRINT .
+ENDIF
+
+/# This would only print 'loop' if it is larger than 0 #/
+
+/# If you would want to use the top item on the stack as loop parameters, this can be done with the ':' character #/
+
+/# eg, if you wanted to print 'hello' 7 times, instead of using #/
+
+FOR 7
+ |hello| PRINT .
+ENDFOR
+
+/# this could be used #/
+7
+FOR :
+ |hello| PRINT .
+ENDFOR
+
+/# Equality and inequality statements use the top 2 items on the stack as parameters, and replace the top two items with the output #/
+/# If it is true, the top 2 items are replaced with '1'. If false, with '0'. #/
+
+7 3 > PRINT . /# 1 #/
+2 10 > PRINT . /# 0 #/
+5 9 <= PRINT . /# 1 #/
+5 5 == PRINT . /# 1 #/
+5 7 == PRINT . /# 0 #/
+3 8 != PRINT . /# 1 #/
+
+/# User defined commands have the syntax of 'DEF [name] [commands] ENDDEF'. #/
+/# eg, if you wanted to define a function with the name of 'printseven' to print '7' 10 times, this could be used #/
+
+DEF printseven
+ FOR 10
+ 7 PRINT .
+ ENDFOR
+ENDDEF
+
+/# to run the defined statement, simply type it and it will be run by the interpereter #/
+
+printseven
+
+/# Montilang supports AND, OR and NOT statements #/
+
+1 0 AND PRINT . /# 0 #/
+1 1 AND PRINT . /# 1 #/
+1 0 OR PRINT . /# 1 #/
+0 0 OR PRINT . /# 0 #/
+1 NOT PRINT . /# 0 #/
+0 NOT PRINT . /# 1 #/
+
+/# Preprocessor statements are made inbetween '&' characters #/
+/# currently, preprocessor statements can be used to make c++-style constants #/
+
+&DEFINE LOOPSTR 20&
+/# must have & on either side with no spaces, 'DEFINE' is case sensative. #/
+/# All statements are scanned and replaced before the program is run, regardless of where the statements are placed #/
+
+FOR LOOPSTR 7 PRINT . ENDFOR /# Prints '7' 20 times. At run, 'LOOPSTR' in source code is replaced with '20' #/
+
+/# Multiple files can be used with the &INCLUDE <filename>& Command that operates similar to c++, where the file specified is tokenized,
+ and the &INCLUDE statement is replaced with the file #/
+
+/# E.G, you can have a program be run through several files. If you had the file 'name.mt' with the following data:
+
+[name.mt]
+|Hello, | OUT . name PRINT .
+
+a program that asks for your name and then prints it out can be defined as such: #/
+
+|What is your name? | INPUT VAR name . &INCLUDE name.mt&
+
+/# ARRAYS: #/
+
+/# arrays are defined with the statement 'ARR'
+When called, everything currently in the stack is put into one
+array and all items on the stack are replaced with the new array. #/
+
+2 3 4 ARR PSTACK . /# [[2, 3, 4]] #/
+
+/# the statement 'LEN' adds the length of the last item on the stack to the stack.
+This can be used on arrays, as well as strings. #/
+
+3 4 5 ARR LEN PRINT . /# 3 #/
+
+/# values can be appended to an array with the statement 'APPEND' #/
+
+1 2 3 ARR 5 APPEND . PRINT . /# [1, 2, 3, 5] #/
+
+/# an array at the top of the stack can be wiped with the statement 'WIPE' #/
+3 4 5 ARR WIPE PRINT . /# [] #/
+
+/# The last item of an array can be removed with the statement 'DROP' #/
+
+3 4 5 ARR DROP PRINT . /# [3, 4]
+/# arrays, like other datatypes can be stored in variables #/
+5 6 7 ARR VAR list .
+list PRINT . /# [5, 6, 7] #/
+
+/# Values at specific indexes can be changed with the statement 'INSERT <index>' #/
+4 5 6 ARR
+97 INSERT 1 . PRINT /# 4, 97, 6 #/
+
+/# Values at specific indexes can be deleted with the statement 'DEL <index>' #/
+1 2 3 ARR
+DEL 1 PRINT . /# [1, 3] #/
+
+/# items at certain indexes of an array can be gotten with the statement 'GET <index>' #/
+
+1 2 3 ARR GET 2 PSTACK /# [[1, 2, 3], 3] #/
+```
+
+## Extra information
+
+- [MontiLang.ml](http://montilang.ml/)
+- [Github Page](https://github.com/lduck11007/MontiLang)
diff --git a/moonscript.html.markdown b/moonscript.html.markdown
new file mode 100644
index 00000000..193d7f97
--- /dev/null
+++ b/moonscript.html.markdown
@@ -0,0 +1,570 @@
+---
+language: moonscript
+contributors:
+ - ["RyanSquared", "https://ryansquared.github.io/"]
+ - ["Job van der Zwan", "https://github.com/JobLeonard"]
+filename: moonscript.moon
+---
+
+MoonScript is a dynamic scripting language that compiles into Lua. It gives
+you the power of one of the fastest scripting languages combined with a
+rich set of features.
+
+See [the MoonScript website](https://moonscript.org/) to see official guides on installation for all platforms.
+
+```moon
+-- Two dashes start a comment. Comments can go until the end of the line.
+-- MoonScript transpiled to Lua does not keep comments.
+
+-- As a note, MoonScript does not use 'do', 'then', or 'end' like Lua would and
+-- instead uses an indented syntax, much like Python.
+
+--------------------------------------------------
+-- 1. Assignment
+--------------------------------------------------
+
+hello = "world"
+a, b, c = 1, 2, 3
+hello = 123 -- Overwrites `hello` from above.
+
+x = 0
+x += 10 -- x = x + 10
+
+s = "hello "
+s ..= "world" -- s = s .. "world"
+
+b = false
+b and= true or false -- b = b and (true or false)
+
+--------------------------------------------------
+-- 2. Literals and Operators
+--------------------------------------------------
+
+-- Literals work almost exactly as they would in Lua. Strings can be broken in
+-- the middle of a line without requiring a \.
+
+some_string = "exa
+mple" -- local some_string = "exa\nmple"
+
+-- Strings can also have interpolated values, or values that are evaluated and
+-- then placed inside of a string.
+
+some_string = "This is an #{some_string}" -- Becomes 'This is an exa\nmple'
+
+--------------------------------------------------
+-- 2.1. Function Literals
+--------------------------------------------------
+
+-- Functions are written using arrows:
+
+my_function = -> -- compiles to `function() end`
+my_function() -- calls an empty function
+
+-- Functions can be called without using parenthesis. Parentheses may still be
+-- used to have priority over other functions.
+
+func_a = -> print "Hello World!"
+func_b = ->
+ value = 100
+ print "The value: #{value}"
+
+-- If a function needs no parameters, it can be called with either `()` or `!`.
+
+func_a!
+func_b()
+
+-- Functions can use arguments by preceding the arrow with a list of argument
+-- names bound by parentheses.
+
+sum = (x, y)-> x + y -- The last expression is returned from the function.
+print sum(5, 10)
+
+-- Lua has an idiom of sending the first argument to a function as the object,
+-- like a 'self' object. Using a fat arrow (=>) instead of a skinny arrow (->)
+-- automatically creates a `self` variable. `@x` is a shorthand for `self.x`.
+
+func = (num)=> @value + num
+
+-- Default arguments can also be used with function literals:
+
+a_function = (name = "something", height=100)->
+ print "Hello, I am #{name}.\nMy height is #{height}."
+
+-- Because default arguments are calculated in the body of the function when
+-- transpiled to Lua, you can reference previous arguments.
+
+some_args = (x = 100, y = x + 1000)-> print(x + y)
+
+--------------------------------------------------
+-- Considerations
+--------------------------------------------------
+
+-- The minus sign plays two roles, a unary negation operator and a binary
+-- subtraction operator. It is recommended to always use spaces between binary
+-- operators to avoid the possible collision.
+
+a = x - 10 -- a = x - 10
+b = x-10 -- b = x - 10
+c = x -y -- c = x(-y)
+d = x- z -- d = x - z
+
+-- When there is no space between a variable and string literal, the function
+-- call takes priority over following expressions:
+
+x = func"hello" + 100 -- func("hello") + 100
+y = func "hello" + 100 -- func("hello" + 100)
+
+-- Arguments to a function can span across multiple lines as long as the
+-- arguments are indented. The indentation can be nested as well.
+
+my_func 5, -- called as my_func(5, 8, another_func(6, 7, 9, 1, 2), 5, 4)
+ 8, another_func 6, 7, -- called as
+ 9, 1, 2, -- another_func(6, 7, 9, 1, 2)
+ 5, 4
+
+-- If a function is used at the start of a block, the indentation can be
+-- different than the level of indentation used in a block:
+
+if func 1, 2, 3, -- called as func(1, 2, 3, "hello", "world")
+ "hello",
+ "world"
+ print "hello"
+
+--------------------------------------------------
+-- 3. Tables
+--------------------------------------------------
+
+-- Tables are defined by curly braces, like Lua:
+
+some_values = {1, 2, 3, 4}
+
+-- Tables can use newlines instead of commas.
+
+some_other_values = {
+ 5, 6
+ 7, 8
+}
+
+-- Assignment is done with `:` instead of `=`:
+
+profile = {
+ name: "Bill"
+ age: 200
+ "favorite food": "rice"
+}
+
+-- Curly braces can be left off for `key: value` tables.
+
+y = type: "dog", legs: 4, tails: 1
+
+profile =
+ height: "4 feet",
+ shoe_size: 13,
+ favorite_foods: -- nested table
+ foo: "ice cream",
+ bar: "donuts"
+
+my_function dance: "Tango", partner: "none" -- :( forever alone
+
+-- Tables constructed from variables can use the same name as the variables
+-- by using `:` as a prefix operator.
+
+hair = "golden"
+height = 200
+person = {:hair, :height}
+
+-- Like in Lua, keys can be non-string or non-numeric values by using `[]`.
+
+t =
+ [1 + 2]: "hello"
+ "hello world": true -- Can use string literals without `[]`.
+
+--------------------------------------------------
+-- 3.1. Table Comprehensions
+--------------------------------------------------
+
+-- List Comprehensions
+
+-- Creates a copy of a list but with all items doubled. Using a star before a
+-- variable name or table can be used to iterate through the table's values.
+
+items = {1, 2, 3, 4}
+doubled = [item * 2 for item in *items]
+-- Uses `when` to determine if a value should be included.
+
+slice = [item for item in *items when item > 1 and item < 3]
+
+-- `for` clauses inside of list comprehensions can be chained.
+
+x_coords = {4, 5, 6, 7}
+y_coords = {9, 2, 3}
+
+points = [{x,y} for x in *x_coords for y in *y_coords]
+
+-- Numeric for loops can also be used in comprehensions:
+
+evens = [i for i=1, 100 when i % 2 == 0]
+
+-- Table Comprehensions are very similar but use `{` and `}` and take two
+-- values for each iteration.
+
+thing = color: "red", name: "thing", width: 123
+thing_copy = {k, v for k, v in pairs thing}
+
+-- Tables can be "flattened" from key-value pairs in an array by using `unpack`
+-- to return both values, using the first as the key and the second as the
+-- value.
+
+tuples = {{"hello", "world"}, {"foo", "bar"}}
+table = {unpack tuple for tuple in *tuples}
+
+-- Slicing can be done to iterate over only a certain section of an array. It
+-- uses the `*` notation for iterating but appends `[start, end, step]`.
+
+-- The next example also shows that this syntax can be used in a `for` loop as
+-- well as any comprehensions.
+
+for item in *points[1, 10, 2]
+ print unpack item
+
+-- Any undesired values can be left off. The second comma is not required if
+-- the step is not included.
+
+words = {"these", "are", "some", "words"}
+for word in *words[,3]
+ print word
+
+--------------------------------------------------
+-- 4. Control Structures
+--------------------------------------------------
+
+have_coins = false
+if have_coins
+ print "Got coins"
+else
+ print "No coins"
+
+-- Use `then` for single-line `if`
+if have_coins then "Got coins" else "No coins"
+
+-- `unless` is the opposite of `if`
+unless os.date("%A") == "Monday"
+ print "It is not Monday!"
+
+-- `if` and `unless` can be used as expressions
+is_tall = (name)-> if name == "Rob" then true else false
+message = "I am #{if is_tall "Rob" then "very tall" else "not so tall"}"
+print message -- "I am very tall"
+
+-- `if`, `elseif`, and `unless` can evaluate assignment as well as expressions.
+if x = possibly_nil! -- sets `x` to `possibly_nil()` and evaluates `x`
+ print x
+
+-- Conditionals can be used after a statement as well as before. This is
+-- called a "line decorator".
+
+is_monday = os.date("%A") == "Monday"
+print("It IS Monday!") if isMonday
+print("It is not Monday..") unless isMonday
+--print("It IS Monday!" if isMonday) -- Not a statement, does not work
+
+--------------------------------------------------
+-- 4.1 Loops
+--------------------------------------------------
+
+for i = 1, 10
+ print i
+
+for i = 10, 1, -1 do print i -- Use `do` for single-line loops.
+
+i = 0
+while i < 10
+ continue if i % 2 == 0 -- Continue statement; skip the rest of the loop.
+ print i
+
+-- Loops can be used as a line decorator, just like conditionals
+print "item: #{item}" for item in *items
+
+-- Using loops as an expression generates an array table. The last statement
+-- in the block is coerced into an expression and added to the table.
+my_numbers = for i = 1, 6 do i -- {1, 2, 3, 4, 5, 6}
+
+-- use `continue` to filter out values
+odds = for i in *my_numbers
+ continue if i % 2 == 0 -- acts opposite to `when` in comprehensions!
+ i -- Only added to return table if odd
+
+-- A `for` loop returns `nil` when it is the last statement of a function
+-- Use an explicit `return` to generate a table.
+print_squared = (t) -> for x in *t do x*x -- returns `nil`
+squared = (t) -> return for x in *t do x*x -- returns new table of squares
+
+-- The following does the same as `(t) -> [i for i in *t when i % 2 == 0]`
+-- But list comprehension generates better code and is more readable!
+
+filter_odds = (t) ->
+ return for x in *t
+ if x % 2 == 0 then x else continue
+evens = filter_odds(my_numbers) -- {2, 4, 6}
+
+--------------------------------------------------
+-- 4.2 Switch Statements
+--------------------------------------------------
+
+-- Switch statements are a shorthand way of writing multiple `if` statements
+-- checking against the same value. The value is only evaluated once.
+
+name = "Dan"
+
+switch name
+ when "Dave"
+ print "You are Dave."
+ when "Dan"
+ print "You are not Dave, but Dan."
+ else
+ print "You are neither Dave nor Dan."
+
+-- Switches can also be used as expressions, as well as compare multiple
+-- values. The values can be on the same line as the `when` clause if they
+-- are only one expression.
+
+b = 4
+next_even = switch b
+ when 1 then 2
+ when 2, 3 then 4
+ when 4, 5 then 6
+ else error "I can't count that high! D:"
+
+--------------------------------------------------
+-- 5. Object Oriented Programming
+--------------------------------------------------
+
+-- Classes are created using the `class` keyword followed by an identifier,
+-- typically written using CamelCase. Values specific to a class can use @ as
+-- the identifier instead of `self.value`.
+
+class Inventory
+ new: => @items = {}
+ add_item: (name)=> -- note the use of fat arrow for classes!
+ @items[name] = 0 unless @items[name]
+ @items[name] += 1
+
+-- The `new` function inside of a class is special because it is called when
+-- an instance of the class is created.
+
+-- Creating an instance of the class is as simple as calling the class as a
+-- function. Calling functions inside of the class uses \ to separate the
+-- instance from the function it is calling.
+
+inv = Inventory!
+inv\add_item "t-shirt"
+inv\add_item "pants"
+
+-- Values defined in the class - not the new() function - will be shared across
+-- all instances of the class.
+
+class Person
+ clothes: {}
+ give_item: (name)=>
+ table.insert @clothes name
+
+a = Person!
+b = Person!
+
+a\give_item "pants"
+b\give_item "shirt"
+
+-- prints out both "pants" and "shirt"
+
+print item for item in *a.clothes
+
+-- Class instances have a value `.__class` that are equal to the class object
+-- that created the instance.
+
+assert(b.__class == Person)
+
+-- Variables declared in class body the using the `=` operator are locals,
+-- so these "private" variables are only accessible within the current scope.
+
+class SomeClass
+ x = 0
+ reveal: ->
+ x += 1
+ print x
+
+a = SomeClass!
+b = SomeClass!
+print a.x -- nil
+a.reveal! -- 1
+b.reveal! -- 2
+
+--------------------------------------------------
+-- 5.1 Inheritance
+--------------------------------------------------
+
+-- The `extends` keyword can be used to inherit properties and methods from
+-- another class.
+
+class Backpack extends Inventory
+ size: 10
+ add_item: (name)=>
+ error "backpack is full" if #@items > @size
+ super name -- calls Inventory.add_item with `name`.
+
+-- Because a `new` method was not added, the `new` method from `Inventory` will
+-- be used instead. If we did want to use a constructor while still using the
+-- constructor from `Inventory`, we could use the magical `super` function
+-- during `new()`.
+
+-- When a class extends another, it calls the method `__inherited` on the
+-- parent class (if it exists). It is always called with the parent and the
+-- child object.
+
+class ParentClass
+ @__inherited: (child)=>
+ print "#{@__name} was inherited by #{child.__name}"
+ a_method: (a, b) => print a .. ' ' .. b
+
+-- Will print 'ParentClass was inherited by MyClass'
+
+class MyClass extends ParentClass
+ a_method: =>
+ super "hello world", "from MyClass!"
+ assert super == ParentClass
+
+--------------------------------------------------
+-- 6. Scope
+--------------------------------------------------
+
+-- All values are local by default. The `export` keyword can be used to
+-- declare the variable as a global value.
+
+export var_1, var_2
+var_1, var_3 = "hello", "world" -- var_3 is local, var_1 is not.
+
+export this_is_global_assignment = "Hi!"
+
+-- Classes can also be prefixed with `export` to make them global classes.
+-- Alternatively, all CamelCase variables can be exported automatically using
+-- `export ^`, and all values can be exported using `export *`.
+
+-- `do` lets you manually create a scope, for when you need local variables.
+
+do
+ x = 5
+print x -- nil
+
+-- Here we use `do` as an expression to create a closure.
+
+counter = do
+ i = 0
+ ->
+ i += 1
+ return i
+
+print counter! -- 1
+print counter! -- 2
+
+-- The `local` keyword can be used to define variables
+-- before they are assigned.
+
+local var_4
+if something
+ var_4 = 1
+print var_4 -- works because `var_4` was set in this scope, not the `if` scope.
+
+-- The `local` keyword can also be used to shadow an existing variable.
+
+x = 10
+if false
+ local x
+ x = 12
+print x -- 10
+
+-- Use `local *` to forward-declare all variables.
+-- Alternatively, use `local ^` to forward-declare all CamelCase values.
+
+local *
+
+first = ->
+ second!
+
+second = ->
+ print data
+
+data = {}
+
+--------------------------------------------------
+-- 6.1 Import
+--------------------------------------------------
+
+-- Values from a table can be brought to the current scope using the `import`
+-- and `from` keyword. Names in the `import` list can be preceded by `\` if
+-- they are a module function.
+
+import insert from table -- local insert = table.insert
+import \add from state: 100, add: (value)=> @state + value
+print add 22
+
+-- Like tables, commas can be excluded from `import` lists to allow for longer
+-- lists of imported items.
+
+import
+ asdf, gh, jkl
+ antidisestablishmentarianism
+ from {}
+
+--------------------------------------------------
+-- 6.2 With
+--------------------------------------------------
+
+-- The `with` statement can be used to quickly call and assign values in an
+-- instance of a class or object.
+
+file = with File "lmsi15m.moon" -- `file` is the value of `set_encoding()`.
+ \set_encoding "utf8"
+
+create_person = (name, relatives)->
+ with Person!
+ .name = name
+ \add_relative relative for relative in *relatives
+me = create_person "Ryan", {"sister", "sister", "brother", "dad", "mother"}
+
+with str = "Hello" -- assignment as expression! :D
+ print "original: #{str}"
+ print "upper: #{\upper!}"
+
+--------------------------------------------------
+-- 6.3 Destructuring
+--------------------------------------------------
+
+-- Destructuring can take arrays, tables, and nested tables and convert them
+-- into local variables.
+
+obj2 =
+ numbers: {1, 2, 3, 4}
+ properties:
+ color: "green"
+ height: 13.5
+
+{numbers: {first, second}, properties: {:color}} = obj2
+
+print first, second, color -- 1 2 green
+
+-- `first` and `second` return [1] and [2] because they are as an array, but
+-- `:color` is like `color: color` so it sets itself to the `color` value.
+
+-- Destructuring can be used in place of `import`.
+
+{:max, :min, random: rand} = math -- rename math.random to rand
+
+-- Destructuring can be done anywhere assignment can be done.
+
+for {left, right} in *{{"hello", "world"}, {"egg", "head"}}
+ print left, right
+```
+
+## Additional Resources
+
+- [Language Guide](https://moonscript.org/reference/)
+- [Online Compiler](https://moonscript.org/compiler/)
diff --git a/ms-my/clojure-macros-my.html.markdown b/ms-my/clojure-macros-my.html.markdown
new file mode 100644
index 00000000..325f92e0
--- /dev/null
+++ b/ms-my/clojure-macros-my.html.markdown
@@ -0,0 +1,151 @@
+---
+language: "clojure macros"
+filename: learnclojuremacros-ms.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+translators:
+ - ["Burhanuddin Baharuddin", "https://github.com/burhanloey"]
+lang: ms-my
+---
+
+Sama seperti Lisp yang lain, sifat Clojure yang mempunyai [homoiconicity](https://en.wikipedia.org/wiki/Homoiconic)
+membolehkan anda untuk menggunakan sepenuhnya language ini untuk menulis code yang boleh generate code sendiri yang
+dipanggil "macro". Macro memberi cara yang sangat menarik untuk mengubahsuai language mengikut kehendak anda.
+
+Jaga-jaga. Penggunaan macro boleh dikatakan tidak elok jika digunakan secara berlebihan jika function sahaja sudah mencukupi.
+Gunakan macro hanya apabila anda mahu lebih kawalan terhadap sesuatu form.
+
+Biasakan diri dengan Clojure terlebih dahulu. Pastikan anda memahami semuanya di
+[Clojure in Y Minutes](/docs/ms-my/clojure-my/).
+
+```clojure
+;; Define macro menggunakan defmacro. Macro anda akan output list yang boleh
+;; dijalankan sebagai code clojure.
+;;
+;; Macro ini adalah sama seperti (reverse "Hello World")
+(defmacro my-first-macro []
+ (list reverse "Hello World"))
+
+;; Lihat hasil macro tersebut menggunakan macroexpand atau macroexpand-1.
+;;
+;; Pastikan panggilan kepada macro tersebut mempunyai tanda petikan
+(macroexpand '(my-first-macro))
+;; -> (#<core$reverse clojure.core$reverse@xxxxxxxx> "Hello World")
+
+;; Anda boleh menggunakan eval terus kepada macroexpand untuk mendapatkan hasil:
+(eval (macroexpand '(my-first-macro)))
+; -> (\d \l \o \r \W \space \o \l \l \e \H)
+
+;; Tetapi anda sepatutnya menggunakan cara yang lebih ringkas, sama seperti panggilan kepada function:
+(my-first-macro) ; -> (\d \l \o \r \W \space \o \l \l \e \H)
+
+;; Anda boleh memudahkan cara untuk membuat macro dengan mengguna tanda petikan
+;; untuk membuat list untuk macro:
+(defmacro my-first-quoted-macro []
+ '(reverse "Hello World"))
+
+(macroexpand '(my-first-quoted-macro))
+;; -> (reverse "Hello World")
+;; Perhatikan yang reverse bukan lagi function tetapi adalah simbol.
+
+;; Macro boleh mengambil argument.
+(defmacro inc2 [arg]
+ (list + 2 arg))
+
+(inc2 2) ; -> 4
+
+;; Tetapi jika anda membuat cara yang sama menggunakan tanda petikan, anda akan mendapat error sebab
+;; argument tersebut juga akan mempunyai tanda petikan. Untuk mengatasi masalah ini, Clojure memberi
+;; cara untuk meletak tanda petikan untuk macro: `. Di dalam `, anda boleh menggunakan ~ untuk mendapatkan scope luaran
+(defmacro inc2-quoted [arg]
+ `(+ 2 ~arg))
+
+(inc2-quoted 2)
+
+;; Anda boleh menggunakan destructuring untuk argument seperti biasa. Gunakan ~@ untuk mengembangkan variable
+(defmacro unless [arg & body]
+ `(if (not ~arg)
+ (do ~@body))) ; Jangan lupa do!
+
+(macroexpand '(unless true (reverse "Hello World")))
+;; ->
+;; (if (clojure.core/not true) (do (reverse "Hello World")))
+
+;; (unless) mengembalikan body jika argument yang pertama adalah false.
+;; Jika tidak, (unless) akan memulangkan nil
+
+(unless true "Hello") ; -> nil
+(unless false "Hello") ; -> "Hello"
+
+;; Jika tidak berhati-hati, macro boleh memeningkan anda dengan mencampuradukkan nama variable
+(defmacro define-x []
+ '(do
+ (def x 2)
+ (list x)))
+
+(def x 4)
+(define-x) ; -> (2)
+(list x) ; -> (2)
+
+;; Untuk mengelakkan masalah ini, gunakan gensym untuk mendapatkan identifier yang berbeza
+(gensym 'x) ; -> x1281 (atau yang sama waktu dengannya)
+
+(defmacro define-x-safely []
+ (let [sym (gensym 'x)]
+ `(do
+ (def ~sym 2)
+ (list ~sym))))
+
+(def x 4)
+(define-x-safely) ; -> (2)
+(list x) ; -> (4)
+
+;; Anda boleh menggunakan # di dalam ` untuk menghasilkan gensym untuk setiap simbol secara automatik
+(defmacro define-x-hygienically []
+ `(do
+ (def x# 2)
+ (list x#)))
+
+(def x 4)
+(define-x-hygienically) ; -> (2)
+(list x) ; -> (4)
+
+;; Kebiasaannya helper function digunakan untuk membuat macro. Jom buat beberapa function untuk
+;; membuatkan program boleh memahami inline arithmetic. Saja suka-suka.
+(declare inline-2-helper)
+(defn clean-arg [arg]
+ (if (seq? arg)
+ (inline-2-helper arg)
+ arg))
+
+(defn apply-arg
+ "Diberi argument [x (+ y)], pulangkan (+ x y)"
+ [val [op arg]]
+ (list op val (clean-arg arg)))
+
+(defn inline-2-helper
+ [[arg1 & ops-and-args]]
+ (let [ops (partition 2 ops-and-args)]
+ (reduce apply-arg (clean-arg arg1) ops)))
+
+;; Kita boleh test terlebih dahulu tanpa membuat macro
+(inline-2-helper '(a + (b - 2) - (c * 5))) ; -> (- (+ a (- b 2)) (* c 5))
+
+; Tetapi, kita perlu membuat macro jika kita mahu jalankan code tersebut
+(defmacro inline-2 [form]
+ (inline-2-helper form))
+
+(macroexpand '(inline-2 (1 + (3 / 2) - (1 / 2) + 1)))
+; -> (+ (- (+ 1 (/ 3 2)) (/ 1 2)) 1)
+
+(inline-2 (1 + (3 / 2) - (1 / 2) + 1))
+; -> 3 (sepatutnya, 3N, sebab nombor tersebut ditukarkan kepada pecahan rasional menggunakan /)
+```
+
+### Bacaaan Lanjut
+
+[Writing Macros daripada](http://www.braveclojure.com/writing-macros/)
+
+[Dokumen rasmi](http://clojure.org/macros)
+
+[Bila perlu guna macro?](https://lispcast.com/when-to-use-a-macro/)
diff --git a/ms-my/clojure-my.html.markdown b/ms-my/clojure-my.html.markdown
new file mode 100644
index 00000000..e199c8f4
--- /dev/null
+++ b/ms-my/clojure-my.html.markdown
@@ -0,0 +1,419 @@
+---
+language: clojure
+filename: learnclojure-ms.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+translators:
+ - ["Burhanuddin Baharuddin", "https://github.com/burhanloey"]
+lang: ms-my
+---
+
+Clojure ialah salah satu bahasa pengaturcaraan dalam keluarga Lisp yang dibangunkan untuk Java Virtual Machine. Ia lebih
+menekankan kepada konsep [functional programming](https://en.wikipedia.org/wiki/Functional_programming) jika dibandingkan
+dengan Common Lisp, tetapi juga menyediakan kemudahan [STM](https://en.wikipedia.org/wiki/Software_transactional_memory)
+untuk mengendalikan *state* apabila diperlukan.
+
+Gabungan tersebut membolehkan Clojure untuk mengendalikan beberapa proses serentak (*concurrency*) dengan mudah,
+dan kebiasaannya secara automatik.
+
+(Anda perlukan Clojure versi 1.2 ke atas)
+
+
+```clojure
+; Komen bermula dengan koma bertitik (semicolon).
+
+; Clojure ditulis dalam bentuk yang seragam, iaitu
+; senarai perkataan di dalam kurungan (parentheses), dipisahkan dengan ruang kosong (whitespace).
+;
+; Pembaca Clojure akan menganggap bahawa perkataan pertama dalam senarai tersebut
+; sebagai `function` atau `macro` untuk digunakan, dan yang selebihnya sebagai arguments.
+
+; Panggilan pertama di dalam fail Clojure mestilah bermula dengan ns, untuk menentukan `namespace`
+(ns learnclojure)
+
+; Contoh-contoh asas yang lain:
+
+; str akan mewujudkan sebuah string daripada beberapa `argument`
+(str "Hello" " " "World") ; => "Hello World"
+
+; Operasi matematik pun mudah
+(+ 1 1) ; => 2
+(- 2 1) ; => 1
+(* 1 2) ; => 2
+(/ 2 1) ; => 2
+
+; Tanda = boleh digunakan untuk membuat perbandingan yang sama
+(= 1 1) ; => true
+(= 2 1) ; => false
+
+; Gunakan not untuk mengubah lojik
+(not true) ; => false
+
+; Bentuk `nested` berfungsi seperti yang dijangkakan
+(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
+
+; Type (Jenis Data)
+;;;;;;;;;;;;;
+
+; Clojure menggunakan jenis `object` dari Java untuk `boolean`, `string` dan nombor.
+; Gunakan `class` untuk memeriksa jenis sesebuah data.
+(class 1) ; Secara default jenis data untuk `Integer` ialah java.lang.Long
+(class 1.); Jenis data untuk Float pula ialah java.lang.Double
+(class ""); `String` sentiasa berada dalam tanda petikan (quotation mark), dan merupakan java.lang.String
+(class false) ; `Boolean` ialah java.lang.Boolean
+(class nil); Nilai "null" dipanggil nil
+
+; Jika mahu membuat senarai data secara harfiah, gunakan ' untuk elakkan senarai tersebut
+; daripada terus berfungsi
+'(+ 1 2) ; => (+ 1 2)
+; (singkatan untuk (quote (+ 1 2)))
+
+; Senarai data secara harfiah boleh berfungsi menggunakan eval
+(eval '(+ 1 2)) ; => 3
+
+; Collection & Sequence (Koleksi & Urutan)
+;;;;;;;;;;;;;;;;;;;
+
+; `List` ialah struktur data `linked-list`, manakala `Vector` pula berasaskan `array`.
+; `Vector` dan `List` juga merupakan class dari Java!
+(class [1 2 3]); => clojure.lang.PersistentVector
+(class '(1 2 3)); => clojure.lang.PersistentList
+
+; Sesebuah list boleh ditulis seperti (1 2 3), tetapi kita perlu meletakkan '
+; untuk mengelakkannya daripada berfungsi.
+; Juga, (list 1 2 3) adalah sama dengan '(1 2 3)
+
+; "Collections" hanyalah kumpulan data
+; Kedua-dua list dan vector ialah collection:
+(coll? '(1 2 3)) ; => true
+(coll? [1 2 3]) ; => true
+
+; "Sequences" (seq) ialah kriteria untuk sesebuah senarai data.
+; Hanya list yang dikira sebagai seq.
+(seq? '(1 2 3)) ; => true
+(seq? [1 2 3]) ; => false
+
+; Sesebuah seq hanya perlukan satu kemasukan data untuk diakses.
+; Jadi, seq yang boleh jadi `lazy` (malas) -- boleh menjadi tidak terkira (infinite):
+(range 4) ; => (0 1 2 3)
+(range) ; => (0 1 2 3 4 ...) (tiada penghujung)
+(take 4 (range)) ; (0 1 2 3)
+
+; Gunakan cons untuk menambah sesuatu di awal sesebuah list atau vector
+(cons 4 [1 2 3]) ; => (4 1 2 3)
+(cons 4 '(1 2 3)) ; => (4 1 2 3)
+
+; Conj akan menambah sesuatu ke dalam collection dengan paling berkesan.
+; Untuk list, data tersebut dimasukkan di permulaan. Untuk vector, dimasukkan di pengakhiran.
+(conj [1 2 3] 4) ; => [1 2 3 4]
+(conj '(1 2 3) 4) ; => (4 1 2 3)
+
+; Gunakan concat untuk menggabungkan list atau vector
+(concat [1 2] '(3 4)) ; => (1 2 3 4)
+
+; Gunakan filter dan map untuk berinteraksi dengan data di dalam collection
+(map inc [1 2 3]) ; => (2 3 4)
+(filter even? [1 2 3]) ; => (2)
+
+; Gunakan reduce untuk dikecilkan (kepada satu nilai)
+(reduce + [1 2 3 4])
+; = (+ (+ (+ 1 2) 3) 4)
+; => 10
+
+; Reduce boleh diberi nilai permulaan
+(reduce conj [] '(3 2 1))
+; = (conj (conj (conj [] 3) 2) 1)
+; => [3 2 1]
+
+; Function
+;;;;;;;;;;;;;;;;;;;;;
+
+; Gunakan fn untuk membuat `function`. Sesebuah function pasti memulangkan semula
+; hasil daripada barisan yang terakhir.
+(fn [] "Hello World") ; => fn
+
+; (Anda perlukan satu lagi kurungan supaya function tersebut dikira)
+((fn [] "Hello World")) ; => "Hello World"
+
+; Anda boleh membuat var menggunakan def
+(def x 1)
+x ; => 1
+
+; Tetapkan sebuah function ke dalam var
+(def hello-world (fn [] "Hello World"))
+(hello-world) ; => "Hello World"
+
+; Proses di atas boleh diringkaskan menggunakan defn
+(defn hello-world [] "Hello World")
+
+; Tanda [] merupakan senarai argument untuk function tersebut.
+(defn hello [name]
+ (str "Hello " name))
+(hello "Steve") ; => "Hello Steve"
+
+; Cara ini juga boleh digunakan untuk membuat function dengan lebih ringkas:
+(def hello2 #(str "Hello " %1))
+(hello2 "Fanny") ; => "Hello Fanny"
+
+; Anda juga boleh membuat satu function yang mempunyai beberapa bilangan argument
+(defn hello3
+ ([] "Hello World")
+ ([name] (str "Hello " name)))
+(hello3 "Jake") ; => "Hello Jake"
+(hello3) ; => "Hello World"
+
+; Function boleh diberi argument ekstra dalam bentuk seq
+(defn count-args [& args]
+ (str "You passed " (count args) " args: " args))
+(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
+
+; Anda boleh letakkan sekali argument biasa dan argument ekstra
+(defn hello-count [name & args]
+ (str "Hello " name ", you passed " (count args) " extra args"))
+(hello-count "Finn" 1 2 3)
+; => "Hello Finn, you passed 3 extra args"
+
+
+; Map
+;;;;;;;;;;
+
+; Hash map dan array map menggunakan `interface` yang sama. Hash map lebih laju untuk diakses
+; tetapi tidak mengekalkan urutan.
+(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
+(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
+
+; Arraymap akan bertukar menjadi hashmap secara automatik untuk kebanyakan operasi
+; apabila mereka menjadi semakin besar, jadi anda tidak perlu bimbang.
+
+; Map boleh menggunakan apa-apa sahaja jenis data sebagai key, tetapi kebiasaannya keyword adalah yang terbaik
+; Keyword adalah sama seperti string cuma lebih efisyen
+(class :a) ; => clojure.lang.Keyword
+
+(def stringmap {"a" 1, "b" 2, "c" 3})
+stringmap ; => {"a" 1, "b" 2, "c" 3}
+
+(def keymap {:a 1, :b 2, :c 3})
+keymap ; => {:a 1, :c 3, :b 2}
+
+; Oh, sebelum terlupa, tanda koma di atas hanya dianggap seperti whitespace, tak buat apa-apa.
+; Dapatkan nilai daripada map dengan menggunakannya seperti function
+(stringmap "a") ; => 1
+(keymap :a) ; => 1
+
+; Keyword juga boleh digunakan untuk mendapatkan nilai daripada map tersebut!
+(:b keymap) ; => 2
+
+; Jangan cuba teknik di atas menggunakan string, tak jadi.
+;("a" stringmap)
+; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
+
+; Apabila key yang digunakan tidak wujud, map akan memberi nil
+(stringmap "d") ; => nil
+
+; Gunakan assoc untuk menambah key yang baru ke dalam hash-map
+(def newkeymap (assoc keymap :d 4))
+newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
+
+; Tetapi ingat, data dalam clojure adalah `immutable` (tidak berubah)!
+keymap ; => {:a 1, :b 2, :c 3}
+
+; Gunakan dissoc untuk membuang key
+(dissoc keymap :a :b) ; => {:c 3}
+
+; Set
+;;;;;;
+
+(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
+(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
+
+; Tambah data menggunakan conj
+(conj #{1 2 3} 4) ; => #{1 2 3 4}
+
+; Buang data menggunakan disj
+(disj #{1 2 3} 1) ; => #{2 3}
+
+; Periksa kewujudan data dengan menggunakan set tersebut sebagai function:
+(#{1 2 3} 1) ; => 1
+(#{1 2 3} 4) ; => nil
+
+; Ada pelbagai lagi function untuk set di namespace clojure.sets.
+
+; Form yang berguna
+;;;;;;;;;;;;;;;;;
+
+; Lojik dalam clojure hanyalah sebuah macro, dan kelihatan seperti
+; yang lain
+(if false "a" "b") ; => "b"
+(if false "a") ; => nil
+
+; Gunakan let untuk membuat binding sementara
+(let [a 1 b 2]
+ (> a b)) ; => false
+
+; Kumpulkan beberapa statement sekali menggunakan do
+(do
+ (print "Hello")
+ "World") ; => "World" (prints "Hello")
+
+; Function sebenarnya ada do secara tersirat
+(defn print-and-say-hello [name]
+ (print "Saying hello to " name)
+ (str "Hello " name))
+(print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff")
+
+; Let pun sama
+(let [name "Urkel"]
+ (print "Saying hello to " name)
+ (str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
+
+
+; Gunakan `threading macro` (-> dan ->>) untuk menulis penggubahan data
+; dengan lebih jelas.
+
+; Macro "thread-first" (->) memasukkan hasil perkiraan ke setiap form
+; yang selepasnya, sebagai argument pertama (item yang kedua)
+(->
+ {:a 1 :b 2}
+ (assoc :c 3) ;=> (assoc {:a 1 :b 2} :c 3)
+ (dissoc :b)) ;=> (dissoc (assoc {:a 1 :b 2} :c 3) :b)
+
+; Code di atas boleh ditulis seperti ini:
+; (dissoc (assoc {:a 1 :b 2} :c 3) :b)
+; dan hasilnya ialah {:a 1 :c 3}
+
+; Yang dua anak panah pula membuat benda yang sama, tetapi memasukkan hasil perkiraan
+; setiap baris ke pengakhiran form selepasnya. Cara ini berguna untuk operasi
+; yang melibatkan collection:
+(->>
+ (range 10)
+ (map inc) ;=> (map inc (range 10)
+ (filter odd?) ;=> (filter odd? (map inc (range 10))
+ (into [])) ;=> (into [] (filter odd? (map inc (range 10)))
+ ; Result: [1 3 5 7 9]
+
+; Jika anda mahu lebih fleksibel untuk meletakkan hasil perkiraan,
+; anda boleh menggunakan macro `as->`. Dengan menggunakan macro tersebut,
+; anda boleh menentukan nama untuk output dan menggunakannya semula
+; ke dalam operasi berangkai:
+
+(as-> [1 2 3] input
+ (map inc input);=> You can use last transform's output at the last position
+ (nth input 2) ;=> and at the second position, in the same expression
+ (conj [4 5 6] input [8 9 10])) ;=> or in the middle !
+
+
+
+; Module
+;;;;;;;;;;;;;;;
+
+; Gunakan "use" untuk mendapatkan semua function daripada sesebuah module
+(use 'clojure.set)
+
+; Sekarang kita boleh menggunakan operasi untuk set
+(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
+(difference #{1 2 3} #{2 3 4}) ; => #{1}
+
+; Anda juga boleh memilih sebahagian daripada function untuk diimport
+(use '[clojure.set :only [intersection]])
+
+; Gunakan require untuk mengimport sesebuah module
+(require 'clojure.string)
+
+; Gunakan / untuk menggunakan function daripada module
+; Di sini, nama module tersebut ialah clojure.string dan function-nya ialah blank?
+(clojure.string/blank? "") ; => true
+
+; Anda juga boleh memberi nama yang lebih ringkas untuk module semasa import
+(require '[clojure.string :as str])
+(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
+; (#"" ialah ungkapan untuk regular expression, regex)
+
+; Anda boleh menggunakan require (dan use, tetapi elakkan) daripada namespace menggunakan :require.
+; Anda tidak perlu menulis semula nama module dengan cara ini.
+(ns test
+ (:require
+ [clojure.string :as str]
+ [clojure.set :as set]))
+
+; Java
+;;;;;;;;;;;;;;;;;
+
+; Java mengandungi banyak standard library yang kita boleh manfaatkan, jadi
+; anda patut tahu bagaimana untuk menggunakannya.
+
+; Gunakan import untuk load module java
+(import java.util.Date)
+
+; Anda juga boleh import menggunakan ns.
+(ns test
+ (:import java.util.Date
+ java.util.Calendar))
+
+; Gunakan nama class berserta "." di hujungnya untuk membuat object baru
+(Date.) ; <object date>
+
+; Gunakan . untuk menggunakan method. Atau gunakan shortcut seperti ".method"
+(. (Date.) getTime) ; <sebuah timestamp>
+(.getTime (Date.)) ; sama sahaja.
+
+; Gunakan / untuk menggunakan static method
+(System/currentTimeMillis) ; <sebuah timestamp> (System sentiasa wujud dalam Java)
+
+; Gunakan doto untuk menjadikan proses yang melibatkan class mutable (boleh berubah) lebih mudah
+(import java.util.Calendar)
+(doto (Calendar/getInstance)
+ (.set 2000 1 1 0 0 0)
+ .getTime) ; => Sebuah Date. yang ditetapkan kepada 2000-01-01 00:00:00
+
+; STM
+;;;;;;;;;;;;;;;;;
+
+; Software Transactional Memory ialah mekanisme dalam Clojure untuk mengendalikan
+; state yang kekal berterusan. Ada beberapa kaedah dalam Clojure yang menggunakan teknik tersebut.
+
+; Atom adalah yang paling mudah. Letakkannya sewaktu meletakkan nilai permulaan.
+(def my-atom (atom {}))
+
+; Kemas kini sebuah atom menggunakan swap!.
+; swap! mengambil satu function dan menggunakannya menggunakan nilai asal atom
+; sebagai argument pertama, dan argument selebihnya sebagai argument kedua
+(swap! my-atom assoc :a 1) ; Tetapkan my-atom kepada hasil perkiraan (assoc {} :a 1)
+(swap! my-atom assoc :b 2) ; Tetapkan my-atom kepada hasil perkiraan (assoc {:a 1} :b 2)
+
+; Gunakan '@' untuk mendapatkan nilai daripada atom
+my-atom ;=> Atom<#...> (memberi object atom itu sendiri)
+@my-atom ; => {:a 1 :b 2}
+
+; Ini adalah contoh untuk mengira menggunakan atom
+(def counter (atom 0))
+(defn inc-counter []
+ (swap! counter inc))
+
+(inc-counter)
+(inc-counter)
+(inc-counter)
+(inc-counter)
+(inc-counter)
+
+@counter ; => 5
+
+; Kaedah lain yang menggunakan STM ialah ref dan agent.
+; Ref: http://clojure.org/refs
+; Agent: http://clojure.org/agents
+```
+
+### Bacaan Lanjut
+
+Ini masih belum lengkap, tetapi harap-harap cukup untuk membuatkan anda lebih bersedia.
+
+Clojure.org mempunyai banyak artikel:
+[http://clojure.org/](http://clojure.org/)
+
+Clojuredocs.org mempunyai dokumentasi berserta contoh untuk menggunakan kebanyakan function teras:
+[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
+
+4Clojure ialah cara yang baik untuk mengasah skill Clojure dan functional programming:
+[http://www.4clojure.com/](http://www.4clojure.com/)
+
+Clojure-doc.org (yup, serius) juga mengandungi beberapa artikel sebagai permulaan:
+[http://clojure-doc.org/](http://clojure-doc.org/)
diff --git a/ms-my/common-lisp-my.html.markdown b/ms-my/common-lisp-my.html.markdown
new file mode 100644
index 00000000..f5914aae
--- /dev/null
+++ b/ms-my/common-lisp-my.html.markdown
@@ -0,0 +1,692 @@
+---
+
+language: "Common Lisp"
+filename: commonlisp-ms.lisp
+contributors:
+ - ["Paul Nathan", "https://github.com/pnathan"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
+translators:
+ - ["Burhanuddin Baharuddin", "https://github.com/burhanloey"]
+lang: ms-my
+---
+
+Common Lisp ialah programming language yang general-purpose (boleh digunakan untuk semua benda) dan multi-paradigm (konsep yang pelbagai) sesuai untuk pelbagai kegunaan di dalam
+industri aplikasi. Common Lisp biasa digelar sebagai programmable programming language (programming language yang boleh di-program-kan).
+
+Sumber bacaan yang klasik ialah [Practical Common Lisp](http://www.gigamonkeys.com/book/). Sumber bacaan yang lain dan
+yang terbaru ialah [Land of Lisp](http://landoflisp.com/). Buku baru mengenai best practices (amalan terbaik),
+[Common Lisp Recipes](http://weitz.de/cl-recipes/), baru sahaja diterbitkan.
+
+
+
+```common-lisp
+
+;;;-----------------------------------------------------------------------------
+;;; 0. Syntax
+;;;-----------------------------------------------------------------------------
+
+;;; General form (Bentuk umum)
+
+;;; Ada dua asas dalam syntax CL: ATOM dan S-EXPRESSION.
+;;; Kebiasaannya, gabungan S-expression dipanggil sebagai `forms`.
+
+10 ; atom; bermaksud seperti yang ditulis iaitu nombor 10
+:thing ; juga atom; bermaksud simbol :thing
+t ; juga atom, bermaksud true (ya/betul/benar)
+(+ 1 2 3 4) ; s-expression
+'(4 :foo t) ; juga s-expression
+
+
+;;; Comment (Komen)
+
+;;; Comment satu baris bermula dengan semicolon; gunakan empat untuk comment
+;;; mengenai file, tiga untuk seksyen penghuraian, dua untuk yang dalam definition,
+;;; dan satu untuk satu baris. Sebagai contoh,
+
+;;;; life.lisp
+
+;;; Foo bar baz, disebabkan quu quux. Sangat optimum untuk krakaboom dan umph.
+;;; Diperlukan oleh function LINULUKO. Ini merepek sahaja kebaboom.
+
+(defun meaning (life)
+ "Memulangkan hasil pengiraan makna KEHIDUPAN"
+ (let ((meh "abc"))
+ ;; Jalankan krakaboom
+ (loop :for x :across meh
+ :collect x))) ; Simpan hasil ke x, kemudian pulangkan
+
+;;; Komen berbentuk blok, sebaliknya, membenarkan komen untuk bentuk bebas. Komen
+;;; tersebut berada di antara #| dan |#
+
+#| Ini adalah komen berbentuk blok di mana
+ tulisan boleh ditulis dalam beberapa baris dan
+ #|
+ juga boleh dalam bentuk nested (berlapis-lapis)!
+ |#
+|#
+
+
+;;; Environment (benda-benda yang diperlukan untuk program menggunakan Common Lisp)
+
+;;; Common Lisp ada banyak jenis; kebanyakannya mengikut standard. SBCL
+;;; ialah titik permulaan yang baik. Quicklisp boleh digunakan untuk install
+;;; library third party.
+
+;;; CL kebiasaannya digunakan dengan text editor dan Real Eval Print
+;;; Loop (REPL) yang dilancarkan dengan serentak. REPL membolehkan kita menjelajah
+;;; program secara interaktif semasa program tersebut sedang berjalan secara "live".
+
+
+;;;-----------------------------------------------------------------------------
+;;; 1. Datatype primitif dan operator
+;;;-----------------------------------------------------------------------------
+
+;;; Simbol
+
+'foo ; => FOO Perhatikan simbol menjadi huruf besar secara automatik.
+
+;;; INTERN menjadikan string sebagai simbol secara manual.
+
+(intern "AAAA") ; => AAAA
+(intern "aaa") ; => |aaa|
+
+;;; Nombor
+
+9999999999999999999999 ; integer
+#b111 ; binary => 7
+#o111 ; octal => 73
+#x111 ; hexadecimal => 273
+3.14159s0 ; single
+3.14159d0 ; double
+1/2 ; ratio
+#C(1 2) ; complex number
+
+;;; Function ditulis sebagai (f x y z ...) di mana f ialah function dan
+;;; x, y, z, ... adalah argument.
+
+(+ 1 2) ; => 3
+
+;;; Jika anda ingin membuat data sebagai data bukannya function, gunakan QUOTE
+;;; untuk mengelakkan data tersebut daripada dikira oleh program
+
+(quote (+ 1 2)) ; => (+ 1 2)
+(quote a) ; => A
+
+;;; Singkatan untuk QUOTE ialah ' (tanda petikan)
+
+'(+ 1 2) ; => (+ 1 2)
+'a ; => A
+
+;;; Operasi arithmetic asas
+
+(+ 1 1) ; => 2
+(- 8 1) ; => 7
+(* 10 2) ; => 20
+(expt 2 3) ; => 8
+(mod 5 2) ; => 1
+(/ 35 5) ; => 7
+(/ 1 3) ; => 1/3
+(+ #C(1 2) #C(6 -4)) ; => #C(7 -2)
+
+;;; Boolean
+
+t ; true; semua nilai yang bukan NIL ialah true
+nil ; false; termasuklah list yang kosong: ()
+(not nil) ; => T
+(and 0 t) ; => T
+(or 0 nil) ; => 0
+
+;;; Character
+
+#\A ; => #\A
+#\λ ; => #\GREEK_SMALL_LETTER_LAMDA
+#\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA
+
+;;; String ialah array character yang tidak berubah panjang
+
+"Hello, world!"
+"Benjamin \"Bugsy\" Siegel" ; backslash ialah escape character
+
+;;; String boleh digabungkan
+
+(concatenate 'string "Hello, " "world!") ; => "Hello, world!"
+
+;;; String boleh diperlakukan seperti urutan character
+
+(elt "Apple" 0) ; => #\A
+
+;;; FORMAT digunakan untuk output mengikut format, daripada penggubahan string
+;;; yang simple sehinggalah loop dan conditional. Argument pertama untuk FORMAT
+;;; menentukan ke mana string akan pergi. Jika NIL, FORMAT
+;;; akan pulangkan string sebagai data string; jika T, FORMAT akan output
+;;; ke standard output, biasanya di screen, kemudian pulangkan NIL.
+
+(format nil "~A, ~A!" "Hello" "world") ; => "Hello, world!"
+(format t "~A, ~A!" "Hello" "world") ; => NIL
+
+
+;;;-----------------------------------------------------------------------------
+;;; 2. Variable
+;;;-----------------------------------------------------------------------------
+
+;;; Anda boleh membuat variable global (dynamically scoped) menggunakan DEFVAR dan
+;;; DEFPARAMETER. Nama variable boleh guna mana-mana character kecuali: ()",'`;#|\
+
+;;; Beza antara DEFVAR dengan DEFPARAMETER ialah DEFVAR tidak akan ubah nilai
+;;; variable jika dijalankan semula. Manakala DEFPARAMETER, akan mengubah nilai
+;;; jika dijalankan semula.
+
+;;; Kebiasaannya, variable global diletakkan earmuff (asterisk) pada nama.
+
+(defparameter *some-var* 5)
+*some-var* ; => 5
+
+;;; Anda juga boleh menggunakan character unicode.
+(defparameter *AΛB* nil)
+
+;;; Variable yang tidak wujud boleh diakses tetapi akan menyebabkan undefined
+;;; behavior. Jangan buat.
+
+;;; Anda boleh membuat local binding menggunakan LET. Dalam snippet berikut, `me`
+;;; terikat dengan "dance with you" hanya dalam (let ...). LET mesti akan pulangkan
+;;; nilai `form` yang paling terakhir.
+
+(let ((me "dance with you")) me) ; => "dance with you"
+
+
+;;;-----------------------------------------------------------------------------;
+;;; 3. Struct dan collection
+;;;-----------------------------------------------------------------------------;
+
+
+;;; Struct
+
+(defstruct dog name breed age)
+(defparameter *rover*
+ (make-dog :name "rover"
+ :breed "collie"
+ :age 5))
+*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
+(dog-p *rover*) ; => T
+(dog-name *rover*) ; => "rover"
+
+;;; DOG-P, MAKE-DOG, dan DOG-NAME semuanya dibuat oleh DEFSTRUCT secara automatik
+
+
+;;; Pair
+
+;;; CONS membuat pair. CAR dan CDR pulangkan head (kepala) dan tail (ekor) CONS-pair.
+
+(cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB)
+(car (cons 'SUBJECT 'VERB)) ; => SUBJECT
+(cdr (cons 'SUBJECT 'VERB)) ; => VERB
+
+
+;;; List
+
+;;; List ialah data structure linked-list, dihasilkan daripada pair CONS dan
+;;; berakhir dengan NIL (atau '()) menandakan akhirnya list tersebut
+
+(cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3)
+
+;;; LIST ialah constructor untuk memudahkan penghasilan list
+
+(list 1 2 3) ; => '(1 2 3)
+
+;;; Apabila argument pertama untuk CONS ialah atom dan argument kedua ialah
+;;; list, CONS akan pulangkan CONS-pair baru dengan argument pertama sebagai
+;;; item pertama dan argument kedua sebagai CONS-pair yang lain
+
+(cons 4 '(1 2 3)) ; => '(4 1 2 3)
+
+;;; Gunakan APPEND untuk menggabungkan list
+
+(append '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;;; Atau CONCATENATE
+
+(concatenate 'list '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;;; List ialah type utama, jadi ada pelbagai function untuk mengendalikan
+;;; list, contohnya:
+
+(mapcar #'1+ '(1 2 3)) ; => '(2 3 4)
+(mapcar #'+ '(1 2 3) '(10 20 30)) ; => '(11 22 33)
+(remove-if-not #'evenp '(1 2 3 4)) ; => '(2 4)
+(every #'evenp '(1 2 3 4)) ; => NIL
+(some #'oddp '(1 2 3 4)) ; => T
+(butlast '(subject verb object)) ; => (SUBJECT VERB)
+
+
+;;; Vector
+
+;;; Vector ialah array yang tidak berubah panjang
+
+#(1 2 3) ; => #(1 2 3)
+
+;;; Gunakan CONCATENATE untuk menggabungkan vector
+
+(concatenate 'vector #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
+
+
+;;; Array
+
+;;; Vector dan string adalah sejenis array.
+
+;;; 2D array
+
+(make-array (list 2 2)) ; => #2A((0 0) (0 0))
+(make-array '(2 2)) ; => #2A((0 0) (0 0))
+(make-array (list 2 2 2)) ; => #3A(((0 0) (0 0)) ((0 0) (0 0)))
+
+;;; Perhatian: nilai awal MAKE-ARRAY adalah bergantung kepada jenis Common Lisp.
+;;; Untuk meletakkan nilai awal secara manual:
+
+(make-array '(2) :initial-element 'unset) ; => #(UNSET UNSET)
+
+;;; Untuk mengakses element di kedudukan 1, 1, 1:
+
+(aref (make-array (list 2 2 2)) 1 1 1) ; => 0
+
+
+;;; Adjustable vector (vector yang boleh berubah)
+
+;;; Adjustable vector mempunyai rupa yang sama dengan
+;;; vector yang tidak berubah panjang.
+
+(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3)
+ :adjustable t :fill-pointer t))
+*adjvec* ; => #(1 2 3)
+
+;;; Tambah element baru
+
+(vector-push-extend 4 *adjvec*) ; => 3
+*adjvec* ; => #(1 2 3 4)
+
+
+;;; Set hanyalah list:
+
+(set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1)
+(intersection '(1 2 3 4) '(4 5 6 7)) ; => 4
+(union '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1 4 5 6 7)
+(adjoin 4 '(1 2 3 4)) ; => (1 2 3 4)
+
+;;; Tetapi, anda perlukan data structure yang lebih baik untuk digunakan dengan
+;;; data set yang sangat banyak
+
+;;; Kamus dibuat menggunakan hash table.
+
+;;; Bina hash table
+
+(defparameter *m* (make-hash-table))
+
+;;; Tetapkan nilai
+
+(setf (gethash 'a *m*) 1)
+
+;;; Baca nilai
+
+(gethash 'a *m*) ; => 1, T
+
+;;; CL boleh memulangkan beberapa nilai (multiple value).
+
+(values 1 2) ; => 1, 2
+
+;;; dan boleh digunakan dengan MULTIPLE-VALUE-BIND untuk bind setiap nilai
+
+(multiple-value-bind (x y)
+ (values 1 2)
+ (list y x))
+
+; => '(2 1)
+
+;;; GETHASH antara contoh function yang memulangkan multiple value. Value
+;;; pertama ialah nilai untuk key dalam hash table; jika key tidak
+;;; jumpa GETHASH akan pulangkan NIL.
+
+;;; Value kedua menentukan sama ada key tersebut betul-betul wujud dalam hash
+;;; table. Jika key tidak jumpa dalam table value tersebut ialah NIL. Cara ini
+;;; membolehkan kita untuk periksa sama ada value untuk key ialah NIL.
+
+;;; Dapatkan value yang tidak wujud akan pulangkan nil
+
+(gethash 'd *m*) ;=> NIL, NIL
+
+;;; Anda boleh menentukan value default untuk key yang tidak wujud
+
+(gethash 'd *m* :not-found) ; => :NOT-FOUND
+
+;;; Jom lihat penggunaan multiple return value di dalam code.
+
+(multiple-value-bind (a b)
+ (gethash 'd *m*)
+ (list a b))
+; => (NIL NIL)
+
+(multiple-value-bind (a b)
+ (gethash 'a *m*)
+ (list a b))
+; => (1 T)
+
+
+;;;-----------------------------------------------------------------------------
+;;; 3. Function
+;;;-----------------------------------------------------------------------------
+
+;;; Gunakan LAMBDA untuk membuat anonymous function. Function sentiasa memulangkan
+;;; value untuk expression terakhir.
+
+(lambda () "Hello World") ; => #<FUNCTION (LAMBDA ()) {1004E7818B}>
+
+;;; Gunakan FUNCALL untuk memanggil anonymous function
+
+(funcall (lambda () "Hello World")) ; => "Hello World"
+(funcall #'+ 1 2 3) ; => 6
+
+;;; Panggilan kepada FUNCALL juga boleh terjadi apabila lambda tersebut ialah CAR
+;;; (yang pertama) untuk list (yang tidak mempunyai tanda petikan)
+
+((lambda () "Hello World")) ; => "Hello World"
+((lambda (val) val) "Hello World") ; => "Hello World"
+
+;;; FUNCALL digunakan apabila argument sudah diketahui. Jika tidak, gunakan APPLY
+
+(apply #'+ '(1 2 3)) ; => 6
+(apply (lambda () "Hello World") nil) ; => "Hello World"
+
+;;; Untuk menamakan sebuah function, guna DEFUN
+
+(defun hello-world () "Hello World")
+(hello-world) ; => "Hello World"
+
+;;; Simbol () di atas bermaksud list kepada argument
+
+(defun hello (name) (format nil "Hello, ~A" name))
+(hello "Steve") ; => "Hello, Steve"
+
+;;; Function boleh ada argument optional (tidak wajib); argument tersebut bernilai
+;;; NIL secara default
+
+(defun hello (name &optional from)
+ (if from
+ (format t "Hello, ~A, from ~A" name from)
+ (format t "Hello, ~A" name)))
+
+(hello "Jim" "Alpacas") ; => Hello, Jim, from Alpacas
+
+;;; Nilai default boleh ditetapkan untuk argument tersebut
+
+(defun hello (name &optional (from "The world"))
+ (format nil "Hello, ~A, from ~A" name from))
+
+(hello "Steve") ; => Hello, Steve, from The world
+(hello "Steve" "the alpacas") ; => Hello, Steve, from the alpacas
+
+;;; Function juga mempunyai keyword argument untuk membolehkan argument diletakkan
+;;; tidak mengikut kedudukan
+
+(defun generalized-greeter (name &key (from "the world") (honorific "Mx"))
+ (format t "Hello, ~A ~A, from ~A" honorific name from))
+
+(generalized-greeter "Jim")
+; => Hello, Mx Jim, from the world
+
+(generalized-greeter "Jim" :from "the alpacas you met last summer" :honorific "Mr")
+; => Hello, Mr Jim, from the alpacas you met last summer
+
+
+;;;-----------------------------------------------------------------------------
+;;; 4. Kesamaan
+;;;-----------------------------------------------------------------------------
+
+;;; CL mempunyai sistem kesaksamaan yang canggih. Antaranya adalah seperti berikut.
+
+;;; Untuk nombor, guna `='
+(= 3 3.0) ; => T
+(= 2 1) ; => NIL
+
+;;; Untuk identiti object (lebih kurang) guna EQL
+(eql 3 3) ; => T
+(eql 3 3.0) ; => NIL
+(eql (list 3) (list 3)) ; => NIL
+
+;;; untuk list, string, dan bit-vector, guna EQUAL
+(equal (list 'a 'b) (list 'a 'b)) ; => T
+(equal (list 'a 'b) (list 'b 'a)) ; => NIL
+
+
+;;;-----------------------------------------------------------------------------
+;;; 5. Control Flow
+;;;-----------------------------------------------------------------------------
+
+;;; Conditional (syarat)
+
+(if t ; test expression
+ "this is true" ; then expression
+ "this is false") ; else expression
+; => "this is true"
+
+;;; Dalam conditional, semua value yang bukan NIL ialah true
+
+(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(GROUCHO ZEPPO)
+(if (member 'Groucho '(Harpo Groucho Zeppo))
+ 'yep
+ 'nope)
+; => 'YEP
+
+;;; Guna COND untuk meletakkan beberapa test
+(cond ((> 2 2) (error "wrong!"))
+ ((< 2 2) (error "wrong again!"))
+ (t 'ok)) ; => 'OK
+
+;;; TYPECASE adalah seperti switch tetapi untuk data type value tersebut
+(typecase 1
+ (string :string)
+ (integer :int))
+; => :int
+
+
+;;; Loop
+
+;;; Recursion
+
+(defun fact (n)
+ (if (< n 2)
+ 1
+ (* n (fact(- n 1)))))
+
+(fact 5) ; => 120
+
+;;; Iteration
+
+(defun fact (n)
+ (loop :for result = 1 :then (* result i)
+ :for i :from 2 :to n
+ :finally (return result)))
+
+(fact 5) ; => 120
+
+(loop :for x :across "abc" :collect x)
+; => (#\a #\b #\c #\d)
+
+(dolist (i '(1 2 3 4))
+ (format t "~A" i))
+; => 1234
+
+
+;;;-----------------------------------------------------------------------------
+;;; 6. Mutation
+;;;-----------------------------------------------------------------------------
+
+;;; Guna SETF untuk meletakkan nilai baru untuk variable yang sedia ada. Ini sama
+;;; seperti contoh hash table di atas.
+
+(let ((variable 10))
+ (setf variable 2))
+; => 2
+
+;;; Sebaik-baiknya kurangkan penggunaan destructive function dan elakkan
+;;; mutation jika boleh.
+
+
+;;;-----------------------------------------------------------------------------
+;;; 7. Class dan object
+;;;-----------------------------------------------------------------------------
+
+;;; Takde dah class untuk haiwan. Jom buat Human-Powered Mechanical
+;;; Conveyances (Kenderaan Mekanikal Berkuasa Manusia).
+
+(defclass human-powered-conveyance ()
+ ((velocity
+ :accessor velocity
+ :initarg :velocity)
+ (average-efficiency
+ :accessor average-efficiency
+ :initarg :average-efficiency))
+ (:documentation "A human powered conveyance"))
+
+;;; Argument untuk DEFCLASS, mengikut susunan ialah:
+;;; 1. nama class
+;;; 2. list untuk superclass
+;;; 3. list untuk slot
+;;; 4. specifier optional (tidak wajib)
+
+;;; Apabile list untuk superclass tidak ditetapkan, list yang kosong bermaksud
+;;; class standard-object. Ini *boleh* ditukar, kalau anda tahu apa yang anda buat.
+;;; Baca Art of the Metaobject Protocol untuk maklumat lebih lanjut.
+
+(defclass bicycle (human-powered-conveyance)
+ ((wheel-size
+ :accessor wheel-size
+ :initarg :wheel-size
+ :documentation "Diameter of the wheel.")
+ (height
+ :accessor height
+ :initarg :height)))
+
+(defclass recumbent (bicycle)
+ ((chain-type
+ :accessor chain-type
+ :initarg :chain-type)))
+
+(defclass unicycle (human-powered-conveyance) nil)
+
+(defclass canoe (human-powered-conveyance)
+ ((number-of-rowers
+ :accessor number-of-rowers
+ :initarg :number-of-rowers)))
+
+;;; Panggilan DESCRIBE kepada class HUMAN-POWERED-CONVEYANCE di REPL akan memberi:
+
+(describe 'human-powered-conveyance)
+
+; COMMON-LISP-USER::HUMAN-POWERED-CONVEYANCE
+; [symbol]
+;
+; HUMAN-POWERED-CONVEYANCE names the standard-class #<STANDARD-CLASS
+; HUMAN-POWERED-CONVEYANCE>:
+; Documentation:
+; A human powered conveyance
+; Direct superclasses: STANDARD-OBJECT
+; Direct subclasses: UNICYCLE, BICYCLE, CANOE
+; Not yet finalized.
+; Direct slots:
+; VELOCITY
+; Readers: VELOCITY
+; Writers: (SETF VELOCITY)
+; AVERAGE-EFFICIENCY
+; Readers: AVERAGE-EFFICIENCY
+; Writers: (SETF AVERAGE-EFFICIENCY)
+
+;;; Perhatikan apa yang berlaku. CL memang direka sebagai sistem interaktif.
+
+;;; Untuk membuat method, jom kira berapa panjang lilitan untuk
+;;; roda basikal menggunakan formula: C = d * pi
+
+(defmethod circumference ((object bicycle))
+ (* pi (wheel-size object)))
+
+;;; Nilai PI memang sudah ada dalam CL
+
+;;; Katakanlah kita ingin ambil tahu efficiency value (nilai keberkesanan)
+;;; rower (pendayung) di dalam canoe (perahu) adalah berbentuk logarithmic. Ini
+;;; boleh ditetapkan di dalam constructor/initializer.
+
+;;; Untuk initialize instance selepas CL sudah siap construct:
+
+(defmethod initialize-instance :after ((object canoe) &rest args)
+ (setf (average-efficiency object) (log (1+ (number-of-rowers object)))))
+
+;;; Kemudian untuk construct sesebuah instance dan periksa purata efficiency...
+
+(average-efficiency (make-instance 'canoe :number-of-rowers 15))
+; => 2.7725887
+
+
+;;;-----------------------------------------------------------------------------
+;;; 8. Macro
+;;;-----------------------------------------------------------------------------
+
+;;; Macro membolehkan anda untuk menambah syntax language. CL tidak ada
+;;; WHILE loop, tetapi, kita boleh mencipta syntax ter. Jika kita buat menggunakan
+;;; naluri, kita akan dapat:
+
+(defmacro while (condition &body body)
+ "While `condition` is true, `body` is executed.
+`condition` is tested prior to each execution of `body`"
+ (let ((block-name (gensym)) (done (gensym)))
+ `(tagbody
+ ,block-name
+ (unless ,condition
+ (go ,done))
+ (progn
+ ,@body)
+ (go ,block-name)
+ ,done)))
+
+;;; Jom lihat versi yang lebih high-level:
+
+(defmacro while (condition &body body)
+ "While `condition` is true, `body` is executed.
+`condition` is tested prior to each execution of `body`"
+ `(loop while ,condition
+ do
+ (progn
+ ,@body)))
+
+;;; Namun, dengan compiler yang modern, cara ini tidak diperlukan; form LOOP
+;;; compile sama sahaja dan juga mudah dibaca.
+
+;;; Perhatikan ``` digunakan, sama juga `,` dan `@`. ``` ialah operator jenis quote
+;;; yang dipanggil quasiquote; operator tersebut membolehkan penggunaan `,` .
+;;; `,` membolehkan variable "di-unquote-kan". @ mengembangkan list.
+
+;;; GENSYM membuat simbol unik yang pasti tidak wujud di tempat-tempat yang
+;;; lain. Ini kerana macro dikembangkan semasa compile dan
+;;; nama variable di dalam macro boleh bertembung dengan nama variable yang
+;;; digunakan dalam code yang biasa.
+
+;;; Baca Practical Common Lisp dan On Lisp untuk maklumat lebih lanjut mengenai macro.
+```
+
+
+## Bacaan lanjut
+
+- [Practical Common Lisp](http://www.gigamonkeys.com/book/)
+- [Common Lisp: A Gentle Introduction to Symbolic Computation](https://www.cs.cmu.edu/~dst/LispBook/book.pdf)
+
+
+## Maklumat tambahan
+
+- [CLiki](http://www.cliki.net/)
+- [common-lisp.net](https://common-lisp.net/)
+- [Awesome Common Lisp](https://github.com/CodyReichert/awesome-cl)
+- [Lisp Lang](http://lisp-lang.org/)
+
+
+## Kredit
+
+Terima kasih banyak diucapkan kepada ahli Scheme yang membuat permulaan yang sangat
+bagus dan mudah untuk diguna pakai untuk Common Lisp.
+
+- [Paul Khuong](https://github.com/pkhuong) untuk review yang bagus.
diff --git a/ms-my/elisp-my.html.markdown b/ms-my/elisp-my.html.markdown
new file mode 100644
index 00000000..73dff0f4
--- /dev/null
+++ b/ms-my/elisp-my.html.markdown
@@ -0,0 +1,347 @@
+---
+language: elisp
+contributors:
+ - ["Bastien Guerry", "https://bzg.fr"]
+ - ["Saurabh Sandav", "http://github.com/SaurabhSandav"]
+translators:
+ - ["Burhanuddin Baharuddin", "https://github.com/burhanloey"]
+lang: ms-my
+filename: learn-emacs-lisp-ms.el
+---
+
+```scheme
+;; Ini adalah pengenalan kepada Emacs Lisp dalam masa 15 minit (v0.2d)
+;;
+;; Mula-mula pastikan anda sudah membaca artikel daripada Peter Norvig ini:
+;; http://norvig.com/21-days.html
+;;
+;; Kemudian install GNU Emacs 24.3:
+;;
+;; Debian: apt-get install emacs (atau lihat arahan untuk distro anda)
+;; OSX: http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg
+;; Windows: http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip
+;;
+;; Maklumat lanjut boleh didapati di:
+;; http://www.gnu.org/software/emacs/#Obtaining
+
+;; Amaran penting:
+;;
+;; Tutorial ini tidak akan merosakkan komputer anda melainkan jika anda berasa
+;; terlalu marah sehingga anda menghempap komputer anda ke lantai. Kalau begitu,
+;; saya dengan ini tidak akan bertanggungjawab terhadap apa-apa. Berseronoklah ya!
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Buka Emacs.
+;;
+;; Tekan `q' untuk tutup mesej selamat datang.
+;;
+;; Sekarang lihat garis kelabu di bahagian bawah window:
+;;
+;; "*scratch*" ialah nama ruangan untuk anda edit.
+;; Ruangan ini disebut sebagai "buffer".
+;;
+;; Buffer scratch ialah buffer yang default setiap kali Emacs dibuka.
+;; Anda bukannya edit file: anda edit buffer yang kemudiannya
+;; boleh save ke file.
+;;
+;; "Lisp interaction (interaksi)" merujuk kepada command yang wujud di sini.
+;;
+;; Emacs mempunyai beberapa command yang sedia ada dalam setiap buffer,
+;; dan sesetengah command yang lain boleh didapati jika sesetengah mode
+;; diaktifkan. Di sini kita menggunakan `lisp-interaction-mode', yang
+;; mempunyai command untuk menjalankan dan mengendalikan code Elisp.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Semicolon akan menjadikan comment sepanjang baris tersebut.
+;;
+;; Program Elisp mengandungi symbolic expressions ("sexps"):
+(+ 2 2)
+
+;; Symbolic expression di atas dibaca begini "Tambah 2 pada 2".
+
+;; Sexps dilitupi oleh parentheses, dan boleh dalam bentuk nested (parentheses
+;; dalam parentheses):
+(+ 2 (+ 1 1))
+
+;; Symbolic expression mengandungi atom atau symbolic expression
+;; yang lain. Untuk contoh di atas, 1 dan 2 ialah atom,
+;; (+ 2 (+ 1 1)) dan (+ 1 1) ialah symbolic expression.
+
+;; Dengan menggunakan `lisp-interaction-mode', anda boleh evaluate
+;; (mendapatkan hasil pengiraan) sexps. Letak cursor selepas parenthesis penutup
+;; kemudian tekan control dan j ("C-j").
+
+(+ 3 (+ 1 2))
+;; ^ cursor di sini
+;; `C-j' => 6
+
+;; `C-j' memasukkan jawapan pengiraan ke dalam buffer.
+
+;; `C-xC-e' memaparkan jawapan yang sama di bahagian bawah Emacs,
+;; yang dipanggil "minibuffer". Secara umumnya kita akan menggunakan `C-xC-e',
+;; sebab kita tidak mahu memenuhi buffer dengan teks yang tidak penting.
+
+;; `setq' menyimpan value ke dalam variable:
+(setq my-name "Bastien")
+;; `C-xC-e' => "Bastien" (terpapar di mini-buffer)
+
+;; `insert' akan memasukkan "Hello!" di tempat di mana cursor berada:
+(insert "Hello!")
+;; `C-xC-e' => "Hello!"
+
+;; Di atas, kita menggunakan `insert' dengan satu argument "Hello!", tetapi
+;; kita boleh meletakkan beberapa argument -- di sini kita letak dua:
+
+(insert "Hello" " world!")
+;; `C-xC-e' => "Hello world!"
+
+;; Anda boleh menggunakan variable selain string:
+(insert "Hello, I am " my-name)
+;; `C-xC-e' => "Hello, I am Bastien"
+
+;; Anda boleh menggabungkan sexps untuk membuat function:
+(defun hello () (insert "Hello, I am " my-name))
+;; `C-xC-e' => hello
+
+;; Anda boleh evaluate function:
+(hello)
+;; `C-xC-e' => Hello, I am Bastien
+
+;; Parentheses kosong di dalam function bermaksud function tersebut tidak
+;; terima argument. Sekarang kita tukar function untuk menerima satu argument.
+;; Di sini, argument tersebut dinamakan "name":
+
+(defun hello (name) (insert "Hello " name))
+;; `C-xC-e' => hello
+
+;; Sekarang panggil function tersebut dengan string "you" sebagai value
+;; untuk argument:
+(hello "you")
+;; `C-xC-e' => "Hello you"
+
+;; Yay!
+
+;; Tarik nafas.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Sekarang tukar ke buffer baru dengan nama "*test*" di window yang lain:
+
+(switch-to-buffer-other-window "*test*")
+;; `C-xC-e'
+;; => [The screen has two windows and cursor is in the *test* buffer]
+
+;; Gerakkan mouse ke window atas dan klik kiri untuk pergi balik ke buffer scratch.
+;; Cara lain adalah dengan menggunakan `C-xo' (i.e. tekan control-x kemudian
+;; tekan o) untuk pergi ke window yang lain.
+
+;; Anda boleh menggabungkan beberapa sexps menggunakan `progn':
+(progn
+ (switch-to-buffer-other-window "*test*")
+ (hello "you"))
+;; `C-xC-e'
+;; => [The screen has two windows and cursor is in the *test* buffer]
+
+;; Mulai dari sekarang saya tidak akan beritahu anda untuk tekan `C-xC-e' lagi:
+;; buat untuk setiap sexp yang akan datang.
+
+;; Pergi balik ke buffer *scratch* menggunakan mouse atau `C-xo'.
+
+;; Seelok-eloknya padam buffer tersebut:
+(progn
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (hello "there"))
+
+;; Atau pergi balik ke window lain:
+(progn
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (hello "you")
+ (other-window 1))
+
+;; Anda boleh menetapkan value dengan local variable menggunakan `let':
+(let ((local-name "you"))
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (hello local-name)
+ (other-window 1))
+
+;; Tidak perlu menggunakan `progn', sebab `let' juga menggabungkan
+;; beberapa sexps.
+
+;; Jom format string:
+(format "Hello %s!\n" "visitor")
+
+;; %s ialah tempat untuk meletakkan string, digantikan dengan "visitor".
+;; \n ialah character untuk membuat baris baru.
+
+;; Jom tukar function kita menggunakan format:
+(defun hello (name)
+ (insert (format "Hello %s!\n" name)))
+
+(hello "you")
+
+;; Jom buat function lain menggunakan `let':
+(defun greeting (name)
+ (let ((your-name "Bastien"))
+ (insert (format "Hello %s!\n\nI am %s."
+ name ; argument untuk function
+ your-name ; variable "Bastien" daripada let
+ ))))
+
+;; Kemudian evaluate:
+(greeting "you")
+
+;; Sesetengah function adalah interaktif:
+(read-from-minibuffer "Enter your name: ")
+
+;; Function tersebut akan memulangkan kembali apa yang anda masukkan ke prompt.
+
+;; Jom jadikan function `greeting' untuk prompt nama anda:
+(defun greeting (from-name)
+ (let ((your-name (read-from-minibuffer "Enter your name: ")))
+ (insert (format "Hello!\n\nI am %s and you are %s."
+ from-name ; argument untuk function
+ your-name ; variable daripada let, yang dimasukkan dari prompt
+ ))))
+
+(greeting "Bastien")
+
+;; Jom siapkan function dengan memaparkan result di window yang lain:
+(defun greeting (from-name)
+ (let ((your-name (read-from-minibuffer "Enter your name: ")))
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (insert (format "Hello %s!\n\nI am %s." your-name from-name))
+ (other-window 1)))
+
+;; Test function tersebut:
+(greeting "Bastien")
+
+;; Tarik nafas.
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Jom simpan senarai nama:
+;; Jika anda ingin membuat list(senarai) data, guna ' untuk elak
+;; daripada list tersebut evaluate.
+(setq list-of-names '("Sarah" "Chloe" "Mathilde"))
+
+;; Dapatkan elemen pertama daripada list menggunakan `car':
+(car list-of-names)
+
+;; Dapatkan semua elemen kecuali yang pertama menggunakan `cdr':
+(cdr list-of-names)
+
+;; Tambah elemen di awal list menggunakan `push':
+(push "Stephanie" list-of-names)
+
+;; NOTA: `car' dan `cdr' tidak ubah suai list, tetapi `push' ya.
+;; Perbezaan ini penting: sesetengah function tiada side-effects (kesan sampingan)
+;; (seperti `car') dan yang lain ada side-effect (seperti `push').
+
+;; Jom panggil `hello' untuk setiap elemen dalam `list-of-names':
+(mapcar 'hello list-of-names)
+
+;; Tukar `greeting' supaya ucapkan hello kepada semua orang dalam `list-of-names':
+(defun greeting ()
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ (mapcar 'hello list-of-names)
+ (other-window 1))
+
+(greeting)
+
+;; Ingat lagi function `hello' di atas? Function tersebut mengambil satu
+;; argument, iaitu nama. `mapcar' memanggil `hello', kemudian menggunakan setiap
+;; nama dalam `list-of-names' sebagai argument untuk function `hello'.
+
+;; Sekarang kita susun sedikit untuk apa yang terpapar di buffer:
+
+(defun replace-hello-by-bonjour ()
+ (switch-to-buffer-other-window "*test*")
+ (goto-char (point-min))
+ (while (search-forward "Hello")
+ (replace-match "Bonjour"))
+ (other-window 1))
+
+;; (goto-char (point-min)) akan pergi ke permulaan buffer.
+;; (search-forward "Hello") akan mencari string "Hello".
+;; (while x y) evaluate sexp(s) y selagi x masih pulangkan sesuatu.
+;; Jika x pulangkan `nil', kita akan keluar daripada while loop.
+
+(replace-hello-by-bonjour)
+
+;; Anda akan dapat melihat semua "Hello" dalam buffer *test*
+;; ditukarkan dengan "Bonjour".
+
+;; Anda juga akan dapat error: "Search failed: Hello".
+;;
+;; Bagi mengelakkan error tersebut, anda perlu beritahu `search-forward' sama ada
+;; perlu berhenti mencari pada suatu ketika, dan sama ada perlu diam jika
+;; tidak jumpa apa yang dicari:
+
+;; (search-forward "Hello" nil 't) selesai masalah:
+
+;; Argument `nil' cakap: carian tidak mengikut kedudukan.
+;; Argument `'t' cakap: diam saja jika tidak jumpa apa yang dicari.
+
+;; Kita guna sexp ini di function berikut, barulah tidak keluar error:
+
+(defun hello-to-bonjour ()
+ (switch-to-buffer-other-window "*test*")
+ (erase-buffer)
+ ;; Ucap hello pada nama-nama dalam `list-of-names'
+ (mapcar 'hello list-of-names)
+ (goto-char (point-min))
+ ;; Ganti "Hello" dengan "Bonjour"
+ (while (search-forward "Hello" nil 't)
+ (replace-match "Bonjour"))
+ (other-window 1))
+
+(hello-to-bonjour)
+
+;; Jom jadikan nama-nama tersebut bold:
+
+(defun boldify-names ()
+ (switch-to-buffer-other-window "*test*")
+ (goto-char (point-min))
+ (while (re-search-forward "Bonjour \\(.+\\)!" nil 't)
+ (add-text-properties (match-beginning 1)
+ (match-end 1)
+ (list 'face 'bold)))
+ (other-window 1))
+
+;; Function ini memperkenalkan `re-search-forward': anda mencari menggunakan
+;; pattern iaitu "regular expression", bukannya mencari string "Bonjour".
+
+;; Regular expression tersebut ialah "Bonjour \\(.+\\)!" dan dibaca begini:
+;; string "Bonjour ", dan
+;; kumpulan | ini ialah \\( ... \\)
+;; mana-mana character | ini ialah .
+;; yang boleh berulang | ini ialah +
+;; dan string "!".
+
+;; Dah sedia? Test function tersebut!
+
+(boldify-names)
+
+;; `add-text-properties' tambah... ciri-ciri teks, seperti face.
+
+;; OK, kita sudah selesai. Selamat ber-hacking!
+
+;; Jika anda ingin tahu lebih mengenai variable atau function:
+;;
+;; C-h v a-variable RET
+;; C-h f a-function RET
+;;
+;; Jika anda ingin membaca manual Emacs Lisp menggunakan Emacs:
+;;
+;; C-h i m elisp RET
+;;
+;; Jika ingin membaca pengenalan kepada Emacs Lisp secara online:
+;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html
+```
diff --git a/ms-my/javascript-my.html.markdown b/ms-my/javascript-my.html.markdown
index 90e37133..9a7a23ba 100644
--- a/ms-my/javascript-my.html.markdown
+++ b/ms-my/javascript-my.html.markdown
@@ -1,7 +1,7 @@
---
language: javascript
contributors:
- - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Leigh Brenecki", "https://leigh.net.au"]
- ["Ariel Krakowski", "http://www.learneroo.com"]
filename: javascript-ms.js
translators:
diff --git a/nim.html.markdown b/nim.html.markdown
index 5d00304d..9730e579 100644
--- a/nim.html.markdown
+++ b/nim.html.markdown
@@ -12,10 +12,23 @@ that gives the programmer power without compromises on runtime efficiency.
Nim is efficient, expressive, and elegant.
```nim
+# Single-line comments start with a #
+
+#[
+ This is a multiline comment.
+ In Nim, multiline comments can be nested, beginning with #[
+ ... and ending with ]#
+]#
+
+discard """
+This can also work as a multiline comment.
+Or for unparsable, broken code
+"""
+
var # Declare (and assign) variables,
letter: char = 'n' # with or without type annotations
lang = "N" & "im"
- nLength : int = len(lang)
+ nLength: int = len(lang)
boat: float
truth: bool = false
@@ -35,10 +48,6 @@ when compileBadCode: # `when` is a compile time `if`
discard 1 > 2 # Note: The compiler will complain if the result of an expression
# is unused. `discard` bypasses this.
-discard """
-This can work as a multiline comment.
-Or for unparsable, broken code
-"""
#
# Data Structures
@@ -76,7 +85,7 @@ let myDrink = drinks[2]
# static typing powerful and useful.
type
- Name = string # A type alias gives you a new type that is interchangable
+ Name = string # A type alias gives you a new type that is interchangeable
Age = int # with the old type but is more descriptive.
Person = tuple[name: Name, age: Age] # Define data structures too.
AnotherSyntax = tuple
@@ -109,7 +118,7 @@ when compileBadCode:
type
Color = enum cRed, cBlue, cGreen
- Direction = enum # Alternative formating
+ Direction = enum # Alternative formatting
dNorth
dWest
dEast
diff --git a/nix.html.markdown b/nix.html.markdown
index ef59a135..dde5dbec 100644
--- a/nix.html.markdown
+++ b/nix.html.markdown
@@ -3,6 +3,8 @@ language: nix
filename: learn.nix
contributors:
- ["Chris Martin", "http://chris-martin.org/"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
+ - ["Javier Candeira", "https://candeira.com/"]
---
Nix is a simple functional language developed for the
@@ -11,7 +13,7 @@ Nix is a simple functional language developed for the
You can evaluate Nix expressions using
[nix-instantiate](https://nixos.org/nix/manual/#sec-nix-instantiate)
-or [`nix-repl`](https://github.com/edolstra/nix-repl).
+or [`nix repl`](https://nixos.org/nix/manual/#ssec-relnotes-2.0).
```
with builtins; [
@@ -38,18 +40,26 @@ with builtins; [
#=> "a"
- # Integers
+ # Integers and Floats
#=========================================
- # Integers are the only numeric type.
+ # There are two numeric types: integers and floats
1 0 42 (-3) # Some integers
+ 123.43 .27e13 # A couple of floats
+
+ # Operations will preserve numeric type
+
(4 + 6 + 12 - 2) # Addition
#=> 20
+ (4 - 2.5)
+ #=> 1.5
(7 / 2) # Division
#=> 3
+ (7 / 2.0)
+ #=> 3.5
# Strings
@@ -208,6 +218,12 @@ with builtins; [
{ a = 1; b = 2; }.a
#=> 1
+ # The ? operator tests whether a key is present in a set.
+ ({ a = 1; b = 2; } ? a)
+ #=> true
+ ({ a = 1; b = 2; } ? c)
+ #=> false
+
# The // operator merges two sets.
({ a = 1; } // { b = 2; })
#=> { a = 1; b = 2; }
@@ -231,13 +247,20 @@ with builtins; [
}.a.c
#=> { d = 2; e = 3; }
- # An attribute's descendants cannot be assigned in this
- # way if the attribute itself has been directly assigned.
+ # Sets are immutable, so you can't redefine an attribute:
+ {
+ a = { b = 1; };
+ a.b = 2;
+ }
+ #=> attribute 'a.b' at (string):3:5 already defined at (string):2:11
+
+ # However, an attribute's set members can also be defined piecewise
+ # way even if the attribute itself has been directly assigned.
{
a = { b = 1; };
a.c = 2;
}
- #=> error: attribute ‘a’ already defined
+ #=> { a = { b = 1; c = 2; }; }
# With
@@ -256,7 +279,7 @@ with builtins; [
#=> 7
# This first line of tutorial starts with "with builtins;"
- # because builtins is a set the contains all of the built-in
+ # because builtins is a set that contains all of the built-in
# functions (length, head, tail, filter, etc.). This saves
# us from having to write, for example, "builtins.length"
# instead of just "length".
@@ -314,8 +337,8 @@ with builtins; [
#=========================================
# Because repeatability of builds is critical to the Nix package
- # manager, in which, functional purity is emphasized in the Nix
- # language. But there are a few impurities.
+ # manager, functional purity is emphasized in the Nix language
+ # used to describe Nix packages. But there are a few impurities.
# You can refer to environment variables.
(getEnv "HOME")
@@ -350,5 +373,5 @@ with builtins; [
* [James Fisher - Nix by example - Part 1: The Nix expression language]
(https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55)
-* [Susan Potter - Nix Cookbook - Nix By Example]
- (http://funops.co/nix-cookbook/nix-by-example/)
+* [Rommel Martinez - A Gentle Introduction to the Nix Family]
+ (https://ebzzry.io/en/nix/#nix)
diff --git a/nl-nl/bash-nl.html.markdown b/nl-nl/bash-nl.html.markdown
index da47e2a9..af4a8cc8 100644
--- a/nl-nl/bash-nl.html.markdown
+++ b/nl-nl/bash-nl.html.markdown
@@ -17,8 +17,8 @@ lang: nl-nl
filename: LearnBash-nl.sh
---
-Bash is de naam van den unix shell, deze wordt gebruikt voor het GNU operating system en is de standaard shell op Linux en Mac OS X.
-Bijna alle voorbeelden hier onder kunnen deel uitmaken van een shell script of kunnen uitgevoerd worden in de shell.
+Bash is de naam van de unix shell, deze wordt gebruikt voor het GNU operating system en is de standaard shell op Linux en Mac OS X.
+Bijna alle voorbeelden hieronder kunnen deel uitmaken van een shell script of kunnen uitgevoerd worden in de shell.
[Lees er meer over hier.](http://www.gnu.org/software/bash/manual/bashref.html)
@@ -28,23 +28,23 @@ Bijna alle voorbeelden hier onder kunnen deel uitmaken van een shell script of k
# het script uitgevoerd moet worden: http://en.wikipedia.org/wiki/Shebang_(Unix)
# Zoals je kan zien wordt # gebruikt om een commentaar lijn te starten.
-# Simpel hello world voorbeeld:
+# Een simpel hello world voorbeeld:
echo Hello world!
-# Elke command start op een nieuwe lijn, of achter een puntkomma (;):
+# Elk commando start op een nieuwe lijn, of achter een puntkomma (;):
echo 'Dit is de eerste lijn'; echo 'Dit is de tweede lijn'
-# Een varialbe declareren gebeurt op volgende manier:
+# Een variabele declareren gebeurt op volgende manier:
Variabele="Een string"
# Maar niet op deze manier:
Variabele = "Een string"
-# Bash ziet variable als een commando en zal een error geven omdat dit commando
+# Bash ziet variabelen als een commando en zal een error geven omdat dit commando
# niet bestaat.
# Of op deze manier:
Variabele= 'Een string'
-# Bash zal 'Een string' zien als een commanda en een error geven omdat het niet
+# Bash zal 'Een string' zien als een commando en een error geven omdat het niet
# gevonden kan worden.
# Variabelen gebruiken:
@@ -83,7 +83,7 @@ echo "Wat is uw naam?"
read Naam # Merk op dat we geen variabele gedeclareerd hebben
echo Hallo, $Naam!
-# We hebben ook if structuren
+# We hebben ook logische if structuren
# Gebruik 'man test' voor meer informatie over condities.
if [ $Naam -ne $USER ]
then
diff --git a/nl-nl/bf.html.markdown b/nl-nl/bf.html.markdown
index 016e2ba2..8cb06471 100644
--- a/nl-nl/bf.html.markdown
+++ b/nl-nl/bf.html.markdown
@@ -1,5 +1,6 @@
---
language: bf
+filename: learnbf-nl.bf
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
diff --git a/nl-nl/dynamic-programming-nl.html.markdown b/nl-nl/dynamic-programming-nl.html.markdown
new file mode 100644
index 00000000..e56a9774
--- /dev/null
+++ b/nl-nl/dynamic-programming-nl.html.markdown
@@ -0,0 +1,55 @@
+---
+category: Algorithms & Data Structures
+name: Dynamic Programming
+contributors:
+ - ["Akashdeep Goel", "http://github.com/akashdeepgoel"]
+translators:
+ - ["Jasper Haasdijk", "https://github.com/jhaasdijk"]
+lang: nl-nl
+---
+
+# Dynamisch Programmeren
+
+## Introductie
+
+Dynamisch programmeren is een krachtige techniek die, zoals we zullen zien, gebruikt kan worden om een bepaalde klasse van problemen op te lossen. Het idee is eenvoudig. Als je een oplossing hebt voor een probleem met een bepaalde input, sla dit resultaat dan op. Hiermee kan je voorkomen dat je in de toekomst nog een keer hetzelfde probleem moet gaan oplossen omdat je het resultaat vergeten bent.
+
+Onthoud altijd!
+"Zij die het verleden niet kunnen herinneren, zijn gedoemd het te herhalen."
+
+## Verschillende aanpakken
+
+1. *Top-Down* : Oftewel, van boven naar beneden. Begin je oplossing met het afbreken van het probleem in kleine stukken. Kom je een stukje tegen dat je eerder al hebt opgelost, kijk dan enkel naar het opgeslagen antwoord. Kom je een stukje tegen dat je nog niet eerder hebt opgelost, los het op en sla het antwoord op. Deze manier is voor veel mensen de makkelijke manier om erover na te denken, erg intuitief. Deze methode wordt ook wel Memoization genoemd.
+
+2. *Bottom-Up* : Oftewel, van beneden naar boven. Analyseer het probleem en bekijk de volgorde waarin de sub-problemen opgelost kunnen worden. Begin met het oplossen van de triviale gevallen en maak zodoende de weg naar het gegeven probleem. In dit process is het gegarandeerd dat de sub-problemen eerder worden opgelost dan het gegeven probleem. Deze methode wordt ook wel Dynamisch Programmeren genoemd.
+
+## Voorbeeld van Dynamisch Programmeren
+
+Het langst stijgende sequentie probleem is het probleem waarbij je binnen een bepaalde reeks op zoek bent naar het langste aaneengesloten stijgende stuk. Gegeven een reeks `S = {a1 , a2 , a3, a4, ............., an-1, an }` zijn we op zoek naar het langst aaneengesloten stuk zodanig dat voor alle `j` en `i`, `j<i` in de reeks `aj<ai`.
+
+Ten eerste moeten we de waarde van de langste subreeksen(LSi) op elke index i vinden waar het laatste element van de reeks ai is. Daarna zal LSi het langste subreeks in de gegeven reeks zijn. Om te beginnen heeft LSi de waarde 1 omdat ai een element van de reeks(laatste element) is. Daarna zal voor alle `j` zodanig dat `j<i` en `aj<ai` de grootste LSj gevonden en toegevoegd worden aan LSi. Het algoritme duurt *O(n2)* tijd.
+
+Pseudo-code voor het vinden van de lengte van de langst stijgende subreeks:
+De complexiteit van het algoritme kan worden vermindert door het gebruik van een betere data structuur dan een simpele lijst. Het opslaan van een voorgangers lijst en een variabele als `langste_reeks_dusver` en de index daarvan, kan ook een hoop tijd schelen.
+
+Een soortgelijk concept kan worden toegepast in het vinden van het langste pad in een gerichte acyclische graaf.
+
+```python
+for i=0 to n-1
+ LS[i]=1
+ for j=0 to i-1
+ if (a[i] > a[j] and LS[i]<LS[j])
+ LS[i] = LS[j]+1
+for i=0 to n-1
+ if (langste < LS[i])
+```
+
+### Enkele beroemde DP problemen
+
+- [Floyd Warshall Algorithm - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code)
+- [Integer Knapsack Problem - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem)
+- [Longest Common Subsequence - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence)
+
+## Online Bronnen
+
+* [codechef](https://www.codechef.com/wiki/tutorial-dynamic-programming)
diff --git a/nl-nl/html-nl.html.markdown b/nl-nl/html-nl.html.markdown
new file mode 100644
index 00000000..54c81ed6
--- /dev/null
+++ b/nl-nl/html-nl.html.markdown
@@ -0,0 +1,98 @@
+---
+language: html
+filename: learnhtml-nl.html
+contributors:
+ - ["Christophe THOMAS", "https://github.com/WinChris"]
+translators:
+ - ["Robert Steed", "https://github.com/robochat"]
+ - ["Jeroen Deviaene", "https://github.com/jerodev"]
+lang: nl-nl
+---
+
+HTML staat voor HyperText Markup Language.
+Het is een taal die je toe staat pagina's te maken op het World Wide Web.
+Het is een opmaak taal, dit staat de gebruiker toe om webpagina's te maken in code en zo aan te duiden hoe de pagina moet weergegeven worden.
+Eigenlijk zijn html files zelfs simpele tekst bestanden.
+Wat is deze opmaak? Het is een manier om de structuur en data op de pagina weer te geven met speciale html tags.
+Deze tags dienen om de betekenis te geven aan de tekst die het bevat.
+Zoals vele computer talen heeft html vele verschillende versies. Hier zullen we HTML5 bespreken.
+
+**Merk op:** Je kan de verschillende tags en elementen testen terwijl je door de tutorial gaat met een website zoals [codepen](http://codepen.io/pen/), zo kan je de effecten hier van live zien.
+Dit artikel gaat vooral over de HTML syntax en enkele handige tips
+
+
+```html
+<!-- Commentaren worden toegevoegd zoals deze lijn -->
+
+<!-- #################### De Tags #################### -->
+
+<!-- Hier is een voorbeeld HTML bestand dat we zullen analyseren. -->
+
+<!doctype html>
+ <html>
+ <head>
+ <title>Mijn Website</title>
+ </head>
+ <body>
+ <h1>Hello, world!</h1>
+ <a href="http://codepen.io/anon/pen/xwjLbZ">Neem een kijkje op deze link</a>
+ <p>Dit is een paragraaf.</p>
+ <p>Dit is nog een paragraaf.</p>
+ <ul>
+ <li>Dit is een item in een niet genummerde lijst</li>
+ <li>Dit is nog zo een item</li>
+ <li>En dit is het laatste item van de lijst</li>
+ </ul>
+ </body>
+ </html>
+
+<!-- Een HTML bestand start altijd met een tag die aan de browser laat weten dat we HTML gebruiken -->
+<!doctype html>
+
+<!-- Daarna openen we de root van het bestand met de <html> tag -->
+<html>
+
+<!-- Deze tag moet ook gesloten worden op het einde van het bestand -->
+</html>
+
+<!-- Niets mag nog na deze tag komen! -->
+
+<!-- Binnenin (tussen de html tags <html></html>) vinden we: -->
+
+<!-- Een header, gedefigneerd door <head> (Deze moet gesloten worden met </head>) -->
+<!-- De header bevat beschrijvingen en externe data die niet zichtbaar is op de website; Dit is metadata -->
+
+<head>
+ <title>Mijn Website</title><!-- De <title> tag geeft de tekst aan die in de titelbar van de browser moet weergegeven worden. -->
+</head>
+
+<!-- Achter de <head> sectie vinden we bijna altijd <body> -->
+<!-- Tot op dit punt is nog niets verschenen in het browser venster. -->
+<!-- In de body plaatsen we wat zichtbaar moet zijn in de browser -->
+
+<body>
+ <h1>Hello, world!</h1> <!-- De h1 tag maakt een titel. -->
+ <!-- Er zijn ook sub titels voor <h1> van belangrijk <h2> tot minder belangrijk <h6>. -->
+ <a href="http://codepen.io/anon/pen/xwjLbZ">Neem een kijkje op deze link</a> <!-- een hyperlink naar de aangegeven link waar op geklikt kan worden in de browser -->
+ <p>This is a paragraph.</p> <!-- De tag <p> laat ons tekst toevoegen. -->
+ <p>This is another paragraph.</p>
+ <ul> <!-- De tag <ul> maakt een lijst met puntjes. -->
+ <!-- Om een genummerde lijst te hebben gebruik je <ol>, hiermee worden de elementen <li> automatisch genummerd -->
+ <li>This is an item in a non-enumerated list (bullet list)</li>
+ <li>This is another item</li>
+ <li>And this is the last item on the list</li>
+ </ul>
+</body>
+
+<!-- En dat is het! Zo gemakkelijk is het om een html bestand te maken. -->
+```
+
+## Gebruik
+
+HTML wordt altijd opgeslagen in bestanden die eindigen in `.html`.
+
+## Meer weten
+
+* [wikipedia](https://nl.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/nl-nl/json-nl.html.markdown b/nl-nl/json-nl.html.markdown
index 906112ff..d243802d 100644
--- a/nl-nl/json-nl.html.markdown
+++ b/nl-nl/json-nl.html.markdown
@@ -5,26 +5,27 @@ contributors:
- ["Anna Harren", "https://github.com/iirelu"]
- ["Marco Scannadinari", "https://github.com/marcoms"]
- ["himanshu", "https://github.com/himanshu81494"]
+ - ["Maarten Jacobs", "https://github.com/maartenJacobs"]
translators:
- ["Niels van Velzen", "https://nielsvanvelzen.me"]
lang: nl-nl
---
-Gezien JSON een zeer eenvouding formaat heeft zal dit een van de simpelste
+Gezien JSON een zeer eenvouding formaat heeft zal dit één van de simpelste
Learn X in Y Minutes ooit zijn.
-JSON heeft volgens de specificaties geen commentaar, ondanks dat hebben de
+JSON heeft volgens de specificaties geen commentaar. Ondanks dat hebben de
meeste parsers support voor C-stijl (`//`, `/* */`) commentaar.
Sommige parsers staan zelfs trailing komma's toe.
-(Een komma na het laatste element in een array of ahter de laatste eigenshap van een object).
-Het is wel beter om dit soort dingen te vermijden omdat het niet overal zal werken.
+(Een komma na het laatste element in een array of achter de laatste eigenschap van een object).
+Het is wel beter om dit soort dingen te vermijden omdat het niet in elke parser zal werken.
In het voorbeeld zal alleen 100% geldige JSON gebruikt worden.
Data types gesupport door JSON zijn: nummers, strings, booleans, arrays, objecten en null.
Gesupporte browsers zijn: Firefox(Mozilla) 3.5, Internet Explorer 8, Chrome, Opera 10, Safari 4.
-De extensie voor JSON bestanden is ".json". De MIME type is "application/json"
-Enkele nadelen van JSON zijn het gebrek een type definities en een manier van DTD.
+De extensie voor JSON bestanden is ".json". De MIME type is "application/json".
+Enkele nadelen van JSON zijn het gebrek aan type definities en een manier van DTD.
```json
{
diff --git a/nl-nl/markdown-nl.html.markdown b/nl-nl/markdown-nl.html.markdown
index 35cc67c5..b5b4681c 100644
--- a/nl-nl/markdown-nl.html.markdown
+++ b/nl-nl/markdown-nl.html.markdown
@@ -12,7 +12,7 @@ Markdown is gecreëerd door John Gruber in 2004. Het is bedoeld om met een gemak
schrijven syntax te zijn die gemakkelijk omgevormd kan worden naar HTML (en op heden verschillende
andere formaten)
-```markdown
+```md
<!-- Markdown erft over van HTML, dus ieder HTML bestand is een geldig Markdown
bestand. Dit betekend ook dat html elementen gebruikt kunnen worden in Markdown
zoals het commentaar element. Echter, als je een html element maakt in een Markdown
diff --git a/nl-nl/vim-nl.html.markdown b/nl-nl/vim-nl.html.markdown
new file mode 100644
index 00000000..a69c031c
--- /dev/null
+++ b/nl-nl/vim-nl.html.markdown
@@ -0,0 +1,272 @@
+---
+category: tool
+tool: vim
+contributors:
+ - ["RadhikaG", "https://github.com/RadhikaG"]
+translators:
+ - ["Rick Haan", "https://github.com/RickHaan"]
+filename: learnvim-nl.yaml
+lang: nl-nl
+---
+
+# Vim in het Nederlands
+
+[Vim](http://www.vim.org)
+(Vi IMproved) is een kopie van de populaire vi editor voor Unix. Het is
+ontworpen voor snelheid, verhoogde productiviteit en is beschikbaar in de meeste
+unix-gebaseerde systemen. Het heeft verscheidene toetscombinaties voor snelle
+navigatie en aanpassingen in het doelbestand.
+
+## De Basis van het navigeren in Vim
+
+``` Vim
+ vim <bestandsnaam> # Open <bestandsnaam> in vim
+ :help <onderwerp> # Open ingebouwde documentatie over <onderwerp> als
+ deze bestaat
+ :q # Vim afsluiten
+ :w # Huidig bestand opslaan
+ :wq # Huidig bestand opslaan en vim afsluiten
+ ZZ # Huidig bestand opslaan en vim afsluiten
+ :x # Huidig bestand opslaan en vim afsluiten, verkorte versie
+ :q! # Afsluiten zonder opslaan
+ # ! *forceert* het normale afsluiten met :q
+
+ u # Ongedaan maken
+ CTRL+R # Opnieuw doen
+
+ h # Ga 1 karakter naar links
+ j # Ga 1 regel naar beneden
+ k # Ga 1 regel omhoog
+ l # Ga 1 karakter naar rechts
+
+ Ctrl+B # Ga 1 volledig scherm terug
+ Ctrl+F # Ga 1 volledig scherm vooruit
+ Ctrl+D # Ga 1/2 scherm vooruit
+ Ctrl+U # Ga 1/2 scherm terug
+
+ # Verplaatsen over de regel
+
+ 0 # Verplaats naar het begin van de regel
+ $ # Verplaats naar het eind van de regel
+ ^ # Verplaats naar het eerste niet-lege karakter op de regel
+
+ # Zoeken in de tekst
+
+ /word # Markeert alle voorvallen van 'word' na de cursor
+ ?word # Markeert alle voorvallen van 'word' voor de cursor
+ n # Verplaatst de cursor naar het volgende voorval van
+ de zoekopdracht
+ N # Verplaatst de cursor naar het vorige voorval van
+ de zoekopdracht
+
+ :%s/foo/bar/g # Verander 'foo' naar 'bar' op elke regel van het bestand
+ :s/foo/bar/g # Verander 'foo' naar 'bar' op de huidge regel in
+ het bestand
+ :%s/\n/\r/g # Vervang nieuwe regel karakters met nieuwe regel karakters
+
+ # Spring naar karakters
+
+ f<character> # Spring vooruit en land op <character>
+ t<character> # Spring vooruit en land net voor <character>
+
+ # Bijvoorbeeld,
+ f< # Spring vooruit en land op <
+ t< # Spring vooruit en land net voor <
+
+ # Verplaatsen per woord
+
+ w # Ga 1 woord vooruit
+ b # Ga 1 woord achteruit
+ e # Ga naar het einde van het huidige woord
+
+ # Andere karakters om mee te verplaatsen
+
+ gg # Ga naar de bovenkant van het bestand
+ G # Ga naar de onderkant van het bestand
+ :NUM # Ga naar regel NUM (NUM is elk nummer)
+ H # Ga naar de bovenkant van het scherm
+ M # Ga naar het midden van het scherm
+ L # Ga naar de onderkant van het scherm
+```
+
+## Help documentatie
+
+Vim heeft ingebouwde help documentatie dat benaderd kan worden met
+`:help <onderwerp>`. Bijvoorbeeld `:help navigation` geeft documentatie weer hoe
+door vim te navigeren. `:help` kan ook gebruikt worden zonder onderwerp. Dan wordt de standaard documentatie weergeven die bedoelt is om vim toegankelijker te maken.
+
+## Modus
+
+Vim is gebaseerd op het concept van **modus**.
+
+* Command (opdracht) modus - Vim wordt opgestart in deze mode. Deze mode wordt
+gebruikt om opdrachten te geven en te navigeren
+* Insert (invoer) modus - Wordt gebruikt voor het aanpassen van het bestand
+* Zichtbare (Visual) modus - Wordt gebruikt voor het markeren en bewerken van
+tekst
+* Ex modus - Wordt gebruikt voor het uitvoeren van opdrachten met `:`
+
+``` Vim
+ i # Zet vim in de Command modus voor de cursor positie
+ a # Zet vim in de Insert modus na de cursor positie (append)
+ v # Zet vim in de Visual modus
+ : # Zet vim in de ex modus
+ <esc> # 'Escapes' vanuit elke modus naar de Command modus
+
+ # Het kopiëren en plakken van tekst
+
+ y # Yank (kopieer) wat geselecteerd is
+ yy # Yank (kopieer) de huidige regel
+ d # Verwijder wat geselecteerd is
+ dd # Verwijder de huidige regel
+ p # Plak de huidige tekst op de cursor positie
+ P # Plak de huidige tekst voor de cursor positie
+ x # Verwijder karakter op cursor positie
+```
+
+## De 'gramatica' van vim
+
+Vim kan aangeleerd worden als een set van acties in het 'Verb-Modifier-Noun'
+formaat waar:
+
+Verb (werkwoord) - De uit te voeren actie
+Modifier (bijwoord) - Hoe de actie uitgevoerd dient te worden
+Noun - Het object waarop de actie uitgevoerd wordt
+
+Een paar belangrijke voorbeelden van 'Verbs', 'Modifiers', en 'Nouns' zijn:
+
+``` Vim
+ # 'Verbs'
+
+ d # Verwijder
+ c # Verander
+ y # Kopieer
+ v # Zichtbaar selecteren
+
+ # 'Modifiers'
+
+ i # Binnen
+ a # Rondom
+ NUM # Elk nummer
+ f # Zoekt iets en selecteerd het
+ t # Zoekt iets en selecteerd het karakter voor het
+ / # Vindt een combinatie van tekens vanaf de cursor
+ ? # Vindt een combinatie van tekens voor de cursor
+
+ # 'Nouns'
+
+ w # Woord
+ s # Zin
+ p # Paragraaf
+ b # Blok
+
+ # Voorbeeld 'zinnen' of opdrachten
+
+ d2w # Verwijder twee woorden
+ cis # Verander in de zin
+ yip # Kopiereer in de paragraaf
+ ct< # Verander naar haakje openen
+ # Verander de tekst vanaf de huidige positie tot het volgende haakje
+ openen
+ d$ # Verwijder tot het einde van de regel
+```
+
+## Een aantal afkortingen en trucs
+
+``` Vim
+ > # Verspring de selectie met 1 blok
+ < # Verspring de selectie met 1 blok terug
+ :earlier 15 # Zet het document terug naar de situatie van 15 minuten
+ geleden
+ :later 15 # Zet het document in de situatie 15 minuten in de toekomst
+ (omgekeerde van de vorige opdracht)
+ ddp # Wissel de positie van opeenvolgende regels. dd daarna p
+ . # Herhaal de vorige opdracht
+ :w !sudo tee% # Sla het huidige bestand op als root
+ :set syntax=c # Stel syntax uitlichten in op 'c'
+ :sort # Sorteer alle regels
+ :sort! # Sorteer alle regels omgekeerd
+ :sort u # Sorteer alle regels en verwijder duplicaten
+ ~ # Stel letter case in voor geselecteerde tekst
+ u # Verander de geselecteerde tekst naar kleine letters
+ U # Verander de geselecteerde tekst naar hoofdletters
+
+ # Fold text
+ zf # Creeer een vouw op de geslecteerde tekst
+ zo # Open huidige vouw
+ zc # Sluit huidige vouw
+ zR # Open alle vouwen
+ zM # Sluit alle vouwen
+```
+
+## Macro's
+
+Macro's zijn opgeslagen opdrachten. Wanneer je begint met het opnemen van een
+macro dan worden **alle** acties opgenomen, totdat je stopt met opnemen. Als de
+macro uitgevoerd wordt, worden alle acties in de zelfde volgorde als tijdens het
+opnemen uitgevoerd.
+
+``` Vim
+ qa # Start met het opnemen van de makro genaamd 'a'
+ q # Stop met opnemen
+ @a # Gebruik macro 'a'
+```
+
+## Configureren van .vimrc
+
+Het .vimrc bestand kan gebruikt worden voor het opslaan van een
+standaardconfiguratie van Vim. Het bestand wordt opgeslagen in de home map van de gebruiker. Hieronder staat een voorbeeld van een .vimrc bestand.
+
+``` Vim
+" Voorbeeld ~/.vimrc
+" 2015.10
+
+" In te stellen dat Vim niet samenwerkt met Vi
+set nocompatible
+
+" Stel in dat Vim kijkt naar de bestandstype voor syntax uitlichting en
+automatish inspringen
+filetype indent plugin on
+
+" Zet inspringen aan
+syntax on
+
+" Betere opdracht regel aanvulling
+set wildmenu
+
+" Gebruik niet hoofdlettergevoelig zoeken.
+set ignorecase
+set smartcase
+
+" Gebruik automatisch inspringen
+set autoindent
+
+" Geef regelnummers weer
+set number
+
+" Het aantal zichtbare spatie's per TAB
+set tabstop=4
+
+" Het aantal spatie's tijdens het aanpassen
+set softtabstop=4
+
+" Aantal spatie's wanneer (>> en <<) worden gebruikt
+
+" Maak van TAB's spatie's
+set expandtab
+
+" Gebruik slimme tabs spatie's voor inspringen en uitlijnen
+set smarttab
+```
+
+## Referenties (Engels)
+
+[Vim | Home](http://www.vim.org/index.php)
+
+`$ vimtutor`
+
+[A vim Tutorial and Primer](https://danielmiessler.com/study/vim/)
+
+[What are the dark corners of Vim your mom never told you about? (Stack Overflow thread)](http://stackoverflow.com/questions/726894/what-are-the-dark-corners-of-vim-your-mom-never-told-you-about)
+
+[Arch Linux Wiki](https://wiki.archlinux.org/index.php/Vim) \ No newline at end of file
diff --git a/nl-nl/yaml-nl.html.markdown b/nl-nl/yaml-nl.html.markdown
index 11af784f..7e4d37b1 100644
--- a/nl-nl/yaml-nl.html.markdown
+++ b/nl-nl/yaml-nl.html.markdown
@@ -2,7 +2,7 @@
language: yaml
filename: learnyaml-nl.yaml
contributors:
- - ["Adam Brenecki", "https://github.com/adambrenecki"]
+ - ["Leigh Brenecki", "https://github.com/adambrenecki"]
translators:
- ["Niels van Velzen", "https://nielsvanvelzen.me"]
- ["Sam van Kampen", "http://tehsvk.net"]
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/objective-c.html.markdown b/objective-c.html.markdown
index 2b599378..de3884af 100644
--- a/objective-c.html.markdown
+++ b/objective-c.html.markdown
@@ -731,7 +731,10 @@ if ([myClass conformsToProtocol:@protocol(CarUtilities)]) {
///////////////////////////////////////
// Blocks are statements of code, just like a function, that are able to be used as data.
// Below is a simple block with an integer argument that returns the argument plus 4.
-int (^addUp)(int n); // Declare a variable to store the block.
+^(int n) {
+ return n + 4;
+}
+int (^addUp)(int n); // Declare a variable to store a block.
void (^noParameterBlockVar)(void); // Example variable declaration of block with no arguments.
// Blocks have access to variables in the same scope. But the variables are readonly and the
// value passed to the block is the value of the variable when the block is created.
@@ -786,7 +789,7 @@ MyClass *newVar = [classVar retain]; // If classVar is released, object is still
// Automatic Reference Counting (ARC)
// Because memory management can be a pain, Xcode 4.2 and iOS 4 introduced Automatic Reference Counting (ARC).
// ARC is a compiler feature that inserts retain, release, and autorelease automatically for you, so when using ARC,
-// you must not use retain, relase, or autorelease
+// you must not use retain, release, or autorelease
MyClass *arcMyClass = [[MyClass alloc] init];
// ... code using arcMyClass
// Without ARC, you will need to call: [arcMyClass release] after you're done using arcMyClass. But with ARC,
diff --git a/ocaml.html.markdown b/ocaml.html.markdown
index 59ead9ec..b631df0a 100644
--- a/ocaml.html.markdown
+++ b/ocaml.html.markdown
@@ -1,5 +1,6 @@
---
language: OCaml
+filename: learnocaml.ml
contributors:
- ["Daniil Baturin", "http://baturin.org/"]
---
@@ -160,7 +161,7 @@ let my_lambda = fun x -> x * x ;;
(*** Operators ***)
-(* There is little distintion between operators and functions.
+(* There is little distinction between operators and functions.
Every operator can be called as a function. *)
(+) 3 4 (* Same as 3 + 4 *)
@@ -374,4 +375,3 @@ sum_int_list t ;;
* Visit the official website to get the compiler and read the docs: <http://ocaml.org/>
* Try interactive tutorials and a web-based interpreter by OCaml Pro: <http://try.ocamlpro.com/>
-* Read "OCaml for the skeptical" course: <http://www2.lib.uchicago.edu/keith/ocaml-class/home.html>
diff --git a/opencv.html.markdown b/opencv.html.markdown
new file mode 100644
index 00000000..d1f7ec51
--- /dev/null
+++ b/opencv.html.markdown
@@ -0,0 +1,144 @@
+---
+category: tool
+tool: OpenCV
+filename: learnopencv.py
+contributors:
+ - ["Yogesh Ojha", "http://github.com/yogeshojha"]
+---
+### Opencv
+
+OpenCV (Open Source Computer Vision) is a library of programming functions mainly aimed at real-time computer vision.
+Originally developed by Intel, it was later supported by Willow Garage then Itseez (which was later acquired by Intel).
+Opencv currently supports wide variety of languages like, C++, Python, Java etc
+
+#### Installation
+Please refer to these articles for installation of OpenCV on your computer.
+
+* Windows Installation Instructions: [https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.html#install-opencv-python-in-windows](https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.html#install-opencv-python-in-windows)
+* Mac Installation Instructions (High Sierra): [https://medium.com/@nuwanprabhath/installing-opencv-in-macos-high-sierra-for-python-3-89c79f0a246a](https://medium.com/@nuwanprabhath/installing-opencv-in-macos-high-sierra-for-python-3-89c79f0a246a)
+* Linux Installation Instructions (Ubuntu 18.04): [https://www.pyimagesearch.com/2018/05/28/ubuntu-18-04-how-to-install-opencv](https://www.pyimagesearch.com/2018/05/28/ubuntu-18-04-how-to-install-opencv)
+
+### Here we will be focusing on python implementation of OpenCV
+
+```python
+# Reading image in OpenCV
+import cv2
+img = cv2.imread('cat.jpg')
+
+# Displaying the image
+# imshow() function is used to display the image
+cv2.imshow('Image',img)
+# Your first arguement is the title of the window and second parameter is image
+# If you are getting error, Object Type None, your image path may be wrong. Please recheck the pack to the image
+cv2.waitKey(0)
+# waitKey() is a keyboard binding function and takes arguement in milliseconds. For GUI events you MUST use waitKey() function.
+
+# Writing an image
+cv2.imwrite('catgray.png',img)
+# first arguement is the file name and second is the image
+
+# Convert image to grayscale
+gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+
+# Capturing Video from Webcam
+cap = cv2.VideoCapture(0)
+#0 is your camera, if you have multiple camera, you need to enter their id
+while(True):
+ # Capturing frame-by-frame
+ _, frame = cap.read()
+ cv2.imshow('Frame',frame)
+ # When user presses q -> quit
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+# Camera must be released
+cap.release()
+
+# Playing Video from file
+cap = cv2.VideoCapture('movie.mp4')
+while(cap.isOpened()):
+ _, frame = cap.read()
+ # Play the video in grayscale
+ gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
+ cv2.imshow('frame',gray)
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+cap.release()
+
+# Drawing The Line in OpenCV
+# cv2.line(img,(x,y),(x1,y1),(color->r,g,b->0 to 255),thickness)
+cv2.line(img,(0,0),(511,511),(255,0,0),5)
+
+# Drawing Rectangle
+# cv2.rectangle(img,(x,y),(x1,y1),(color->r,g,b->0 to 255),thickness)
+# thickness = -1 used for filling the rectangle
+cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)
+
+# Drawing Circle
+cv2.circle(img,(xCenter,yCenter), radius, (color->r,g,b->0 to 255), thickness)
+cv2.circle(img,(200,90), 100, (0,0,255), -1)
+
+# Drawing Ellipse
+cv2.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
+
+# Adding Text On Images
+cv2.putText(img,"Hello World!!!", (x,y), cv2.FONT_HERSHEY_SIMPLEX, 2, 255)
+
+# Blending Images
+img1 = cv2.imread('cat.png')
+img2 = cv2.imread('openCV.jpg')
+dst = cv2.addWeighted(img1,0.5,img2,0.5,0)
+
+# Thresholding image
+# Binary Thresholding
+_,thresImg = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
+# Adaptive Thresholding
+adapThres = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,2)
+
+# Blur Image
+# Gaussian Blur
+blur = cv2.GaussianBlur(img,(5,5),0)
+# Median Blur
+medianBlur = cv2.medianBlur(img,5)
+
+# Canny Edge Detection
+img = cv2.imread('cat.jpg',0)
+edges = cv2.Canny(img,100,200)
+
+# Face Detection using Haar Cascades
+# Download Haar Cascades from https://github.com/opencv/opencv/blob/master/data/haarcascades/
+import cv2
+import numpy as np
+face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
+eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
+
+img = cv2.imread('human.jpg')
+gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+
+aces = face_cascade.detectMultiScale(gray, 1.3, 5)
+for (x,y,w,h) in faces:
+ cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
+ roi_gray = gray[y:y+h, x:x+w]
+ roi_color = img[y:y+h, x:x+w]
+ eyes = eye_cascade.detectMultiScale(roi_gray)
+ for (ex,ey,ew,eh) in eyes:
+ cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
+
+cv2.imshow('img',img)
+cv2.waitKey(0)
+
+cv2.destroyAllWindows()
+# destroyAllWindows() destroys all windows.
+# If you wish to destroy specific window pass the exact name of window you created.
+```
+
+### Further Reading:
+
+* Download Cascade from [https://github.com/opencv/opencv/blob/master/data/haarcascades](https://github.com/opencv/opencv/blob/master/data/haarcascades)
+* OpenCV drawing Functions [https://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html](https://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html)
+* An up-to-date language reference can be found at [https://opencv.org](https://opencv.org)
+* Additional resources may be found at [https://en.wikipedia.org/wiki/OpenCV](https://en.wikipedia.org/wiki/OpenCV)
+* Good OpenCv Tutorials
+ * [https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html](https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html)
+ * [https://realpython.com/python-opencv-color-spaces](https://realpython.com/python-opencv-color-spaces)
+ * [https://pyimagesearch.com](https://pyimagesearch.com)
+ * [https://www.learnopencv.com](https://www.learnopencv.com)
diff --git a/opengl.html.markdown b/opengl.html.markdown
new file mode 100644
index 00000000..83ace3e8
--- /dev/null
+++ b/opengl.html.markdown
@@ -0,0 +1,765 @@
+---
+category: tool
+tool: OpenGL
+filename: learnopengl.cpp
+contributors:
+ - ["Simon Deitermann", "s.f.deitermann@t-online.de"]
+---
+
+**Open Graphics Library** (**OpenGL**) is a cross-language cross-platform application programming interface
+(API) for rendering 2D computer graphics and 3D vector graphics.<sup>[1]</sup> In this tutorial we will be
+focusing on modern OpenGL from 3.3 and above, ignoring "immediate-mode", Displaylists and
+VBO's without use of Shaders.
+I will be using C++ with SFML for window, image and context creation aswell as GLEW
+for modern OpenGL extensions, though there are many other librarys available.
+
+```cpp
+// Creating an SFML window and OpenGL basic setup.
+#include <GL/glew.h>
+#include <GL/gl.h>
+#include <SFML/Graphics.h>
+#include <iostream>
+
+int main() {
+ // First we tell SFML how to setup our OpenGL context.
+ sf::ContextSettings context{ 24, // depth buffer bits
+ 8, // stencil buffer bits
+ 4, // MSAA samples
+ 3, // major opengl version
+ 3 }; // minor opengl version
+ // Now we create the window, enable VSync
+ // and set the window active for OpenGL.
+ sf::Window window{ sf::VideoMode{ 1024, 768 },
+ "opengl window",
+ sf::Style::Default,
+ context };
+ window.setVerticalSyncEnabled(true);
+ window.setActive(true);
+ // After that we initialise GLEW and check if an error occured.
+ GLenum error;
+ glewExperimental = GL_TRUE;
+ if ((err = glewInit()) != GLEW_OK)
+ std::cout << glewGetErrorString(err) << std::endl;
+ // Here we set the color glClear will clear the buffers with.
+ glClearColor(0.0f, // red
+ 0.0f, // green
+ 0.0f, // blue
+ 1.0f); // alpha
+ // Now we can start the event loop, poll for events and draw objects.
+ sf::Event event{ };
+ while (window.isOpen()) {
+ while (window.pollEvent(event)) {
+ if (event.type == sf::Event::Closed)
+ window.close;
+ }
+ // Tell OpenGL to clear the color buffer
+ // and the depth buffer, this will clear our window.
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ // Flip front- and backbuffer.
+ window.display();
+ }
+ return 0;
+}
+```
+
+## Loading Shaders
+
+After creating a window and our event loop we should create a function,
+that sets up our shader program.
+
+```cpp
+GLuint createShaderProgram(const std::string& vertexShaderPath,
+ const std::string& fragmentShaderPath) {
+ // Load the vertex shader source.
+ std::stringstream ss{ };
+ std::string vertexShaderSource{ };
+ std::string fragmentShaderSource{ };
+ std::ifstream file{ vertexShaderPath };
+ if (file.is_open()) {
+ ss << file.rdbuf();
+ vertexShaderSource = ss.str();
+ file.close();
+ }
+ // Clear the stringstream and load the fragment shader source.
+ ss.str(std::string{ });
+ file.open(fragmentShaderPath);
+ if (file.is_open()) {
+ ss << file.rdbuf();
+ fragmentShaderSource = ss.str();
+ file.close();
+ }
+ // Create the program.
+ GLuint program = glCreateProgram();
+ // Create the shaders.
+ GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
+ GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
+ // Now we can load the shader source into the shader objects and compile them.
+ // Because glShaderSource() wants a const char* const*,
+ // we must first create a const char* and then pass the reference.
+ const char* cVertexSource = vertexShaderSource.c_str();
+ glShaderSource(vertexShader, // shader
+ 1, // number of strings
+ &cVertexSource, // strings
+ nullptr); // length of strings (nullptr for 1)
+ glCompileShader(vertexShader);
+ // Now we have to do the same for the fragment shader.
+ const char* cFragmentSource = fragmentShaderSource.c_str();
+ glShaderSource(fragmentShader, 1, &cFragmentSource, nullptr);
+ glCompileShader(fragmentShader);
+ // After attaching the source and compiling the shaders,
+ // we attach them to the program;
+ glAttachShader(program, vertexShader);
+ glAttachShader(program, fragmentShader);
+ glLinkProgram(program);
+ // After linking the shaders we should detach and delete
+ // them to prevent memory leak.
+ glDetachShader(program, vertexShader);
+ glDetachShader(program, fragmentShader);
+ glDeleteShader(vertexShader);
+ glDeleteShader(fragmentShader);
+ // With everything done we can return the completed program.
+ return program;
+}
+```
+
+If you want to check the compilation log you can add the following between <code>glCompileShader()</code> and <code>glAttachShader()</code>.
+
+```cpp
+GLint logSize = 0;
+std::vector<GLchar> logText{ };
+glGetShaderiv(vertexShader, // shader
+ GL_INFO_LOG_LENGTH, // requested parameter
+ &logSize); // return object
+if (logSize > 0) {
+ logText.resize(logSize);
+ glGetShaderInfoLog(vertexShader, // shader
+ logSize, // buffer length
+ &logSize, // returned length
+ logText.data()); // buffer
+ std::cout << logText.data() << std::endl;
+}
+```
+
+The same is possibile after <code>glLinkProgram()</code>, just replace <code>glGetShaderiv()</code> with <code>glGetProgramiv()</code>
+and <code>glGetShaderInfoLog()</code> with <code>glGetProgramInfoLog()</code>.
+
+```cpp
+// Now we can create a shader program with a vertex and a fragment shader.
+// ...
+glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+
+GLuint program = createShaderProgram("vertex.glsl", "fragment.glsl");
+
+sf::Event event{ };
+// ...
+// We also have to delete the program at the end of the application.
+// ...
+ }
+ glDeleteProgram(program);
+ return 0;
+}
+// ...
+```
+
+Ofcourse we have to create the vertex and fragment shader before we can load them,
+so lets create two basic shaders.
+
+**Vertex Shader**
+
+```glsl
+// Declare which version of GLSL we use.
+// Here we declare, that we want to use the OpenGL 3.3 version of GLSL.
+#version 330 core
+// At attribute location 0 we want an input variable of type vec3,
+// that contains the position of the vertex.
+// Setting the location is optional, if you don't set it you can ask for the
+// location with glGetAttribLocation().
+layout(location = 0) in vec3 position;
+// Every shader starts in it's main function.
+void main() {
+ // gl_Position is a predefined variable that holds
+ // the final vertex position.
+ // It consists of a x, y, z and w coordinate.
+ gl_Position = vec4(position, 1.0);
+}
+```
+
+**Fragment Shader**
+
+```glsl
+#version 330 core
+// The fragment shader does not have a predefined variable for
+// the vertex color, so we have to define a output vec4,
+// that holds the final vertex color.
+out vec4 outColor;
+
+void main() {
+ // We simply set the ouput color to red.
+ // The parameters are red, green, blue and alpha.
+ outColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+```
+
+## VAO and VBO
+Now we need to define some vertex position we can pass to our shaders. Lets define a simple 2D quad.
+
+```cpp
+// The vertex data is defined in a counter-clockwise way,
+// as this is the default front face.
+std::vector<float> vertexData {
+ -0.5f, 0.5f, 0.0f,
+ -0.5f, -0.5f, 0.0f,
+ 0.5f, -0.5f, 0.0f,
+ 0.5f, 0.5f, 0.0f
+};
+// If you want to use a clockwise definition, you can simply call
+glFrontFace(GL_CW);
+// Next we need to define a Vertex Array Object (VAO).
+// The VAO stores the current state while its active.
+GLuint vao = 0;
+glGenVertexArrays(1, &vao);
+glBindVertexArray(vao);
+// With the VAO active we can now create a Vertex Buffer Object (VBO).
+// The VBO stores our vertex data.
+GLuint vbo = 0;
+glGenBuffers(1, &vbo);
+glBindBuffer(GL_ARRAY_BUFFER, vbo);
+// For reading and copying there are also GL_*_READ and GL_*_COPY,
+// if your data changes more often use GL_DYNAMIC_* or GL_STREAM_*.
+glBufferData(GL_ARRAY_BUFFER, // target buffer
+ sizeof(vertexData[0]) * vertexData.size(), // size
+ vertexData.data(), // data
+ GL_STATIC_DRAW); // usage
+// After filling the VBO link it to the location 0 in our vertex shader,
+// which holds the vertex position.
+// ...
+// To ask for the attibute location, if you haven't set it:
+GLint posLocation = glGetAttribLocation(program, "position");
+// ..
+glEnableVertexAttribArray(0);
+glVertexAttribPointer(0, 3, // location and size
+ GL_FLOAT, // type of data
+ GL_FALSE, // normalized (always false for floats)
+ 0, // stride (interleaved arrays)
+ nullptr); // offset (interleaved arrays)
+// Everything should now be saved in our VAO and we can unbind it and the VBO.
+glBindVertexArray(0);
+glBindBuffer(GL_ARRAY_BUFFER, 0);
+// Now we can draw the vertex data in our render loop.
+// ...
+glClear(GL_COLOR_BUFFER_BIT);
+// Tell OpenGL we want to use our shader program.
+glUseProgram(program);
+// Binding the VAO loads the data we need.
+glBindVertexArray(vao);
+// We want to draw a quad starting at index 0 of the VBO using 4 indices.
+glDrawArrays(GL_QUADS, 0, 4);
+glBindVertexArray(0);
+window.display();
+// ...
+// Ofcource we have to delete the allocated memory for the VAO and VBO at
+// the end of our application.
+// ...
+glDeleteBuffers(1, &vbo);
+glDeleteVertexArrays(1, &vao);
+glDeleteProgram(program);
+return 0;
+// ...
+```
+
+You can find the current code here: [OpenGL - 1](https://pastebin.com/W8jdmVHD).
+
+## More VBO's and Color
+Let's create another VBO for some colors.
+
+```cpp
+std::vector<float> colorData {
+ 1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f,
+ 1.0f, 1.0f, 0.0f
+};
+```
+
+Next we can simply change some previous parameters to create a second VBO for our colors.
+
+```cpp
+// ...
+GLuint vbo[2];
+glGenBuffers(2, vbo);
+glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
+// ...
+glDeleteBuffers(2, vbo);
+/ ...
+// With these changes made we now have to load our color data into the new VBO
+// ...
+glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
+
+glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
+glBufferData(GL_ARRAY_BUFFER, sizeof(colorData[0]) * colorData.size(),
+ colorData.data(), GL_STATIC_DRAW);
+glEnableVertexAttribArray(1);
+glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
+
+glBindVertexArray(0);
+// ...
+```
+
+Next we have to change our vertex shader to pass the color data to the fragment shader.<br>
+**Vertex Shader**
+
+```glsl
+#version 330 core
+
+layout(location = 0) in vec3 position;
+// The new location has to differ from any other input variable.
+// It is the same index we need to pass to
+// glEnableVertexAttribArray() and glVertexAttribPointer().
+layout(location = 1) in vec3 color;
+
+out vec3 fColor;
+
+void main() {
+ fColor = color;
+ gl_Position = vec4(position, 1.0);
+}
+```
+
+**Fragment Shader**
+
+```glsl
+#version 330 core
+
+in vec3 fColor;
+
+out vec4 outColor;
+
+void main() {
+ outColor = vec4(fColor, 1.0);
+}
+```
+
+We define a new input variable ```color``` which represents our color data, this data
+is passed on to ```fColor```, which is an output variable of our vertex shader and
+becomes an input variable for our fragment shader.
+It is imporatant that variables passed between shaders have the exact same name
+and type.
+
+## Handling VBO's
+
+```cpp
+// If you want to completely clear and refill a VBO use glBufferData(),
+// just like we did before.
+// ...
+// There are two mains ways to update a subset of a VBO's data.
+// To update a VBO with existing data
+std::vector<float> newSubData {
+ -0.25f, 0.5f, 0.0f
+};
+glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
+glBufferSubData(GL_ARRAY_BUFFER, // target buffer
+ 0, // offset
+ sizeof(newSubData[0]) * newSubData.size(), // size
+ newSubData.data()); // data
+// This would update the first three values in our vbo[0] buffer.
+// If you want to update starting at a specific location just set the second
+// parameter to that value and multiply by the types size.
+// ...
+// If you are streaming data, for example from a file,
+// it is faster to directly pass the data to the buffer.
+// Other access values are GL_READ_ONLY and GL_READ_WRITE.
+glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
+// You can static_cast<float*>() the void* to be more safe.
+void* Ptr = glMapBuffer(GL_ARRAY_BUFFER, // buffer to map
+ GL_WRITE_ONLY); // access to buffer
+memcpy(Ptr, newSubData.data(), sizeof(newSubData[0]) * newSubData.size());
+// To copy to a specific location add a destination offset to memcpy().
+glUnmapBuffer(GL_ARRAY_BUFFER);
+// ...
+// There is also a way to copy data from one buffer to another,
+// If we have two VBO's vbo[0] and vbo[1], we can copy like so
+// You can also read from GL_ARRAY_BUFFER.
+glBindBuffer(GL_COPY_READ_BUFFER, vbo[0]);
+// GL_COPY_READ_BUFFER and GL_COPY_WRITE_BUFFER are specifically for
+// copying buffer data.
+glBindBuffer(GL_COPY_WRITE_BUFFER, vbo[1]);
+glCopyBufferSubData(GL_COPY_READ_BUFFER, // read buffer
+ GL_COPY_WRITE_BUFFER, // write buffer
+ 0, 0, // read and write offset
+ sizeof(vbo[0]) * 3); // copy size
+// This will copy the first three elements from vbo[0] to vbo[1].
+```
+
+## Uniforms
+
+**Fragment Shader**
+
+```glsl
+// Uniforms are variables like in and out, however,
+// we can change them easily by passing new values with glUniform().
+// Lets define a time variable in our fragment shader.
+#version 330 core
+// Unlike a in/out variable we can use a uniform in every shader,
+// without the need to pass it to the next one, they are global.
+// Don't use locations already used for attributes!
+// Uniform layout locations require OpenGL 4.3!
+layout(location = 10) uniform float time;
+
+in vec3 fColor;
+
+out vec4 outColor;
+
+void main() {
+ // Create a sine wave from 0 to 1 based on the time passed to the shader.
+ float factor = (sin(time * 2) + 1) / 2;
+ outColor = vec4(fColor.r * factor, fColor.g * factor, fColor.b * factor, 1.0);
+}
+```
+
+Back to our source code.
+
+```cpp
+// If we haven't set the layout location, we can ask for it.
+GLint timeLocation = glGetUniformLocation(program, "time");
+// ...
+// Also we should define a Timer counting the current time.
+sf::Clock clock{ };
+// In out render loop we can now update the uniform every frame.
+ // ...
+ window.display();
+ glUniform1f(10, // location
+ clock.getElapsedTime().asSeconds()); // data
+}
+// ...
+```
+
+With the time getting updated every frame the quad should now be changing from
+fully colored to pitch black.
+There are different types of glUniform() you can find simple documentation here:
+[glUniform - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glUniform.xhtml)
+
+## Indexing and IBO's
+
+Element Array Buffers or more commonly Index Buffer Objects (IBO) allow us to use the
+same vertex data again which makes drawing a lot easier and faster. here's an example:
+
+```cpp
+// Lets create a quad from two rectangles.
+// We can simply use the old vertex data from before.
+// First, we have to create the IBO.
+// The index is referring to the first declaration in the VBO.
+std::vector<unsigned int> iboData {
+ 0, 1, 2,
+ 0, 2, 3
+};
+// That's it, as you can see we could reuse 0 - the top left
+// and 2 - the bottom right.
+// Now that we have our data, we have to fill it into a buffer.
+// Note that this has to happen between the two glBindVertexArray() calls,
+// so it gets saved into the VAO.
+GLuint ibo = 0;
+glGenBufferrs(1, &ibo);
+glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
+glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(iboData[0]) * iboData.size(),
+ iboData.data(), GL_STATIC_DRAW);
+// Next in our render loop, we replace glDrawArrays() with:
+glDrawElements(GL_TRIANGLES, iboData.size(), GL_UNSINGED_INT, nullptr);
+// Remember to delete the allocated memory for the IBO.
+```
+
+You can find the current code here: [OpenGL - 2](https://pastebin.com/R3Z9ACDE).
+
+## Textures
+
+To load out texture we first need a library that loads the data, for simplicity I will be
+using SFML, however there are a lot of librarys for loading image data.
+
+```cpp
+// Lets save we have a texture called "my_tex.tga", we can load it with:
+sf::Image image;
+image.loadFromFile("my_tex.tga");
+// We have to flip the texture around the y-Axis, because OpenGL's texture
+// origin is the bottom left corner, not the top left.
+image.flipVertically();
+// After loading it we have to create a OpenGL texture.
+GLuint texture = 0;
+glGenTextures(1, &texture);
+glBindTexture(GL_TEXTURE_2D, texture);
+// Specify what happens when the coordinates are out of range.
+glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+// Specify the filtering if the object is very large.
+glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+// Load the image data to the texture.
+glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getSize().x, image.getSize().y,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
+// Unbind the texture to prevent modifications.
+glBindTexture(GL_TEXTURE_2D, 0);
+// Delete the texture at the end of the application.
+// ...
+glDeleteTextures(1, &texture);
+```
+
+Ofcourse there are more texture formats than only 2D textures,
+You can find further information on parameters here:
+[glBindTexture - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBindTexture.xhtml)<br>
+[glTexImage2D - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml)<br>
+[glTexParameter - OpenGL Refpage](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexParameter.xhtml)<br>
+
+```cpp
+// With the texture created, we now have to specify the UV,
+// or in OpenGL terms ST coordinates.
+std::vector<float> texCoords {
+ // The texture coordinates have to match the triangles/quad
+ // definition.
+ 0.0f, 1.0f, // start at top-left
+ 0.0f, 0.0f, // go round counter-clockwise
+ 1.0f, 0.0f,
+ 1.0f, 1.0f // end at top-right
+};
+// Now we increase the VBO's size again just like we did for the colors.
+// ...
+GLuint vbo[3];
+glGenBuffers(3, vbo);
+// ...
+glDeleteBuffers(3, vbo);
+// ...
+// Load the texture coordinates into the new buffer.
+glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
+glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords[0]) * texCoords.size(),
+ texCoords.data(), GL_STATIC_DRAW);
+glEnableVertexAttribArray(2);
+glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
+// Because the VAO does not store the texture we have to bind it before drawing.
+// ...
+glBindVertexArray(vao);
+glBindTexture(GL_TEXTURE_2D, texture);
+glDrawElements(GL_TRIANGLES, iboData.size(), GL_UNSINGED_INT, nullptr);
+// ...
+```
+
+Change the shaders to pass the data to the fragment shader.<br>
+
+**Vertex Shader**
+
+```glsl
+#version 330 core
+
+layout(location = 0) in vec3 position;
+layout(location = 1) in vec3 color;
+layout(location = 2) in vec2 texCoords;
+
+out vec3 fColor;
+out vec2 fTexCoords;
+
+void main() {
+ fColor = color;
+ fTexCoords = texCoords;
+ gl_Position = vec4(position, 1.0);
+}
+```
+
+**Fragment Shader**
+
+```glsl
+#version 330 core
+// sampler2D represents our 2D texture.
+uniform sampler2D tex;
+uniform float time;
+
+in vec3 fColor;
+in vec2 fTexCoords;
+
+out vec4 outColor;
+
+void main() {
+ // texture() loads the current texure data at the specified texture coords,
+ // then we can simply multiply them by our color.
+ outColor = texture(tex, fTexCoords) * vec4(fColor, 1.0);
+}
+```
+
+You can find the current code here: [OpenGL - 3](https://pastebin.com/u3bcwM6q)
+
+## Matrix Transformation
+
+**Vertex Shader**
+
+```glsl
+#version 330 core
+
+layout(location = 0) in vec3 position;
+layout(location = 1) in vec3 color;
+layout(location = 2) in vec2 texCoords;
+// Create 2 4x4 matricies, 1 for the projection matrix
+// and 1 for the model matrix.
+// Because we draw in a static scene, we don't need a view matrix.
+uniform mat4 projection;
+uniform mat4 model;
+
+out vec3 fColor;
+out vec2 fTexCoords;
+
+void main() {
+ fColor = color;
+ fTexCoords = texCoords;
+ // Multiplay the position by the model matrix and then by the
+ // projection matrix.
+ // Beware order of multiplication for matricies!
+ gl_Position = projection * model * vec4(position, 1.0);
+}
+```
+
+In our source we now need to change the vertex data, create a model- and a projection matrix.
+
+```cpp
+// The new vertex data, counter-clockwise declaration.
+std::vector<float> vertexData {
+ 0.0f, 1.0f, 0.0f, // top left
+ 0.0f, 0.0f, 0.0f, // bottom left
+ 1.0f, 0.0f, 0.0f, // bottom right
+ 1.0f, 1.0f, 0.0f // top right
+};
+// Request the location of our matricies.
+GLint projectionLocation = glGetUniformLocation(program, "projection");
+GLint modelLocation = glGetUniformLocation(program, "model");
+// Declaring the matricies.
+// Orthogonal matrix for a 1024x768 window.
+std::vector<float> projection {
+ 0.001953f, 0.0f, 0.0f, 0.0f,
+ 0.0f, -0.002604f, 0.0f, 0.0f,
+ 0.0f, 0.0f, -1.0f, 0.0f,
+ -1.0f, 1.0f, 0.0f, 1.0f
+};
+// Model matrix translating to x 50, y 50
+// and scaling to x 200, y 200.
+std::vector<float> model {
+ 200.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 200.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 50.0f, 50.0f, 0.0f, 1.0f
+};
+// Now we can send our calculated matricies to the program.
+glUseProgram(program);
+glUniformMatrix4fv(projectionLocation, // location
+ 1, // count
+ GL_FALSE, // transpose the matrix
+ projection.data()); // data
+glUniformMatrix4fv(modelLocation, 1, GL_FALSE, model.data());
+glUseProgram(0);
+// The glUniform*() calls have to be done, while the program is bound.
+```
+
+The application should now display the texture at the defined position and size.<br>
+You can find the current code here: [OpenGL - 4](https://pastebin.com/9ahpFLkY)
+
+```cpp
+// There are many math librarys for OpenGL, which create
+// matricies and vectors, the most used in C++ is glm (OpenGL Mathematics).
+// Its a header only library.
+// The same code using glm would look like:
+glm::mat4 projection{ glm::ortho(0.0f, 1024.0f, 768.0f, 0.0f) };
+glUniformMatrix4fv(projectionLocation, 1, GL_FALSE,
+ glm::value_ptr(projection));
+// Initialise the model matrix to the identity matrix, otherwise every
+// multiplication would be 0.
+glm::mat4 model{ 1.0f };
+model = glm::translate(model, glm::vec3{ 50.0f, 50.0f, 0.0f });
+model = glm::scale(model, glm::vec3{ 200.0f, 200.0f, 0.0f });
+glUniformMatrix4fv(modelLocation, 1, GL_FALSE,
+ glm::value_ptr(model));
+```
+
+## Geometry Shader
+
+Gemoetry shaders were introduced in OpenGL 3.2, they can produce vertices
+that are send to the rasterizer. They can also change the primitive type e.g.
+they can take a point as an input and output other primitives.
+Geometry shaders are inbetween the vertex and the fragment shader.
+
+**Vertex Shader**
+
+```glsl
+#version 330 core
+
+layout(location = 0) in vec3 position;
+layout(location = 1) in vec3 color;
+// Create an output interface block passed to the next shadaer stage.
+// Interface blocks can be used to structure data passed between shaders.
+out VS_OUT {
+ vec3 color;
+} vs_out;
+
+void main() {
+ vs_out.color = color
+ gl_Position = vec4(position, 1.0);
+}
+```
+
+**Geometry Shader**
+
+```glsl
+#version 330 core
+// The geometry shader takes in points.
+layout(points) in;
+// It outputs a triangle every 3 vertices emitted.
+layout(triangle_strip, max_vertices = 3) out;
+// VS_OUT becomes an input variable in the geometry shader.
+// Every input to the geometry shader in treated as an array.
+in VS_OUT {
+ vec3 color;
+} gs_in[];
+// Output color for the fragment shader.
+// You can also simply define color as 'out vec3 color',
+// If you don't want to use interface blocks.
+out GS_OUT {
+ vec3 color;
+} gs_out;
+
+void main() {
+ // Each emit calls the fragment shader, so we set a color for each vertex.
+ gs_out.color = mix(gs_in[0].color, vec3(1.0, 0.0, 0.0), 0.5);
+ // Move 0.5 units to the left and emit the new vertex.
+ // gl_in[] is the current vertex from the vertex shader, here we only
+ // use 0, because we are receiving points.
+ gl_Position = gl_in[0].gl_Position + vec4(-0.5, 0.0, 0.0, 0.0);
+ EmitVertex();
+ gs_out.color = mix(gs_in[0].color, vec3(0.0, 1.0, 0.0), 0.5);
+ // Move 0.5 units to the right and emit the new vertex.
+ gl_Position = gl_in[0].gl_Position + vec4(0.5, 0.0, 0.0, 0.0);
+ EmitVertex();
+ gs_out.color = mix(gs_in[0].color, vec3(0.0, 0.0, 1.0), 0.5);
+ // Move 0.5 units up and emit the new vertex.
+ gl_Position = gl_in[0].gl_Position + vec4(0.0, 0.75, 0.0, 0.0);
+ EmitVertex();
+ EndPrimitive();
+}
+```
+
+**Fragment Shader**
+
+```glsl
+in GS_OUT {
+ vec3 color;
+} fs_in;
+
+out vec4 outColor;
+
+void main() {
+ outColor = vec4(fs_in.color, 1.0);
+}
+```
+
+If you now store a single point with a single color in a VBO and draw them,
+you should see a triangle, with your color mixed half way between
+red, green and blue on each vertex.
+
+
+## Quotes
+<sup>[1]</sup>[OpenGL - Wikipedia](https://en.wikipedia.org/wiki/OpenGL)
+
+## Books
+
+- OpenGL Superbible - Fifth Edition (covering OpenGL 3.3)
+- OpenGL Programming Guide - Eighth Edition (covering OpenGL 4.3)
diff --git a/p5.html.markdown b/p5.html.markdown
new file mode 100644
index 00000000..f6084b98
--- /dev/null
+++ b/p5.html.markdown
@@ -0,0 +1,53 @@
+---
+category: tool
+tool: p5
+contributors:
+ - ['Amey Bhavsar', 'https://github.com/ameybhavsar24']
+ - ['Claudio Busatto', 'https://github.com/cjcbusatto']
+filename: p5.js
+---
+
+p5.js is a JavaScript library that starts with the original goal of [Processing](https://processing.org), to make coding accessible for artists, designers, educators, and beginners, and reinterprets this for today's web.
+Since p5 is a JavaScript library, you should learn [Javascript](https://learnxinyminutes.com/docs/javascript/) first.
+
+```js
+///////////////////////////////////
+// p5.js has two important functions to work with.
+
+function setup() {
+ // the setup function gets executed just once when the window is loaded
+}
+function draw() {
+ // the draw function gets called every single frame. This means that for a frameRate(30) it would get called 30 times per second.
+}
+
+// the following code explains all features
+
+function setup() {
+ createCanvas(640, 480); // creates a new canvas element with 640px as width as 480px as height
+ background(128); // changes the background color of the canvas, can accept rgb values like background(100,200,20) else grayscale values like background(0) = black or background(255) = white
+}
+
+function draw() {
+ ellipse(10, 10, 50, 50); // creates a ellipse at the 10px from the left and 10px from the top with width adn height as 50 each, so its basically a circle.
+ //remember in p5.js the origin is at the top-left corner of the canvas
+
+ if (mouseIsPressed) {
+ // mouseIsPressed is a boolean variable that changes to true if the mouse buttton is pressed down at that instant
+
+ fill(0); // fill refers to the innner color or filling color of whatever shape you are going to draw next
+ } else {
+ fill(255); // you can give in rgb values like fill(72, 240, 80) to get colors, else a single values determines the grayscale where fill(255) stands for #FFF(white) and fill(0) stands for #000(black)
+ }
+
+ ellipse(mouseX, mouseY, 80, 80);
+ // mouseX is the x-coordinate of the mouse's current position and mouseY is the y-coordinate of the mouse's current position
+
+ // the above code creates a circle wherever mouse's current position and fills it either black or white based on the mouseIsPressed
+}
+```
+
+## Further Reading
+
+- [p5.js | get started](http://p5js.org/get-started/) The official documentation
+- [Code! Programming for Beginners with p5.js - YouTube](https://www.youtube.com/watch?v=yPWkPOfnGsw&vl=en) Introduction and Coding challenges using Processing and p5.js by Coding Train
diff --git a/pascal.html.markdown b/pascal.html.markdown
new file mode 100644
index 00000000..a505a38f
--- /dev/null
+++ b/pascal.html.markdown
@@ -0,0 +1,206 @@
+---
+language: Pascal
+filename: learnpascal.pas
+contributors:
+ - ["Ganesha Danu", "http://github.com/blinfoldking"]
+ - ["Keith Miyake", "https://github.com/kaymmm"]
+---
+
+
+>Pascal is an imperative and procedural programming language, which Niklaus Wirth designed in 1968–69 and published in 1970, as a small, efficient language intended to encourage good programming practices using structured programming and data structuring. It is named in honor of the French mathematician, philosopher and physicist Blaise Pascal.
+source : [wikipedia](https://en.wikipedia.org/wiki/Pascal_(programming_language))
+
+
+
+to compile and run a pascal program you could use a free pascal compiler. [Download Here](https://www.freepascal.org/)
+
+```pascal
+//Anatomy of a Pascal Program
+//this is a comment
+{
+ this is a
+ multiline comment
+}
+
+//name of the program
+program learn_pascal; //<-- dont forget a semicolon
+
+const
+ {
+ this is where you should declare constant values
+ }
+type
+ {
+ this is where you should delcare a custom
+ data-types
+ }
+var
+ {
+ this is where you should declare a variable
+ }
+
+//main program area
+begin
+ {
+ area to declare your instruction
+ }
+end. // End of a main program area should required a "." symbol
+```
+
+```pascal
+//declaring variable
+//you can do this
+var a:integer;
+var b:integer;
+//or this
+var
+ a : integer;
+ b : integer;
+//or this
+var a,b : integer;
+```
+
+```pascal
+program Learn_More;
+//Lets learn about data types and their operations
+
+const
+ PI = 3.141592654;
+ GNU = 'GNU''s Not Unix';
+ // constants are conventionally named using CAPS
+ // their values are fixed and cannot be changed during runtime
+ // holds any standard data type (integer, real, boolean, char, string)
+
+type
+ ch_array : array [0..255] of char;
+ // arrays are new 'types' specifying the length and data type
+ // this defines a new data type that contains 255 characters
+ // (this is functionally equivalent to a string[256] variable)
+ md_array : array of array of integer;
+ // nested arrays are equivalent to multidimensional arrays
+ // can define zero (0) length arrays that are dynamically sized
+ // this is a 2-dimensional array of integers
+
+//Declaring variables
+var
+ int, c, d : integer;
+ // three variables that contain integer numbers
+ // integers are 16-bits and limited to the range [-32,768..32,767]
+ r : real;
+ // a variable that contains a real number data types
+ // reals can range between [3.4E-38..3.4E38]
+ bool : boolean;
+ // a variable that contains a Boolean(True/False) value
+ ch : char;
+ // a variable that contains a character value
+ // char variables are stored as 8-bit data types so no UTF
+ str : string;
+ // a non-standard variable that contains a string value
+ // strings are an extension included in most Pascal compilers
+ // they are stored as an array of char with default length of 255.
+ s : string[50];
+ // a string with maximum length of 50 chars.
+ // you can specify the length of the string to minimize memory usage
+ my_str: ch_array;
+ // you can declare variables of custom types
+ my_2d : md_array;
+ // dynamically sized arrays need to be sized before they can be used.
+
+ // additional integer data types
+ b : byte; // range [0..255]
+ shi : shortint; // range [-128..127]
+ smi : smallint; // range [-32,768..32,767] (standard Integer)
+ w : word; // range [0..65,535]
+ li : longint; // range [-2,147,483,648..2,147,483,647]
+ lw : longword; // range [0..4,294,967,295]
+ c : cardinal; // longword
+ i64 : int64; // range [-9223372036854775808..9223372036854775807]
+ qw : qword; // range [0..18,446,744,073,709,551,615]
+
+ // additional real types
+ rr : real; // range depends on platform (i.e., 8-bit, 16-bit, etc.)
+ rs : single; // range [1.5E-45..3.4E38]
+ rd : double; // range [5.0E-324 .. 1.7E308]
+ re : extended; // range [1.9E-4932..1.1E4932]
+ rc : comp; // range [-2E64+1 .. 2E63-1]
+
+Begin
+ int := 1;// how to assign a value to a variable
+ r := 3.14;
+ ch := 'a';
+ str := 'apple';
+ bool := true;
+ //pascal is not a case-sensitive language
+ //arithmethic operation
+ int := 1 + 1; // int = 2 overwriting the previous assignment
+ int := int + 1; // int = 2 + 1 = 3;
+ int := 4 div 2; //int = 2 division operation where result will be floored
+ int := 3 div 2; //int = 1
+ int := 1 div 2; //int = 0
+
+ bool := true or false; // bool = true
+ bool := false and true; // bool = false
+ bool := true xor true; // bool = false
+
+ r := 3 / 2; // a division operator for real
+ r := int; // can assign an integer to a real variable but not the reverse
+
+ c := str[1]; // assign the first letter of str to c
+ str := 'hello' + 'world'; //combining strings
+
+ my_str[0] := 'a'; // array assignment needs an index
+
+ setlength(my_2d,10,10); // initialize dynamically sized arrays: 10×10 array
+ for c := 0 to 9 do // arrays begin at 0 and end at length-1
+ for d := 0 to 9 do // for loop counters need to be declared variables
+ my_2d[c,d] := c * d;
+ // address multidimensional arrays with a single set of brackets
+
+End.
+```
+
+```pascal
+program Functional_Programming;
+
+Var
+ i, dummy : integer;
+
+function factorial_recursion(const a: integer) : integer;
+{ recursively calculates the factorial of integer parameter a }
+
+// Declare local variables within the function
+// e.g.:
+// Var
+// local_a : integer;
+
+Begin
+ If a >= 1 Then
+ // return values from functions by assigning a value to the function name
+ factorial_recursion := a * factorial_recursion(a-1)
+ Else
+ factorial_recursion := 1;
+End; // terminate a function using a semicolon after the End statement.
+
+procedure get_integer(var i : integer; dummy : integer);
+{ get user input and store it in the integer parameter i.
+ parameters prefaced with 'var' are variable, meaning their value can change
+ outside of the parameter. Value parameters (without 'var') like 'dummy' are
+ static and changes made within the scope of the function/procedure do not
+ affect the variable passed as a parameter }
+
+Begin
+ write('Enter an integer: ');
+ readln(i);
+ dummy := 4; // dummy will not change value outside of the procedure
+End;
+
+Begin // main program block
+ dummy := 3;
+ get_integer(i, dummy);
+ writeln(i, '! = ', factorial_recursion(i));
+ // outputs i!
+ writeln('dummy = ', dummy); // always outputs '3' since dummy is unchanged.
+End.
+
+```
+
diff --git a/pcre.html.markdown b/pcre.html.markdown
index 0b61653d..9e091721 100644
--- a/pcre.html.markdown
+++ b/pcre.html.markdown
@@ -3,16 +3,18 @@ language: PCRE
filename: pcre.txt
contributors:
- ["Sachin Divekar", "http://github.com/ssd532"]
-
+
---
-A regular expression (regex or regexp for short) is a special text string for describing a search pattern. e.g. to extract domain name from a string we can say `/^[a-z]+:/` and it will match `http:` from `http://github.com/`.
+A regular expression (regex or regexp for short) is a special text string for describing a search pattern. e.g. to extract domain name from a string we can say `/^[a-z]+:/` and it will match `http:` from `http://github.com/`.
PCRE (Perl Compatible Regular Expressions) is a C library implementing regex. It was written in 1997 when Perl was the de-facto choice for complex text processing tasks. The syntax for patterns used in PCRE closely resembles Perl. PCRE syntax is being used in many big projects including PHP, Apache, R to name a few.
There are two different sets of metacharacters:
+
* Those that are recognized anywhere in the pattern except within square brackets
+
```
\ general escape character with several uses
^ assert start of string (or line, in multiline mode)
@@ -32,18 +34,19 @@ There are two different sets of metacharacters:
```
* Those that are recognized within square brackets. Outside square brackets. They are also called as character classes.
-
+
```
-
+
\ general escape character
^ negate the class, but only if the first character
- indicates character range
[ POSIX character class (only if followed by POSIX syntax)
] terminates the character class
-
-```
-PCRE provides some generic character types, also called as character classes.
+```
+
+PCRE provides some generic character types, also called as character classes.
+
```
\d any decimal digit
\D any character that is not a decimal digit
@@ -59,24 +62,22 @@ PCRE provides some generic character types, also called as character classes.
## Examples
-We will test our examples on following string `66.249.64.13 - - [18/Sep/2004:11:07:48 +1000] "GET /robots.txt HTTP/1.0" 200 468 "-" "Googlebot/2.1"`. It is a standard Apache access log.
+We will test our examples on the following string:
-| Regex | Result | Comment |
-| :---- | :-------------- | :------ |
-| GET | GET | GET matches the characters GET literally (case sensitive) |
-| \d+.\d+.\d+.\d+ | 66.249.64.13 | `\d+` match a digit [0-9] one or more times defined by `+` quantifier, `\.` matches `.` literally |
-| (\d+\.){3}\d+ | 66.249.64.13 | `(\d+\.){3}` is trying to match group (`\d+\.`) exactly three times. |
-| \[.+\] | [18/Sep/2004:11:07:48 +1000] | `.+` matches any character (except newline), `.` is any character |
-| ^\S+ | 66.249.64.13 | `^` means start of the line, `\S+` matches any number of non-space characters |
-| \+[0-9]+ | +1000 | `\+` matches the character `+` literally. `[0-9]` character class means single number. Same can be achieved using `\+\d+` |
-
-All these examples can be tried at https://regex101.com/
+```
+66.249.64.13 - - [18/Sep/2004:11:07:48 +1000] "GET /robots.txt HTTP/1.0" 200 468 "-" "Googlebot/2.1"
+```
-1. Copy the example string in `TEST STRING` section
-2. Copy regex code in `Regular Expression` section
-3. The web application will show the matching result
+ It is a standard Apache access log.
+| Regex | Result | Comment |
+| :---- | :-------------- | :------ |
+| `GET` | GET | GET matches the characters GET literally (case sensitive) |
+| `\d+.\d+.\d+.\d+` | 66.249.64.13 | `\d+` match a digit [0-9] one or more times defined by `+` quantifier, `\.` matches `.` literally |
+| `(\d+\.){3}\d+` | 66.249.64.13 | `(\d+\.){3}` is trying to match group (`\d+\.`) exactly three times. |
+| `\[.+\]` | [18/Sep/2004:11:07:48 +1000] | `.+` matches any character (except newline), `.` is any character |
+| `^\S+` | 66.249.64.13 | `^` means start of the line, `\S+` matches any number of non-space characters |
+| `\+[0-9]+` | +1000 | `\+` matches the character `+` literally. `[0-9]` character class means single number. Same can be achieved using `\+\d+` |
## Further Reading
-
-
+[Regex101](https://regex101.com/) - Regular Expression tester and debugger
diff --git a/perl.html.markdown b/perl.html.markdown
index 3cbd2801..8811dd08 100644
--- a/perl.html.markdown
+++ b/perl.html.markdown
@@ -8,9 +8,9 @@ contributors:
- ["Dan Book", "http://github.com/Grinnz"]
---
-Perl 5 is a highly capable, feature-rich programming language with over 25 years of development.
+Perl is a highly capable, feature-rich programming language with over 25 years of development.
-Perl 5 runs on over 100 platforms from portables to mainframes and is suitable for both rapid prototyping and large scale development projects.
+Perl runs on over 100 platforms from portables to mainframes and is suitable for both rapid prototyping and large scale development projects.
```perl
# Single line comments start with a number sign.
@@ -37,10 +37,14 @@ use warnings;
# A scalar represents a single value:
my $animal = "camel";
my $answer = 42;
+my $display = "You have $answer ${animal}s.\n";
# Scalar values can be strings, integers or floating point numbers, and
# Perl will automatically convert between them as required.
+# Strings in single quotes are literal strings. Strings in double quotes
+# will interpolate variables and escape codes like "\n" for newline.
+
## Arrays
# An array represents a list of values:
my @animals = ("camel", "llama", "owl");
@@ -51,6 +55,25 @@ 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";
+
+# Arrays can also be interpolated into double-quoted strings, and the
+# elements are separated by a space character by default.
+
+print "We have these numbers: @numbers\n";
+
+# Be careful when using double quotes for strings containing symbols
+# such as email addresses, as it will be interpreted as a variable.
+
+my @example = ('secret', 'array');
+my $oops_email = "foo@example.com"; # 'foosecret array.com'
+my $ok_email = 'foo@example.com';
+
## Hashes
# A hash represents a set of key/value pairs:
@@ -67,6 +90,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).
@@ -124,26 +152,30 @@ while (condition) {
...
}
-
+my $max = 5;
# for loops and iteration
-for (my $i = 0; $i < $max; $i++) {
+for my $i (0 .. $max) {
print "index is $i";
}
-for (my $i = 0; $i < @elements; $i++) {
- print "Current element is " . $elements[$i];
-}
-
for my $element (@elements) {
print $element;
}
+map {print} @elements;
+
# implicitly
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 +202,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 +217,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
deleted file mode 100644
index 34ad70b7..00000000
--- a/perl6.html.markdown
+++ /dev/null
@@ -1,1639 +0,0 @@
----
-category: language
-language: perl6
-filename: learnperl6.p6
-contributors:
- - ["vendethiel", "http://github.com/vendethiel"]
- - ["Samantha McVey", "https://cry.nu"]
----
-
-Perl 6 is a highly capable, feature-rich programming language made for at
-least the next hundred years.
-
-The primary Perl 6 compiler is called [Rakudo](http://rakudo.org), which runs on
-the JVM and [the MoarVM](http://moarvm.com).
-
-Meta-note : the triple pound signs are here to denote headlines,
-double paragraphs, and single notes.
-
-`#=>` represents the output of a command.
-
-```perl
-# Single line comment start with a pound
-
-#`(
- Multiline comments use #` and a quoting construct.
- (), [], {}, 「」, etc, will work.
-)
-
-### Variables
-
-# In Perl 6, you declare a lexical variable using `my`
-my $variable;
-# Perl 6 has 4 kinds of variables:
-
-## * Scalars. They represent a single value. They start with a `$`
-
-my $str = 'String';
-# double quotes allow for interpolation (which we'll see later):
-my $str2 = "String";
-
-# Variable names can contain but not end with simple quotes and dashes,
-# and can contain (and end with) underscores :
-# my $weird'variable-name_ = 5; # works !
-
-my $bool = True; # `True` and `False` are Perl 6's boolean values.
-my $inverse = !$bool; # You can invert a bool with the prefix `!` operator
-my $forced-bool = so $str; # And you can use the prefix `so` operator
- # which turns its operand into a Bool
-
-## * Lists. They represent multiple values. Their name start with `@`.
-
-my @array = 'a', 'b', 'c';
-# equivalent to :
-my @letters = <a b c>; # array of words, delimited by space.
- # Similar to perl5's qw, or Ruby's %w.
-my @array = 1, 2, 3;
-
-say @array[2]; # Array indices start at 0 -- This is the third element
-
-say "Interpolate all elements of an array using [] : @array[]";
-#=> Interpolate all elements of an array using [] : 1 2 3
-
-@array[0] = -1; # Assign a new value to an array index
-@array[0, 1] = 5, 6; # Assign multiple values
-
-my @keys = 0, 2;
-@array[@keys] = @letters; # Assignment using an array containing index values
-say @array; #=> a 6 b
-
-## * Hashes, or key-value Pairs.
-# Hashes are pairs of keys and values.
-# You can construct a Pair object using the syntax `Key => Value`.
-# Hash tables are very fast for lookup, and are stored unordered.
-# Keep in mind that keys get "flattened" in hash context, and any duplicated
-# keys are deduplicated.
-my %hash = 1 => 2,
- 3 => 4;
-my %hash = foo => "bar", # keys get auto-quoted
- "some other" => "value", # trailing commas are okay
- ;
-# Even though hashes are internally stored differently than arrays,
-# Perl 6 allows you to easily create a hash from an even numbered array:
-my %hash = <key1 value1 key2 value2>;
-
-my %hash = key1 => 'value1', key2 => 'value2'; # same result as above
-
-# You can also use the "colon pair" syntax:
-# (especially handy for named parameters that you'll see later)
-my %hash = :w(1), # equivalent to `w => 1`
- # this is useful for the `True` shortcut:
- :truey, # equivalent to `:truey(True)`, or `truey => True`
- # and for the `False` one:
- :!falsey, # equivalent to `:falsey(False)`, or `falsey => False`
- ;
-
-say %hash{'key1'}; # You can use {} to get the value from a key
-say %hash<key2>; # If it's a string, you can actually use <>
- # (`{key1}` doesn't work, as Perl6 doesn't have barewords)
-
-## * Subs: subroutines or functions as most other languages call them are
-# created with the `sub` keyword.
-sub say-hello { say "Hello, world" }
-
-sub say-hello-to(Str $name) { # You can provide the type of an argument
- # and it'll be checked at compile-time.
-
- say "Hello, $name !";
-}
-
-## It can also have optional arguments:
-sub with-optional($arg?) { # the "?" marks the argument optional
- say "I might return `(Any)` (Perl's 'null'-like value) if I don't have
- an argument passed, or I'll return my argument";
- $arg;
-}
-with-optional; # returns Any
-with-optional(); # returns Any
-with-optional(1); # returns 1
-
-## You can also give them a default value when they're not passed:
-sub hello-to($name = "World") {
- say "Hello, $name !";
-}
-hello-to; #=> Hello, World !
-hello-to(); #=> Hello, World !
-hello-to('You'); #=> Hello, You !
-
-## You can also, by using a syntax akin to the one of hashes (yay unified syntax !),
-## pass *named* arguments to a `sub`.
-# They're optional, and will default to "Any".
-sub with-named($normal-arg, :$named) {
- say $normal-arg + $named;
-}
-with-named(1, named => 6); #=> 7
-# There's one gotcha to be aware of, here:
-# If you quote your key, Perl 6 won't be able to see it at compile time,
-# and you'll have a single Pair object as a positional parameter,
-# which means this fails:
-with-named(1, 'named' => 6);
-
-with-named(2, :named(5)); #=> 7
-
-# To make a named argument mandatory, you can use `?`'s inverse, `!`
-sub with-mandatory-named(:$str!) {
- say "$str !";
-}
-with-mandatory-named(str => "My String"); #=> My String !
-with-mandatory-named; # run time error: "Required named parameter not passed"
-with-mandatory-named(3); # run time error: "Too many positional parameters passed"
-
-## If a sub takes a named boolean argument ...
-sub takes-a-bool($name, :$bool) {
- say "$name takes $bool";
-}
-# ... you can use the same "short boolean" hash syntax:
-takes-a-bool('config', :bool); # config takes True
-takes-a-bool('config', :!bool); # config takes False
-
-## You can also provide your named arguments with defaults:
-sub named-def(:$def = 5) {
- say $def;
-}
-named-def; #=> 5
-named-def(def => 15); #=> 15
-
-# Since you can omit parenthesis to call a function with no arguments,
-# you need "&" in the name to store `say-hello` in a variable.
-my &s = &say-hello;
-my &other-s = sub { say "Anonymous function !" }
-
-# A sub can have a "slurpy" parameter, or "doesn't-matter-how-many"
-sub as-many($head, *@rest) { # `*@` (slurpy) will basically "take everything else".
- # Note: you can have parameters *before* (like here)
- # a slurpy one, but not *after*.
- say @rest.join(' / ') ~ " !";
-}
-say as-many('Happy', 'Happy', 'Birthday'); #=> Happy / Birthday !
- # Note that the splat (the *) did not
- # consume the parameter before.
-
-## You can call a function with an array using the
-# "argument list flattening" operator `|`
-# (it's not actually the only role of this operator, but it's one of them)
-sub concat3($a, $b, $c) {
- say "$a, $b, $c";
-}
-concat3(|@array); #=> a, b, c
- # `@array` got "flattened" as a part of the argument list
-
-### Containers
-# In Perl 6, values are actually stored in "containers".
-# The assignment operator asks the container on the left to store the value on
-# its right. When passed around, containers are marked as immutable.
-# Which means that, in a function, you'll get an error if you try to
-# mutate one of your arguments.
-# If you really need to, you can ask for a mutable container using `is rw`:
-sub mutate($n is rw) {
- $n++;
- say "\$n is now $n !";
-}
-
-my $m = 42;
-mutate $m; # $n is now 43 !
-
-# This works because we are passing the container $m to mutate. If we try
-# to just pass a number instead of passing a variable it won't work because
-# there is no container being passed and integers are immutable by themselves:
-
-mutate 42; # Parameter '$n' expected a writable container, but got Int value
-
-# If what you want a copy instead, use `is copy`.
-
-# A sub itself returns a container, which means it can be marked as rw:
-my $x = 42;
-sub x-store() is rw { $x }
-x-store() = 52; # in this case, the parentheses are mandatory
- # (else Perl 6 thinks `x-store` is an identifier)
-say $x; #=> 52
-
-
-### Control Flow Structures
-## Conditionals
-
-# - `if`
-# Before talking about `if`, we need to know which values are "Truthy"
-# (represent True), and which are "Falsey" (or "Falsy") -- represent False.
-# Only these values are Falsey: 0, (), {}, "", Nil, A type (like `Str` or `Int`),
-# and of course False itself.
-# Every other value is Truthy.
-if True {
- say "It's true !";
-}
-
-unless False {
- say "It's not false !";
-}
-
-# As you can see, you don't need parentheses around conditions.
-# However, you do need the brackets around the "body" block:
-# if (true) say; # This doesn't work !
-
-# You can also use their postfix versions, with the keyword after:
-say "Quite truthy" if True;
-
-# - Ternary conditional, "?? !!" (like `x ? y : z` in some other languages)
-# returns $value-if-true if the condition is true and $value-if-false
-# if it is false.
-# my $result = $value condition ?? $value-if-true !! $value-if-false;
-
-my $age = 30;
-say $age > 18 ?? "You are an adult" !! "You are under 18";
-
-# - `given`-`when` looks like other languages' `switch`, but is much more
-# powerful thanks to smart matching and Perl 6's "topic variable", $_.
-#
-# This variable contains the default argument of a block,
-# a loop's current iteration (unless explicitly named), etc.
-#
-# `given` simply puts its argument into `$_` (like a block would do),
-# and `when` compares it using the "smart matching" (`~~`) operator.
-#
-# Since other Perl 6 constructs use this variable (as said before, like `for`,
-# blocks, etc), this means the powerful `when` is not only applicable along with
-# a `given`, but instead anywhere a `$_` exists.
-
-given "foo bar" {
- say $_; #=> foo bar
- when /foo/ { # Don't worry about smart matching yet – just know `when` uses it.
- # This is equivalent to `if $_ ~~ /foo/`.
- say "Yay !";
- }
- when $_.chars > 50 { # smart matching anything with True (`$a ~~ True`) is True,
- # so you can also put "normal" conditionals.
- # This when is equivalent to this `if`:
- # if $_ ~~ ($_.chars > 50) {...}
- # Which means:
- # if $_.chars > 50 {...}
- say "Quite a long string !";
- }
- default { # same as `when *` (using the Whatever Star)
- say "Something else"
- }
-}
-
-## Looping constructs
-
-# - `loop` is an infinite loop if you don't pass it arguments,
-# but can also be a C-style `for` loop:
-loop {
- say "This is an infinite loop !";
- last; # last breaks out of the loop, like the `break` keyword in other languages
-}
-
-loop (my $i = 0; $i < 5; $i++) {
- next if $i == 3; # `next` skips to the next iteration, like `continue`
- # in other languages. Note that you can also use postfix
- # conditionals, loops, etc.
- say "This is a C-style for loop !";
-}
-
-# - `for` - Passes through an array
-for @array -> $variable {
- say "I've got $variable !";
-}
-
-# As we saw with given, for's default "current iteration" variable is `$_`.
-# That means you can use `when` in a `for` just like you were in a `given`.
-for @array {
- say "I've got $_";
-
- .say; # This is also allowed.
- # A dot call with no "topic" (receiver) is sent to `$_` by default
- $_.say; # the above and this are equivalent.
-}
-
-for @array {
- # You can...
- next if $_ == 3; # Skip to the next iteration (`continue` in C-like languages).
- redo if $_ == 4; # Re-do the iteration, keeping the same topic variable (`$_`).
- last if $_ == 5; # Or break out of a loop (like `break` in C-like languages).
-}
-
-# The "pointy block" syntax isn't specific to for.
-# It's just a way to express a block in Perl6.
-if long-computation() -> $result {
- say "The result is $result";
-}
-
-### Operators
-
-## Since Perl languages are very much operator-based languages,
-## Perl 6 operators are actually just funny-looking subroutines, in syntactic
-## categories, like infix:<+> (addition) or prefix:<!> (bool not).
-
-## The categories are:
-# - "prefix": before (like `!` in `!True`).
-# - "postfix": after (like `++` in `$a++`).
-# - "infix": in between (like `*` in `4 * 3`).
-# - "circumfix": around (like `[`-`]` in `[1, 2]`).
-# - "post-circumfix": around, after another term (like `{`-`}` in `%hash{'key'}`)
-
-## The associativity and precedence list are explained below.
-
-# Alright, you're set to go !
-
-## * Equality Checking
-
-# - `==` is numeric comparison
-3 == 4; # False
-3 != 4; # True
-
-# - `eq` is string comparison
-'a' eq 'b';
-'a' ne 'b'; # not equal
-'a' !eq 'b'; # same as above
-
-# - `eqv` is canonical equivalence (or "deep equality")
-(1, 2) eqv (1, 3);
-
-# - Smart Match Operator: `~~`
-# Aliases the left hand side to $_ and then evaluates the right hand side.
-# Here are some common comparison semantics:
-
-# String or Numeric Equality
-
-'Foo' ~~ 'Foo'; # True if strings are equal.
-12.5 ~~ 12.50; # True if numbers are equal.
-
-# Regex - For matching a regular expression against the left side.
-# Returns a (Match) object, which evaluates as True if regexp matches.
-
-my $obj = 'abc' ~~ /a/;
-say $obj; # 「a」
-say $obj.WHAT; # (Match)
-
-# Hashes
-'key' ~~ %hash; # True if key exists in hash
-
-# Type - Checks if left side "has type" (can check superclasses and roles)
-
-1 ~~ Int; # True
-
-# Smart-matching against a boolean always returns that boolean (and will warn).
-
-1 ~~ True; # True
-False ~~ True; # True
-
-# # General syntax is $arg ~~ &bool-returning-function;
-# For a complete list of combinations, use this table:
-# http://perlcabal.org/syn/S03.html#Smart_matching
-
-# You also, of course, have `<`, `<=`, `>`, `>=`.
-# Their string equivalent are also avaiable : `lt`, `le`, `gt`, `ge`.
-3 > 4;
-
-## * Range constructors
-3 .. 7; # 3 to 7, both included
-# `^` on either side them exclusive on that side :
-3 ^..^ 7; # 3 to 7, not included (basically `4 .. 6`)
-# This also works as a shortcut for `0..^N`:
-^10; # means 0..^10
-
-# This also allows us to demonstrate that Perl 6 has lazy/infinite arrays,
-# using the Whatever Star:
-my @array = 1..*; # 1 to Infinite ! `1..Inf` is the same.
-say @array[^10]; # you can pass arrays as subscripts and it'll return
- # an array of results. This will print
- # "1 2 3 4 5 6 7 8 9 10" (and not run out of memory !)
-# Note : when reading an infinite list, Perl 6 will "reify" the elements
-# it needs, then keep them in memory. They won't be calculated more than once.
-# It also will never calculate more elements that are needed.
-
-# An array subscript can also be a closure.
-# It'll be called with the length as the argument
-say join(' ', @array[15..*]); #=> 15 16 17 18 19
-# which is equivalent to:
-say join(' ', @array[-> $n { 15..$n }]);
-# Note: if you try to do either of those with an infinite array,
-# you'll trigger an infinite loop (your program won't finish)
-
-# You can use that in most places you'd expect, even assigning to an array
-my @numbers = ^20;
-
-# Here numbers increase by "6"; more on `...` operator later.
-my @seq = 3, 9 ... * > 95; # 3 9 15 21 27 [...] 81 87 93 99;
-@numbers[5..*] = 3, 9 ... *; # even though the sequence is infinite,
- # only the 15 needed values will be calculated.
-say @numbers; #=> 0 1 2 3 4 3 9 15 21 [...] 81 87
- # (only 20 values)
-
-## * And &&, Or ||
-3 && 4; # 4, which is Truthy. Calls `.Bool` on `4` and gets `True`.
-0 || False; # False. Calls `.Bool` on `0`
-
-## * Short-circuit (and tight) versions of the above
-# Returns the first argument that evaluates to False, or the last argument.
-
-my ( $a, $b, $c ) = 1, 0, 2;
-$a && $b && $c; # Returns 0, the first False value
-
-# || Returns the first argument that evaluates to True
-$b || $a; # 1
-
-# And because you're going to want them,
-# you also have compound assignment operators:
-$a *= 2; # multiply and assignment. Equivalent to $a = $a * 2;
-$b %%= 5; # divisible by and assignment
-@array .= sort; # calls the `sort` method and assigns the result back
-
-### More on subs !
-# As we said before, Perl 6 has *really* powerful subs. We're going to see
-# a few more key concepts that make them better than in any other language :-).
-
-## Unpacking !
-# It's the ability to "extract" arrays and keys (AKA "destructuring").
-# It'll work in `my`s and in parameter lists.
-my ($f, $g) = 1, 2;
-say $f; #=> 1
-my ($, $, $h) = 1, 2, 3; # keep the non-interesting anonymous
-say $h; #=> 3
-
-my ($head, *@tail) = 1, 2, 3; # Yes, it's the same as with "slurpy subs"
-my (*@small) = 1;
-
-sub unpack_array(@array [$fst, $snd]) {
- say "My first is $fst, my second is $snd ! All in all, I'm @array[].";
- # (^ remember the `[]` to interpolate the array)
-}
-unpack_array(@tail); #=> My first is 2, my second is 3 ! All in all, I'm 2 3
-
-
-# If you're not using the array itself, you can also keep it anonymous,
-# much like a scalar:
-sub first-of-array(@ [$fst]) { $fst }
-first-of-array(@small); #=> 1
-first-of-array(@tail); # Throws an error "Too many positional parameters passed"
- # (which means the array is too big).
-
-# You can also use a slurp ...
-sub slurp-in-array(@ [$fst, *@rest]) { # You could keep `*@rest` anonymous
- say $fst + @rest.elems; # `.elems` returns a list's length.
- # Here, `@rest` is `(3,)`, since `$fst` holds the `2`.
-}
-slurp-in-array(@tail); #=> 3
-
-# You could even extract on a slurpy (but it's pretty useless ;-).)
-sub fst(*@ [$fst]) { # or simply : `sub fst($fst) { ... }`
- say $fst;
-}
-fst(1); #=> 1
-fst(1, 2); # errors with "Too many positional parameters passed"
-
-# You can also destructure hashes (and classes, which you'll learn about later !)
-# The syntax is basically `%hash-name (:key($variable-to-store-value-in))`.
-# The hash can stay anonymous if you only need the values you extracted.
-sub key-of(% (:value($val), :qua($qua))) {
- say "Got val $val, $qua times.";
-}
-
-# Then call it with a hash: (you need to keep the brackets for it to be a hash)
-key-of({value => 'foo', qua => 1});
-#key-of(%hash); # the same (for an equivalent `%hash`)
-
-## The last expression of a sub is returned automatically
-# (though you may use the `return` keyword, of course):
-sub next-index($n) {
- $n + 1;
-}
-my $new-n = next-index(3); # $new-n is now 4
-
-# This is true for everything, except for the looping constructs
-# (due to performance reasons): there's reason to build a list
-# if we're just going to discard all the results.
-# If you still want to build one, you can use the `do` statement prefix:
-# (or the `gather` prefix, which we'll see later)
-sub list-of($n) {
- do for ^$n { # note the use of the range-to prefix operator `^` (`0..^N`)
- $_ # current loop iteration
- }
-}
-my @list3 = list-of(3); #=> (0, 1, 2)
-
-## You can create a lambda with `-> {}` ("pointy block") or `{}` ("block")
-my &lambda = -> $argument { "The argument passed to this lambda is $argument" }
-# `-> {}` and `{}` are pretty much the same thing, except that the former can
-# take arguments, and that the latter can be mistaken as a hash by the parser.
-
-# We can, for example, add 3 to each value of an array using map:
-my @arrayplus3 = map({ $_ + 3 }, @array); # $_ is the implicit argument
-
-# A sub (`sub {}`) has different semantics than a block (`{}` or `-> {}`):
-# A block doesn't have a "function context" (though it can have arguments),
-# which means that if you return from it,
-# you're going to return from the parent function. Compare:
-sub is-in(@array, $elem) {
- # this will `return` out of the `is-in` sub
- # once the condition evaluated to True, the loop won't be run anymore
- map({ return True if $_ == $elem }, @array);
-}
-sub truthy-array(@array) {
- # this will produce an array of `True` and `False`:
- # (you can also say `anon sub` for "anonymous subroutine")
- map(sub ($i) { if $i { return True } else { return False } }, @array);
- # ^ the `return` only returns from the anonymous `sub`
-}
-
-# You can also use the "whatever star" to create an anonymous function
-# (it'll stop at the furthest operator in the current expression)
-my @arrayplus3 = map(*+3, @array); # `*+3` is the same as `{ $_ + 3 }`
-my @arrayplus3 = map(*+*+3, @array); # Same as `-> $a, $b { $a + $b + 3 }`
- # also `sub ($a, $b) { $a + $b + 3 }`
-say (*/2)(4); #=> 2
- # Immediatly execute the function Whatever created.
-say ((*+3)/5)(5); #=> 1.6
- # works even in parens !
-
-# But if you need to have more than one argument (`$_`)
-# in a block (without wanting to resort to `-> {}`),
-# you can also use the implicit argument syntax, `$^` :
-map({ $^a + $^b + 3 }, @array); # equivalent to following:
-map(sub ($a, $b) { $a + $b + 3 }, @array); # (here with `sub`)
-
-# Note : those are sorted lexicographically.
-# `{ $^b / $^a }` is like `-> $a, $b { $b / $a }`
-
-## About types...
-# Perl6 is gradually typed. This means you can specify the type
-# of your variables/arguments/return types, or you can omit them
-# and they'll default to "Any".
-# You obviously get access to a few base types, like Int and Str.
-# The constructs for declaring types are "class", "role",
-# which you'll see later.
-
-# For now, let us examine "subset":
-# a "subset" is a "sub-type" with additional checks.
-# For example: "a very big integer is an Int that's greater than 500"
-# You can specify the type you're subtyping (by default, Any),
-# and add additional checks with the "where" keyword:
-subset VeryBigInteger of Int where * > 500;
-
-## Multiple Dispatch
-# Perl 6 can decide which variant of a `sub` to call based on the type of the
-# arguments, or on arbitrary preconditions, like with a type or a `where`:
-
-# with types
-multi sub sayit(Int $n) { # note the `multi` keyword here
- say "Number: $n";
-}
-multi sayit(Str $s) { # a multi is a `sub` by default
- say "String: $s";
-}
-sayit("foo"); # prints "String: foo"
-sayit(True); # fails at *compile time* with
- # "calling 'sayit' will never work with arguments of types ..."
-
-# with arbitrary precondition (remember subsets?):
-multi is-big(Int $n where * > 50) { "Yes !" } # using a closure
-multi is-big(Int $ where 10..50) { "Quite." } # Using smart-matching
- # (could use a regexp, etc)
-multi is-big(Int $) { "No" }
-
-subset Even of Int where * %% 2;
-
-multi odd-or-even(Even) { "Even" } # The main case using the type.
- # We don't name the argument.
-multi odd-or-even($) { "Odd" } # "else"
-
-# You can even dispatch based on a positional's argument presence !
-multi with-or-without-you(:$with!) { # You need make it mandatory to
- # be able to dispatch against it.
- say "I can live ! Actually, I can't.";
-}
-multi with-or-without-you {
- say "Definitely can't live.";
-}
-# This is very, very useful for many purposes, like `MAIN` subs (covered later),
-# and even the language itself is using it in several places.
-#
-# - `is`, for example, is actually a `multi sub` named `trait_mod:<is>`,
-# and it works off that.
-# - `is rw`, is simply a dispatch to a function with this signature:
-# sub trait_mod:<is>(Routine $r, :$rw!) {}
-#
-# (commented because running this would be a terrible idea !)
-
-
-### Scoping
-# In Perl 6, unlike many scripting languages, (such as Python, Ruby, PHP),
-# you must declare your variables before using them. The `my` declarator
-# you have learned uses "lexical scoping". There are a few other declarators,
-# (`our`, `state`, ..., ) which we'll see later.
-# This is called "lexical scoping", where in inner blocks,
-# you can access variables from outer blocks.
-my $file_scoped = 'Foo';
-sub outer {
- my $outer_scoped = 'Bar';
- sub inner {
- say "$file_scoped $outer_scoped";
- }
- &inner; # return the function
-}
-outer()(); #=> 'Foo Bar'
-
-# As you can see, `$file_scoped` and `$outer_scoped` were captured.
-# But if we were to try and use `$bar` outside of `foo`,
-# the variable would be undefined (and you'd get a compile time error).
-
-### Twigils
-
-# There are many special `twigils` (composed sigil's) in Perl 6.
-# Twigils define the variables' scope.
-# The * and ? twigils work on standard variables:
-# * Dynamic variable
-# ? Compile-time variable
-# The ! and the . twigils are used with Perl 6's objects:
-# ! Attribute (class member)
-# . Method (not really a variable)
-
-# `*` Twigil: Dynamic Scope
-# These variables use the`*` twigil to mark dynamically-scoped variables.
-# Dynamically-scoped variables are looked up through the caller, not through
-# the outer scope
-
-my $*dyn_scoped_1 = 1;
-my $*dyn_scoped_2 = 10;
-
-sub say_dyn {
- say "$*dyn_scoped_1 $*dyn_scoped_2";
-}
-
-sub call_say_dyn {
- my $*dyn_scoped_1 = 25; # Defines $*dyn_scoped_1 only for this sub.
- $*dyn_scoped_2 = 100; # Will change the value of the file scoped variable.
- say_dyn(); #=> 25 100 $*dyn_scoped 1 and 2 will be looked for in the call.
- # It uses he value of $*dyn_scoped_1 from inside this sub's lexical
- # scope even though the blocks aren't nested (they're call-nested).
-}
-say_dyn(); #=> 1 10
-call_say_dyn(); #=> 25 100
- # Uses $*dyn_scoped_1 as defined in call_say_dyn even though
- # we are calling it from outside.
-say_dyn(); #=> 1 100 We changed the value of $*dyn_scoped_2 in call_say_dyn
- # so now its value has changed.
-
-### Object Model
-
-# To call a method on an object, add a dot followed by the method name:
-# => $object.method
-# Classes are declared with the `class` keyword. Attributes are declared
-# with the `has` keyword, and methods declared with `method`.
-# Every attribute that is private uses the ! twigil for example: `$!attr`.
-# Immutable public attributes use the `.` twigil.
-# (you can make them mutable with `is rw`)
-# The easiest way to remember the `$.` twigil is comparing it to how methods
-# are called.
-
-# Perl 6's object model ("SixModel") is very flexible,
-# and allows you to dynamically add methods, change semantics, etc ...
-# (these will not all be covered here, and you should refer to:
-# https://docs.perl6.org/language/objects.html.
-
-class Attrib-Class {
- has $.attrib; # `$.attrib` is immutable.
- # From inside the class, use `$!attrib` to modify it.
- has $.other-attrib is rw; # You can mark a public attribute `rw`.
- has Int $!private-attrib = 10;
-
- method get-value {
- $.attrib + $!private-attrib;
- }
-
- method set-value($param) { # Methods can take parameters
- $!attrib = $param; # This works, because `$!` is always mutable.
- # $.attrib = $param; # Wrong: You can't use the `$.` immutable version.
-
- $.other-attrib = 5; # This works, because `$.other-attrib` is `rw`.
- }
-
- method !private-method {
- say "This method is private to the class !";
- }
-};
-
-# Create a new instance of Attrib-Class with $.attrib set to 5 :
-# Note: you can't set private-attribute from here (more later on).
-my $class-obj = Attrib-Class.new(attrib => 5);
-say $class-obj.get-value; #=> 15
-#$class-obj.attrib = 5; # This fails, because the `has $.attrib` is immutable
-$class-obj.other-attrib = 10; # This, however, works, because the public
- # attribute is mutable (`rw`).
-
-## Object Inheritance
-# Perl 6 also has inheritance (along with multiple inheritance)
-# While `method`'s are inherited, `submethod`'s are not.
-# Submethods are useful for object construction and destruction tasks,
-# such as BUILD, or methods that must be overriden by subtypes.
-# We will learn about BUILD later on.
-
-class Parent {
- has $.age;
- has $.name;
- # This submethod won't be inherited by Child.
- submethod favorite-color {
- say "My favorite color is Blue";
- }
- # This method is inherited
- method talk { say "Hi, my name is $!name" }
-}
-# Inheritance uses the `is` keyword
-class Child is Parent {
- method talk { say "Goo goo ga ga" }
- # This shadows Parent's `talk` method, This child hasn't learned to speak yet!
-}
-my Parent $Richard .= new(age => 40, name => 'Richard');
-$Richard.favorite-color; #=> "My favorite color is Blue"
-$Richard.talk; #=> "Hi, my name is Richard"
-# # $Richard is able to access the submethod, he knows how to say his name.
-
-my Child $Madison .= new(age => 1, name => 'Madison');
-$Madison.talk; # prints "Goo goo ga ga" due to the overrided method.
-# $Madison.favorite-color does not work since it is not inherited
-
-# When you use `my T $var`, `$var` starts off with `T` itself in it,
-# so you can call `new` on it.
-# (`.=` is just the dot-call and the assignment operator:
-# `$a .= b` is the same as `$a = $a.b`)
-# Also note that `BUILD` (the method called inside `new`)
-# will set parent properties too, so you can pass `val => 5`.
-
-
-## Roles are supported too (also called Mixins in other languages)
-role PrintableVal {
- has $!counter = 0;
- method print {
- say $.val;
- }
-}
-
-# you "import" a mixin (a "role") with "does":
-class Item does PrintableVal {
- has $.val;
-
- # When `does`-ed, a `role` literally "mixes in" the class:
- # the methods and attributes are put together, which means a class can access
- # the private attributes/methods of its roles (but not the inverse !):
- method access {
- say $!counter++;
- }
-
- # However, this:
- # method print {}
- # is ONLY valid when `print` isn't a `multi` with the same dispatch.
- # (this means a parent class can shadow a child class's `multi print() {}`,
- # but it's an error if a role does)
-
- # NOTE: You can use a role as a class (with `is ROLE`). In this case, methods
- # will be shadowed, since the compiler will consider `ROLE` to be a class.
-}
-
-### Exceptions
-# Exceptions are built on top of classes, in the package `X` (like `X::IO`).
-# In Perl6 exceptions are automatically 'thrown'
-open 'foo'; #> Failed to open file foo: no such file or directory
-# It will also print out what line the error was thrown at and other error info
-
-# You can throw an exception using `die`:
-die 'Error!'; #=> Error!
-# Or more explicitly:
-die X::AdHoc.new(payload => 'Error!');
-
-# In Perl 6, `orelse` is similar to the `or` operator, except it only matches
-# undefined variables instead of anything evaluating as false.
-# 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;
-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
-# error messages to the screen.
-# We can use the exception method on $_ to access the exception
-open 'foo' orelse say "Something happened {.exception}";
-# This also works:
-open 'foo' orelse say "Something happened $_"; #> Something happened
- #> Failed to open file foo: no such file or directory
-# Both of those above work but in case we get an object from the left side that
-# is not a failure we will probably get a warning. We see below how we can use
-# `try` and `CATCH` to be more specific with the exceptions we catch.
-
-## Using `try` and `CATCH`
-# By using `try` and `CATCH` you can contain and handle exceptions without
-# disrupting the rest of the program. `try` will set the last exception to
-# the special variable `$!` Note: This has no relation to $!variables.
-try open 'foo';
-say "Well, I tried! $!" if defined $!; #> Well, I tried! Failed to open file
- #foo: no such file or directory
-# Now, what if we want more control over handling the exception?
-# Unlike many other languages, in Perl 6, you put the `CATCH` block *within*
-# the block to `try`. Similar to how $_ was set when we 'disarmed' the
-# exception with orelse, we also use $_ in the CATCH block.
-# Note: ($! is only set *after* the `try` block)
-# By default, a `try` has a `CATCH` block that catches
-# any exception (`CATCH { default {} }`).
-
-try { my $a = (0 %% 0); CATCH { say "Something happened: $_" } }
- #=> Something happened: Attempt to divide by zero using infix:<%%>
-
-# You can redefine it using `when`s (and `default`)
-# to handle the exceptions you want:
-try {
- open 'foo';
- CATCH { # In the `CATCH` block, the exception is set to $_
- when X::AdHoc { say "Error: $_" }
- #=>Error: Failed to open file /dir/foo: no such file or directory
-
- # Any other exception will be re-raised, since we don't have a `default`
- # Basically, if a `when` matches (or there's a `default`) marks the
- # exception as
- # "handled" so that it doesn't get re-thrown from the `CATCH`.
- # You still can re-throw the exception (see below) by hand.
- }
-}
-
-# There are also some subtleties to exceptions. Some Perl 6 subs return a
-# `Failure`, which is a kind of "unthrown exception". They're not thrown until
-# you tried to look at their content, unless you call `.Bool`/`.defined` on
-# them - then they're handled.
-# (the `.handled` method is `rw`, so you can mark it as `False` back yourself)
-#
-# You can throw a `Failure` using `fail`. Note that if the pragma `use fatal`
-# is on, `fail` will throw an exception (like `die`).
-fail "foo"; # We're not trying to access the value, so no problem.
-try {
- fail "foo";
- CATCH {
- default { say "It threw because we tried to get the fail's value!" }
- }
-}
-
-# There is also another kind of exception: Control exceptions.
-# Those are "good" exceptions, which happen when you change your program's flow,
-# using operators like `return`, `next` or `last`.
-# You can "catch" those with `CONTROL` (not 100% working in Rakudo yet).
-
-### Packages
-# Packages are a way to reuse code. Packages are like "namespaces", and any
-# element of the six model (`module`, `role`, `class`, `grammar`, `subset`
-# and `enum`) are actually packages. (Packages are the lowest common denominator)
-# Packages are important - especially as Perl is well-known for CPAN,
-# the Comprehensive Perl Archive Network.
-
-# You can use a module (bring its declarations into scope) with `use`
-use JSON::Tiny; # if you installed Rakudo* or Panda, you'll have this module
-say from-json('[1]').perl; #=> [1]
-
-# Declare your own packages like this:
-# `class Package::Name::Here;` to declare a class, or if you only want to
-# export variables/subs, you can use `module`. If you're coming from Perl 5
-# please note you're not usually supposed to use the `package` keyword.
-
-module Hello::World { # Bracketed form
- # If `Hello` doesn't exist yet, it'll just be a "stub",
- # that can be redeclared as something else later.
- # ... declarations here ...
-}
-unit module Parse::Text; # file-scoped form
-
-grammar Parse::Text::Grammar { # A grammar is a package, which you could `use`
-} # You will learn more about grammars in the regex section
-
-# As said before, any part of the six model is also a package.
-# Since `JSON::Tiny` uses (its own) `JSON::Tiny::Actions` class, you can use it:
-my $actions = JSON::Tiny::Actions.new;
-
-# We'll see how to export variables and subs in the next part:
-
-### Declarators
-# In Perl 6, you get different behaviors based on how you declare a variable.
-# You've already seen `my` and `has`, we'll now explore the others.
-
-## * `our` declarations happen at `INIT` time -- (see "Phasers" below)
-# It's like `my`, but it also creates a package variable.
-# (All packagish things (`class`, `role`, etc) are `our` by default)
-module Var::Increment {
- our $our-var = 1; # Note: you can't put a type constraint like Int on an
- my $my-var = 22; # `our` variable.
- our sub Inc {
-
- our sub available { # If you try to make inner `sub`s `our`...
- # Better know what you're doing (Don't !).
- say "Don't do that. Seriously. You'll get burned.";
- }
-
- my sub unavailable { # `my sub` is the default
- say "Can't access me from outside, I'm 'my'!";
- }
- say ++$our-var; # Increment the package variable and output its value
- }
-
-}
-say $Var::Increment::our-var; #=> 1 This works
-say $Var::Increment::my-var; #=> (Any) This will not work.
-
-Var::Increment::Inc; #=> 2
-Var::Increment::Inc; #=> 3 # Notice how the value of $our-var was
- # retained.
-Var::Increment::unavailable; #> Could not find symbol '&unavailable'
-
-## * `constant` (happens at `BEGIN` time)
-# You can use the `constant` keyword to declare a compile-time variable/symbol:
-constant Pi = 3.14;
-constant $var = 1;
-
-# And if you're wondering, yes, it can also contain infinite lists.
-constant why-not = 5, 15 ... *;
-say why-not[^5]; #=> 5 15 25 35 45
-
-## * `state` (happens at run time, but only once)
-# State variables are only initialized one time
-# (they exist in other langages such as C as `static`)
-sub fixed-rand {
- state $val = rand;
- say $val;
-}
-fixed-rand for ^10; # will print the same number 10 times
-
-# Note, however, that they exist separately in different enclosing contexts.
-# If you declare a function with a `state` within a loop, it'll re-create the
-# variable for each iteration of the loop. See:
-for ^5 -> $a {
- sub foo {
- state $val = rand; # This will be a different value for every value of `$a`
- }
- for ^5 -> $b {
- say foo; # This will print the same value 5 times, but only 5.
- # Next iteration will re-run `rand`.
- }
-}
-
-
-
-### Phasers
-# Phasers in Perl 6 are blocks that happen at determined points of time in your
-# program. They are called phasers because they mark a change in the phase
-# of a program. For example, when the program is compiled, a for loop runs,
-# you leave a block, or an exception gets thrown. (`CATCH` is actually a phaser !)
-# Some of them can be used for their return values, some of them can't
-# (those that can have a "[*]" in the beginning of their explanation text).
-# Let's have a look !
-
-## * Compile-time phasers
-BEGIN { say "[*] Runs at compile time, as soon as possible, only once" }
-CHECK { say "[*] Runs at compile time, as late as possible, only once" }
-
-## * Run-time phasers
-INIT { say "[*] Runs at run time, as soon as possible, only once" }
-END { say "Runs at run time, as late as possible, only once" }
-
-## * Block phasers
-ENTER { say "[*] Runs everytime you enter a block, repeats on loop blocks" }
-LEAVE { say "Runs everytime you leave a block, even when an exception
- happened. Repeats on loop blocks." }
-
-PRE { say "Asserts a precondition at every block entry,
- before ENTER (especially useful for loops)" }
-# exemple:
-for 0..2 {
- PRE { $_ > 1 } # This is going to blow up with "Precondition failed"
-}
-
-POST { say "Asserts a postcondition at every block exit,
- after LEAVE (especially useful for loops)" }
-for 0..2 {
- POST { $_ < 2 } # This is going to blow up with "Postcondition failed"
-}
-
-## * Block/exceptions phasers
-sub {
- KEEP { say "Runs when you exit a block successfully (without throwing an exception)" }
- UNDO { say "Runs when you exit a block unsuccessfully (by throwing an exception)" }
-}
-
-## * Loop phasers
-for ^5 {
- FIRST { say "[*] The first time the loop is run, before ENTER" }
- NEXT { say "At loop continuation time, before LEAVE" }
- LAST { say "At loop termination time, after LEAVE" }
-}
-
-## * Role/class phasers
-COMPOSE { "When a role is composed into a class. /!\ NOT YET IMPLEMENTED" }
-
-# They allow for cute tricks or clever code ...:
-say "This code took " ~ (time - CHECK time) ~ "s to compile";
-
-# ... or clever organization:
-sub do-db-stuff {
- $db.start-transaction; # start a new transaction
- KEEP $db.commit; # commit the transaction if all went well
- UNDO $db.rollback; # or rollback if all hell broke loose
-}
-
-### Statement prefixes
-# Those act a bit like phasers: they affect the behavior of the following code.
-# Though, they run in-line with the executable code, so they're in lowercase.
-# (`try` and `start` are theoretically in that list, but explained somewhere else)
-# Note: all of these (except start) don't need explicit brackets `{` and `}`.
-
-# - `do` (that you already saw) - runs a block or a statement as a term
-# You can't normally use a statement as a value (or "term"):
-#
-# my $value = if True { 1 } # `if` is a statement - parse error
-#
-# This works:
-my $a = do if True { 5 } # with `do`, `if` is now a term.
-
-# - `once` - Makes sure a piece of code only runs once
-for ^5 { once say 1 }; #=> 1
- # Only prints ... once.
-# Like `state`, they're cloned per-scope
-for ^5 { sub { once say 1 }() } #=> 1 1 1 1 1
- # Prints once per lexical scope
-
-# - `gather` - Co-routine thread
-# Gather allows you to `take` several values in an array,
-# much like `do`, but allows you to take any expression.
-say gather for ^5 {
- take $_ * 3 - 1;
- take $_ * 3 + 1;
-} #=> -1 1 2 4 5 7 8 10 11 13
-say join ',', gather if False {
- take 1;
- take 2;
- take 3;
-} # Doesn't print anything.
-
-# - `eager` - Evaluate statement eagerly (forces eager context)
-# Don't try this at home:
-#
-# eager 1..*; # this will probably hang for a while (and might crash ...).
-#
-# But consider:
-constant thrice = gather for ^3 { say take $_ }; # Doesn't print anything
-# versus:
-constant thrice = eager gather for ^3 { say take $_ }; #=> 0 1 2
-
-### Iterables
-# Iterables are objects that can be iterated similar to the `for` construct
-# `flat`, flattens iterables:
-say (1, 10, (20, 10) ); #> (1 10 (20 10)) Notice how grouping is maintained
-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; #> [...] List has not been iterated on!
-my @lazy-array { .print }; # This works and will only do as much work as is
-# needed.
-[//]: # ( TODO explain that gather/take and map are all lazy)
-# - `sink` - An `eager` that discards the results (forces sink context)
-constant nilthingie = sink for ^3 { .say } #=> 0 1 2
-say nilthingie.perl; #=> Nil
-
-# - `quietly` blocks will suppress warnings:
-quietly { warn 'This is a warning!' }; #=> No output
-
-# - `contend` - Attempts side effects under STM
-# Not yet implemented !
-
-### More operators thingies !
-
-## Everybody loves operators ! Let's get more of them
-
-# The precedence list can be found here:
-# https://docs.perl6.org/language/operators#Operator_Precedence
-# But first, we need a little explanation about associativity:
-
-# * Binary operators:
-$a ! $b ! $c; # with a left-associative `!`, this is `($a ! $b) ! $c`
-$a ! $b ! $c; # with a right-associative `!`, this is `$a ! ($b ! $c)`
-$a ! $b ! $c; # with a non-associative `!`, this is illegal
-$a ! $b ! $c; # with a chain-associative `!`, this is `($a ! $b) and ($b ! $c)`
-$a ! $b ! $c; # with a list-associative `!`, this is `infix:<>`
-
-# * Unary operators:
-!$a! # with left-associative `!`, this is `(!$a)!`
-!$a! # with right-associative `!`, this is `!($a!)`
-!$a! # with non-associative `!`, this is illegal
-
-## Create your own operators !
-# Okay, you've been reading all of that, so I guess I should try
-# to show you something exciting.
-# I'll tell you a little secret (or not-so-secret):
-# In Perl 6, all operators are actually just funny-looking subroutines.
-
-# You can declare an operator just like you declare a sub:
-sub prefix:<win>($winner) { # refer to the operator categories
- # (yes, it's the "words operator" `<>`)
- say "$winner Won !";
-}
-win "The King"; #=> The King Won !
- # (prefix is before)
-
-# you can still call the sub with its "full name"
-say prefix:<!>(True); #=> False
-
-sub postfix:<!>(Int $n) {
- [*] 2..$n; # using the reduce meta-operator ... See below ;-) !
-}
-say 5!; #=> 120
- # Postfix operators (after) have to come *directly* after the term.
- # No whitespace. You can use parentheses to disambiguate, i.e. `(5!)!`
-
-
-sub infix:<times>(Int $n, Block $r) { # infix in the middle
- for ^$n {
- $r(); # You need the explicit parentheses to call the function in `$r`,
- # else you'd be referring at the variable itself, like with `&r`.
- }
-}
-3 times -> { say "hello" }; #=> hello
- #=> hello
- #=> hello
- # You're very recommended to put spaces
- # around your infix operator calls.
-
-# For circumfix and post-circumfix ones
-sub circumfix:<[ ]>(Int $n) {
- $n ** $n
-}
-say [5]; #=> 3125
- # circumfix is around. Again, no whitespace.
-
-sub postcircumfix:<{ }>(Str $s, Int $idx) {
- # post-circumfix is
- # "after a term, around something"
- $s.substr($idx, 1);
-}
-say "abc"{1}; #=> b
- # after the term `"abc"`, and around the index (1)
-
-# This really means a lot -- because everything in Perl 6 uses this.
-# For example, to delete a key from a hash, you use the `:delete` adverb
-# (a simple named argument underneath):
-%h{$key}:delete;
-# equivalent to:
-postcircumfix:<{ }>(%h, $key, :delete); # (you can call operators like that)
-# It's *all* using the same building blocks!
-# Syntactic categories (prefix infix ...), named arguments (adverbs), ...,
-# - used to build the language - are available to you.
-
-# (you are, obviously, recommended against making an operator out of
-# *everything* -- with great power comes great responsibility)
-
-## Meta operators !
-# Oh boy, get ready. Get ready, because we're delving deep
-# into the rabbit's hole, and you probably won't want to go
-# back to other languages after reading that.
-# (I'm guessing you don't want to already at that point).
-# Meta-operators, as their name suggests, are *composed* operators.
-# Basically, they're operators that apply another operator.
-
-## * Reduce meta-operator
-# It's a prefix meta-operator that takes a binary function and
-# one or many lists. If it doesn't get passed any argument,
-# it either returns a "default value" for this operator
-# (a meaningless value) or `Any` if there's none (examples below).
-#
-# Otherwise, it pops an element from the list(s) one at a time, and applies
-# the binary function to the last result (or the list's first element)
-# and the popped element.
-#
-# To sum a list, you could use the reduce meta-operator with `+`, i.e.:
-say [+] 1, 2, 3; #=> 6
-# equivalent to `(1+2)+3`
-say [*] 1..5; #=> 120
-# equivalent to `((((1*2)*3)*4)*5)`.
-
-# You can reduce with any operator, not just with mathematical ones.
-# For example, you could reduce with `//` to get
-# the first defined element of a list:
-say [//] Nil, Any, False, 1, 5; #=> False
- # (Falsey, but still defined)
-
-
-# Default value examples:
-say [*] (); #=> 1
-say [+] (); #=> 0
- # meaningless values, since N*1=N and N+0=N.
-say [//]; #=> (Any)
- # There's no "default value" for `//`.
-
-# You can also call it with a function you made up, using double brackets:
-sub add($a, $b) { $a + $b }
-say [[&add]] 1, 2, 3; #=> 6
-
-## * Zip meta-operator
-# This one is an infix meta-operator than also can be used as a "normal"
-# operator. It takes an optional binary function (by default, it just creates
-# a pair), and will pop one value off of each array and call its binary function
-# on these until it runs out of elements. It returns an array with all of these
-# new elements.
-(1, 2) Z (3, 4); # ((1, 3), (2, 4)), since by default, the function makes an array
-1..3 Z+ 4..6; # (5, 7, 9), using the custom infix:<+> function
-
-# Since `Z` is list-associative (see the list above),
-# you can use it on more than one list
-(True, False) Z|| (False, False) Z|| (False, False); # (True, False)
-
-# And, as it turns out, you can also use the reduce meta-operator with it:
-[Z||] (True, False), (False, False), (False, False); # (True, False)
-
-
-## And to end the operator list:
-
-## * Sequence operator
-# The sequence operator is one of Perl 6's most powerful features:
-# it's composed of first, on the left, the list you want Perl 6 to deduce from
-# (and might include a closure), and on the right, a value or the predicate
-# that says when to stop (or Whatever for a lazy infinite list).
-my @list = 1, 2, 3 ... 10; # basic deducing
-#my @list = 1, 3, 6 ... 10; # this dies because Perl 6 can't figure out the end
-my @list = 1, 2, 3 ...^ 10; # as with ranges, you can exclude the last element
- # (the iteration when the predicate matches).
-my @list = 1, 3, 9 ... * > 30; # you can use a predicate
- # (with the Whatever Star, here).
-my @list = 1, 3, 9 ... { $_ > 30 }; # (equivalent to the above)
-
-my @fib = 1, 1, *+* ... *; # lazy infinite list of fibonacci series,
- # computed using a closure!
-my @fib = 1, 1, -> $a, $b { $a + $b } ... *; # (equivalent to the above)
-my @fib = 1, 1, { $^a + $^b } ... *; #(... also equivalent to the above)
-# $a and $b will always take the previous values, meaning here
-# they'll start with $a = 1 and $b = 1 (values we set by hand).
-# then $a = 1 and $b = 2 (result from previous $a+$b), and so on.
-
-say @fib[^10]; #=> 1 1 2 3 5 8 13 21 34 55
- # (using a range as the index)
-# Note : as for ranges, once reified, elements aren't re-calculated.
-# That's why `@primes[^100]` will take a long time the first time you print
-# it, then be instant.
-
-### Regular Expressions
-# I'm sure a lot of you have been waiting for this one.
-# Well, now that you know a good deal of Perl 6 already, we can get started.
-# First off, you'll have to forget about "PCRE regexps" (perl-compatible regexps).
-#
-# IMPORTANT: Don't skip them because you know PCRE. They're different.
-# Some things are the same (like `?`, `+`, and `*`),
-# but sometimes the semantics change (`|`).
-# Make sure you read carefully, because you might trip over a new behavior.
-#
-# Perl 6 has many features related to RegExps. After all, Rakudo parses itself.
-# We're first going to look at the syntax itself,
-# then talk about grammars (PEG-like), differences between
-# `token`, `regex` and `rule` declarators, and some more.
-# Side note: you still have access to PCRE regexps using the `:P5` modifier.
-# (we won't be discussing this in this tutorial, however)
-#
-# In essence, Perl 6 natively implements PEG ("Parsing Expression Grammars").
-# The pecking order for ambiguous parses is determined by a multi-level
-# tie-breaking test:
-# - Longest token matching. `foo\s+` beats `foo` (by 2 or more positions)
-# - Longest literal prefix. `food\w*` beats `foo\w*` (by 1)
-# - Declaration from most-derived to less derived grammars
-# (grammars are actually classes)
-# - Earliest declaration wins
-say so 'a' ~~ /a/; #=> True
-say so 'a' ~~ / a /; #=> True # More readable with some spaces!
-
-# In all our examples, we're going to use the smart-matching operator against
-# a regexp. We're converting the result using `so`, but in fact, it's
-# returning a `Match` object. They know how to respond to list indexing,
-# hash indexing, and return the matched string.
-# The results of the match are available as `$/` (implicitly lexically-scoped).
-# You can also use the capture variables which start at 0:
-# `$0`, `$1', `$2`...
-#
-# You can also note that `~~` does not perform start/end checking
-# (meaning the regexp can be matched with just one char of the string),
-# we're going to explain later how you can do it.
-
-# In Perl 6, you can have any alphanumeric as a literal,
-# everything else has to be escaped, using a backslash or quotes.
-say so 'a|b' ~~ / a '|' b /; # `True`. Wouldn't mean the same if `|` wasn't escaped
-say so 'a|b' ~~ / a \| b /; # `True`. Another way to escape it.
-
-# The whitespace in a regexp is actually not significant,
-# unless you use the `:s` (`:sigspace`, significant space) adverb.
-say so 'a b c' ~~ / a b c /; #> `False`. Space is not significant here
-say so 'a b c' ~~ /:s a b c /; #> `True`. We added the modifier `:s` here.
-# If we use only one space between strings in a regex, Perl 6 will warn us:
-say so 'a b c' ~~ / a b c /; #> 'False' #> Space is not significant here; please
-# use quotes or :s (:sigspace) modifier (or, to suppress this warning, omit the
-# space, or otherwise change the spacing)
-# To fix this and make the spaces less ambiguous, either use at least two
-# spaces between strings or use the `:s` adverb.
-
-# As we saw before, we can embed the `:s` inside the slash delimiters, but we can
-# also put it outside of them if we specify `m` for 'match':
-say so 'a b c' ~~ m:s/a b c/; #> `True`
-# By using `m` to specify 'match' we can also use delimiters other than slashes:
-say so 'abc' ~~ m{a b c}; #> `True`
-# Use the :i adverb to specify case insensitivity:
-say so 'ABC' ~~ m:i{a b c}; #> `True`
-# It is, however, important as for how modifiers (that you're gonna see just below)
-# are applied ...
-
-## Quantifying - `?`, `+`, `*` and `**`.
-# - `?` - 0 or 1
-so 'ac' ~~ / a b c /; # `False`
-so 'ac' ~~ / a b? c /; # `True`, the "b" matched 0 times.
-so 'abc' ~~ / a b? c /; # `True`, the "b" matched 1 time.
-
-# ... As you read just before, whitespace is important because it determines
-# which part of the regexp is the target of the modifier:
-so 'def' ~~ / a b c? /; # `False`. Only the `c` is optional
-so 'def' ~~ / a b? c /; # `False`. Whitespace is not significant
-so 'def' ~~ / 'abc'? /; # `True`. The whole "abc" group is optional.
-
-# Here (and below) the quantifier applies only to the `b`
-
-# - `+` - 1 or more
-so 'ac' ~~ / a b+ c /; # `False`; `+` wants at least one matching
-so 'abc' ~~ / a b+ c /; # `True`; one is enough
-so 'abbbbc' ~~ / a b+ c /; # `True`, matched 4 "b"s
-
-# - `*` - 0 or more
-so 'ac' ~~ / a b* c /; # `True`, they're all optional.
-so 'abc' ~~ / a b* c /; # `True`
-so 'abbbbc' ~~ / a b* c /; # `True`
-so 'aec' ~~ / a b* c /; # `False`. "b"(s) are optional, not replaceable.
-
-# - `**` - (Unbound) Quantifier
-# If you squint hard enough, you might understand
-# why exponentation is used for quantity.
-so 'abc' ~~ / a b**1 c /; # `True` (exactly one time)
-so 'abc' ~~ / a b**1..3 c /; # `True` (one to three times)
-so 'abbbc' ~~ / a b**1..3 c /; # `True`
-so 'abbbbbbc' ~~ / a b**1..3 c /; # `False` (too much)
-so 'abbbbbbc' ~~ / a b**3..* c /; # `True` (infinite ranges are okay)
-
-# - `<[]>` - Character classes
-# Character classes are the equivalent of PCRE's `[]` classes, but
-# they use a more perl6-ish syntax:
-say 'fooa' ~~ / f <[ o a ]>+ /; #=> 'fooa'
-# You can use ranges:
-say 'aeiou' ~~ / a <[ e..w ]> /; #=> 'ae'
-# Just like in normal regexes, if you want to use a special character, escape it
-# (the last one is escaping a space)
-say 'he-he !' ~~ / 'he-' <[ a..z \! \ ]> + /; #=> 'he-he !'
-# You'll get a warning if you put duplicate names
-# (which has the nice effect of catching the wrote quoting:)
-'he he' ~~ / <[ h e ' ' ]> /; # Warns "Repeated characters found in characters class"
-
-# You can also negate them ... (equivalent to `[^]` in PCRE)
-so 'foo' ~~ / <-[ f o ]> + /; # False
-
-# ... and compose them: :
-so 'foo' ~~ / <[ a..z ] - [ f o ]> + /; # False (any letter except f and o)
-so 'foo' ~~ / <-[ a..z ] + [ f o ]> + /; # True (no letter except f and o)
-so 'foo!' ~~ / <-[ a..z ] + [ f o ]> + /; # True (the + doesn't replace the left part)
-
-## Grouping and capturing
-# Group: you can group parts of your regexp with `[]`.
-# These groups are *not* captured (like PCRE's `(?:)`).
-so 'abc' ~~ / a [ b ] c /; # `True`. The grouping does pretty much nothing
-so 'foo012012bar' ~~ / foo [ '01' <[0..9]> ] + bar /;
-# The previous line returns `True`.
-# We match the "012" 1 or more time (the `+` was applied to the group).
-
-# But this does not go far enough, because we can't actually get back what
-# we matched.
-# Capture: We can actually *capture* the results of the regexp, using parentheses.
-so 'fooABCABCbar' ~~ / foo ( 'A' <[A..Z]> 'C' ) + bar /; # `True`. (using `so` here, `$/` below)
-
-# So, starting with the grouping explanations.
-# As we said before, our `Match` object is available as `$/`:
-say $/; # Will print some weird stuff (we'll explain) (or "Nil" if nothing matched).
-
-# As we also said before, it has array indexing:
-say $/[0]; #=> 「ABC」 「ABC」
- # These weird brackets are `Match` objects.
- # Here, we have an array of these.
-say $0; # The same as above.
-
-# Our capture is `$0` because it's the first and only one capture in the regexp.
-# You might be wondering why it's an array, and the answer is simple:
-# Some capture (indexed using `$0`, `$/[0]` or a named one) will be an array
-# IFF it can have more than one element
-# (so, with `*`, `+` and `**` (whatever the operands), but not with `?`).
-# Let's use examples to see that:
-so 'fooABCbar' ~~ / foo ( A B C )? bar /; # `True`
-say $/[0]; #=> 「ABC」
-say $0.WHAT; #=> (Match)
- # It can't be more than one, so it's only a single match object.
-so 'foobar' ~~ / foo ( A B C )? bar /; #=> True
-say $0.WHAT; #=> (Any)
- # This capture did not match, so it's empty
-so 'foobar' ~~ / foo ( A B C ) ** 0..1 bar /; # `True`
-say $0.WHAT; #=> (Array)
- # A specific quantifier will always capture an Array,
- # may it be a range or a specific value (even 1).
-
-# The captures are indexed per nesting. This means a group in a group will be nested
-# under its parent group: `$/[0][0]`, for this code:
-'hello-~-world' ~~ / ( 'hello' ( <[ \- \~ ]> + ) ) 'world' /;
-say $/[0].Str; #=> hello~
-say $/[0][0].Str; #=> ~
-
-# This stems from a very simple fact: `$/` does not contain strings, integers or arrays,
-# it only contains match objects. These contain the `.list`, `.hash` and `.Str` methods.
-# (but you can also just use `match<key>` for hash access
-# and `match[idx]` for array access)
-say $/[0].list.perl; #=> (Match.new(...),).list
- # We can see it's a list of Match objects. Those contain
- # a bunch of infos: where the match started/ended,
- # the "ast" (see actions later), etc.
- # You'll see named capture below with grammars.
-
-## Alternatives - the `or` of regexps
-# WARNING: They are DIFFERENT from PCRE regexps.
-so 'abc' ~~ / a [ b | y ] c /; # `True`. Either "b" or "y".
-so 'ayc' ~~ / a [ b | y ] c /; # `True`. Obviously enough ...
-
-# The difference between this `|` and the one you're used to is LTM.
-# LTM means "Longest Token Matching". This means that the engine will always
-# try to match as much as possible in the strng
-'foo' ~~ / fo | foo /; # `foo`, because it's longer.
-# To decide which part is the "longest", it first splits the regex in two parts:
-# The "declarative prefix" (the part that can be statically analyzed)
-# and the procedural parts.
-# Declarative prefixes include alternations (`|`), conjuctions (`&`),
-# sub-rule calls (not yet introduced), literals, characters classes and quantifiers.
-# The latter include everything else: back-references, code assertions,
-# and other things that can't traditionnaly be represented by normal regexps.
-#
-# Then, all the alternatives are tried at once, and the longest wins.
-# Exemples:
-# DECLARATIVE | PROCEDURAL
-/ 'foo' \d+ [ <subrule1> || <subrule2> ] /;
-# DECLARATIVE (nested groups are not a problem)
-/ \s* [ \w & b ] [ c | d ] /;
-# However, closures and recursion (of named regexps) are procedural.
-# ... There are also more complicated rules, like specificity
-# (literals win over character classes)
-
-# Note: the first-matching `or` still exists, but is now spelled `||`
-'foo' ~~ / fo || foo /; # `fo` now.
-
-
-
-
-### Extra: the MAIN subroutine
-# The `MAIN` subroutine is called when you run a Perl 6 file directly.
-# It's very powerful, because Perl 6 actually parses the arguments
-# and pass them as such to the sub. It also handles named argument (`--foo`)
-# and will even go as far as to autogenerate a `--help`
-sub MAIN($name) { say "Hello, $name !" }
-# This produces:
-# $ perl6 cli.pl
-# Usage:
-# t.pl <name>
-
-# And since it's a regular Perl 6 sub, you can haz multi-dispatch:
-# (using a "Bool" for the named argument so that we can do `--replace`
-# instead of `--replace=1`)
-subset File of Str where *.IO.d; # convert to IO object to check the file exists
-
-multi MAIN('add', $key, $value, Bool :$replace) { ... }
-multi MAIN('remove', $key) { ... }
-multi MAIN('import', File, Str :$as) { ... } # omitting parameter name
-# This produces:
-# $ perl6 cli.pl
-# Usage:
-# t.pl [--replace] add <key> <value>
-# t.pl remove <key>
-# t.pl [--as=<Str>] import (File)
-# As you can see, this is *very* powerful.
-# It even went as far as to show inline the constants.
-# (the type is only displayed if the argument is `$`/is named)
-
-###
-### APPENDIX A:
-###
-### List of things
-###
-
-# It's considered by now you know the Perl6 basics.
-# This section is just here to list some common operations,
-# but which are not in the "main part" of the tutorial to bloat it up
-
-## Operators
-
-
-## * Sort comparison
-# They return one value of the `Order` enum : `Less`, `Same` and `More`
-# (which numerify to -1, 0 or +1).
-1 <=> 4; # sort comparison for numerics
-'a' leg 'b'; # sort comparison for string
-$obj eqv $obj2; # sort comparison using eqv semantics
-
-## * Generic ordering
-3 before 4; # True
-'b' after 'a'; # True
-
-## * Short-circuit default operator
-# Like `or` and `||`, but instead returns the first *defined* value :
-say Any // Nil // 0 // 5; #=> 0
-
-## * Short-circuit exclusive or (XOR)
-# Returns `True` if one (and only one) of its arguments is true
-say True ^^ False; #=> True
-## * Flip Flop
-# The flip flop operators (`ff` and `fff`, equivalent to P5's `..`/`...`).
-# are operators that take two predicates to test:
-# They are `False` until their left side returns `True`, then are `True` until
-# their right side returns `True`.
-# Like for ranges, you can exclude the iteration when it became `True`/`False`
-# by using `^` on either side.
-# Let's start with an example :
-for <well met young hero we shall meet later> {
- # by default, `ff`/`fff` smart-match (`~~`) against `$_`:
- if 'met' ^ff 'meet' { # Won't enter the if for "met"
- # (explained in details below).
- .say
- }
-
- if rand == 0 ff rand == 1 { # compare variables other than `$_`
- say "This ... probably will never run ...";
- }
-}
-# This will print "young hero we shall meet" (excluding "met"):
-# the flip-flop will start returning `True` when it first encounters "met"
-# (but will still return `False` for "met" itself, due to the leading `^`
-# on `ff`), until it sees "meet", which is when it'll start returning `False`.
-
-# The difference between `ff` (awk-style) and `fff` (sed-style) is that
-# `ff` will test its right side right when its left side changes to `True`,
-# and can get back to `False` right away
-# (*except* it'll be `True` for the iteration that matched) -
-# While `fff` will wait for the next iteration to
-# try its right side, once its left side changed:
-.say if 'B' ff 'B' for <A B C B A>; #=> B B
- # because the right-hand-side was tested
- # directly (and returned `True`).
- # "B"s are printed since it matched that time
- # (it just went back to `False` right away).
-.say if 'B' fff 'B' for <A B C B A>; #=> B C B
- # The right-hand-side wasn't tested until
- # `$_` became "C"
- # (and thus did not match instantly).
-
-# A flip-flop can change state as many times as needed:
-for <test start print it stop not printing start print again stop not anymore> {
- .say if $_ eq 'start' ^ff^ $_ eq 'stop'; # exclude both "start" and "stop",
- #=> "print it print again"
-}
-
-# you might also use a Whatever Star,
-# which is equivalent to `True` for the left side or `False` for the right:
-for (1, 3, 60, 3, 40, 60) { # Note: the parenthesis are superfluous here
- # (sometimes called "superstitious parentheses")
- .say if $_ > 50 ff *; # Once the flip-flop reaches a number greater than 50,
- # it'll never go back to `False`
- #=> 60 3 40 60
-}
-
-# You can also use this property to create an `If`
-# that'll not go through the first time :
-for <a b c> {
- .say if * ^ff *; # the flip-flop is `True` and never goes back to `False`,
- # but the `^` makes it *not run* on the first iteration
- #=> b c
-}
-
-
-# - `===` is value identity and uses `.WHICH` on the objects to compare them
-# - `=:=` is container identity and uses `VAR()` on the objects to compare them
-
-```
-
-If you want to go further, you can:
-
- - Read the [Perl 6 Docs](https://docs.perl6.org/). This is a great
- resource on Perl6. If you are looking for something, use the search bar.
- This will give you a dropdown menu of all the pages referencing your search
- term (Much better than using Google to find Perl 6 documents!)
- - Read the [Perl 6 Advent Calendar](http://perl6advent.wordpress.com/). This
- is a great source of Perl 6 snippets and explainations. If the docs don't
- describe something well enough, you may find more detailed information here.
- This information may be a bit older but there are many great examples and
- explainations. Posts stopped at the end of 2015 when the language was declared
- stable and Perl 6.c was released.
- - Come along on `#perl6` at `irc.freenode.net`. The folks here are always helpful.
- - Check the [source of Perl 6's functions and classes](https://github.com/rakudo/rakudo/tree/nom/src/core). Rakudo is mainly written in Perl 6 (with a lot of NQP, "Not Quite Perl", a Perl 6 subset easier to implement and optimize).
- - Read [the language design documents](http://design.perl6.org). They explain P6 from an implementor point-of-view, but it's still very interesting.
-
- [//]: # ( vim: set filetype=perl softtabstop=2 shiftwidth=2 expandtab cc=80 : )
diff --git a/php.html.markdown b/php.html.markdown
index 82d27546..57ba29c4 100644
--- a/php.html.markdown
+++ b/php.html.markdown
@@ -34,6 +34,7 @@ echo "World\n"; // Prints "World" with a line break
?>
Hello World Again!
<?php
+// That is because historically PHP started as a Template engine
/************************************
@@ -41,12 +42,15 @@ Hello World Again!
*/
// Variables begin with the $ symbol.
-// A valid variable name starts with a letter or underscore,
+// A valid variable name starts with a letter or an underscore,
// followed by any number of letters, numbers, or underscores.
+// You don't have to (and cannot) declare variables.
+// Once you assign a value, PHP will create the variable with the right type.
+
// Boolean values are case-insensitive
$boolean = true; // or TRUE or True
-$boolean = false; // or FALSE or False
+$boolean = FALSE; // or false or False
// Integers
$int1 = 12; // => 12
@@ -122,9 +126,9 @@ echo 'Multiple', 'Parameters', 'Valid'; // Returns 'MultipleParametersValid'
// followed by any number of letters, numbers, or underscores.
define("FOO", "something");
-// access to a constant is possible by calling the choosen name without a $
+// access to a constant is possible by calling the chosen name without a $
echo FOO; // Returns 'something'
-echo 'This outputs ' . FOO; // Returns 'This ouputs something'
+echo 'This outputs ' . FOO; // Returns 'This outputs something'
@@ -132,9 +136,7 @@ echo 'This outputs ' . FOO; // Returns 'This ouputs something'
* Arrays
*/
-// All arrays in PHP are associative arrays (hashmaps),
-
-// Associative arrays, known as hashmaps in some languages.
+// All arrays in PHP are associative arrays (hashmaps in some languages)
// Works with all PHP versions
$associative = array('One' => 1, 'Two' => 2, 'Three' => 3);
@@ -291,7 +293,7 @@ if (false) {
print (false ? 'Does not get printed' : 'Does');
// ternary shortcut operator since PHP 5.3
-// equivalent of "$x ? $x : 'Does'""
+// equivalent of "$x ? $x : 'Does'"
$x = false;
print($x ?: 'Does');
@@ -342,7 +344,7 @@ switch ($x) {
$i = 0;
while ($i < 5) {
echo $i++;
-}; // Prints "01234"
+} // Prints "01234"
echo "\n";
@@ -445,7 +447,7 @@ echo $function_name(1, 2); // => 3
// Or, use call_user_func(callable $callback [, $parameter [, ... ]]);
-// You can get the all the parameters passed to a function
+// You can get all the parameters passed to a function
function parameters() {
$numargs = func_num_args();
if ($numargs > 0) {
@@ -467,7 +469,7 @@ function variable($word, ...$list) {
}
}
-variable("Separate", "Hello", "World") // Separate || Hello | World |
+variable("Separate", "Hello", "World"); // Separate || Hello | World |
/********************************
* Includes
@@ -796,7 +798,7 @@ But I'm ChildClass
/**********************
* Magic constants
-*
+*
*/
// Get current class name. Must be used inside a class declaration.
@@ -824,11 +826,11 @@ 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
-*
+*
*/
// Simple error handling can be done with try catch block
@@ -839,7 +841,10 @@ try {
// Handle exception
}
-// When using try catch blocks in a namespaced enviroment use the following
+// When using try catch blocks in a namespaced environment it is important to
+// escape to the global namespace, because Exceptions are classes, and the
+// Exception class exists in the global namespace. This can be done using a
+// leading backslash to catch the Exception.
try {
// Do something
@@ -856,7 +861,7 @@ try {
$condition = true;
if ($condition) {
- throw new MyException('Something just happend');
+ throw new MyException('Something just happened');
}
} catch (MyException $e) {
@@ -873,6 +878,9 @@ and community input.
If you're interested in up-to-date best practices, visit
[PHP The Right Way](http://www.phptherightway.com/).
+A tutorial covering basics of language, setting up coding environment and making
+few practical projects at [Codecourse - PHP Basics](https://www.youtube.com/playlist?list=PLfdtiltiRHWHjTPiFDRdTOPtSyYfz3iLW).
+
If you're coming from a language with good package management, check out
[Composer](http://getcomposer.org/).
diff --git a/pl-pl/bf-pl.html.markdown b/pl-pl/bf-pl.html.markdown
index 801f1a9a..09c85362 100644
--- a/pl-pl/bf-pl.html.markdown
+++ b/pl-pl/bf-pl.html.markdown
@@ -1,11 +1,15 @@
---
+category: language
language: bf
+filename: learnbf-pl.bf
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
translators:
- ["Jakub Młokosiewicz", "https://github.com/hckr"]
+ - ["Mateusz Burniak", "https://github.com/matbur"]
lang: pl-pl
+
---
Brainfuck (pisane małymi literami, za wyjątkiem początku zdania) jest bardzo
@@ -29,9 +33,9 @@ Oto osiem poleceń brainfucka:
. : wyświetla wartość bieżącej komórki (w formie znaku ASCII, np. 65 = 'A')
, : wczytuje (jeden) znak z wejścia do bieżącej komórki
(konkretnie jego numer z tabeli ASCII)
-[ : jeśli wartość w bieżącej komórce jest rózna zero, przechodzi do
+[ : jeśli wartość w bieżącej komórce jest równa zeru, przechodzi do
odpowiadającego ]; w przeciwnym wypdaku przechodzi do następnej instrukcji
-] : Jeśli wartość w bieżącej komórce jest rózna od zera, przechodzi do
+] : Jeśli wartość w bieżącej komórce jest równa zeru, przechodzi do
następnej instrukcji; w przeciwnym wypdaku przechodzi do odpowiadającego [
[ i ] oznaczają pętlę while. Oczywiście każda pętla rozpoczęta [
diff --git a/pl-pl/haskell-pl.html.markdown b/pl-pl/haskell-pl.html.markdown
new file mode 100644
index 00000000..236b8958
--- /dev/null
+++ b/pl-pl/haskell-pl.html.markdown
@@ -0,0 +1,449 @@
+---
+category: language
+filename: haskell-pl.hs
+language: Haskell
+contributors:
+ - ["Adit Bhargava", "http://adit.io"]
+translators:
+ - ["Remigiusz Suwalski", "https://github.com/remigiusz-suwalski"]
+lang: pl-pl
+
+---
+
+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'
+
+----------------------------------------------------
+-- 2. 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/pl-pl/java-pl.html.markdown b/pl-pl/java-pl.html.markdown
new file mode 100644
index 00000000..0da449c5
--- /dev/null
+++ b/pl-pl/java-pl.html.markdown
@@ -0,0 +1,1026 @@
+---
+language: java
+filename: LearnJavaPl.java
+contributors:
+ - ["Jake Prather", "https://github.com/JakeHP"]
+ - ["Jakukyo Friel", "https://weakish.github.io"]
+ - ["Madison Dickson", "https://github.com/mix3d"]
+ - ["Simon Morgan", "https://sjm.io/"]
+ - ["Zachary Ferguson", "https://github.com/zfergus2"]
+ - ["Cameron Schermerhorn", "https://github.com/cschermerhorn"]
+ - ["Rachel Stiyer", "https://github.com/rstiyer"]
+ - ["Michael Dähnert", "https://github.com/JaXt0r"]
+ - ["Rob Rose", "https://github.com/RobRoseKnows"]
+ - ["Sean Nam", "https://github.com/seannam"]
+ - ["Shawn M. Hanes", "https://github.com/smhanes15"]
+filename: LearnJava.java
+translators:
+ - ["Jacek Wachowiak", "https://github.com/jacekwachowiak"]
+lang: pl-pl
+---
+
+Java jest współbieżnym, opartym na klasach, obiektowym językiem programowania
+ogólnego zastosowania.
+[Tu znajdziesz więcej informacji po angielsku.]
+(https://docs.oracle.com/javase/tutorial/java/)
+
+```java
+// Pojedyncze komentarze oznaczamy //
+
+/*
+Komentarze wieloliniowe wyglądają tak
+*/
+
+/**
+ * Komentarze JavaDoc wygladają w ten sposób. Używane są do opisu klas lub
+ * różnych właściwości klas.
+ * Główne właściwości:
+ *
+ * @author Imię i nazwisko (i kontakt np. email) autora.
+ * @version Aktualna wersja programu.
+ * @since Kiedy ta część programu została dodana.
+ * @param Służy do opisu parametrów metody.
+ * @return Służy do opisu zwracanej wartości.
+ * @deprecated Służy do oznaczenia nieaktualnego lub niezalecanego kodu.
+ * @see Linki do innej cześci dokumentacji.
+*/
+
+// Import klasy ArrayList z paczki java.util
+import java.util.ArrayList;
+// Import wszystkich klas z paczki java.security
+import java.security.*;
+
+public class LearnJava {
+
+ // Aby móc uruchomić program w języku java musi on mieć główną metodę jako
+ // punkt wejścia.
+ public static void main(String[] args) {
+
+ ///////////////////////////////////////
+ // Operacje wejścia/wyjścia (input/output)
+ ///////////////////////////////////////
+
+ /*
+ * Wyjście
+ */
+
+ // System.out.println() służy do wyświetlania linii tekstu.
+ System.out.println("Hello World!");
+ System.out.println(
+ "Integer: " + 10 +
+ " Double: " + 3.14 +
+ " Boolean: " + true);
+
+ // Aby wyświetlić bez nowej linii użyj System.out.print().
+ System.out.print("Hello ");
+ System.out.print("World");
+
+ // System.out.printf() służy do łatwego formatowania wyświetlanego elementu.
+ System.out.printf("pi = %.5f", Math.PI); // => pi = 3.14159
+
+ /*
+ * Wejście
+ */
+
+ // Scanner służy do wczytywania danych
+ // niezbędny jest import java.util.Scanner;
+ Scanner scanner = new Scanner(System.in);
+
+ // zczytaj string (tekst)
+ String name = scanner.next();
+
+ // zczytaj zmienną typu bajt
+ byte numByte = scanner.nextByte();
+
+ // zczytaj zmienną typu integer - liczba całkowita
+ int numInt = scanner.nextInt();
+
+ // zczytaj zmienną typu float - liczba zmiennoprzecinkowa
+ float numFloat = scanner.nextFloat();
+
+ // zczytaj zmienna typu double -liczba zmiennoprzecinkowa
+ double numDouble = scanner.nextDouble();
+
+ // zczytaj zmienną typu boolowskiego -
+ boolean bool = scanner.nextBoolean();
+
+ ///////////////////////////////////////
+ // Zmienne
+ ///////////////////////////////////////
+
+ /*
+ * Deklaracja zmiennych
+ */
+ // Zmienną deklaruje się poprzez <rodzaj> <nazwa>
+ int fooInt;
+ // Dozwolona jest deklaracja wielu zmiennych tego samego typu na raz
+ // rodzaj <nazwa1>, <nazwa2>, <nazwa3>
+ int fooInt1, fooInt2, fooInt3;
+
+ /*
+ * Inicjalizacja zmiennych
+ */
+
+ // Zmienną inicjalizuje się poprzez <rodzaj> <nazwa> = <wartość>
+ int barInt = 1;
+ // Możliwe jest zainicjalizowanie wielu zmiennych tego samego typu tą samą wartością
+ // rodzaj <nazwa1>, <nazwa2>, <nazwa3>
+ // <nazwa1> = <nazwa2> = <nazwa3> = <wartość>
+ int barInt1, barInt2, barInt3;
+ barInt1 = barInt2 = barInt3 = 1;
+
+ /*
+ * Rodzaje zmiennych
+ */
+ // Bajt - 8-bitowa, zawierająca ujemne wartości zmienna w dwójkowym
+ // systemie pozycyjnym
+ // (-128 <= byte <= 127)
+ byte fooByte = 100;
+
+ // Jeśli chcemy zinterpretować bajt jako zmienną typu unsigned integer
+ // - liczbę całkowitą z wartościami ujemnymi ta operacja może pomóc:
+ int unsignedIntLessThan256 = 0xff & fooByte;
+ // jako kontrast operacja zmiany typu która może zwrócić wartość ujemną.
+ int signedInt = (int) fooByte;
+
+ // Short - 16-bitowa, zawierająca ujemne wartości zmienna w dwójkowym
+ // systemie pozycyjnym (-32,768 <= short <= 32,767)
+ short fooShort = 10000;
+
+ // Integer - 32-bitowa, zawierająca ujemne wartości zmienna w dwójkowym systemie pozycyjnym
+ // (-2,147,483,648 <= int <= 2,147,483,647)
+ int bazInt = 1;
+
+ // Long - 64-bitowa, zawierająca ujemne wartości zmienna w dwójkowym
+ // systemie pozycyjnym
+ // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
+ long fooLong = 100000L;
+ // L jest używane do zaznaczenia, że wartość zmiennej jest typu Long;
+ // bez L wszystko inne będzie traktowane z założenia jako integer.
+
+ // Uwaga: byte, short, int and long zawierają ujemne wartości.
+ // Nie istnieją odpowiedniki z jedynie pozytywnymi wartościami.
+ // Jedynie char jest 16-bitowym typem zmiennej, który akceptuje tylko
+ // wartości nieujemne.
+
+ // Float - 32-bitowy typ zmiennoprzecinkowy zgodnie z IEEE 754
+ // Floating Point 2^-149 <= float <= (2-2^-23) * 2^127
+ float fooFloat = 234.5f;
+ // f or F jest używane aby zaznaczyć, że dana zmienna jest typu float;
+ // w przeciwnym razie będzie ona traktowana jako double.
+
+ // Double - 64-bitowy typ zmiennoprzecinkowy zgodnie z IEEE 754
+ // Floating Point 2^-1074 <= x <= (2-2^-52) * 2^1023
+ double fooDouble = 123.4;
+
+ // Typ boolowski - true/prawda & false/fałsz
+ boolean fooBoolean = true;
+ boolean barBoolean = false;
+
+ // Char - pojedynczy 16-bitowy symbol Unicode
+ char fooChar = 'A';
+
+ // zmienne zadeklarowane z użyciem final nie mogą być edytowane,
+ final int HOURS_I_WORK_PER_WEEK = 9001;
+ // ale możliwa jest późniejsza inicjalizacja.
+ final double E;
+ E = 2.71828;
+
+ // BigInteger - Nieedytowalny typ zmiennej o nieograniczonej długości
+ // dla liczb całkowitych
+ //
+ // BigInteger jest typem zmiennej, który pozwala na operacje na liczbach całkowitych dłuższych niż 64 bity.
+ // Liczby są przechowywane jako tablica bajtów
+ // i modyfikowane za pomocą funkcji wbudowanych w BigInteger
+ //
+ // BigInteger może być zainicjalizowany za pomocą tablicy bajtów lub jako string.
+ BigInteger fooBigInteger = new BigInteger(fooByteArray);
+
+ // BigDecimal - Nieedytowalny typ zmiennej o nieograniczonej długości dla
+ // liczb zmiennoprzecinkowych
+ //
+ // BigDecimal zaiwera 2 części: typ integer o arbitralnej precyzji bez skalowania
+ // oraz 32-bitową skalę
+ //
+ // BigDecimal pozwala programiście na całkowitą kontrolę zaokrąglenia dziesiętnego.
+ // Zalecane jest używanie BigDecimal z wartościami walut.
+ // oraz tam, gdzie absolutna dokładność jest niezbędna.
+ //
+ // BigDecimal można zainicjalizowac używając int, long, double or String
+ // a także inicjalizując nieprzeskalowaną wartość (BigInteger) i skalę (int).
+ BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt);
+
+ // Uwaga na konstruktor, który przyjmuje float lub double jako, że
+ // niedokładność float/double będzie przeniesiona do BigDecimal.
+ // Zalecane jest uzywanie konstruktora typu String gdy konieczne jest
+ // uzyskanie absolutnej precyzji.
+ BigDecimal tenCents = new BigDecimal("0.1");
+
+ // String - zmienna tekstowa
+ String fooString = "Tutaj jest mój string!";
+
+ // \n jest symbolem karetki, która rozpoczyna nową linę
+ String barString = "Wyświetlanie w nowej linii?\nNie ma problemu!";
+ // \t jest symbolem tabulatora, który dodaje odstęp.
+ String bazString = "Chesz dodać tabulator?\tBez problemu!";
+ System.out.println(fooString);
+ System.out.println(barString);
+ System.out.println(bazString);
+
+ // Budowanie Stringów
+ // #1 - za pomocą operatora dodawania
+ // To jest podstawowy sposób (zoptymalizowany)
+ String plusConcatenated = "Stringi mogą " + "być łączone " + "operatorem +.";
+ System.out.println(plusConcatenated);
+ // Wyjście: Stringi będą połączone operatorem +.
+
+ // #2 - za pomocą StringBuilder
+ // Ten sposób nie tworzy żadnych pośrednich stringów, jedynie zachowuje
+ // części i wiąże je po kolei gdy wywołane jest toString().
+ // Wskazówka: Ta klasa nie jest bezpieczna z punktu widzenia wątków.
+ // Bezpieczną alternatywą jest (wiążąca się ze spadkiem wydajności)
+ // StringBuffer.
+ StringBuilder builderConcatenated = new StringBuilder();
+ builderConcatenated.append("Możesz ");
+ builderConcatenated.append("użyć ");
+ builderConcatenated.append("klasy StringBuilder.");
+ System.out.println(builderConcatenated.toString()); // dopiero tutaj
+ //budowany jest string
+ // Wyjście: Używany jest StringBuilder.
+
+ // StringBuilder jest wydajny, gdy połączony string nie jest używany aż do końcowego przetworzenia.
+ StringBuilder stringBuilder = new StringBuilder();
+ String inefficientString = "";
+ for (int i = 0 ; i < 10; i++) {
+ stringBuilder.append(i).append(" ");
+ inefficientString += i + " ";
+ }
+ System.out.println(inefficientString);
+ System.out.println(stringBuilder.toString());
+ // inefficientString wymaga dużo więcej pracy przy stworzeniu ponieważ
+ // tworzy string przy każdej iteracji.
+ // Proste łączenie za pomocą + jest kompilowane do StringBuilder i
+ // toString(). Unikaj łączenia stringów w pętlach.
+
+ // #3 - za pomocą String formatter
+ // Inna możliwość, szybka i czytelna.
+ String.format("%s wolisz %s.", "A może", "String.format()");
+ // Wyjście: Być może wolisz String.format().
+
+ // Tablice
+ // Rozmiar tablicy musi być określony przy stworzeniu.
+ // Podane poniżej sposoby są dozwolone prz deklaracji tablicy
+ // <rodzaj>[] <nazwa> = new <rodzaj>[<rozmiar>];
+ // <rodzaj> <nazwa>[] = new <rodzaj>[<rozmiar>];
+ int[] intArray = new int[10];
+ String[] stringArray = new String[1];
+ boolean boolArray[] = new boolean[100];
+
+ // Inny sposób deklaracji i inicjalizacji tablicy
+ int[] y = {9000, 1000, 1337};
+ String names[] = {"Bob", "John", "Fred", "Juan Pedro"};
+ boolean bools[] = {true, false, false};
+
+ // Indeksowanie tablicy - dostęp do elementów
+ System.out.println("intArray @ 0: " + intArray[0]);
+
+ // Tablice zaczynają się z indeksem 0 i są edytowalne.
+ intArray[1] = 1;
+ System.out.println("intArray @ 1: " + intArray[1]); // => 1
+
+ // Inny typ zmiennej, z którymi warto się zapoznać
+ // ArrayLists - Tablice z większą funkcjonalnością
+ // i zmiennym rozmiarem.
+ // LinkedLists - Dwustronnie połączone listy. Wszystkie operacje
+ // na listach zaimpllementowane.
+ // Maps - Mapy zawierające klucz i wartość. Mapa jest interfejsem
+ // i nie może zostać zainicjalizowana.
+ // Rodzaj klucza i wartości dla mapy musi zostać określony
+ // przy inicjalizacji implementującej mapę klasy
+ // Każdy klucz przypisany jest do tylko jednej wartości,
+ // każdy klucz może wystąpić tylko raz (brak duplikatów).
+ // HashMaps - Używa tablicy hashów do implementacji interfejsu mapy
+ // Pozwala to na użycie podstawowych operacji, jak
+ // get i insert, które pozostają niezmiennie wydajne
+ // czasowo nawet dla dużych zestawów danych
+ // TreeMap - Mapa posortowana przez klucze. Każda modyfikacja
+ // utrzymuje sortowanie, zdefiniowane przez komparator
+ // dodany przy inicjalizacji lub porównanie każdego obiektu
+ // jeśli zaimplementowany jest interfejs Comparable.
+ // Niepowodzenie kluczy wimplemntacji Comparable połączone
+ // z niepowodzeniem dostarczenia komparatora spowoduje
+ // ClassCastExceptions.
+ // Dodawanie i usuwanie kosztuje O(log(n)) czasu,
+ // zalecane jest nieużywanie tego typu jeżeli sortowanie
+ // nie jest przydatne.
+
+ ///////////////////////////////////////
+ // Operatory
+ ///////////////////////////////////////
+ System.out.println("\n->Operatory");
+
+ int i1 = 1, i2 = 2; // Skrót dla wielokrotnych deklaracji
+
+ // Arytmetyka jest prosta
+ System.out.println("1+2 = " + (i1 + i2)); // => 3
+ System.out.println("2-1 = " + (i2 - i1)); // => 1
+ System.out.println("2*1 = " + (i2 * i1)); // => 2
+ System.out.println("1/2 = " + (i1 / i2)); // => 0 (int/int zwraca int)
+ System.out.println("1/2.0 = " + (i1 / (double)i2)); // => 0.5
+
+ // Modulo
+ System.out.println("11%3 = "+(11 % 3)); // => 2
+
+ // Porównania
+ System.out.println("3 == 2? " + (3 == 2)); // => false
+ System.out.println("3 != 2? " + (3 != 2)); // => true
+ System.out.println("3 > 2? " + (3 > 2)); // => true
+ System.out.println("3 < 2? " + (3 < 2)); // => false
+ System.out.println("2 <= 2? " + (2 <= 2)); // => true
+ System.out.println("2 >= 2? " + (2 >= 2)); // => true
+
+ // Operacje boolowskie
+ System.out.println("3 > 2 && 2 > 3? " + ((3 > 2) && (2 > 3))); // => false
+ System.out.println("3 > 2 || 2 > 3? " + ((3 > 2) || (2 > 3))); // => true
+ System.out.println("!(3 == 2)? " + (!(3 == 2))); // => true
+
+ // Operacje na bitach!
+ /*
+ ~ Odwrócenie bitów
+ << Przesunięcie w lewo
+ >> Przesunięcie w prawo, arytmetyczne/dla wartości ujemnych -signed
+ >>> Przesunięcie w prawo, logiczne/dla wartości dodatnich - unsigned
+ & Bitowe AND
+ ^ Bitowe XOR
+ | Bitowe OR
+ */
+
+ // Operatory inkrementacji
+ int i = 0;
+ System.out.println("\n->In/De-krementacja");
+ // Operatory ++ i -- zwiększają lub zmniejszają o 1 daną wartość.
+ // Jeżeli używane są przed zmienną, wykonywane są przed powrotem zmiennej.
+ // Użyte po zmiennej najpierw zwracają zmienną a następnie dokonują
+ // zmiany wartości.
+ System.out.println(i++); // i = 1, wyświetli 0 (post-increment)
+ System.out.println(++i); // i = 2, wyświetli 2 (pre-increment)
+ System.out.println(i--); // i = 1, wyświetli 2 (post-decrement)
+ System.out.println(--i); // i = 0, wyświetli 0 (pre-decrement)
+
+ ///////////////////////////////////////
+ // Przepływ sterowania
+ ///////////////////////////////////////
+ System.out.println("\n->Przepływ sterowania");
+
+ // Instrukcja if wygląda jak w c
+ int j = 10;
+ if (j == 10) {
+ System.out.println("Wyświetlam się");
+ } else if (j > 10) {
+ System.out.println("A ja nie");
+ } else {
+ System.out.println("Ja też nie");
+ }
+
+ // Pętla while
+ int fooWhile = 0;
+ while(fooWhile < 100) {
+ System.out.println(fooWhile);
+ // Licznik jest zwiększany
+ // Iteruje 100 razy, fooWhile 0,1,2...99
+ fooWhile++;
+ }
+ System.out.println("Wartość fooWhile: " + fooWhile);
+
+ // Pętla do while
+ int fooDoWhile = 0;
+ do {
+ System.out.println(fooDoWhile);
+ // Licznik jest zwiększany
+ // Iteruje 99 razy, fooDoWhile 0->99
+ fooDoWhile++;
+ } while(fooDoWhile < 100);
+ System.out.println("Wartość fooDoWhile: " + fooDoWhile);
+
+ // Pętla for
+ // struktura pętli for => for(<początek>; <warunek>; <krok>)
+ for (int fooFor = 0; fooFor < 10; fooFor++) {
+ System.out.println(fooFor);
+ // Iteruje 10 razy, fooFor 0->9
+ }
+ System.out.println("Wartość fooFor: " + fooFor);
+
+ // Wyjście z zagnieżdżonej, oznaczonej pętli for
+ outer:
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ if (i == 5 && j ==5) {
+ break outer;
+ // wychodzi z zewnętrznej pętli zamiast jednynie z aktualnej z
+ // powodu oznaczenia
+ }
+ }
+ }
+
+ // Pętla for each
+ // Pętla for each może iterować tablice jak i obiekty
+ // które implementują interfejs Iterable.
+ int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ // Struktura for each => for (<element> : <obiekt iterowany>)
+ // należy rozumieć jako: dla każdego elementu w obiekcie iterowanym
+ // uwaga: typ zdefiniowango elementu musi się zgadzać z typem w
+ //obiekcie iterowanym.
+ for (int bar : fooList) {
+ System.out.println(bar);
+ //Iteruje 9 razy i wyświetla 1-9 w nowych liniach
+ }
+
+ // Switch Case
+ // Switch (przełącznik) działa z zmiennymi typu byte, short, char, int.
+ // Działa również z enumeratorami (zobacz typ Enum),
+ // klasą String, i kilkoma specjalnymi klasami które zawierają typy
+ // podstawowe: Character, Byte, Short, and Integer.
+ // Z wersją Java 7 i wyższymi możliwe jest użycie typu String.
+ // Uwagga: Pamiętaj, że nie dodając "break" na końcu danego case
+ // spowoduje przejście do następnego (jeżeli spełniony jest warunek).
+ int month = 3;
+ String monthString;
+ switch (month) {
+ case 1: monthString = "Styczeń";
+ break;
+ case 2: monthString = "Luty";
+ break;
+ case 3: monthString = "Marzec";
+ break;
+ default: monthString = "Inny miesiąc";
+ break;
+ }
+ System.out.println("Wynik Switch Case : " + monthString);
+
+
+ // Try-with-resources (Java 7+)
+ // Try-catch-finally działa zgodnie z oczekiwaniami jednakże w Java 7+
+ // dodatkowo jest dostępny try-with-resources statement.
+ // Try-with-resources upraszcza try-catch-finally automatycznie
+ // usuwając zasoby.
+
+ // Aby użyć try-with-resources, użyj instancji klasy
+ // w części "try". Klasa musi implementować java.lang.AutoCloseable.
+ try (BufferedReader br = new BufferedReader(new FileReader("foo.txt"))) {
+ // Tutaj możesz spróbować wywołac wyjątek.
+ System.out.println(br.readLine());
+ // W Java 7 zasoby będą zawsze usuwane nawet jeśli nastąpi wyjątek.
+ } catch (Exception ex) {
+ // Zasób będzie usunięty zanim wykona się catch.
+ System.out.println("readLine() nie powiódł się.");
+ }
+ // Nie ma potrzeby używać sekcji "finally", jako że BufferedReader
+ // został już zamknięty. Ten sposób może zostać użyty aby uniknąć
+ // pewnych wartości brzegowych gdzie "finally" nie zostałoby wywołane
+ // Więcej na ten temat po angielsku:
+ // https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
+
+
+ // Skrócone instrukcje warunkowe
+ // Dozwolone jest użycie operatora '?' aby szybko sprawdzić warunek
+ // logiczny. Rozumiane jest to jako "Jeśli (warunek) jest spełniony, użyj
+ // <pierwszej wartości>, inaczej, użyj <drugiej wartości>"
+ int foo = 5;
+ String bar = (foo < 10) ? "A" : "B";
+ System.out.println("bar : " + bar); // Wyśwletli "bar : A", poineważ
+ // warunke jest spełniony.
+ // Lub prościej
+ System.out.println("bar : " + (foo < 10 ? "A" : "B"));
+
+
+ ////////////////////////////////////////
+ // Konwersja typów danych
+ ////////////////////////////////////////
+
+ // Konwersja danych
+
+ // Konwersja String do Integer
+ Integer.parseInt("123");//zwraca zmienna typu Integer o wartości "123"
+
+ // Konwersja Integer do String
+ Integer.toString(123);//zwraca zmienną typu String o wartości 123
+
+ // Inne konwersje możesz sprawdzić dla klas:
+ // Double
+ // Long
+ // String
+
+ ///////////////////////////////////////
+ // Klasy i funkcje
+ ///////////////////////////////////////
+
+ System.out.println("\n->Klasy & Funkcje");
+
+ // (definicja klasy Rower nieco niżej)
+
+ // Użyj new aby zainstancjonować klasę
+ Rower trek = new Rower();
+
+ // Wywoływanie metod klasy
+ trek.predkoscZwieksz(3); // Zawsze używaj settera i gettera jako metod
+ trek.setPedalowanie(100);
+
+ // toString zwraca reprezentację typu String tego obiektu.
+ System.out.println("trek info: " + trek.toString());
+
+ // Inicjalizacja za pomocą podwójnego nawiasu
+ // Język Java nie zawiera możliwości stworzenia statycznej kolekcji
+ // Dlatego zwykle odbywa się to w ten sposób:
+ private static final Set<String> KRAJE = new HashSet<String>();
+ static {
+ KRAJE.add("DANIA");
+ KRAJE.add("SZWECJA");
+ KRAJE.add("FINLANDIA");
+ }
+
+ // Jest jednak sprytny sposób aby łatwiej osiągnąc ten sam efekt
+ // używając czegoś nazywanego Double Brace Initialization -
+ // inicjalizacja za pomocą podwójnego nawiasu.
+ private static final Set<String> KRAJE = new HashSet<String>() {{
+ add("DANIA");
+ add("SZWECJA");
+ add("FINLANDIA");
+ }}
+
+ // Pierwszy nawias tworzy nową klasę AnonymousInnerClass,
+ // drugi deklaruje instancję bloku inicjalizacji. Blok ten
+ // jest wywoływany gdy wewnętrzna, anonimowa klasa jest tworzona.
+ // Dany sposób działa nie tylko dla kolekcji, ale również dla
+ // wszystkich nie-finalnych klas.
+
+ } // Koniec metody main
+} // Koniec klasy LearnJava
+
+// Możesz zawrzeć inne, niepubliczne, zewnętrzne klasy w pliku .java,
+// jednak nie jest to zalecane. Zalecane jest dzielenie klas na osobne pliki.
+
+// Składnia deklaracji klasy:
+// <public/private/protected> class <nazwa klasy> {
+// // pola danych, konstruktory, funkcje.
+// // w jężyku Java funkcje są wywoływane jako metody.
+// }
+
+class Rower {
+
+ // Zmienne klasy
+ public int pedalowanie; // Public: Dostępne wszędzie
+ private int predkosc; // Private: Dostępne tylko w klasie
+ protected int przerzutka; // Protected: Dostępne w klasie i podklasach
+ String nazwa; // domyślnie: Dostępne tlyko w danej paczce
+ static String nazwaKlasy; // Zmienna statyczna
+
+ // Blok statyczny
+ // Java nie posiada implemntacji konstruktorów staycznych, ale
+ // posiada blok stayczny, który może być użyty aby zainicjalizować
+ // statyczne zmienne klasy
+ // Ten blok będzie wywołane gdy klasa jest ładowana.
+ static {
+ nazwaKlasy = "Rower";
+ }
+
+ // Konstruktory służą do stworzenia instancji klas
+ // Too jest konstruktor
+ public Rower() {
+ // Możesz wywołać także inny konstruktor:
+ // this(1, 50, 5, "Bontrager");
+ przerzutka = 1;
+ pedalowanie = 50;
+ predkosc = 5;
+ nazwa = "Bontrager";
+ }
+ // To jest konstruktor, który przyjmuje argumenty
+ public Rower(int poczatkowePedalowanie, int poczatkowaPredkosc, int początkowaPrzerzutka,
+ String nazwa) {
+ this.przerzutka = początkowaPrzerzutka;
+ this.pedalowanie = poczatkowePedalowanie;
+ this.predkosc = poczatkowaPredkosc;
+ this.nazwa = nazwa;
+ }
+
+ // Składnia metod:
+ // <public/private/protected> <zwracany rodzaj> <nazwa funkcji>(<argumenty>)
+
+ // Klasy często implementują metody getter i setter dla danych wewnątrz
+
+ // Składnia deklaracji metody:
+ // <dostępność> <zwracany rodzaj> <nawa metody>(<argumenty>)
+ public int getPedalowanie() {
+ return pedalowanie;
+ }
+
+ // metody void nie wymagają słowa kluczowego return, nic nie zwracają
+ public void setPedalowanie(int newValue) {
+ pedalowanie = newValue;
+ }
+ public void setPrzerzutka(int newValue) {
+ przerzutka = newValue;
+ }
+ public void predkoscZwieksz(int inkrement) {
+ predkosc += inkrement;
+ }
+ public void predkoscZmniejsz(int dekrement) {
+ predkosc -= dekrement;
+ }
+ public void nadajNazwe(String nowaNazwa) {
+ nazwa = nowaNazwa;
+ }
+ public String zwrocNazwe() {
+ return nazwa;
+ }
+
+ // Metoda do wyświetlenia wartości atrybutów danego obiektu.
+ @Override // Dziedziczy z klasy obiektu.
+ public String toString() {
+ return "przerzutka: " + przerzutka + " pedalowanie: " + pedalowanie + " predkosc: " + predkosc +
+ " nazwa: " + nazwa;
+ }
+} // koniec klasy Rower
+
+// PennyFarthing jest podklasą klasy Rower
+class PennyFarthing extends Rower {
+ // (Penny Farthing to rower z wielkim przednim kołem.
+ // Nie ma przerzutek.)
+
+ public PennyFarthing(int poczatkowePedalowanie, int poczatkowaPredkosc) {
+ // Wywołanie kostruktora klasy z której dziedziczymy za pomocą super
+ super(poczatkowePedalowanie, poczatkowaPredkosc, 0, "PennyFarthing");
+ }
+
+ // Używamy annotacji @annotation przy przeciążaniu metod.
+ // Aby dowiedzieć się więcej o annotacjach przydatne jest przejrzenie
+ // (w języku angielskim):
+ // http://docs.oracle.com/javase/tutorial/java/annotations/
+ @Override
+ public void setPrzerzutka(int przerzutka) {
+ this.przerzutka = 0;
+ }
+}
+
+// Rzutowanie
+// Jako, że klasa PennyFarthing dziedziczy z klasy Rower, możemy uznać, że
+// instancja PennyFarthing jest typu Rower i napisać :
+// Rower rower = new PennyFarthing();
+// Dana operacja jest rzutowaniem obiektu, gdzie jego domyślna klasa jest inna niż docelowa.
+// Więcej szczegółów i przykładów oraz ciekawych konceptów (po angielsku):
+// https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
+
+// Interfejsy
+// Składnia deklaracji interfejsu
+// <dostępność> interface <nazwa interfejsu> extends <super-interfaces> {
+// // Zmienne typu constant
+// // Deklaracje metod
+// }
+
+// Przykład - Jedzenie:
+public interface Jadalne {
+ public void jedz(); // Każda klasa która implemetuje ten interfejs musi
+ // implementować tę metodę.
+}
+
+public interface Przetrawialne {
+ public void przetrawiaj();
+ // Wraz z Java 8, interfejsy mogą mieć metodę domyślną.
+ public default void defaultMethod() {
+ System.out.println("Hej z metody domyślnej ...");
+ }
+}
+
+// Teraz stworzymy klasę, która zaimplementuje oba interfejsy.
+public class Owoc implements Jadalne, Przetrawialne {
+ @Override
+ public void jedz() {
+ // ...
+ }
+
+ @Override
+ public void przetrawiaj() {
+ // ...
+ }
+}
+
+// W Javie możesz dziedziczyć jedynie z jednej klasy, jednak implementować
+// wiele interfejsów. Na przykład:
+public class Przyklad extends Przodek implements Interfejs1,
+ Interfejs2 {
+ @Override
+ public void Interfejs1Metoda() {
+ }
+
+ @Override
+ public void Interfejs2Metoda() {
+ }
+
+}
+
+// Klasy abstrakcyjne
+
+// Składnia deklaracji klasy abstrakcyjnej
+// <dostępność> abstract class <nawa klasy abstrakcyjnej> extends
+// <superklasy, z których dziedziczy> {
+// // Zmienne i stałe
+// // Deklaracje metod
+// }
+
+// Klasy abstrakcyjne nie mogą posiadać instancji.
+// Klasy abstrakcyjne mogą definiować metody abstrakcyjne.
+// Metody abstrakcyjne nie mają ciała funkcji i są oznaczone jako abstrakcyjne.
+// Nieabstrakcyjne klasy-dzieci muszą przeciążać wszystkie abstrakcyjne metody
+// superklasy.
+// Klasy abstrakcyjne są użyteczne gdy wymagana jest powtarzalna logika działania,
+// jednak należy zaauważyć, że jako, że wymagają dziedziczenia, łamią
+// zasadę "Composition over inheritance". Rozważ inne podejścia używając
+// kompozycji. https://en.wikipedia.org/wiki/Composition_over_inheritance
+
+public abstract class Zwierze
+{
+ private int wiek;
+
+ public abstract void dajGlos();
+
+ // Metody mogą mieć ciało
+ public void jedz()
+ {
+ System.out.println("Jestem zwierzeciem i jem.");
+ // Uwaga: Możliwy jest dostęp do zmiennych prywatnych.
+ wiek = 30;
+ }
+
+ public void wyswietlWiek()
+ {
+ System.out.println(wiek);
+ }
+
+ // Klasy abstrakcyjne mogą mieć metodę główną.
+ public static void main(String[] args)
+ {
+ System.out.println("Jestem abstrakcyjna");
+ }
+}
+
+class Pies extends Zwierze
+{
+ // Musimy przeciążyć wszystkie abstrakcyjne metody z klasy abstrakcyjnej
+ @Override
+ public void dajGlos()
+ {
+ System.out.println("Hau");
+ // wiek = 30; ==> BLAD! wiek jest typu private dla Zwierze
+ }
+
+ // NOTE: Wystąpi błąd jeżeli użyto annotacji @Override jako, że Java
+ // nie pozwala na przeciążanie metod statycznych.
+ // Występuje tutaj METHOD HIDING - ukrywanie metod.
+ // Więcej w poście na SO: http://stackoverflow.com/questions/16313649/
+ public static void main(String[] args)
+ {
+ Pies pluto = new Pies();
+ pluto.dajGLos();
+ pluto.jedz();
+ pluto.wyswietlWiek();
+ }
+}
+
+// Klasy finalne
+
+// Składnia deklaracji klasy finalnej
+// <dostępność> final <nazwa klasy finalnej> {
+// // Zmienne i stałe
+// // Deklaracje Metody
+// }
+
+// Klasy finalne są klasami, które nie mogą być użyte do dziedziczenia, są więc
+// z założenia ostatnim elementem dziedziczenia. W ten sposób są przeciwnością
+// klas abstrakcyjnych, które z założenia muszą być dziedziczone.
+public final class TygrysSzablozebny extends Zwierze
+{
+ // Nadal musimy przeciążyć metody abstrakcyjne klasy abstrakcyjnej Zwierze
+ @Override
+ public void dajGlos()
+ {
+ System.out.println("Roar");
+ }
+}
+
+// Metody finalne
+public abstract class Ssak
+{
+ // Składnia metody finalnej:
+ // <dostępność> final <zwracany rodzaj> <nazwa funkcji>(<argumenty>)
+
+ // Metody finalne, jak klasy finalne nie mogą być przeciążane
+ // i są w ten sposób ostatecznymi implementacjami danej metody.
+ public final boolean jestStalocieplny()
+ {
+ return true;
+ }
+}
+
+// Enumeratory
+//
+// Enumerator jest specjalnym tyme danej, która pozwala zmiennej na bycie
+// zestawem wcześniej zdefiniowanych stałych. Zmienna musi być równa jednej z
+// wartości wcześniej zdefiniowanych. Jako, że są to stałe, nazwy pól typu enum
+// są pisane wielkimi literami. W języku Java typ enum definiujemy przez użycie
+// słowa enum. Na przykład aby zdefiniować dni tygodnia:
+public enum Dzien {
+ PONIEDZIALEK, WTOREK, SRODA, CZWARTEK,
+ PIATEK, SOBOTA, NIEDZIELA
+}
+
+// We can use our enum Day like that:
+public class EnumTest {
+ // Zmienna typu enum
+ Dzien dzien;
+
+ public EnumTest(Dzien dzien) {
+ this.dzien = dzien;
+ }
+
+ public void opiszDzien() {
+ switch (dzien) {
+ case PONIEDZIALEK:
+ System.out.println("Nie lubię poniedziałku!");
+ break;
+ case PIATEK:
+ System.out.println("Piątki są dużo lepsze.");
+ break;
+ case SOBOTA:
+ case NIEDZIELA:
+ System.out.println("Weekendy są najlepsze.");
+ break;
+ default:
+ System.out.println("Środek tygodnia jest taki sobie.");
+ break;
+ }
+ }
+
+ public static void main(String[] args) {
+ EnumTest pierwszyDzien = new EnumTest(Dzien.PONIEDZIALEK);
+ pierwszyDzien.opiszDzien(); // => Nie lubię poniedziałku!
+ EnumTest trzeciDzien = new EnumTest(Dzien.SRODA);
+ trzeciDzien.opiszDzien(); // => Środek tygodnia jest taki sobie.
+ }
+}
+
+// Typ enum jest bardziej wszechstronny niż powyższa demostracja.
+// Ciało typu enum może zawierać metody i inne pola.
+// Rzuć okiem na (angielski) https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
+
+// Wprowadzenie do wyrażeń lambda
+//
+// Nowe w Javie 8 są wyrażenia lambda. Lambdy znajdujemy zwykle w funkcyjnych
+// językach programowania, co oznacza, że są metodami, które potrafią być
+// stowrzone bez klasy i przekazywane jak gdyby były obiektem oraz wykonywane
+// gdy zajdzie potrzeba.
+//
+// Ostatnia uwaga - lambdy muszą implementować funcjonalny interfejs.
+// Interfels funkcjonalny to taki, który ma jedynie jedną zadeklarowaną metodę
+// abstrakcyjną, ale może mieć dowolną ilość domyślnych metod. Wyrażenia lambda
+// mogą być używane jako instancje tego interfejsu. Każdy inteferjs, który
+// spełnia wymagania jest traktowany jako funkcjonalny. Więcej o interfejsach
+// znajdziesz powyżej, w odpowiedniej sekcji.
+//
+import java.util.Map;
+import java.util.HashMap;
+import java.util.function.*;
+import java.security.SecureRandom;
+
+public class Lambdas {
+ public static void main(String[] args) {
+ // Składnia deklaracji lambdy:
+ // <zero lub więcej parametrów> -> <ciało wyrażenia lub blok instrukcji>
+
+ // Poniżej w przykładzie użyjemy tablicy z hashowaniem.
+ Map<String, String> planety = new HashMap<>();
+ planety.put("Merkury", "87.969");
+ planety.put("Wenus", "224.7");
+ planety.put("Ziemia", "365.2564");
+ planety.put("Mars", "687");
+ planety.put("Jowisz", "4,332.59");
+ planety.put("Saturn", "10,759");
+ planety.put("Uran", "30,688.5");
+ planety.put("Neptun", "60,182");
+
+ // Lambda z zerową liczbą parametrów używając funkcjonalnego interfejsu
+ // Supplier z java.util.function.Supplier. Faktyczną lambdą jest częśc
+ // po numPlanets =.
+ Supplier<String> numPlanety = () -> Integer.toString(planety.size());
+ System.out.format("Liczba planet: %s\n\n", numPlanety.get());
+
+ // Lambda z jednym parametrem używająca funkcjonalnego interfejsu
+ // Consumer z java.util.function.Consumer.planety jest mapą, która
+ // wimplementuje Collection jak i Iterable. Użyty forEach pochodzi z
+ // Iterable i jest użyty w lambdzie na każdym elemencie kolekcji
+ // Domyślna implementacja forEach wygląda tak:
+ /*
+ for (T t : this)
+ action.accept(t);
+ */
+
+ // Faktyczna lambda jest parametrem przekazywanym do forEach.
+ planety.keySet().forEach((p) -> System.out.format("%s\n", p));
+
+ // Jeżeli przekazujemy tyklo pojedynczy argumentpowyższy zapis możemy
+ // przekształcić do (zauważ brak nawiasów dookoła p):
+ planety.keySet().forEach(p -> System.out.format("%s\n", p));
+
+ // Śledząc powyższe widzimy, że planety jest typu HashMap, a keySet()
+ // zwraca zestaw kluczy, forEach stosuje o każdego elementu lambdę:
+ // (parameter p) -> System.out.format("%s\n", p). Za każdym razem
+ // element jest uznawany jako "konsumowany" i wyrażenie (wyrażenia)
+ // w lambdzie są wykonywane. Pamiętaj, że ciało lambdy to część po
+ // symbolu ->.
+
+ // Powyższy przykład bez użycia lambdy wyglądałby tradycyjnie tak:
+ for (String planeta : planety.keySet()) {
+ System.out.format("%s\n", planeta);
+ }
+
+ // Poniższy przykład różni się od powyższego sposobem implementacji
+ // forEach: forEach użyty w klasie HashMap implementuje intefejs Map.
+ // Poniższy forEach przyjmuje BiConsumer, który ogólnie ujmując jest
+ // wymyślnym sposobem stwierdzenia, że zajmuje się zestawem par
+ // klucz-wartość Key -> Value dla każdego klucza. Ta domyślna
+ // implementacja działa jak:
+ /*
+ for (Map.Entry<K, V> entry : map.entrySet())
+ action.accept(entry.getKey(), entry.getValue());
+ */
+
+ // Faktyczna lambda jest parametrem przekazywanym do forEach.
+ String orbity = "%s okrąża Słońce w %s dni.\n";
+ planety.forEach((K, V) -> System.out.format(orbity, K, V));
+
+ // Powyższe bez użycia lambdy wyglądałoby tradycyjnie tak:
+ for (String planet : planety.keySet()) {
+ System.out.format(orbity, planet, planety.get(planet));
+ }
+
+ // Lub jeżeli postępujemy zgodnie ze specyfikacją domyślnej implementacji:
+ for (Map.Entry<String, String> planeta : planety.entrySet()) {
+ System.out.format(orbity, planeta.getKey(), planeta.getValue());
+ }
+
+ // Podane przykłady pokrywają jedynie podstawowe zastosowanie wyrażeń
+ // lambda. Być może wydają się one niezbyt przydatne, jednak należy
+ // pamiętać, że lambdy można stworzyć jako obiekty, które nastepnie mogą
+ // zostać przekazane jako parametry do innych metod.
+ }
+}
+```
+
+## Dalsze materiały
+
+Linki zamieszczone poniżej służą pomocą w zrozumieniu wybranego tematu, w razie braku rozwiązania wyszukanie w Google zwykle służy pomocą
+
+**Oficjalne poradniki Oracle po angielsku**:
+
+* [Tutorial w Javie od Sun / Oracle](https://docs.oracle.com/javase/tutorial/index.html)
+
+* [Modyfikacje poziomu dostępu w Java](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)
+
+* [Koncepty programowania obiektowego](https://docs.oracle.com/javase/tutorial/java/concepts/index.html):
+ * [Dziedziczenie](https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html)
+ * [Polimorfizm](https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html)
+ * [Abstrakcja](https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)
+
+* [Wyjątki](https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html)
+
+* [Interfejsy](https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html)
+
+* [Uogólnianie](https://docs.oracle.com/javase/tutorial/java/generics/index.html)
+
+* [Konwencja kodu Java](https://www.oracle.com/technetwork/java/codeconvtoc-136057.html)
+
+* Nowości z Java 8:
+ * [Funkcje Lambda (programowanie funkcyjne)](https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html)
+ * [Data y czas API (java.time package)](http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html)
+
+**Kursy po polsku**
+
+* [PJWSTK - Podstawy programowania w języku Java](http://edu.pjwstk.edu.pl/wyklady/ppj/scb/)
+
+* [PJWSTK - Programowanie obiektowe w języku Java](http://edu.pjwstk.edu.pl/wyklady/poj/scb/)
+
+**Tutoriale i ćwiczenia online po angielsku**
+
+* [Learneroo.com - Learn Java](http://www.learneroo.com)
+
+* [Codingbat.com](http://codingbat.com/java)
+
+* [Codewars - Java Katas](https://www.codewars.com/?language=java)
+
+**Książki po angielsku**:
+
+* [Head First Java](http://www.headfirstlabs.com/books/hfjava/)
+
+* [Thinking in Java](http://www.mindview.net/Books/TIJ/)
+
+* [Objects First with Java](https://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660)
+
+* [Java The Complete Reference](https://www.amazon.com/gp/product/0071606300)
diff --git a/pl-pl/json-pl.html.markdown b/pl-pl/json-pl.html.markdown
index 872455de..edd059bf 100644
--- a/pl-pl/json-pl.html.markdown
+++ b/pl-pl/json-pl.html.markdown
@@ -1,6 +1,6 @@
---
+category: language
language: json
-filename: learnjson-pl.json
contributors:
- ["Anna Harren", "https://github.com/iirelu"]
- ["Marco Scannadinari", "https://github.com/marcoms"]
@@ -9,6 +9,7 @@ contributors:
translators:
- ["Michał Mitrosz", "https://github.com/Voltinus"]
lang: pl-pl
+filename: learnjson-pl.json
---
JSON to bardzo prosty format wymiany danych. Jak jest napisane na [json.org](http://json.org), jest łatwy do pisania i czytania dla ludzi i do parsowania i generowania dla maszyn.
diff --git a/pl-pl/perl-pl.html.markdown b/pl-pl/perl-pl.html.markdown
index 029ca006..43d68b05 100644
--- a/pl-pl/perl-pl.html.markdown
+++ b/pl-pl/perl-pl.html.markdown
@@ -2,17 +2,20 @@
name: perl
category: language
language: perl
-filename: learnperl.pl
+filename: learnperl-pl.pm
contributors:
- ["Korjavin Ivan", "http://github.com/korjavin"]
+ - ["Dan Book", "http://github.com/Grinnz"]
+translators:
- ["Michał Kupczyński", "http://github.com/ukoms"]
lang: pl-pl
+
---
-Perl 5 jest wysoce użytecznym, bogatym w wiele opcji językiem programowania
+Perl jest wysoce użytecznym, bogatym w wiele opcji językiem programowania
z ponad 25 latami nieustannego rozwoju.
-Perl 5 używany jest na ponad 100 różnych platformach (od przenośnych do w
+Perl używany jest na ponad 100 różnych platformach (od przenośnych do w
pełni stacjonarnych) i nadaje się zarówno do szybkiego prototypowania jak
i projektów deweloperskich prowadzonych na szeroką skalę.
diff --git a/pl-pl/python-pl.html.markdown b/pl-pl/pythonlegacy-pl.html.markdown
index 023c3e6b..2b35ce90 100644
--- a/pl-pl/python-pl.html.markdown
+++ b/pl-pl/pythonlegacy-pl.html.markdown
@@ -1,8 +1,6 @@
---
-name: python
-category: language
-language: python
-filename: learnpython-pl.py
+language: Python 2 (legacy)
+filename: learnpythonlegacy-pl.py
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
- ["Amin Bandali", "http://aminbandali.com"]
@@ -532,7 +530,7 @@ Czlowiek.grunt() # => "*grunt*"
# Tak importuje się moduły:
import math
-print(math.sqrt(16)) # => 4
+print(math.sqrt(16)) # => 4.0
# Można podać konkretne funkcje, np. ceil, floor z modułu math
from math import ceil, floor
diff --git a/pl-pl/vim-pl.html.markdown b/pl-pl/vim-pl.html.markdown
index 21c8c152..8ac2df56 100644
--- a/pl-pl/vim-pl.html.markdown
+++ b/pl-pl/vim-pl.html.markdown
@@ -10,7 +10,7 @@ filename: LearnVim-pl.txt
---
-[Vim](www.vim.org)
+[Vim](http://www.vim.org)
(Vi IMproved) jest klonem popularnego edytora vi dla systemów Unix.
Zaprojektowany z myślą o prędkości edycji i zwiększeniu produktywności jest
wszechobecny na systemach UNIXopodobnych. Posiada wiele skrótów klawiszowych
diff --git a/powershell.html.markdown b/powershell.html.markdown
index f34d5b4e..318bf043 100644
--- a/powershell.html.markdown
+++ b/powershell.html.markdown
@@ -3,6 +3,7 @@ category: tool
tool: powershell
contributors:
- ["Wouter Van Schandevijl", "https://github.com/laoujin"]
+ - ["Andrew Ryan Davis", "https://github.com/AndrewDavis1191"]
filename: LearnPowershell.ps1
---
@@ -13,104 +14,374 @@ Nearly all examples below can be a part of a shell script or executed directly
in the shell.
A key difference with Bash is that it is mostly objects that you manipulate
-rather than plain text.
+rather than plain text. After years of evolving, it resembles Python a bit.
-[Read more here.](https://technet.microsoft.com/en-us/library/bb978526.aspx)
+[Read more here.](https://docs.microsoft.com/powershell/scripting/overview)
-If you are uncertain about your environment:
+Powershell as a Language:
```powershell
-Get-ExecutionPolicy -List
-Set-ExecutionPolicy AllSigned
-# Execution policies include:
-# - Restricted: Scripts won't run.
-# - RemoteSigned: Downloaded scripts run only if signed by a trusted publisher.
-# - AllSigned: Scripts need to be signed by a trusted publisher.
-# - Unrestricted: Run all scripts.
-help about_Execution_Policies # for more info
-# Current PowerShell version:
-$PSVersionTable
-```
+# Single line comments start with a number symbol.
-Getting help:
+<#
+ Multi-line comments
+ like so
+#>
-```
-# Find commands
-Get-Command about_* # alias: gcm
-Get-Command -Verb Add
-Get-Alias ps
-Get-Alias -Definition Get-Process
-Get-Help ps | less # alias: help
-ps | Get-Member # alias: gm
+####################################################
+## 1. Primitive Datatypes and Operators
+####################################################
+
+# Numbers
+3 # => 3
+
+# Math
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7.0
+
+# Powershell uses banker's rounding,
+# meaning [int]1.5 would round to 2 but so would [int]2.5
+# Division always returns a float.
+# You must cast result to [int] to round.
+[int]5 / [int]3 # => 1.66666666666667
+[int]-5 / [int]3 # => -1.66666666666667
+5.0 / 3.0 # => 1.66666666666667
+-5.0 / 3.0 # => -1.66666666666667
+[int]$result = 5 / 3
+$result # => 2
+
+# Modulo operation
+7 % 3 # => 1
+
+# Exponentiation requires longform or the built-in [Math] class.
+[Math]::Pow(2,3) # => 8
+
+# Enforce order of operations with parentheses.
+1 + 3 * 2 # => 7
+(1 + 3) * 2 # => 8
+
+# Boolean values are primitives (Note: the $)
+$True # => True
+$False # => False
+
+# negate with !
+!$True # => False
+!$False # => True
+
+# Boolean Operators
+# Note "-and" and "-or" usage
+$True -and $False # => False
+$False -or $True # => True
+
+# True and False are actually 1 and 0 but only support limited arithmetic.
+# However, casting the bool to int resolves this.
+$True + $True # => 2
+$True * 8 # => '[System.Boolean] * [System.Int32]' is undefined
+[int]$True * 8 # => 8
+$False - 5 # => -5
+
+# Comparison operators look at the numerical value of True and False.
+0 -eq $False # => True
+1 -eq $True # => True
+2 -eq $True # => False
+-5 -ne $False # => True
+
+# Using boolean logical operators on ints casts to booleans for evaluation.
+# but their non-cast value is returned
+# Don't mix up with bool(ints) and bitwise -band/-bor
+[bool](0) # => False
+[bool](4) # => True
+[bool](-6) # => True
+0 -band 2 # => 0
+-5 -bor 0 # => -5
+
+# Equality is -eq (equals)
+1 -eq 1 # => True
+2 -eq 1 # => False
+
+# Inequality is -ne (notequals)
+1 -ne 1 # => False
+2 -ne 1 # => True
+
+# More comparisons
+1 -lt 10 # => True
+1 -gt 10 # => False
+2 -le 2 # => True
+2 -ge 2 # => True
+
+# Seeing whether a value is in a range
+1 -lt 2 -and 2 -lt 3 # => True
+2 -lt 3 -and 3 -lt 2 # => False
+
+# (-is vs. -eq) -is checks if two objects are the same type.
+# -eq checks if the objects have the same values.
+# Note: we called '[Math]' from .NET previously without the preceeding
+# namespaces. We can do the same with [Collections.ArrayList] if preferred.
+[System.Collections.ArrayList]$a = @() # Point a at a new list
+$a = (1,2,3,4)
+$b = $a # => Point b at what a is pointing to
+$b -is $a.GetType() # => True, a and b equal same type
+$b -eq $a # => True, a and b values are equal
+[System.Collections.Hashtable]$b = @{} # => Point a at a new hash table
+$b = @{'one' = 1
+ 'two' = 2}
+$b -is $a.GetType() # => False, a and b types not equal
+
+# Strings are created with " or ' but " is required for string interpolation
+"This is a string."
+'This is also a string.'
+
+# Strings can be added too! But try not to do this.
+"Hello " + "world!" # => "Hello world!"
+
+# A string can be treated like a list of characters
+"Hello world!"[0] # => 'H'
+
+# You can find the length of a string
+("This is a string").Length # => 16
+
+# You can also format using f-strings or formatted string literals.
+$name = "Steve"
+$age = 22
+"He said his name is $name."
+# => "He said his name is Steve"
+"{0} said he is {1} years old." -f $name, $age
+# => "Steve said he is 22 years old"
+"$name's name is $($name.Length) characters long."
+# => "Steve's name is 5 characters long."
+
+# Escape Characters in Powershell
+# Many languages use the '\', but Windows uses this character for
+# file paths. Powershell thus uses '`' to escape characters
+# Take caution when working with files, as '`' is a
+# valid character in NTFS filenames.
+"Showing`nEscape Chars" # => new line between Showing and Escape
+"Making`tTables`tWith`tTabs" # => Format things with tabs
+
+# Negate pound sign to prevent comment
+# Note that the function of '#' is removed, but '#' is still present
+`#Get-Process # => Fail: not a recognized cmdlet
+
+# $null is not an object
+$null # => None
+
+# $null, 0, and empty strings and arrays all evaluate to False.
+# All other values are True
+function Test-Value ($value) {
+ if ($value) {
+ Write-Output 'True'
+ }
+ else {
+ Write-Output 'False'
+ }
+}
-Show-Command Get-EventLog # Display GUI to fill in the parameters
+Test-Value ($null) # => False
+Test-Value (0) # => False
+Test-Value ("") # => False
+Test-Value [] # => True
+# *[] calls .NET class; creates '[]' string when passed to function
+Test-Value ({}) # => True
+Test-Value @() # => False
-Update-Help # Run as admin
-```
-The tutorial starts here:
+####################################################
+## 2. Variables and Collections
+####################################################
+
+# Powershell uses the "Write-Output" function to print
+Write-Output "I'm Posh. Nice to meet you!" # => I'm Posh. Nice to meet you!
+
+# Simple way to get input data from console
+$userInput = Read-Host "Enter some data: " # Returns the data as a string
+
+# There are no declarations, only assignments.
+# Convention is to use camelCase or PascalCase, whatever your team uses.
+$someVariable = 5
+$someVariable # => 5
+
+# Accessing a previously unassigned variable does not throw exception.
+# The value is $null by default
+
+# Ternary Operators exist in Powershell 7 and up
+0 ? 'yes' : 'no' # => no
-```
-# As you already figured, comments start with #
-
-# Simple hello world example:
-echo Hello world!
-# echo is an alias for Write-Output (=cmdlet)
-# Most cmdlets and functions follow the Verb-Noun naming convention
-
-# Each command starts on a new line, or after a semicolon:
-echo 'This is the first line'; echo 'This is the second line'
-
-# Declaring a variable looks like this:
-$aString="Some string"
-# Or like this:
-$aNumber = 5 -as [double]
-$aList = 1,2,3,4,5
-$aString = $aList -join '--' # yes, -split exists also
-$aHashtable = @{name1='val1'; name2='val2'}
-
-# Using variables:
-echo $aString
-echo "Interpolation: $aString"
-echo "`$aString has length of $($aString.Length)"
-echo '$aString'
-echo @"
-This is a Here-String
-$aString
-"@
-# Note that ' (single quote) won't expand the variables!
-# Here-Strings also work with single quote
-
-# Builtin variables:
-# There are some useful builtin variables, like
-echo "Booleans: $TRUE and $FALSE"
-echo "Empty value: $NULL"
-echo "Last program's return value: $?"
-echo "Exit code of last run Windows-based program: $LastExitCode"
-echo "The last token in the last line received by the session: $$"
-echo "The first token: $^"
-echo "Script's PID: $PID"
-echo "Full path of current script directory: $PSScriptRoot"
-echo 'Full path of current script: ' + $MyInvocation.MyCommand.Path
-echo "FUll path of current directory: $Pwd"
-echo "Bound arguments in a function, script or code block: $PSBoundParameters"
-echo "Unbound arguments: $($Args -join ', ')."
-# More builtins: `help about_Automatic_Variables`
-
-# Inline another file (dot operator)
-. .\otherScriptName.ps1
-
-
-### Control Flow
-# We have the usual if structure:
-if ($Age -is [string]) {
- echo 'But.. $Age cannot be a string!'
-} elseif ($Age -lt 12 -and $Age -gt 0) {
- echo 'Child (Less than 12. Greater than 0)'
-} else {
- echo 'Adult'
+
+# The default array object in Powershell is an fixed length array.
+$defaultArray = "thing","thing2","thing3"
+# you can add objects with '+=', but cannot remove objects.
+$defaultArray.Add("thing4") # => Exception "Collection was of a fixed size."
+# To have a more workable array, you'll want the .NET [ArrayList] class
+# It is also worth noting that ArrayLists are significantly faster
+
+# ArrayLists store sequences
+[System.Collections.ArrayList]$array = @()
+# You can start with a prefilled ArrayList
+[System.Collections.ArrayList]$otherArray = @(4, 5, 6)
+
+# Add to the end of a list with 'Add' (Note: produces output, append to $null)
+$array.Add(1) > $null # $array is now [1]
+$array.Add(2) > $null # $array is now [1, 2]
+$array.Add(4) > $null # $array is now [1, 2, 4]
+$array.Add(3) > $null # $array is now [1, 2, 4, 3]
+# Remove from end with index of count of objects-1; array index starts at 0
+$array.RemoveAt($array.Count-1) # => 3 and array is now [1, 2, 4]
+# Let's put it back
+$array.Add(3) > $null # array is now [1, 2, 4, 3] again.
+
+# Access a list like you would any array
+$array[0] # => 1
+# Look at the last element
+$array[-1] # => 3
+
+# Looking out of bounds returns nothing
+$array[4] # blank line returned
+
+# You can look at ranges with slice syntax.
+# The start index is included, the end index is not
+# (It's a closed/open range for you mathy types.)
+$array[1..3] # Return array from index 1 to 3 => [2, 4]
+$array[2..-1] # Return array starting from index 2 => [4, 3]
+$array[0..3] # Return array from beginning until index 3 => [1, 2, 4]
+$array[0..2] # Return array selecting every second entry => [1, 4]
+$array.Reverse() # mutates array to reverse order => [3, 4, 2, 1]
+# Use any combination of these to make advanced slices
+
+# Remove arbitrary elements from a array with "del"
+$array.Remove($array[2]) # $array is now [1, 2, 3]
+
+# Insert an element at a specific index
+$array.Insert(1, 2) # $array is now [1, 2, 3] again
+
+# Get the index of the first item found matching the argument
+$array.IndexOf(2) # => 1
+$array.IndexOf(6) # Returns -1 as "outside array"
+
+# You can add arrays
+# Note: values for $array and for $otherArray are not modified.
+$array + $otherArray # => [1, 2, 3, 4, 5, 6]
+
+# Concatenate arrays with "AddRange()"
+$array.AddRange($otherArray) # Now $array is [1, 2, 3, 4, 5, 6]
+
+# Check for existence in a array with "in"
+1 -in $array # => True
+
+# Examine length with "Count" (Note: "Length" on arrayList = each items length)
+$array.Count # => 6
+
+
+# Tuples are like arrays but are immutable.
+# To use Tuples in powershell, you must use the .NET tuple class.
+$tuple = [System.Tuple]::Create(1, 2, 3)
+$tuple.Item(0) # => 1
+$tuple.Item(0) = 3 # Raises a TypeError
+
+# You can do some of the array methods on tuples, but they are limited.
+$tuple.Length # => 3
+$tuple + (4, 5, 6) # => Exception
+$tuple[0..2] # => $null
+2 -in $tuple # => False
+
+
+# Hashtables store mappings from keys to values, similar to Dictionaries.
+$emptyHash = @{}
+# Here is a prefilled dictionary
+$filledHash = @{"one"= 1
+ "two"= 2
+ "three"= 3}
+
+# Look up values with []
+$filledHash["one"] # => 1
+
+# Get all keys as an iterable with ".Keys".
+# items maintain the order at which they are inserted into the dictionary.
+$filledHash.Keys # => ["one", "two", "three"]
+
+# Get all values as an iterable with ".Values".
+$filledHash.Values # => [1, 2, 3]
+
+# Check for existence of keys or values in a hash with "-in"
+"one" -in $filledHash.Keys # => True
+1 -in $filledHash.Values # => False
+
+# Looking up a non-existing key returns $null
+$filledHash["four"] # $null
+
+# Adding to a dictionary
+$filledHash.Add("five",5) # $filledHash["five"] is set to 5
+$filledHash.Add("five",6) # exception "Item with key "five" has already been added"
+$filledHash["four"] = 4 # $filledHash["four"] is set to 4, running again does nothing
+
+# Remove keys from a dictionary with del
+$filledHash.Remove("one") # Removes the key "one" from filled dict
+
+
+####################################################
+## 3. Control Flow and Iterables
+####################################################
+
+# Let's just make a variable
+$someVar = 5
+
+# Here is an if statement.
+# This prints "$someVar is smaller than 10"
+if ($someVar -gt 10) {
+ Write-Output "$someVar is bigger than 10."
+}
+elseif ($someVar -lt 10) { # This elseif clause is optional.
+ Write-Output "$someVar is smaller than 10."
+}
+else { # This is optional too.
+ Write-Output "$someVar is indeed 10."
+}
+
+
+<#
+Foreach loops iterate over arrays
+prints:
+ dog is a mammal
+ cat is a mammal
+ mouse is a mammal
+#>
+foreach ($animal in ("dog", "cat", "mouse")) {
+ # You can use -f to interpolate formatted strings
+ "{0} is a mammal" -f $animal
+}
+
+<#
+For loops iterate over arrays and you can specify indices
+prints:
+ 0 a
+ 1 b
+ 2 c
+ 3 d
+ 4 e
+ 5 f
+ 6 g
+ 7 h
+#>
+$letters = ('a','b','c','d','e','f','g','h')
+for($i=0; $i -le $letters.Count-1; $i++){
+ Write-Host $i, $letters[$i]
+}
+
+<#
+While loops go until a condition is no longer met.
+prints:
+ 0
+ 1
+ 2
+ 3
+#>
+$x = 0
+while ($x -lt 4) {
+ Write-Output $x
+ $x += 1 # Shorthand for x = x + 1
}
# Switch statements are more powerful compared to most languages
@@ -121,88 +392,53 @@ switch($val) {
{ $_ -like 's*' } { "Case insensitive"; break }
{ $_ -clike 's*'} { "clike, ceq, cne for case sensitive"; break }
{ $_ -notmatch '^.*$'} { "Regex matching. cnotmatch, cnotlike, ..."; break }
- { 'x' -contains 'x'} { "FALSE! -contains is for lists!"; break }
default { "Others" }
}
-# The classic for
-for($i = 1; $i -le 10; $i++) {
- "Loop number $i"
+# Handle exceptions with a try/catch block
+try {
+ # Use "throw" to raise an error
+ throw "This is an error"
}
-# Or shorter
-1..10 | % { "Loop number $_" }
-
-# PowerShell also offers
-foreach ($var in 'val1','val2','val3') { echo $var }
-# while () {}
-# do {} while ()
-# do {} until ()
-
-# Exception handling
-try {} catch {} finally {}
-try {} catch [System.NullReferenceException] {
- echo $_.Exception | Format-List -Force
+catch {
+ Write-Output $Error.ExceptionMessage
+}
+finally {
+ Write-Output "We can clean up resources here"
}
-### Providers
-# List files and directories in the current directory
-ls # or `dir`
-cd ~ # goto home
-
-Get-Alias ls # -> Get-ChildItem
-# Uh!? These cmdlets have generic names because unlike other scripting
-# languages, PowerShell does not only operate in the current directory.
-cd HKCU: # go to the HKEY_CURRENT_USER registry hive
-
-# Get all providers in your session
-Get-PSProvider
-
-
-### Pipeline
-# Cmdlets have parameters that control their execution:
-Get-ChildItem -Filter *.txt -Name # Get just the name of all txt files
-# Only need to type as much of a parameter name until it is no longer ambiguous
-ls -fi *.txt -n # -f is not possible because -Force also exists
-# Use `Get-Help Get-ChildItem -Full` for a complete overview
-
-# Results of the previous cmdlet can be passed to the next as input.
-# `$_` is the current object in the pipeline object.
-ls | Where-Object { $_.Name -match 'c' } | Export-CSV export.txt
-ls | ? { $_.Name -match 'c' } | ConvertTo-HTML | Out-File export.html
+# Writing to a file
+$contents = @{"aa"= 12
+ "bb"= 21}
+$contents | Export-CSV "$env:HOMEDRIVE\file.csv" # writes to a file
-# If you get confused in the pipeline use `Get-Member` for an overview
-# of the available methods and properties of the pipelined objects:
-ls | Get-Member
-Get-Date | gm
+$contents = "test string here"
+$contents | Out-File "$env:HOMEDRIVE\file.txt" # writes to another file
-# ` is the line continuation character. Or end the line with a |
-Get-Process | Sort-Object ID -Descending | Select-Object -First 10 Name,ID,VM `
- | Stop-Process -WhatIf
+# Read file contents and convert to json
+Get-Content "$env:HOMEDRIVE\file.csv" | ConvertTo-Json
-Get-EventLog Application -After (Get-Date).AddHours(-2) | Format-List
-# Use % as a shorthand for ForEach-Object
-(a,b,c) | ForEach-Object `
- -Begin { "Starting"; $counter = 0 } `
- -Process { "Processing $_"; $counter++ } `
- -End { "Finishing: $counter" }
+####################################################
+## 4. Functions
+####################################################
-# Get-Process as a table with three columns
-# The third column is the value of the VM property in MB and 2 decimal places
-# Computed columns can be written more verbose as:
-# `@{name='lbl';expression={$_}`
-ps | Format-Table ID,Name,@{n='VM(MB)';e={'{0:n2}' -f ($_.VM / 1MB)}} -autoSize
+# Use "function" to create new functions
+# Keep the Verb-Noun naming convention for functions
+function Add-Numbers {
+ $args[0] + $args[1]
+}
+Add-Numbers 1 2 # => 3
-### Functions
-# The [string] attribute is optional.
-function foo([string]$name) {
- echo "Hey $name, have a function"
+# Calling functions with parameters
+function Add-ParamNumbers {
+ param( [int]$firstNumber, [int]$secondNumber )
+ $firstNumber + $secondNumber
}
-# Calling your function
-foo "Say my name"
+Add-ParamNumbers -FirstNumber 1 -SecondNumber 2 # => 3
# Functions with named parameters, parameter attributes, parsable documentation
<#
@@ -219,112 +455,353 @@ New-Website siteName 2000 # ERROR! Port argument could not be validated
('name1','name2') | New-Website -Verbose
#>
function New-Website() {
- [CmdletBinding()]
- param (
- [Parameter(ValueFromPipeline=$true, Mandatory=$true)]
- [Alias('name')]
- [string]$siteName,
- [ValidateSet(3000,5000,8000)]
- [int]$port = 3000
- )
- BEGIN { Write-Verbose 'Creating new website(s)' }
- PROCESS { echo "name: $siteName, port: $port" }
- END { Write-Verbose 'Website(s) created' }
+ [CmdletBinding()]
+ param (
+ [Parameter(ValueFromPipeline=$true, Mandatory=$true)]
+ [Alias('name')]
+ [string]$siteName,
+ [ValidateSet(3000,5000,8000)]
+ [int]$port = 3000
+ )
+ BEGIN { Write-Output 'Creating new website(s)' }
+ PROCESS { Write-Output "name: $siteName, port: $port" }
+ END { Write-Output 'Website(s) created' }
}
-### It's all .NET
-# A PS string is in fact a .NET System.String
-# All .NET methods and properties are thus available
-'string'.ToUpper().Replace('G', 'ggg')
-# Or more powershellish
-'string'.ToUpper() -replace 'G', 'ggg'
-
-# Unsure how that .NET method is called again?
-'string' | gm
-
-# Syntax for calling static .NET methods
-[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
-
-# Note that .NET functions MUST be called with parentheses
-# while PS functions CANNOT be called with parentheses.
-# If you do call a cmdlet/PS function with parentheses,
-# it is the same as passing a single parameter list
-$writer = New-Object System.IO.StreamWriter($path, $true)
-$writer.Write([Environment]::NewLine)
-$writer.Dispose()
-
-### IO
-# Reading a value from input:
-$Name = Read-Host "What's your name?"
-echo "Hello, $Name!"
-[int]$Age = Read-Host "What's your age?"
-
-# Test-Path, Split-Path, Join-Path, Resolve-Path
-# Get-Content filename # returns a string[]
-# Set-Content, Add-Content, Clear-Content
-Get-Command ConvertTo-*,ConvertFrom-*
-
-
-### Useful stuff
-# Refresh your PATH
-$env:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") +
- ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
-
-# Find Python in path
-$env:PATH.Split(";") | Where-Object { $_ -like "*python*"}
-
-# Change working directory without having to remember previous path
-Push-Location c:\temp # change working directory to c:\temp
-Pop-Location # change back to previous working directory
-# Aliases are: pushd and popd
-
-# Unblock a directory after download
-Get-ChildItem -Recurse | Unblock-File
-
-# Open Windows Explorer in working directory
-ii .
-
-# Any key to exit
-$host.UI.RawUI.ReadKey()
-return
-
-# Create a shortcut
-$WshShell = New-Object -comObject WScript.Shell
-$Shortcut = $WshShell.CreateShortcut($link)
-$Shortcut.TargetPath = $file
-$Shortcut.WorkingDirectory = Split-Path $file
-$Shortcut.Save()
+####################################################
+## 5. Modules
+####################################################
+
+# You can import modules and install modules
+# The Install-Module is similar to pip or npm, pulls from Powershell Gallery
+Install-Module dbaTools
+Import-Module dbaTools
+
+$query = "SELECT * FROM dbo.sometable"
+$queryParams = @{
+ SqlInstance = 'testInstance'
+ Database = 'testDatabase'
+ Query = $query
+}
+Invoke-DbaQuery @queryParams
+
+# You can get specific functions from a module
+Import-Module -Function Invoke-DbaQuery
+
+
+# Powershell modules are just ordinary Posh files. You
+# can write your own, and import them. The name of the
+# module is the same as the name of the file.
+
+# You can find out which functions and attributes
+# are defined in a module.
+Get-Command -module dbaTools
+Get-Help dbaTools -Full
+
+
+####################################################
+## 6. Classes
+####################################################
+
+# We use the "class" statement to create a class
+class Instrument {
+ [string]$Type
+ [string]$Family
+}
+
+$instrument = [Instrument]::new()
+$instrument.Type = "String Instrument"
+$instrument.Family = "Plucked String"
+
+$instrument
+
+<# Output:
+Type Family
+---- ------
+String Instrument Plucked String
+#>
+
+
+####################################################
+## 6.1 Inheritance
+####################################################
+
+# Inheritance allows new child classes to be defined that inherit
+# methods and variables from their parent class.
+
+class Guitar : Instrument
+{
+ [string]$Brand
+ [string]$SubType
+ [string]$ModelType
+ [string]$ModelNumber
+}
+
+$myGuitar = [Guitar]::new()
+$myGuitar.Brand = "Taylor"
+$myGuitar.SubType = "Acoustic"
+$myGuitar.ModelType = "Presentation"
+$myGuitar.ModelNumber = "PS14ce Blackwood"
+
+$myGuitar.GetType()
+
+<#
+IsPublic IsSerial Name BaseType
+-------- -------- ---- --------
+True False Guitar Instrument
+#>
+
+
+####################################################
+## 7. Advanced
+####################################################
+
+# The powershell pipeline allows things like High-Order Functions.
+
+# Group-Object is a handy cmdlet that does incredible things.
+# It works much like a GROUP BY in SQL.
+
+<#
+ The following will get all the running processes,
+ group them by Name,
+ and tell us how many instances of each process we have running.
+ Tip: Chrome and svcHost are usually big numbers in this regard.
+#>
+Get-Process | Foreach-Object ProcessName | Group-Object
+
+# Useful pipeline examples are iteration and filtering.
+1..10 | ForEach-Object { "Loop number $PSITEM" }
+1..10 | Where-Object { $PSITEM -gt 5 } | ConvertTo-Json
+
+# A notable pitfall of the pipeline is it's performance when
+# compared with other options.
+# Additionally, raw bytes are not passed through the pipeline,
+# so passing an image causes some issues.
+# See more on that in the link at the bottom.
+
+<#
+ Asynchronous functions exist in the form of jobs.
+ Typically a procedural language,
+ Powershell can operate non-blocking functions when invoked as Jobs.
+#>
+
+# This function is known to be non-optimized, and therefore slow.
+$installedApps = Get-CimInstance -ClassName Win32_Product
+
+# If we had a script, it would hang at this func for a period of time.
+$scriptBlock = {Get-CimInstance -ClassName Win32_Product}
+Start-Job -ScriptBlock $scriptBlock
+
+# This will start a background job that runs the command.
+# You can then obtain the status of jobs and their returned results.
+$allJobs = Get-Job
+$jobResponse = Get-Job | Receive-Job
+
+
+# Math is built in to powershell and has many functions.
+$r=2
+$pi=[math]::pi
+$r2=[math]::pow( $r, 2 )
+$area = $pi*$r2
+$area
+
+# To see all possibilities, check the members.
+[System.Math] | Get-Member -Static -MemberType All
+
+
+<#
+ This is a silly one:
+ You may one day be asked to create a func that could take $start and $end
+ and reverse anything in an array within the given range
+ based on an arbitrary array without mutating the original array.
+ Let's see one way to do that and introduce another data structure.
+#>
+
+$targetArray = 'a','b','c','d','e','f','g','h','i','j','k','l','m'
+
+function Format-Range ($start, $end, $array) {
+ [System.Collections.ArrayList]$firstSectionArray = @()
+ [System.Collections.ArrayList]$secondSectionArray = @()
+ [System.Collections.Stack]$stack = @()
+ for ($index = 0; $index -lt $array.Count; $index++) {
+ if ($index -lt $start) {
+ $firstSectionArray.Add($array[$index]) > $null
+ }
+ elseif ($index -ge $start -and $index -le $end) {
+ $stack.Push($array[$index])
+ }
+ else {
+ $secondSectionArray.Add($array[$index]) > $null
+ }
+ }
+ $finalArray = $firstSectionArray + $stack.ToArray() + $secondSectionArray
+ return $finalArray
+}
+
+Format-Range 2 6 $targetArray
+# => 'a','b','g','f','e','d','c','h','i','j','k','l','m'
+
+# The previous method works, but uses extra memory by allocating new arrays.
+# It's also kind of lengthy.
+# Let's see how we can do this without allocating a new array.
+# This is slightly faster as well.
+
+function Format-Range ($start, $end) {
+ while ($start -lt $end)
+ {
+ $temp = $targetArray[$start]
+ $targetArray[$start] = $targetArray[$end]
+ $targetArray[$end] = $temp
+ $start++
+ $end--
+ }
+ return $targetArray
+}
+
+Format-Range 2 6 # => 'a','b','g','f','e','d','c','h','i','j','k','l','m'
+```
+Powershell as a Tool:
+
+Getting Help:
+
+```Powershell
+# Find commands
+Get-Command about_* # alias: gcm
+Get-Command -Verb Add
+Get-Alias ps
+Get-Alias -Definition Get-Process
+
+Get-Help ps | less # alias: help
+ps | Get-Member # alias: gm
+
+Show-Command Get-WinEvent # Display GUI to fill in the parameters
+
+Update-Help # Run as admin
```
+If you are uncertain about your environment:
-Configuring your shell
+```Powershell
+Get-ExecutionPolicy -List
+Set-ExecutionPolicy AllSigned
+# Execution policies include:
+# - Restricted: Scripts won't run.
+# - RemoteSigned: Downloaded scripts run only if signed by a trusted publisher.
+# - AllSigned: Scripts need to be signed by a trusted publisher.
+# - Unrestricted: Run all scripts.
+help about_Execution_Policies # for more info
+# Current PowerShell version:
+$PSVersionTable
```
-# $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)) {
- New-Item -Type file -Path $Profile -Force
- notepad $Profile
+
+```Powershell
+# Calling external commands, executables,
+# and functions with the call operator.
+# Exe paths with arguments passed or containing spaces can create issues.
+C:\Program Files\dotnet\dotnet.exe
+# The term 'C:\Program' is not recognized as a name of a cmdlet,
+# function, script file, or executable program.
+# Check the spelling of the name, or if a path was included,
+# verify that the path is correct and try again
+
+"C:\Program Files\dotnet\dotnet.exe"
+C:\Program Files\dotnet\dotnet.exe # returns string rather than execute
+
+&"C:\Program Files\dotnet\dotnet.exe --help" # fail
+&"C:\Program Files\dotnet\dotnet.exe" --help # success
+# Alternatively, you can use dot-sourcing here
+."C:\Program Files\dotnet\dotnet.exe" --help # success
+
+# the call operator (&) is similar to Invoke-Expression,
+# but IEX runs in current scope.
+# One usage of '&' would be to invoke a scriptblock inside of your script.
+# Notice the variables are scoped
+$i = 2
+$scriptBlock = { $i=5; Write-Output $i }
+& $scriptBlock # => 5
+$i # => 2
+
+invoke-expression ' $i=5; Write-Output $i ' # => 5
+$i # => 5
+
+# Alternatively, to preserve changes to public variables
+# you can use "Dot-Sourcing". This will run in the current scope.
+$x=1
+&{$x=2};$x # => 1
+
+.{$x=2};$x # => 2
+
+
+# Remoting into computers is easy.
+Enter-PSSession -ComputerName RemoteComputer
+
+# Once remoted in, you can run commands as if you're local.
+RemoteComputer\PS> Get-Process powershell
+
+<#
+Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
+------- ------ ----- ----- ------ -- -- -----------
+ 1096 44 156324 179068 29.92 11772 1 powershell
+ 545 25 49512 49852 25348 0 powershell
+#>
+RemoteComputer\PS> Exit-PSSession
+
+<#
+ Powershell is an incredible tool for Windows management and Automation.
+ Let's take the following scenario:
+ You have 10 servers.
+ You need to check whether a service is running on all of them.
+ You can RDP and log in, or PSSession to all of them, but why?
+ Check out the following
+#>
+
+$serverList = @(
+ 'server1',
+ 'server2',
+ 'server3',
+ 'server4',
+ 'server5',
+ 'server6',
+ 'server7',
+ 'server8',
+ 'server9',
+ 'server10'
+)
+
+[scriptblock]$script = {
+ Get-Service -DisplayName 'Task Scheduler'
+}
+
+foreach ($server in $serverList) {
+ $cmdSplat = @{
+ ComputerName = $server
+ JobName = 'checkService'
+ ScriptBlock = $script
+ AsJob = $true
+ ErrorAction = 'SilentlyContinue'
+ }
+ Invoke-Command @cmdSplat | Out-Null
}
-# More info: `help about_profiles`
-# For a more useful shell, be sure to check the project PSReadLine below
+
+<#
+ Here we've invoked jobs across many servers.
+ We can now Receive-Job and see if they're all running.
+ Now scale this up 100x as many servers :)
+#>
```
Interesting Projects
* [Channel9](https://channel9.msdn.com/Search?term=powershell%20pipeline#ch9Search&lang-en=en) PowerShell tutorials
+* [KevinMarquette's Powershell Blog](https://powershellexplained.com/) Excellent blog that goes into great detail on Powershell
* [PSGet](https://github.com/psget/psget) NuGet for PowerShell
* [PSReadLine](https://github.com/lzybkr/PSReadLine/) A bash inspired readline implementation for PowerShell (So good that it now ships with Windows10 by default!)
* [Posh-Git](https://github.com/dahlbyk/posh-git/) Fancy Git Prompt (Recommended!)
+* [Oh-My-Posh](https://github.com/JanDeDobbeleer/oh-my-posh) Shell customization similar to the popular Oh-My-Zsh on Mac
* [PSake](https://github.com/psake/psake) Build automation tool
* [Pester](https://github.com/pester/Pester) BDD Testing Framework
* [Jump-Location](https://github.com/tkellogg/Jump-Location) Powershell `cd` that reads your mind
-* [PowerShell Community Extensions](http://pscx.codeplex.com/) (Dead)
-
-Not covered
-
-* WMI: Windows Management Intrumentation (Get-CimInstance)
-* Multitasking: Start-Job -scriptBlock {...},
-* Code Signing
-* Remoting (Enter-PSSession/Exit-PSSession; Invoke-Command)
+* [PowerShell Community Extensions](https://github.com/Pscx/Pscx)
+* [More on the Powershell Pipeline Issue](https://github.com/PowerShell/PowerShell/issues/1908)
diff --git a/processing.html.markdown b/processing.html.markdown
new file mode 100644
index 00000000..777c6981
--- /dev/null
+++ b/processing.html.markdown
@@ -0,0 +1,469 @@
+---
+language: processing
+filename: learnprocessing.pde
+contributors:
+ - ["Phone Thant Ko", "http://github.com/phonethantko"]
+ - ["Divay Prakash", "https://github.com/divayprakash"]
+---
+
+## Introduction
+
+Processing is a programming language for creation of digital arts and
+multimedia content, allowing non-programmers to learn fundamentals of computer
+programming in a visual context.
+
+While the language is based on Java language, its syntax has been largely
+influenced by both Java and Javascript syntaxes. [See more here](https://processing.org/reference/)
+
+The language is statically typed, and also comes with its official IDE to
+compile and run the scripts.
+
+```
+/* ---------
+ Comments
+ ---------
+*/
+
+// Single-line comment starts with //
+
+/*
+ Since Processing is based on Java,
+ the syntax for its comments are the same as Java (as you may have noticed above)!
+ Multi-line comments are wrapped as seen here.
+*/
+
+/* ---------------------------------------
+ Writing and Running Processing Programs
+ ---------------------------------------
+*/
+
+// In Processing, the program entry point is a function named setup() with a
+// void return type.
+// Note! The syntax looks strikingly similar to that of C++.
+void setup() {
+ // This prints out the classic output "Hello World!" to the console when run.
+ println("Hello World!"); // Another language with a semi-column trap, aint it?
+}
+
+// Normally, we put all the static codes inside the setup() method as the name
+// suggest since it only runs once.
+// It can range from setting the background colours, setting the canvas size.
+background(color); // setting the background colour
+size(width,height,[renderer]); // setting the canvas size with optional
+// parameter defining renderer
+// You will see more of them throughout this document.
+
+// If you want to run the codes indefinitely, it has to be placed in draw()
+// method.
+// draw() must exist if you want the code to run continuously and obviously,
+// there can only be one draw() method.
+int i = 0;
+void draw() {
+ // This block of code loops forever until stopped
+ print(i);
+ i++; // Increment Operator!
+}
+
+// Now that we know how to write the working script and how to run it,
+// we will proceed to explore what data types and collections are supported in
+// Processing.
+
+/* ------------------------
+ Datatypes & collections
+ ------------------------
+*/
+
+// According to Processing References, Processing supports 8 primitive
+// datatypes as follows.
+
+boolean booleanValue = true; // Boolean
+byte byteValueOfA = 23; // Byte
+char charValueOfA = 'A'; // Char
+color colourValueOfWhiteM = color(255, 255, 255); // Colour (Specified using
+// color() method)
+color colourValueOfWhiteH = #FFFFFF; // Colour (Specified using hash value)
+int intValue = 5; // Integer (Number without decimals)
+long longValue = 2147483648L; // "L" is added to number to mark it as a long
+float floatValue = 1.12345; // Float (32-bit floating-point numbers)
+double doubleValue = 1.12345D; // Double (64-bit floating-point numbers)
+
+// NOTE!
+// Although datatypes "long" and "double" work in the language,
+// processing functions do not use these datatypes, therefore
+// they need to be converted into "int" and "float" datatypes respectively,
+// using (int) and (float) syntax before passing into a function.
+
+// There is a whole bunch of default composite datatypes available for use in
+// Processing.
+// Primarily, I will brief through the most commonly used ones to save time.
+
+// String
+// While char datatype uses '', String datatype uses "" - double quotes.
+String sampleString = "Hello, Processing!";
+// String can be constructed from an array of char datatypes as well. We will
+// discuss array very soon.
+char source = {'H', 'E', 'L', 'L', 'O'};
+String stringFromSource = new String(source); // HELLO
+// As in Java, strings can be concatenated using the "+" operator.
+print("Hello " + "World!"); // Hello World!
+
+// Array
+// Arrays in Processing can hold any datatypes including Objects themselves.
+// Since arrays are similar to objects, they must be created with the keyword
+// "new".
+int[] intArray = new int[5];
+int[] intArrayWithValues = {1, 2, 3}; // You can also populate with data.
+
+// ArrayList
+// Functions are similar to those of array; arraylists can hold any datatypes.
+// The only difference is arraylists resize dynamically, as it is a form of
+// resizable-array implementation of the Java "List" interface.
+ArrayList<Integer> intArrayList = new ArrayList<Integer>();
+
+// Object
+// Since it is based on Java, Processing supports object-oriented programming.
+// That means you can basically define any datatypes of your own and manipulate
+// them to your needs.
+// Of course, a class has to be defined before for the object you want.
+// Format --> ClassName InstanceName
+SomeRandomClass myObject // then instantiate later
+//or
+SomeRandomClass myObjectInstantiated = new SomeRandomClass();
+
+// Processing comes up with more collections (eg. - Dictionaries and Lists) by
+// default, for the simplicity sake, I will leave them out of discussion here.
+
+/* ------------
+ Maths
+ ------------
+*/
+
+// Arithmetic
+1 + 1 // 2
+2 - 1 // 1
+2 * 3 // 6
+3 / 2 // 1
+3.0 / 2 // 1.5
+3.0 % 2 // 1.0
+
+// Processing also comes with a set of functions that simplify mathematical
+// operations.
+float f = sq(3); // f = 9.0
+float p = pow(3, 3); // p = 27.0
+int a = abs(-13); // a = 13
+int r1 = round(3.1); // r1 = 3
+int r2 = round(3.7); // r2 = 4
+float sr = sqrt(25); // sr = 5.0
+
+// Vectors
+// Processing provides an easy way to implement vectors in its environment
+// using PVector class. It can describe a two or three dimensional vector and
+// comes with a set of methods which are useful for matrices operations.
+// You can find more information on PVector class and its functions here.
+// (https://processing.org/reference/PVector.html)
+
+// Trigonometry
+// Processing also supports trigonometric operations by supplying a set of
+// functions. sin(), cos(), tan(), asin(), acos(), atan() and also degrees()
+// and radians() for convenient conversion.
+// However, those functions take angle in radians as the parameter so it has
+// to be converted beforehand.
+float one = sin(PI/2); // one = 1.0
+// As you may have noticed, there exists a set of constants for trigonometric
+// uses;
+// PI, HALF_PI, QUARTER_PI and so on...
+
+/* -------------
+ Control Flow
+ -------------
+*/
+
+// Conditional Statements
+// If Statements - The same syntax as if statements in Java.
+if (author.getAppearance().equals("hot")) {
+ print("Narcissism at its best!");
+} else {
+ // You can check for other conditions here.
+ print("Something is really wrong here!");
+}
+// A shortcut for if-else statements can also be used.
+int i = 3;
+String value = (i > 5) ? "Big" : "Small"; // "Small"
+
+// Switch-case structure can be used to check multiple conditions concisely.
+// It is important to use the break statement. If the `break`-statement does
+// not exist the program executes all the following cases after a case was true.
+int value = 2;
+switch(value) {
+ case 0:
+ print("Nought!"); // This does not get executed.
+ break; // Jumps to the next statement
+ case 1:
+ print("Getting there..."); // This again does not get executed.
+ break;
+ case 2:
+ print("Bravo!"); // This line gets executed.
+ break;
+ default:
+ print("Not found!"); // This line gets executed if our value was some other value.
+ break;
+}
+
+// Iterative statements
+// For Statements - Again, the same syntax as in Java
+for(int i = 0; i < 5; i++){
+ print(i); // prints from 0 to 4
+}
+
+// While Statements - Again, nothing new if you are familiar with Java syntax.
+int j = 3;
+while(j > 0) {
+ print(j);
+ j--; // This is important to prevent from the code running indefinitely.
+}
+
+// loop()| noLoop() | redraw() | exit()
+// These are more of Processing-specific functions to configure program flow.
+loop(); // allows the draw() method to run forever while
+noLoop(); // only allows it to run once.
+redraw(); // runs the draw() method once more.
+exit(); // This stops the program. It is useful for programs with draw()
+// running continuously.
+```
+
+## Drawing with Processing
+
+Since you will have understood the basics of the language by now, we will now
+look into the best part of Processing - DRAWING.
+
+```
+/* ------
+ Shapes
+ ------
+*/
+
+// 2D Shapes
+
+// Point
+point(x, y); // In 2D space
+point(x, y, z); // In 3D space
+// Draws a point in the coordinate space.
+
+// Line
+line(x1, y1, x2, y2); // In 2D space
+line(x1, y1, z1, x2, y2, z2); // In 3D space
+// Draws a line connecting two points defined by (x1, y1) and (x2, y2).
+
+// Triangle
+triangle(x1, y1, x2, y2, x3, y3);
+// Draws a triangle connecting three points defined by coordinate paramters.
+
+// Rectangle
+rect(a, b, c, d, [r]); // With optional parameter defining the radius of all corners
+rect(a, b, c, d, [tl, tr, br, bl]); // With optional set of parameters defining
+// radius of each corner
+// Draws a rectangle with {a, b} as a top left coordinate and c and d as width
+// and height respectively.
+
+// Quad
+quad(x, y, x2, y2, x3, y3, x4, y4);
+// Draws a quadrilateral with parameters defining coordinates of each corner
+// point.
+
+// Ellipse
+ellipse(x, y, width, height);
+// Draws an eclipse at point {x, y} with width and height specified.
+
+// Arc
+arc(x, y, width, height, start, stop, [mode]);
+// While the first four parameters are self-explanatory,
+// start and end defined the angles the arc starts and ends (in radians).
+// Optional parameter [mode] defines the filling;
+// PIE gives pie-like outline, CHORD gives the chord-like outline and OPEN is
+// CHORD without strokes
+
+// Curves
+// Processing provides two implementation of curves; using curve() and bezier().
+// Since I plan to keep this simple I wont be discussing any further details.
+// However, if you want to implement it in your sketch, here are the references:
+// (https://processing.org/reference/curve_.html)
+// (https://processing.org/reference/bezier_.html)
+
+// 3D Shapes
+
+// 3D space can be configured by setting "P3D" to the renderer parameter in
+// size() method.
+size(width, height, P3D);
+// In 3D space, you will have to translate to the particular coordinate to
+// render the 3D shapes.
+
+// Box
+box(size); // Cube with same length defined by size
+box(w, h, d); // Box with width, height and depth separately defined
+
+// Sphere
+sphere(radius); // Its size is defined using the radius parameter
+// Mechanism behind rendering spheres is implemented by tessellating triangles.
+// That said, how much detail being rendered is controlled by function
+// sphereDetail(res)
+// More information here: (https://processing.org/reference/sphereDetail_.html)
+
+// Irregular Shapes
+// What if you wanted to draw something thats not made available by Processing
+// functions?
+// You can use beginShape(), endShape(), vertex(x,y) to define shapes by
+// specifying each point. More information here:
+// (https://processing.org/reference/beginShape_.html)
+// You can also use custom made shapes using PShape class:
+// (https://processing.org/reference/PShape.html)
+
+/* ---------------
+ Transformations
+ ---------------
+*/
+
+// Transformations are particularly useful to keep track of the coordinate
+// space and the vertices of the shapes you have drawn. Particularly;
+// matrix stack methods; pushMatrix(), popMatrix() and translate(x,y)
+pushMatrix(); // Saves the current coordinate system to the stack
+// ... apply all the transformations here ...
+popMatrix(); // Restores the saved coordinate system
+// Using them, the coordinate system can be preserved and visualized without
+// causing any conflicts.
+
+// Translate
+translate(x, y); // Translates to point{x, y} i.e. - setting origin to that point
+translate(x, y, z); // 3D counterpart of the function
+
+// Rotate
+rotate(angle); // Rotate the amount specified by the angle parameter
+// It has 3 3D counterparts to perform rotation, each for every dimension,
+// namely: rotateX(angle), rotateY(angle), rotateZ(angle)
+
+// Scale
+scale(s); // Scale the coordinate system by either expanding or contracting it.
+
+/* --------------------
+ Styling and Textures
+ --------------------
+*/
+
+// Colours
+// As I have discussed earlier, the background colour can be configured using
+// background() function. You can define a color object beforehand and then
+// pass it to the function as an argument.
+color c = color(255, 255, 255); // WHITE!
+// By default, Processing uses RGB colour scheme but it can be configured to
+// HSB using colorMode(). Read more here:
+// (https://processing.org/reference/colorMode_.html)
+background(c); // By now, the background colour should be white.
+// You can use fill() function to select the colour for filling the shapes.
+// It has to be configured before you start drawing shapes so the colours gets
+// applied.
+fill(color(0, 0, 0));
+// If you just want to colour the outlines of the shapes then you can use
+// stroke() function.
+stroke(255, 255, 0, 200); // stroke colour set to yellow with transparency
+// set to a lower value.
+
+// Images
+// Processing can render images and use them in several ways. Mostly stored as
+// PImage datatype.
+filter(shader); // Processing supports several filter functions for image manipulation.
+texture(image); // PImage can be passed into arguments for texture-mapping the shapes.
+```
+
+If you want to take things further, there are more things Processing is powered
+for. Rendering models, shaders and whatnot. There's too much to cover in a
+short documentation, so I will leave them out here. Shoud you be interested,
+please check out the references.
+
+```
+// Before we move on, I will touch a little bit more on how to import libraries
+// so you can extend Processing functionality to another horizon.
+
+/* -------
+ Imports
+ -------
+*/
+
+// The power of Processing can be further visualized when we import libraries
+// and packages into our sketches.
+// Import statement can be written as below at the top of the source code.
+import processing.something.*;
+```
+
+## DTC?
+
+Down To Code? Let's get our hands dirty!
+
+Let us see an example from openprocessing to visualize how much Processing is
+capable of within few lines of code.
+
+Copy the code below into your Processing IDE and see the magic.
+
+```
+// Disclaimer: I did not write this program since I currently am occupied with
+// internship and this sketch is adapted from openprocessing since it shows
+// something cool with simple codes.
+// Retrieved from: (https://www.openprocessing.org/sketch/559769)
+
+float theta;
+float a;
+float col;
+float num;
+
+void setup() {
+ size(600,600);
+}
+
+void draw() {
+ background(#F2F2F2);
+ translate(width/2, height/2);
+ theta = map(sin(millis()/1000.0), -1, 1, 0, PI/6);
+
+ float num=6;
+ for (int i=0; i<num; i++) {
+ a =350;
+ rotate(TWO_PI/num);
+ branch(a);
+ }
+
+}
+
+void branch(float len) {
+ col=map(len, 0, 90, 150, 255);
+ fill(col, 0, 74);
+ stroke (col, 0, 74);
+ line(0, 0, 0, -len);
+ ellipse(0, -len, 3, 3);
+ len *= 0.7;
+
+ if (len>30) {
+ pushMatrix();
+ translate(0, -30);
+ rotate(theta);
+ branch(len);
+ popMatrix();
+
+ pushMatrix();
+ translate(0, -30);
+ rotate(-theta);
+ branch(len);
+ popMatrix();
+
+ }
+}
+```
+
+Processing is easy to learn and is particularly useful to create multimedia
+contents (even in 3D) without having to type a lot of codes. It is so simple
+that you can read through the code and get a rough idea of the program flow.
+
+However, that does not apply when you introduce external libraries, packages
+and even your own classes. (Trust me! Processing projects can get real humongous...)
+
+## Some useful resources
+
+ - [Processing Website](http://processing.org)
+ - [Processing Sketches](http://openprocessing.org)
diff --git a/prolog.html.markdown b/prolog.html.markdown
new file mode 100644
index 00000000..d4c28cba
--- /dev/null
+++ b/prolog.html.markdown
@@ -0,0 +1,339 @@
+---
+language: prolog
+filename: learnprolog.pl
+contributors:
+ - ["hyphz", "http://github.com/hyphz/"]
+---
+
+Prolog is a logic programming language first specified in 1972, and refined into multiple modern implementations.
+
+```
+% This is a comment.
+
+% Prolog treats code entered in interactive mode differently
+% to code entered in a file and loaded ("consulted").
+% This code must be loaded from a file to work as intended.
+% Lines that begin with ?- can be typed in interactive mode.
+% A bunch of errors and warnings will trigger when you load this file
+% due to the examples which are supposed to fail - they can be safely
+% ignored.
+
+% Output is based on SWI-prolog 7.2.3. Different Prologs may behave
+% differently.
+
+% Prolog is based on the ideal of logic programming.
+% A subprogram (called a predicate) represents a state of the world.
+% A command (called a goal) tells Prolog to make that state of the world
+% come true, if possible.
+
+% As an example, here is a definition of the simplest kind of predicate:
+% a fact.
+
+magicNumber(7).
+magicNumber(9).
+magicNumber(42).
+
+% This introduces magicNumber as a predicate and says that it is true
+% with parameter 7, 9, or 42, but no other parameter. Note that
+% predicate names must start with lower case letters. We can now use
+% interactive mode to ask if it is true for different values:
+
+?- magicNumber(7). % True
+?- magicNumber(8). % False
+?- magicNumber(9). % True
+
+% Some older Prologs may display "Yes" and "No" instead of True and
+% False.
+
+% What makes Prolog unusual is that we can also tell Prolog to _make_
+% magicNumber true, by passing it an undefined variable. Any name
+% starting with a capital letter is a variable in Prolog.
+
+?- magicNumber(Presto). % Presto = 7 ;
+ % Presto = 9 ;
+ % Presto = 42.
+
+% Prolog makes magicNumber true by assigning one of the valid numbers to
+% the undefined variable Presto. By default it assigns the first one, 7.
+% By pressing ; in interactive mode you can reject that solution and
+% force it to assign the next one, 9. Pressing ; again forces it to try
+% the last one, 42, after which it no longer accepts input because this
+% is the last solution. You can accept an earlier solution by pressing .
+% instead of ;.
+
+% This is Prolog's central operation: unification. Unification is
+% essentially a combination of assignment and equality! It works as
+% follows:
+% If both sides are bound (ie, defined), check equality.
+% If one side is free (ie, undefined), assign to match the other side.
+% If both sides are free, the assignment is remembered. With some luck,
+% one of the two sides will eventually be bound, but this isn't
+% necessary.
+%
+% The = sign in Prolog represents unification, so:
+
+?- 2 = 3. % False - equality test
+?- X = 3. % X = 3 - assignment
+?- X = 2, X = Y. % X = Y = 2 - two assignments
+ % Note Y is assigned too, even though it is
+ % on the right hand side, because it is free
+?- X = 3, X = 2. % False
+ % First acts as assignment and binds X=3
+ % Second acts as equality because X is bound
+ % Since 3 does not equal 2, gives False
+ % Thus in Prolog variables are immutable
+?- X = 3+2. % X = 3+2 - unification can't do arithmetic
+?- X is 3+2. % X = 5 - "is" does arithmetic.
+?- 5 = X+2. % This is why = can't do arithmetic -
+ % because Prolog can't solve equations
+?- 5 is X+2. % Error. Unlike =, the right hand side of IS
+ % must always be bound, thus guaranteeing
+ % no attempt to solve an equation.
+?- X = Y, X = 2, Z is Y + 3. % X = Y, Y = 2, Z = 5.
+ % X = Y are both free, so Prolog remembers
+ % it. Therefore assigning X will also
+ % assign Y.
+
+% Any unification, and thus any predicate in Prolog, can either:
+% Succeed (return True) without changing anything,
+% because an equality-style unification was true
+% Succeed (return True) and bind one or more variables in the process,
+% because an assignment-style unification was made true
+% or Fail (return False)
+% because an equality-style unification was false
+% (Failure can never bind variables)
+
+% The ideal of being able to give any predicate as a goal and have it
+% made true is not always possible, but can be worked toward. For
+% example, Prolog has a built in predicate plus which represents
+% arithmetic addition but can reverse simple additions.
+
+?- plus(1, 2, 3). % True
+?- plus(1, 2, X). % X = 3 because 1+2 = X.
+?- plus(1, X, 3). % X = 2 because 1+X = 3.
+?- plus(X, 2, 3). % X = 1 because X+2 = 3.
+?- plus(X, 5, Y). % Error - although this could be solved,
+ % the number of solutions is infinite,
+ % which most predicates try to avoid.
+
+% When a predicate such as magicNumber can give several solutions, the
+% overall compound goal including it may have several solutions too.
+
+?- magicNumber(X), plus(X,Y,100). % X = 7, Y = 93 ;
+ % X = 9, Y = 91 ;
+ % X = 42, Y = 58 .
+% Note: on this occasion it works to pass two variables to plus because
+% only Y is free (X is bound by magicNumber).
+
+% However, if one of the goals is fully bound and thus acts as a test,
+% then solutions which fail the test are rejected.
+?- magicNumber(X), X > 40. % X = 42
+?- magicNumber(X), X > 100. % False
+
+% To see how Prolog actually handles this, let's introduce the print
+% predicate. Print always succeeds, never binds any variables, and
+% prints out its parameter as a side effect.
+
+?- print("Hello"). % "Hello" true.
+?- X = 2, print(X). % 2 true.
+?- X = 2, print(X), X = 3. % 2 false - print happens immediately when
+ % it is encountered, even though the overall
+ % compound goal fails (because 2 != 3,
+ % see the example above).
+
+% By using Print we can see what actually happens when we give a
+% compound goal including a test that sometimes fails.
+?- magicNumber(X), print(X), X > 40. % 7 9 42 X = 42 .
+
+% MagicNumber(X) unifies X with its first possibility, 7.
+% Print(X) prints out 7.
+% X > 40 tests if 7 > 40. It is not, so it fails.
+% However, Prolog remembers that magicNumber(X) offered multiple
+% solutions. So it _backtracks_ to that point in the code to try
+% the next solution, X = 9.
+% Having backtracked it must work through the compound goal
+% again from that point including the Print(X). So Print(X) prints out
+% 9.
+% X > 40 tests if 9 > 40 and fails again.
+% Prolog remembers that magicNumber(X) still has solutions and
+% backtracks. Now X = 42.
+% It works through the Print(X) again and prints 42.
+% X > 40 tests if 42 > 40 and succeeds so the result bound to X
+% The same backtracking process is used when you reject a result at
+% the interactive prompt by pressing ;, for example:
+
+?- magicNumber(X), print(X), X > 8. % 7 9 X = 9 ;
+ % 42 X = 42.
+
+% As you saw above we can define our own simple predicates as facts.
+% More complex predicates are defined as rules, like this:
+
+nearby(X,Y) :- X = Y.
+nearby(X,Y) :- Y is X+1.
+nearby(X,Y) :- Y is X-1.
+
+% nearby(X,Y) is true if Y is X plus or minus 1.
+% However this predicate could be improved. Here's why:
+
+?- nearby(2,3). % True ; False.
+% Because we have three possible definitions, Prolog sees this as 3
+% possibilities. X = Y fails, so Y is X+1 is then tried and succeeds,
+% giving the True answer. But Prolog still remembers there are more
+% possibilities for nearby() (in Prolog terminology, "it has a
+% choice point") even though "Y is X-1" is doomed to fail, and gives us
+% the option of rejecting the True answer, which doesn't make a whole
+% lot of sense.
+
+?- nearby(4, X). % X = 4 ;
+ % X = 5 ;
+ % X = 3. Great, this works
+?- nearby(X, 4). % X = 4 ;
+ % error
+% After rejecting X = 4 prolog backtracks and tries "Y is X+1" which is
+% "4 is X+1" after substitution of parameters. But as we know from above
+% "is" requires its argument to be fully instantiated and it is not, so
+% an error occurs.
+
+% One way to solve the first problem is to use a construct called the
+% cut, !, which does nothing but which cannot be backtracked past.
+
+nearbychk(X,Y) :- X = Y, !.
+nearbychk(X,Y) :- Y is X+1, !.
+nearbychk(X,Y) :- Y is X-1.
+
+% This solves the first problem:
+?- nearbychk(2,3). % True.
+
+% But unfortunately it has consequences:
+?- nearbychk(2,X). % X = 2.
+% Because Prolog cannot backtrack past the cut after X = Y, it cannot
+% try the possibilities "Y is X+1" and "Y is X-1", so it only generates
+% one solution when there should be 3.
+% However if our only interest is in checking if numbers are nearby,
+% this may be all we need, thus the name nearbychk.
+% This structure is used in Prolog itself from time to time (for example
+% in list membership).
+
+% To solve the second problem we can use built-in predicates in Prolog
+% to verify if a parameter is bound or free and adjust our calculations
+% appropriately.
+nearby2(X,Y) :- nonvar(X), X = Y.
+nearby2(X,Y) :- nonvar(X), Y is X+1.
+nearby2(X,Y) :- nonvar(X), Y is X-1.
+nearby2(X,Y) :- var(X), nonvar(Y), nearby2(Y,X).
+
+% We can combine this with a cut in the case where both variables are
+% bound, to solve both problems.
+nearby3(X,Y) :- nonvar(X), nonvar(Y), nearby2(X,Y), !.
+nearby3(X,Y) :- nearby2(X,Y).
+
+% However when writing a predicate it is not normally necessary to go to
+% these lengths to perfectly support every possible parameter
+% combination. It suffices to support parameter combinations we need to
+% use in the program. It is a good idea to document which combinations
+% are supported. In regular Prolog this is informally in structured
+% comments, but in some Prolog variants like Visual Prolog and Mercury
+% this is mandatory and checked by the compiler.
+
+% Here is the structured comment declaration for nearby3:
+
+%! nearby3(+X:Int, +Y:Int) is semideterministic.
+%! nearby3(+X:Int, -Y:Int) is multi.
+%! nearby3(-X:Int, +Y:Int) is multi.
+
+% For each variable we list a type. The + or - before the variable name
+% indicates if the parameter is bound (+) or free (-). The word after
+% "is" describes the behaviour of the predicate:
+% semideterministic - can succeed once or fail
+% ( Two specific numbers are either nearby or not )
+% multi - can succeed multiple times but cannot fail
+% ( One number surely has at least 3 nearby numbers )
+% Other possibilities are:
+% det - always succeeds exactly once (eg, print)
+% nondet - can succeed multiple times or fail.
+% In Prolog these are just structured comments and strictly informal but
+% extremely useful.
+
+% An unusual feature of Prolog is its support for atoms. Atoms are
+% essentially members of an enumerated type that are created on demand
+% whenever an unquoted non variable value is used. For example:
+character(batman). % Creates atom value batman
+character(robin). % Creates atom value robin
+character(joker). % Creates atom value joker
+character(darthVader). % Creates atom value darthVader
+?- batman = batman. % True - Once created value is reused
+?- batman = batMan. % False - atoms are case sensitive
+?- batman = darthVader. % False - atoms are distinct
+
+% Atoms are popular in examples but were created on the assumption that
+% Prolog would be used interactively by end users - they are less
+% useful for modern applications and some Prolog variants abolish them
+% completely. However they can be very useful internally.
+
+% Loops in Prolog are classically written using recursion.
+% Note that below, writeln is used instead of print because print is
+% intended for debugging.
+
+%! countTo(+X:Int) is deterministic.
+%! countUpTo(+Value:Int, +Limit:Int) is deterministic.
+countTo(X) :- countUpTo(1,X).
+countUpTo(Value, Limit) :- Value = Limit, writeln(Value), !.
+countUpTo(Value, Limit) :- Value \= Limit, writeln(Value),
+ NextValue is Value+1,
+ countUpTo(NextValue, Limit).
+
+?- countTo(10). % Outputs 1 to 10
+
+% Note the use of multiple declarations in countUpTo to create an
+% IF test. If Value = Limit fails the second declaration is run.
+% There is also a more elegant syntax.
+
+%! countUpTo2(+Value:Int, +Limit:Int) is deterministic.
+countUpTo2(Value, Limit) :- writeln(Value),
+ Value = Limit -> true ; (
+ NextValue is Value+1,
+ countUpTo2(NextValue, Limit)).
+
+?- countUpTo2(1,10). % Outputs 1 to 10
+
+% If a predicate returns multiple times it is often useful to loop
+% through all the values it returns. Older Prologs used a hideous syntax
+% called a "failure-driven loop" to do this, but newer ones use a higher
+% order function.
+
+%! countTo2(+X:Int) is deterministic.
+countTo2(X) :- forall(between(1,X,Y),writeln(Y)).
+
+?- countTo2(10). % Outputs 1 to 10
+
+% Lists are given in square brackets. Use memberchk to check membership.
+% A group is safe if it doesn't include Joker or does include Batman.
+
+%! safe(Group:list(atom)) is deterministic.
+safe(Group) :- memberchk(joker, Group) -> memberchk(batman, Group) ; true.
+
+?- safe([robin]). % True
+?- safe([joker]). % False
+?- safe([joker, batman]). % True
+
+% The member predicate works like memberchk if both arguments are bound,
+% but can accept free variables and thus can be used to loop through
+% lists.
+
+?- member(X, [1,2,3]). % X = 1 ; X = 2 ; X = 3 .
+?- forall(member(X,[1,2,3]),
+ (Y is X+1, writeln(Y))). % 2 3 4
+
+% The maplist function can be used to generate lists based on other
+% lists. Note that the output list is a free variable, causing an
+% undefined value to be passed to plus, which is then bound by
+% unification. Also notice the use of currying on the plus predicate -
+% it's a 3 argument predicate, but we specify only the first, because
+% the second and third are filled in by maplist.
+
+?- maplist(plus(1), [2,3,4], Output). % Output = [3, 4, 5].
+```
+
+##Ready For More?
+
+* [SWI-Prolog](http://www.swi-prolog.org/)
diff --git a/protocol-buffer-3.html.markdown b/protocol-buffer-3.html.markdown
new file mode 100644
index 00000000..46065536
--- /dev/null
+++ b/protocol-buffer-3.html.markdown
@@ -0,0 +1,247 @@
+---
+language: protocol-buffers
+filename: protocol-buffers.proto
+contributors:
+ - ["Shankar Shastri", "https://github.com/shankarshastri"]
+---
+# Protocol Buffers
+
+## Why Protocol Buffers
+
+Protocol buffers are Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler.
+You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.
+Protocol Buffers are Schema Of Messages. They are language agnostic.
+They can be converted to binary and converted back to message formats using the code generated by the protoc compiler for various languages.
+
+```
+/*
+* Language Syntax
+*/
+
+/*
+* Specifying Syntax Of Protocol Buffer Version
+* Specifying Which Protocol Buffer Version To Use
+* It can be usually proto3 or proto2
+*/
+syntax = "proto3";
+
+/*
+* Declaring Message In Protocol Buffer:
+* As you can see, each field in the message definition has a unique number.
+* These field numbers are used to identify your fields in the message binary format,
+* and should not be changed once your message type is in use.
+* Note that field numbers in the range 1 through 15 take one byte to encode, including the field number and the field's type (you can find out more about this in Protocol Buffer Encoding).
+* Field numbers in the range 16 through 2047 take two bytes. So you should reserve the numbers 1 through 15 for very frequently occurring message elements.
+* Remember to leave some room for frequently occurring elements that might be added in the future.
+* The smallest field number you can specify is 1, and the largest is 2^29 - 1, or 536,870,911.
+* You also cannot use the numbers 19000 through 19999 (FieldDescriptor::kFirstReservedNumber through FieldDescriptor::kLastReservedNumber),
+* as they are reserved for the Protocol Buffers implementation - the protocol buffer compiler will complain if you use one of these reserved numbers in your .proto.
+* Similarly, you cannot use any previously reserved field numbers.
+*
+*/
+
+/*
+Syntax For Declaring Message:
+ message ${MessageName} {
+ ${Scalar Value Type} ${FieldName1} = ${Tag Number1};
+ .
+ .
+ .
+ ${Scalar Value Type} ${FieldNameN} = ${Tag NumberN};
+ }
+
+Default Values Will be applied any case if the message doesn't contain a existing field defined
+in the message definition
+*/
+
+message MessageTypes {
+ /*
+ * Scalar Value Types
+ */
+ string stringType = 1; // A string must always contain UTF-8 encoded or 7-bit ASCII text. Default value = ""
+
+ // Number Types, Default Value = 0
+ int32 int32Type = 2; // Uses Variable Length Encoding. Inefficient For Negative Numbers, Instead Use sint32.
+ int64 int64Type = 3; // Uses Variable Length Encoding. Inefficient For Negative Numbers, Instead Use sint64.
+ uint32 uInt32Type = 4; // Uses Variable Length Encoding
+ uint64 uInt64Type = 5; // Uses Variable Length Encoding
+ sint32 sInt32Type = 6; // Uses Variable Length Encoding. They are efficient in encoding for negative numbers.
+ // Use this instead of int32 for negative numbers
+ sint64 sInt64Type = 7; // Uses Variable Length Encoding. They are efficient in encoding for negative numbers.
+ // Use this instead of int64 for negative numbers.
+
+ fixed32 fixed32Type = 8; // Always four bytes. More efficient than uint32 if values are often greater than 2^28.
+ fixed64 fixed64Type = 9; // Always eight bytes. More efficient than uint64 if values are often greater than 2^56
+
+ sfixed32 sfixed32Type = 10; // Always four bytes.
+ sfixed64 sfixed64Type = 11; // Always Eight bytes.
+
+ bool boolType = 12; // Boolean Type. Default Value = false
+
+ bytes bytesType = 13; // May contain any arbitrary sequence of bytes. Default Value = Empty Bytes
+
+ double doubleType = 14;
+ float floatType = 15;
+
+ enum Week {
+ UNDEFINED = 0; // Tag 0 is always used as default in case of enum
+ SUNDAY = 1;
+ MONDAY = 2;
+ TUESDAY = 3;
+ WEDNESDAY = 4;
+ THURSDAY = 5;
+ FRIDAY = 6;
+ SATURDAY = 7;
+ }
+ Week wkDayType = 16;
+
+ /*
+ * Defining Collection Of Scalar Value Type
+ * Syntax: repeated ${ScalarType} ${name} = TagValue
+ */
+ repeated string listOfString = 17; // List[String]
+}
+
+/*
+* Defining Defined Message Types In Other Message Definition
+*/
+message Person {
+ string fname = 1;
+ string sname = 2;
+}
+
+message City {
+ Person p = 1;
+}
+
+/*
+* Nested Message Definitions
+*/
+
+message NestedMessages {
+ message FirstLevelNestedMessage {
+ string firstString = 1;
+ message SecondLevelNestedMessage {
+ string secondString = 2;
+ }
+ }
+ FirstLevelNestedMessage msg = 1;
+ FirstLevelNestedMessage.SecondLevelNestedMessage msg2 = 2;
+}
+
+/*
+* Importing Message From A File
+*/
+
+// one.proto
+// message One {
+// string oneMsg = 1;
+// }
+
+// two.proto
+// import "myproject/one.proto"
+// message Two {
+// string twoMsg = 2;
+// }
+
+
+/*
+* Advanced Topics
+*/
+
+/*
+* Handling Message Type Changes:
+* Never Change/Use The TagNumber Of A Message Field Which Was Removed
+* We should use reserved in case of message definition update.
+* (https://developers.google.com/protocol-buffers/docs/proto3#updating)
+*/
+
+/*
+* Reserved Fields
+* It's used in case if we need to add/remove new fields into message.
+* Using Reserved Backward and Forward Compatibility Of Messages can be achieved
+*/
+
+
+message ReservedMessage {
+ reserved 0, 1, 2, 3 to 10; // Set Of Tag Numbers Which Can't be reused.
+ reserved "firstMsg", "secondMsg", "thirdMsg"; // Set Of Labels Which Can't Be reused.
+}
+
+/*
+* Any
+* The Any message type lets you use messages as embedded types without having their .proto definition.
+* An Any contains an arbitrary serialized message as bytes,
+* along with a URL that acts as a globally unique identifier for and resolves to that message's type.
+* For Any to work we need to import it as shown below.
+*/
+/*
+ import "google/protobuf/any.proto";
+ message AnySampleMessage {
+ repeated google.protobuf.Any.details = 1;
+ }
+
+*/
+
+
+/*
+* OneOf
+* There are cases, wherein only one field at-most might be present as part of the message.
+* Note: OneOf messages can't be repeated.
+*/
+
+message OneOfMessage {
+ oneof msg {
+ string fname = 1;
+ string sname = 2;
+ };
+}
+
+/*
+* Maps
+* Map fields cannot be repeated.
+* Ordering Of A Map Is Not Guaranteed.
+*/
+
+message MessageWithMaps {
+ map<string, string> mapOfMessages = 1;
+}
+
+
+/*
+* Packages
+* Used for preventing name clashes between protocol message types
+* Syntax:
+ package ${packageName};
+
+ To Access the package;
+ ${packageName}.${messageName} = ${tagNumber};
+*/
+
+/*
+* Services
+* Message Types Defined For Using In RPC system.
+* When protoc compiler generates for various languages it generates stub methods for the services.
+*/
+
+message SearchRequest {
+ string queryString = 1;
+}
+
+message SearchResponse {
+ string queryResponse = 1;
+}
+service SearchService {
+ rpc Search (SearchRequest) returns (SearchResponse);
+}
+```
+
+## Generating Classes In Various Languages For Protocol Buffers
+
+```shell
+protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto
+```
+
+## References
+
+[Google Protocol Buffers](https://developers.google.com/protocol-buffers/)
diff --git a/pt-br/amd.html.markdown b/pt-br/amd-pt.html.markdown
index 38c1f70f..40c7cd09 100644
--- a/pt-br/amd.html.markdown
+++ b/pt-br/amd-pt.html.markdown
@@ -141,7 +141,7 @@ require(['jquery', 'coolLibFromBower', 'modules/algunsHelpers'], function($, coo
coolLib.facaAlgoDoidoCom(helpers.transform($('#foo')));
});
```
-Apps baseados em `require.js` geralmente terão u´m único ponto de acesso (`main.js`) que é passado à tag script do `require.js` como um data-attribute. Ele vai ser automaticamente carregado e executado com o carregamento da página:
+Apps baseados em `require.js` geralmente terão um único ponto de acesso (`main.js`) que é passado à tag script do `require.js` como um data-attribute. Ele vai ser automaticamente carregado e executado com o carregamento da página:
```html
<!DOCTYPE html>
diff --git a/pt-br/asciidoc-pt.html.markdown b/pt-br/asciidoc-pt.html.markdown
index 75b3c268..b12c0693 100644
--- a/pt-br/asciidoc-pt.html.markdown
+++ b/pt-br/asciidoc-pt.html.markdown
@@ -87,10 +87,6 @@ Título de seções
===== Nível 4 <h5>
-====== Nível 5 <h6>
-
-======= Nível 6 <h7>
-
```
Listas
@@ -103,7 +99,7 @@ Para criar uma lista com marcadores use asteriscos.
* baz
```
-Para criar uma lista númerada use pontos.
+Para criar uma lista numerada use pontos.
```
. item 1
diff --git a/pt-br/asymptotic-notation-pt.html.markdown b/pt-br/asymptotic-notation-pt.html.markdown
index 2e299d09..b70d26b7 100644
--- a/pt-br/asymptotic-notation-pt.html.markdown
+++ b/pt-br/asymptotic-notation-pt.html.markdown
@@ -13,7 +13,7 @@ lang: pt-br
## O que é?
Notação Assintótica é uma linguagem que nos permite analisar o tempo de execução
- de um algoritmo através da indentificação de seu comportamento com o
+ de um algoritmo através da identificação de seu comportamento com o
crescimento da entrada oferecida. Isso também é conhecido como taxa de
crescimento do algoritmo. O algoritmo de repente torna-se lento quando o
tamanho da entrada cresce? O algoritmo mantém, em geral, seu tempo de execução
@@ -33,12 +33,12 @@ Um modo seria contar o número de operações primitivas com diferentes tamanhos
## Tipos de Notação Assintótica
-Na primeira seção desse documento, descrevemos como Notação Assintótica identifica o comportamento de um algoritmo
+Na primeira seção deste documento, descrevemos como Notação Assintótica identifica o comportamento de um algoritmo
a medida que o tamanho da entrada cresce. Imaginemos um algoritmo como uma função
*f*, *n* como o tamanho da entrada e *f(n)* sendo o tempo de execução. Então,
para dado algoritmo *f*, com entrada de tamanho *n*, você terá tempo de execução
- *f(n)*. Isto resulta em um gráfico onde a coordernada Y é o tempo de execução
-, a coordernada X representa o tamanho da entrada e os pontos representao o tempo
+ *f(n)*. Isto resulta em um gráfico onde a coordenada Y é o tempo de execução,
+ a coordenada X representa o tamanho da entrada e os pontos representam o tempo
de execução para dado tamanho de entrada.
Você pode representar a função, ou o algoritmo, com Notação Assintótica de várias
@@ -49,7 +49,7 @@ não avalia o melhor caso, porque essas condições não são atingidas com freq
Um bom exemplo disto seria em algoritmos de ordenação; especificamente, na adição
de elementos à árvores. O melhor caso na maioria de algoritmos pode ser de apenas
uma operação. Entretanto, na maioria dos casos, o elemento a ser adicionado terá
-que percorrer a árvore de forma apropriada, o que pode causar a analise de um
+que percorrer a árvore de forma apropriada, o que pode causar a análise de um
ramo inteiro.
Este é o pior caso, e isto é o que você está se preparando.
@@ -63,16 +63,16 @@ Função Polinomial - an^z + . . . + an^2 + a*n^1 + a*n^0, onde *z* é uma const
Função Exponencial - a^n, onde a é alguma constante
```
Estas são as funções básicas de crescimento usadas em várias notações. A lista
- começa com a de crescimento mais lento (logarítima, a de execução mais rápida)
+ começa com a de crescimento mais lento (logarítmica, a de execução mais rápida)
e segue para a de crescimento mais rápido (exponencial, de execução mais lenta).
-Repare que enquando *n*, a entrada, cresce, cada uma dessas funções cresce mais
-rápido que quadrático, polinimial e exponencial, comparadas com logaritma e linear.
+Repare que enquanto *n*, a entrada, cresce, cada uma dessas funções cresce mais
+rápido que quadrático, polinomial e exponencial, comparadas com logarítmica e linear.
Uma nota extremamente importante para notações é tentar usar os termos mais simples.
Isto significa descartar constantes e termos de ordem mais baixa, pois quando o
tamanho da entrada cresce para o infinito (limites matemáticos), os termos de ordem
mais baixa e constantes tornam-se irrelevantes. Por exemplo, se você tiver uma
-constante muito grande, 2^9001, a simplificação não afeterá sua notação.
+constante muito grande, 2^9001, a simplificação não afetará sua notação.
Já que queremos as formas mais simples, mudemos nossa tabela um pouco...
@@ -87,8 +87,8 @@ Função Exponencial - a^n, onde *a* é uma constante
### Big-O
Big-O, também escrita como O, é uma Notação Assintótica para o pior caso. Digamos
-*f(n)* seja o tempo de exeução de um algoritmo e *g(n)) um tempo de complexidade
-arbritário que você quer relacionar com seu algoritmo. *f(n)* é O(g(n)), se, para
+*f(n)* seja o tempo de execução de um algoritmo e *g(n)) um tempo de complexidade
+arbitrário que você quer relacionar com seu algoritmo. *f(n)* é O(g(n)), se, para
quando constante real c (c > 0), *f(n)* <= *c g(n)* para todo tamanho de entrada
n (n > 0).
@@ -116,7 +116,7 @@ Há alguma constante c que satisfaça a definição para todo n?
3log n + 100 <= 150 * log n, n > 2 (Indefinido em n = 1)
```
-Sim! A definição de Big-I for atentida, portante `f(n)` é `O(g(n))`.
+Sim! A definição de Big-O foi atendida, portanto `f(n)` é `O(g(n))`.
*Exemplo 2*
@@ -146,7 +146,7 @@ Big-Omega, também escrita como Ω, é uma Notação Assintótica para o melhor
Sinta-se livre para adicionar mais exemplos. Big-O é a notação primária usada para medir complexidade de algoritmos.
### Notas Finais
-É difícil manter esse tipo de tópico curto e você deveria ler os livros e artigos listados abaixo. Eles cobrem muito mais profundamente definições e exemplos. Mais x='Algoritms & Data Structures' virá; teremos um documento sobre analisar código em breve.
+É difícil manter esse tipo de tópico curto e você deveria ler os livros e artigos listados abaixo. Eles cobrem muito mais profundamente definições e exemplos. Mais x='Algorithms & Data Structures' virá; teremos um documento sobre analisar código em breve.
## Livros
diff --git a/pt-br/asymptoticnotation-pt.html.markdown b/pt-br/asymptoticnotation-pt.html.markdown
deleted file mode 100644
index c5299a11..00000000
--- a/pt-br/asymptoticnotation-pt.html.markdown
+++ /dev/null
@@ -1,161 +0,0 @@
----
-category: Algorithms & Data Structures
-name: Asymptotic Notation
-contributors:
- - ["Jake Prather", "http://github.com/JakeHP"]
-translators:
- - ["Carolina Knoll", "http://github.com/carolinaknoll"]
-lang: pt-br
----
-
-# Aprenda X em Y minutos
-## Onde X=Notação Assintótica
-
-# Notações Assintóticas
-## O que são?
-
-Notações assintóticas são notações matemáticas que nos permitem analisar tempo de execução
-de um algoritmo, identificando o seu comportamento de acordo como o tamanho de entrada para
-o algoritmo aumenta. Também é conhecido como taxa de "crescimento" de um algoritmo. O algoritmo
-simplesmente se torna incrivelmente lento conforme o seu tamanho aumenta? Será que pode-se na
-maior parte manter o seu tempo de execução rápido mesmo quando o tamanho de entrada aumenta?
-A notação assintótica nos dá a capacidade de responder a essas perguntas.
-
-## Além desta, existem outras alternativas para responder a essas perguntas?
-
-Uma forma seria a de contar o número de operações primitivas em diferentes tamanhos de entrada.
-Embora esta seja uma solução válida, a quantidade de trabalho necessário, mesmo para algoritmos
-simples, não justifica a sua utilização.
-
-Outra maneira é a de medir fisicamente a quantidade de tempo que leva para se executar um algoritmo
-de diferentes tamanhos. No entanto, a precisão e a relatividade (já que tempos obtidos só teriam
-relação à máquina em que eles foram testados) deste método estão ligadas a variáveis ambientais,
-tais como especificações de hardware, poder de processamento, etc.
-
-## Tipos de Notação Assintótica
-
-Na primeira seção deste documento nós descrevemos como uma notação assintótica identifica o comportamento
-de um algoritmo como as alterações de tamanho de entrada (input). Imaginemos um algoritmo como uma função
-f, n como o tamanho da entrada, e f (n) sendo o tempo de execução. Assim, para um determinado algoritmo f,
-com tamanho de entrada n você obtenha algum tempo de execução resultante f (n). Isto resulta num gráfico,
-em que o eixo Y representa o tempo de execução, o eixo X é o tamanho da entrada, e os pontos marcados são
-os resultantes da quantidade de tempo para um dado tamanho de entrada.
-
-Pode-se rotular uma função ou algoritmo com uma notação assintótica de diversas maneiras diferentes.
-Dentre seus exemplos, está descrever um algoritmo pelo seu melhor caso, pior caso, ou caso equivalente.
-O mais comum é o de analisar um algoritmo pelo seu pior caso. Isso porque você normalmente não avaliaria
-pelo melhor caso, já que essas condições não são as que você está planejando. Um bom exemplo disto é o de
-algoritmos de ordenação; especificamente, a adição de elementos a uma estrutura de tipo árvore. O melhor
-caso para a maioria dos algoritmos pode ser tão simples como uma única operação. No entanto, na maioria
-dos casos, o elemento que você está adicionando terá de ser ordenado de forma adequada através da árvore,
-o que poderia significar a análise de um ramo inteiro. Este é o pior caso, e é por ele que precisamos seguir.
-
-### Tipos de funções, limites, e simplificação
-
-```
-Função Logaritmica - log n
-Função Linear - an + b
-Função Quadrática - an^2 + bn + c
-Função Polinomial - an^z + . . . + an^2 + a*n^1 + a*n^0, onde z é uma constante
-Função Exponencial - a^n, onde a é uma constante
-```
-
-Estas são algumas classificações básicas de crescimento de função usados em várias notações. A lista
-começa com a função crescimento mais lento (logarítmica, com tempo de execução mais rápido) e vai até
-a mais rápida (exponencial, com tempo de execução mais lento). Observe que 'n', ou nossa entrada,
-cresce em cada uma dessas funções, e o resultado claramente aumenta muito mais rapidamente em função
-quadrática, polinomial e exponencial, em comparação com a logarítmica e a linear.
-
-Uma observação de boa importância é que, para as notações a serem discutidas, deve-se fazer o melhor
-para utilizar termos mais simples. Isto significa desrespeitar constantes, e simplificar termos de
-ordem, porque, como o tamanho da entrada (ou n no nosso f (n) exemplo) aumenta infinitamente (limites
-matemáticos), os termos em ordens mais baixas e constantes são de pouca ou nenhuma importância. Dito
-isto, se você possui constantes com valor 2^9001, ou alguma outra quantidade ridícula, inimaginável,
-perceberá que a simplificação distorcerá a precisão de sua notação.
-
-Já que nós queremos a forma mais simples, vamos modificar nossas funções um pouco.
-
-```
-Logaritmica - log n
-Linear - n
-Quadrática - n^2
-Polinomial - n^z, onde z é uma constante
-Exponencial - a^n, onde a é uma constante
-```
-
-### O Grande-O
-
-Grande-O, geralmente escrita como O, é uma Notação Assintótica para o pior caso para uma dada função. Digamos
-que `f(n)` é o tempo de execução de seu algoritmo, e `g(n)` é uma complexidade de tempo arbitrário que você está
-tentando se relacionar com o seu algoritmo. `f(n)` será O(g(n)), se, por qualquer constante real c (c > 0),
-`f(n)` <= `c g(n)` para cada tamanho de entrada n (n > 0).
-
-*Exemplo 1*
-
-```
-f(n) = 3log n + 100
-g(n) = log n
-```
-
-É `f(n)` um O(g(n))?
-É 3 `log n + 100` igual a O(log n)?
-Vamos checar na definição de Grande-O.
-
-```
-3log n + 100 <= c * log n
-```
-
-Existe alguma constante c que satisfaça isso para todo n?
-
-```
-3log n + 100 <= 150 * log n, n > 2 (indefinido em n = 1)
-```
-
-Sim! A definição de Grande-O foi satisfeita. Sendo assim, `f(n)` é O(g(n)).
-
-*Exemplo 2*
-
-```
-f(n) = 3 * n^2
-g(n) = n
-```
-
-É `f(n)` um O(g(n))?
-É `3 * n^2` um O(n)?
-Vamos ver na definição de Grande-O.
-
-```
-3 * n^2 <= c * n
-```
-
-Existe alguma constante que satisfaça isso para todo n?
-Não, não existe. `f(n)` NÃO É O(g(n)).
-
-### Grande-Omega
-
-Grande-Omega, comumente escrito como Ω, é uma Notação Assintótica para o melhor caso, ou
-uma taxa de crescimento padrão para uma determinada função.
-
-`f(n)` é Ω(g(n)), se, por qualquer constante c real (c > 0), `f(n)` é >= `c g(n)` para cada
-tamanho de entrada n (n > 0).
-
-Sinta-se livre para pesquisar recursos adicionais e obter mais exemplos sobre este assunto!
-Grande-O é a notação primária utilizada para tempo de execução de algoritmos, de modo geral.
-
-### Notas de Finalização
-
-É complicado exibir este tipo de assunto de forma tão curta, então é definitivamente recomendado
-pesquisar além dos livros e recursos on-line listados. Eles serão capazes de analisar o assunto com
-uma profundidade muito maior, além de ter definições e exemplos. Mais sobre onde X="Algoritmos e
-Estruturas de Dados" está a caminho: Haverá conteúdo focado na análise de exemplos de códigos reais
-em breve.
-
-## Livros
-
-* [Algorithms] (http://www.amazon.com/Algorithms-4th-Robert-Sedgewick/dp/032157351X)
-* [Algorithm Design] (http://www.amazon.com/Algorithm-Design-Foundations-Analysis-Internet/dp/0471383651)
-
-## Recursos Online
-
-* [MIT] (http://web.mit.edu/16.070/www/lecture/big_o.pdf)
-* [KhanAcademy] (https://www.khanacademy.org/computing/computer-science/algorithms/asymptotic-notation/a/asymptotic-notation)
diff --git a/pt-br/awk-pt.html.markdown b/pt-br/awk-pt.html.markdown
new file mode 100644
index 00000000..70d0a01c
--- /dev/null
+++ b/pt-br/awk-pt.html.markdown
@@ -0,0 +1,377 @@
+---
+category: tool
+tool: awk
+filename: learnawk-pt.awk
+contributors:
+ - ["Marshall Mason", "http://github.com/marshallmason"]
+translators:
+ - ["Paulo Henrique Rodrigues Pinheiro", "https://github.com/paulohrpinheiro"]
+lang: pt-br
+
+---
+
+AWK é uma ferramenta padrão em todos os sistemas UNIX compatíveis com POSIX. É
+como um Perl despojado, perfeito para tarefas de processamento de texto e
+outras tarefas de script. Possui uma sintaxe C-like, mas sem ponto e vírgula,
+gerenciamento manual de memória, ou tipagem estática. Destaca-se no
+processamento de texto. Você pode chamá-lo a partir de um shell-script, ou você
+pode usá-lo como uma linguagem de script autônomo.
+
+Por que usar AWK ao invés de Perl? Principalmente porque AWK faz parte do UNIX.
+Você pode sempre contar com ele, enquanto o futuro do Perl é indefinido. AWK é
+também mais fácil de ler que Perl. Para scripts simples de processamento de
+texto, particularmente aqueles que leem arquivos linha por linha e fatiam texto
+por delimitadores, AWK é provavelmente a ferramenta certa para a tarefa.
+
+```awk
+#!/usr/bin/awk -f
+
+# Comentários são assim
+
+# Programas AWK consistem de uma coleção de padrões e ações. O mais
+# importante padrão é chamado BEGIN. Ações estão dentro de blocos
+# entre chaves.
+
+BEGIN {
+
+ # O bloco BEGIN será executado no começo do programa. É onde você coloca
+ # todo código que prepara a execução, antes que você processe qualquer
+ # arquivo de texto. Se você não tem arquivos de texto, então pense no
+ # BEGIN como o ponto principal de entrada.
+
+ # Variáveis são globais. Simplesmente atribua valores ou as use, sem
+ # necessidade de declarar.
+
+ # Operadores são como em C e similares
+ a = count + 1
+ b = count - 1
+ c = count * 1
+ d = count / 1 # divisão inteira
+ e = count % 1 # módulo
+ f = count ^ 1 # exponenciação
+
+ a += 1
+ b -= 1
+ c *= 1
+ d /= 1
+ e %= 1
+ f ^= 1
+
+ # Incrementando e decrementando por um
+ a++
+ b--
+
+ # Como um operador pré-fixado, retorna o valor incrementado
+ ++a
+ --b
+
+ # Perceba, não há pontuação, como ponto-e-vírgula, ao final das declarações
+
+ # Declarações de controle
+ if (count == 0)
+ print "Começando com count em 0"
+ else
+ print "Como é que é?"
+
+ # Ou você pode usar o operador ternário
+ print (count == 0) ? "Começando com count em 0" : "Como é que é?"
+
+ # Blocos multilinhas devem usar chaves
+ while (a < 10) {
+ print "Concatenação de texto é feita" " com uma série" " de"
+ " textos separados por espaço"
+ print a
+
+ a++
+ }
+
+ for (i = 0; i < 10; i++)
+ print "Uma boa opção para um loop de uma linha"
+
+ # Quanto a comparações, eis os padrões:
+ a < b # Menor que
+ a <= b # Menor ou igual a
+ a != b # Não igual
+ a == b # Igual
+ a > b # Maior que
+ a >= b # Maior ou igual a
+
+ # Bem como operadores lógicos
+ a && b # E
+ a || b # OU (inclusivo)
+
+ # Em adição, há o utilíssimo operador para expressões regulares
+ if ("foo" ~ "^fo+$")
+ print "Fooey!"
+ if ("boo" !~ "^fo+$")
+ print "Boo!"
+
+ # Matrizes
+ arr[0] = "foo"
+ arr[1] = "bar"
+ # Infelizmente, não há outra forma para inicializar uma matriz. Apenas
+ # coloque cada valor em uma linha, como mostrado acima.
+
+ # Você também pode ter matrizes associativas
+ assoc["foo"] = "bar"
+ assoc["bar"] = "baz"
+
+ # E matrizes multidimensionais, com algumas limitações que não mencionarei
+ multidim[0,0] = "foo"
+ multidim[0,1] = "bar"
+ multidim[1,0] = "baz"
+ multidim[1,1] = "boo"
+
+ # Você pode testar a pertinência de um elemento em uma matriz
+ if ("foo" in assoc)
+ print "Fooey!"
+
+ # Você pode também usar o operador 'in' para percorrer as chaves de uma
+ # matriz associativa
+ for (key in assoc)
+ print assoc[key]
+
+ # Os argumentos da linha de comando estão em uma matriz especial ARGV
+ for (argnum in ARGV)
+ print ARGV[argnum]
+
+ # Você pode remover elementos de uma matriz
+ # Isso é muito útil para prevenir que o AWK assuma que os argumentos são
+ # arquivo para ele processar
+ delete ARGV[1]
+
+ # A quantidade de argumentos passados está na variável ARGC
+ print ARGC
+
+ # O AWK tem várias funções nativas. Elas estão separadas em três categorias.
+ # Demonstrarei cada uma delas logo mais abaixo.
+
+ return_value = arithmetic_functions(a, b, c)
+ string_functions()
+ io_functions()
+}
+
+# Eis como você deve definir uma função
+function arithmetic_functions(a, b, c, d) {
+
+ # Provavelmente a parte mais irritante do AWK é ele não possuir variáveis
+ # locais. Tudo é global. Para pequenos scripts, isso não é problema, e
+ # pode até mesmo ser considerado útil, mas para grandes scripts, isso pode
+ # ser um problema.
+
+ # Mas há como contornar isso (um hack). Os argumentos de função são locais
+ # para a função e o AWK permite que você defina mais argumentos de função
+ # do que ele precise. Então, coloque a variável local na declaração de
+ # função, como eu fiz acima. Como uma convenção, adicione alguns espaços
+ # extras para distinguir entre parâmetros de função reais e variáveis
+ # locais. Neste exemplo, a, b e c são parâmetros reais, enquanto d é
+ # meramente uma variável local.
+
+ # Agora, serão demonstradas as funções aritméticas
+
+ # Muitas implementações AWK possuem algumas funções trigonométricas padrão
+ localvar = sin(a)
+ localvar = cos(a)
+ localvar = atan2(b, a) # arco-tangente de b / a
+
+ # E conteúdo logarítmico
+ localvar = exp(a)
+ localvar = log(a)
+
+ # Raiz quadrada
+ localvar = sqrt(a)
+
+ # Descartando a parte não inteira de um número em ponto flutuante.
+ localvar = int(5.34) # localvar => 5
+
+ # Números aleatórios
+ srand() # Forneça uma semente como argumento. Por padrão, ele usa a hora atual
+ localvar = rand() # Número aleatório entre 0 e 1.
+
+ # Aqui mostramos como retornar um valor
+ return localvar
+}
+
+function string_functions( localvar, arr) {
+
+ # Sendo o AWK uma linguagem para processamento de texto, ele possui
+ # várias funções para manipulação de texto, muitas das quais
+ # fortemente dependentes de expressões regulares.
+
+ # Procurar e substituir, primeira instância (sub), ou todas (gsub)
+ # Ambas retornam o número de instâncias substituídas
+ localvar = "fooooobar"
+ sub("fo+", "Meet me at the ", localvar) # localvar => "Meet me at the bar"
+ gsub("e+", ".", localvar) # localvar => "m..t m. at th. bar"
+
+ # Localiza um texto que casa com uma expressão regular
+ # index() faz a mesma coisa, mas não permite uma expressão regular
+ match(localvar, "t") # => 4, pois 't' é o quarto carácter
+
+ # Separa por delimitador
+ split("foo-bar-baz", arr, "-") # a => ["foo", "bar", "baz"]
+
+ # Outras coisas úteis
+ sprintf("%s %d %d %d", "Testing", 1, 2, 3) # => "Testing 1 2 3"
+ substr("foobar", 2, 3) # => "oob"
+ substr("foobar", 4) # => "bar"
+ length("foo") # => 3
+ tolower("FOO") # => "foo"
+ toupper("foo") # => "FOO"
+}
+
+function io_functions( localvar) {
+
+ # Você já viu como imprimir
+ print "Hello world"
+
+ # Também há o printf
+ printf("%s %d %d %d\n", "Testing", 1, 2, 3)
+
+ # O AWK não disponibiliza manipuladores de arquivo. Ele irá automaticamente
+ # manipular um arquivo quando você fizer algo que precise disso. O texto
+ # que você usou para isso pode ser usado como um manipulador de arquivo,
+ # para propósitos de E/S. Isso faz ele parecer com um shell script:
+
+ print "foobar" >"/tmp/foobar.txt"
+
+ # Agora a string "/tmp/foobar.txt" é um manipulador de arquivos. Você pode
+ # fechá-lo:
+ close("/tmp/foobar.txt")
+
+ # Aqui está como você pode executar alguma coisa no shell
+ system("echo foobar") # => prints foobar
+
+ # Lê uma linha da entrada padrão e armazena em localvar
+ getline localvar
+
+ # Lê uma linha de um pipe
+ "echo foobar" | getline localvar # localvar => "foobar"
+ close("echo foobar")
+
+ # Lê uma linha de um arquivo e armazena em localvar
+ getline localvar <"/tmp/foobar.txt"
+ close("/tmp/foobar.txt")
+}
+
+# Como dito no início, os programas AWK consistem de uma coleção de padrões
+# e ações. Você já viu o padrão BEGIN, o mais importante. Outros padrões são
+# usados apenas se você estiver processando linhas de arquivos ou a entrada
+# padrão.
+
+# Quando você passa argumentos para o AWK, eles são tratados como nomes de
+# arquivos para processar. Todos serão processados, em ordem. Pense nisso como
+# um implícito para loop, iterando sobre as linhas nesses arquivos. Esses
+# padrões e ações são como instruções de mudança dentro do loop.
+
+/^fo+bar$/ {
+
+ # Esta ação será executada para cada linha que corresponda à expressão
+ # regular, / ^ fo + bar $ /, e será ignorada para qualquer linha que não
+ # corresponda. Vamos apenas imprimir a linha:
+
+ print
+
+ # Opa, sem argumento! Isso ocorre pois print tem um argumento padrão: $0.
+ # $0 é o nome da linha atual que está sendo processada. Essa variável é
+ # criada automaticamente para você.
+
+ # Você provavelmente pode adivinhar que existem outras variáveis $. Toda
+ # linha é implicitamente dividida antes de cada ação ser chamada, como
+ # o shell faz. E, como o shell, cada campo pode ser acessado com um sinal
+ # de cifrão
+
+ # Isso irá imprimir o segundo e quarto campos da linha
+ print $2, $4
+
+ # O AWK automaticamente define muitas outras variáveis para ajudar você
+ # a inspecionar processar cada linha. A mais importante delas é NF.
+
+ # Imprime o número de campos da linha atual
+ print NF
+
+ # Imprime o último campo da linha atual
+ print $NF
+}
+
+# Todo padrão é na verdade um teste verdadeiro/falso. A expressão regular no
+# último padrão também é um teste verdadeiro/falso, mas parte dele estava
+# escondido. Se você não informar um texto para testar, AWK assumirá $0,
+# a linha que está atualmente sendo processada. Assim, a versão completa
+# é a seguinte:
+
+$0 ~ /^fo+bar$/ {
+ print "Equivalente ao último padrão"
+}
+
+a > 0 {
+ # Isso será executado uma vez para cada linha, quando a for positivo
+}
+
+# Você entendeu. Processar arquivos de texto, ler uma linha de cada vez, e
+# fazer algo com ela, particularmente dividir com base em um delimitador, é
+# tão comum no UNIX que AWK é uma linguagem de script que faz tudo por você,
+# sem você precisa perguntar. Tudo o que você precisa fazer é escrever os
+# padrões e ações com base no que você espera da entrada, e o que você quer
+# fazer com isso.
+
+# Aqui está um exemplo rápido de um script simples, o tipo de coisa que o AWK
+# é perfeito para fazer. Ele irá ler um nome da entrada padrão e depois
+# imprimirá a média de idade de todos com esse primeiro nome. Digamos que você
+# forneça como argumento o nome de um arquivo com esses dados:
+
+# Bob Jones 32
+# Jane Doe 22
+# Steve Stevens 83
+# Bob Smith 29
+# Bob Barker 72
+#
+# Eis o script:
+
+BEGIN {
+
+ # Primeiro, pergunte o nome do usuário
+ print "Para qual nome você quer calcular a média de idade?"
+
+ # Pega uma linha da entrada padrão, não dos arquivos indicados na
+ # linha de comando
+ getline name <"/dev/stdin"
+}
+
+# Agora, processa cada linha em que o primeiro nome é o nome informado
+$1 == name {
+
+ # Dentro desse bloco, nós temos acesso a algumas variáveis uteis, que
+ # foram pré-carregadas para nós:
+ # $0 é a linha corrente completa
+ # $3 é o terceiro campo, que é o que nos interessa aqui
+ # NF é a quantidade de campos, que deve ser 3
+ # NR é o número de registros (linhas) lidas até agora
+ # FILENAME é o nome do arquivo sendo processado
+ # FS é o delimitador em uso, que é " " aqui
+ # ...etc. Há muito mais, documentadas no manual.
+
+ # Mantenha um registro do total e da quantidade de linhas encontradas
+ sum += $3
+ nlines++
+}
+
+# Outro padrão especial é chamado END. Ele será executado após o processamento
+# de todos os arquivos de texto. Ao contrário de BEGIN, ele só será executado
+# se você tiver dado a ele dados para processar. Ele será executado depois de
+# todos os arquivos terem sido lidos e processados de acordo com as regras e
+# ações que você forneceu. O objetivo disso em geral é produzir algum tipo de
+# relatório final, ou fazer algo com o agregado dos dados acumulados ao longo
+# do script.
+
+END {
+ if (nlines)
+ print "A média da idade para " name " é " sum / nlines
+}
+
+```
+Leituras adicionais (em inglês):
+
+* [Awk tutorial](http://www.grymoire.com/Unix/Awk.html)
+* [Awk man page](https://linux.die.net/man/1/awk)
+* [The GNU Awk User's Guide](https://www.gnu.org/software/gawk/manual/gawk.html) GNU AWK é encontrado na maioria dos sistemas GNU/Linux.
diff --git a/pt-br/bash-pt.html.markdown b/pt-br/bash-pt.html.markdown
index ae18435a..988e8e7d 100644
--- a/pt-br/bash-pt.html.markdown
+++ b/pt-br/bash-pt.html.markdown
@@ -16,7 +16,7 @@ lang: pt-br
Tutorial de shell em português
-Bash é o nome do shell do Unix, que também é distribuido como shell do sistema
+Bash é o nome do shell do Unix, que também é distribuído como shell do sistema
operacional GNU e como shell padrão para Linux e Mac OS X. Praticamente todos
os exemplos abaixo podem fazer parte de um shell script e pode ser executados
diretamente no shell.
@@ -33,7 +33,7 @@ diretamente no shell.
# Exemplo simples de hello world:
echo Hello World!
-# Cada comando começa com uma nova linha, ou após um ponto virgula:
+# Cada comando começa com uma nova linha, ou após um ponto e vírgula:
echo 'Essa é a primeira linha'; echo 'Essa é a segunda linha'
# A declaração de variáveis é mais ou menos assim
@@ -41,14 +41,14 @@ Variavel="Alguma string"
# Mas não assim:
Variavel = "Alguma string"
-# Bash interpretará Variavel como um comando e tentará executar e lhe retornar
+# Bash interpretará Variavel como um comando e tentará executar e lhe retornará
# um erro porque o comando não pode ser encontrado.
# Ou assim:
Variavel= 'Alguma string'
-# Bash interpretará 'Alguma string' como um comando e tentará executar e lhe retornar
-# um erro porque o comando não pode ser encontrado. (Nesse caso a a parte 'Variavel='
-# é vista com uma declaração de variável valida apenas para o escopo do comando 'Uma string').
+# Bash interpretará 'Alguma string' como um comando e tentará executar e lhe retornará
+# um erro porque o comando não pôde ser encontrado. (Nesse caso a a parte 'Variavel='
+# é vista com uma declaração de variável válida apenas para o escopo do comando 'Uma string').
# Usando a variável:
echo $Variavel
@@ -65,15 +65,15 @@ echo ${Variavel/Alguma/Uma}
# Substring de uma variável
Tamanho=7
echo ${Variavel:0:Tamanho}
-# Isso retornará apenas os 7 primeiros caractéres da variável
+# Isso retornará apenas os 7 primeiros caracteres da variável
# Valor padrão de uma variável
echo ${Foo:-"ValorPadraoSeFooNaoExistirOuEstiverVazia"}
# Isso funciona para nulo (Foo=) e (Foo=""); zero (Foo=0) retorna 0.
-# Note que isso apenas retornar o valor padrão e não mudar o valor da variável.
+# Note que isso apenas retornará o valor padrão e não mudará o valor da variável.
# Variáveis internas
-# Tem algumas variáveis internas bem uteis, como
+# Tem algumas variáveis internas bem úteis, como
echo "O ultimo retorno do programa: $?"
echo "PID do script: $$"
echo "Numero de argumentos passados para o script $#"
@@ -86,7 +86,7 @@ read Nome # Note que nós não precisamos declarar a variável
echo Ola, $Nome
# Nós temos a estrutura if normal:
-# use 'man test' para mais infomações para as condicionais
+# use 'man test' para mais informações para as condicionais
if [ $Nome -ne $USER ]
then
echo "Seu nome não é o seu username"
@@ -109,7 +109,7 @@ then
echo "Isso vai rodar se $Nome é Daniela ou Jose."
fi
-# Expressões são denotadas com o seguinte formato
+# Expressões são escritas com o seguinte formato
echo $(( 10 + 5))
# Diferentemente das outras linguagens de programação, bash é um shell, então ele
@@ -118,9 +118,9 @@ echo $(( 10 + 5))
ls
#Esse comando tem opções que controlam sua execução
-ls -l # Lista todo arquivo e diretorio em linhas separadas
+ls -l # Lista todo arquivo e diretório em linhas separadas
-# Os resultados do comando anterior pode ser passado para outro comando como input.
+# Os resultados do comando anterior podem ser passados para outro comando como input.
# O comando grep filtra o input com o padrão passado. É assim que listamos apenas
# os arquivos .txt no diretório atual:
ls -l | grep "\.txt"
@@ -165,7 +165,7 @@ echo "#helloworld" | tee output.out > /dev/null
rm -v output.out error.err output-and-error.log
# Comando podem ser substituídos por outros comandos usando $( ):
-# O comando a seguir mostra o número de arquivos e diretórios no diretorio atual
+# O comando a seguir mostra o número de arquivos e diretórios no diretório atual
echo "Existem $(ls | wc -l) itens aqui."
# O mesmo pode ser feito usando crase `` mas elas não podem ser aninhadas - dá se
@@ -241,14 +241,14 @@ head -n 10 arquivo.txt
sort arquivo.txt
# reporta ou omite as linhas repetidas, com -d você as reporta
uniq -d arquivo.txt
-# exibe apenas a primeira coluna após o caráctere ','
+# exibe apenas a primeira coluna após o caractere ','
cut -d ',' -f 1 arquivo.txt
# substitui todas as ocorrencias de 'okay' por 'legal' em arquivo.txt (é compativel com regex)
sed -i 's/okay/legal/g' file.txt
# exibe para o stdout todas as linhas do arquivo.txt que encaixam com o regex
# O exemplo exibe linhas que começam com "foo" e terminam com "bar"
grep "^foo.*bar$" arquivo.txt
-# passe a opção "-c" para ao invês de imprimir o numero da linha que bate com o regex
+# passe a opção "-c" para ao invés de imprimir o número da linha que bate com o regex
grep -c "^foo.*bar$" arquivo.txt
# se você quer literalmente procurar por uma string,
# e não pelo regex, use fgrep (ou grep -F)
diff --git a/pt-br/bf.html.markdown b/pt-br/bf-pt.html.markdown
index d6d7c6e9..53baa9a2 100644
--- a/pt-br/bf.html.markdown
+++ b/pt-br/bf-pt.html.markdown
@@ -1,5 +1,6 @@
---
language: bf
+filename: learnbf-pt.bf
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
@@ -12,7 +13,9 @@ lang: pt-br
Brainfuck (em letras minúsculas, exceto no início de frases) é uma linguagem de
programação Turing-completa extremamente simples com apenas 8 comandos.
-```
+Você pode experimentar brainfuck pelo seu browser com [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/).
+
+```bf
Qualquer caractere exceto "><+-.,[]" (sem contar as aspas) é ignorado.
Brainfuck é representado por um vetor com 30 000 células inicializadas em zero
diff --git a/pt-br/c++-pt.html.markdown b/pt-br/c++-pt.html.markdown
index e2e95268..42a29991 100644
--- a/pt-br/c++-pt.html.markdown
+++ b/pt-br/c++-pt.html.markdown
@@ -1,6 +1,6 @@
---
language: c++
-filename: learncpp.cpp
+filename: learncpp-pt.cpp
contributors:
- ["Steven Basart", "http://github.com/xksteven"]
- ["Matt Kline", "https://github.com/mrkline"]
@@ -18,10 +18,10 @@ foi concebida para
- suportar programação orientada a objetos
- 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
+Embora sua sintaxe possa ser mais difícil ou complexa do que as linguagens mais
+recentes, C++ é amplamente utilizada porque compila para instruções nativas que
+podem ser executadas diretamente pelo processador e oferece um controle rígido sobre o 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,17 +33,17 @@ 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.
int main(int argc, char** argv)
{
- // Argumentos de linha de comando são passados em pelo argc e argv da mesma
+ // Argumentos de linha de comando são passados para argc e argv da mesma
// forma que eles estão em C.
// argc indica o número de argumentos,
- // e argv é um array de strings, feito C (char*) representado os argumentos
+ // e argv é um array de strings, feito C (char*) representando os argumentos
// O primeiro argumento é o nome pelo qual o programa foi chamado.
// argc e argv pode ser omitido se você não se importa com argumentos,
// dando a assinatura da função de int main()
@@ -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 objeto 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)
@@ -564,15 +564,15 @@ void doSomethingWithAFile(const std::string& filename)
// Isto tem _grandes_ vantagens:
// 1. Não importa o que aconteça,
-// o recurso (neste caso, o identificador de ficheiro) irá ser limpo.
+// o recurso (neste caso, o identificador de ficheiro) será limpo.
// Depois de escrever o destruidor corretamente,
// É _impossível_ esquecer de fechar e vazar o recurso
// 2. Nota-se que o código é muito mais limpo.
// As alças destructor fecham o arquivo por trás das cenas
// sem que você precise se preocupar com isso.
// 3. O código é seguro de exceção.
-// Uma exceção pode ser jogado em qualquer lugar na função e a limpeza
-// irá ainda ocorrer.
+// Uma exceção pode ser lançada em qualquer lugar na função e a limpeza
+// ainda irá ocorrer.
// Todos códigos C++ usam RAII extensivamente para todos os recursos.
// Outros exemplos incluem
@@ -609,7 +609,6 @@ h=sum<double>(f,g);
```
Leitura Adicional:
-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>
+* Uma referência atualizada da linguagem pode ser encontrada em [CPP Reference](http://cppreference.com/w/cpp).
+* Uma fonte adicional pode ser encontrada em [CPlusPlus](http://cplusplus.com).
+* Um tutorial cobrindo o básico da linguagem e configurando o ambiente de codificação está disponível em [TheChernoProject - C ++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb).
diff --git a/pt-br/c-pt.html.markdown b/pt-br/c-pt.html.markdown
index 0af553c8..4e55f068 100644
--- a/pt-br/c-pt.html.markdown
+++ b/pt-br/c-pt.html.markdown
@@ -8,6 +8,7 @@ translators:
- ["João Farias", "https://github.com/JoaoGFarias"]
- ["Elton Viana", "https://github.com/eltonvs"]
- ["Cássio Böck", "https://github.com/cassiobsilva"]
+ - ["Heitor P. de Bittencourt", "https://github.com/heitorPB/"]
lang: pt-br
filename: c-pt.el
---
@@ -182,7 +183,7 @@ int main() {
int a, b, c;
a = b = c = 0;
- // Aritimética é óbvia
+ // Aritmética é óbvia
i1 + i2; // => 3
i2 - i1; // => 1
i2 * i1; // => 2
@@ -191,7 +192,7 @@ int main() {
f1 / f2; // => 0.5, mais ou menos epsilon
// Números e cálculos de ponto flutuante não são exatos
- // Modulo também existe
+ // Módulo também existe
11 % 3; // => 2
// Operadores de comparação provavelmente são familiares,
@@ -538,7 +539,7 @@ int area(retan r)
return r.largura * r.altura;
}
-// Se você tiver structus grande, você pode passá-las "por ponteiro"
+// Se você tiver structs grandes, você pode passá-las "por ponteiro"
// para evitar cópia de toda a struct:
int area(const retan *r)
{
@@ -638,16 +639,17 @@ typedef void (*minha_função_type)(char *);
## Leitura adicional
É recomendado ter uma cópia de [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language).
-Este é *o* livro sobre C, escrito pelos criadores da linguage. Mas cuidado - ele é antigo e contém alguns erros (bem,
-ideias que não são consideradas boas hoje) ou práticas mudadas.
+Este é *o* livro sobre C, escrito pelos criadores da linguagem. Mas cuidado - ele é antigo e contém alguns erros (bem,
+ideias que não são mais consideradas boas) ou práticas ultrapassadas.
-Outra boa referência é [Learn C the hard way](http://c.learncodethehardway.org/book/).
+Outra boa referência é [Learn C the hard way](http://learncodethehardway.org/c/).
Se você tem uma pergunta, leia [compl.lang.c Frequently Asked Questions](http://c-faq.com).
É importante usar espaços e indentação adequadamente e ser consistente com seu estilo de código em geral.
-Código legível é melhor que código 'esperto' e rápido. Para adotar um estilo de código bom e são, veja
-[Linux kernel coding stlye](https://www.kernel.org/doc/Documentation/CodingStyle).
+Código legível é melhor que código 'esperto' e rápido. Para adotar um estilo de código bom e sensato, veja
+[Linux kernel coding style](https://www.kernel.org/doc/Documentation/CodingStyle).
Além disso, Google é teu amigo.
+
[1] http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member
diff --git a/pt-br/clojure-macros-pt.html.markdown b/pt-br/clojure-macros-pt.html.markdown
index d56840e0..c686bb80 100644
--- a/pt-br/clojure-macros-pt.html.markdown
+++ b/pt-br/clojure-macros-pt.html.markdown
@@ -13,15 +13,15 @@ do Clojure lhe dá acesso a toda a extensão da linguagem
para escrever rotinas de geração de código chamados "macros". Macros fornecem uma poderosa forma de adequar a linguagem
às suas necessidades.
-Pórem Tenha cuidado. É considerado má pratica escrever uma macro quando uma função vai fazer. Use uma macro apenas
-quando você precisar do controle sobre quando ou se os argumentos para um formulário será avaliado.
+Pórem, tenha cuidado. É considerado má pratica escrever uma macro quando uma função vai fazer. Use uma macro apenas
+quando você precisar de controle sobre quando ou se os argumentos de um formulário serão avaliados.
Você vai querer estar familiarizado com Clojure. Certifique-se de entender tudo em
-[Clojure em Y Minutos](/docs/clojure/).
+[Aprenda Clojure em Y Minutos](/docs/clojure/).
```clojure
-;; Defina uma macro utilizando defmacro. Sua macro deve ter como saida uma lista que possa
-;; ser avaliada como codigo Clojure.
+;; Defina uma macro utilizando defmacro. Sua macro deve ter como saída uma lista que possa
+;; ser avaliada como código Clojure.
;;
;; Essa macro é a mesma coisa que se você escrever (reverse "Hello World")
(defmacro my-first-macro []
@@ -33,14 +33,14 @@ Você vai querer estar familiarizado com Clojure. Certifique-se de entender tudo
(macroexpand '(my-first-macro))
;; -> (#<core$reverse clojure.core$reverse@xxxxxxxx> "Hello World")
-;; Você pode avaliar o resultad de macroexpand diretamente:
+;; Você pode avaliar o resultado de macroexpand diretamente:
(eval (macroexpand '(my-first-macro)))
; -> (\d \l \o \r \W \space \o \l \l \e \H)
-;; mas você deve usar esse mais suscinto, sintax como de função:
+;; mas você deve usar essa sintaxe mais sucinta e familiar a funções:
(my-first-macro) ; -> (\d \l \o \r \W \space \o \l \l \e \H)
-;; Você pode tornar as coisas mais faceis pra você, utilizando a sintaxe de citação mais suscinta
+;; Você pode tornar as coisas mais fáceis pra você, utilizando a sintaxe de citação mais suscinta
;; para criar listas nas suas macros:
(defmacro my-first-quoted-macro []
'(reverse "Hello World"))
diff --git a/pt-br/clojure-pt.html.markdown b/pt-br/clojure-pt.html.markdown
index 7e8b3f7b..e40b8fe7 100644
--- a/pt-br/clojure-pt.html.markdown
+++ b/pt-br/clojure-pt.html.markdown
@@ -5,12 +5,13 @@ contributors:
- ["Adam Bard", "http://adambard.com/"]
translators:
- ["Mariane Siqueira Machado", "https://twitter.com/mariane_sm"]
+ - ["Ygor Sad", "https://github.com/ysads"]
lang: pt-br
---
-Clojure é uma linguagem da família do Lisp desenvolvida para a JVM (máquina virtual Java). Possui uma ênfase muito mais forte em [programação funcional] (https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_funcional) pura do que Common Lisp, mas inclui diversas utilidades [STM](https://en.wikipedia.org/wiki/Software_transactional_memory) para lidar com estado a medida que isso se torna necessário.
+Clojure é uma linguagem da família do Lisp desenvolvida para a JVM (máquina virtual Java). Possui uma ênfase muito mais forte em [programação funcional] (https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_funcional) pura do que Common Lisp, mas inclui diversos recursos [STM](https://en.wikipedia.org/wiki/Software_transactional_memory) para lidar com estado e mutabilidade, caso isso seja necessário.
-Essa combinação permite gerenciar processamento concorrente de maneira muito simples, e frequentemente de maneira automática.
+Essa combinação permite gerenciar processamento concorrente de maneira muito simples - frequentemente, de modo automático.
(Sua versão de clojure precisa ser pelo menos 1.2)
@@ -18,367 +19,552 @@ Essa combinação permite gerenciar processamento concorrente de maneira muito s
```clojure
; Comentários começam por ponto e vírgula
-; Clojure é escrito em "forms", os quais são simplesmente
-; listas de coisas dentro de parênteses, separados por espaços em branco.
+; Código Clojure é escrito em formas - 'forms', em inglês. Tais estruturas são
+; simplesmente listas de valores encapsuladas dentro de parênteses, separados por
+; espaços em branco.
-; O "reader" (leitor) de Clojure presume que o primeiro elemento de
-; uma par de parênteses é uma função ou macro, e que os resto são argumentos.
+; Ao interpretar um código em Clojure, o interpretador ou leitor - do inglês 'reader' - assume
+; que o primeiro valor dentro de uma forma é uma função ou macro, de modo que os demais valores
+; são seus argumentos. Isso se deve ao fato de que Clojure, por ser uma derivação de Lisp,
+; usa notação prefixa (ou polonesa).
-: A primeira chamada de um arquivo deve ser ns, para configurar o namespace (espaço de nomes)
+; Num arquivo, a primeira chamada deve ser sempre para a função ns,
+; que é responsável por definir em qual namespace o código em questão
+; deve ser alocado
(ns learnclojure)
; Alguns exemplos básicos:
-; str cria uma string concatenando seus argumentos
-(str "Hello" " " "World") ; => "Hello World"
+; Aqui, str é uma função e "Olá" " " e "Mundo" são seus argumentos. O que ela faz é criar
+; uma string concatenando seus argumentos.
+(str "Olá" " " "Mundo") ; => "Olá Mundo"
-; Cálculos são feitos de forma direta e intuitiva
+; Note que espaços em branco separam os argumentos de uma função. Opcionalmente vírgulas
+; podem ser usadas, se você quiser.
+(str, "Olá", " ", "Mundo") ; => "Olá Mundo"
+
+; As operações matemáticas básicas usam os operadores de sempre
(+ 1 1) ; => 2
(- 2 1) ; => 1
(* 1 2) ; => 2
(/ 2 1) ; => 2
-; Você pode comparar igualdade utilizando =
+; Esses operadores aceitam um número arbitrário de argumentos
+(+ 2 2 2) ; = 2 + 2 + 2 => 6
+(- 5 1 1) ; = 5 - 1 - 1 => 3
+(* 3 3 3 3) ; = 3 * 3 * 3 * 3 => 81
+
+; Para verificar se dois valores são iguais, o operador = pode ser usado
(= 1 1) ; => true
(= 2 1) ; => false
-; Negação para operações lógicas
-(not true) ; => false
+; Para saber se dois valores são diferentes
+(not= 1 2) ; => true
+(not (= 1 2)) ; => true
-; Aninhar "forms" funciona como esperado
+; Conforme vimos acima, é possível aninhar duas formas
(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
+(* (- 3 2) (+ 1 2)) ; = (3 - 2) * (1 + 2) => 3
+
+; Se a leitura ficar comprometida, as fórmulas também podem ser escritas em múltiplas linhas
+(* (- 3 2)
+ (+ 1 2)) ; => 3
+(*
+ (- 3 2)
+ (+ 1 2)) ; => 3
+
; Tipos
;;;;;;;;;;;;;
-; Clojure usa os tipos de objetos de Java para booleanos, strings e números.
-; Use `class` para inspecioná-los
-(class 1) ; Literais Integer são java.lang.Long por padrão
-(class 1.); Literais Float são java.lang.Double
-(class ""); Strings são sempre com aspas duplas, e são java.lang.String
+; Por ter interoperabilidade com Java, Clojure usa os tipos de objetos de Java para booleanos,
+; strings e números. Para descobrir qual o tipo de um valor, você pode usar a função `class`:
+(class 1234) ; Literais Integer são java.lang.Long por padrão
+(class 1.50) ; Literais Float são java.lang.Double
+(class "oi") ; Strings sempre usam aspas duplas e são java.lang.String
(class false) ; Booleanos são java.lang.Boolean
-(class nil); O valor "null" é chamado nil
-; Se você quiser criar um lista de literais, use aspa simples para
-; ela não ser avaliada
-'(+ 1 2) ; => (+ 1 2)
-; (que é uma abreviação de (quote (+ 1 2)))
+; Tenha cuidado, ao dividir valores inteiros:
+(= (/ 1 2)
+ (/ 1.0 2.0)) ; => false
+
+(class (/ 1 2)) ; => clojure.lang.Ratio
+(class (/ 1.0 2.0)) ; => java.lang.Double
+
+; Aqui temos uma diferença em relação a Java, pois valores nulos são representados por `nil`
+(class nil) ; nil
-; É possível avaliar uma lista com aspa simples
-(eval '(+ 1 2)) ; => 3
; Coleções e sequências
;;;;;;;;;;;;;;;;;;;
-; Listas são estruturas encadeadas, enquanto vetores são implementados como arrays.
-; Listas e Vetores são classes Java também!
-(class [1 2 3]); => clojure.lang.PersistentVector
-(class '(1 2 3)); => clojure.lang.PersistentList
+; Os dois tipos básicos de coleção são listas - "list" em inglês - e vetores - "vectors"
+; no original. A principal diferença entre eles se
+; dá pela implementação:
+; - Vetores são implementados como arrays
+; - Listas são listas ligadas
+(class [1 2 3]) ; => clojure.lang.PersistentVector
+(class '(1 2 3)) ; => clojure.lang.PersistentList
-; Uma lista é escrita como (1 2 3), mas temos que colocar a aspa
-; simples para impedir o leitor (reader) de pensar que é uma função.
-; Também, (list 1 2 3) é o mesmo que '(1 2 3)
+; Outra forma de declarar listas é usando a função list
+(list 1 2 3) ; => '(1 2 3)
-; "Coleções" são apenas grupos de dados
-; Listas e vetores são ambos coleções:
+; Clojure classifica conjuntos de dados de duas maneiras
+
+; "Coleções" são grupos simples de dados
+; Tanto listas quanto vetores são coleções:
(coll? '(1 2 3)) ; => true
(coll? [1 2 3]) ; => true
; "Sequências" (seqs) são descrições abstratas de listas de dados.
-; Apenas listas são seqs.
+; Sequências - ou seqs - são conjuntos de dados com avaliação "lazy"
+; Apenas listas são seqs:
(seq? '(1 2 3)) ; => true
(seq? [1 2 3]) ; => false
-; Um seq precisa apenas prover uma entrada quando é acessada.
-; Portanto, já que seqs podem ser avaliadas sob demanda (lazy) -- elas podem definir séries infinitas:
-(range 4) ; => (0 1 2 3)
-(range) ; => (0 1 2 3 4 ...) (uma série infinita)
-(take 4 (range)) ; (0 1 2 3)
+; Ter avaliação lazy significa que uma seq somente precisa prover uma informação quando
+; ela for requisitada. Isso permite às seqs representar listas infinitas.
+(range) ; => (0 1 2 3 4 ...)
+(cycle [1 2]) ; => (1 2 1 2 1 2 ...)
+(take 4 (range)) ; => (0 1 2 3)
-; Use cons para adicionar um item no início de uma lista ou vetor
+; A função cons é usada para adicionar um item ao início de uma lista ou vetor:
(cons 4 [1 2 3]) ; => (4 1 2 3)
(cons 4 '(1 2 3)) ; => (4 1 2 3)
-; Conj adiciona um item em uma coleção sempre do jeito mais eficiente.
-; Para listas, elas inserem no início. Para vetores, é inserido no final.
+; Já conj adiciona um item em uma coleção sempre do jeito mais eficiente.
+; Em listas, isso significa inserir no início. Já em vetores, ao final.
(conj [1 2 3] 4) ; => [1 2 3 4]
(conj '(1 2 3) 4) ; => (4 1 2 3)
-; Use concat para concatenar listas e vetores
+; Concatenação de coleções pode ser feita usando concat. Note que ela sempre gera uma
+; seq como resultado e está sujeita a problemas de perfomance em coleções grandes, por
+; conta da natureza lazy das seqs.
+(concat '(1 2) [3 4]) ; => (1 2 3 4)
(concat [1 2] '(3 4)) ; => (1 2 3 4)
-; Use filter, map para interagir com coleções
+; Outra forma de concatenar coleções é usando into. Ela não está sujeita a problemas
+; com a avaliação lazy, mas o resultado final da ordem e do tipo dos argumentos passados
+(into [1 2] '(3 4)) ; => [1 2 3 4]
+(into '(1 2) [3 4]) ; => (4 3 1 2)
+
+; Note que em into a ordem dos parâmetros influencia a coleção final.
+(into [1 2] '(3 4)) ; => (1 2 3 4)
+(into '(1 2) [3 4]) ; => (4 3 1 2)
+
+; As funções filter e map podem ser usadas para interagir com as coleções. Repare que
+; elas sempre retornam seqs, independentemente do tipo do seu argumento.
(map inc [1 2 3]) ; => (2 3 4)
-(filter even? [1 2 3]) ; => (2)
+(filter even? [1 2 3 4]) ; => (2 4)
+
+; Use reduce reduzir coleções a um único valor. Também é possível passar um argumento
+; para o valor inicial das operações
+(reduce + [1 2 3]) ; = (+ (+ (+ 1 2) 3) 4) => 10
+(reduce + 10 [1 2 3 4]) ; = (+ (+ (+ (+ 10 1) 2) 3) 4) => 20
+(reduce conj [] '(3 2 1)) ; = (conj (conj (conj [] 3) 2) 1) => [3 2 1]
+
+; Reparou na semelhança entre listas e as chamadas de código Clojure? Isso se deve ao
+; fato de que todo código clojure é escrito usando listas. É por isso que elas sempre
+; são declaradas com o caracter ' na frente. Dessa forma o interpretador não tenta
+; avaliá-las.
+'(+ 2 3) ; cria uma lista com os elementos +, 2 e 3
+(+ 2 3) ; o interpretador chama a função + passando como argumentos 2 e 3
-; Use reduce para reduzi-los
-(reduce + [1 2 3 4])
-; = (+ (+ (+ 1 2) 3) 4)
-; => 10
+; Note que ' é apenas uma abreviação para a função quote.
+(quote (1 2 3)) ; => '(1 2 3)
+
+; É possível passar uma lista para que o interpretador a avalie. Note que isso está
+; sujeito ao primeiro elemento da lista ser um literal com um nome de uma função válida.
+(eval '(+ 2 3)) ; => 5
+(eval '(1 2 3)) ; dá erro pois o interpretador tenta chamar a função 1, que não existe
-; Reduce pode receber um argumento para o valor inicial
-(reduce conj [] '(3 2 1))
-; = (conj (conj (conj [] 3) 2) 1)
-; => [3 2 1]
; Funções
;;;;;;;;;;;;;;;;;;;;;
-; Use fn para criar novas funções. Uma função sempre retorna
-; sua última expressão.
-(fn [] "Hello World") ; => fn
+; Use fn para criar novas funções. Uma função sempre retorna sua última expressão.
+(fn [] "Olá Mundo") ; => fn
+
+; Para executar suas funções, é preciso chamá-las, envolvendo-as em parênteses.
+((fn [] "Olá Mundo")) ; => "Olá Mundo"
+
+; Como isso não é muito prático, você pode nomear funções atribuindo elas a literais.
+; Isso torna muito mais fácil chamá-las:
+(def ola-mundo (fn [] "Olá Mundo")) ; => fn
+(ola-mundo) ; => "Olá Mundo"
-; (É necessário colocar parênteses para chamá-los)
-((fn [] "Hello World")) ; => "Hello World"
+; Você pode abreviar esse processo usando defn:
+(defn ola-mundo [] "Olá Mundo")
-; Você pode atribuir valores a variáveis utilizando def
-(def x 1)
-x ; => 1
+; Uma função pode receber uma lista de argumentos:
+(defn ola
+ [nome]
+ (str "Olá " nome))
+(ola "Jonas") ; => "Olá Jonas"
-; Atribua uma função para uma var
-(def hello-world (fn [] "Hello World"))
-(hello-world) ; => "Hello World"
+; É possível criar funções que recebam multivariadas, isto é, que aceitam números
+; diferentes de argumentos:
+(defn soma
+ ([] 0)
+ ([a] a)
+ ([a b] (+ a b)))
-; Você pode abreviar esse processo usando defn
-(defn hello-world [] "Hello World")
+(soma) ; => 0
+(soma 1) ; => 1
+(soma 1 2) ; => 3
-; O [] é uma lista de argumentos para um função.
-(defn hello [name]
- (str "Hello " name))
-(hello "Steve") ; => "Hello Steve"
+; Funções podem agrupar argumentos extras em uma seq:
+(defn conta-args
+ [& args]
+ (str "Você passou " (count args) " argumentos: " args))
+(conta-args 1 2 3 4) ; => "Você passou 4 argumentos: (1 2 3 4)"
-; Você pode ainda usar essa abreviação para criar funcões:
-(def hello2 #(str "Hello " %1))
-(hello2 "Fanny") ; => "Hello Fanny"
+; Você pode misturar argumentos regulares e argumentos em seq:
+(defn ola-e-conta
+ [nome & args]
+ (str "Olá " nome ", você passou " (count args) " argumentos extras"))
+(ola-e-conta "Maria" 1 2 3 4) ; => "Olá Maria, você passou 4 argumentos extras"
-; Vocé pode ter funções multi-variadic, isto é, com um número variável de argumentos
-(defn hello3
- ([] "Hello World")
- ([name] (str "Hello " name)))
-(hello3 "Jake") ; => "Hello Jake"
-(hello3) ; => "Hello World"
-; Funções podem agrupar argumentos extras em uma seq
-(defn count-args [& args]
- (str "You passed " (count args) " args: " args))
-(count-args 1 2 3) ; => "You passed 3 args: (1 2 3)"
+; Nos exemplos acima usamos def para associar nomes a funções, mas poderíamos usá-lo
+; para associar nomes a quaisquer valores:
+(def xis :x)
+xis ; => :x
-; Você pode misturar argumentos regulares e argumentos em seq
-(defn hello-count [name & args]
- (str "Hello " name ", you passed " (count args) " extra args"))
-(hello-count "Finn" 1 2 3)
-; => "Hello Finn, you passed 3 extra args"
+; Inclusive, tais literais podem possuir alguns caracteres não usuais em outras linguagens:
+(def *num-resposta* 42)
+(def conexao-ativa? true)
+(def grito-de-medo! "AAAAAAA")
+(def ->vector-vazio [])
+
+; É possível, inclusive, criar apelidos a nomes que já existem:
+(def somar! soma)
+(somar! 41 1) ; => 42
+
+; Uma forma rápida de criar funções é por meio de funções anônimas. Elas são ótimas
+; para manipulação de coleções e seqs, já que podem ser passadas para map, filter
+; e reduce. Nessas funções, % é substituído por cada um dos items na seq ou na coleção:
+(filter #(not= % nil) ["Joaquim" nil "Maria" nil "Antônio"]) ; => ("Joaquim" "Maria" "Antônio")
+(map #(* % (+ % 2)) [1 2]) ; => (3 8)
; Mapas
;;;;;;;;;;
-; Hash maps e array maps compartilham uma mesma interface. Hash maps são mais
-; rápidos para pesquisa mas não mantém a ordem da chave.
+; Existem dois tipos de mapas: hash maps e array maps. Ambos compartilham uma mesma
+; interface e funções. Hash maps são mais rápidos para retornar dados, mas não mantém
+; as chaves ordenadas.
(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
-; Arraymaps pode automaticamente se tornar hashmaps através da maioria das
-; operações se eles ficarem grandes o suficiente, portanto não há necessida de
-; se preocupar com isso.
-
-;Mapas podem usar qualquer valor que se pode derivar um hash como chave
+; Clojure converte automaticamente array maps em hash maps, por meio da maioria das
+; funções de manipulação de mapas, caso eles fiquem grandes o suficiente. Não é
+; preciso se preocupar com isso.
-
-; Mapas podem usar qualquer valor em que se pode derivar um hash como chave,
-; mas normalmente palavras-chave (keywords) são melhores.
-; Keywords são como strings mas com algumas vantagens.
+; Chaves podem ser qualquer valor do qual possa ser obtido um hash, mas normalmente
+; usam-se keywords como chave, por possuírem algumas vantagens.
(class :a) ; => clojure.lang.Keyword
-(def stringmap {"a" 1, "b" 2, "c" 3})
-stringmap ; => {"a" 1, "b" 2, "c" 3}
+; Keywords são como strings, porém, duas keywords de mesmo valor são sempre armazenadas
+; na mesma posição de memória, o que as torna mais eficientes.
+(identical? :a :a) ; => true
+(identical? (String. "a") (String. "a")) ; => false
-(def keymap {:a 1, :b 2, :c 3})
-keymap ; => {:a 1, :c 3, :b 2}
+(def mapa-strings {"a" 1 "b" 2 "c" 3})
+mapa-strings ; => {"a" 1, "b" 2, "c" 3}
-; A propósito, vírgulas são sempre tratadas como espaçoes em branco e não fazem nada.
+(def mapa-keywords {:a 1 :b 2 :c 3})
+mapa-keywords ; => {:a 1, :c 3, :b 2}
-; Recupere o valor de um mapa chamando ele como uma função
-(stringmap "a") ; => 1
-(keymap :a) ; => 1
+; Você pode usar um mapa como função para recuperar um valor dele:
+(mapa-strings "a") ; => 1
+(mapa-keywords :a) ; => 1
-; Uma palavra-chave pode ser usada pra recuperar os valores de um mapa
-(:b keymap) ; => 2
+; Se a chave buscada for uma keyword, ela também pode ser usada como função para recuperar
+; valores. Note que isso não funciona com strings.
+(:b mapa-keywords) ; => 2
+("b" mapa-strings) ; => java.lang.String cannot be cast to clojure.lang.IFn
-; Não tente isso com strings
-;("a" stringmap)
-; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
+; Se você buscar uma chave que não existe, Clojure retorna nil:
+(mapa-strings "d") ; => nil
-; Buscar uma chave não presente retorna nil
-(stringmap "d") ; => nil
+; Use assoc para adicionar novas chaves em um mapa.
+(def mapa-keywords-estendido (assoc mapa-keywords :d 4))
+mapa-keywords-estendido ; => {:a 1, :b 2, :c 3, :d 4}
-; Use assoc para adicionar novas chaves para hash-maps
-(def newkeymap (assoc keymap :d 4))
-newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
+; Mas lembre-se que tipos em Clojure são sempre imutáveis! Isso significa que o mapa
+; inicial continua com as mesmas informações e um novo mapa, com mais dados, é criado
+; a partir dele
+mapa-keywords ; => {:a 1, :b 2, :c 3}
-; Mas lembre-se, tipos em Clojure são sempre imutáveis!
-keymap ; => {:a 1, :b 2, :c 3}
+; assoc também pode ser usado para atualizar chaves:
+(def outro-mapa-keywords (assoc mapa-keywords :a 0))
+outro-mapa-keywords ; => {:a 0, :b 2, :c 3}
; Use dissoc para remover chaves
-(dissoc keymap :a :b) ; => {:c 3}
+(dissoc mapa-keywords :a :b) ; => {:c 3}
+
+; Mapas também são coleções - mas não seqs!
+(coll? mapa-keywords) ; => true
+(seq? mapa-keywords) ; => false
+
+; É possível usar filter, map e qualquer outra função de coleções em mapas.
+; Porém a cada iteração um vetor no formato [chave valor] vai ser passado como
+; argumento. Por isso é conveniente usar funções anônimas.
+(filter #(odd? (second %)) mapa-keywords) ; => ([:a 1] [:c 3])
+(map #(inc (second %)) mapa-keywords) ; => (2 3 4)
; Conjuntos
;;;;;;
-(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
+; Conjuntos são um tipo especial de coleções que não permitem elementos repetidos.
+; Eles podem ser criados com #{} ou com a função set.
(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
+(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
-; Adicione um membro com conj
-(conj #{1 2 3} 4) ; => #{1 2 3 4}
+; Note que nem sempre um set vai armazenar seus elementos na ordem esperada.
+(def meu-conjunto #{1 2 3})
+meu-conjunto ; => #{1 3 2}
-; Remova um membro com disj
-(disj #{1 2 3} 1) ; => #{2 3}
+; Adição funciona normalmente com conj.
+(conj meu-conjunto 4) ; => #{1 4 3 2}
-; Test por existência usando set como função:
-(#{1 2 3} 1) ; => 1
-(#{1 2 3} 4) ; => nil
+; Remoção, no entanto, precisa ser feita com disj:
+(disj meu-conjunto 1) ; => #{3 2}
-; Existem muitas outras funções no namespace clojure.sets
+; Para saber se um elemento está em um conjunto, use-o como função. Nesse aspecto
+; conjuntos funcionam de maneira semelhante a mapas.
+(meu-conjunto 1) ; => 1
+(meu-conjunto 4) ; => nil
-; Forms úteis
-;;;;;;;;;;;;;;;;;
-; Construções lógicas em Clojure são como macros, e
-; se parecem com as demais
-(if false "a" "b") ; => "b"
-(if false "a") ; => nil
+; Condicionais e blocos
+;;;;;;;;;;;;;;;;;
-; Use let para criar um novo escopo associando sîmbolos a valores (bindings)
+; Você pode usar um bloco let para criar um escopo local, no qual estarão disponíveis
+; os nomes que você definir:
(let [a 1 b 2]
- (> a b)) ; => false
+ (+ a b)) ; => 3
-; Agrupe comandos juntos com "do"
-(do
- (print "Hello")
- "World") ; => "World" (prints "Hello")
+(let [cores {:yellow "Amarelo" :blue "Azul"}
+ nova-cor :red
+ nome-cor "Vermelho"]
+ (assoc cores nova-cor nome-cor)) ; => {:yellow "Amarelo", :blue "Azul", :red "Vermelho"}
-; Funções tem um do implícito
-(defn print-and-say-hello [name]
- (print "Saying hello to " name)
- (str "Hello " name))
-(print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff")
+; Formas do tipo if aceitam três argumentos: a condição de teste, o comando a ser
+; executado caso a condição seja positiva; e o comando para o caso de ela ser falsa.
+(if true "a" "b") ; => "a"
+(if false "a" "b") ; => "b"
+
+; Opcionalmente você pode não passar o último argumento, mas se a condição for falsa
+; o if vai retornar nil.
+(if false "a") ; => nil
+
+; A forma if somente aceita um comando para ser executado em cada caso. Se você
+; precisar executar mais comandos, você pode usar a função do:
+(if true
+ (do
+ (print "Olá ")
+ (print "Mundo"))) ; => escreve "Olá Mundo" na saída
+
+; Se você só deseja tratar o caso de sua condição ser verdadeira, o comando when é
+; uma alternativa melhor. Seu comportamento é idêntico a um if sem condição negativa.
+; Uma de suas vantagens é permitir a execução de vários comandos sem exigir do:
+(when true "a") ; => "a"
+(when true
+ (print "Olá ")
+ (print "Mundo")) ; => também escreve "Olá Mundo" na saída
+
+; Isso ocorre porque when possui um bloco do implícito. O mesmo se aplica a funções e
+; comandos let:
+(defn escreve-e-diz-xis
+ [nome]
+ (print "Diga xis, " nome)
+ (str "Olá " nome))
+(escreve-e-diz-xis "João") ;=> "Olá João", além de escrever "Diga xis, João" na saída.
+
+(let [nome "Nara"]
+ (print "Diga xis, " nome)
+ (str "Olá " nome)) ;=> "Olá João", além de escrever "Diga xis, João" na saída.
-; Assim como let
-(let [name "Urkel"]
- (print "Saying hello to " name)
- (str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
; Módulos
;;;;;;;;;;;;;;;
-; Use "use" para poder usar todas as funções de um modulo
+; Você pode usar a função use para carregar todas as funções de um módulo.
(use 'clojure.set)
-; Agora nós podemos usar operações com conjuntos
+; Agora nós podemos usar operações de conjuntos definidas nesse módulo:
(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
(difference #{1 2 3} #{2 3 4}) ; => #{1}
-; Você pode escolher um subconjunto de funções para importar
-(use '[clojure.set :only [intersection]])
-
-; Use require para importar um módulo
+; Isso porém não é uma boa prática pois dificulta saber de qual módulo cada função
+; veio, além de expor o código a conflitos de nomes, caso dois módulos diferentes
+; definam funções com o mesmo nome. A melhor forma de referenciar módulos é por meio
+; de require:
(require 'clojure.string)
-; Use / para chamar funções de um módulo
+; Com isso podemos chamar as funções de clojure.string usando o operador /
; Aqui, o módulo é clojure.string e a função é blank?
(clojure.string/blank? "") ; => true
-; Você pode dar para um módulo um nome mais curto no import
+; Porém isso não é muito prático, por isso é possível dar para um nome mais curto para
+; o módulo ao carregá-lo:
(require '[clojure.string :as str])
-(str/replace "This is a test." #"[a-o]" str/upper-case) ; => "THIs Is A tEst."
-; (#"" denota uma expressão regular literal)
+(str/replace "alguém quer teste?" #"[aeiou]" str/upper-case) ; => "AlgUém qUEr tEstE?"
-; Você pode usar require (e até "use", mas escolha require) de um namespace utilizando :require.
-; Não é necessário usar aspa simples nos seus módulos se você usar desse jeito.
+; Nesse exemplo usamos também a construção #"", que delimita uma expressão regular.
+
+; É possível carregar outros módulos direto na definição do namespace. Note que nesse
+; contexto não é preciso usar ' antes do vetor que define a importação do módulo.
(ns test
(:require
[clojure.string :as str]
[clojure.set :as set]))
+
+; Operadores thread
+;;;;;;;;;;;;;;;;;
+
+; Uma das funções mais interessantes de clojure são os operadores -> e ->> - respectivamente
+; thread-first e thread-last macros. Elas permitem o encadeamento de chamadas de funções,
+; sendo perfeitas para melhorar a legibilidade em transformações de dados.
+
+; -> usa o resultado de uma chamada como o primeiro argumento da chamada à função seguinte:
+(-> " uMa StRIng com! aLG_uNs ##problemas. "
+ (str/replace #"[!#_]" "")
+ (str/replace #"\s+" " ")
+ str/trim ; se a função só aceitar um argumento, não é preciso usar parênteses
+ (str/lower-case)) ; => "uma string com alguns problemas."
+
+; Na thread uma string com vários problemas foi passada como primeiro argumento à função
+; str/replace, que criou uma nova string, a partir da original, porém somente com caracteres
+; alfabéticos. Essa nova string foi passada como primeiro argumento para a chamada str/replace
+; seguinte, que criou uma nova string sem espaços duplos. Essa nova string foi então passada
+; como primeiro argumento para str/trim, que removeu espaços de seu início e fim, passando essa
+; última string para str/lower-case, que a converteu para caracteres em caixa baixa.
+
+; ->> é equivalente a ->, porém o retorno de cada função é passado como último argumento da
+; função seguinte. Isso é particularmente útil para lidar com seqs, já que as funções que
+; as manipulam sempre as tomam como último argumento.
+(->> '(1 2 3 4)
+ (filter even?) ; => '(2 4)
+ (map inc) ; => '(3 5)
+ (reduce *)) ; => 15
+
+
; Java
;;;;;;;;;;;;;;;;;
-; Java tem uma biblioteca padrão enorme e muito útil,
-; portanto é importante aprender como utiliza-la.
+; A biblioteca padrão de Java é enorme e possui inúmeros algoritmos e estruturas de
+; dados já implementados. Por isso é bastante conveniente saber como usá-la dentro
+; de Clojure.
-; Use import para carregar um modulo java
+; Use import para carregar um módulo Java.
(import java.util.Date)
-; Você pode importar usando ns também.
+; Você pode importar classes Java dentro de ns também:
(ns test
(:import java.util.Date
- java.util.Calendar))
+ java.util.Calendar
+ java.util.ArrayList))
; Use o nome da clase com um "." no final para criar uma nova instância
-(Date.) ; <a date object>
+(def instante (Date.))
+(class instante) => ; java.util.Date
+
+; Para chamar um método, use o operador . com o nome do método. Outra forma é
+; usar simplesmente .<nome do método>
+(. instante getTime) ; => retorna um inteiro representando o instante
+(.getTime instante) ; => exatamente o mesmo que acima
+
+; Para chamar métodos estáticos dentro de classes Java, use /
+(System/currentTimeMillis) ; => retorna um timestamp
-; Use . para chamar métodos. Ou, use o atalho ".method"
-(. (Date.) getTime) ; <a timestamp>
-(.getTime (Date.)) ; exatamente a mesma coisa.
+; Note que não é preciso importar o módulo System, pois ele está sempre presente
-; Use / para chamar métodos estáticos
-(System/currentTimeMillis) ; <a timestamp> (o módulo System está sempre presente)
+; Caso queira submeter uma instância de uma classe mutável a uma sequência de operações,
+; você pode usar a função doto. Ela é funciona de maneira semelhante à função -> - ou
+; thread-first -, exceto pelo fato de que ele opera com valores mutáveis.
+(doto (java.util.ArrayList.)
+ (.add 11)
+ (.add 3)
+ (.add 7)
+ (java.util.Collections/sort)) ; => #<ArrayList [3, 7, 11]>
-; Use doto para pode lidar com classe (mutáveis) de forma mais tolerável
-(import java.util.Calendar)
-(doto (Calendar/getInstance)
- (.set 2000 1 1 0 0 0)
- .getTime) ; => A Date. set to 2000-01-01 00:00:00
; STM
;;;;;;;;;;;;;;;;;
-; Software Transactional Memory é o mecanismo que Clojure usa para gerenciar
-; estado persistente. Tem algumas construções em Clojure que o utilizam.
+; Até aqui usamos def para associar nomes a valores. Isso, no entanto, possui algumas
+; limitações, já que, uma vez definido essa associação, não podemos alterar o valor
+; para o qual um nome aponta. Isso significa que nomes definidos com def não se
+; comportam como as variáveis de outras linguagens.
-; O atom é o mais simples. Passe pra ele um valor inicial
-(def my-atom (atom {}))
+; Para lidar com estado persistente e mutação de valores, Clojure usa o mecanismo Software
+; Transactional Memory. O atom é o mais simples de todos. Passe pra ele um valor inicial e
+; e ele criará um objeto que é seguro de atualizar:
+(def atom-mapa (atom {}))
-; Atualize o atom com um swap!.
-; swap! pega uma funçnao and chama ela com o valor atual do atom
-; como primeiro argumento, e qualquer argumento restante como o segundo
-(swap! my-atom assoc :a 1) ; Coloca o valor do átomo my-atom como o resultado de (assoc {} :a 1)
-(swap! my-atom assoc :b 2) ; Coloca o valor do átomo my-atom como o resultado de (assoc {:a 1} :b 2)
+; Para acessar o valor de um atom, você pode usar a função deref ou o operador @:
+@atom-mapa ; => {}
+(deref atom-mapa) ; => {}
-; Use '@' para desreferenciar um atom e acessar seu valor
-my-atom ;=> Atom<#...> (Retorna o objeto do Atom)
-@my-atom ; => {:a 1 :b 2}
+; Para mudar o valor de um atom, você deve usar a função swap!
+; O que ela faz é chamar a função passada usando o atom como seu primeiro argumento. Com
+; isso, ela altera o valor do atom de maneira segura.
+(swap! atom-mapa assoc :a 1) ; Atribui a atom-mapa o resultado de (assoc {} :a 1)
+(swap! atom-mapa assoc :b 2) ; Atribui a atom-mapa o resultado de (assoc {:a 1} :b 2)
-; Abaixo um contador simples usando um atom
-(def counter (atom 0))
-(defn inc-counter []
- (swap! counter inc))
+; Observe que essas chamadas alteraram de fato o valor de atom-mapa. Seu novo valor é:
+@atom-mapa ; => {:a 1 :b 2}
-(inc-counter)
-(inc-counter)
-(inc-counter)
-(inc-counter)
-(inc-counter)
+; Isso é diferente de fazer:
+(def atom-mapa-2 (atom {}))
+(def atom-mapa-3 (assoc @atom-mapa-2 :a 1))
-@counter ; => 5
+; Nesse exemplo, atom-mapa-2 permanece com o seu valor original e é gerado um novo mapa,
+; atom-mapa-3, que contém o valor de atom-mapa-2 atualizado. Note que atom-mapa-3 é um
+; simples mapa, e não uma instância de um atom
+@atom-mapa-2 ; => {}
+atom-mapa-3 ; => {:a 1}
-; Outras construção STM são refs e agents.
+(class atom-mapa-2) ; => clojure.lang.Atom
+(class atom-mapa-3) ; => clojure.lang.PersistentArrayMap
+
+; A ideia é que o valor do atom só será atualizado se, após ser executada a função passada
+; para swap!, o atom ainda estiver com o mesmo valor de antes. Isto é, se durante a execução
+; da função alguém alterar o valor do atom, swap! reexecutará a função recebida usando o valor
+; atual do átoma como argumento.
+
+; Isso é ótimo em situações nas quais é preciso garantir a consistência de algum valor - tais
+; como sistemas bancários e sites de compra. Para mais exemplos e informações sobre outras
+; construções STM:
+
+; Exemplos e aplicações: https://www.braveclojure.com/zombie-metaphysics/
; Refs: http://clojure.org/refs
; Agents: http://clojure.org/agents
```
### Leitura adicional
-Esse tutorial está longe de ser exaustivo, mas deve ser suficiente para que você possa começar.
+Esse tutorial está longe de ser completo, mas deve ser suficiente para que você possa dar seus primeiros passos em Clojure.
+Caso queira aprender mais:
-Clojure.org tem vários artigos:
+* clojure.org tem vários artigos:
[http://clojure.org/](http://clojure.org/)
-Clojuredocs.org tem documentação com exemplos para quase todas as funções principais (pertecentes ao core):
+* Brave Clojure possui um e-book que explora em profundidade diversos recursos de clojure, incluindo ótimos exemplos:
+[https://www.braveclojure.com/](https://www.braveclojure.com/)
+
+* clojuredocs.org tem documentação com exemplos para quase todas as funções principais (pertecentes ao core):
[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
-4Clojure é um grande jeito de aperfeiçoar suas habilidades em Clojure/Programação Funcional:
+* 4clojure possui alguns problemas e desafios interessantes para quem quiser treinar clojure ou programação funcional:
[http://www.4clojure.com/](http://www.4clojure.com/)
-Clojure-doc.org tem um bom número de artigos para iniciantes:
+* clojure-doc.org tem um bom número de artigos para iniciantes:
[http://clojure-doc.org/](http://clojure-doc.org/)
+
+Clojure for the Brave and True é um livro de introdução ao Clojure e possui uma versão gratuita online:
+[https://www.braveclojure.com/clojure-for-the-brave-and-true/](https://www.braveclojure.com/clojure-for-the-brave-and-true/)
diff --git a/pt-br/cmake-pt.html.markdown b/pt-br/cmake-pt.html.markdown
new file mode 100644
index 00000000..d11fe4f4
--- /dev/null
+++ b/pt-br/cmake-pt.html.markdown
@@ -0,0 +1,179 @@
+---
+category: tool
+tool: cmake
+contributors:
+ - ["Bruno Alano", "https://github.com/brunoalano"]
+filename: CMake-br
+translators:
+ - ["Lucas Pugliesi", "https://github.com/fplucas"]
+lang: pt-br
+---
+
+CMake é um programa de compilação open-source e multiplataforma. Essa ferramenta
+permitirá testar, compilar e criar pacotes a partir do seu código fonte.
+
+O problema que o CMake tenta resolver são os problemas de configurar os Makefiles
+e Autoconfigure (diferente dos interpretadores make que tem comandos diferentes)
+e sua facilidade de uso envolvendo bibliotecas terceiras.
+
+CMake é um sistema open-source extensível que gerencia o processo de build em um
+sistema operacional e um método independente de compilador. Diferente de sistemas
+multiplataformas, CMake é designado a usar em conjunto ao ambiente de compilação
+nativo. Seus simples arquivos de configuração localizados em seus diretórios
+(chamados arquivos CMakeLists.txt) que são usados para gerar padrões de arquivos
+de compilação (ex: makefiles no Unix e projetos em Windows MSVC) que são usados
+de maneira simples.
+
+```cmake
+# No CMake, isso é um comentário
+
+# Para rodar nosso código, iremos utilizar esses comandos:
+# - mkdir build && cd build
+# - cmake ..
+# - make
+#
+# Com esses comandos, iremos seguir as melhores práticas para compilar em um
+# subdiretório e na segunda linha pediremos ao CMake para gerar um novo Makefile
+# independente de sistema operacional. E finalmente, rodar o comando make.
+
+#------------------------------------------------------------------------------
+# Básico
+#------------------------------------------------------------------------------
+#
+# O arquivo CMake deve ser chamado de "CMakeLists.txt".
+
+# Configura a versão mínima requerida do CMake para gerar o Makefile
+cmake_minimum_required (VERSION 2.8)
+
+# Exibe FATAL_ERROR se a versão for menor que 2.8
+cmake_minimum_required (VERSION 2.8 FATAL_ERROR)
+
+# Configuramos o nome do nosso projeto. Mas antes disso, iremos alterar alguns
+# diretórios em nome da convenção gerada pelo CMake. Podemos enviar a LANG do
+# código como segundo parâmetro
+project (learncmake C)
+
+# Configure o diretório do código do projeto (somente convenção)
+set( LEARN_CMAKE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
+set( LEARN_CMAKE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} )
+
+# Isso é muito útil para configurar a versão do nosso código no sistema de compilação
+# usando um estilo `semver`
+set (LEARN_CMAKE_VERSION_MAJOR 1)
+set (LEARN_CMAKE_VERSION_MINOR 0)
+set (LEARN_CMAKE_VERSION_PATCH 0)
+
+# Envie as variáveis (número da versão) para o cabeçalho de código-fonte
+configure_file (
+ "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
+ "${PROJECT_BINARY_DIR}/TutorialConfig.h"
+)
+
+# Inclua Diretórios
+# No GCC, isso irá invocar o comando "-I"
+include_directories( include )
+
+# Onde as bibliotecas adicionais estão instaladas? Nota: permite incluir o path
+# aqui, na sequência as checagens irão resolver o resto
+set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake/modules/" )
+
+# Condições
+if ( CONDICAO )
+ # reposta!
+
+ # Informação incidental
+ message(STATUS "Minha mensagem")
+
+ # Aviso CMake, continua processando
+ message(WARNING "Minha mensagem")
+
+ # Aviso (dev) CMake, continua processando
+ message(AUTHOR_WARNING "Minha mensagem")
+
+ # Erro CMake, continua processando, mas pula a geração
+ message(SEND_ERROR "Minha mensagem")
+
+ # Erro CMake, para o processamento e a geração
+ message(FATAL_ERROR "Minha mensagem")
+endif()
+
+if( CONDICAO )
+
+elseif( CONDICAO )
+
+else( CONDICAO )
+
+endif( CONDICAO )
+
+# Loops
+foreach(loop_var arg1 arg2 ...)
+ COMANDO1(ARGS ...)
+ COMANDO2(ARGS ...)
+ ...
+endforeach(loop_var)
+
+foreach(loop_var RANGE total)
+foreach(loop_var RANGE start stop [step])
+
+foreach(loop_var IN [LISTS [list1 [...]]]
+ [ITEMS [item1 [...]]])
+
+while(condicao)
+ COMANDO1(ARGS ...)
+ COMANDO2(ARGS ...)
+ ...
+endwhile(condicao)
+
+
+# Operações Lógicas
+if(FALSE AND (FALSE OR TRUE))
+ message("Não exiba!")
+endif()
+
+# Configure um cache normal, ou uma variável de ambiente com o dado valor.
+# Se a opção PARENT_SCOPE for informada em uma variável que será setada no escopo
+# acima do escopo corrente.
+# `set(<variavel> <valor>... [PARENT_SCOPE])`
+
+# Como refencia variáveis dentro de aspas ou não, argumentos com strings vazias
+# não serão setados
+${nome_da_variavel}
+
+# Listas
+# Configure a lista de arquivos código-fonte
+set( LEARN_CMAKE_SOURCES
+ src/main.c
+ src/imagem.c
+ src/pather.c
+)
+
+# Chama o compilador
+#
+# ${PROJECT_NAME} referencia ao Learn_CMake
+add_executable( ${PROJECT_NAME} ${LEARN_CMAKE_SOURCES} )
+
+# Linka as bibliotecas
+target_link_libraries( ${PROJECT_NAME} ${LIBS} m )
+
+# Onde as bibliotecas adicionais serão instaladas? Nota: nos permite incluir o path
+# aqui, em seguida os testes irão resolver o restante
+set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMake/modules/" )
+
+# Condição do compilador (gcc ; g++)
+if ( "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" )
+ message( STATUS "Setting the flags for ${CMAKE_C_COMPILER_ID} compiler" )
+ add_definitions( --std=c99 )
+endif()
+
+# Checa o Sistema Operacional
+if( UNIX )
+ set( LEARN_CMAKE_DEFINITIONS
+ "${LEARN_CMAKE_DEFINITIONS} -Wall -Wextra -Werror -Wno-deprecated-declarations -Wno-unused-parameter -Wno-comment" )
+endif()
+```
+
+### Mais Recursos
+
++ [cmake tutorial](https://cmake.org/cmake-tutorial/)
++ [cmake documentation](https://cmake.org/documentation/)
++ [mastering cmake](http://amzn.com/1930934319/)
diff --git a/pt-br/coffeescript-pt.html.markdown b/pt-br/coffeescript-pt.html.markdown
index 8b1094b1..7129a463 100644
--- a/pt-br/coffeescript-pt.html.markdown
+++ b/pt-br/coffeescript-pt.html.markdown
@@ -3,19 +3,20 @@ language: coffeescript
contributors:
- ["Tenor Biel", "http://github.com/L8D"]
- ["Xavier Yao", "http://github.com/xavieryao"]
+ - ["Claudio Busatto", "http://github.com/cjcbusatto"]
translators:
- ["Miguel Araújo", "https://github.com/miguelarauj1o"]
lang: pt-br
filename: learncoffeescript-pt.coffee
---
-CoffeeScript é uma pequena linguagem que compila um-para-um para o JavaScript
-equivalente, e não há interpretação em tempo de execução. Como um dos sucessores
-de JavaScript, CoffeeScript tenta o seu melhor para exibir uma saída legível,
-bem-impressa e bom funcionamento dos códigos JavaScript em todo o tempo de
+CoffeeScript é uma pequena linguagem que compila um-para-um para o JavaScript
+equivalente, e não há interpretação em tempo de execução. Como um dos sucessores
+de JavaScript, CoffeeScript tenta o seu melhor para exibir uma saída legível,
+bem-impressa e bom funcionamento dos códigos JavaScript em todo o tempo de
execução JavaScript.
-Veja também [site do CoffeeScript](http://coffeescript.org/), que tem um tutorial
+Veja também [site do CoffeeScript](http://coffeescript.org/), que tem um tutorial
completo sobre CoffeeScript.
``` coffeescript
@@ -23,35 +24,35 @@ completo sobre CoffeeScript.
#Segue as tendências de muitas linguagens modernas
#Assim, os comentários são iguais a Ruby e Python, eles usam símbolos numéricos.
-###
-Os comentários em bloco são como estes, e eles traduzem diretamente para '/ *'s e
+###
+Os comentários em bloco são como estes, e eles traduzem diretamente para '/ *'s e
'* /'s para o código JavaScript que resulta...
-Você deveria entender mais de semântica de JavaScript antes de continuar...
+Você deveria entender mais de semântica de JavaScript antes de continuar...
###
-# Tarefa:
-numero = 42 #=> número var = 42;
+# Tarefa:
+numero = 42 #=> var numero = 42;
oposto = true #=> var oposto = true;
-# Condições:
-numero = -42 if oposto #=> if (oposto) {número = -42;}
+# Condições:
+numero = -42 if oposto #=> if (oposto) {numero = -42;}
-# Funções:
+# Funções:
quadrado = (x) -> x * x #=> var quadrado = function (x) {return x * x;}
-preencher = (recipiente, líquido = "coffee") ->
- "Preenchendo o #{recipiente} with #{líquido}..."
+preencher = (recipiente, liquido = "coffee") ->
+ "Preenchendo o #{recipiente} with #{liquido}..."
#=>var preencher;
#
-#preencher = function(recipiente, líquido) {
-# if (líquido == null) {
-# líquido = "coffee";
+#preencher = function(recipiente, liquido) {
+# if (liquido == null) {
+# liquido = "coffee";
# }
-# return "Preenchendo o " + recipiente + " with " + líquido + "...";
+# return "Preenchendo o " + recipiente + " with " + liquido + "...";
#};
-# Alcances:
+# Alcances:
list = [1 .. 5] #=> lista var = [1, 2, 3, 4, 5];
# Objetos:
@@ -79,7 +80,7 @@ alert "Eu sabia!" if elvis?
#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("Eu sabia!"); }
# Compressão de Matrizes:
-cubes = (math.cube num for num in list)
+cubes = (math.cube num for num in list)
#=>cubes = (function() {
# var _i, _len, _results;
# _results = [];
@@ -99,8 +100,9 @@ eat alimento for alimento in comidas when alimento isnt 'chocolate'
# if (alimento !== 'chocolate') {
# eat(alimento);
# }
+```
## Recursos adicionais
- [Smooth CoffeeScript](http://autotelicum.github.io/Smooth-CoffeeScript/)
-- [CoffeeScript Ristretto](https://leanpub.com/coffeescript-ristretto/read) \ No newline at end of file
+- [CoffeeScript Ristretto](https://leanpub.com/coffeescript-ristretto/read)
diff --git a/pt-br/common-lisp-pt.html.markdown b/pt-br/common-lisp-pt.html.markdown
index 03a7c15c..c22cfd8e 100644
--- a/pt-br/common-lisp-pt.html.markdown
+++ b/pt-br/common-lisp-pt.html.markdown
@@ -19,7 +19,7 @@ Outro livro recente e popular é o
[Land of Lisp](http://landoflisp.com/).
-```common_lisp
+```lisp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 0. Sintaxe
diff --git a/pt-br/csharp.html.markdown b/pt-br/csharp-pt.html.markdown
index 547f4817..384ca325 100644
--- a/pt-br/csharp.html.markdown
+++ b/pt-br/csharp-pt.html.markdown
@@ -6,23 +6,23 @@ contributors:
lang: pt-br
---
-C# é uma linguagem elegante e altamente tipado orientada a objetos que permite aos desenvolvedores criarem uma variedade de aplicações seguras e robustas que são executadas no .NET Framework.
+C# é uma linguagem elegante, altamente tipada e orientada a objetos que permite aos desenvolvedores criar uma variedade de aplicações seguras e robustas que são executadas no .NET Framework.
-[Read more here.](http://msdn.microsoft.com/pt-br/library/vstudio/z1zx9t92.aspx)
+[Leia mais aqui.](http://msdn.microsoft.com/pt-br/library/vstudio/z1zx9t92.aspx)
```c#
-// Comentário de linha única começa com //
+// Comentários de linha única começam com //
/*
-Múltipas linhas é desta forma
+Comentários de múltiplas linhas são desta forma
*/
/// <summary>
-/// Esta é uma documentação comentário XML que pode ser usado para gerar externo
-/// documentação ou fornecer ajuda de contexto dentro de um IDE
+/// Este é um comentário de documentação XML que pode ser usado para gerar documentação
+/// externa ou para fornecer ajuda de contexto dentro de uma IDE
/// </summary>
//public void MethodOrClassOrOtherWithParsableHelp() {}
-// Especificar qual namespace seu código irá usar
-// Os namespaces a seguir são padrões do .NET Framework Class Library
+// Especifica os namespaces que o código irá usar
+// Os namespaces a seguir são padrões da biblioteca de classes do .NET Framework
using System;
using System.Collections.Generic;
using System.Dynamic;
@@ -33,11 +33,11 @@ using System.IO;
// Mas este aqui não é :
using System.Data.Entity;
-// Para que consiga utiliza-lo, você precisa adicionar novas referências
+// Para que consiga utilizá-lo, você precisa adicionar novas referências
// Isso pode ser feito com o gerenciador de pacotes NuGet : `Install-Package EntityFramework`
-// Namespaces são escopos definidos para organizar o códgo em "pacotes" or "módulos"
-// Usando este código a partir de outra arquivo de origem: using Learning.CSharp;
+// Namespaces são escopos definidos para organizar o código em "pacotes" ou "módulos"
+// Usando este código a partir de outro arquivo de origem: using Learning.CSharp;
namespace Learning.CSharp
{
// Cada .cs deve conter uma classe com o mesmo nome do arquivo
@@ -59,7 +59,7 @@ namespace Learning.CSharp
Console.Write("World");
///////////////////////////////////////////////////
- // Tpos e Variáveis
+ // Tipos e Variáveis
//
// Declare uma variável usando <tipo> <nome>
///////////////////////////////////////////////////
@@ -78,15 +78,17 @@ namespace Learning.CSharp
short fooShort = 10000;
ushort fooUshort = 10000;
- // Integer - 32-bit integer
+ // Integer - inteiro de 32 bits
int fooInt = 1; // (-2,147,483,648 <= int <= 2,147,483,647)
uint fooUint = 1; // (0 <= uint <= 4,294,967,295)
-
+ //Números por padrão são int ou uint, dependendo do tamanho.
+
// Long - 64-bit integer
long fooLong = 100000L; // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807)
ulong fooUlong = 100000L; // (0 <= ulong <= 18,446,744,073,709,551,615)
- // Numbers default to being int or uint depending on size.
- // L is used to denote that this variable value is of type long or ulong
+
+ // Números por padrão são int ou uint dependendo do tamanho.
+ // L é usado para denotar que o valor da variável é do tipo long ou ulong.
// Double - Double-precision 64-bit IEEE 754 Floating Point
double fooDouble = 123.4; // Precision: 15-16 digits
@@ -95,8 +97,8 @@ namespace Learning.CSharp
float fooFloat = 234.5f; // Precision: 7 digits
// f is used to denote that this variable value is of type float
- // Decimal - a 128-bits data type, with more precision than other floating-point types,
- // suited for financial and monetary calculations
+ // Decimal - um tipo de dados de 128 bits, com mais precisão do que outros tipos de ponto flutuante,
+ // adequado para cálculos financeiros e monetários
decimal fooDecimal = 150.3m;
// Boolean - true & false
@@ -294,9 +296,9 @@ on a new line! ""Wow!"", the masses cried";
case 3:
monthString = "March";
break;
- // You can assign more than one case to an action
- // But you can't add an action without a break before another case
- // (if you want to do this, you would have to explicitly add a goto case x
+ // Você pode declarar mais de um "case" para uma ação
+ // Mas você não pode adicionar uma ação sem um "break" antes de outro "case"
+ // (se você quiser fazer isso, você tem que explicitamente adicionar um "goto case x")
case 6:
case 7:
case 8:
@@ -308,25 +310,26 @@ on a new line! ""Wow!"", the masses cried";
}
///////////////////////////////////////
- // Converting Data Types And Typecasting
+ // Convertendo Data Types e Typecasting
///////////////////////////////////////
- // Converting data
+ // Convertendo dados
+
+ // Converter String para Integer
- // Convert String To Integer
- // this will throw a FormatException on failure
- int.Parse("123");//returns an integer version of "123"
+ // isso vai jogar um erro FormatException quando houver falha
+ int.Parse("123");//retorna uma verão em Integer da String "123"
- // try parse will default to type default on failure
- // in this case: 0
+ // try parse vai ir por padrão para o typo default quando houver uma falha
+ // nesse caso: 0
int tryInt;
- if (int.TryParse("123", out tryInt)) // Function is boolean
+ if (int.TryParse("123", out tryInt)) // Função booleana
Console.WriteLine(tryInt); // 123
- // Convert Integer To String
- // Convert class has a number of methods to facilitate conversions
+ // Converter Integer para String
+ // A classe Convert possuí métodos para facilitar as conversões
Convert.ToString(123);
- // or
+ // ou
tryInt.ToString();
// Casting
@@ -336,28 +339,28 @@ on a new line! ""Wow!"", the masses cried";
}
///////////////////////////////////////
- // CLASSES - see definitions at end of file
+ // CLASSES - Veja definições no fim do arquivo
///////////////////////////////////////
public static void Classes()
{
- // See Declaration of objects at end of file
+ // Veja Declaração de objetos no fim do arquivo
- // Use new to instantiate a class
+ // Use new para instanciar uma classe
Bicycle trek = new Bicycle();
- // Call object methods
- trek.SpeedUp(3); // You should always use setter and getter methods
+ // Chame métodos do objeto
+ trek.SpeedUp(3); // Você deve sempre usar métodos setter e getter
trek.Cadence = 100;
- // ToString is a convention to display the value of this Object.
+ // ToString é uma convenção para exibir o valor desse Objeto.
Console.WriteLine("trek info: " + trek.Info());
- // Instantiate a new Penny Farthing
+ // Instancie um novo Penny Farthing
PennyFarthing funbike = new PennyFarthing(1, 10);
Console.WriteLine("funbike info: " + funbike.Info());
Console.Read();
- } // End main method
+ } // Fim do método principal
// CONSOLE ENTRY A console application must have a main method as an entry point
public static void Main(string[] args)
@@ -407,12 +410,12 @@ on a new line! ""Wow!"", the masses cried";
return result;
}
- // You can narrow down the objects that are passed in
+ // Você pode pode restringir os objetos que são passados
public static void IterateAndPrint<T>(T toPrint) where T: IEnumerable<int>
{
- // We can iterate, since T is a IEnumerable
+ // Nos podemos iterar, desde que T seja um "IEnumerable"
foreach (var item in toPrint)
- // Item is an int
+ // Item é um inteiro
Console.WriteLine(item.ToString());
}
@@ -522,7 +525,7 @@ on a new line! ""Wow!"", the masses cried";
foreach (var key in responses.Keys)
Console.WriteLine("{0}:{1}", key, responses[key]);
- // DYNAMIC OBJECTS (great for working with other languages)
+ // OBJETOS DINÂMICOS (ótimo para trabalhar com outros idiomas)
dynamic student = new ExpandoObject();
student.FirstName = "First Name"; // No need to define class first!
@@ -720,9 +723,9 @@ on a new line! ""Wow!"", the masses cried";
_speed -= decrement;
}
- // properties get/set values
- // when only data needs to be accessed, consider using properties.
- // properties may have either get or set, or both
+ // propriedade recupera e/ou atribui valores (get/set).
+ // quando os dados precisam apenas ser acessados, considere o uso de propriedades.
+ // uma propriedade pode ter "get" ou "set", ou ambos.
private bool _hasTassles; // private variable
public bool HasTassles // public accessor
{
@@ -730,10 +733,10 @@ on a new line! ""Wow!"", the masses cried";
set { _hasTassles = value; }
}
- // You can also define an automatic property in one line
- // this syntax will create a backing field automatically.
- // You can set an access modifier on either the getter or the setter (or both)
- // to restrict its access:
+ // Você também pode definir uma propriedade automática em uma linha
+        // Esta sintaxe criará um campo de apoio automaticamente.
+        // Você pode definir um modificador de acesso no getter ou no setter (ou ambos)
+        // para restringir seu acesso:
public bool IsBroken { get; private set; }
// Properties can be auto-implemented
@@ -762,7 +765,7 @@ on a new line! ""Wow!"", the masses cried";
}
}
- //Method to display the attribute values of this Object.
+ //Método para exibir os valores dos atributos deste objeto.
public virtual string Info()
{
return "Gear: " + Gear +
@@ -784,13 +787,13 @@ on a new line! ""Wow!"", the masses cried";
} // end class Bicycle
- // PennyFarthing is a subclass of Bicycle
+ // PennyFarthing é uma subclasse de Bicycle
class PennyFarthing : Bicycle
{
- // (Penny Farthings are those bicycles with the big front wheel.
- // They have no gears.)
+ // (Penny Farthings são aquelas bicicletas com uma grande roda frontal.
+ // Elas não tem correias.)
- // calling parent constructor
+ // chamando construtor pai
public PennyFarthing(int startCadence, int startSpeed) :
base(startCadence, startSpeed, 0, "PennyFarthing", true, BikeBrand.Electra)
{
@@ -823,10 +826,10 @@ on a new line! ""Wow!"", the masses cried";
}
}
- // Interfaces only contain signatures of the members, without the implementation.
+ // Interfaces contêm apenas as assinaturas dos membros, sem a implementação.
interface IJumpable
{
- void Jump(int meters); // all interface members are implicitly public
+ void Jump(int meters); // todos os membros da interface são implicitamente públicos
}
interface IBreakable
@@ -834,7 +837,7 @@ on a new line! ""Wow!"", the masses cried";
bool Broken { get; } // interfaces can contain properties as well as methods & events
}
- // Class can inherit only one other class, but can implement any amount of interfaces
+ // Classes podem herdar apenas de uma outra classe, mas podem implementar qualquer quantidade de interfaces.
class MountainBike : Bicycle, IJumpable, IBreakable
{
int damage = 0;
@@ -854,8 +857,8 @@ on a new line! ""Wow!"", the masses cried";
}
/// <summary>
- /// Used to connect to DB for LinqToSql example.
- /// EntityFramework Code First is awesome (similar to Ruby's ActiveRecord, but bidirectional)
+ /// Exemplo de como conectar-se ao DB via LinqToSql.
+    /// EntityFramework First Code é impressionante (semelhante ao ActiveRecord de Ruby, mas bidirecional)
/// http://msdn.microsoft.com/en-us/data/jj193542.aspx
/// </summary>
public class BikeRepository : DbContext
diff --git a/pt-br/css-pt.html.markdown b/pt-br/css-pt.html.markdown
index b1fbd961..e6dea5b8 100644
--- a/pt-br/css-pt.html.markdown
+++ b/pt-br/css-pt.html.markdown
@@ -9,23 +9,25 @@ contributors:
- ["Deepanshu Utkarsh", "https://github.com/duci9y"]
translators:
- ["Gabriel Gomes", "https://github.com/gabrielgomesferraz"]
+ - ["Gabriele Luz", "https://github.com/gabrieleluz"]
+
lang: pt-br
---
-Nos primeiros dias da web não havia elementos visuais, apenas texto puro. Mas com maior desenvolvimento de navegadores da web, páginas web totalmente visuais também se tornou comum.
+No início da web não havia elementos visuais, apenas texto puro. Mas com maior desenvolvimento de navegadores da web, páginas web totalmente visuais também se tornaram comuns.
-CSS ajuda a manter a separação entre o conteúdo (HTML) e o look-and-feel de uma página web.
+CSS ajuda a manter a separação entre o conteúdo (HTML) e o visual de uma página web.
CSS permite atingir diferentes elementos em uma página HTML e atribuir diferentes propriedades visuais para eles.
-Este guia foi escrito para CSS2, embora CSS3 está rapidamente se tornando popular.
+Este guia foi escrito para CSS2, embora CSS3 esteja rapidamente se tornando popular.
-**NOTA:** Porque CSS produz resultados visuais, a fim de aprender, você precisa tentar de tudo em um playground CSS como [dabblet](http://dabblet.com/).
+**NOTA:** Porque CSS produz resultados visuais, a fim de aprender, você precisa treinar em um playground CSS como [dabblet](http://dabblet.com/).
O foco principal deste artigo é sobre a sintaxe e algumas dicas gerais.
```css
/* Comentários aparecem dentro do slash-asterisk, tal como esta linha!
- não há "comentários de uma linha"; este é o único estilo de comentário * /
+ Não há "comentários de uma linha"; este é o único estilo de comentário * /
/* ####################
## SELETORES
@@ -40,7 +42,7 @@ Abaixo um elemento de exemplo:
<div class='class1 class2' id='anID' attr='value' otherAttr='pt-br foo bar' />
*/
-/* Você pode direciona-lo usando uma das suas classes CSS */
+/* Você pode direcioná-lo usando uma das suas classes CSS */
.class1 { }
/* ou ambas as classes! */
@@ -80,9 +82,9 @@ classe div.some [attr $ = 'ue'] {}
/* Você pode selecionar um elemento que é filho de outro elemento */
div.some-parent> .class-name {}
-/* Ou um descendente de um outro elemento. As crianças são os descendentes diretos de
-   seu elemento pai, apenas um nível abaixo da árvore. Pode ser qualquer descendentes
-   nivelar por baixo da árvore. */
+/* Ou um descendente de um outro elemento. Os filhos são os descendentes diretos de
+   seu elemento pai, apenas um nível abaixo da árvore. Pode ser quaisquer descendentes
+   nivelados por baixo da árvore. */
div.some-parent class-name {}
/* Atenção: o mesmo seletor sem espaço tem um outro significado.
@@ -95,7 +97,7 @@ div.some-parent.class-name {}
/* Ou qualquer irmão que o precede */
.i am-qualquer-elemento antes ~ .Este elemento {}
-/* Existem alguns selectores chamado pseudo classes que podem ser usados para selecionar um
+/* Existem alguns seletores chamados pseudo classes que podem ser usados para selecionar um
   elemento quando ele está em um determinado estado */
/* Por exemplo, quando o cursor passa sobre um elemento */
@@ -116,7 +118,7 @@ seletor:first-child {}
/* Qualquer elemento que é o último filho de seu pai */
seletor:last-child {}
-/* Assim como pseudo classes, pseudo elementos permitem que você estilo certas partes de um documento */
+/* Assim como pseudo classes, pseudo elementos permitem que você estilize certas partes de um documento */
/* Corresponde a um primeiro filho virtual do elemento selecionado */
seletor::before {}
@@ -125,10 +127,10 @@ seletor::before {}
seletor::after {}
/* Nos locais apropriados, um asterisco pode ser utilizado como um curinga para selecionar todos
-   elemento */
+   os elementos */
* {} /* */ Todos os elementos
.parent * {} /* */ todos os descendentes
-.parent> * {} /* */ todas as crianças
+.parent> * {} /* */ todos os filhos
/* ####################
   ## PROPRIEDADES
@@ -139,7 +141,7 @@ seletor {
    /* Unidades de comprimento pode ser absoluta ou relativa. */
    /* Unidades relativas */
-    width: 50%; /* Percentagem de largura elemento pai */
+    width: 50%; /* Percentagem de largura do elemento pai */
    font-size: 2em; /* Múltiplos de font-size original de elemento */
    font-size: 2rem; /* Ou do elemento raiz font-size */
    font-size: 2vw; /* Múltiplos de 1% da largura da janela de exibição (CSS 3) */
@@ -179,7 +181,7 @@ seletor {
## Uso
-Guardar uma folha de estilo CSS com a extensão `.css`.
+Salvar uma folha de estilo CSS com a extensão `.css`.
```xml
<!-- Você precisa incluir o arquivo css no da sua página <head>. Isto é o
@@ -198,7 +200,7 @@ Guardar uma folha de estilo CSS com a extensão `.css`.
## Precedência ou Cascata
-Um elemento pode ser alvo de vários seletores e pode ter um conjunto de propriedades em que mais de uma vez. Nestes casos, uma das regras tem precedência sobre os outros. Geralmente, uma regra em um seletor mais específico têm precedência sobre um menos específico, e uma regra que ocorre mais tarde na folha de estilo substitui uma anterior.
+Um elemento pode ser alvo de vários seletores e pode ter um conjunto de propriedades em que mais de uma vez. Nestes casos, uma das regras tem precedência sobre as outras. Geralmente, uma regra em um seletor mais específico têm precedência sobre um menos específico, e uma regra que ocorre mais tarde na folha de estilo substitui uma anterior.
Este processo é chamado de cascata, portanto, as Fichas de nome de estilo em cascata.
@@ -236,9 +238,48 @@ A precedência de estilo é a seguinte. Lembre-se, a precedência é para cada
* `B` é o próximo.
* `D` é a última.
+## Media Queries
+Media queries são recursos do CSS3 que permitem especificar quando determinadas regras de CSS devem ser aplicadas; é possível aplicar regras diferentes quando a página é impressa, quando a tela possui determinadas dimensões ou densidade de pixels e quando é lida por um leitor de tela. Media queries não adicionam especificidade ao seletor.
+
+```css
+/* Uma regra que será aplicada a todos os dispositivos */
+h1 {
+ font-size: 2em;
+ color: white;
+ background-color: black;
+}
+
+/* Altera a cor do h1 para utilizar menos tinta durante a impressão */
+@media print {
+ h1 {
+ color: black;
+ background-color: white;
+ }
+}
+
+/* Altera o tamanho da fonte quando exibida numa tela com pelo menos 480px de largura */
+@media screen and (min-width: 480px) {
+ h1 {
+ font-size: 3em;
+ font-weight: normal;
+ }
+}
+```
+Media queries podem incluir os seguintes atributos: `width`, `height`, `device-width`, `device-height`, `orientation`, `aspect-ratio`, `device-aspect-ratio`, `color`, `color-index`, `monochrome`, `resolution`, `scan`, `grid`. A maioria desses atributos pode ser prefixada com `min-` ou `max-`.
+
+O atributo `resolution` não é suportado em dispositivos mais antigos. Em vez disso, use `device-pixel-ratio`.
+
+Muitos smartphones e tablets tentarão renderizar a página como se estivesse num desktop a menos que você utilize a meta-tag `viewport`.
+
+```html
+<head>
+ <meta name="viewport" content="width=device-width; initial-scale=1.0">
+</head>
+```
+
## Compatibilidade
-A maior parte dos recursos do CSS 2 (e muitos em CSS 3) estão disponíveis em todos os navegadores e dispositivos. Mas é sempre boa prática para verificar antes de usar um novo recurso.
+A maior parte dos recursos do CSS 2 (e muitos em CSS 3) estão disponíveis em todos os navegadores e dispositivos. Mas é sempre boa prática verificar antes de usar um novo recurso.
## Recursos
diff --git a/pt-br/cypher-pt.html.markdown b/pt-br/cypher-pt.html.markdown
new file mode 100644
index 00000000..d4400148
--- /dev/null
+++ b/pt-br/cypher-pt.html.markdown
@@ -0,0 +1,250 @@
+---
+language: cypher
+filename: LearnCypher-br.cql
+contributors:
+ - ["Théo Gauchoux", "https://github.com/TheoGauchoux"]
+
+lang: pt-br
+---
+
+O Cypher é a linguagem de consulta do Neo4j para manipular gráficos facilmente. Ela reutiliza a sintaxe do SQL e a mistura com o tipo de ascii-art para representar gráficos. Este tutorial pressupõe que você já conheça conceitos de gráficos como nós e relacionamentos.
+
+[Leia mais aqui.](https://neo4j.com/developer/cypher-query-language/)
+
+
+Nós
+---
+
+**Representa um registro em um gráfico.**
+
+`()`
+É um *nó* vazio, para indicar que existe um *nó*, mas não é relevante para a consulta.
+
+`(n)`
+É um *nó* referido pela variável **n**, reutilizável na consulta. Começa com minúsculas e usa o camelCase.
+
+`(p:Person)`
+Você pode adicionar um *label* ao seu nó, aqui **Person**. É como um tipo / uma classe / uma categoria. Começa com maiúsculas e usa o camelCase.
+
+`(p:Person:Manager)`
+Um nó pode ter muitos *labels*.
+
+`(p:Person {name : 'Théo Gauchoux', age : 22})`
+Um nó pode ter algumas *propriedades*, aqui **name** e **age**. Começa com minúsculas e usa o camelCase.
+
+Os tipos permitidos nas propriedades:
+
+ - Numeric
+ - Boolean
+ - String
+ - Lista de tipos primitivos anteriores
+
+*Aviso: não há propriedade datetime no Cypher! Você pode usar String com um padrão específico ou um Numeric a partir de uma data específica.*
+
+`p.name`
+Você pode acessar uma propriedade com o estilo de ponto.
+
+
+Relacionamentos (ou Arestas)
+---
+
+**Conecta dois nós**
+
+`[:KNOWS]`
+É um *relacionamento* com o *label* **KNOWS**. É um *label* como um rótulo do nó. Começa com maiúsculas e usa UPPER_SNAKE_CASE.
+
+`[k:KNOWS]`
+O mesmo *relacionamento*, referido pela variável **k**, reutilizável na consulta, mas não é necessário.
+
+`[k:KNOWS {since:2017}]`
+O mesmo *relacionamento*, com *propriedades* (como *nó*), aqui **since**.
+
+`[k:KNOWS*..4]`
+É uma informação estrutural para usar em um *path* (visto posteriormente). Aqui, **\*..4** diz, “Corresponda o padrão, com a relação **k** que é repetida de 1 a 4 vezes.
+
+
+Paths
+---
+
+**A maneira de misturar nós e relacionamentos.**
+
+`(a:Person)-[:KNOWS]-(b:Person)`
+Um path descrevendo que **a** e **b** se conhecem.
+
+`(a:Person)-[:MANAGES]->(b:Person)`
+Um path pode ser direcionado. Este path descreve que **a** é o gerente de **b**.
+
+`(a:Person)-[:KNOWS]-(b:Person)-[:KNOWS]-(c:Person)`
+Você pode encadear vários relacionamentos. Este path descreve o amigo de um amigo.
+
+`(a:Person)-[:MANAGES]->(b:Person)-[:MANAGES]->(c:Person)`
+Uma encadeamento também pode ser direcionada. Este path descreve que **a** é o chefe de **b** e o grande chefe de **c**.
+
+Padrões frequentemente usados ​​(do Neo4j doc) :
+
+```
+// Amigo de um amigo
+(user)-[:KNOWS]-(friend)-[:KNOWS]-(foaf)
+
+// Path mais curto
+path = shortestPath( (user)-[:KNOWS*..5]-(other) )
+
+// Filtragem colaborativa
+(user)-[:PURCHASED]->(product)<-[:PURCHASED]-()-[:PURCHASED]->(otherProduct)
+
+// Navegação de árvore
+(root)<-[:PARENT*]-(leaf:Category)-[:ITEM]->(data:Product)
+
+```
+
+
+Crie consultas
+---
+
+Crie um novo nó
+```
+CREATE (a:Person {name:"Théo Gauchoux"})
+RETURN a
+```
+*`RETURN` permite ter um resultado após a consulta. Pode ser múltiplo, como `RETURN a, b`.*
+
+Crie um novo relacionamento (com 2 novos nós)
+```
+CREATE (a:Person)-[k:KNOWS]-(b:Person)
+RETURN a,k,b
+```
+
+Consultas que casam
+---
+
+Casam todos os nós
+```
+MATCH (n)
+RETURN n
+```
+
+Casam nós por label
+```
+MATCH (a:Person)
+RETURN a
+```
+
+Casam nós por label e propriedade
+```
+MATCH (a:Person {name:"Théo Gauchoux"})
+RETURN a
+```
+
+Casam nós de acordo com os relacionamentos (não direcionados)
+```
+MATCH (a)-[:KNOWS]-(b)
+RETURN a,b
+```
+
+Casam nós de acordo com os relacionamentos (direcionados)
+```
+MATCH (a)-[:MANAGES]->(b)
+RETURN a,b
+```
+
+Casam nós com um cláusula `WHERE`
+```
+MATCH (p:Person {name:"Théo Gauchoux"})-[s:LIVES_IN]->(city:City)
+WHERE s.since = 2015
+RETURN p,state
+```
+
+Você pode usa a cláusula `MATCH WHERE` com a cláusula `CREATE`
+```
+MATCH (a), (b)
+WHERE a.name = "Jacquie" AND b.name = "Michel"
+CREATE (a)-[:KNOWS]-(b)
+```
+
+
+Atualizar consultas
+---
+
+Atualizar uma propriedade específica de um nó
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+SET p.age = 23
+```
+
+Substituir todas as propriedades de um nó
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+SET p = {name: "Michel", age: 23}
+```
+
+Adicionar nova propriedade a um nó
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+SET p + = {studies: "IT Engineering"}
+```
+
+Adicione um label a um nó
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+SET p:Internship
+```
+
+
+Excluir consultas
+---
+
+Excluir um nó específico (os relacionamentos vinculados devem ser excluídos antes)
+```
+MATCH (p:Person)-[relationship]-()
+WHERE p.name = "Théo Gauchoux"
+DELETE relationship, p
+```
+
+Remover uma propriedade em um nó específico
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+REMOVE p.age
+```
+*Prestar atenção à palavra chave `REMOVE`, não é `DELETE` !*
+
+Remover um label de um nó específico
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+DELETE p:Person
+```
+
+Excluir o banco de dados inteiro
+```
+MATCH (n)
+OPTIONAL MATCH (n)-[r]-()
+DELETE n, r
+```
+*Sério, é o `rm -rf /` do Cypher !*
+
+
+Outras cláusulas úteis
+---
+
+`PROFILE`
+Antes de uma consulta, mostre o plano de execução dela.
+
+`COUNT(e)`
+Contar entidades (nós ou relacionamentos) que casam com **e**.
+
+`LIMIT x`
+Limite o resultado aos primeiros x resultados.
+
+
+Dicas Especiais
+---
+
+- Há apenas comentários de uma linha no Cypher, com barras duplas : // Comentários
+- Você pode executar um script Cypher armazenado em um arquivo **.cql** diretamente no Neo4j (é uma importação). No entanto, você não pode ter várias instruções neste arquivo (separadas por **;**).
+- Use o shell Neo4j para escrever Cypher, é realmente incrível.
+- O Cypher será a linguagem de consulta padrão para todos os bancos de dados de gráficos (conhecidos como **OpenCypher**).
diff --git a/pt-br/dart-pt.html.markdown b/pt-br/dart-pt.html.markdown
new file mode 100644
index 00000000..e9d72850
--- /dev/null
+++ b/pt-br/dart-pt.html.markdown
@@ -0,0 +1,509 @@
+---
+language: dart
+filename: learndart-pt.dart
+contributors:
+ - ["Joao Pedrosa", "https://github.com/jpedrosa/"]
+translators:
+ - ["Junior Damacena", "https://github.com/jdamacena/"]
+lang: pt-br
+---
+
+Dart é uma novata no reino das linguagens de programação.
+Ela empresta muito de outras linguagens mais conhecidas, e tem a meta de não se diferenciar muito de seu irmão, JavaScript. Assim como JavaScript, Dart foi pensada para oferecer grande integração com o Browser.
+
+A característica mais controversa da Dart é a sua Tipagem Opcional, ou seja, não é obrigatório declarar tipos.
+
+```dart
+import "dart:collection";
+import "dart:math" as DM;
+
+// Bem vindo ao Aprenda Dart em 15 minutos. http://www.dartlang.org/
+// Este é um tutorial executável. Você pode rodar esse tutorial com Dart ou no
+// site Try Dart!, é só copiar e colar este código lá. http://try.dartlang.org/
+
+// Declarações de funções e métodos são iguais. Declarações de funções
+// podem ser aninhadas. A declaração é feita das seguintes formas
+// nome() {} ou nome() => expressaoDeUmaLinhaSo;
+// A declaração feita com a seta tem um return implícito para o resultado da
+// expressão.
+example1() {
+ example1nested1() {
+ example1nested2() => print("Example1 nested 1 nested 2");
+ example1nested2();
+ }
+ example1nested1();
+}
+
+// Funções anônimas são criadas sem um nome.
+example2() {
+ example2nested1(fn) {
+ fn();
+ }
+ example2nested1(() => print("Example2 nested 1"));
+}
+
+// Quando uma função é declarada como parâmetro, a declaração pode incluir o número
+// de parâmetros que a função recebe, isso é feito especificando o nome de cada um dos
+// parâmetros que serão recebidos pela função.
+example3() {
+ example3nested1(fn(informSomething)) {
+ fn("Example3 nested 1");
+ }
+ example3planB(fn) { // Ou não declare o número de parâmetros.
+ fn("Example3 plan B");
+ }
+ example3nested1((s) => print(s));
+ example3planB((s) => print(s));
+}
+
+// Funções têm acesso à variáveis fora de seu escopo
+var example4Something = "Example4 nested 1";
+example4() {
+ example4nested1(fn(informSomething)) {
+ fn(example4Something);
+ }
+ example4nested1((s) => print(s));
+}
+
+// Declaração de classe com um método chamado sayIt, que também tem acesso
+// à variável externa, como se fosse uma função como se viu antes.
+var example5method = "Example5 sayIt";
+class Example5Class {
+ sayIt() {
+ print(example5method);
+ }
+}
+example5() {
+ // Criar uma instância anônima de Example5Class e chamar o método sayIt
+ // nela.
+ new Example5Class().sayIt();
+}
+
+// A declaração de uma classe é feita da seguinte maneira: class name { [classBody] }.
+// onde classBody pode incluir métodos e variáveis de instância, assim como
+// métodos e variáveis de classe.
+class Example6Class {
+ var example6InstanceVariable = "Example6 instance variable";
+ sayIt() {
+ print(example6InstanceVariable);
+ }
+}
+example6() {
+ new Example6Class().sayIt();
+}
+
+// Métodos e variáveis de classe são declarados como "static".
+class Example7Class {
+ static var example7ClassVariable = "Example7 class variable";
+ static sayItFromClass() {
+ print(example7ClassVariable);
+ }
+ sayItFromInstance() {
+ print(example7ClassVariable);
+ }
+}
+example7() {
+ Example7Class.sayItFromClass();
+ new Example7Class().sayItFromInstance();
+}
+
+// Literais são ótimos, mas há uma limitação para o que eles podem ser
+// quando estão fora do corpo de uma função/método. Literais fora do escopo da classe
+// ou fora da classe têm que ser constantes. Strings e números são constantes
+// por padrão. Mas arrays e mapas não. Eles podem ser declarados como constantes
+// usando o comando "const".
+var example8A = const ["Example8 const array"],
+ example8M = const {"someKey": "Example8 const map"};
+example8() {
+ print(example8A[0]);
+ print(example8M["someKey"]);
+}
+
+// Loops em Dart são criados com for () {} ou while () {},
+// um pouco mais moderno temos for (.. in ..) {}, ou funções de callbacks com muitas
+// funcionalidades, começando com o forEach.
+var example9A = const ["a", "b"];
+example9() {
+ for (var i = 0; i < example9A.length; i++) {
+ print("Example9 for loop '${example9A[i]}'");
+ }
+ var i = 0;
+ while (i < example9A.length) {
+ print("Example9 while loop '${example9A[i]}'");
+ i++;
+ }
+ for (var e in example9A) {
+ print("Example9 for-in loop '${e}'");
+ }
+ example9A.forEach((e) => print("Example9 forEach loop '${e}'"));
+}
+
+// Para percorrer os caracteres de uma string ou extrair uma substring.
+var example10S = "ab";
+example10() {
+ for (var i = 0; i < example10S.length; i++) {
+ print("Example10 String character loop '${example10S[i]}'");
+ }
+ for (var i = 0; i < example10S.length; i++) {
+ print("Example10 substring loop '${example10S.substring(i, i + 1)}'");
+ }
+}
+
+// Int e double são os dois formatos de número suportados.
+example11() {
+ var i = 1 + 320, d = 3.2 + 0.01;
+ print("Example11 int ${i}");
+ print("Example11 double ${d}");
+}
+
+// DateTime traz operações com data/hora.
+example12() {
+ var now = new DateTime.now();
+ print("Example12 now '${now}'");
+ now = now.add(new Duration(days: 1));
+ print("Example12 tomorrow '${now}'");
+}
+
+// Expressões regulares são suportadas.
+example13() {
+ var s1 = "some string", s2 = "some", re = new RegExp("^s.+?g\$");
+ match(s) {
+ if (re.hasMatch(s)) {
+ print("Example13 regexp matches '${s}'");
+ } else {
+ print("Example13 regexp doesn't match '${s}'");
+ }
+ }
+ match(s1);
+ match(s2);
+}
+
+// Expressões booleanas precisam retornar ou true ou false, já que
+// Dart não faz a conversão implicitamente.
+example14() {
+ var v = true;
+ if (v) {
+ print("Example14 value is true");
+ }
+ v = null;
+ try {
+ if (v) {
+ // Nunca seria executada
+ } else {
+ // Nunca seria executada
+ }
+ } catch (e) {
+ print("Example14 null value causes an exception: '${e}'");
+ }
+}
+
+// try/catch/finally e throw são usados para tratamento de exceções.
+// throw aceita qualquer objeto como parâmetro;
+example15() {
+ try {
+ try {
+ throw "Some unexpected error.";
+ } catch (e) {
+ print("Example15 an exception: '${e}'");
+ throw e; // Re-throw
+ }
+ } catch (e) {
+ print("Example15 catch exception being re-thrown: '${e}'");
+ } finally {
+ print("Example15 Still run finally");
+ }
+}
+
+// Para mais eficiência ao criar strings longas dinamicamente, use o
+// StringBuffer. Ou você pode também concatenar um array de strings.
+example16() {
+ var sb = new StringBuffer(), a = ["a", "b", "c", "d"], e;
+ for (e in a) { sb.write(e); }
+ print("Example16 dynamic string created with "
+ "StringBuffer '${sb.toString()}'");
+ print("Example16 join string array '${a.join()}'");
+}
+
+// Strings podem ser concatenadas apenas colocando strings literais uma perto
+// da outra, sem necessidade de nenhum outro operador.
+example17() {
+ print("Example17 "
+ "concatenar "
+ "strings "
+ "é simples assim");
+}
+
+// Strings podem ser delimitadas por apóstrofos ou aspas e não há
+// diferença entre os dois. Essa flexibilidade pode ser boa para
+// evitar a necessidade de escapar conteúdos que contenham o delimitador da string.
+// Por exemplo, aspas dos atributos HTMLse a string conter HTML.
+example18() {
+ print('Example18 <a href="etc">'
+ "Don't can't I'm Etc"
+ '</a>');
+}
+
+// Strings com três apóstrofos ou aspas podem
+// ter muitas linhas e incluem os delimitadores de linha (ou seja, os enter).
+example19() {
+ print('''Example19 <a href="etc">
+Example19 Don't can't I'm Etc
+Example19 </a>''');
+}
+
+// Strings têm a função de interpolação que é chamada com o caractere $.
+// Com $ { [expression] }, o retorno da expressão é interpolado.
+// $ seguido pelo nome de uma variável interpola o conteúdo dessa variável.
+// $ pode ser escapedo assim \$.
+example20() {
+ var s1 = "'\${s}'", s2 = "'\$s'";
+ print("Example20 \$ interpolation ${s1} or $s2 works.");
+}
+
+// A tipagem opcional permite que APIs usem anotações e também ajuda os
+// IDEs na hora das refatorações, auto-complete e checagem de
+// erros. Note que até agora não declaramos nenhum tipo e o programa está
+// funcionando normalmente. De fato, os tipos são ignorados em tempo de execução.
+// Os tipos podem até mesmo estarem errados e o programa ainda vai dar o
+// benefício da dúvida e rodar, visto que os tipos não importam.
+// Existe um parâmetro que checa erros de tipagem que é o
+// checked mode, dizem que é útil enquanto se está desenvolvendo,
+// mas também é mais lento devido às checagens extras e por isso
+// é evitado em ambiente de produção.
+class Example21 {
+ List<String> _names;
+ Example21() {
+ _names = ["a", "b"];
+ }
+ List<String> get names => _names;
+ set names(List<String> list) {
+ _names = list;
+ }
+ int get length => _names.length;
+ void add(String name) {
+ _names.add(name);
+ }
+}
+void example21() {
+ Example21 o = new Example21();
+ o.add("c");
+ print("Example21 names '${o.names}' and length '${o.length}'");
+ o.names = ["d", "e"];
+ print("Example21 names '${o.names}' and length '${o.length}'");
+}
+
+// Herança em classes é feito assim: class name extends AnotherClassName {}.
+class Example22A {
+ var _name = "Some Name!";
+ get name => _name;
+}
+class Example22B extends Example22A {}
+example22() {
+ var o = new Example22B();
+ print("Example22 class inheritance '${o.name}'");
+}
+
+// Mistura de classes também é possível, e é feito assim:
+// class name extends SomeClass with AnotherClassName {}
+// É necessário extender uma classe para poder misturar com outra.
+// No momento, classes misturadas não podem ter construtor.
+// Mistura de classes é mais usado para compartilhar métodos com classes distantes, então
+// a herança comum não fica no caminho do reuso de código.
+// As misturas aparecem após o comando "with" na declaração da classe.
+class Example23A {}
+class Example23Utils {
+ addTwo(n1, n2) {
+ return n1 + n2;
+ }
+}
+class Example23B extends Example23A with Example23Utils {
+ addThree(n1, n2, n3) {
+ return addTwo(n1, n2) + n3;
+ }
+}
+example23() {
+ var o = new Example23B(), r1 = o.addThree(1, 2, 3),
+ r2 = o.addTwo(1, 2);
+ print("Example23 addThree(1, 2, 3) results in '${r1}'");
+ print("Example23 addTwo(1, 2) results in '${r2}'");
+}
+
+// O método construtor da classe usa o mesmo nome da classe e
+// é feito assim SomeClass() : super() {}, onde a parte ": super()"
+// é opcional e é usada para passar parâmetros estáticos para o
+// construtor da classe pai.
+class Example24A {
+ var _value;
+ Example24A({value: "someValue"}) {
+ _value = value;
+ }
+ get value => _value;
+}
+class Example24B extends Example24A {
+ Example24B({value: "someOtherValue"}) : super(value: value);
+}
+example24() {
+ var o1 = new Example24B(),
+ o2 = new Example24B(value: "evenMore");
+ print("Example24 calling super during constructor '${o1.value}'");
+ print("Example24 calling super during constructor '${o2.value}'");
+}
+
+// Há um atalho para passar parâmetros para o construtor no caso de classes mais simples.
+// Simplesmente use o prefixo this.nomeDoParametro e isso irá passar o parâmetro para uma
+// instância de variável de mesmo nome.
+class Example25 {
+ var value, anotherValue;
+ Example25({this.value, this.anotherValue});
+}
+example25() {
+ var o = new Example25(value: "a", anotherValue: "b");
+ print("Example25 shortcut for constructor '${o.value}' and "
+ "'${o.anotherValue}'");
+}
+
+// Parâmetros com nome estão disponíveis quando declarados entre {}.
+// Quando os parâmetros têm nomes, eles podem ser passados em qualquer ordem.
+// Parâmetros declarados entre [] são opcionais.
+example26() {
+ var _name, _surname, _email;
+ setConfig1({name, surname}) {
+ _name = name;
+ _surname = surname;
+ }
+ setConfig2(name, [surname, email]) {
+ _name = name;
+ _surname = surname;
+ _email = email;
+ }
+ setConfig1(surname: "Doe", name: "John");
+ print("Example26 name '${_name}', surname '${_surname}', "
+ "email '${_email}'");
+ setConfig2("Mary", "Jane");
+ print("Example26 name '${_name}', surname '${_surname}', "
+ "email '${_email}'");
+}
+
+// Variáveis declaradas com um final só podem receber valor uma vez.
+// No caso de classes, variáveis final podem ter valor atribuido através
+// de um parâmetro no construtor
+class Example27 {
+ final color1, color2;
+ // Um pouco de flexibilidade ao criar variáveis final com a sintaxe
+ // que é a seguinte:
+ Example27({this.color1, color2}) : color2 = color2;
+}
+example27() {
+ final color = "orange", o = new Example27(color1: "lilac", color2: "white");
+ print("Example27 color is '${color}'");
+ print("Example27 color is '${o.color1}' and '${o.color2}'");
+}
+
+// para importar uma biblioteca, use import "libraryPath" ou se for uma biblioteca da linguagem,
+// import "dart:libraryName". Também tem o gerenciador de pacotes "pub"que tem
+// sua própria convenção de import "package:packageName".
+// Veja o import "dart:collection"; no início do arquivo. Imports devem vir no início
+// do arquivo. IterableBase vem de dart:collection.
+class Example28 extends IterableBase {
+ var names;
+ Example28() {
+ names = ["a", "b"];
+ }
+ get iterator => names.iterator;
+}
+example28() {
+ var o = new Example28();
+ o.forEach((name) => print("Example28 '${name}'"));
+}
+
+// Para controle de fluxo nós temos:
+// * switch com comandos break obrigatórios
+// * if-else if-else e se-ternário ..?..:..
+// * closures e funções anônimas
+// * comandos break, continue e return
+example29() {
+ var v = true ? 30 : 60;
+ switch (v) {
+ case 30:
+ print("Example29 switch statement");
+ break;
+ }
+ if (v < 30) {
+ } else if (v > 30) {
+ } else {
+ print("Example29 if-else statement");
+ }
+ callItForMe(fn()) {
+ return fn();
+ }
+ rand() {
+ v = new DM.Random().nextInt(50);
+ return v;
+ }
+ while (true) {
+ print("Example29 callItForMe(rand) '${callItForMe(rand)}'");
+ if (v != 30) {
+ break;
+ } else {
+ continue;
+ }
+ // Nunca chega aqui.
+ }
+}
+
+// Você pode converter string para int, double para int, ou só pegar a parte inteira da divisão
+// usando o comando ~/. Vamos jogar um jogo de adivinhação.
+example30() {
+ var gn, tooHigh = false,
+ n, n2 = (2.0).toInt(), top = int.parse("123") ~/ n2, bottom = 0;
+ top = top ~/ 6;
+ gn = new DM.Random().nextInt(top + 1); // +1 porque o máximo do nextInt conta o número passado - 1
+ print("Example30 Diga um número entre 0 e ${top}");
+ guessNumber(i) {
+ if (n == gn) {
+ print("Example30 Você acertou! O número é ${gn}");
+ } else {
+ tooHigh = n > gn;
+ print("Example30 O número ${n} é muito "
+ "${tooHigh ? 'alto' : 'baixo'}. Tente de novo");
+ }
+ return n == gn;
+ }
+ n = (top - bottom) ~/ 2;
+ while (!guessNumber(n)) {
+ if (tooHigh) {
+ top = n - 1;
+ } else {
+ bottom = n + 1;
+ }
+ n = bottom + ((top - bottom) ~/ 2);
+ }
+}
+
+// Programas em Dart só têm um ponto de entrada, que é a função main.
+// Nada será executado antes da funcão main de um programa.
+// Isso ajuda a carregar o programa mais rapidamente, até mesmo quando o
+// carregamento é "Lazy".
+// O programa deve começar com:
+main() {
+ print("Aprenda Dart em 15 minutos!");
+ [example1, example2, example3, example4, example5, example6, example7,
+ example8, example9, example10, example11, example12, example13, example14,
+ example15, example16, example17, example18, example19, example20,
+ example21, example22, example23, example24, example25, example26,
+ example27, example28, example29, example30
+ ].forEach((ef) => ef());
+}
+
+```
+
+## Continue lendo
+
+Dart tem um site bastante fácil de entender. Ele tem os docs da API, tutoriais, artigos e muito mais, incluindo uma
+opção muito útil de testar o Dart online.
+* [https://www.dartlang.org](https://www.dartlang.org)
+* [https://try.dartlang.org](https://try.dartlang.org)
+
+
+
+
diff --git a/pt-br/dynamic-programming-pt.html.markdown b/pt-br/dynamic-programming-pt.html.markdown
index 8de9bee6..93171955 100644
--- a/pt-br/dynamic-programming-pt.html.markdown
+++ b/pt-br/dynamic-programming-pt.html.markdown
@@ -22,16 +22,16 @@ Sempre se lembre!!
## Maneiras de Solucionar tais Problemas
-1. Top-Down (De cima para baixo): Começe solucionando o problema quebrando-o em
+1. Top-Down (De cima para baixo): Comece solucionando o problema quebrando-o em
partes. Se você perceber que o problema já foi resolvido, então simplemente
pegue a resposta salva. Se ainda não foi resolvido, solucione-o e salve a
resposta. Isso é geralmente fácil de pensar e muito intuitivo. É geralmente
referenciado como Memorização.
2. Bottom-Up (De baixo para cima): Analise o problema e veja a ordem em que os
-subproblemas são resolvidos e começe a solucionar dos problemas mais triviais,
+subproblemas são resolvidos e comece a solucionar dos problemas mais triviais,
até o problema dado. Neste processo, é garantido que os subproblemas são
-resolvidos antes de resoler o problema. Isto é referenciado como Programação Dinâmica.
+resolvidos antes de resolver o problema. Isto é referenciado como Programação Dinâmica.
## Exemplo de Programação Dinâmica
@@ -51,7 +51,7 @@ array antecedente e uma variável como maiorSequenciasAteAgora e seu índice
ajudariam a poupar muito tempo.
Um conceito similar poderia ser aplicado ao procurar o maior caminho em um
grafo acíclico dirigido.
----------------------------------------------------------------------------
+
```
for i=0 to n-1
LS[i]=1
@@ -62,14 +62,12 @@ grafo acíclico dirigido.
if (largest < LS[i])
```
-### Alguns Problemas Famosos de Programação Dinâmica
-```
-Floyd Warshall Algorithm - Tutorial and C Program source code:http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code
-
-Integer Knapsack Problem - Tutorial and C Program source code: http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem
+## Alguns Problemas Famosos de Programação Dinâmica
-Longest Common Subsequence - Tutorial and C Program source code : http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence
-```
+- [Floyd Warshall Algorithm - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code)
+- [Integer Knapsack Problem - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem)
+- [Longest Common Subsequence - Tutorial and C Program source code](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence)
+
## Recursos Online (EN)
diff --git a/pt-br/elisp-pt.html.markdown b/pt-br/elisp-pt.html.markdown
index fc2d1e40..aa611097 100644
--- a/pt-br/elisp-pt.html.markdown
+++ b/pt-br/elisp-pt.html.markdown
@@ -111,7 +111,7 @@ filename: learn-emacs-lisp-pt.el
(hello)
;; `C-xC-e' => Hello, I am Bastien
-;; Os parêntesis vazios na definição da função significam que ela
+;; Os parênteses vazios na definição da função significam que ela
;; não aceita argumentos. Mas sempre utilizar `my-name' é um tédio!
;; Vamos dizer à função para aceitar um argumento (o argumento é
;; chamado "name"):
diff --git a/pt-br/elixir.html.markdown b/pt-br/elixir-pt.html.markdown
index f8c56101..4ba78f52 100644
--- a/pt-br/elixir.html.markdown
+++ b/pt-br/elixir-pt.html.markdown
@@ -40,7 +40,7 @@ e muitos outros recursos.
# Tuplas que são guardadas contiguamente em memória.
{1,2,3} # tupla
-# Podemos acessar um elemento de uma tupla om a função `elem`:
+# Podemos acessar um elemento de uma tupla com a função `elem`:
elem({1, 2, 3}, 0) #=> 1
# Listas que são implementadas como listas ligadas.
diff --git a/pt-br/elm-pt.html.markdown b/pt-br/elm-pt.html.markdown
index 78a4f1b7..d2469a93 100644
--- a/pt-br/elm-pt.html.markdown
+++ b/pt-br/elm-pt.html.markdown
@@ -76,8 +76,8 @@ List.head [] -- Nothing
-- Acesse os elementos de um par com as funções first e second.
-- (Este é um atalho; nós iremos para o "caminho real" em breve.)
-fst ("elm", 42) -- "elm"
-snd ("elm", 42) -- 42
+Tuple.first ("elm", 42) -- "elm"
+Tuple.second ("elm", 42) -- 42
-- Uma tupla vazia ou "unidade" às vezes é utilizada como um placeholder.
-- É o único valor de seu tipo, também chamado de "Unit".
diff --git a/pt-br/factor-pt.html.markdown b/pt-br/factor-pt.html.markdown
new file mode 100644
index 00000000..b4b5c7f5
--- /dev/null
+++ b/pt-br/factor-pt.html.markdown
@@ -0,0 +1,184 @@
+---
+language: factor
+contributors:
+ - ["hyphz", "http://github.com/hyphz/"]
+filename: learnfactor-br.factor
+
+lang: pt-br
+---
+
+Factor é uma linguagem moderna baseada em pilha, baseado em Forth, criada por Slava Pestov.
+
+Código neste arquivo pode ser digitado em Fator, mas não importado diretamente porque o cabeçalho de vocabulário e importação faria o início completamente confuso.
+
+```factor
+! Este é um comentário
+
+! Como Forth, toda a programação é feita manipulando a pilha.
+! A indicação de um valor literal o coloca na pilha.
+5 2 3 56 76 23 65 ! Nenhuma saída, mas a pilha é impressa no modo interativo
+
+! Esses números são adicionados à pilha, da esquerda para a direita.
+! .s imprime a pilha de forma não destrutiva.
+.s ! 5 2 3 56 76 23 65
+
+! A aritmética funciona manipulando dados na pilha.
+5 4 + ! Sem saída
+
+! `.` mostra o resultado superior da pilha e o imprime.
+. ! 9
+
+! Mais exemplos de aritmética:
+6 7 * . ! 42
+1360 23 - . ! 1337
+12 12 / . ! 1
+13 2 mod . ! 1
+
+99 neg . ! -99
+-99 abs . ! 99
+52 23 max . ! 52
+52 23 min . ! 23
+
+! Várias palavras são fornecidas para manipular a pilha, coletivamente conhecidas como palavras embaralhadas.
+
+3 dup - ! duplica o primeiro item (1st agora igual a 2nd): 3 - 3
+2 5 swap / ! troca o primeiro com o segundo elemento: 5 / 2
+4 0 drop 2 / ! remove o primeiro item (não imprima na tela): 4 / 2
+1 2 3 nip .s ! remove o segundo item (semelhante a drop): 1 3
+1 2 clear .s ! acaba com toda a pilha
+1 2 3 4 over .s ! duplica o segundo item para o topo: 1 2 3 4 3
+1 2 3 4 2 pick .s ! duplica o terceiro item para o topo: 1 2 3 4 2 3
+
+! Criando Palavras
+! O `:` conjuntos de palavras do Factor no modo de compilação até que ela veja a palavra `;`.
+: square ( n -- n ) dup * ; ! Sem saída
+5 square . ! 25
+
+! Podemos ver o que as palavra fazem também.
+! \ suprime a avaliação de uma palavra e coloca seu identificador na pilha.
+\ square see ! : square ( n -- n ) dup * ;
+
+! Após o nome da palavra para criar, a declaração entre parênteses dá o efeito da pilha.
+! Podemos usar os nomes que quisermos dentro da declaração:
+: weirdsquare ( camel -- llama ) dup * ;
+
+! Contanto que sua contagem corresponda ao efeito da pilha da palavra:
+: doubledup ( a -- b ) dup dup ; ! Error: Stack effect declaration is wrong
+: doubledup ( a -- a a a ) dup dup ; ! Ok
+: weirddoubledup ( i -- am a fish ) dup dup ; ! Além disso Ok
+
+! Onde Factor difere do Forth é no uso de citações.
+! Uma citação é um bloco de código que é colocado na pilha como um valor.
+! [ inicia o modo de citação; ] termina.
+[ 2 + ] ! A citação que adiciona 2 é deixada na pilha
+4 swap call . ! 6
+
+! E assim, palavras de ordem mais alta. TONS de palavras de ordem superior.
+2 3 [ 2 + ] dip .s ! Retira valor do topo da pilha, execute citação, empurre de volta: 4 3
+3 4 [ + ] keep .s ! Copie o valor do topo da pilha, execute a citação, envie a cópia: 7 4
+1 [ 2 + ] [ 3 + ] bi .s ! Executar cada citação no valor do topo, empurrar os dois resultados: 3 4
+4 3 1 [ + ] [ + ] bi .s ! As citações em um bi podem extrair valores mais profundos da pilha: 4 5 ( 1+3 1+4 )
+1 2 [ 2 + ] bi@ .s ! Executar a citação no primeiro e segundo valores
+2 [ + ] curry ! Injeta o valor fornecido no início da citação: [ 2 + ] é deixado na pilha
+
+! Condicionais
+! Qualquer valor é verdadeiro, exceto o valor interno f.
+! m valor interno não existe, mas seu uso não é essencial.
+! Condicionais são palavras de maior ordem, como com os combinadores acima.
+
+5 [ "Five is true" . ] when ! Cinco é verdadeiro
+0 [ "Zero is true" . ] when ! Zero é verdadeiro
+f [ "F is true" . ] when ! Sem saída
+f [ "F is false" . ] unless ! F é falso
+2 [ "Two is true" . ] [ "Two is false" . ] if ! Two é verdadeiro
+
+! Por padrão, as condicionais consomem o valor em teste, mas variantes com asterisco
+! deixe sozinho se é verdadeiro:
+
+5 [ . ] when* ! 5
+f [ . ] when* ! Nenhuma saída, pilha vazia, f é consumida porque é falsa
+
+
+! Laços
+! Você adivinhou .. estas são palavras de ordem mais elevada também.
+
+5 [ . ] each-integer ! 0 1 2 3 4
+4 3 2 1 0 5 [ + . ] each-integer ! 0 2 4 6 8
+5 [ "Hello" . ] times ! Hello Hello Hello Hello Hello
+
+! Here's a list:
+{ 2 4 6 8 } ! Goes on the stack as one item
+
+! Aqui está uma lista:
+{ 2 4 6 8 } [ 1 + . ] each ! Exibe 3 5 7 9
+{ 2 4 6 8 } [ 1 + ] map ! Sai { 3 5 7 9 } na pilha
+
+! Reduzir laços ou criar listas:
+{ 1 2 3 4 5 } [ 2 mod 0 = ] filter ! Mantém apenas membros da lista para os quais a citação é verdadeira: { 2 4 }
+{ 2 4 6 8 } 0 [ + ] reduce . ! Como "fold" em linguagens funcionais: exibe 20 (0+2+4+6+8)
+{ 2 4 6 8 } 0 [ + ] accumulate . . ! Como reduzir, mas mantém os valores intermediários em uma lista: exibe { 0 2 6 12 } então 20
+1 5 [ 2 * dup ] replicate . ! Repete a citação 5 vezes e coleta os resultados em uma lista: { 2 4 8 16 32 }
+1 [ dup 100 < ] [ 2 * dup ] produce ! Repete a segunda citação até que a primeira retorne como falsa e colete os resultados: { 2 4 8 16 32 64 128 }
+
+! Se tudo mais falhar, uma finalidade geral, enquanto repete:
+1 [ dup 10 < ] [ "Hello" . 1 + ] while ! Exibe "Hello" 10 vezes
+ ! Sim, é difícil de ler
+ ! Isso é o que todos esses loops variantes são para
+
+! Variáveis
+! Normalmente, espera-se que os programas Factor mantenham todos os dados na pilha.
+! Usar variáveis ​​nomeadas torna a refatoração mais difícil (e é chamada de Factor por um motivo)
+! Variáveis ​​globais, se você precisar:
+
+SYMBOL: name ! Cria o nome como uma palavra identificadora
+"Bob" name set-global ! Sem saída
+name get-global . ! "Bob"
+
+! Variáveis ​​locais nomeadas são consideradas uma extensão, mas estão disponíveis
+! Em uma citação ..
+[| m n ! A citação captura os dois principais valores da pilha em m e n
+ | m n + ] ! Leia-os
+
+! Ou em uma palavra..
+:: lword ( -- ) ! Note os dois pontos duplos para invocar a extensão da variável lexica
+ 2 :> c ! Declara a variável imutável c para manter 2
+ c . ; ! Imprima isso
+
+! Em uma palavra declarada dessa maneira, o lado de entrada da declaração de pilha
+! torna-se significativo e fornece os valores das variáveis ​​em que os valores da pilha são capturados
+:: double ( a -- result ) a 2 * ;
+
+! Variáveis ​​são declaradas mutáveis ​​ao terminar seu nome com um ponto de exclamação
+:: mword2 ( a! -- x y ) ! Capture o topo da pilha na variável mutável a
+ a ! Empurrar a
+ a 2 * a! ! Multiplique por 2 e armazene o resultado em a
+ a ; ! Empurre novo valor de a
+5 mword2 ! Pilha: 5 10
+
+! Listas e Sequências
+! Vimos acima como empurrar uma lista para a pilha
+
+0 { 1 2 3 4 } nth ! Acessar um membro específico de uma lista: 1
+10 { 1 2 3 4 } nth ! Error: índice de sequência fora dos limites
+1 { 1 2 3 4 } ?nth ! O mesmo que nth se o índice estiver dentro dos limites: 2
+10 { 1 2 3 4 } ?nth ! Nenhum erro se estiver fora dos limites: f
+
+{ "at" "the" "beginning" } "Append" prefix ! { "Append" "at" "the" "beginning" }
+{ "Append" "at" "the" } "end" suffix ! { "Append" "at" "the" "end" }
+"in" 1 { "Insert" "the" "middle" } insert-nth ! { "Insert" "in" "the" "middle" }
+"Concat" "enate" append ! "Concatenate" - strings are sequences too
+"Concatenate" "Reverse " prepend ! "Reverse Concatenate"
+{ "Concatenate " "seq " "of " "seqs" } concat ! "Concatenate seq of seqs"
+{ "Connect" "subseqs" "with" "separators" } " " join ! "Connect subseqs with separators"
+
+! E se você quiser obter meta, as citações são seqüências e podem ser desmontadas..
+0 [ 2 + ] nth ! 2
+1 [ 2 + ] nth ! +
+[ 2 + ] \ - suffix ! Quotation [ 2 + - ]
+
+
+```
+
+##Pronto para mais?
+
+* [Documentação do Factor](http://docs.factorcode.org/content/article-help.home.html)
diff --git a/pt-br/fsharp-pt.html.markdown b/pt-br/fsharp-pt.html.markdown
new file mode 100644
index 00000000..55966cda
--- /dev/null
+++ b/pt-br/fsharp-pt.html.markdown
@@ -0,0 +1,639 @@
+---
+language: F#
+filename: learnfsharp-pt.fs
+contributors:
+ - ["Scott Wlaschin", "http://fsharpforfunandprofit.com"]
+ - ["Adelar da Silva Queiróz", "https://adelarsq.github.io"]
+lang: pt-br
+---
+
+F# é uma linguagem de propósito geral funcional e orientada a objetos. É livre, de código aberto e executa em Linux, Mac, Windows e outros.
+
+Possui um sistema de tipagem poderoso que evita muitos erros em tempo de compilação. Para isto utilizando inferência de tipos, o que a faz se comportar como uma linguagem dinâmica.
+
+A sintaxe é diferente das linguagens do estilo C (C, C#, Java, etc):
+
+* Chaves não são usadas para delimitar blocos de código. Ao invés disso é utilizada indentação (semelhante ao Python).
+* Espaços em branco são usados para separar parâmetros, ao invés de vírgulas.
+
+Se você deseja executar o código abaixo, copie e cole em [https://try.fsharp.org](https://try.fsharp.org), que é um REPL online.
+
+```fsharp
+
+// comentários de linhas únicas usam barras duplas
+(* comentários de linhas múltiplas usam o par (* . . . *)
+
+-fim do comentário de linhas múltiplas- *)
+
+// ================================================
+// Sintaxe básica
+// ================================================
+
+// ------ "Variáveis" (mas não exatamente) ------
+// A palavra reservada "let" define um valor imutável
+let myInt = 5
+let myFloat = 3.14
+let myString = "hello" // note que nenhum tipo é necessário
+
+// ------ Listas ------
+let twoToFive = [2; 3; 4; 5] // Colchetes criam uma lista com
+ // ponto e vírgula como delimitadores
+let oneToFive = 1 :: twoToFive // :: cria uma lista com um novo primeiro elemento
+// O resultado é [1; 2; 3; 4; 5]
+let zeroToFive = [0; 1] @ twoToFive // @ concatena duas listas
+
+// IMPORTANTE: vírgulas nunca são usadas como delimitadores, somente ponto e vírgula!
+
+// ------ Funções ------
+// A palavra chave "let" também define nomes para funções.
+let square x = x * x // Note que não são usados parêntesis
+square 3 // Agora executando a função. Também sem parêntesis
+
+let add x y = x + y // Não use add (x,y)! Isto significa algo
+ // completamente diferente.
+add 2 3 // Agora execute a função.
+
+// para definir uma função de múltiplas linhas apenas use indentação. Nenhum ponto e vírgula é necessário
+let evens list =
+ let isEven x = x % 2 = 0 // Define "isEven"como uma sub função. Note
+ // que o operador de igualdade é um simples "=".
+ List.filter isEven list // List.filter é uma função da biblioteca padrão
+ // com dois parâmetros: uma função que retorna boolean
+ // e uma lista para verificar
+
+evens oneToFive // Agora executando a função
+
+// Usando parênteses é possível deixar mais clara a precedência. Neste exemplo,
+// "map" é usado primeiro, com dois argumentos, então executa "sum" no resultado.
+// Sem os parênteses, "List.map" seria passado como uma argumento para List.sum
+let sumOfSquaresTo100 =
+ List.sum ( List.map square [1..100] )
+
+// É possível redirecionar a saída de uma operação para a próxima usando pipe ("|>")
+// Redirecimento de dados é algo comum em F#, similar a pipes Unix.
+
+// Aqui é a mesma função sumOfSquares escrita com pipe
+let sumOfSquaresTo100piped =
+ [1..100] |> List.map square |> List.sum // "square" foi definido anteriormente
+
+// você pode definir lambdas (funções anônimas) usando a palavra reservada "fun"
+let sumOfSquaresTo100withFun =
+ [1..100] |> List.map (fun x -> x * x) |> List.sum
+
+// Em F# não há a palavra chave "return". Funções sempre
+// retornam o valor da última expressão usada.
+
+// ------ Casamento de padrões (Pattern Matching) ------
+// Match..with.. é um poderoso case/switch.
+let simplePatternMatch =
+ let x = "a"
+ match x with
+ | "a" -> printfn "x is a"
+ | "b" -> printfn "x is b"
+ | _ -> printfn "x is something else" // sublinhado combina com qualquer coisa
+
+// F# não permite null por padrão -- deve-se usar um Option
+// e então efetuar um casamento de padrão.
+// Some(..) e None são análogos a Nullable
+let validValue = Some(99)
+let invalidValue = None
+
+// Neste exemplo, match..with casa com "Some" e "None",
+// e também desconstrói o valor em "Some" ao mesmo tempo.
+let optionPatternMatch input =
+ match input with
+ | Some i -> printfn "input is an int=%d" i
+ | None -> printfn "input is missing"
+
+optionPatternMatch validValue
+optionPatternMatch invalidValue
+
+// ------ Escrevando na tela ------
+// As funções printf/printfn são similares às
+// Console.Write/WriteLine encontradas no C#.
+printfn "Printing an int %i, a float %f, a bool %b" 1 2.0 true
+printfn "A string %s, and something generic %A" "hello" [1; 2; 3; 4]
+
+// Exitem também as funções sprintf/sprintfn para formatação de dados
+// em uma string, semelhante à String.Format do C#.
+
+// ================================================
+// Mais sobre funções
+// ================================================
+
+// F# é uma liguagem verdadeiramente funcional -- funções fazem
+// parte das classes e podem ser combinadas facilmente para criar
+// poderosos construtores
+
+// Módulos podem usar um grupo de funções
+// É necessário usar indentação para defini-las.
+module FunctionExamples =
+
+ // define uma função de soma
+ let add x y = x + y
+
+ // básico uso de uma função
+ let a = add 1 2
+ printfn "1 + 2 = %i" a
+
+ // aplicação parcial de parâmetros
+ let add42 = add 42
+ let b = add42 1
+ printfn "42 + 1 = %i" b
+
+ // composição para combinar funções
+ let add1 = add 1
+ let add2 = add 2
+ let add3 = add1 >> add2
+ let c = add3 7
+ printfn "3 + 7 = %i" c
+
+ // funções de alta ordem
+ [1..10] |> List.map add3 |> printfn "new list is %A"
+
+ // listas de funções e mais
+ let add6 = [add1; add2; add3] |> List.reduce (>>)
+ let d = add6 7
+ printfn "1 + 2 + 3 + 7 = %i" d
+
+// ================================================
+// Listas e coleções
+// ================================================
+
+// Existem três tipos de coleções ordenadas:
+// * Listas são o tipo mais básico de coleção imutável;
+// * Arrays são mutáveis e mais eficientes;
+// * Sequences são lazy e infinitas (semelhante a enumerator).
+//
+// Outras coleções incluem maps e conjuntos imutáveis
+// mais todas as coleções padrões do .NET
+
+module ListExamples =
+
+ // listas usam colchetes
+ let list1 = ["a"; "b"]
+ let list2 = "c" :: list1 // :: é usado para adicionar um elemento no início da lista
+ let list3 = list1 @ list2 // @ é o operador de concatenação
+
+ // list comprehensions (generators)
+ let squares = [for i in 1..10 do yield i * i]
+
+ // Um gerador de números primos
+ // - este usa a notação custa para casamento de padrões
+ // - (p::xs) significa 'primeiro :: cauda' da lista, e pode ser escrito como p :: xs
+ // isto significa que casa 'p' (o primeiro item da lista), e xs recebe o resto da lista
+ // que é chamdo de 'cons pattern'
+ // - usa a palavra chave 'rec', que é necessária quando se usa recursão
+ let rec sieve = function
+ | (p::xs) -> p :: sieve [ for x in xs do if x % p > 0 then yield x ]
+ | [] -> []
+ let primes = sieve [2..50]
+ printfn "%A" primes
+
+ // casamento de padrões (pattern matching) com listas
+ let listMatcher aList =
+ match aList with
+ | [] -> printfn "the list is empty"
+ | [first] -> printfn "the list has one element %A " first
+ | [first; second] -> printfn "list is %A and %A" first second
+ | first :: _ -> printfn "the list has more than two elements, first element %A" first
+
+ listMatcher [1; 2; 3; 4]
+ listMatcher [1; 2]
+ listMatcher [1]
+ listMatcher []
+
+ // recursão usando listas
+ let rec sum aList =
+ match aList with
+ | [] -> 0
+ | x::xs -> x + sum xs
+ sum [1..10]
+
+ // -----------------------------------------
+ // Funções da biblioteca padrão
+ // -----------------------------------------
+
+ // mapas
+ let add3 x = x + 3
+ [1..10] |> List.map add3
+
+ // filtros
+ let even x = x % 2 = 0
+ [1..10] |> List.filter even
+
+ // muito mais -- veja a documentação
+
+module ArrayExamples =
+
+ // arrays usam colchetes com barra vertical
+ let array1 = [| "a"; "b" |]
+ let first = array1.[0] // acesso por índice usando ponto
+
+ // casamento de padrões (pattern matching) para arrays é feito da mesma forma que de listas
+ let arrayMatcher aList =
+ match aList with
+ | [| |] -> printfn "the array is empty"
+ | [| first |] -> printfn "the array has one element %A " first
+ | [| first; second |] -> printfn "array is %A and %A" first second
+ | _ -> printfn "the array has more than two elements"
+
+ arrayMatcher [| 1; 2; 3; 4 |]
+
+ // As funções da biblioteca padrão são as mesmas que para List
+
+ [| 1..10 |]
+ |> Array.map (fun i -> i + 3)
+ |> Array.filter (fun i -> i % 2 = 0)
+ |> Array.iter (printfn "value is %i. ")
+
+
+module SequenceExamples =
+
+ // sequências usam chaves
+ let seq1 = seq { yield "a"; yield "b" }
+
+ // sequências podem usar yield e
+ // podem conter subsequencias
+ let strange = seq {
+ // "yield" adiciona um elemento
+ yield 1; yield 2;
+
+ // "yield!" adiciona uma subsequencia
+ yield! [5..10]
+ yield! seq {
+ for i in 1..10 do
+ if i % 2 = 0 then yield i }}
+ // teste
+ strange |> Seq.toList
+
+ // Sequências podem ser criadas usando "unfold"
+ // Este é um exemplo da série de Fibonacci
+ let fib = Seq.unfold (fun (fst,snd) ->
+ Some(fst + snd, (snd, fst + snd))) (0,1)
+
+ // teste
+ let fib10 = fib |> Seq.take 10 |> Seq.toList
+ printf "first 10 fibs are %A" fib10
+
+
+// ================================================
+// Tipos de dados
+// ================================================
+
+module DataTypeExamples =
+
+ // Todos os dados são imutáveis por padrão
+
+ // Tuplas são uma forma rápida de reprentar n elementos de tipos anônimos
+ // -- Use a vírgula para criar uma tupla
+ let twoTuple = 1, 2
+ let threeTuple = "a", 2, true
+
+ // Casamento de padrões (pattern match) para desconstruir
+ let x, y = twoTuple // atribui x = 1, y = 2
+
+ // ------------------------------------
+ // O tipo registro possui nomes nos campos
+ // ------------------------------------
+
+ // Use "type" com chaves para definir um registro
+ type Person = {First:string; Last:string}
+
+ // Use "let" com chaves para criar um registro
+ let person1 = {First="John"; Last="Doe"}
+
+ // Casamento de padrões para desconstruir
+ let {First = first} = person1 // atribui first="John"
+
+ // ------------------------------------
+ // Tipos union (variantes) possuem um conjunto de escolhas
+ // Somente um caso pode ser válido por vez.
+ // ------------------------------------
+
+ // Use "type" com barra/pipe para definir um union
+ type Temp =
+ | DegreesC of float
+ | DegreesF of float
+
+ // Use qualquer dos tipos para criar um
+ let temp1 = DegreesF 98.6
+ let temp2 = DegreesC 37.0
+
+ // Casamento de padrões deve cobrir todos os tipos de definidos para desconstruir
+ let printTemp = function
+ | DegreesC t -> printfn "%f degC" t
+ | DegreesF t -> printfn "%f degF" t
+
+ printTemp temp1
+ printTemp temp2
+
+ // ------------------------------------
+ // Tipos recursivos
+ // ------------------------------------
+
+ // Tipos podem ser combinados recursivamente de formas complexas
+ // sem ter que criar subclasses
+ type Employee =
+ | Worker of Person
+ | Manager of Employee list
+
+ let jdoe = {First="John"; Last="Doe"}
+ let worker = Worker jdoe
+
+ // ------------------------------------
+ // Modelando com tipos
+ // ------------------------------------
+
+ // Tipos union são muito bons para modelagem de estados sem usar flags
+ type EmailAddress =
+ | ValidEmailAddress of string
+ | InvalidEmailAddress of string
+
+ let trySendEmail email =
+ match email with // casamento de padrões
+ | ValidEmailAddress address -> () // envia
+ | InvalidEmailAddress address -> () // não envia
+
+ // A combinação de tipos union e registros juntos
+ // provê uma grande fundação para DDD (Domain Driven Design).
+ // Você pode criar centenas de pequenos tipos que refletem
+ // exatamente o seu domínio.
+
+ type CartItem = { ProductCode: string; Qty: int }
+ type Payment = Payment of float
+ type ActiveCartData = { UnpaidItems: CartItem list }
+ type PaidCartData = { PaidItems: CartItem list; Payment: Payment}
+
+ type ShoppingCart =
+ | EmptyCart // nenhum dado
+ | ActiveCart of ActiveCartData
+ | PaidCart of PaidCartData
+
+ // ------------------------------------
+ // Comportamento padrão para tipos
+ // ------------------------------------
+
+ // Tipos padrões possuem um padrão já definido, não precisando de codificação nenhuma.
+ // * Imutáveis
+ // * Impressão formatada para depuração
+ // * Igualdade e comparação
+ // * Serialização
+
+ // Impressão formatada usando %A
+ printfn "twoTuple=%A,\nPerson=%A,\nTemp=%A,\nEmployee=%A"
+ twoTuple person1 temp1 worker
+
+ // Igualdade e comparação padrão.
+ // Um exemplo com cartas:
+ type Suit = Club | Diamond | Spade | Heart
+ type Rank = Two | Three | Four | Five | Six | Seven | Eight
+ | Nine | Ten | Jack | Queen | King | Ace
+
+ let hand = [ Club, Ace; Heart, Three; Heart, Ace;
+ Spade, Jack; Diamond, Two; Diamond, Ace ]
+
+ // ordenando
+ List.sort hand |> printfn "sorted hand is (low to high) %A"
+ List.max hand |> printfn "high card is %A"
+ List.min hand |> printfn "low card is %A"
+
+
+// ================================================
+// Padrões ativos (Active patterns)
+// ================================================
+
+module ActivePatternExamples =
+
+ // F# possui um tipo especial de casamento de padrões chamado "padrões ativos" ("active patterns")
+ // onde o padrão pode ser interpretado ou detectado dinamicamente.
+
+ // parêntesis e barra são a sintaxe para "padrões ativos"
+
+ // Você pode usar "elif" ao invés de "else if" em expressões condicionais.
+ // Elas são equivalentes em F#
+
+ // por exemplo, defina um "padrão ativo" para tratar tipos de caracteres...
+ let (|Digit|Letter|Whitespace|Other|) ch =
+ if System.Char.IsDigit(ch) then Digit
+ elif System.Char.IsLetter(ch) then Letter
+ elif System.Char.IsWhiteSpace(ch) then Whitespace
+ else Other
+
+ // ... e então use ele para interpretar de forma bem mais simples
+ let printChar ch =
+ match ch with
+ | Digit -> printfn "%c is a Digit" ch
+ | Letter -> printfn "%c is a Letter" ch
+ | Whitespace -> printfn "%c is a Whitespace" ch
+ | _ -> printfn "%c is something else" ch
+
+ // imprima a lista
+ ['a'; 'b'; '1'; ' '; '-'; 'c'] |> List.iter printChar
+
+ // ------------------------------------------------
+ // FizzBuzz usando padrões ativos (active patterns)
+ // ------------------------------------------------
+
+ // É possível criar casamento de padrões parcial também
+ // Apenas use sublinhado para a definição, e retorne Some se casado.
+ let (|MultOf3|_|) i = if i % 3 = 0 then Some MultOf3 else None
+ let (|MultOf5|_|) i = if i % 5 = 0 then Some MultOf5 else None
+
+ // a função principal
+ let fizzBuzz i =
+ match i with
+ | MultOf3 & MultOf5 -> printf "FizzBuzz, "
+ | MultOf3 -> printf "Fizz, "
+ | MultOf5 -> printf "Buzz, "
+ | _ -> printf "%i, " i
+
+ // teste
+ [1..20] |> List.iter fizzBuzz
+
+// ================================================
+// Expressividade
+// ================================================
+
+module AlgorithmExamples =
+
+ // F# possui uma alta razão sinais/ruídos, assim o código
+ // é lido praticamento como se descreve o algoritmo
+
+ // ------ Exemplo: defina uma função que faça soma dos quadrados ------
+ let sumOfSquares n =
+ [1..n] // 1) pega todos os números de 1 a n
+ |> List.map square // 2) eleva ao quadrado cada um
+ |> List.sum // 3) soma os resultados
+
+ // teste
+ sumOfSquares 100 |> printfn "Sum of squares = %A"
+
+ // ------ Examplo: defina uma função de ordenação ------
+ let rec sort list =
+ match list with
+ // Se a lista está vazia
+ | [] ->
+ [] // retorna a lista vazia
+ // Se a lista não está vazia
+ | firstElem::otherElements -> // pega o primeiro elemento
+ let smallerElements = // extrai os elementos menores
+ otherElements // dos restantes
+ |> List.filter (fun e -> e < firstElem)
+ |> sort // e ordena eles
+ let largerElements = // extrai os elementos maiores
+ otherElements // dos restantes
+ |> List.filter (fun e -> e >= firstElem)
+ |> sort // e ordena eles
+ // Combine as 3 partes em uma nova lista e retorne ela
+ List.concat [smallerElements; [firstElem]; largerElements]
+
+ // teste
+ sort [1; 5; 23; 18; 9; 1; 3] |> printfn "Sorted = %A"
+
+// ================================================
+// Código assíncrono
+// ================================================
+
+module AsyncExample =
+
+ // F# possui suporte a funcionalidades para ajudar a escrever código assíncrono
+ // sem tornar o código difícil de manter ("pyramid of doom")
+ //
+ // O seguinte exemplo efetua download de um conjunto de páginas em paralelo.
+
+ open System.Net
+ open System
+ open System.IO
+ open Microsoft.FSharp.Control.CommonExtensions
+
+ // Obtém o conteúdo de cara página de forma assíncrona
+ let fetchUrlAsync url =
+ async { // a palavra chave "async" e chaves
+ // criam um objeto assíncrono
+ let req = WebRequest.Create(Uri(url))
+ use! resp = req.AsyncGetResponse()
+ // use! é uma atribuição assíncrona
+ use stream = resp.GetResponseStream()
+ // "use" dispara automaticamente close()
+ // no recurso no fim do escopo
+ use reader = new IO.StreamReader(stream)
+ let html = reader.ReadToEnd()
+ printfn "finished downloading %s" url
+ }
+
+ // uma lista de sites para fazer download
+ let sites = ["http://www.bing.com";
+ "http://www.google.com";
+ "http://www.microsoft.com";
+ "http://www.amazon.com";
+ "http://www.yahoo.com"]
+
+ // efetue
+ sites
+ |> List.map fetchUrlAsync // cria uma lista de tarefas assíncronas
+ |> Async.Parallel // coloca as tarefas para executarem em paralelo
+ |> Async.RunSynchronously // inicia cada uma
+
+// ================================================
+// Compatibilidade com .NET
+// ================================================
+
+module NetCompatibilityExamples =
+
+ // F# pode pode fazer praticamente tudo que C# pode fazer, e integra
+ // de forma simples com bibliotecas .NET e Mono
+
+ // ------- usando uma função de uma biblioteca existente -------
+
+ let (i1success, i1) = System.Int32.TryParse("123");
+ if i1success then printfn "parsed as %i" i1 else printfn "parse failed"
+
+ // ------- Implementando interfaces de forma simples! -------
+
+ // cria um novo objeto que implementa IDisposable
+ let makeResource name =
+ { new System.IDisposable
+ with member this.Dispose() = printfn "%s disposed" name }
+
+ let useAndDisposeResources =
+ use r1 = makeResource "first resource"
+ printfn "using first resource"
+ for i in [1..3] do
+ let resourceName = sprintf "\tinner resource %d" i
+ use temp = makeResource resourceName
+ printfn "\tdo something with %s" resourceName
+ use r2 = makeResource "second resource"
+ printfn "using second resource"
+ printfn "done."
+
+ // ------- Código orientado a objetos -------
+
+ // F# também possui suporte a orientação a objetos.
+ // Possui suporte a classes, herança, métodos virtuais, etc.
+
+ // interface com tipo genérico
+ type IEnumerator<'a> =
+ abstract member Current : 'a
+ abstract MoveNext : unit -> bool
+
+ // classe base abstrata com métodos virtuais
+ [<AbstractClass>]
+ type Shape() =
+ // propriedades somente leitura
+ abstract member Width : int with get
+ abstract member Height : int with get
+ // método não virtual
+ member this.BoundingArea = this.Height * this.Width
+ // método virtual com implementação base
+ abstract member Print : unit -> unit
+ default this.Print () = printfn "I'm a shape"
+
+ // classe concreta que herda da classe base e sobrescreve
+ type Rectangle(x:int, y:int) =
+ inherit Shape()
+ override this.Width = x
+ override this.Height = y
+ override this.Print () = printfn "I'm a Rectangle"
+
+ // testes
+ let r = Rectangle(2, 3)
+ printfn "The width is %i" r.Width
+ printfn "The area is %i" r.BoundingArea
+ r.Print()
+
+ // ------- métodos de extensão -------
+
+ // Assim como em C#, F# pode extender classes já existentes com métodos de extensão.
+ type System.String with
+ member this.StartsWithA = this.StartsWith "A"
+
+ // testes
+ let s = "Alice"
+ printfn "'%s' starts with an 'A' = %A" s s.StartsWithA
+
+ // ------- eventos -------
+
+ type MyButton() =
+ let clickEvent = new Event<_>()
+
+ [<CLIEvent>]
+ member this.OnClick = clickEvent.Publish
+
+ member this.TestEvent(arg) =
+ clickEvent.Trigger(this, arg)
+
+ // teste
+ let myButton = new MyButton()
+ myButton.OnClick.Add(fun (sender, arg) ->
+ printfn "Click event with arg=%O" arg)
+
+ myButton.TestEvent("Hello World!")
+
+```
+
+## Mais Informações
+
+Para mais demonstrações de F# acesse [why use F#](http://fsharpforfunandprofit.com/why-use-fsharp/).
+
+Leia mais sobre F# em [fsharp.org](http://fsharp.org/) e [dotnet's F# page](https://dotnet.microsoft.com/languages/fsharp).
diff --git a/pt-br/go-pt.html.markdown b/pt-br/go-pt.html.markdown
index c7339831..31473ee1 100644
--- a/pt-br/go-pt.html.markdown
+++ b/pt-br/go-pt.html.markdown
@@ -16,7 +16,7 @@ A linguagem Go foi criada a partir da necessidade de ver trabalho feito. Não
forma de resolver os problemas do mundo real.
Tem conceitos familiares de linguagens imperativas com tipagem estática. É
-rápida a compilar e rápida a executar, acrescentando mecanismos de concorrência
+rápida para compilar e rápida para executar, acrescentando mecanismos de concorrência
fáceis de entender para tirar partido dos CPUs multi-core de hoje em dia, e tem
recursos para ajudar com a programação em larga escala.
@@ -39,10 +39,10 @@ import (
)
// Definição de uma função. Main é especial. É o ponto de entrada para o
-// programa executável. Goste-se ou não, a linguagem Go usa chavetas.
+// programa executável. Goste-se ou não, a linguagem Go usa chaves.
func main() {
// A função Println envia uma linha para stdout.
- // É necessário qualifica-la com o nome do pacote, fmt.
+ // É necessário qualificá-la com o nome do pacote, fmt.
fmt.Println("Olá Mundo!")
// Chama outra função dentro deste pacote.
diff --git a/pt-br/groovy-pt.html.markdown b/pt-br/groovy-pt.html.markdown
index 2ec7d967..3acfce21 100644
--- a/pt-br/groovy-pt.html.markdown
+++ b/pt-br/groovy-pt.html.markdown
@@ -1,7 +1,7 @@
---
language: Groovy
category: language
-filename: learngroovy.groovy
+filename: learngroovy-pt.groovy
contributors:
- ["Roberto Pérez Alcolea", "http://github.com/rpalcolea"]
translators:
@@ -14,10 +14,10 @@ Groovy - Uma linguagem dinâmica para a plataforma Java. [Leia mais aqui.](http:
```groovy
/*
- Prepara-se:
+ Prepare-se:
1) Instale a máquina virtual de Groovy - http://gvmtool.net/
- 2) Intalse o Groovy: gvm install groovy
+ 2) Instale o Groovy: gvm install groovy
3) Inicie o console groovy digitando: groovyConsole
*/
@@ -104,7 +104,7 @@ tecnologiasOrdenadas = tecnologias.sort( false )
/*** Manipulando listas ***/
-//Substitue todos os elementos da lista
+//Substitui todos os elementos da lista
Collections.replaceAll(tecnologias, 'Gradle', 'gradle')
//Desorganiza a lista
@@ -159,7 +159,7 @@ println devMap.values()
usará este campo.
* Se você quer uma propriedade private ou protected, você deve prover seus
- próprios getters e setter, que devem ser declarados como private ou protected.
+ próprios getters e setters, que devem ser declarados como private ou protected.
* Se você acessar uma propriedade dentro da classe e esta propriedade é definida
em tempo de compilação com 'this', implícito ou explícito (por exemplo,
@@ -226,15 +226,17 @@ for (i in array) {
//Itera sobre um mapa
def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
-x = 0
+x = ""
for ( e in map ) {
x += e.value
+ x += " "
}
+assert x.equals("Roberto Grails Groovy ")
/*
Operadores
- Sobrecarregamento de Operadores para uma lsita dos operadores comuns que
+ Sobrecarga de Operadores para uma lista dos operadores comuns que
Grooby suporta:
http://www.groovy-lang.org/operators.html#Operator-Overloading
@@ -252,7 +254,7 @@ def nomeUsuario = usuario?.nomeUsuario
/*
Closures
- Um closure, em Grooby, é como um "bloco de código" ou um ponteiro para método.
+ Um closure, em Groovy, é como um "bloco de código" ou um ponteiro para método.
É um pedação de código que é definido e executado em um momento posterior.
Mais informação em: http://www.groovy-lang.org/closures.html
@@ -267,7 +269,7 @@ clos()
def soma = { a, b -> println a+b }
soma(2,4)
-//Closdures por referir-se a variáveis que não estão listadas em sua
+//Closures podem referir-se a variáveis que não estão listadas em sua
//lista de parêmetros.
def x = 5
def multiplicarPor = { num -> num * x }
@@ -307,7 +309,7 @@ chamaClosure(3, 4)
/*
Expando
- A classe Expando é um bean dinâmico que permite adicionar propriedade e
+ A classe Expando é um bean dinâmico que permite adicionar propriedades e
closures como métodos a uma instância desta classe
http://mrhaki.blogspot.mx/2009/10/groovy-goodness-expando-as-dynamic-bean.html
diff --git a/pt-br/haskell-pt.html.markdown b/pt-br/haskell-pt.html.markdown
index 788dc1d2..c55a4c03 100644
--- a/pt-br/haskell-pt.html.markdown
+++ b/pt-br/haskell-pt.html.markdown
@@ -41,7 +41,7 @@ o desenvolvimento deste paradigma de programação.
7 * 7 -- 7 vezes 7
7 / 7 -- 7 dividido por 7
--- Divisões não são inteiras, são fracionádas por padrão da linguagem
+-- Divisões não são inteiras, são fracionadas por padrão da linguagem
28736 / 82374 -- 0.3488479374559934
@@ -67,7 +67,7 @@ not False -- Nega uma falácia
7 > 7 -- 7 é maior que 7 ?
-{- Haskell é uma linguagem que tem uma sintáxe bastante familiar na
+{- Haskell é uma linguagem que tem uma sintaxe bastante familiar na
matemática, por exemplo em chamadas de funções você tem:
NomeFunção ArgumentoA ArgumentoB ArgumentoC ...
@@ -93,7 +93,7 @@ not False -- Nega uma falácia
"AbBbbcAbbcbBbcbcb" !! 2 -- 'B'
----------------------------------------------------
--- Listas e Túplas
+-- 2. Listas e Túplas
----------------------------------------------------
-- A construção de uma lista precisa ser de elementos homogêneos
diff --git a/pt-br/haxe-pt.html.markdown b/pt-br/haxe-pt.html.markdown
new file mode 100644
index 00000000..13264dec
--- /dev/null
+++ b/pt-br/haxe-pt.html.markdown
@@ -0,0 +1,795 @@
+---
+language: haxe
+filename: LearnHaxe3-br.hx
+contributors:
+ - ["Justin Donaldson", "https://github.com/jdonaldson/"]
+ - ["Dan Korostelev", "https://github.com/nadako/"]
+translators:
+ - ["David Lima", "https://github.com/davelima/"]
+lang: pt-br
+---
+
+Haxe é uma linguagem baseada na web que provê suporte a C++, C#, SWF/ActionScript,
+Java e Neko byte code (também desenvolvida pelo autor de Haxe). Observe que
+este guia é para a versão 3 de Haxe. Alguns pontos do guia são aplicáveis
+para versões anteriores, mas é recomendado que você busque outras referências
+para essas versões.
+
+
+```csharp
+/*
+ Bem vindo ao Aprenda Haxe 3 em 15 minutos. http://www.haxe.org
+ Este é um tutorial executável. Você pode compilar e rodar este tutorial
+ usando o compilador haxe, estando no mesmo diretório de LearnHaxe.hx:
+ $> haxe -main LearnHaxe3 -x out
+
+ Olhe para os sinais de /* e */ em volta desses parágrafos. Nós estamos
+ dentro de um "Comentário multilinha". Nós podemos colocar observações aqui
+ e elas serão ignoradas pelo compilador.
+
+ Comentários multilinha também são utilizados para gerar documentação haxedoc,
+ seguindo o estilo javadoc. Eles serão usados pelo haxedoc se precerem imediatamente
+ uma classe, uma função de uma classe ou uma variável de uma classe.
+
+ */
+
+// Duas barras, como as dessa linha, farão um comentário de linha única.
+
+
+/*
+ Este será o primeiro código haxe de verdade, e está declarando um pacote vazio.
+ Não é necessário usar um pacote, mas ele será útil se você quiser criar
+ um namespace para o seu código (exemplo: org.seuapp.SuaClasse).
+
+ Omitir a declaração de pacote é a mesma coisa que declarar um pacote vazio.
+ */
+package; // pacote vazio, sem namespace.
+
+/*
+ Pacotes são diretórios que contém módulos. Cada módulo é um arquivo .hx que
+ contém tipos definidos em um pacote. Nomes de pacotes (ex. org.seuapp)
+ devem estar em letras minúsculas, enquanto nomes de módulos devem começar
+ com uma letra maiúscula. Um módulo contem um ou mais tipos, cujo os nomes
+ também devem começar com uma letra maiúscula.
+
+ Exemplo: a classe "org.seuapp.Foo" deve ter a estrutura de diretório org/module/Foo.hx,
+ sendo acessível do diretório do compilador ou caminho da classe.
+
+ Se você importar código de outros arquivos, isso deve ser declarado antes
+ do restante do código. Haxe disponibiliza várias classes padrões para você
+ começar:
+ */
+import haxe.ds.ArraySort;
+
+// você pode importar várias classes/módulos de uma vez usando "*"
+import haxe.ds.*;
+
+// você pode importar campos estáticos
+import Lambda.array;
+
+// você também pode usar "*" para importar todos os campos estáticos
+import Math.*;
+
+/*
+ Você também pode importar classes de uma forma diferente, habilitando-as para
+ extender a funcionalidade de outras classes, como um "mixin". Falaremos sobre
+ "using" em breve.
+ */
+using StringTools;
+
+/*
+ Typedefs são como variáveis... para tipos. Eles devem ser declarados antes
+ de qualquer código. Veremos isso em breve.
+ */
+typedef FooString = String;
+
+// Typedefs também podem referenciar tipos "estruturais". Também veremos isso em breve.
+typedef FooObject = { foo: String };
+
+/*
+ Esta é a definição da classe. É a classe principal do arquivo, visto que
+ possui o mesmo nome (LearnHaxe3)
+ */
+class LearnHaxe3{
+ /*
+ Se você quiser que um determinado código rode automaticamente, você
+ precisa colocá-lo em uma função estática "main", e especificar a classe
+ nos argumentos do compilador.
+ Nesse caso, nós especificamos a classe "LearnHaxe3" no nos argumentos
+ do compilador acima.
+ */
+ static function main(){
+
+ /*
+ Trace é o método padrão para imprimir expressões haxe na tela.
+ Temos diferentes métodos para conseguir isso em diferentes destinos.
+ Por exemplo: Java, C++, C#, etc. irão imprimir para stdout.
+ Javascript irá imprimir no console.log, e Flash irá imprimir para um
+ TextField anexado. Todos os "traces" imprimem também uma linha em branco
+ por padrão. Por fim, é possível prevenir um trace de ser exibido usando
+ o argumento "--no-traces" no compilador.
+ */
+ trace("Olá mundo, com trace()!");
+
+ /*
+ Trace pode tratar qualquer tipo de valor ou objeto. O método tentará
+ imprimir a representação de uma expressão da melhor forma. Você também
+ pode concatenar strings usando o operador "+":
+ */
+ trace( " Integer: " + 10 + " Float: " + 3.14 + " Boolean: " + true);
+
+ /*
+ Em Haxe, é obrigatório separar expressões no mesmo bloco com ';'. Mas
+ é possível colocar duas expressões na mesma linha, dessa forma:
+ */
+ trace('duas expressões..'); trace('uma linha');
+
+
+ //////////////////////////////////////////////////////////////////
+ // Tipos & Variáveis
+ //////////////////////////////////////////////////////////////////
+ trace("***Tipos & Variáveis***");
+
+ /*
+ Vcoê pode atrelar valores e referências à estruturas usando a
+ palavra-chave "var":
+ */
+ var um_inteiro:Int = 1;
+ trace(um_inteiro + " é o valor de um_inteiro");
+
+
+ /*
+ Haxe é tipada estaticamente, então "um_inteiro" temos que declarar
+ um valor do tipo "Int", e o restante da expressão atrela o valor "1"
+ a esta variável. Em muitos casos, não é necessário declarar o tipo.
+ Aqui, o compilador haxe assume que o tipo de "outro_inteiro" deve
+ ser "Int"
+ */
+ var outro_inteiro = 2;
+ trace(outro_inteiro + " é o valor de outro_inteiro");
+
+ // O método $type() imprime o tipo que o compilador assume:
+ $type(outro_inteiro);
+
+ // Você também pode representar inteiros em hexadecimal:
+ var hex_inteiro = 0xffffff;
+
+ /*
+ Haxe usa precisão de pltaforma para os tamanhos de Int e Float.
+ Ele também usa o comportamento de plataforma para sobrecarga.
+ (É possível ter outros tipos numéricos e comportamentos usando
+ bibliotecas especiais)
+ */
+
+ /*
+ Em adição a valores simples como Integers, Floats e Booleans,
+ Haxe disponibiliza implementações padrões de bibliotecas para
+ dados comuns de estrutura como strings, arrays, lists e maps:
+ */
+
+ var uma_string = "alguma" + 'string'; // strings podem estar entre aspas simples ou duplas
+ trace(uma_string + " é o valor de uma_string");
+
+ /*
+ Strings podem ser "interpoladas" se inserirmos variáveis em
+ posições específicas. A string deve estar entre aspas simples, e as
+ variáveis devem ser precedidas por "$". Expressões podem estar entre
+ ${...}.
+ */
+ var x = 1;
+ var uma_string_interpolada = 'o valor de x é $x';
+ var outra_string_interpolada = 'o valor de x + 1 é ${x + 1}';
+
+ /*
+ Strings são imutáveis, métodos retornarão uma cópia de partes
+ ou de toda a string. (Veja também a classe StringBuf)
+ */
+ var uma_sub_string = a_string.substr(0,4);
+ trace(uma_sub_string + " é o valor de a_sub_string");
+
+ /*
+ Regex também são suportadas, mas não temos espaço suficiente para
+ entrar em muitos detalhes.
+ */
+ var re = ~/foobar/;
+ trace(re.match('foo') + " é o valor de (~/foobar/.match('foo')))");
+
+ /*
+ Arrays são indexadas a partir de zero, dinâmicas e mutáveis. Valores
+ faltando são definidos como null.
+ */
+ var a = new Array<String>(); // um array que contém Strings
+ a[0] = 'foo';
+ trace(a.length + " é o valor de a.length");
+ a[9] = 'bar';
+ trace(a.length + " é o valor de a.length (depois da modificação)");
+ trace(a[3] + " é o valor de a[3]"); // null
+
+ /*
+ Arrays são *genéricas*, então você pode indicar quais valores elas
+ contém usando um parâmetro de tipo:
+ */
+ var a2 = new Array<Int>(); // um Array de Ints
+ var a3 = new Array<Array<String>>(); // um Array de Arrays (de Strings).
+
+ /*
+ Mapas são estruturas simples de chave/valor. A chave e o valor podem
+ ser de qualquer tipo.
+ */
+ var m = new Map<String, Int>(); // As chaves são strings, os valores são Ints.
+ m.set('foo', 4);
+ // Você também pode usar a notação de array;
+ m['bar'] = 5;
+ trace(m.exists('bar') + " é o valor de m.exists('bar')");
+ trace(m.get('bar') + " é o valor de m.get('bar')");
+ trace(m['bar'] + " é o valor de m['bar']");
+
+ var m2 = ['foo' => 4, 'baz' => 6]; // Syntaxe alternativa de map
+ trace(m2 + " é o valor de m2");
+
+ /*
+ Lembre-se, você pode usar descoberta de tipo. O compilador
+ Haxe irá decidir o tipo da variável assim que você passar um
+ argumento que define um parâmetro de tipo.
+ */
+ var m3 = new Map();
+ m3.set(6, 'baz'); // m3 agora é Map<Int,String>
+ trace(m3 + " é o valor de m3");
+
+ /*
+ Haxe possui mais algumas estruturas de dados padrões no módulo haxe.ds,
+ tais como List, Stack e BalancedTree
+ */
+
+
+ //////////////////////////////////////////////////////////////////
+ // Operadores
+ //////////////////////////////////////////////////////////////////
+ trace("***OPERADORES***");
+
+ // aritmética básica
+ trace((4 + 3) + " é o valor de (4 + 3)");
+ trace((5 - 1) + " é o valor de (5 - 1)");
+ trace((2 * 4) + " é o valor de (2 * 4)");
+ trace((8 / 3) + " é o valor de (8 / 3) (divisão sempre produz Floats)");
+ trace((12 % 4) + " é o valor de (12 % 4)");
+
+
+ // comparação básica
+ trace((3 == 2) + " é o valor de 3 == 2");
+ trace((3 != 2) + " é o valor de 3 != 2");
+ trace((3 > 2) + " é o valor de 3 > 2");
+ trace((3 < 2) + " é o valor de 3 < 2");
+ trace((3 >= 2) + " é o valor de 3 >= 2");
+ trace((3 <= 2) + " é o valor de 3 <= 2");
+
+ // operadores bit-a-bit padrões
+ /*
+ ~ Complemento bit-a-bit unário
+ << Deslocamento a esquerda
+ >> Deslocamento a direita
+ >>> Deslocamento a direita com preenchimento de 0
+ & Bit-a-bit AND
+ ^ Bit-a-bit OR exclusivo
+ | Bit-a-bit OR inclusivo
+ */
+
+ // incrementos
+ var i = 0;
+ trace("Incrementos e decrementos");
+ trace(i++); //i = 1. Pós-incremento
+ trace(++i); //i = 2. Pré-incremento
+ trace(i--); //i = 1. Pós-decremento
+ trace(--i); //i = 0. Pré-decremento
+
+ //////////////////////////////////////////////////////////////////
+ // Estruturas de controle
+ //////////////////////////////////////////////////////////////////
+ trace("***ESTRUTURAS DE CONTROLE***");
+
+ // operadores if
+ var j = 10;
+ if (j == 10){
+ trace("isto é impresso");
+ } else if (j > 10){
+ trace("não é maior que 10, então não é impresso");
+ } else {
+ trace("também não é impresso.");
+ }
+
+ // temos também um if "ternário":
+ (j == 10) ? trace("igual a 10") : trace("diferente de 10");
+
+ /*
+ Por fim, temos uma outra forma de estrutura de controle que opera
+ e na hora da compilação: compilação condicional.
+ */
+#if neko
+ trace('olá de neko');
+#elseif js
+ trace('olá de js');
+#else
+ trace('olá de outra plataforma!');
+#end
+ /*
+ O código compilado irá mudar de acordo com o alvo de plataforma.
+ Se estivermos compilando para neko (-x ou -neko), só teremos a
+ saudação de neko.
+ */
+
+
+ trace("Loops e Interações");
+
+ // loop while
+ var k = 0;
+ while(k < 100){
+ // trace(counter); // irá iprimir números de 0 a 99
+ k++;
+ }
+
+ // loop do-while
+ var l = 0;
+ do{
+ trace("do sempre rodará pelo menos uma vez");
+ } while (l > 0);
+
+ // loop for
+ /*
+ Não há loop for no estilo C para Haxe, pois é propenso
+ a erros e não é necessário. Ao invés disso, Haxe possui
+ uma versão muito mais simples e segura que usa Iterators
+ (veremos isso logo mais).
+ */
+ var m = [1,2,3];
+ for (val in m){
+ trace(val + " é o valor de val no array m");
+ }
+
+ // Perceba que você pode iterar em um índice usando uma lista limitada
+ // (veremos isso em breve também)
+ var n = ['foo', 'bar', 'baz'];
+ for (val in 0...n.length){
+ trace(val + " é o valor de val (um índice de n)");
+ }
+
+
+ trace("Compreensões de array");
+
+ // Compreensões de array servem para que você posse iterar um array
+ // enquanto cria filtros e modificações
+ var n_filtrado = [for (val in n) if (val != "foo") val];
+ trace(n_filtrado + " é o valor de n_filtrado");
+
+ var n_modificado = [for (val in n) val += '!'];
+ trace(n_modificado + " é o valor de n_modificado");
+
+ var n_filtrado_e_modificado = [for (val in n) if (val != "foo") val += "!"];
+ trace(n_filtrado_e_modificado + " é o valor de n_filtrado_e_modificado");
+
+ //////////////////////////////////////////////////////////////////
+ // Blocos Switch (Tipos de valor)
+ //////////////////////////////////////////////////////////////////
+ trace("***BLOCOS SWITCH (Tipos de valor)***");
+
+ /*
+ Blocos Switch no Haxe são muito poderosos. Além de funcionar com
+ valores básicos como strings e ints, também funcionam com tipos
+ algébricos em enums (falaremos sobre enums depois).
+ Veja alguns exemplos de valor básico por enquanto:
+ */
+ var meu_cachorro = "fido";
+ var coisa_favorita = "";
+ switch(meu_cachorro){
+ case "fido" : favorite_thing = "osso";
+ case "rex" : favorite_thing = "sapato";
+ case "spot" : favorite_thing = "bola de tênis";
+ default : favorite_thing = "algum brinquedo desconhecido";
+ // case _ : favorite_thing = "algum brinquedo desconhecido"; // mesma coisa que default
+ }
+ // O case "_" acima é um valor "coringa" que
+ // que funcionará para qualquer coisa.
+
+ trace("O nome do meu cachorro é " + meu_cachorro
+ + ", e sua coisa favorita é: "
+ + coisa_favorita);
+
+ //////////////////////////////////////////////////////////////////
+ // Declarações de expressão
+ //////////////////////////////////////////////////////////////////
+ trace("***DECLARAÇÕES DE EXPRESSÃO***");
+
+ /*
+ As declarações de controle em Haxe são muito poderosas pois
+ toda declaração também é uma expressão, considere o seguinte:
+ */
+
+ // declarações if
+ var k = if (true) 10 else 20;
+
+ trace("k igual a ", k); // retorna 10
+
+ var outra_coisa_favorita = switch(meu_cachorro) {
+ case "fido" : "ursinho";
+ case "rex" : "graveto";
+ case "spot" : "bola de futebol";
+ default : "algum brinquedo desconhecido";
+ }
+
+ trace("O nome do meu cachorro é " + meu cachorro
+ + ", e sua outra coisa favorita é: "
+ + outra_coisa_favorita);
+
+ //////////////////////////////////////////////////////////////////
+ // Convertendo tipos de valores
+ //////////////////////////////////////////////////////////////////
+ trace("***CONVERTENDO TIPOS DE VALORES***");
+
+ // Você pode converter strings em ints de forma bem fácil.
+
+ // string para int
+ Std.parseInt("0"); // retorna 0
+ Std.parseFloat("0.4"); // retorna 0.4;
+
+ // int para string
+ Std.string(0); // retorna "0";
+ // concatenar com strings irá converter automaticamente em string.
+ 0 + ""; // retorna "0";
+ true + ""; // retorna "true";
+ // Veja a documentação de parseamento em Std para mais detalhes.
+
+
+ //////////////////////////////////////////////////////////////////
+ // Lidando com Tipos
+ //////////////////////////////////////////////////////////////////
+
+ /*
+ Como mencionamos anteriormente, Haxe é uma linguagem tipada
+ estaticamente. Tipagem estática é uma coisa maravilhosa. Isto
+ permite autocompletar mais preciso, e pode ser usado para checar
+ completamente o funcionamento de um programa. Além disso, o compilador
+ Haxe é super rápido.
+
+ *ENTRETANTO*, há momentos em que você espera que o compilador apenas
+ deixe algo passar, e não lance um "type error" em um determinado caso.
+
+ Para fazer isso, Haxe tem duas palavras-chave separadas. A primeira
+ é o tipo "Dynamic":
+ */
+ var din: Dynamic = "qualquer tipo de variável, assim como essa string";
+
+ /*
+ Tudo o que você sabe sobre uma variável Dynamic é que o compilador
+ não irá mais se preocupar com o tipo dela. É como uma variável
+ "coringa": você pode usar isso ao invés de qualquer tipo de variável,
+ e você pode atrelar qualquer valor a essa variável.
+
+ A outra (e mais extrema) opção é a palavra-chave "untyped":
+ */
+
+ untyped {
+ var x:Int = 'foo'; // não faz sentido!
+ var y:String = 4; // loucura!
+ }
+
+ /*
+ A palavra-chave "untyped" opera em *blocos* inteiros de código,
+ ignorando qualquer verificação de tipo que seria obrigatória em
+ outros casos. Essa palavra-chave deve ser usada com muita cautela,
+ como em situações limitadas de compilação condicional onde a
+ verificação de tipo pode ser um obstáculo.
+
+ No geral, ignorar verificações de tipo *não* é recomendado. Use
+ os modelos de enum, herança ou estrutural para garantir o correto
+ funcionamento do seu programa. Só quando você tiver certeza de que
+ nenhum desses modelos funcionam no seu caso, você deve usar "Dynamic"
+ ou "untyped".
+ */
+
+ //////////////////////////////////////////////////////////////////
+ // Programação básica orientada a objetos
+ //////////////////////////////////////////////////////////////////
+ trace("***PROGRAMAÇÃO BÁSICA ORIENTADA A OBJETOS***");
+
+
+ /*
+ Cria uma instância da FooClass. As definicções dessas classes
+ estão no final do arquivo.
+ */
+ var instancia_foo = new FooClass(3);
+
+ // lê a variável pública normalmente
+ trace(instancia_foo.variavel_publica + " é o valor de instancia_foo.variavel_publica");
+
+ // nós podemos ler essa variável
+ trace(instancia_foo.publica_leitura + " é o valor de instancia_foo.publica_leitura");
+ // mas não podemos escrever nela
+ // instancia_foo.publica_leitura = 4; // isso irá causar um erro se descomentado:
+ // trace(instancia_foo.public_escrita); // e isso também.
+
+ // chama o método toString:
+ trace(instancia_foo + " é o valor de instancia_foo");
+ // mesma coisa:
+ trace(instancia_foo.toString() + " é o valor de instancia_foo.toString()");
+
+
+ /*
+ A instancia_foo é do tipo "FooClass", enquanto acceptBarInstance
+ é do tipo BarClass. Entretanto, como FooClass extende BarClass,
+ ela é aceita.
+ */
+ BarClass.acceptBarInstance(instancia_foo);
+
+ /*
+ As classes abaixo têm mais alguns exemplos avançados, o método
+ "example()" executará esses exemplos aqui:
+ */
+ SimpleEnumTest.example();
+ ComplexEnumTest.example();
+ TypedefsAndStructuralTypes.example();
+ UsingExample.example();
+
+ }
+
+}
+
+/*
+ Essa é a "classe filha" do classe principal LearnHaxe3
+ */
+class FooClass extends BarClass implements BarInterface{
+ public var variavel_publica:Int; // variáveis públicas são acessíveis de qualquer lugar
+ public var publica_leitura (default, null): Int; // somente leitura pública habilitada
+ public var publica_escrita (null, default): Int; // somente escrita pública habilitada
+ public var property (get, set): Int; // use este estilo para habilitar getters e setters
+
+ // variáveis privadas não estão disponíveis fora da classe.
+ // veja @:allow para formas de fazer isso.
+ var _private:Int; // variáveis são privadas se não forem marcadas como públicas
+
+ // um construtor público
+ public function new(arg:Int){
+ // chama o construtor do objeto pai, já que nós extendemos a BarClass:
+ super();
+
+ this.variavel_publica = 0;
+ this._private = arg;
+
+ }
+
+ // getter para _private
+ function get_property() : Int {
+ return _private;
+ }
+
+ // setter para _private
+ function set_property(val:Int) : Int {
+ _private = val;
+ return val;
+ }
+
+ // função especial que é chamada sempre que uma instância é convertida em string.
+ public function toString(){
+ return _private + " com o método toString()!";
+ }
+
+ // essa classe precisa ter essa função definida, pois ela implementa
+ // a interface BarInterface
+ public function baseFunction(x: Int) : String{
+ // converte o int em string automaticamente
+ return x + " foi passado pela baseFunction!";
+ }
+}
+
+/*
+ Uma classe simples para extendermos
+*/
+class BarClass {
+ var base_variable:Int;
+ public function new(){
+ base_variable = 4;
+ }
+ public static function acceptBarInstance(b:BarClass){
+ }
+}
+
+/*
+ Uma interface simples para implementarmos
+*/
+interface BarInterface{
+ public function baseFunction(x:Int):String;
+}
+
+//////////////////////////////////////////////////////////////////
+// Declarações Enum e Switch
+//////////////////////////////////////////////////////////////////
+
+/*
+ Enums no Haxe são muito poderosos. Resumidamente, enums são
+ um tipo com um número limitado de estados:
+ */
+
+enum SimpleEnum {
+ Foo;
+ Bar;
+ Baz;
+}
+
+// Uma classe que faz uso desse enum:
+
+class SimpleEnumTest{
+ public static function example(){
+ var e_explicit:SimpleEnum = SimpleEnum.Foo; // você pode especificar o nome "completo"
+ var e = Foo; // bas descoberta de tipo também funciona.
+ switch(e){
+ case Foo: trace("e era Foo");
+ case Bar: trace("e era Bar");
+ case Baz: trace("e era Baz"); // comente esta linha e teremos um erro.
+ }
+
+ /*
+ Isso não parece tão diferente de uma alteração simples de valor em strings.
+ Entretanto, se nós não incluirmos *todos* os estados, o compilador
+ reclamará. Você pode testar isso comentando a linha mencionada acima.
+
+ Você também pode especificar um valor padrão (default) para enums:
+ */
+ switch(e){
+ case Foo: trace("e é Foo outra vez");
+ default : trace("default funciona aqui também");
+ }
+ }
+}
+
+/*
+ Enums vão muito mais além que estados simples, nós também
+ podemos enumerar *construtores*, mas nós precisaremos de um
+ exemplo mais complexo de enum:
+ */
+enum ComplexEnum{
+ IntEnum(i:Int);
+ MultiEnum(i:Int, j:String, k:Float);
+ SimpleEnumEnum(s:SimpleEnum);
+ ComplexEnumEnum(c:ComplexEnum);
+}
+// Observação: O enum acima pode incluir *outros* enums também, incluindo ele mesmo!
+// Observação: Isto é o que chamamos de *Tipos de dado algébricos* em algumas outras linguagens.
+
+class ComplexEnumTest{
+ public static function example(){
+ var e1:ComplexEnum = IntEnum(4); // especificando o parâmetro enum
+ /*
+ Agora nós podemos usar switch no enum, assim como extrair qualquer
+ parâmetros que ele possa ter.
+ */
+ switch(e1){
+ case IntEnum(x) : trace('$x foi o parâmetro passado para e1');
+ default: trace("Isso não deve ser impresso");
+ }
+
+ // outro parâmetro aqui que também é um enum... um enum enum?
+ var e2 = SimpleEnumEnum(Foo);
+ switch(e2){
+ case SimpleEnumEnum(s): trace('$s foi o parâmetro passado para e2');
+ default: trace("Isso não deve ser impresso");
+ }
+
+ // enum dentro de enum dentro de enum
+ var e3 = ComplexEnumEnum(ComplexEnumEnum(MultiEnum(4, 'hi', 4.3)));
+ switch(e3){
+ // Você pode buscar por certos enums aninhados especificando-os
+ // explicitamente:
+ case ComplexEnumEnum(ComplexEnumEnum(MultiEnum(i,j,k))) : {
+ trace('$i, $j, e $k foram passados dentro desse monstro aninhado.');
+ }
+ default: trace("Isso não deve ser impresso");
+ }
+ /*
+ Veja outros "tipos de dado algébricos" (GADT, do inglês) para mais
+ detalhes sobre o porque eles são tão úteis.
+ */
+ }
+}
+
+class TypedefsAndStructuralTypes {
+ public static function example(){
+ /*
+ Aqui nós usaremos tipos typedef, ao invés de tipos base.
+ Lá no começo, nós definimos que o tipo "FooString" é um tipo "String".
+ */
+ var t1:FooString = "alguma string";
+
+ /*
+ Aqui nós usamos typedefs para "tipos estruturais" também. Esses tipos
+ são definidos pela sua estrutura de campos, não por herança de classe.
+ Aqui temos um objeto anônimo com um campo String chamado "foo":
+ */
+
+ var anon_obj = { foo: 'hi' };
+
+ /*
+ A variável anon_obj não tem um tipo declarado, e é um objeto anônimo
+ de acordo com o compilador. Entretanto, lembra que lá no início nós
+ declaramos a typedef FooObj? Visto que o anon_obj tem a mesma estrutura,
+ nós podemos usar ele em qualquer lugar que um "FooObject" é esperado.
+ */
+
+ var f = function(fo:FooObject){
+ trace('$fo foi passado para esta função');
+ }
+ f(anon_obj); // chama a assinatura de FooObject com anon_obj.
+
+ /*
+ Note que typedefs podem ter campos opcionais também, marcados com "?"
+
+ typedef OptionalFooObj = {
+ ?optionalString: String,
+ requiredInt: Int
+ }
+ */
+
+ /*
+ Typedefs também funcionam com compilação condicional. Por exemplo,
+ nós poderíamos ter incluído isso no topo deste arquivo:
+
+#if( js )
+ typedef Surface = js.html.CanvasRenderingContext2D;
+#elseif( nme )
+ typedef Surface = nme.display.Graphics;
+#elseif( !flash9 )
+ typedef Surface = flash8.MovieClip;
+#elseif( java )
+ typedef Surface = java.awt.geom.GeneralPath;
+#end
+
+ E teríamos apenas um tipo "Surface" para funcionar em todas
+ essas plataformas.
+ */
+ }
+}
+
+class UsingExample {
+ public static function example() {
+
+ /*
+ A palavra-chave "using" é um tipo especial de import de classe que
+ altera o comportamento de qualquer método estático na classe.
+
+ Neste arquivo, nós aplicamos "using" em "StringTools", que contém
+ alguns métodos estáticos para tratar tipos String.
+ */
+ trace(StringTools.endsWith("foobar", "bar") + " deve ser verdadeiro!");
+
+ /*
+ Com um import "using", o primeiro argumento é extendido com o método.
+ O que isso significa? Bem, como "endsWith" tem um primeiro argumento
+ de tipo "String", isso significa que todos os tipos "String" agora
+ possuem o método "endsWith":
+ */
+ trace("foobar".endsWith("bar") + " deve ser verdadeiro!");
+
+ /*
+ Essa técnica habilita uma grande quantidade de expressões para certos
+ tipos, e limita o escopo de modificações para um único arquivo.
+
+ Note que a instância String *não* é modificada em tempo de execução.
+ O novo método adicionado não é uma parte da instância anexada, e o
+ compilador ainda irá gerar o código equivalente ao método estático.
+ */
+ }
+
+}
+
+```
+Isso foi apenas o começo do que Haxe pode fazer. Para uma documentação de todos
+os recursos de Haxe, veja o [manual](https://haxe.org/manual) e a
+[documentação de API](https://api.haxe.org/). Para um diretório de bibliotecas de terceiros
+disponíveis, veja a [Haxelib](https://lib.haxe.org/)
+
+Para tópicos mais avançados, dê uma olhada em:
+
+* [Tipos abstratos](https://haxe.org/manual/types-abstract.html)
+* [Macros](https://haxe.org/manual/macro.html)
+* [Recursos do compilador](https://haxe.org/manual/cr-features.html)
+
+Por fim, participe do [forum Haxe](https://community.haxe.org/),
+ou no IRC [#haxe onfreenode](http://webchat.freenode.net/), ou no
+[Chat Gitter](https://gitter.im/HaxeFoundation/haxe).
diff --git a/pt-br/html-pt.html.markdown b/pt-br/html-pt.html.markdown
new file mode 100644
index 00000000..22b7836e
--- /dev/null
+++ b/pt-br/html-pt.html.markdown
@@ -0,0 +1,125 @@
+---
+language: html
+filename: learnhtml-br.txt
+contributors:
+ - ["Christophe THOMAS", "https://github.com/WinChris"]
+translators:
+ - ["Robert Steed", "https://github.com/robochat"]
+lang: pt-br
+---
+
+HTML é um acrônimo de HyperText Markup Language(Linguagem de Marcação de HiperTexto).
+É uma linguagem que nos permite escrever páginas para a "world wide web".
+É uma linguagem de marcação, nos permite escrever páginas na web usando código
+para indicar como o texto e os dados serão ser exibidos.
+De fato, arquivos HTML são simples arquivos de texto.
+O que seria marcação? É um método de organização dos dados da página envolvidos
+por abertura e fechamento de tags.
+Essa marcação serve para dar significado ao texto que envolve.
+Assim como outras linguagens, o HTML tem diversas versões. Aqui falaremos sobre o HTML5.
+
+**NOTA :** Você pode testar diferentes tags e elementos conforme progride os
+tutoriais em sites como [codepen](http://codepen.io/pen/) podendo ver seus efeitos,
+entendendo como funcionam e se familiarizando com a linguagem.
+Esse artigo tem seu foco principal na sintaxe do HTML e algumas dicas úteis.
+
+
+```html
+<!-- Comentários são envolvidos conforme essa linha! -->
+
+<!-- #################### As Tags #################### -->
+
+<!-- Aqui está um exemplo de arquivo HTML que iremos analisar. -->
+
+<!doctype html>
+ <html>
+ <head>
+ <title>Meu Site</title>
+ </head>
+ <body>
+ <h1>Olá, mundo!</h1>
+ <a href = "http://codepen.io/anon/pen/xwjLbZ">Venha ver como isso aparece</a>
+ <p>Esse é um parágrafo.</p>
+ <p>Esse é um outro parágrafo.</p>
+ <ul>
+ <li>Esse é um item de uma lista não enumerada (bullet list)</li>
+ <li>Esse é um outro item</li>
+ <li>E esse é o último item da lista</li>
+ </ul>
+ </body>
+ </html>
+
+<!-- Um arquivo HTML sempre inicia indicando ao navegador que é uma página HTML. -->
+<!doctype html>
+
+<!-- Após isso, inicia abrindo a tag <html>. -->
+<html>
+
+<!-- Essa tag deverá ser fechada ao final do arquivo com </html>. -->
+</html>
+
+<!-- Não deverá haver nada após o fechamento desta tag. -->
+
+<!-- Entre a abertura e o fechamento das tags <html></html>, nós encontramos: -->
+
+<!-- Um cabeçalho definido por <head> (deverá ser fechado com </head>). -->
+<!-- O cabeçalho contém uma descrição e algumas informações adicionais que não serão exibidas; chamam-se metadados. -->
+
+<head>
+ <title>Meu Site</title><!-- Essa tag <title> indica ao navegador o título a ser exibido na barra de títulos e no nome da aba. -->
+</head>
+
+<!-- Após a seção <head>, nós encontramos a tag - <body> -->
+<!-- Até esse ponto, nada descrito irá aparecer na janela do browser. -->
+<!-- Nós deveremos preencher o body(corpo) com o conteúdo a ser exibido. -->
+
+<body>
+ <h1>Olá, mundo!</h1> <!-- A tag h1 cria um título. -->
+ <!-- Há também subtítulos do <h1>, o mais importante, aos mais precisos (h6). -->
+ <a href = "http://codepen.io/anon/pen/xwjLbZ">Venha ver o que isso exibe</a> <!-- Um hiperlink ao endereço preenchido no atributo href="" -->
+ <p>Esse é um parágrafo.</p> <!-- A tag <p> permite incluir um texto na página. -->
+ <p>Esse é um outro parágrafo.</p>
+ <ul> <!-- A tag <ul> cria uma lista de marcação. -->
+ <!-- Para criar uma lista ordenada, devemos usar <ol>, exibindo 1. para o primeiro elemento, 2. para o segundo, etc. -->
+ <li>Esse é um item de uma lista não-enumerada.</li>
+ <li>Esse é um outro item</li>
+ <li>E esse é o último item da lista</li>
+ </ul>
+</body>
+
+<!-- E é isso, criar um arquivo HTML pode ser bem simples. -->
+
+<!-- Também é possível adicionar alguns outros tipos de tags HTML. -->
+
+<!-- Para inserir uma imagem. -->
+<img src="http://i.imgur.com/XWG0O.gif"/> <!-- O caminho da imagem deve ser indicado usando o atributo src="" -->
+<!-- O caminho da imagem pode ser uma URL ou até mesmo o caminho do arquivo no seu computador. -->
+
+<!-- Também é possível criar uma tabela. -->
+
+<table> <!-- Iniciamos a tabela com a tag <table>. -->
+ <tr> <!-- <tr> nos permite criar uma linha. -->
+ <th>Primeiro cabeçalho</th> <!-- <th> nos permite criar o título de uma coluna. -->
+ <th>Segundo cabeçalho</th>
+ </tr>
+ <tr>
+ <td>Primeira linha, primeira coluna</td> <!-- <td> nos permite criar uma célula da tabela. -->
+ <td>Primeira linha, segunda coluna</td>
+ </tr>
+ <tr>
+ <td>Segunda linha, primeira coluna</td>
+ <td>Segunda linha, segunda coluna</td>
+ </tr>
+</table>
+
+```
+
+## Uso
+
+HTML é escrito em arquivos com a extensão `.html` ou `.htm`. Seu mime type é `text/html`.
+
+## Para aprender mais
+
+* [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/pt-br/hy-pt.html.markdown b/pt-br/hy-pt.html.markdown
index 5fa4df75..c69ac859 100644
--- a/pt-br/hy-pt.html.markdown
+++ b/pt-br/hy-pt.html.markdown
@@ -1,6 +1,6 @@
---
language: hy
-filename: learnhy.hy
+filename: learnhy-pt.hy
contributors:
- ["Abhishek L", "http://twitter.com/abhishekl"]
translators:
diff --git a/pt-br/java-pt.html.markdown b/pt-br/java-pt.html.markdown
index db087a5f..1b9d7fc6 100644
--- a/pt-br/java-pt.html.markdown
+++ b/pt-br/java-pt.html.markdown
@@ -42,7 +42,7 @@ public class LearnJava {
" Double: " + 3.14 +
" Boolean: " + true);
- // Para imprimir sem inserir uma nova lina, use o System.out.print
+ // Para imprimir sem inserir uma nova linha, use o System.out.print
System.out.print("Olá ");
System.out.print("Mundo");
@@ -407,7 +407,7 @@ class Velocipede extends Bicicleta {
// Interfaces
// Sintaxe de declaração de Interface
-// <nível de acesso> Interface <nome-da-interface> extends <super-interfaces> {
+// <nível de acesso> interface <nome-da-interface> extends <super-interfaces> {
// // Constantes
// // Declarações de método
//}
@@ -415,11 +415,15 @@ class Velocipede extends Bicicleta {
// Exemplo - Comida:
public interface Comestivel {
public void comer(); // Qualquer classe que implementa essa interface, deve
-                        // Implementar este método.
+                        // implementar este método.
}
public interface Digestivel {
public void digerir();
+ // Em Java 8, interfaces podem ter métodos default.
+ // public void digerir() {
+ // System.out.println("digerindo ...");
+ // }
}
@@ -438,7 +442,7 @@ public class Fruta implements Comestivel, Digestivel {
}
// Em Java, você pode estender somente uma classe, mas você pode implementar muitas
-// Interfaces. Por exemplo:
+// interfaces. Por exemplo:
public class ClasseExemplo extends ExemploClassePai implements InterfaceUm,
InterfaceDois {
@@ -461,8 +465,8 @@ public class ClasseExemplo extends ExemploClassePai implements InterfaceUm,
//}
// Marcar uma classe como abstrata significa que ela contém métodos abstratos que devem
-// ser definido em uma classe filha. Semelhante às interfaces, classes abstratas não podem
-// ser instanciadas, ao invés disso devem ser extendidas e os métodos abstratos
+// ser definidos em uma classe filha. Semelhante às interfaces, classes abstratas não podem
+// ser instanciadas, ao invés disso devem ser estendidas e os métodos abstratos
// definidos. Diferente de interfaces, classes abstratas podem conter uma mistura de
// métodos concretos e abstratos. Métodos em uma interface não podem ter um corpo,
// a menos que o método seja estático, e as variáveis sejam finais, por padrão, ao contrário de um
@@ -482,7 +486,7 @@ public abstract class Animal
// Não há necessidade de inicializar, no entanto, em uma interface
    // a variável é implicitamente final e, portanto, tem
-    // de ser inicializado.
+    // de ser inicializada.
protected int idade;
public void mostrarIdade()
@@ -501,7 +505,7 @@ class Cachorro extends Animal
{
// Nota: ainda precisamos substituir os métodos abstratos na
-    // classe abstrata
+    // classe abstrata.
@Override
public void fazerSom()
{
@@ -532,13 +536,13 @@ class Cachorro extends Animal
//}
// Classes finais são classes que não podem ser herdadas e são, portanto, um
-// filha final. De certa forma, as classes finais são o oposto de classes abstratas
-// Porque classes abstratas devem ser estendidas, mas as classes finais não pode ser
+// filho final. De certa forma, as classes finais são o oposto de classes abstratas,
+// porque classes abstratas devem ser estendidas, mas as classes finais não podem ser
// estendidas.
public final class TigreDenteDeSabre extends Animal
{
// Nota: Ainda precisamos substituir os métodos abstratos na
-     // classe abstrata.
+    // classe abstrata.
@Override
public void fazerSom();
{
@@ -552,7 +556,7 @@ public abstract class Mamifero()
// Sintaxe de Métodos Finais:
// <modificador-de-acesso> final <tipo-de-retorno> <nome-do-método>(<argumentos>)
- // Métodos finais, como, classes finais não podem ser substituídas por uma classe filha,
+ // Métodos finais, como classes finais, não podem ser substituídos por uma classe filha,
    // e são, portanto, a implementação final do método.
public final boolean EImpulsivo()
{
diff --git a/pt-br/javascript-pt.html.markdown b/pt-br/javascript-pt.html.markdown
index e337f4bc..e38804f3 100644
--- a/pt-br/javascript-pt.html.markdown
+++ b/pt-br/javascript-pt.html.markdown
@@ -1,7 +1,8 @@
---
language: javascript
+filename: javascript-pt.js
contributors:
- - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Leigh Brenecki", "https://leigh.net.au"]
- ["Ariel Krakowski", "http://www.learneroo.com"]
translators:
- ["Willian Justen", "http://willianjusten.com.br"]
@@ -19,12 +20,12 @@ que é um projeto que fornece um interpretador baseado no motor V8 do Google
Chrome e está se tornando cada vez mais famoso.
Feedback são muito apreciados! Você me encontrar em
-[@adambrenecki](https://twitter.com/adambrenecki), ou
-[adam@brenecki.id.au](mailto:adam@brenecki.id.au).
+[@ExcitedLeigh](https://twitter.com/ExcitedLeigh), ou
+[l@leigh.net.au](mailto:l@leigh.net.au).
```js
// Comentários são como em C. Comentários de uma linha começam com duas barras,
-/* e comentários de múltplas linhas começam com barra-asterisco
+/* e comentários de múltiplas linhas começam com barra-asterisco
e fecham com asterisco-barra */
// comandos podem ser terminados com ;
@@ -360,7 +361,7 @@ myObj.myFunc(); // = "Olá mundo!"
var myFunc = myObj.myFunc;
myFunc(); // = undefined
-// Inversamente, uma função pode ser atribuída a um objeto e ganhar a acesso
+// Inversamente, uma função pode ser atribuída à um objeto e ganhar a acesso
// através do `this`, até mesmo se ela não for chamada quando foi definida.
var myOtherFunc = function(){
return this.myString.toUpperCase();
@@ -415,7 +416,7 @@ myNewObj.myNumber; // = 5
// vai olhar imediatamente para o seu prototype.
// Algumas implementações em JS deixam você acessar o objeto prototype com a
-// propriedade mágica `__proto__`. Enquanto isso é util para explicar
+// propriedade mágica `__proto__`. Enquanto isso é útil para explicar
// prototypes, não é parte de um padrão; nós vamos falar de algumas formas de
// usar prototypes depois.
@@ -488,7 +489,7 @@ if (0){
}
// Entretanto, esses objetos encapsulados e as funções originais compartilham
-// um mesmo prototype, portanto você pode adicionar funcionalidades a uma string,
+// um mesmo prototype, portanto você pode adicionar funcionalidades à uma string,
// por exemplo.
String.prototype.firstCharacter = function(){
return this.charAt(0);
diff --git a/pt-br/json-pt.html.markdown b/pt-br/json-pt.html.markdown
index fd822c03..62d9ccad 100644
--- a/pt-br/json-pt.html.markdown
+++ b/pt-br/json-pt.html.markdown
@@ -16,7 +16,7 @@ Como JSON é um formato de intercâmbio de dados, este será, muito provavelment
JSON na sua forma mais pura não tem comentários, mas a maioria dos analisadores
aceitarão comentários no estilo C (//, /\* \*/). No entanto estes devem ser evitados para otimizar a compatibilidade.
-Um valor JSON pode ser um numero, uma string, um array, um objeto, um booleano (true, false) ou null.
+Um valor JSON pode ser um número, uma string, um array, um objeto, um booleano (true, false) ou null.
Os browsers suportados são: Firefox 3.5+, Internet Explorer 8.0+, Chrome 1.0+, Opera 10.0+, e Safari 4.0+.
diff --git a/pt-br/julia-pt.html.markdown b/pt-br/julia-pt.html.markdown
index 48d97e58..52675bf5 100644
--- a/pt-br/julia-pt.html.markdown
+++ b/pt-br/julia-pt.html.markdown
@@ -8,7 +8,7 @@ translators:
lang: pt-br
---
-Julia é uma linguagem homoiconic funcional focada na computação tecnica. Ao mesmo tempo que ela tem todo o poder dos homoiconic macros, funções de primeira classe, e controle de baixo nivel, Julia é tão facil para aprender e usar quanto Python.
+Julia é uma linguagem homoicônica funcional focada na computação técnica. Ao mesmo tempo que ela tem todo o poder dos macros homoicônicos, funções de primeira classe, e controle de baixo nível, Julia é tão fácil para aprender e usar quanto Python.
Este tutorial é baseado no Julia 0.3.
@@ -104,7 +104,7 @@ println("Eu sou Julia. Prazer em conhece-lo!")
## 2. Variáveis e coleções
####################################################
-#Você não declara variáveis antes de atribui-lás.
+#Você não declara variáveis antes de atribui-las.
some_var = 5 # => 5
some_var # => 5
diff --git a/pt-br/kotlin-pt.html.markdown b/pt-br/kotlin-pt.html.markdown
new file mode 100644
index 00000000..bbe8c0d1
--- /dev/null
+++ b/pt-br/kotlin-pt.html.markdown
@@ -0,0 +1,384 @@
+---
+language: kotlin
+filename: LearnKotlin-pt.kt
+contributors:
+ - ["S Webber", "https://github.com/s-webber"]
+translators:
+ - ["Márcio Torres", "https://github.com/marciojrtorres"]
+lang: pt-br
+---
+
+Kotlin é uma linguagem de programação estaticamente tipada para a JVM, Android e navegadores web. Ela é 100% interoperável com Java.
+[Leia mais aqui.](https://kotlinlang.org/)
+
+```kotlin
+// Comentários de uma linha iniciam com //
+/*
+Comentários multilinha se parecem com este.
+*/
+
+// A palavra-chave "package" funciona do mesmo modo que no Java.
+package com.learnxinyminutes.kotlin
+
+/*
+O ponto de entrada para um programa em Kotlin é uma função chamada "main"
+Esta função recebe um vetor contendo quaisquer argumentos da linha de comando
+*/
+fun main(args: Array<String>) {
+ /*
+ A declaração de valores pode ser feita tanto com "var" como "val"
+ Declarações com "val" não podem ser reatribuídas, enquanto com "var" podem.
+ */
+ val umVal = 10 // não se poderá reatribuir qualquer coisa a umVal
+ var umVar = 10
+ umVar = 20 // umVar pode ser reatribuída, mas respeitando o tipo
+
+ /*
+ Na maioria dos casos Kotlin pode inferir o tipo, então não é preciso sempre
+ especificar o tipo explicitamente, mas quando o fazemos é assim:
+ */
+ val umInteiro: Int = 7
+
+ /*
+ Strings podem ser representadas de forma semelhante a Java.
+ A contrabarra realiza o "escape", da mesma forma.
+ */
+ val umaString = "Minha String está aqui!"
+ val outraString = "Imprimir na outra linha?\nSem problema!"
+ val maisString = "Você quer adicionar um tab?\tSem problema!"
+ println(umaString)
+ println(outraString)
+ println(maisString)
+
+ /*
+ Uma string bruta é delimitada com três aspas (""").
+ Strings brutas podem conter novas linhas e outros caracteres.
+ */
+ val umaStringBruta = """
+fun olaMundo(val nome : String) {
+ println("Olá, mundo!")
+}
+"""
+ println(umaStringBruta)
+
+ /*
+ As strings podem conter expressões modelo (template).
+ Uma expressão modelo começa com um cifrão ($).
+ É semelhante à interpolação de Strings em Ruby.
+ */
+ val umaStringModelo = "$umaString tem ${umaString.length} caracteres"
+ println(umaStringModelo)
+
+ /*
+ Para uma variável receber null deve-se explicitamente declará-la
+ como anulável.
+ A declaração de anulável é realizada incluindo uma "?" ao fim do tipo.
+ Pode-se acessar uma variável anulável usando o operador "?."
+ Usa-se o operador "?:" (também conhecido como operador Elvis) para
+ atribuir um valor alternativo para quando uma variável é nula.
+ */
+ var umaVariavelAnulavel: String? = "abc"
+ println(umaVariavelAnulavel?.length) // => 3
+ println(umaVariavelAnulavel?.length ?: -1) // => 3
+ umaVariavelAnulavel = null
+ println(umaVariavelAnulavel?.length) // => null
+ println(umaVariavelAnulavel?.length ?: -1) // => -1
+
+ /*
+ Funções podem ser declaradas usando a palavra-chave "fun"
+ Os parâmetros da função são declarados entre parênteses logo
+ após o nome da função.
+ Os parâmetros da função podem ter opcionalmente um valor padrão.
+ O tipo de retorno da função, se necessário, é especificado após os argumentos.
+ */
+ fun ola(nome: String = "mundo"): String {
+ return "Olá, $nome!"
+ }
+ println(ola("você")) // => Olá, você!
+ println(ola(nome = "tu")) // => Olá, tu!
+ println(ola()) // => Olá, mundo!
+
+ /*
+ Um parâmetro pode ser declarado com a palavra-chave "vararg" para
+ permitir que seja passado um número variável de argumentos.
+ */
+ fun exemploVarArg(vararg numeros: Int) {
+ println("Foram recebidos ${numeros.size} argumentos")
+ }
+ exemploVarArg() // => Passando nenhum argumento (0 argumentos)
+ exemploVarArg(1) // => Passando 1 argumento
+ exemploVarArg(1, 2, 3) // => Passando 3 argumentos
+
+ /*
+ Quando uma função consiste numa única expressão as chaves
+ podem ser omitidas e o corpo declarado após o símbolo de "="
+ */
+ fun impar(x: Int): Boolean = x % 2 == 1
+ println(impar(6)) // => false
+ println(impar(7)) // => true
+
+ // O tipo de retorno não precisa ser declarado se pode ser inferido.
+ fun impar(x: Int) = x % 2 == 0
+ println(impar(6)) // => true
+ println(impar(7)) // => false
+
+ // Funções podem receber e retornar outras funções
+ fun nao(f: (Int) -> Boolean): (Int) -> Boolean {
+ return {n -> !f.invoke(n)}
+ }
+ // Funções nomeadas podem ser passadas como argumento usando o operador "::"
+ val naoImpar = nao(::impar)
+ val naoPar = nao(::par)
+ // Expressões Lambda podem ser usadas como argumentos
+ val naoZero = nao {n -> n == 0}
+ /*
+ Se uma lambda têm apenas um parâmetro sua declaração pode ser omitida,
+ incluindo o símbolo "->".
+ Neste caso o nome do único parâmetro deve ser "it".
+ */
+ val naoPositivo = nao {it > 0}
+ for (i in 0..4) {
+ println("${naoImpar(i)} ${naoPar(i)} ${naoZero(i)} ${naoPositivo(i)}")
+ }
+
+ // A palavra-chave "class" é usada para declarar classes
+ class ClasseExemplo(val x: Int) {
+ fun funcaoMembro(y: Int): Int { // ou "método"
+ return x + y
+ }
+
+ infix fun funcaoMembroInfixa(y: Int): Int {
+ return x * y
+ }
+ }
+ /*
+ Para criar uma nova instância chama-se o construtor.
+ Note que Kotlin não tem a palavra-chave "new".
+ */
+ val umaInstanciaDaClasseExemplo = ClasseExemplo(7)
+ // Funções membro (métodos) podem ser chamados usando a notação ponto "."
+ println(umaInstanciaDaClasseExemplo.funcaoMembro(4)) // => 11
+ /*
+ Se uma função foi declarada com a palavra-chave "infix" então
+ ela pode ser invocada com a notação infixa.
+ */
+ println(umaInstanciaDaClasseExemplo funcaoMembroInfixa 4) // => 28
+
+ /*
+ Classes de dados são um modo sucinto de criar classes que servem apenas
+ para guardar informações.
+ Os métodos "hashCode", "equals" e "toString" são gerados automaticamente.
+ */
+ data class ExemploClasseDados (val x: Int, val y: Int, val z: Int)
+ val objetoDados = ExemploClasseDados(1, 2, 4)
+ println(objetoDados) // => ExemploClasseDados(x=1, y=2, z=4)
+
+ // Classes de dados têm uma função "copy"
+ val dadosCopia = objetoDados.copy(y = 100)
+ println(dadosCopia) // => ExemploClasseDados(x=1, y=100, z=4)
+
+ // Objetos podem ser desestruturados em múltiplas variáveis.
+ val (a, b, c) = dadosCopia
+ println("$a $b $c") // => 1 100 4
+
+ // desestruturando em um laço "for"
+ for ((a, b, c) in listOf(objetoDados)) {
+ println("$a $b $c") // => 1 100 4
+ }
+
+ val mapaDados = mapOf("a" to 1, "b" to 2)
+ // Map.Entry também é desestruturável
+ for ((chave, valor) in mapaDados) {
+ println("$chave -> $valor")
+ }
+
+ // A função "with" é semelhante à declaração "with" do JavaScript
+ data class ExemploClasseDadosMutaveis (var x: Int, var y: Int, var z: Int)
+ val objDadosMutaveis = ExemploClasseDadosMutaveis(7, 4, 9)
+ with (objDadosMutaveis) {
+ x -= 2
+ y += 2
+ z--
+ }
+ println(objDadosMutaveis) // => ExemploClasseDadosMutaveis(x=5, y=6, z=8)
+
+ /*
+ Pode-se criar uma lista usando a função "listOf".
+ A lista é imutável, isto é, elementos não podem ser adicionados ou removidos.
+ */
+ val umaLista = listOf("a", "b", "c")
+ println(umaLista.size) // => 3
+ println(umaLista.first()) // => a
+ println(umaLista.last()) // => c
+ // Elementos de uma lista podem ser acessados pelo índice
+ println(umaLista[1]) // => b
+
+ // Uma lista mutável pode ser criada com a função "mutableListOf".
+ val umaListaMutavel = mutableListOf("a", "b", "c")
+ umaListaMutavel.add("d")
+ println(umaListaMutavel.last()) // => d
+ println(umaListaMutavel.size) // => 4
+
+ // Similarmente, pode-se criar um conjunto com a função "setOf".
+ val umConjunto = setOf("a", "b", "c")
+ println(umConjunto.contains("a")) // => true
+ println(umConjunto.contains("z")) // => false
+
+ // Da mesma forma que um mapa com a função "mapOf".
+ val umMapa = mapOf("a" to 8, "b" to 7, "c" to 9)
+ // Os valores contidos no mapa podem ser acessados pela sua chave.
+ println(umMapa["a"]) // => 8
+
+ /*
+ Sequências representam coleções avaliadas "preguiçosamente" (sob demanda).
+ Pode-se criar uma sequência usando a função "generateSequence".
+ */
+ val umaSequencia = generateSequence(1, { it + 1 })
+ val x = umaSequencia.take(10).toList()
+ println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+
+ // Um exemplo de uma sequência usada para gerar Números de Fibonacci:
+ fun sequenciaFibonacci(): Sequence<Long> {
+ var a = 0L
+ var b = 1L
+
+ fun proximo(): Long {
+ val resultado = a + b
+ a = b
+ b = resultado
+ return a
+ }
+
+ return generateSequence(::proximo)
+ }
+ val y = sequenciaFibonacci().take(10).toList()
+ println(y) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
+
+ // Kotlin oferece funções de alta-ordem para trabalhar com coleções.
+ val z = (1..9).map {it * 3}
+ .filter {it < 20}
+ .groupBy {it % 2 == 0}
+ .mapKeys {if (it.key) "par" else "impar"}
+ println(z) // => {impar=[3, 9, 15], par=[6, 12, 18]}
+
+ // Um "for" pode ser usado com qualquer coisa que ofereça um "iterator"
+ for (c in "salve") {
+ println(c)
+ }
+
+ // O "while" funciona da mesma forma que em outras linguagens.
+ var contador = 0
+ while (contador < 5) {
+ println(contador)
+ contador++
+ }
+ do {
+ println(contador)
+ contador++
+ } while (contador < 10)
+
+ /*
+ "if" pode ser usado como uma expressão que retorna um valor.
+ Por este motivo o operador ternário "? :" não é necessário em Kotlin.
+ */
+ val numero = 5
+ val mensagem = if (numero % 2 == 0) "par" else "impar"
+ println("$numero é $mensagem") // => 5 é impar
+
+ // "when" pode ser usado como alternativa às correntes de "if-else if".
+ val i = 10
+ when {
+ i < 7 -> println("primeiro block")
+ umaString.startsWith("oi") -> println("segundo block")
+ else -> println("bloco else")
+ }
+
+ // "when" pode ser usado com um argumento.
+ when (i) {
+ 0, 21 -> println("0 ou 21")
+ in 1..20 -> println("entre 1 e 20")
+ else -> println("nenhum dos anteriores")
+ }
+
+ // "when" pode ser usada como uma função que retorna um valor.
+ var resultado = when (i) {
+ 0, 21 -> "0 ou 21"
+ in 1..20 -> "entre 1 e 20"
+ else -> "nenhum dos anteriores"
+ }
+ println(resultado)
+
+ /*
+ Pode-se verificar se um objeto é de um certo tipo usando o operador "is".
+ Se o objeto passar pela verificação então ele pode ser usado como
+ este tipo, sem a necessidade de uma coerção (cast) explícita (SmartCast).
+ */
+ fun exemploSmartCast(x: Any) : Boolean {
+ if (x is Boolean) {
+ // x é automaticamente coagido para Boolean
+ return x
+ } else if (x is Int) {
+ // x é automaticamente coagido para Int
+ return x > 0
+ } else if (x is String) {
+ // x é automaticamente coagido para String
+ return x.isNotEmpty()
+ } else {
+ return false
+ }
+ }
+ println(exemploSmartCast("Olá, mundo!")) // => true
+ println(exemploSmartCast("")) // => false
+ println(exemploSmartCast(5)) // => true
+ println(exemploSmartCast(0)) // => false
+ println(exemploSmartCast(true)) // => true
+
+ // O Smartcast também funciona com blocos "when"
+ fun exemploSmartCastComWhen(x: Any) = when (x) {
+ is Boolean -> x
+ is Int -> x > 0
+ is String -> x.isNotEmpty()
+ else -> false
+ }
+
+ /*
+ As extensões são uma maneira nova de adicionar funcionalidades a classes.
+ Elas são similares aos "extension methods" da linguagem C#.
+ */
+ fun String.remove(c: Char): String {
+ return this.filter {it != c}
+ }
+ println("olá, mundo!".remove('o')) // => lá, mund!
+
+ println(ExemploEnum.A) // => A
+ println(ExemploObjeto.ola()) // => olá
+}
+
+// Classes Enum são similares aos "enum types" do Java.
+enum class ExemploEnum {
+ A, B, C
+}
+
+/*
+A palavra-chave "object" pode ser usar para criar Singletons.
+Eles não são instanciados, mas podem referenciar sua instância única pelo nome.
+É semelhante aos "singleton objects" da linguagem Scala.
+*/
+object ExemploObjeto {
+ fun ola(): String {
+ return "olá"
+ }
+}
+
+fun usaObjeto() {
+ ExemploObjeto.ola()
+ val algumaReferencia: Any = ExemploObjeto // usa-se o nome diretamente
+}
+
+```
+
+### Leitura Adicional
+
+* [Tutoriais de Kotlin](https://kotlinlang.org/docs/tutorials/)(EN)
+* [Experimente Kotlin no seu navegador](http://try.kotlinlang.org/)(EN)
+* [Uma lista de material sobre Kotlin](http://kotlin.link/)(EN)
diff --git a/pt-br/latex-pt.html.markdown b/pt-br/latex-pt.html.markdown
new file mode 100644
index 00000000..58586522
--- /dev/null
+++ b/pt-br/latex-pt.html.markdown
@@ -0,0 +1,291 @@
+---
+language: latex
+contributors:
+ - ["Chaitanya Krishna Ande", "http://icymist.github.io"]
+ - ["Colton Kohnke", "http://github.com/voltnor"]
+ - ["Sricharan Chiruvolu", "http://sricharan.xyz"]
+ - ["Ramanan Balakrishnan", "https://github.com/ramananbalakrishnan"]
+ - ["Svetlana Golubeva", "https://attillax.github.io/"]
+translators:
+ - ["Paulo Henrique Rodrigues Pinheiro", "https://github.com/paulohrpinheiro"]
+lang: pt-br
+filename: learn-latex-pt.tex
+---
+
+```tex
+% Todas as linhas de comentários começam com %
+% Não existem comentários multilinhas
+
+$ LaTeX não é um programa processador de textos "Visual" como
+% MS Word ou OpenOffice Writer
+
+$ Todo comando LaTeX começa com uma barra invertida (\)
+
+% Documentos LaTeX começam com a definição do tipo que será % compilado
+% Os tipos de documento podem ser livro, relatório, apresentação, etc.
+% As opções para um documento aparecem entre [] chaves. Nesse caso
+% está especificado que queremos o tamanho da fonte em 12pt.
+\documentclass[12pt]{article}
+
+% Em seguida definimos os pacotes que o documento usa.
+% Se você quiser incluir gráficos, texto colorido, ou código fonte de outra
+% linguagem em outro arquivo em seu documento, você precisa ampliar as
+% capacidades do LaTeX. Isso é feito adicionando-se pacotes.
+% Serão incluídos os pacotes float e caption para imagens e hyperref
+% para links.
+\usepackage{caption}
+\usepackage{float}
+\usepackage{hyperref}
+
+% Para poder usar caracteres acentuados, use o seguinte pacote:
+\usepackage[utf8]{inputenc}
+
+% Podemos definir algumas outras propriedades do documento também!
+\author{Chaitanya Krishna Ande, Colton Kohnke, Sricharan Chiruvolu \& \\
+Svetlana Golubeva}
+\date{\today}
+\title{Aprenda \LaTeX \hspace{1pt} em Y Minutos!}
+
+% Agora estamos prontos para começar o documento
+% Tudo antes dessa linha é chamado "preâmbulo".
+\begin{document}
+% Se informarmos os campos author (autores), date (data), "title" (título),
+% LaTeX poderá cria uma página inicial para nós.
+\maketitle
+% Se tivermos seções, poderemos criar uma tabela de conteúdo. Para isso,
+% o documento deve ser compilado duas vezes, para que tudo apareça na ordem
+% correta.
+% É uma boa prática separar a tabela de conteúdo do corpo do documento. Para
+% isso usa-se o comando \newpage
+\newpage
+\tableofcontents
+
+\newpage
+
+% Muitos artigos de pesquisa possuem um resumo, e pode-se usar comandos
+% predefinidos para isso.
+% Isso deve aparecer em sua ordem lógica, portanto, após o topo,
+% mas antes das seções principais do corpo.
+% Esse comando está disponível para os documentos do tipo artigo (article)
+% e relatório (report).
+\begin{abstract}
+ Documentação do \LaTeX \hspace{1pt} escrita em \LaTeX! Nada original!
+\end{abstract}
+
+% Comandos para seções são intuitivos.
+% Todos os títulos de seção são adicionados automaticamente à tabela de conteúdo.
+\section{Introdução}
+Olá, meu nome é Colton e juntos estamos explorando o mundo do \LaTeX!
+
+\section{Outra seção}
+Esse é o texto para outra seção. Penso que precisamos de uma subseção.
+
+\subsection{Isso é uma subseção} % Subseções também são intuitivas.
+Penso que precisamos de mais uma
+
+\subsubsection{Pythagoras}
+Muito melhor agora.
+\label{subsec:pythagoras}
+
+% Ao usar o asterisco nós impedimos a numeração automática.
+% Isso funciona para outros comandos \LaTeX também.
+\section*{Essa é uma seção não numerada}
+Afinal nem todas as seções precisam ser numeradas!
+
+\section{Algumas notas sobre texto}
+%\section{Espaçamento % É necessário mais informação sobre intervalos de espaço.
+\LaTeX \hspace{1pt} geralmente é muito bom sobre colocar texto onde ele deve
+ser posto. Se
+uma linha \\ deve \\ ser \\ quebrada \\ adicione \textbackslash\textbackslash
+\hspace{1pt} ao código de seu documento. \\
+
+\section{Listas}
+Listas são uma das coisas mais fáceis de criar no \LaTeX! Preciso fazer compras
+amanhã, então façamos uma lista de compras.
+\begin{enumerate} % Isso cria o bloco "enumerate".
+ % \item faz com que o enumerate incremente
+ \item Salada.
+ \item 27 melancias.
+ \item Uma lebre.
+ % pode-se também sobrescrever o número do item usando []
+ \item[quantas?] Pistolas de água médias.
+
+ Não é um item da lista, mas faz parte do bloco enumerate.
+
+ \end{enumerate} % Todos os blocos devem ter um final (end{}).
+
+\section{Matemática}
+
+Um dos usos iniciais para \LaTeX \hspace{1pt} foi a produção de artigos
+acadêmicos e técnicos. Usualmente nos campos da matemática e ciência. Assim, é
+necessários que consigamos incluir alguns símbolos especiais em nosso texto! \\
+
+A matemática tem muitos símbolos, além dos quais se pode encontrar no teclado;
+símbolos para relações e conjuntos, setas, operadores, e letras gregas, apenas
+para mencionar alguns.\\
+
+Conjuntos e relações são essenciais em muitos textos de pesquisa em matemática.
+Aqui está como você pode indicar como todo x que pertence
+a X, $\forall$ x $\in$ X. \\
+% Perceba que é necessário adicionar os sinais $ antes e depois dos símbolos.
+% Isso é porque quando escrevendo, estamos em modo texto.
+% Mas os símbolos de matemática só existem no modo matemática.
+% Podemos entrar no modo matemática a partir do modo texto com os símbolos $.
+% O oposto também pode ocorrer. Variáveis podem ser renderizadas no modo
+% matemática.
+% Também podemos entrar no modo matemática com \[\]
+
+\[a^2 + b^2 = c^2 \]
+
+Minha letra grega favorita é $\xi$. Eu também gosto da $\beta$, $\gamma$ e $\sigma$.
+Eu ainda não encontrei uma letra grega que o \LaTeX \hspace{1pt} não tenha!\\
+
+Operadores são parte essencial de um documento sobre matemática:
+funções trigonométricas ($\sin$, $\cos$, $\tan$),
+logaritmo e exponencial ($\log$, $\exp$),
+limites ($\lim$), etc.
+possuem comandos pré-definidos em LaTex.
+Vamos escrever uma equação para ver como se faz:
+$\cos(2\theta) = \cos^{2}(\theta) - \sin^{2}(\theta)$ \\
+
+Frações (numerador/denominador) podem ser escritas dessa forma:
+
+% 10 / 7
+$$ ^{10}/_{7} $$
+
+% Frações relativamente complexas podem ser escritas como
+% \frac{numerator}{denominator}
+$$ \frac{n!}{k!(n - k)!} $$ \\
+
+Também podemos escrever equações em um ``bloco de equação''.
+
+% Apresenta matemática com o 'bloco' equação
+\begin{equation} % entra no modo matemática
+ c^2 = a^2 + b^2.
+ \label{eq:pythagoras} % para referência
+ \end{equation} % toda declaração \begin precisa de uma declaração end
+
+Podemos então referenciar nossa nova equação!
+A equação~\ref{eq:pythagoras} é também conhecida como Teorema de Pitágoras que é
+também assunto da Seção~\ref{subsec:pythagoras}. Muitas coisas podem ser
+rotuladas: figuras, equações, seções, etc.
+
+Somatórios e Integrais são escritas com os comandos sum e int:
+
+% Alguns compiladores LaTeX irão reclamar se existirem linhas em branco
+% em um bloco de equação.
+\begin{equation}
+ \sum_{i=0}^{5} f_{i}
+\end{equation}
+\begin{equation}
+ \int_{0}^{\infty} \mathrm{e}^{-x} \mathrm{d}x
+\end{equation}
+
+\section{Figuras}
+
+Insiramos uma Figura. O local para colocar a figura pode ser difícil
+de determinar. Eu tenho sempre que verificar as opções toda vez.
+
+\begin{figure}[H] % H aqui é uma opção para o local da figura.
+ \centering % centra a figura na página
+ % Inclui uma figura com escala de 0.8 do tamanho da página.
+ %\includegraphics[width=0.8\linewidth]{right-triangle.png}
+ % Comentado para propósitos de compilação. Por favor, use sua imaginação.
+ \caption{Triângulo retângulo com lados $a$, $b$, $c$}
+ \label{fig:right-triangle}
+\end{figure}
+
+\subsection{Tabelas}
+Também podemos incluir tabelas da mesma forma que figuras.
+
+\begin{table}[H]
+ \caption{Título para a Tabela.}
+ % os argumentos {} abaixo descrevem como cada linha da tabela é desenhada.
+ % Aqui também, Preciso ver isso. Toda. E. Cada. Vez.
+ \begin{tabular}{c|cc}
+ Número & Sobrenome & Primeiro Nome \\ % Colunas são separadas por &
+ \hline % uma linha horizontal
+ 1 & Biggus & Dickus \\
+ 2 & Monty & Python
+ \end{tabular}
+\end{table}
+
+\section{Fazendo o \LaTeX \hspace{1pt} não compilar algo (o código fonte)}
+Digamos que precisamos incluir algum código dentro do nosso
+documento \LaTeX \hspace{1pt}, para isso precisamos com o \LaTeX \hspace{1pt}
+não tente interpretar esse texto e que apenas inclua ele no documento. Fazemos
+isso com o bloco verbatim.
+
+% Existem outros pacotes (por exemplo, minty, lstlisting, etc.)
+% mas verbatim é o básico
+\begin{verbatim}
+ print("Hello World!")
+ a%b; % olha só! Podemos usar os sinais % no bloco verbatim.
+ random = 4; #decided by fair random dice roll
+\end{verbatim}
+
+\section{Compilando}
+
+Imagino que agora você esteja pensando como compilar esse fantástico documento
+e visualizar a gloriosa glória que é um pdf gerado por \LaTeX \hspace{1pt} pdf.
+(sim, esse documento é compilável). \\
+
+Finalizando o documento usando \LaTeX \hspace{1pt} consiste nos seguintes passos:
+ \begin{enumerate}
+ \item Escrever o documento em texto puro (o ``código fonte'').
+ \item Compilar o código fonte para gerar um pdf.
+ Os passos para compilar se parecem (em Linux) com: \\
+ \begin{verbatim}
+ > pdflatex learn-latex.tex
+ \end{verbatim}
+ \end{enumerate}
+
+Existem editores de \LaTeX \hspace{1pt} que combinam os passos 1 e 2 no mesmo
+sistema de software. Assim, você pode ver o passo 1, mas não o passo 2 por
+completo. Passo 2 estará acontecendo escondido\footnote{Por exemplo, quando usar
+referências (como Equação~\ref{eq:pythagoras}), pode ser necessário executar o
+passo 2 várias vezes, para gerar arquivos *.aux intermediários.}.
+% É assim que você adiciona notas de rodapé em seus documentos!
+
+Você escreve toda a informação de formatação em texto puro, no passo 1. O
+momento da compilação no passo 2 é responsável por produzir o documento no
+formato que você definiu no passo 1.
+
+\section{Links}
+Nós podemos inserir links em nosso documento. Para isso nós necessitamos incluir
+o pacote hyperref no preâmbulo com o comando:
+\begin{verbatim}
+ \usepackage{hyperref}
+\end{verbatim}
+
+Existem dois tipos principais de links: URL visíveis \\
+\url{https://learnxinyminutes.com/docs/latex/}, ou
+\href{https://learnxinyminutes.com/docs/latex/}{um texto alternativo}
+% Você não pode adicionar espaços extras ou símbolos especiais no texto
+% alternativo, pois isso causará problemas na compilação.
+
+Esse pacote também produz uma lista de thumbnails no documento pdf gerado e
+ativa os links na tabela de conteúdo.
+
+\section{End}
+
+Por enquanto é isso!
+
+% Frequentemente você precisa de uma seção de referências em seu documento.
+% A forma mais fácil de configurá-la é usando uma seção de bibliografia
+\begin{thebibliography}{1}
+ % como em outras listas, o comando \bibitem pode ser usado para itens da lista
+ % cada entrada pode ser citada diretamente no corpo do texto
+ \bibitem{latexwiki} The amazing \LaTeX \hspace{1pt} wikibook: {\em
+https://en.wikibooks.org/wiki/LaTeX}
+ \bibitem{latextutorial} An actual tutorial: {\em http://www.latex-tutorial.com}
+\end{thebibliography}
+
+% end the document
+\end{document}
+```
+
+## Mais sobre LaTeX
+
+* The amazing LaTeX wikibook: [https://en.wikibooks.org/wiki/LaTeX](https://en.wikibooks.org/wiki/LaTeX)
+* An actual tutorial: [http://www.latex-tutorial.com/](http://www.latex-tutorial.com/)
diff --git a/pt-br/less-pt.html.markdown b/pt-br/less-pt.html.markdown
new file mode 100644
index 00000000..f6cf2d71
--- /dev/null
+++ b/pt-br/less-pt.html.markdown
@@ -0,0 +1,390 @@
+---
+language: less
+filename: learnless-br.less
+contributors:
+ - ["Saravanan Ganesh", "http://srrvnn.me"]
+
+lang: pt-br
+---
+
+Less é um pré-processador de CSS, que adiciona recursos como variáveis, aninhamento, mixins e muito mais.
+Less (e outros pré-processadores, como o [Sass](http://sass-lang.com/)) ajudam os desenvolvedores a escreverem código que pode ser mantido e DRY (não se repita).
+
+```css
+
+
+//Comentários de linha única são removidos quando Less é compilado para CSS.
+
+/*Comentários de várias linhas são preservados.*/
+
+
+
+/* Variáveis
+==============================*/
+
+
+/* Você pode armazenar um valor de CSS (como uma cor) em uma variável.
+ Use o símbolo '@' para criar uma variável. */
+
+@primary-color: #a3a4ff;
+@secondary-color: #51527f;
+@body-font: 'Roboto', sans-serif;
+
+/* Você pode usar as variáveis ​​em toda a sua folha de estilo.
+ Agora, se você quiser alterar uma cor, só precisa fazer a alteração uma vez. */
+
+body {
+ background-color: @primary-color;
+ color: @secondary-color;
+ font-family: @body-font;
+}
+
+/* Isso compilará para: */
+
+body {
+ background-color: #a3a4ff;
+ color: #51527F;
+ font-family: 'Roboto', sans-serif;
+}
+
+
+/* Isso é muito mais sustentável do que ter que mudar a cor
+ cada vez que aparece em toda a sua folha de estilo. */
+
+
+
+/* Mixins
+==============================*/
+
+
+/* Se você achar que está escrevendo o mesmo código para mais de um
+ elemento, você pode querer reutilizá-lo facilmente. */
+
+.center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+}
+
+/* Você pode usar o mixin simplesmente adicionando o seletor como um estilo. */
+
+div {
+ .center;
+ background-color: @primary-color;
+}
+
+/* Que compilaria para: */
+
+.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;
+}
+
+/* Você pode omitir o código mixin de ser compilado adicionando parênteses
+ depois do seletor. */
+
+.center() {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+}
+
+div {
+ .center;
+ background-color: @primary-color;
+}
+
+/* Que compilaria para: */
+div {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+ background-color: #a3a4ff;
+}
+
+
+
+/* Aninhamento
+==============================*/
+
+
+/* Less permite aninhar seletores nos seletores. */
+
+ul {
+ list-style-type: none;
+ margin-top: 2em;
+
+ li {
+ background-color: #f00;
+ }
+}
+
+/* '&' será substituído pelo seletor pai. */
+/* Você também pode aninhar pseudo-classes. */
+/* Tenha em mente que o aninhamento excessivo tornará seu código menos sustentável.
+ As melhores práticas recomendam não ultrapassar 3 níveis de profundidade ao aninhar.
+ Por exemplo: */
+
+ul {
+ list-style-type: none;
+ margin-top: 2em;
+
+ li {
+ background-color: red;
+
+ &:hover {
+ background-color: blue;
+ }
+
+ a {
+ color: white;
+ }
+ }
+}
+
+/* Compila para: */
+
+ul {
+ list-style-type: none;
+ margin-top: 2em;
+}
+
+ul li {
+ background-color: red;
+}
+
+ul li:hover {
+ background-color: blue;
+}
+
+ul li a {
+ color: white;
+}
+
+
+
+/* Functions
+==============================*/
+
+
+/* Less fornece funções que podem ser usadas para realizar uma variedade de
+ tarefas. Considere o seguinte: */
+
+/* Funções podem ser invocadas usando seu nome e passando os
+ argumentos requeridos. */
+
+body {
+ width: round(10.25px);
+}
+
+.header {
+ background-color: lighten(#000, 0.5);
+}
+
+.footer {
+ background-color: fadeout(#000, 0.25)
+}
+
+/* Compila para: */
+
+body {
+ width: 10px;
+}
+
+.header {
+ background-color: #010101;
+}
+
+.footer {
+ background-color: rgba(0, 0, 0, 0.75);
+}
+
+/* Você também pode definir suas próprias funções. Funções são muito semelhantes às
+ mixins. Ao tentar escolher entre uma função ou a um mixin, lembre-se
+ que mixins são melhores para gerar CSS, enquanto as funções são melhores para
+ lógica que pode ser usada em todo o seu código Less. Os exemplos na
+ seção 'Operadores Matemáticos' são candidatos ideais para se tornarem funções reutilizáveis. */
+
+/* Esta função calcula a média de dois números: */
+
+.average(@x, @y) {
+ @average-result: ((@x + @y) / 2);
+}
+
+div {
+ .average(16px, 50px); // "chama" o mixin
+ padding: @average-result; // use seu valor de "retorno"
+}
+
+/* Compila para: */
+
+div {
+ padding: 33px;
+}
+
+
+
+/* Estender (herança)
+==============================*/
+
+
+/* Estender é uma maneira de compartilhar as propriedades de um seletor com outro. */
+
+.display {
+ height: 50px;
+}
+
+.display-success {
+ &:extend(.display);
+ border-color: #22df56;
+}
+
+/* Compila para: */
+
+.display,
+.display-success {
+ height: 50px;
+}
+.display-success {
+ border-color: #22df56;
+}
+
+/* Estender uma instrução CSS é preferível para criar um mixin
+ por causa da maneira como agrupa as classes que compartilham
+ o mesmo estilo base. Se isso foi feito com um mixin, as propriedades
+ seriam duplicadas para cada declaração que
+ chamou o mixin. Embora isso não afete o seu fluxo de trabalho,
+ adicione o inchaço desnecessário aos arquivos criados pelo compilador Less. */
+
+
+
+/* Parciais e Importações
+==============================*/
+
+
+/* Less permite criar arquivos parciais. Isso pode ajudar a manter o seu
+ código Less modularizado. Arquivos parciais convencionalmente começam com um '_',
+ por exemplo. _reset.less. e são importados para um arquivo less principal que recebe
+ o css compilado. */
+
+/* Considere o seguinte CSS que vamos colocar em um arquivo chamado _reset.less */
+
+html,
+body,
+ul,
+ol {
+ margin: 0;
+ padding: 0;
+}
+
+/* Less disponibiliza @import que podem ser usadas para importar parciais em um arquivo.
+ Isso difere da declaração tradicional CSS @import que faz
+ outra solicitação HTTP para buscar o arquivo importado. Less leva o
+ arquivo importado e combina com o código compilado. */
+
+@import 'reset';
+
+body {
+ font-size: 16px;
+ font-family: Helvetica, Arial, Sans-serif;
+}
+
+/* Compila para: */
+
+html, body, ul, ol {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ font-size: 16px;
+ font-family: Helvetica, Arial, Sans-serif;
+}
+
+
+
+/* Operações Matemáticas
+==============================*/
+
+
+/* Less fornece os seguintes operadores: +, -, *, / e %. Estes podem
+ ser úteis para calcular valores diretamente nos seus arquivos Less
+ para usar valores que você já calculou manualmente. Abaixo está um exemplo
+ de como configurar um design simples de duas colunas. */
+
+@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;
+}
+
+/* Compila para: */
+
+body {
+ width: 100%;
+}
+
+.main-content {
+ width: 62.5%;
+}
+
+.sidebar {
+ width: 31.25%;
+}
+
+.gutter {
+ width: 6.25%;
+}
+
+
+```
+
+## Pratique Less
+
+Se você quiser praticar com Less no seu navegador, confira: * [Codepen](http://codepen.io/) * [LESS2CSS](http://lesscss.org/less-preview/)
+
+## Compatibilidade
+
+Less pode ser usado em qualquer projeto, desde que você tenha um programa para compilá-lo em CSS. Você deseja verificar
+se o CSS que você está usando é compatível com seus navegadores de destino.
+
+[QuirksMode CSS](http://www.quirksmode.org/css/) e [CanIUse](http://caniuse.com) são ótimos recursos para verificar a compatibilidade.
+
+## Leitura adicional
+* [Documentação Oficial](http://lesscss.org/features/)
+* [Less CSS - Guia do iniciante](http://www.hongkiat.com/blog/less-basic/)
diff --git a/pt-br/lua-pt.html.markdown b/pt-br/lua-pt.html.markdown
new file mode 100644
index 00000000..0c75da26
--- /dev/null
+++ b/pt-br/lua-pt.html.markdown
@@ -0,0 +1,423 @@
+---
+language: Lua
+contributors:
+ - ["Tyler Neylon", "http://tylerneylon.com/"]
+filename: learnlua.lua
+translators:
+ - ["Iaan Mesquita", "https://github.com/ianitow"]
+lang: pt-br
+---
+
+```lua
+-- Dois hífens começam um comentário de uma linha.
+
+--[[
+ Adicionar dois [ ] (colchetes) criam um comentário
+ de múltiplas linhas.
+--]]
+
+----------------------------------------------------
+-- 1. Variáveis e fluxo de controle.
+----------------------------------------------------
+
+num = 42 -- Todos os números são doubles.
+-- Não se preocupe, doubles de 64-bits contém 52 bits para
+-- armazenar corretamente valores int; a precisão da máquina
+-- não é um problema para ints que são < 52 bits.
+
+s = 'alternados' -- String são imutáveis, como em Python.
+t = "Aspas duplas também são válidas"
+u = [[ Dois colchetes
+ começam e terminam
+ strings de múltiplas linhas.]]
+t = nil -- Torna t undefined(indefinido); Lua tem um Garbage Collector.
+
+-- Blocos são representados com palavras do/end:
+while num < 50 do
+ num = num + 1 -- Sem operadores do tipo ++ ou +=
+end
+
+--Cláusula If :
+if num > 40 then
+ print('over 40')
+elseif s ~= 'walternate' then -- ~= signfica não é igual.
+ -- Para fazer checagem use == como em Python; Funciona para comparar strings também.
+ io.write('not over 40\n') -- Padrão para saídas.
+else
+ -- Variáveis são globais por padrão.
+ thisIsGlobal = 5 -- Camel case é o comum.
+
+ -- Como fazer variáveis locais:
+ local line = io.read() -- Leia a proxima linha de entrada.
+
+ -- Para concatenação de strings use o operador .. :
+ print('Winter is coming, ' .. line)
+end
+
+-- Variáveis indefinidas são do tipo nil.
+-- Isso não é um erro:
+foo = anUnknownVariable -- Agora foo = nil.
+
+aBoolValue = false
+
+-- Apenas nil e false são do tipo falso; 0 e '' são verdadeiros!
+if not aBoolValue then print('twas false') end
+
+-- 'or' e 'and' são operadores lógicos.
+-- Esse operador em C/JS a?b:c , em lua seria o mesmo que:
+ans = aBoolValue and 'yes' or 'no' --> 'no'
+
+karlSum = 0
+for i = 1, 100 do -- O intervalo inclui inicio e fim.
+ karlSum = karlSum + i
+end
+
+-- Use "100, 1, -1" para um intervalo que diminui:
+fredSum = 0
+for j = 100, 1, -1 do fredSum = fredSum + j end
+
+-- Em geral, o intervalo é começo, fim[, etapas].
+
+-- Outro construtor de loop:
+repeat
+ print('A estrada do futuro.')
+ num = num - 1
+until num == 0
+
+
+----------------------------------------------------
+-- 2. Funções.
+----------------------------------------------------
+
+function fib(n)
+ if n < 2 then return 1 end
+ return fib(n - 2) + fib(n - 1)
+end
+
+-- Closures e Funções anônimas são permitidas:
+function adder(x)
+ -- O retorno da função é criado quando adder é
+ -- chamado, e ele sabe o valor de x:
+ return function (y) return x + y end
+end
+a1 = adder(9)
+a2 = adder(36)
+print(a1(16)) --> 25
+print(a2(64)) --> 100
+
+-- Retornos, chamadas de funções e atribuições, todos eles trabalham
+-- com listas que podem ter tamanhos incompatíveis.
+-- Receptores incompatpiveis serão nil;
+-- Destinos incompatíveis serão descartados.
+
+x, y, z = 1, 2, 3, 4
+-- Agora x = 1, y = 2, z = 3, e 4 é jogado fora.
+
+function bar(a, b, c)
+ print(a, b, c)
+ return 4, 8, 15, 16, 23, 42
+end
+
+x, y = bar('zaphod') --> imprime "zaphod nil nil"
+-- Agora x = 4, y = 8, os valores 15...42 foram descartados.
+
+-- Funções são de primeira-classe, portanto podem ser local/global.
+-- Estes exemplos são equivalentes:
+function f(x) return x * x end
+f = function (x) return x * x end
+
+-- Logo, estes são equivalentes também:
+local function g(x) return math.sin(x) end
+local g; g = function (x) return math.sin(x) end
+-- 'local g' essa declaração de auto-referência é válida.
+
+-- A propósito, as funções de trigonometria trabalham em radianos.
+
+-- Chamadas de função com apenas um parâmetro de string não precisam de parênteses:
+print 'hello' -- Funciona perfeitamente.
+
+
+----------------------------------------------------
+-- 3. Tabelas.
+----------------------------------------------------
+
+-- Tabelas = A unica estrutura de dados composta em Lua;
+-- elas são matrizes associativas.
+-- Semelhantes aos arrays de PHP ou objetos de javascript, eles são:
+-- hash-lookup(chave:valor) que também podem ser usados como listas.
+
+-- Usando tabelas como dicionário / mapas:
+
+-- Dicionários literais tem strings como chaves por padrão:
+t = {key1 = 'value1', key2 = false}
+
+-- As chaves do tipo string podem usar notação de ponto,semelhante a javascript:
+print(t.key1) -- Imprime 'value1'.
+t.newKey = {} -- Adiciona um novo par chave/valor.
+t.key2 = nil -- Remove key2 da tabela.
+
+-- Qualquer notação literal (não-nulo) pode ser uma chave:
+u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
+print(u[6.28]) -- imprime "tau"
+
+-- A correspondência de chave é basicamente o valor para números
+-- e strings, mas por identidade para tabelas.
+a = u['@!#'] -- Agora a = 'qbert'.
+b = u[{}] -- Nós esperavamso o resultado 1729, mas ele é nil:
+-- b = nil já que a busca falha. Ela falha
+-- porque a chave que usamos não é a mesma que o objeto
+-- como aquele que usamos para guardar o valor original. Por isso
+-- strings & numeros são chaves mais recomendadas.
+
+-- Uma chamada de função de apenas um paramêtro de tabela, não precisa de parênteses:
+
+function h(x) print(x.key1) end
+h{key1 = 'Sonmi~451'} -- Imprime 'Sonmi~451'.
+
+for key, val in pairs(u) do -- Iteração de tabela.
+ print(key, val)
+end
+
+-- _G é uma tabela especial que guarda tudo que é global.
+print(_G['_G'] == _G) -- Imprime 'true'.
+
+-- Usando tabelas como listas / arrays:
+
+-- Listas literais com chaves int implícitas:
+v = {'value1', 'value2', 1.21, 'gigawatts'}
+for i = 1, #v do -- #v é o tamanho de v
+ print(v[i]) -- Índices começam em 1 !! MUITO LOCO!
+end
+-- Uma 'list' não é um tipo real. v é apenas uma tabela
+-- com chaves int consecutivas, tratando ela como uma lista.
+
+----------------------------------------------------
+-- 3.1 Metatabelas e metamétodos.
+----------------------------------------------------
+
+-- Uma tabela pode ter uma metatabela que fornece à tabela
+-- um compotamento de sobrecarga de operador. Depois veremos
+-- como metatabelas suportam o comportamento do Javascript-prototype.
+
+f1 = {a = 1, b = 2} -- Representa uma fração de a/b.
+f2 = {a = 2, b = 3}
+
+-- Isso falharia:
+-- s = f1 + f2
+
+metafraction = {}
+function metafraction.__add(f1, f2)
+ sum = {}
+ sum.b = f1.b * f2.b
+ sum.a = f1.a * f2.b + f2.a * f1.b
+ return sum
+end
+
+setmetatable(f1, metafraction)
+setmetatable(f2, metafraction)
+
+s = f1 + f2 -- chama __add(f1, f2) na metatabela de f1
+
+-- f1, f2 não tem chave para sua metatabela, ao contrário de
+-- prototypes em javascript, então você deve recuperá-lo com
+-- getmetatable(f1). A metatabela é uma tabela normal
+-- com chaves que Lua reconhece, como __add.
+
+-- Mas a proxima linha irá falhar porque s não tem uma metatabela:
+-- t = s + s
+-- O padrão de Classes abaixo consertam esse problema.
+
+-- Uma __index em uma metatable sobrecarrega pesquisas de ponto:
+defaultFavs = {animal = 'gru', food = 'donuts'}
+myFavs = {food = 'pizza'}
+setmetatable(myFavs, {__index = defaultFavs})
+eatenBy = myFavs.animal -- Funciona! obrigado, metatabela.
+
+-- As pesquisas diretas de tabela que falham tentarão pesquisar novamente usando
+-- o __index da metatabela, e isso é recursivo.
+
+-- Um valor de __index também pode ser uma function(tbl, key)
+-- para pesquisas mais personalizadas.
+
+-- Valores do tipo __index,add, .. são chamados de metamétodos.
+-- Uma lista completa com os metamétodos.
+
+-- __add(a, b) para a + b
+-- __sub(a, b) para a - b
+-- __mul(a, b) para a * b
+-- __div(a, b) para a / b
+-- __mod(a, b) para a % b
+-- __pow(a, b) para a ^ b
+-- __unm(a) para -a
+-- __concat(a, b) para a .. b
+-- __len(a) para #a
+-- __eq(a, b) para a == b
+-- __lt(a, b) para a < b
+-- __le(a, b) para a <= b
+-- __index(a, b) <fn or a table> para a.b
+-- __newindex(a, b, c) para a.b = c
+-- __call(a, ...) para a(...)
+
+----------------------------------------------------
+-- 3.2 Tabelas como Classes e sua herança.
+----------------------------------------------------
+
+-- Classes não são disseminadas; existem maneiras diferentes
+-- para fazer isso usando tabelas e metamétodos...
+
+-- A explicação para este exemplo está logo abaixo.
+
+Dog = {} -- 1.
+
+function Dog:new() -- 2.
+ newObj = {sound = 'woof'} -- 3.
+ self.__index = self -- 4.
+ return setmetatable(newObj, self) -- 5.
+end
+
+function Dog:makeSound() -- 6.
+ print('I say ' .. self.sound)
+end
+
+mrDog = Dog:new() -- 7.
+mrDog:makeSound() -- 'I say woof' -- 8.
+
+-- 1. Dog atua como uma classe; mas na verdade, é uma tabela.
+-- 2. function tablename:fn(...) é a mesma coisa que
+-- function tablename.fn(self, ...)
+-- O : apenas adiciona um primeiro argumento chamado self.
+-- Leia 7 & 8 abaixo para ver como self obtém seu valor.
+-- 3. newObj será uma instância da classe Dog.
+-- 4. self = a classe que que foi instanciada. Regularmente
+-- self = Dog, mas a herança pode mudar isso.
+-- newObj recebe as funções de self como se tivessimos definido em ambos
+-- a metatabela de newObj e self __index para self.
+-- 5. Lembre-se: setmetatable retorna seu primeiro argumento definido.
+-- 6. O : funciona como em 2, mas desta vez esperamos que
+-- self seja uma instância já instanciada da classe.
+-- 7. Igual a Dog.new(Dog), logo self = Dog no new().
+-- 8. Igual a mrDog.makeSound(mrDog); self = mrDog.
+
+----------------------------------------------------
+
+-- Heranças exemplos:
+
+LoudDog = Dog:new() -- 1.
+
+function LoudDog:makeSound()
+ s = self.sound .. ' ' -- 2.
+ print(s .. s .. s)
+end
+
+seymour = LoudDog:new() -- 3.
+seymour:makeSound() -- 'woof woof woof' -- 4.
+
+-- 1. LoudDog recebe os metodos e variáveis de Dog.
+-- 2. self tem uma chave 'sound' vindo de new(), veja o 3.
+-- 3. Mesma coisa que LoudDog.new(LoudDog), convertido para
+-- Dog.new(LoudDog) como LoudDog não tem uma chave 'new',
+-- mas tem uma chave __index = Dog na sua metatabela o
+-- resultado será: a metabela de seymour é a LoudDog, e
+-- LoudDog.__index = LoudDog. Então seymour.key será
+-- = seymour.key, LoudDog.key, Dog.key,seja qual for a primeira
+-- chave fornecida.
+-- 4. A chave 'makeSound' foi encontrada em LoudDog; isto
+-- é a mesma coisa que LoudDog.makeSound(seymour).
+
+-- Se precisar de, uma subclasse de new() como uma base:
+function LoudDog:new()
+ newObj = {}
+ -- define newObj
+ self.__index = self
+ return setmetatable(newObj, self)
+end
+
+----------------------------------------------------
+-- 4. Módulos.
+----------------------------------------------------
+
+
+--[[ Estou comentando esta seção, então o resto
+-- desse script é executável.
+```
+
+```lua
+-- Suponhamos que o arquivo mod.lua se pareça com isso:
+local M = {}
+
+local function sayMyName()
+ print('Hrunkner')
+end
+
+function M.sayHello()
+ print('Why hello there')
+ sayMyName()
+end
+
+return M
+
+-- Outro arquivo pode usar as funcionalidades de mod.lua:
+local mod = require('mod') -- Roda o arquivo mod.lua.
+
+-- require é a forma que usamos para incluir módulos.
+-- require atua como: (se não for cacheado; veja abaixo)
+local mod = (function ()
+ <contents of mod.lua>
+end)()
+-- É como se mod.lua fosse um corpo de uma função, então
+-- os locais dentro de mod.lua são invisíveis fora dele.
+
+-- Isso irá funcionar porque mod aqui = M dentro de mod.lua:
+mod.sayHello() -- Diz olá para Hrunkner.
+
+-- Isso aqui é errado; sayMyName existe apenas em mod.lua:
+mod.sayMyName() -- erro
+
+-- valores retornados de require são armazenados em cache para que um arquivo seja
+-- execute no máximo uma vez, mesmo quando é exigidos várias vezes.
+
+-- Suponhamos que mod2.lua contém "print('Hi!')".
+local a = require('mod2') -- Imprime Hi!
+local b = require('mod2') -- Não imprime;pois a=b.
+
+-- dofile é parecido com require, porém sem cacheamento:
+dofile('mod2.lua') --> Hi!
+dofile('mod2.lua') --> Hi! (roda novamente)
+
+-- loadfile carrega um arquivo lua, porém não o executa.
+f = loadfile('mod2.lua') -- Chame f() para executar.
+
+-- loadstring é um loadfile para strings.
+g = loadstring('print(343)') -- Retorna uma função.
+g() -- Imprime 343; nada foi impresso antes disso.
+
+--]]
+
+```
+
+## Referências
+
+Fiquei bastante animado para aprender Lua pois consegui fazer jogos
+com a <a href="http://love2d.org/">Love 2D engine de jogos</a>.
+
+Eu comecei com <a href="http://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/">BlackBulletIV's para programadores LUA</a>.
+Em seguida, eu li a documentação oficial <a href="https://www.lua.org/manual/5.1/pt/index.html#contents">Programando em Lua</a>.
+É assim que se começa.
+
+Pode ser útil conferir <a href="http://lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf">Uma pequena referencia sobre LUA</a> em lua-users.org.
+
+Os principais tópicos não cobertos, são as bibliotecas padrões:
+
+- <a href="http://lua-users.org/wiki/StringLibraryTutorial">Biblioteca de strings</a>
+- <a href="http://lua-users.org/wiki/TableLibraryTutorial">Biblioteca de tabelas</a>
+- <a href="http://lua-users.org/wiki/MathLibraryTutorial">Biblioteca de matemática</a>
+- <a href="http://lua-users.org/wiki/IoLibraryTutorial">Biblioteca de entrada/saída</a>
+- <a href="http://lua-users.org/wiki/OsLibraryTutorial">Biblioteca do sistema operacional</a>
+
+A propósito, todo este arquivo é um código LUA válido, salve-o como
+aprenda.lua e rode-o com "lua aprenda.lua" !
+
+Este guia foi escrito pela primeira vez por tylerneylon.com, e agora
+também disponível em <a href="https://gist.github.com/tylerneylon/5853042">github gist</a>. E também em português.
+
+Se divirta com lua
diff --git a/pt-br/make-pt.html.markdown b/pt-br/make-pt.html.markdown
new file mode 100644
index 00000000..cbdebde7
--- /dev/null
+++ b/pt-br/make-pt.html.markdown
@@ -0,0 +1,243 @@
+---
+category: tool
+tool: make
+contributors:
+ - ["Robert Steed", "https://github.com/robochat"]
+ - ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
+filename: Makefile
+
+lang: pt-br
+---
+
+Um Makefile define um gráfico de regras para criar um alvo (ou alvos). Sua finalidade é fazer o mínimo de trabalho necessário para atualizar um alvo para a versão mais recente da fonte. Famosamente escrito ao longo de um fim de semana por Stuart Feldman em 1976, ainda é amplamente usada (particularmente no Unix e no Linux) apesar de muitos concorrentes e críticas.
+
+Existem muitas variedades de make na existência, no entanto, este artigo pressupõe que estamos usando o GNU make, que é o padrão no Linux.
+
+```make
+
+# Comentários podem ser escritos assim.
+
+# O arquivo deve ser nomeado Makefile e então pode ser executado como `make <alvo>`.
+# Caso contrário, nós usamos `make -f "nome-do-arquivo" <alvo>`.
+
+# Aviso - use somente TABS para identar em Makefiles, nunca espaços!
+
+#-----------------------------------------------------------------------
+# Noções básicas
+#-----------------------------------------------------------------------
+
+# Regras são do formato
+# alvo: <pré-requisito>
+# onde os pré-requisitos são opcionais.
+
+# Uma regra - esta regra só será executada se o arquivo0.txt não existir.
+arquivo0.txt:
+ echo "foo" > arquivo0.txt
+ # Mesmo os comentários nestas seções da 'receita' são passados ​​para o shell.
+ # Experimentar `make arquivo0.txt` or simplyou simplesmente `make` - primeira regra é o padrão.
+
+# Esta regra só será executada se arquivo0.txt for mais recente que arquivo1.txt.
+arquivo1.txt: arquivo0.txt
+ cat arquivo0.txt > arquivo1.txt
+ # se as mesmas regras de citação do shell.
+ @cat arquivo0.txt >> arquivo1.txt
+ # @ pára o comando de ser ecoado para stdout.
+ -@echo 'hello'
+ # - significa que make continuará em caso de erro.
+ # Experimentar `make arquivo1.txt` na linha de comando.
+
+# Uma regra pode ter vários alvos e vários pré-requisitos
+arquivo2.txt arquivo3.txt: arquivo0.txt arquivo1.txt
+ touch arquivo2.txt
+ touch arquivo3.txt
+
+# Make vai reclamar sobre várias receitas para a mesma regra. Esvaziar
+# receitas não contam e podem ser usadas para adicionar novas dependências.
+
+#-----------------------------------------------------------------------
+# Alvos falsos
+#-----------------------------------------------------------------------
+
+# Um alvo falso. Qualquer alvo que não seja um arquivo.
+# Ele nunca será atualizado, portanto, o make sempre tentará executá-lo.
+all: maker process
+
+# Podemos declarar as coisas fora de ordem.
+maker:
+ touch ex0.txt ex1.txt
+
+# Pode evitar quebrar regras falsas quando um arquivo real tem o mesmo nome
+.PHONY: all maker process
+# Este é um alvo especial. Existem vários outros.
+
+# Uma regra com dependência de um alvo falso sempre será executada
+ex0.txt ex1.txt: maker
+
+# Alvos falsos comuns são: todos fazem instalação limpa ...
+
+#-----------------------------------------------------------------------
+# Variáveis ​​Automáticas e Curingas
+#-----------------------------------------------------------------------
+
+process: Arquivo*.txt # Usando um curinga para corresponder nomes de arquivos
+ @echo $^ # $^ é uma variável que contém a lista de pré-requisitos
+ @echo $@ # imprime o nome do alvo
+ #(fpara várias regras alvo, $@ é o que causou a execução da regra)
+ @echo $< # o primeiro pré-requisito listado
+ @echo $? # somente as dependências que estão desatualizadas
+ @echo $+ # todas as dependências, incluindo duplicadas (ao contrário do normal)
+ #@echo $| # todos os pré-requisitos 'somente pedidos'
+
+# Mesmo se dividirmos as definições de dependência de regra, $^ vai encontrá-los
+process: ex1.txt arquivo0.txt
+# ex1.txt será encontrado, mas arquivo0.txt será desduplicado.
+
+#-----------------------------------------------------------------------
+# Padrões
+#-----------------------------------------------------------------------
+
+# Pode ensinar make a converter certos arquivos em outros arquivos.
+
+%.png: %.svg
+ inkscape --export-png $^
+
+# As regras padrões só farão qualquer coisa se decidirem criar o alvo.
+
+# Os caminhos de diretório são normalmente ignorados quando as regras de
+# padrões são correspondentes. Mas make tentará usar a regra mais
+# apropriada disponível.
+small/%.png: %.svg
+ inkscape --export-png --export-dpi 30 $^
+
+# make utilizará a última versão para uma regra de padrão que encontrar.
+%.png: %.svg
+ @echo esta regra é escolhida
+
+# No entanto, o make usará a primeira regra padrão que pode se tornar o alvo
+%.png: %.ps
+ @echo esta regra não é escolhida se *.svg and *.ps estão ambos presentes
+
+# make já tem algumas regras padrões embutidas. Por exemplo, ele sabe
+# como transformar arquivos *.c em arquivos *.o.
+
+# Makefiles antigos podem usar regras de sufixo em vez de regras padrões
+.png.ps:
+ @echo essa regra é semelhante a uma regra de padrão.
+
+# make sobre a regra de sufixo
+.SUFFIXES: .png
+
+#-----------------------------------------------------------------------
+# Variáveis
+#-----------------------------------------------------------------------
+# aka. macros
+
+# As variáveis ​​são basicamente todos os tipos de string
+
+name = Ted
+name2="Sarah"
+
+echo:
+ @echo $(name)
+ @echo ${name2}
+ @echo $name # Isso não funcionará, tratado como $ (n)ame.
+ @echo $(name3) # Variáveis ​​desconhecidas são tratadas como strings vazias.
+
+# Existem 4 lugares para definir variáveis.
+# Em ordem de prioridade, do maior para o menor:
+# 1: argumentos de linha de comando
+# 2: Makefile
+# 3: variáveis ​​de ambiente do shell - faça importações automaticamente.
+# 4: make tem algumas variáveis ​​predefinidas
+
+name4 ?= Jean
+# Somente defina a variável se a variável de ambiente ainda não estiver definida.
+
+override name5 = David
+# Pára os argumentos da linha de comando de alterar essa variável.
+
+name4 +=grey
+# Anexar valores à variável (inclui um espaço).
+
+# Valores variáveis ​​específicos de padrões (extensão GNU).
+echo: name2 = Sara # Verdadeiro dentro da regra de correspondência
+ # e também dentro de suas recursivas dependências
+ # (exceto que ele pode quebrar quando seu gráfico ficar muito complicado!)
+
+# Algumas variáveis ​​definidas automaticamente pelo make
+echo_inbuilt:
+ echo $(CC)
+ echo ${CXX}
+ echo $(FC)
+ echo ${CFLAGS}
+ echo $(CPPFLAGS)
+ echo ${CXXFLAGS}
+ echo $(LDFLAGS)
+ echo ${LDLIBS}
+
+#-----------------------------------------------------------------------
+# Variáveis 2
+#-----------------------------------------------------------------------
+
+# O primeiro tipo de variáveis ​​é avaliado a cada vez que elas são usadas.
+# TIsso pode ser caro, então existe um segundo tipo de variável que é
+# avaliado apenas uma vez. (Esta é uma extensão do GNU make)
+
+var := hello
+var2 ::= $(var) hello
+#:= e ::= são equivalentes.
+
+# Essas variáveis ​​são avaliadas procedimentalmente (na ordem em que
+# aparecem), quebrando assim o resto da línguagem!
+
+# Isso não funciona
+var3 ::= $(var4) and good luck
+var4 ::= good night
+
+#-----------------------------------------------------------------------
+# Funções
+#-----------------------------------------------------------------------
+
+# make tem muitas funções disponíveis.
+
+sourcefiles = $(wildcard *.c */*.c)
+objectfiles = $(patsubst %.c,%.o,$(sourcefiles))
+
+# O formato é $(func arg0,arg1,arg2...)
+
+# Alguns exemplos
+ls: * src/*
+ @echo $(filter %.txt, $^)
+ @echo $(notdir $^)
+ @echo $(join $(dir $^),$(notdir $^))
+
+#-----------------------------------------------------------------------
+# Diretivas
+#-----------------------------------------------------------------------
+
+# Inclua outros makefiles, úteis para código específico da plataforma
+include foo.mk
+
+sport = tennis
+# Compilação condicional
+report:
+ifeq ($(sport),tennis)
+ @echo 'game, set, match'
+else
+ @echo "They think it's all over; it is now"
+endif
+
+# Há também ifneq, ifdef, ifndef
+
+foo = true
+
+ifdef $(foo)
+bar = 'hello'
+endif
+```
+
+### More Resources
+
++ [documentação gnu make](https://www.gnu.org/software/make/manual/)
++ [tutorial de carpintaria de software](http://swcarpentry.github.io/make-novice/)
++ aprenda C da maneira mais difícil [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html)
diff --git a/pt-br/markdown-pt.html.markdown b/pt-br/markdown-pt.html.markdown
index f22093f9..dc50cac1 100644
--- a/pt-br/markdown-pt.html.markdown
+++ b/pt-br/markdown-pt.html.markdown
@@ -4,6 +4,9 @@ contributors:
- ["Dan Turkel", "http://danturkel.com/"]
translators:
- ["Miguel Araújo", "https://github.com/miguelarauj1o"]
+ - ["Gabriele Luz", "https://github.com/gabrieleluz"]
+ - ["Monique Baptista", "https://github.com/bfmonique"]
+
lang: pt-br
filename: learnmarkdown-pt.md
---
@@ -11,40 +14,50 @@ filename: learnmarkdown-pt.md
Markdown foi criado por John Gruber in 2004. Originado para ser fácil de ler e
escrever sintaxe que converte facilmente em HTML (hoje, suporta outros formatos também).
-Dê-me feedback tanto quanto você quiser! / Sinta-se livre para a garfar (fork) e
+Dê-me feedback tanto quanto você quiser! / Sinta-se livre para fazer uma bifurcação (fork) e
puxar o projeto (pull request)
-```markdown
-<!-- Markdown é um superconjunto do HTML, de modo que qualquer arvquivo HTML é
-um arquivo Markdown válido, isso significa que nós podemos usar elementos HTML
+## Elementos HTML
+Markdown é um superconjunto do HTML, de modo que qualquer arvquivo HTML é
+um arquivo Markdown válido.
+```md
+<!-- Markdown é um superconjunto do HTML, de modo que qualquer arquivo HTML é
+um arquivo Markdown válido. Isso significa que nós podemos usar elementos HTML
em Markdown, como o elemento de comentário, e eles não serão afetados pelo analisador
de remarcação. No entanto, se você criar um elemento HTML em seu arquivo Markdown, você
-não pode usar sintaxe remarcação dentro desse conteúdo do elemento.-->
+não pode usar sintaxe de remarcação dentro desse conteúdo do elemento.-->
+
+<!--A maneira como o Markdown é analisado varia de software para software.
+Este guia vai tentar esclarecer quando as características são universais, ou quando eles são específicos para um determinado interpretador -->
+
-<!--Markdown também varia de implementação de um analisador para uma próxima.
-Este guia vai tentar esclarecer quando as características são universais, ou quando eles são
-específico para um determinado parser -->
+## Cabeçalhos
+
+Você pode criar elementos HTML `<h1>` até `<h6>` facilmente antecedendo o texto
+que deseja estar nesse elemento por um número de hashes (#)
-<!-- Cabeçalhos -->
-<!-- Você pode criar elementos HTML <h1> até <h6> facilmente antecedendo o texto
-que deseja estar nesse elemento por um número de hashes (#) -->
# Isto é um cabeçalho <h1>
## Isto é um cabeçalho <h2>
### Isto é um cabeçalho <h3>
#### Isto é um cabeçalho <h4>
##### Isto é um cabeçalho <h5>
###### Isto é um cabeçalho <h6>
+```
+
+Markdown também nos fornece duas maneiras alternativas de indicar h1 e h2
-<!-- Markdown também nos fornece duas maneiras alternativas de indicar h1 e h2 -->
+```md
Isto é um cabeçalho h1
======================
Isto é um cabeçalho h2
----------------------
+```
-<!-- Estilos de texto simples -->
-<!-- O texto pode ser facilmente denominado como remarcação itálico, negrito ou tachado usando -->
+## Estilos de texto simples
+O texto pode ser facilmente denominado como marcação itálico, negrito ou tachado usando:
+```md
*Este texto está em itálico*
_E este também está._
@@ -54,43 +67,55 @@ __E este também está._
***Este texto está em negrito e itálico.***
**_E este também está_**
*--Danouse! Este também__*
+```
-<!-- Em GitHub Flavored Markdown, que é usado para processar arquivos Markdown
-GitHub, nós também temos: -->
+Em GitHub Flavored Markdown, que é usado para processar arquivos Markdown
+GitHub, nós também temos:
+```md
~~Este texto é processado com tachado.~~
+```
-<!-- Os parágrafos estão uma ou várias linhas adjacentes de texto separadas por
-uma ou múltiplas linhas em branco. -->
+## Parágrafos
+Os parágrafos estão uma ou várias linhas adjacentes de texto separadas por
+uma ou múltiplas linhas em branco.
+```md
Este é um parágrafo. Eu estou digitando em um parágrafo, não é legal?
-Agora, eu estou no parágrado 2.
+Agora, eu estou no parágrafo 2.
... Ainda continuo no parágrafo 2! :)
Eu estou no parágrafo três.
+```
-<!-- Se você quiser inserir uma tag HTML <br />, você pode acabar com um parágrafo
-com dois ou mais espaços e, em seguida, começar um novo parágrafo -->
+Se você quiser inserir uma tag HTML `<br />`, você pode acabar com um parágrafo
+com dois ou mais espaços e, em seguida, começar um novo parágrafo
+```md
Termino com dois espaços (destacar-me para vê-los).
Há um <br /> acima de mim!
+```
-<!-- Bloco de citações são fáceis e feito com o caractere >. -->
+Bloco de citações são fáceis e feito com o caractere >.
+
+```md
> Este é um bloco de citação. Você pode
-> Enrolar manualmente suas linhas e colocar um `>` antes de cada linha ou você pode
-> deixar suas linhas ficarem muito longas e enrolar por conta própria. Não faz diferença,
+> Quebrar manualmente suas linhas e colocar um `>` antes de cada linha ou você pode
+> deixar suas linhas ficarem muito longas e quebrarem por conta própria. Não faz diferença,
> desde que eles começam com um `>`.
+
> Você também pode usar mais de um nível
->> De recuo?
-> Como pura é isso?
+>> De recuo?
+```
-<!-- Listas -->
-<!-- As listas não ordenadas podem ser feitas usando asteriscos, positivos ou hífens -->
+## Listas
+As listas não ordenadas podem ser feitas usando asteriscos, positivos ou hífens
+```md
* Item
* Item
* Outro item
@@ -106,146 +131,202 @@ ou
- Item
- Item
- Um último item
+```
-<!-- Listas ordenadas são feitas com um número seguido por um ponto -->
+Listas ordenadas são feitas com um número seguido por um ponto.
+```md
1. Item um
2. Item dois
-3. Tem três
+3. Item três
+```
-<!-- Você não tem poder para rotular os itens corretamente e a remarcação será ainda
-tornar os números em ordem, mas isso pode não ser uma boa idéia -->
+<!-- Você não tem poder para rotular os itens corretamente e a remarcação ainda deixará os
+itens em ordem, mas isso pode não ser uma boa idéia -->
+
+```md
1. Item um
1. Item dois
1. Item três
-<!-- (Isto é processado da mesma forma que o exemplo acima) -->
+```
+(Isto é processado da mesma forma que o exemplo acima)
-<!-- Você também pode usar subtítulos -->
+Você também pode usar sublistas
+```md
1. Item um
2. Item dois
3. Item três
* Sub-item
* Sub-item
4. Item quatro
+```
-<!-- blocos de código -->
-<!-- Você pode indicar um bloco de código (que utiliza o elemento <code>) pelo recuo
-uma linha com quatro espaços ou uma guia -->
+Existem também listas de tarefas. Isso cria checkboxes (caixas de seleção) de HTML
+```md
+As caixas abaixo sem o 'x' são checkboxes HTML desmarcadas
+- [ ] Primeira tarefa a completar
+- [ ] Segunda tarefa a completar
+A caixa de seleção abaixo será exibida como uma checkbox HTML marcada
+- [x] Essa tarefa foi completa
+
+```
+
+
+## Blocos de código
+Você pode indicar um bloco de código (que utiliza o elemento `<code>`) pelo recuo
+uma linha com quatro espaços ou uma guia
+```md
Isto é código
É assim, sacou?
+
+```
-<!-- Você pode também re-guia (ou adicionar mais quatro espaços adicionais) para o recuo
-dentro do seu código -->
+Você pode também re-guia (ou adicionar mais quatro espaços adicionais) para o recuo
+dentro do seu código
+```md
my_array.each do |item|
puts item
end
+ ```
-<!-- Código embutido pode ser criada usando o caractere de crase ` -->
+Código embutido pode ser criada usando o caractere de crase `` ` ``
-John não sabia nem o que o função 'goto()' fazia!
-
-<!-- Em GitHub Flavored Markdown, você pode usar uma sintaxe especial para o código -->
+```md
+John não sabia nem o que o função `goto()` fazia!
+```
+Em GitHub Flavored Markdown, você pode usar uma sintaxe especial para o código
+```md
+ ``` ruby
+ def foobar
+ puts "Hello world!"
+ end
+ ```
+```
+=======
\`\`\`ruby <!-- exceto remover essas barras invertidas quando você faz isso, apenas ```
ruby! -->
def foobar
puts "Hello world!"
end
-\`\`\` <!-- Aqui também, não barras invertidas, apenas ``` -->
+\`\`\` <!-- Aqui também, não use barras invertidas, apenas ``` -->
-<-- O texto acima não requer recuo, mas o GitHub vai usar a sintaxe
-destacando do idioma que você especificar após a ``` -->
+O texto acima não requer recuo, além disso o GitHub vai usar a sintaxe highlight da linguagem que você especificar após a \`\`\`.
-<!-- Regra Horizontal (<hr />) -->
-<!-- Regras horizontais são facilmente adicionados com três ou mais asteriscos ou hífens,
-com ou sem espaços. -->
+## Linha Horizontal
+Linhas horizontais são facilmente adicionados com três ou mais asteriscos ou hífens,
+com ou sem espaços.
+```md
***
---
- - -
****************
+```
-<!-- Links -->
-<!-- Uma das melhores coisas sobre a remarcação é o quão fácil é fazer ligações. Colocar
-o texto a ser exibido entre parênteses rígidos [] seguido pela url em parênteses () -->
+## Links
+Uma das melhores coisas sobre a marcação é o quão fácil é fazer ligações. Colocar
+o texto a ser exibido entre parênteses rígidos [] seguido pela url em parênteses ()
+```md
[Click aqui!](http://test.com/)
+```
-<!-- Você também pode adicionar um título link usando aspas dentro dos parênteses -->
+Você também pode adicionar um título link usando aspas dentro dos parênteses
+```md
[Click aqui!](http://test.com/ "Link para Test.com")
+```
-<!-- Caminhos relativos funcionam também. -->
+Caminhos relativos funcionam também.
+```md
[Ir para música](/música/).
+```
-<!-- Markdown também suporta ligações de estilo de referência -->
+Markdown também suporta ligações de estilo de referência
+```md
[Clique neste link] [link1] para mais informações sobre isso!
[Além disso, verifique este link] [foobar] se você quiser.
[link1]: http://test.com/ "Legal!"
[foobar]: http://foobar.biz/ "OK!"
+```
-<!-- O título também pode estar entre aspas simples ou entre parênteses, ou omitido
+O título também pode estar entre aspas simples ou entre parênteses, ou omitido
inteiramente. As referências podem estar em qualquer lugar no documento e os IDs de referência
-pode ser qualquer um, desde que eles são únicos. -->
+pode ser qualquer um, desde que eles são únicos.
-<!-- Existe também o "nomear implícita", que permite que você use o texto do link como o id -->
+Existe também a "nomeação implicita", que permite que você use o texto do link como o id
+```md
[Este] [] é um link.
[este]: http://thisisalink.com/
+```
-<!-- Mas não são usados normalmente-->
+Mas não são usados normalmente
-<!-- Imagens -->
-<!-- As imagens são feitas da mesma forma que as ligações, mas com um ponto de exclamação na frente! -->
+## Imagens
+As imagens são feitas da mesma forma que as ligações, mas com um ponto de exclamação na frente!
+```md
![Este é pairar-texto (texto alternativo) para minha imagem](http://imgur.com/myimage.jpg "Um título opcional")
+```
-<!-- E estilo de referência funciona como esperado -->
+E estilo de referência funciona como esperado
+```md
![Este é o pairar-texto.][Myimage]
[myimage]: relative/urls/legal/image.jpg "se você precisa de um título, é aqui"
+```
-<!-- Miscelânea -->
-<!-- Auto-links -->
+## Miscelânea
+### Auto-links
+```md
<http://testwebsite.com/> é equivalente a
[http://testwebsite.com/](http://testwebsite.com/)
+```
-<!-- Auto-links para e-mails -->
+### Auto-links para e-mails
+```md
<foo@bar.com>
+```
-<!-- Escapando caracteres -->
+### Escapando caracteres
Quero digitar * Este texto entre asteriscos *, mas eu não quero que ele seja
em itálico, então eu faço o seguinte: \*Este texto entre asteriscos \*.
-<!-- Tabelas -->
-<!-- Tabelas estão disponíveis apenas no GitHub Flavored Markdown e são ligeiramente
-complicadas, mas se você realmente quer: -->
+### Tabelas
+Tabelas estão disponíveis apenas no GitHub Flavored Markdown e são ligeiramente
+complicadas, mas se você realmente quer:
+```md
| Col1 | Col2 | Col3 |
| :----------- | :------: | ------------: |
| esquerda-alin| Centrado | direita-alinh |
| blah | blah | blah |
+```
-<!-- Ou, para os mesmos resultados -->
+Ou, para os mesmos resultados
+```md
Col 1 | Col2 | Col3
:-- | :-: | --:
Ugh isso é tão feio | faça isto | parar
+```
-<!-- O fim! -->
+Fim!
-```
+---
Para mais informações, confira o post oficial de John Gruber de sintaxe [aqui](http://daringfireball.net/projects/markdown/syntax)
e de Adam Pritchard grande cheatsheet [aqui](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).
diff --git a/pt-br/matlab-pt.html.markdown b/pt-br/matlab-pt.html.markdown
index eb660d4c..fae17bca 100644
--- a/pt-br/matlab-pt.html.markdown
+++ b/pt-br/matlab-pt.html.markdown
@@ -206,8 +206,7 @@ size(A) % Resposta = 3 3
A(1, :) =[] % Remove a primeira linha da matriz
A(:, 1) =[] % Remove a primeira coluna da matriz
-transpose(A) % Transposta a matriz, que é o mesmo de:
-A one
+transpose(A) % Transposta a matriz, que é o mesmo de: A.'
ctranspose(A) % Transposta a matriz
% (a transposta, seguida pelo conjugado complexo de cada elemento)
@@ -357,7 +356,7 @@ disp(a) % Imprime o valor da variável a
disp('Olá Mundo') % Imprime a string
fprintf % Imprime na janela de comandos com mais controle
-% Estruturas Condicionais (os parênteses são opicionais, porém uma boa prática)
+% Estruturas Condicionais (os parênteses são opcionais, porém uma boa prática)
if (a > 15)
disp('Maior que 15')
elseif (a == 23)
diff --git a/pt-br/paren-pt.html.markdown b/pt-br/paren-pt.html.markdown
index 464a69d2..92414ba3 100644
--- a/pt-br/paren-pt.html.markdown
+++ b/pt-br/paren-pt.html.markdown
@@ -182,8 +182,8 @@ a ; => (3 2)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Macros lhe permitem estender a sintaxe da linguagem.
-;; Os macros no Paren são fáceis.
-;; Na verdade, (defn) é um macro.
+;; As macros no Paren são fáceis.
+;; Na verdade, (defn) é uma macro.
(defmacro setfn (nome ...) (set nome (fn ...)))
(defmacro defn (nome ...) (def nome (fn ...)))
@@ -191,6 +191,6 @@ a ; => (3 2)
(defmacro infix (a op ...) (op a ...))
(infix 1 + 2 (infix 3 * 4)) ; => 15
-;; Macros não são higiênicos, você pode sobrescrever as variáveis já existentes!
-;; Eles são transformações de códigos.
+;; Macros não são higiênicas, você pode sobrescrever as variáveis já existentes!
+;; Elas são transformações de códigos.
```
diff --git a/pt-br/pascal-pt.html.markdown b/pt-br/pascal-pt.html.markdown
new file mode 100644
index 00000000..72302695
--- /dev/null
+++ b/pt-br/pascal-pt.html.markdown
@@ -0,0 +1,254 @@
+---
+language: Pascal
+filename: learnpascal-pt.pas
+contributors:
+ - ["Ganesha Danu", "https://github.com/blinfoldking"]
+ - ["Keith Miyake", "https//github.com/kaymmm"]
+ - ["Raul Almeida", "https://github.com/almeidaraul"]
+translators:
+ - ["Raul Almeida", "https://github.com/almeidaraul"]
+lang: pt-br
+---
+
+
+>Pascal é uma linguagem de programação estruturada, que recebeu este nome em homenagem ao matemático e físico Blaise Pascal. Foi criada em 1970 pelo suíço Niklaus Wirth,tendo em mente encorajar o uso de código estruturado.
+fonte : [wikipédia](https://pt.wikipedia.org/wiki/Pascal_(linguagem_de_programa%C3%A7%C3%A3o))
+
+
+
+Para compilar e executar um programa em Pascal, você pode usar o freepascal,
+um compilador gratuito. [Faça o download aqui](https://www.freepascal.org/)
+
+```pascal
+//Corpo de um programa em Pascal
+//isso é um comentário
+{
+ isso também é um comentário,
+ mas com várias linhas
+}
+
+//cabeçalho do programa
+PROGRAM aprendendo_pascal; //<-- não esqueça o ponto e vírgula. O nome do
+programa deve começar com uma letra.
+
+CONST
+ {
+ aqui você declara valores constantes
+ }
+TYPE
+ {
+ aqui você declara tipos não nativos
+ }
+VAR
+ {
+ aqui você declara variáveis
+ }
+
+//programa de fato
+BEGIN
+ 80
+ aqui ficam todas as instruções que não pertencem nem a funções
+ nem a procedimentos
+
+ blocos de código começam com BEGIN e terminam com END
+ (como as chaves em C)
+ }
+END. //o "end" no final do programa requer um ponto final.
+```
+
+```pascal
+//formas de declarar uma variável
+VAR a:INTEGER;
+VAR b:INTEGER;
+
+VAR
+ a : INTEGER;
+ b : INTEGER;
+
+VAR a,b : INTEGER;
+```
+
+```pascal
+PROGRAM Learn_More;
+//agora, mais sobre tipos de dados e operações
+
+CONST
+ PI = 3.141592654;
+ GNU = 'GNU''s Not Unix';
+ { a convenção é usar caixa alta para constantes
+
+ constantes têm valores fixos que só podem ser alterados
+ antes da compilação
+
+ constantes podem ser de qualquer tipo nativo (integer, real, boolean,
+ char, string)
+
+TYPE
+ vet_char : array [0..255] of CHAR;
+ // isso declara um novo tipo de variável, vet_char, com 256 caracteres
+ vet_multd : array of array of INTEGER;
+ // vetores de vetores são vetores multidimensionais
+ // use vetores de tamanho 0 (daí, usa-se alocação dinâmica)
+ // vetores do tipo vet_multd são de duas dimensões
+
+//declarando variáveis
+VAR
+ int, c, d : INTEGER;
+ // três variáveis que guardam valores inteiros
+ // inteiros têm 16 bits (vão de -32768 a 32767)
+ r : REAL;
+ // uma variável que guarda um valor real
+ // reais vão de 3.4E-38 a 3.4E38
+ bool : BOOLEAN;
+ // uma variável que guarda um valor booleano (verdadeiro ou falso)
+ ch : CHAR;
+ // uma variável que guarda um caractere
+ // caracteres têm 8 bits
+ str : STRING;
+ // STRING não é um tipo padrão, mas vem na maioria dos compiladores
+ // string é um vetor de caracteres com tamanho padrão de 255 elementos
+ s : STRING[50];
+ // especificar o tamanho de uma string assim otimiza o uso de memória
+ my_str: vet_char;
+ // aqui, uma variável de um tipo personalizado declarado acima
+ my_2d : vet_multd;
+ // defina o tamanho de vetores dinâmicos antes de usá-los
+
+// outros tipos de dados (pascal é uma linguagem fortemente tipada)
+
+ // tipos adicionais de inteiros
+ b : BYTE; // faixa [0..255]
+ shi : SHORTINT; // faixa [-128..127]
+ smi : SMALLINT; // faixa [-32,768..32,767] (inteiro padrão)
+ w : WORD; // faixa [0..65,535]
+ li : LONGINT; // faixa [-2,147,483,648..2,147,483,647]
+ lw : LONGWORD; // faixa [0..4,294,967,295]
+ c : CARDINAL; // longword
+ i64 : INT64; // faixa [-9223372036854775808..9223372036854775807]
+ qw : QWORD; // faixa [0..18,446,744,073,709,551,615]
+
+ // tipos adicionais de reais
+ rr : REAL; // faixa depende da plataforma (8 bits, 16 bits, etc)
+ rs : SINGLE; // faixa [1.5E-45..3.4E38]
+ rd : DOUBLE; // faixa [5.0E-324 .. 1.7E308]
+ re : EXTENDED; // faixa [1.9E-4932..1.1E4932]
+ rc : COMP; // faixa [-2E64+1 .. 2E63-1]
+
+BEGIN
+ int := 1;// usa-se := para atribuir valores a variáveis
+ r := 3.14;
+ ch := 'a';
+ str := 'apple';
+ bool := true;
+ //pascal não é case-sensitive (não diferencia maiúsculas de minúsculas)
+ // uma opção de organização é usar maiúsculas para termos da linguagem
+ // (BEGIN, END, INTEGER, etc) e constantes
+ // aritmética
+ int := 1 + 1; // int deixa de ser 1 e passa a ser 2
+ int := int + 1; // int = 2 + 1 = 3;
+ int := 4 DIV 2; //int = 2 (DIV é uma divisão inteira - ignora o resto)
+ int := 3 DIV 2; //int = 1
+ int := 1 DIV 2; //int = 0
+
+ bool := true OR false; // bool = true
+ bool := false AND true; // bool = false
+ bool := true XOR true; // bool = false
+
+ r := 3 / 2; // usa-se a "/" para divisões entre inteiros
+ r := int; // um real pode receber um valor inteiro (mas não o contrário)
+
+ c := str[1]; //acessando elementos de um vetor: vetor[índice do elemento]
+ str := 'hello' + 'world'; //concatenação de strings
+
+ my_str[0] := 'a'; { só se pode atribuir valores a vetores elemento
+ por elemento (não o vetor inteiro de uma vez) }
+
+ // LAÇOS
+ WHILE (ch != 'a') DO
+ BEGIN
+ writeln('ch é diferente de a');
+ IF (ch = 'c') THEN
+ writeln('ch é igual a c');
+ END;
+
+ SETLENGTH(my_2d,10,10);
+ // inicialização de um vetor com alocação dinâmica; my_2d vira um 10x10
+ FOR c := 0 to 9 DO
+ { vetores começam em 0 e terminam em tamanho-1
+ (exceto se, declarando o tipo, forem especificados valores diferentes) }
+ FOR d := 0 to 9 DO
+ // a variável usada em um laço FOR deve ter sido declarada no cabeçalho
+ my_2d[c,d] := c * d;
+ // acessam-se elementos de vetores multidimensionais com [d1, d2, d3...]
+
+
+END.
+```
+
+```pascal
+PROGRAM programacao_com_funcoes;
+
+VAR
+ i, inutil : INTEGER;
+
+{ OBS: diferença entre procedimento e função
+ função: realiza operações e retorna valor
+ procedimento: só realiza operações
+}
+//declarando e descrevendo uma função
+FUNCTION fatorial_recursiva(CONST a: INTEGER) : INTEGER;
+{ calcula a! recursivamente }
+
+// pode-se declarar variáveis locais para funções e procedimentos
+// exemplo:
+// VAR
+// local_a : INTEGER;
+
+BEGIN
+ { O bloco ELSE só funciona se não houver ponto e vírgula no bloco do IF
+ exemplo:
+ IF a THEN
+ writeln('a');
+ ELSE
+ writeln('b');
+ Isso não permitiria que o programa compilasse }
+
+ IF a >= 1 THEN
+ // o valor de retorno é atribuído como se a função fosse uma variável
+ fatorial_recursiva := a * fatorial_recursiva(a-1)
+ ELSE
+ fatorial_recursiva := 1;
+END; // o END de funções e procedimentos recebe ponto e vírgula
+
+//declarando e descrevendo um procedimento
+PROCEDURE salvainteiro(VAR i : INTEGER; inutil : INTEGER);
+{ recebe entrada do usuário e salva na variável i
+ passagem de valor:
+
+ POR REFERÊNCIA - "VAR i: integer"; implica que alterações na variável i
+ dentro da função são guardadas para o escopo de todo o programa
+
+ POR VALOR - "inutil: integer"; implica que o valor do argumento é copiado
+ e alterações na variável inutil não são guardadas
+}
+
+BEGIN
+ WRITE('Insira um inteiro: '); //escreve sem quebrar linha
+ READLN(i); //lê i com quebra de linha
+ inutil := 4; // inutil não terá seu valor alterado fora do procedimento.
+END;
+
+BEGIN // programa principal
+ inutil := 3;
+ salvainteiro(i, inutil);
+
+ // escrevendo i!
+ WRITELN(i, '! = ', factorial_recursion(i)); // escreve e quebra linha
+ // valores numéricos são automaticamente convertidos para texto na escrita
+
+ // escrever valor de inutil (sempre 3, já que salvainteiro não a altera)
+ WRITELN('inutil = ', inutil);
+END.
+
+```
+
diff --git a/pt-br/perl-pt.html.markdown b/pt-br/perl-pt.html.markdown
index cc07a2ec..55a10626 100644
--- a/pt-br/perl-pt.html.markdown
+++ b/pt-br/perl-pt.html.markdown
@@ -10,9 +10,9 @@ translators:
lang: pt-br
---
-Perl 5 é, uma linguagem de programação altamente capaz, rica em recursos, com mais de 25 anos de desenvolvimento.
+Perl é, uma linguagem de programação altamente capaz, rica em recursos, com mais de 25 anos de desenvolvimento.
-Perl 5 roda em mais de 100 plataformas, de portáteis a mainframes e é adequada tanto para prototipagem rápida, quanto em projetos de desenvolvimento em grande escala.
+Perl roda em mais de 100 plataformas, de portáteis a mainframes e é adequada tanto para prototipagem rápida, quanto em projetos de desenvolvimento em grande escala.
```perl
# Comentários de uma linha começam com um sinal de número.
@@ -21,7 +21,7 @@ Perl 5 roda em mais de 100 plataformas, de portáteis a mainframes e é adequada
# Variáveis iniciam com um sigilo, que é um símbolo que mostra o tipo.
# Um nome de variável válido começa com uma letra ou sublinhado,
-# seguido por qualquer número de letras, números ou sublinhados.
+# seguido por qualquer quantidade de letras, números ou sublinhados.
### Perl has three main variable types: $scalar, @array, e %hash.
@@ -52,10 +52,10 @@ my %fruta_cor = (
banana => "amarelo",
);
-# Scalars, arrays and hashes são documentados mais profundamentes em perldata.
+# Scalars, arrays and hashes são documentados mais profundamente em perldata.
# (perldoc perldata).
-# Mais tipos de dados complexos podem ser construídas utilizando referências,
+# Mais tipos de dados complexos podem ser construídos utilizando referências,
# o que permite que você crie listas e hashes dentro de listas e hashes.
#### Condicionais e construtores de iteração
diff --git a/pt-br/php-pt.html.markdown b/pt-br/php-pt.html.markdown
index 8a1c956e..e55f1100 100644
--- a/pt-br/php-pt.html.markdown
+++ b/pt-br/php-pt.html.markdown
@@ -20,7 +20,7 @@ Este documento descreve PHP 5+.
// Duas barras iniciam o comentário de uma linha.
-# O hash (aka pound symbol) também inicia, mas // é mais comum.
+# O hash (conhecido como "pound symbol") também inicia, mas // é mais comum.
/*
O texto envolto por barra-asterisco e asterisco-barra
diff --git a/pt-br/pyqt-pt.html.markdown b/pt-br/pyqt-pt.html.markdown
new file mode 100644
index 00000000..40fe82d5
--- /dev/null
+++ b/pt-br/pyqt-pt.html.markdown
@@ -0,0 +1,92 @@
+---
+category: tool
+tool: PyQT
+filename: learnpyqt-pt.py
+contributors:
+ - ["Nathan Hughes", "https://github.com/sirsharpest"]
+translators:
+ - ["Lucas Pugliesi", "https://github.com/fplucas"]
+lang: pt-br
+---
+
+**Qt** é amplamente conhecido como um framework para desenvolvimento de
+software multi-plataforma que pode rodar em várias outras plataformas de
+softwares e hardwares com pouca ou nenhuma alteração no código, enquanto mantém
+o poder e a velocidade de uma aplicação nativa. Embora o **Qt** tenha sido
+originalmente escrito em *C++*.
+
+
+Essa é uma adaptação de uma introdução ao QT em C++ por
+[Aleksey Kholovchuk](https://github.com/vortexxx192), alguns dos exemplos de
+código podem resultar na mesma funcionalidade que essa versão, apenas usando
+o pyqt!
+
+```python
+import sys
+from PyQt4 import QtGui
+
+def window():
+ # Cria um objeto para a aplicação
+ app = QtGui.QApplication(sys.argv)
+ # Cria um widget onde o nosso label será inserido
+ w = QtGui.QWidget()
+ # Adiciona um label ao widget
+ b = QtGui.QLabel(w)
+ # Informa algum texto ao label
+ b.setText("Hello World!")
+ # Define os tamanhos e posições dos objetos
+ w.setGeometry(100, 100, 200, 50)
+ b.move(50, 20)
+ # Define o título da janela
+ w.setWindowTitle("PyQt")
+ # Exibe a janela
+ w.show()
+ # Executa tudo o que foi pedido, apenas uma vez
+ sys.exit(app.exec_())
+
+if __name__ == '__main__':
+ window()
+
+```
+
+Para utilizar mais funcionalidades no **pyqt** veremos a construção de alguns
+outros elementos.
+Aqui mostraremos como criar uma janela popup, muito útil para perguntar ao
+usuário qual decisão tomar ou exibir alguma informação.
+
+```Python
+import sys
+from PyQt4.QtGui import *
+from PyQt4.QtCore import *
+
+
+def window():
+ app = QApplication(sys.argv)
+ w = QWidget()
+ # Cria um botão e o anexa ao widget w
+ b = QPushButton(w)
+ b.setText("Press me")
+ b.move(50, 50)
+ # Informa b a chamar essa função quando for clicado
+ # observe que a função chamada não necessita de "()"
+ b.clicked.connect(showdialog)
+ w.setWindowTitle("PyQt Dialog")
+ w.show()
+ sys.exit(app.exec_())
+
+# Essa função deve criar uma janela de diálogo com um botão,
+# aguarda ser clicado e encerra o programa
+def showdialog():
+ d = QDialog()
+ b1 = QPushButton("ok", d)
+ b1.move(50, 50)
+ d.setWindowTitle("Dialog")
+ # Essa modalidade define que o popup deve bloquear as outras janelas quando ativo
+ d.setWindowModality(Qt.ApplicationModal)
+ # Ao ser clicado deve encerrar o processo
+ b1.clicked.connect(sys.exit)
+ d.exec_()
+
+if __name__ == '__main__':
+ window()
+```
diff --git a/pt-br/python-pt.html.markdown b/pt-br/python-pt.html.markdown
index 5afd46d0..3f9c54c1 100644
--- a/pt-br/python-pt.html.markdown
+++ b/pt-br/python-pt.html.markdown
@@ -1,29 +1,36 @@
---
-language: python
+language: Python
contributors:
- - ["Louie Dinh", "http://ldinh.ca"]
+ - ["Louie Dinh", "http://pythonpracticeprojects.com"]
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+ - ["Zachary Ferguson", "http://github.com/zfergus2"]
translators:
- - ["Vilson Vieira", "http://automata.cc"]
+ - ["Paulo Henrique Rodrigues Pinheiro", "http://www.sysincloud.it"]
+ - ["Monique Baptista", "https://github.com/bfmonique"]
lang: pt-br
filename: learnpython-pt.py
---
-Python foi criado por Guido Van Rossum no começo dos anos 90. Atualmente é uma
-das linguagens de programação mais populares. Eu me apaixonei por Python, por
-sua clareza de sintaxe. É basicamente pseudocódigo executável.
+Python foi criada por Guido Van Rossum nos anos 1990. Ela é atualmente uma
+das linguagens mais populares existentes. Eu me apaixonei por
+Python por sua clareza sintática. É praticamente pseudocódigo executável.
-Comentários serão muito apreciados! Você pode me contactar em
-[@louiedinh](http://twitter.com/louiedinh) ou louiedinh [arroba]
-[serviço de email do google]
+Opniões são muito bem vindas. Você pode encontrar-me em
+[@louiedinh](http://twitter.com/louiedinh) ou louiedinh [em]
+[serviço de e-mail do google].
-Nota: Este artigo usa Python 2.7 especificamente, mas deveria ser aplicável a
-qualquer Python 2.x. Logo haverá uma versão abordando Python 3!
+Observação: Este artigo trata de Python 3 especificamente. Verifique
+[aqui](http://learnxinyminutes.com/docs/pt-br/python-pt/) se você pretende
+aprender o velho Python 2.7.
```python
-# Comentários de uma linha começam com cerquilha (ou sustenido)
+
+# Comentários em uma única linha começam com uma cerquilha (também conhecido por sustenido).
+
""" Strings de várias linhas podem ser escritas
usando três ", e são comumente usadas
- como comentários
+ como comentários.
"""
####################################################
@@ -31,287 +38,385 @@ qualquer Python 2.x. Logo haverá uma versão abordando Python 3!
####################################################
# Você usa números normalmente
-3 #=> 3
-
-# Operadores matemáticos são aqueles que você já está acostumado
-1 + 1 #=> 2
-8 - 1 #=> 7
-10 * 2 #=> 20
-35 / 5 #=> 7
-
-# A divisão é um pouco estranha. A divisão de números inteiros arredonda
-# para baixo o resultado, automaticamente
-5 / 2 #=> 2
+3 # => 3
-# Para concertar a divisão, precisamos aprender sobre números de ponto
-# flutuante (conhecidos como 'float').
-2.0 # Isso é um 'float'
-11.0 / 4.0 #=> 2.75 ahhh... muito melhor
+# Matemática é como você espera que seja
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
-# Forçamos a precedência de operadores usando parênteses
-(1 + 3) * 2 #=> 8
+# Números são inteiros por padrão, exceto na divisão, que retorna número
+# de ponto flutuante (float).
+35 / 5 # => 7.0
-# Valores booleanos (ou 'boolean') são também tipos primitivos
-True
-False
+# O resultado da divisão inteira arredonda para baixo tanto para números
+# positivos como para negativos.
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # funciona em float também
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
-# Negamos usando 'not'
-not True #=> False
-not False #=> True
+# Quando você usa um float, o resultado é float.
+3 * 2.0 # => 6.0
-# Testamos igualdade usando '=='
-1 == 1 #=> True
-2 == 1 #=> False
+# operador módulo
+7 % 3 # => 1
-# E desigualdade com '!='
-1 != 1 #=> False
-2 != 1 #=> True
-
-# Mais comparações
-1 < 10 #=> True
-1 > 10 #=> False
-2 <= 2 #=> True
-2 >= 2 #=> True
+# Exponenciação (x**y, x elevado à potência y)
+2**4 # => 16
-# As comparações podem ser encadeadas!
-1 < 2 < 3 #=> True
-2 < 3 < 2 #=> False
+# Determine a precedência usando parênteses
+(1 + 3) * 2 # => 8
-# Strings são criadas com " ou '
-"Isso é uma string."
-'Isso também é uma string.'
+# Valores lógicos são primitivos (Atenção à primeira letra maiúscula)
+True
+False
-# Strings podem ser somadas (ou melhor, concatenadas)!
-"Olá " + "mundo!" #=> "Olá mundo!"
+# negação lógica com not
+not True # => False
+not False # => True
-# Uma string pode ser tratada como uma lista de caracteres
-"Esta é uma string"[0] #=> 'E'
+# Operadores lógicos
+# Observe que "and" e "or" são sensíveis a maiúsculas e minúsculas
+True and False # => False
+False or True # => True
-# O caractere % pode ser usado para formatar strings, desta forma:
-"%s podem ser %s" % ("strings", "interpoladas")
+# Observe a utilização de operadores lógicos com números inteiros
+0 and 2 # => 0
+-5 or 0 # => -5
+0 == False # => True
+2 == True # => False
+1 == True # => True
-# Um jeito novo de formatar strings é usando o método 'format'.
-# Esse método é o jeito mais usado
-"{0} podem ser {1}".format("strings", "formatadas")
-# Você pode usar palavras-chave (ou 'keywords') se você não quiser contar.
-"{nome} quer comer {comida}".format(nome="João", comida="lasanha")
+# Igualdade é ==
+1 == 1 # => True
+2 == 1 # => False
-# 'None' é um objeto
-None #=> None
+# Diferença é !=
+1 != 1 # => False
+2 != 1 # => True
-# Não use o operador de igualdade `==` para comparar objetos com 'None'
-# Ao invés disso, use `is`
-"etc" is None #=> False
-None is None #=> True
+# Mais comparações
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# Comparações podem ser agrupadas
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# 'is' verifica se duas variáveis representam o mesmo endereço
+# na memória; '==' verifica se duas variáveis têm o mesmo valor
+a = [1, 2, 3, 4] # Referência a uma nova lista, [1, 2, 3, 4]
+b = a # b referencia o que está referenciado por a
+b is a # => True, a e b referenciam o mesmo objeto
+b == a # => True, objetos a e b tem o mesmo conteúdo
+b = [1, 2, 3, 4] # Referência a uma nova lista, [1, 2, 3, 4]
+b is a # => False, a e b não referenciam o mesmo objeto
+b == a # => True, objetos a e b tem o mesmo conteúdo
-# O operador 'is' teste a identidade de um objeto. Isso não é
-# muito útil quando estamos lidando com valores primitivos, mas é
-# muito útil quando lidamos com objetos.
+# Strings são criadas com " ou '
+"Isto é uma string."
+'Isto também é uma string.'
-# None, 0, e strings/listas vazias são todas interpretadas como 'False'.
-# Todos os outros valores são 'True'
-0 == False #=> True
-"" == False #=> True
+# Strings também podem ser somadas! Mas tente não fazer isso.
+"Olá " + "mundo!" # => "Olá mundo!"
+# Strings podem ser somadas sem usar o '+'
+"Olá " "mundo!" # => "Olá mundo!"
+# Uma string pode ser manipulada como se fosse uma lista de caracteres
+"Isso é uma string"[0] # => 'I'
-####################################################
-## 2. Variáveis e Coleções
-####################################################
+# .format pode ser usado para formatar strings, dessa forma:
+"{} podem ser {}".format("Strings", "interpoladas") # => "Strings podem ser interpoladas"
-# Imprimir na tela é muito fácil
-print "Eu sou o Python. Prazer em te conhecer!"
+# Você pode repetir os argumentos para digitar menos.
+"Seja ágil {0}, seja rápido {0}, salte sobre o {1} {0}".format("Jack", "castiçal")
+# => "Seja ágil Jack, seja rápido Jack, salte sobre o castiçal Jack."
+# Você pode usar palavras-chave se quiser contar.
+"{nome} quer comer {comida}".format(nome="Beto", comida="lasanha") # => "Beto quer comer lasanha"
-# Nós não precisamos declarar variáveis antes de usá-las, basta usar!
-alguma_variavel = 5 # A convenção é usar caixa_baixa_com_sobrescritos
-alguma_variavel #=> 5
+# Se você precisa executar seu código Python3 com um interpretador Python 2.5 ou acima, você pode usar a velha forma para formatação de texto:
+"%s podem ser %s da forma %s" % ("Strings", "interpoladas", "antiga") # => "Strings podem ser interpoladas da forma antiga"
-# Acessar uma variável que não teve nenhum valor atribuído anteriormente é
-# uma exceção.
-# Veja a seção 'Controle' para aprender mais sobre tratamento de exceção.
-outra_variavel # Gera uma exceção de erro de nome
-# 'if' pode ser usado como uma expressão
-"uepa!" if 3 > 2 else 2 #=> "uepa!"
+# None é um objeto
+None # => None
-# Listas armazenam sequências de elementos
-lista = []
-# Você pode inicializar uma lista com valores
-outra_lista = [4, 5, 6]
+# Não use o operador de igualdade "==" para comparar objetos com None
+# Use "is" para isso. Ele checará pela identidade dos objetos.
+"etc" is None # => False
+None is None # => True
-# Adicione elementos no final da lista usando 'append'
-lista.append(1) # lista é agora [1]
-lista.append(2) # lista é agora [1, 2]
-lista.append(4) # lista é agora [1, 2, 4]
-lista.append(3) # lista é agora [1, 2, 4, 3]
-# Remova elementos do fim da lista usando 'pop'
-lista.pop() #=> 3 e lista é agora [1, 2, 4]
-# Vamos adicionar o elemento novamente
-lista.append(3) # lista agora é [1, 2, 4, 3] novamente.
+# None, 0, e strings/listas/dicionários vazios todos retornam False.
+# Qualquer outra coisa retorna True
+bool(0) # => False
+bool("") # => False
+bool([]) # => False
+bool({}) # => False
-# Acesse elementos de uma lista através de seu índices
-lista[0] #=> 1
-# Acesse o último elemento com índice negativo!
-lista[-1] #=> 3
-# Tentar acessar um elemento fora dos limites da lista gera uma exceção
-# do tipo 'IndexError'
-lista[4] # Gera uma exceção 'IndexError'
-
-# Você pode acessar vários elementos ao mesmo tempo usando a sintaxe de
-# limites
-# (Para quem gosta de matemática, isso é um limite fechado/aberto)
-lista[1:3] #=> [2, 4]
-# Você pode omitir o fim se quiser os elementos até o final da lista
-lista[2:] #=> [4, 3]
-# O mesmo para o início
-lista[:3] #=> [1, 2, 4]
+####################################################
+## 2. Variáveis e coleções
+####################################################
-# Remova um elemento qualquer de uma lista usando 'del'
-del lista[2] # lista agora é [1, 2, 3]
+# Python tem uma função print
+print("Eu sou o Python. Prazer em conhecer!") # => Eu sou o Python. Prazer em conhecer!
+
+# Por padrão a função print também imprime o caractere de nova linha ao final.
+# Use o argumento opcional end para mudar o caractere final.
+print("Olá, Mundo", end="!") # => Olá, Mundo!
+
+# Forma simples para capturar dados de entrada via console
+input_string_var = input("Digite alguma coisa: ") # Retorna o que foi digitado em uma string
+# Observação: Em versões antigas do Python, o método input() era chamado raw_input()
+
+# Não é necessário declarar variáveis antes de iniciá-las
+# É uma convenção usar letras_minúsculas_com_sublinhados
+alguma_variavel = 5
+alguma_variavel # => 5
+
+# Acessar uma variável que não tenha sido inicializada gera uma exceção.
+# Veja Controle de Fluxo para aprender mais sobre tratamento de exceções.
+alguma_variavel_nao_inicializada # Gera a exceção NameError
+
+# Listas armazenam sequências
+li = []
+# Você pode iniciar uma lista com valores
+outra_li = [4, 5, 6]
+
+# Adicione conteúdo ao fim da lista com append
+li.append(1) # li agora é [1]
+li.append(2) # li agora é [1, 2]
+li.append(4) # li agora é [1, 2, 4]
+li.append(3) # li agora é [1, 2, 4, 3]
+# Remova do final da lista com pop
+li.pop() # => 3 e agora li é [1, 2, 4]
+# Vamos colocá-lo lá novamente!
+li.append(3) # li agora é [1, 2, 4, 3] novamente.
+
+# Acesse uma lista da mesma forma que você faz com um array
+li[0] # => 1
+# Acessando o último elemento
+li[-1] # => 3
+
+# Acessar além dos limites gera um IndexError
+li[4] # Gera o IndexError
+
+# Você pode acessar vários elementos com a sintaxe de limites
+# Inclusivo para o primeiro termo, exclusivo para o segundo
+li[1:3] # => [2, 4]
+# Omitindo o final
+li[2:] # => [4, 3]
+# Omitindo o início
+li[:3] # => [1, 2, 4]
+# Selecione cada segunda entrada
+li[::2] # => [1, 4]
+# Tenha uma cópia em ordem invertida da lista
+li[::-1] # => [3, 4, 2, 1]
+# Use qualquer combinação dessas para indicar limites complexos
+# li[inicio:fim:passo]
+
+# Faça uma cópia profunda de um nível usando limites
+li2 = li[:] # => li2 = [1, 2, 4, 3] mas (li2 is li) resultará em False.
+
+# Apague elementos específicos da lista com "del"
+del li[2] # li agora é [1, 2, 3]
+
+# Você pode somar listas
+# Observação: valores em li e other_li não são modificados.
+li + other_li # => [1, 2, 3, 4, 5, 6]
+
+# Concatene listas com "extend()"
+li.extend(other_li) # Agora li é [1, 2, 3, 4, 5, 6]
+
+# Verifique se algo existe na lista com "in"
+1 in li # => True
+
+# Examine tamanho com "len()"
+len(li) # => 6
+
+
+# Tuplas são como l istas, mas imutáveis.
+tup = (1, 2, 3)
+tup[0] # => 1
+tup[0] = 3 # Gera um TypeError
+
+# Observe que uma tupla de tamanho um precisa ter uma vírgula depois do
+# último elemento mas tuplas de outros tamanhos, mesmo vazias, não precisa,.
+type((1)) # => <class 'int'>
+type((1,)) # => <class 'tuple'>
+type(()) # => <class 'tuple'>
+
+# Você pode realizar com tuplas a maior parte das operações que faz com listas
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# Você pode desmembrar tuplas (ou listas) em variáveis.
+a, b, c = (1, 2, 3) # a é 1, b é 2 e c é 3
+# Por padrão, tuplas são criadas se você não coloca parêntesis.
+d, e, f = 4, 5, 6
+# Veja como é fácil permutar dois valores
+e, d = d, e # d é 5, e é 4
-# Você pode somar listas (obs: as listas originais não são modificadas)
-lista + outra_lista #=> [1, 2, 3, 4, 5, 6]
+# Dicionários armazenam mapeamentos
+empty_dict = {}
+# Aqui está um dicionário preenchido na definição da referência
+filled_dict = {"um": 1, "dois": 2, "três": 3}
-# Você também pode concatenar usando o método 'extend' (lista será modificada!)
-lista.extend(outra_lista) # Agora lista é [1, 2, 3, 4, 5, 6]
+# Observe que chaves para dicionários devem ser tipos imutáveis. Isto é para
+# assegurar que a chave pode ser convertida para uma valor hash constante para
+# buscas rápidas.
+# Tipos imutáveis incluem inteiros, flotas, strings e tuplas.
+invalid_dict = {[1,2,3]: "123"} # => Gera um TypeError: unhashable type: 'list'
+valid_dict = {(1,2,3):[1,2,3]} # Já os valores, podem ser de qualquer tipo.
-# Para checar se um elemento pertence a uma lista, use 'in'
-1 in lista #=> True
+# Acesse valores com []
+filled_dict["um"] # => 1
-# Saiba quantos elementos uma lista possui com 'len'
-len(lista) #=> 6
+# Acesse todas as chaves como um iterável com "keys()". É necessário encapsular
+# a chamada com um list() para transformá-las em uma lista. Falaremos sobre isso
+# mais adiante. Observe que a ordem de uma chave de dicionário não é garantida.
+# Por isso, os resultados aqui apresentados podem não ser exatamente como os
+# aqui apresentados.
+list(filled_dict.keys()) # => ["três", "dois", "um"]
-# Tuplas são iguais a listas, mas são imutáveis
-tup = (1, 2, 3)
-tup[0] #=> 1
-tup[0] = 3 # Isso gera uma exceção do tipo TypeError
-
-# Você pode fazer nas tuplas todas aquelas coisas fez com a lista
-len(tup) #=> 3
-tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
-tup[:2] #=> (1, 2)
-2 in tup #=> True
-
-# Você pode 'desempacotar' tuplas (ou listas) em variáveis, associando cada
-# elemento da tupla/lista a uma variável correspondente
-a, b, c = (1, 2, 3) # a agora é 1, b agora é 2, c agora é 3
-# Tuplas são criadas por padrão, mesmo se você não usar parênteses
-d, e, f = 4, 5, 6
-# Sabendo disso, veja só como é fácil trocar os valores de duas variáveis!
-e, d = d, e # d agora é 5, e agora é 4
+# Acesse todos os valores de um iterável com "values()". Novamente, é
+# necessário encapsular ele com list() para não termos um iterável, e sim os
+# valores. Observe que, como foi dito acima, a ordem dos elementos não é
+# garantida.
+list(filled_dict.values()) # => [3, 2, 1]
-# Dicionários armazenam 'mapeamentos' (do tipo chave-valor)
-dicionario_vazio = {}
-# Aqui criamos um dicionário já contendo valores
-dicionario = {"um": 1, "dois": 2, "três": 3}
+# Verifique a existência de chaves em um dicionário com "in"
+"um" in filled_dict # => True
+1 in filled_dict # => False
-# Acesse valores usando []
-dicionario["um"] #=> 1
+# Acessar uma chave inexistente gera um KeyError
+filled_dict["quatro"] # KeyError
-# Retorna uma lista com todas as chaves do dicionário
-dicionario.keys() #=> ["três", "dois", "um"]
-# Nota: A ordem das chaves não é garantida.
-# O resultado no seu interpretador não necessariamente será igual a esse.
+# Use o método "get()" para evitar um KeyError
+filled_dict.get("um") # => 1
+filled_dict.get("quatro") # => None
+# O método get permite um parâmetro padrão para quando não existir a chave
+filled_dict.get("um", 4) # => 1
+filled_dict.get("quatro", 4) # => 4
-# Retorna uma lista com todos os valores do dicionário
-dicionario.values() #=> [3, 2, 1]
-# Nota: A mesma nota acima sobre a ordenação é válida aqui.
+# "setdefault()" insere em dicionário apenas se a dada chave não existir
+filled_dict.setdefault("cinco", 5) # filled_dict["cinco"] tem valor 5
+filled_dict.setdefault("cinco", 6) # filled_dict["cinco"] continua 5
-# Veja se uma chave qualquer está em um dicionário usando 'in'
-"um" in dicionario #=> True
-1 in dicionario #=> False
+# Inserindo em um dicionário
+filled_dict.update({"quatro":4}) # => {"um": 1, "dois": 2, "três": 3, "quatro": 4}
+#filled_dict["quatro"] = 4 #outra forma de inserir em um dicionário
-# Tentar acessar uma chave que não existe gera uma exceção do tipo 'KeyError'
-dicionario["quatro"] # Gera uma exceção KeyError
+# Remova chaves de um dicionário com del
+del filled_dict["um"] # Remove a chave "um" de filled_dict
-# Você pode usar o método 'get' para evitar gerar a exceção 'KeyError'.
-# Ao invés de gerar essa exceção, irá retornar 'None' se a chave não existir.
-dicionario.get("um") #=> 1
-dicionario.get("quatro") #=> None
-# O método 'get' suporta um argumento que diz qual valor deverá ser
-# retornado se a chave não existir (ao invés de 'None').
-dicionario.get("um", 4) #=> 1
-dicionario.get("quatro", 4) #=> 4
-# O método 'setdefault' é um jeito seguro de adicionar um novo par
-# chave-valor a um dicionário, associando um valor padrão imutável à uma chave
-dicionario.setdefault("cinco", 5) # dicionario["cinco"] é definido como 5
-dicionario.setdefault("cinco", 6) # dicionario["cinco"] ainda é igual a 5
+# Armazenamento em sets... bem, são conjuntos
+empty_set = set()
+# Inicializa um set com alguns valores. Sim, ele parece um dicionário. Desculpe.
+some_set = {1, 1, 2, 2, 3, 4} # some_set agora é {1, 2, 3, 4}
+# Da mesma forma que chaves em um dicionário, elementos de um set devem ser
+# imutáveis.
+invalid_set = {[1], 1} # => Gera um TypeError: unhashable type: 'list'
+valid_set = {(1,), 1}
-# Conjuntos (ou sets) armazenam ... bem, conjuntos
-# Nota: lembre-se que conjuntos não admitem elementos repetidos!
-conjunto_vazio = set()
-# Podemos inicializar um conjunto com valores
-conjunto = set([1, 2, 2, 3, 4]) # conjunto é set([1, 2, 3, 4]), sem repetição!
+# Pode definir novas variáveis para um conjunto
+filled_set = some_set
-# Desde o Python 2.7, {} pode ser usado para declarar um conjunto
-conjunto = {1, 2, 2, 3, 4} # => {1 2 3 4}
+# Inclua mais um item no set
+filled_set.add(5) # filled_set agora é {1, 2, 3, 4, 5}
-# Adicione mais ítens a um conjunto com 'add'
-conjunto.add(5) # conjunto agora é {1, 2, 3, 4, 5}
+# Faça interseção de conjuntos com &
+other_set = {3, 4, 5, 6}
+filled_set & other_set # => {3, 4, 5}
-# Calcule a intersecção de dois conjuntos com &
-outro_conj = {3, 4, 5, 6}
-conjunto & outro_conj #=> {3, 4, 5}
+# Faça união de conjuntos com |
+filled_set | other_set # => {1, 2, 3, 4, 5, 6}
-# Calcule a união de dois conjuntos com |
-conjunto | outro_conj #=> {1, 2, 3, 4, 5, 6}
+# Faça a diferença entre conjuntos com -
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
-# E a diferença entre dois conjuntos com -
-{1,2,3,4} - {2,3,5} #=> {1, 4}
+# Verifique a existência em um conjunto com in
+2 in filled_set # => True
+10 in filled_set # => False
-# Veja se um elemento existe em um conjunto usando 'in'
-2 in conjunto #=> True
-10 in conjunto #=> False
####################################################
-## 3. Controle
+## 3. Controle de fluxo e iteráveis
####################################################
-# Para começar, vamos apenas criar uma variável
-alguma_var = 5
+# Iniciemos um variável
+some_var = 5
-# Aqui está uma expressão 'if'. Veja como a identação é importante em Python!
-# Esses comandos irão imprimir "alguma_var é menor que 10"
-if alguma_var > 10:
- print "some_var é maior que 10."
-elif some_var < 10: # Esse 'elif' é opcional
- print "some_var é menor que 10."
-else: # Esse 'else' também é opcional
- print "some_var é igual a 10."
+# Aqui está uma expressão if. Indentação é significante em python!
+# imprime "somevar é menor que10"
+if some_var > 10:
+ print("some_var é absolutamente maior que 10.")
+elif some_var < 10: # Esta cláusula elif é opcional.
+ print("some_var é menor que 10.")
+else: # Isto também é opcional.
+ print("some_var é, de fato, 10.")
"""
-Laços (ou loops) 'for' iteram em listas.
-Irá imprimir:
+Laços for iteram sobre listas
+imprime:
cachorro é um mamífero
gato é um mamífero
rato é um mamífero
"""
for animal in ["cachorro", "gato", "rato"]:
- # Você pode usar % para interpolar strings formatadas
- print "%s é um mamífero" % animal
-
+ # Você pode usar format() para interpolar strings formatadas
+ print("{} é um mamífero".format(animal))
+
"""
-A função `range(um número)` retorna uma lista de números
-do zero até o número dado.
-Irá imprimir:
+"range(número)" retorna um iterável de números
+de zero até o número escolhido
+imprime:
0
1
2
3
"""
for i in range(4):
- print i
+ print(i)
+
+"""
+"range(menor, maior)" gera um iterável de números
+começando pelo menor até o maior
+imprime:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print(i)
"""
-Laços 'while' executam enquanto uma condição dada for verdadeira.
-Irá imprimir:
+"range(menor, maior, passo)" retorna um iterável de números
+começando pelo menor número até o maior númeno, pulando de
+passo em passo. Se o passo não for indicado, o valor padrão é um.
+imprime:
+ 4
+ 6
+"""
+for i in range(4, 8, 2):
+ print(i)
+"""
+
+Laços while executam até que a condição não seja mais válida.
+imprime:
0
1
2
@@ -319,143 +424,221 @@ Irá imprimir:
"""
x = 0
while x < 4:
- print x
- x += 1 # Isso é um atalho para a expressão x = x + 1
-
-# Tratamos excessões usando o bloco try/except
-# Funciona em Python 2.6 e versões superiores:
+ print(x)
+ x += 1 # Maneira mais curta para for x = x + 1
+# Lide com exceções com um bloco try/except
try:
- # Use 'raise' para gerar um erro
- raise IndexError("Isso é um erro de índice")
+ # Use "raise" para gerar um erro
+ raise IndexError("Isto é um erro de índice")
except IndexError as e:
- pass # Pass é um operador que não faz nada, deixa passar.
- # Usualmente você iria tratar a exceção aqui...
+ pass # Pass é um não-operador. Normalmente você usa algum código de recuperação aqui.
+except (TypeError, NameError):
+ pass # Varias exceções podem ser gerenciadas, se necessário.
+else: # Cláusula opcional para o bloco try/except. Deve estar após todos os blocos de exceção.
+ print("Tudo certo!") # Executa apenas se o código em try não gera exceção
+finally: # Sempre é executado
+ print("Nós podemos fazer o código de limpeza aqui.")
+
+# Ao invés de try/finally para limpeza você pode usar a cláusula with
+with open("myfile.txt") as f:
+ for line in f:
+ print(line)
+
+# Python provê uma abstração fundamental chamada Iterável.
+# Um iterável é um objeto que pode ser tratado como uma sequência.
+# O objeto retornou a função range, um iterável.
+
+filled_dict = {"um": 1, "dois": 2, "três": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) # => range(1,10). Esse é um objeto que implementa nossa interface iterável.
+
+# Nós podemos percorrê-la.
+for i in our_iterable:
+ print(i) # Imprime um, dois, três
+
+# Mas não podemos acessar os elementos pelo seu índice.
+our_iterable[1] # Gera um TypeError
+
+# Um iterável é um objeto que sabe como criar um iterador.
+our_iterator = iter(our_iterable)
+
+# Nosso iterador é um objeto que pode lembrar o estado enquanto nós o percorremos.
+# Nós acessamos o próximo objeto com "next()".
+next(our_iterator) # => "um"
+
+# Ele mantém o estado enquanto nós o percorremos.
+next(our_iterator) # => "dois"
+next(our_iterator) # => "três"
+
+# Após o iterador retornar todos os seus dados, ele gera a exceção StopIterator
+next(our_iterator) # Gera StopIteration
+
+# Você pode capturar todos os elementos de um iterador aplicando list() nele.
+list(filled_dict.keys()) # => Retorna ["um", "dois", "três"]
####################################################
## 4. Funções
####################################################
-# Use 'def' para definir novas funções
-def soma(x, y):
- print "x é %s e y é %s" % (x, y)
- return x + y # Retorne valores usando 'return'
+# Use "def" para criar novas funções.
+def add(x, y):
+ print("x é {} e y é {}".format(x, y))
+ return x + y # Retorne valores com a cláusula return
# Chamando funções com parâmetros
-soma(5, 6) #=> imprime "x é 5 e y é 6" e retorna o valor 11
+add(5, 6) # => imprime "x é 5 e y é 6" e retorna 11
-# Um outro jeito de chamar funções é especificando explicitamente os valores
-# de cada parâmetro com chaves
-soma(y=6, x=5) # Argumentos com chaves podem vir em qualquer ordem.
+# Outro meio de chamar funções é com argumentos nomeados
+add(y=6, x=5) # Argumentos nomeados podem aparecer em qualquer ordem.
-# Você pode definir funções que recebem um número qualquer de argumentos
-# (respeitando a sua ordem)
+# Você pode definir funções que pegam um número variável de argumentos
+# posicionais
def varargs(*args):
return args
-varargs(1, 2, 3) #=> (1,2,3)
+varargs(1, 2, 3) # => (1, 2, 3)
+# Você pode definir funções que pegam um número variável de argumentos nomeados
+# também
+def keyword_args(**kwargs):
+ return kwargs
-# Você também pode definir funções que recebem um número qualquer de argumentos
-# com chaves
-def args_com_chaves(**ch_args):
- return ch_args
+# Vamos chamá-lo para ver o que acontece
+keyword_args(peh="grande", lago="ness") # => {"peh": "grande", "lago": "ness"}
-# Vamos chamar essa função para ver o que acontece
-args_com_chaves(pe="grande", lago="Ness") #=> {"pe": "grande", "lago": "Ness"}
-# Você pode fazer as duas coisas ao mesmo tempo, se desejar
-def todos_args(*args, **ch_wargs):
- print args
- print ch_args
+# Você pode fazer ambos simultaneamente, se você quiser
+def all_the_args(*args, **kwargs):
+ print(args)
+ print(kwargs)
"""
-todos_args(1, 2, a=3, b=4) imprime:
+all_the_args(1, 2, a=3, b=4) imprime:
(1, 2)
{"a": 3, "b": 4}
"""
-# Quando você chamar funções, pode fazer o oposto do que fizemos até agora!
-# Podemos usar * para expandir tuplas de argumentos e ** para expandir
-# dicionários de argumentos com chave.
+# Quando chamar funções, você pode fazer o oposto de args/kwargs!
+# Use * para expandir tuplas e use ** para expandir dicionários!
args = (1, 2, 3, 4)
-ch_args = {"a": 3, "b": 4}
-todos_args(*args) # equivalente a todos_args(1, 2, 3, 4)
-todos_args(**ch_args) # equivalente a todos_args(a=3, b=4)
-todos_args(*args, **ch_args) # equivalente a todos_args(1, 2, 3, 4, a=3, b=4)
-
-# Em Python, funções são elementos de primeira ordem (são como objetos,
-# strings ou números)
-def cria_somador(x):
- def somador(y):
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # equivalente a foo(1, 2, 3, 4)
+all_the_args(**kwargs) # equivalente a foo(a=3, b=4)
+all_the_args(*args, **kwargs) # equivalente a foo(1, 2, 3, 4, a=3, b=4)
+
+# Retornando múltiplos valores (com atribuição de tuplas)
+def swap(x, y):
+ return y, x # Retorna múltiplos valores como uma tupla sem os parêntesis.
+ # (Observação: os parêntesis foram excluídos mas podem estar
+ # presentes)
+
+x = 1
+y = 2
+x, y = swap(x, y) # => x = 2, y = 1
+# (x, y) = swap(x,y) # Novamente, os parêntesis foram excluídos mas podem estar presentes.
+
+# Escopo de função
+x = 5
+
+def setX(num):
+ # A variável local x não é a mesma variável global x
+ x = num # => 43
+ print (x) # => 43
+
+def setGlobalX(num):
+ global x
+ print (x) # => 5
+ x = num # variável global x agora é 6
+ print (x) # => 6
+
+setX(43)
+setGlobalX(6)
+
+
+# Python tem funções de primeira classe
+def create_adder(x):
+ def adder(y):
return x + y
- return somador
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) # => 13
-soma_10 = cria_somador(10)
-soma_10(3) #=> 13
+# Também existem as funções anônimas
+(lambda x: x > 2)(3) # => True
+(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
-# Desta forma, existem também funções anônimas
-(lambda x: x > 2)(3) #=> True
+# TODO - Fix for iterables
+# Existem funções internas de alta ordem
+map(add_10, [1, 2, 3]) # => [11, 12, 13]
+map(max, [1, 2, 3], [4, 2, 1]) # => [4, 2, 3]
-# E existem funções de alta ordem por padrão
-map(soma_10, [1,2,3]) #=> [11, 12, 13]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
-reduce(lambda x, y: x + y, [3, 4, 5, 6, 7]) #=> 25
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
-# Nós podemos usar compreensão de listas para mapear e filtrar também
-[soma_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]
+# Nós podemos usar compreensão de lista para interessantes mapas e filtros
+# Compreensão de lista armazena a saída como uma lista que pode ser uma lista
+# aninhada
+[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
####################################################
## 5. Classes
####################################################
-# Para criar uma nova classe, devemos herdar de 'object'
-class Humano(object):
- # Um atributo de classe. Ele é compartilhado por todas as instâncias dessa
- # classe
- especie = "H. sapiens"
-
- # Definimos um inicializador básico
- def __init__(self, nome):
- # Atribui o valor de argumento dado a um atributo da instância
- self.nome = nome
+# Nós usamos o operador "class" para ter uma classe
+class Human:
- # Um método de instância. Todos os métodos levam 'self' como primeiro
+ # Um atributo de classe. Ele é compartilhado por todas as instâncias dessa
+ # classe.
+ species = "H. sapiens"
+
+ # Construtor básico, é chamado quando esta classe é instanciada.
+ # Note que dois sublinhados no início e no final de uma identificados
+ # significa objetos ou atributos que são usados pelo python mas vivem em
+ # um namespace controlado pelo usuário. Métodos (ou objetos ou atributos)
+ # como: __init__, __str__, __repr__, etc. são chamados métodos mágicos (ou
+ # algumas vezes chamados métodos dunder - "double underscore")
+ # Você não deve usar nomes assim por sua vontade.
+ def __init__(self, name):
+ @ Atribui o argumento ao atributo da instância
+ self.name = name
+
+ # Um método de instância. Todos os métodos tem "self" como primeiro
# argumento
- def diga(self, msg):
- return "%s: %s" % (self.nome, msg)
+ def say(self, msg):
+ return "{name}: {message}".format(name=self.name, message=msg)
# Um método de classe é compartilhado por todas as instâncias
- # Eles são chamados passando o nome da classe como primeiro argumento
+ # Eles são chamados com a classe requisitante como primeiro argumento
@classmethod
- def get_especie(cls):
- return cls.especie
+ def get_species(cls):
+ return cls.species
# Um método estático é chamado sem uma referência a classe ou instância
@staticmethod
- def ronca():
- return "*arrrrrrr*"
+ def grunt():
+ return "*grunt*"
# Instancie uma classe
-i = Humano(nome="Ivone")
-print i.diga("oi") # imprime "Ivone: oi"
+i = Human(name="Ian")
+print(i.say("oi")) # imprime "Ian: oi"
j = Human("Joel")
-print j.say("olá") #prints out "Joel: olá"
+print(j.say("olá")) # imprime "Joel: olá"
-# Chame nosso método de classe
-i.get_especie() #=> "H. sapiens"
+# Chama nosso método de classe
+i.get_species() # => "H. sapiens"
-# Modifique um atributo compartilhado
-Humano.especie = "H. neanderthalensis"
-i.get_especie() #=> "H. neanderthalensis"
-j.get_especie() #=> "H. neanderthalensis"
+# Altera um atributo compartilhado
+Human.species = "H. neanderthalensis"
+i.get_species() # => "H. neanderthalensis"
+j.get_species() # => "H. neanderthalensis"
-# Chame o método estático
-Humano.ronca() #=> "*arrrrrrr*"
+# Chama o método estático
+Human.grunt() # => "*grunt*"
####################################################
@@ -464,46 +647,100 @@ Humano.ronca() #=> "*arrrrrrr*"
# Você pode importar módulos
import math
-print math.sqrt(16) #=> 4
+print(math.sqrt(16)) # => 4.0
-# Você pode importar funções específicas de um módulo
+# Você pode importar apenas funções específicas de um módulo
from math import ceil, floor
-print ceil(3.7) #=> 4.0
-print floor(3.7) #=> 3.0
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
-# Você também pode importar todas as funções de um módulo
-# Atenção: isso não é recomendado!
+# Você pode importar todas as funções de um módulo para o namespace atual
+# Atenção: isso não é recomendado
from math import *
-# Você pode usar apelidos para os módulos, encurtando seus nomes
+# Você pode encurtar o nome dos módulos
import math as m
-math.sqrt(16) == m.sqrt(16) #=> True
+math.sqrt(16) == m.sqrt(16) # => True
-# Módulos em Python são apenas arquivos Python. Você
-# pode escrever o seu próprio módulo e importá-lo. O nome do
-# módulo será o mesmo que o nome do arquivo.
+# Módulos python são apenas arquivos python comuns. Você
+# pode escrever os seus, e importá-los. O nome do
+# módulo é o mesmo nome do arquivo.
-# Você pode descobrir quais funções e atributos
-# estão definidos em um módulo qualquer.
+# Você pode procurar que atributos e funções definem um módulo.
import math
dir(math)
+####################################################
+## 7. Avançado
+####################################################
+
+# Geradores podem ajudar você a escrever código "preguiçoso"
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# Um gerador cria valores conforme necessário.
+# Ao invés de gerar e retornar todos os valores de uma só vez ele cria um em
+# cada interação. Isto significa que valores maiores que 15 não serão
+# processados em double_numbers.
+# Nós usamos um sublinhado ao final do nome das variáveis quando queremos usar
+# um nome que normalmente colide com uma palavra reservada do python.
+range_ = range(1, 900000000)
+# Multiplica por 2 todos os números até encontrar um resultado >= 30
+for i in double_numbers(range_):
+ print(i)
+ if i >= 30:
+ break
+
+
+# Decoradores
+# Neste exemplo beg encapsula say
+# beg irá chamar say. Se say_please é verdade então ele irá mudar a mensagem
+# retornada
+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, "Por favor! Eu sou pobre :(")
+ return msg
+
+ return wrapper
+
+
+@beg
+def say(say_please=False):
+ msg = "Você me paga uma cerveja?"
+ return msg, say_please
+
+
+print(say()) # Você me paga uma cerveja?
+print(say(say_please=True)) # Você me paga uma cerveja? Por favor! Eu sou pobre :(
```
## Pronto para mais?
-### Online e gratuito
+### Free Online
+* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
* [Dive Into Python](http://www.diveintopython.net/)
-* [The Official Docs](http://docs.python.org/2.6/)
+* [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 Module of the Week](http://pymotw.com/2/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+* [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/)
-### Livros impressos
+### Dead Tree
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
-
diff --git a/pt-br/python3-pt.html.markdown b/pt-br/python3-pt.html.markdown
deleted file mode 100644
index 9b6bd1b6..00000000
--- a/pt-br/python3-pt.html.markdown
+++ /dev/null
@@ -1,746 +0,0 @@
----
-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"]
-translators:
- - ["Paulo Henrique Rodrigues Pinheiro", "http://www.sysincloud.it"]
-lang: pt-br
-filename: learnpython3-pt.py
----
-
-Python foi criado por Guido Van Rossum nos anos 1990. Ele é atualmente uma
-das mais populares linguagens em existência. Eu fiquei morrendo de amor
-pelo Python por sua clareza sintática. É praticamente pseudocódigo executável.
-
-Suas opiniões são grandemente apreciadas. Você pode encontrar-me em
-[@louiedinh](http://twitter.com/louiedinh) ou louiedinh [em]
-[serviço de e-mail do google].
-
-Observação: Este artigo trata de Python 3 especificamente. Verifique
-[aqui](http://learnxinyminutes.com/docs/pt-br/python-pt/) se você pretende
-aprender o velho Python 2.7.
-
-```python
-
-# Comentários em uma única linha começam com uma cerquilha (também conhecido por sustenido).
-
-""" Strings de várias linhas podem ser escritas
- usando três ", e são comumente usadas
- como comentários.
-"""
-
-####################################################
-## 1. Tipos de dados primitivos e operadores
-####################################################
-
-# Você usa números normalmente
-3 # => 3
-
-# Matemática é como você espera que seja
-1 + 1 # => 2
-8 - 1 # => 7
-10 * 2 # => 20
-
-# Números inteiros por padrão, exceto na divisão, que retorna número
-# de ponto flutuante (float).
-35 / 5 # => 7.0
-
-# O resultado da divisão inteira arredonda para baixo tanto para números
-# positivos como para negativos.
-5 // 3 # => 1
-5.0 // 3.0 # => 1.0 # funciona em float também
--5 // 3 # => -2
--5.0 // 3.0 # => -2.0
-
-# Quando você usa um float, o resultado é float.
-3 * 2.0 # => 6.0
-
-# operador módulo
-7 % 3 # => 1
-
-# Exponenciação (x**y, x elevado à potência y)
-2**4 # => 16
-
-# Determine a precedência usando parêntesis
-(1 + 3) * 2 # => 8
-
-# Valores lógicos são primitivos (Atenção à primeira letra maiúscula)
-True
-False
-
-# negação lógica com not
-not True # => False
-not False # => True
-
-# Operadores lógicos
-# Observe que "and" e "or" são sensíveis a maiúsculas e minúsculas
-True and False # => False
-False or True # => True
-
-# Observe a utilização de operadores lógicos com números inteiros
-0 and 2 # => 0
--5 or 0 # => -5
-0 == False # => True
-2 == True # => False
-1 == True # => True
-
-# Igualdade é ==
-1 == 1 # => True
-2 == 1 # => False
-
-# Diferença é !=
-1 != 1 # => False
-2 != 1 # => True
-
-# Mais comparações
-1 < 10 # => True
-1 > 10 # => False
-2 <= 2 # => True
-2 >= 2 # => True
-
-# Comparações podem ser agrupadas
-1 < 2 < 3 # => True
-2 < 3 < 2 # => False
-
-# (operador 'is' e operador '==') is verifica se duas referenciam um
-# mesmo objeto, mas == verifica se as variáveis apontam para o
-# mesmo valor.
-a = [1, 2, 3, 4] # Referência a uma nova lista, [1, 2, 3, 4]
-b = a # b referencia o que está referenciado por a
-b is a # => True, a e b referenciam o mesmo objeto
-b == a # => True, objetos a e b tem o mesmo conteúdo
-b = [1, 2, 3, 4] # Referência a uma nova lista, [1, 2, 3, 4]
-b is a # => False, a e b não referenciam o mesmo objeto
-b == a # => True, objetos a e b tem o mesmo conteúdo
-
-# Strings são criadas com " ou '
-"Isto é uma string."
-'Isto também é uma string.'
-
-# Strings também podem ser somadas! Mas tente não fazer isso.
-"Olá " + "mundo!" # => "Olá mundo!"
-# Strings podem ser somadas sem usar o '+'
-"Olá " "mundo!" # => "Olá mundo!"
-
-# Uma string pode ser manipulada como se fosse uma lista de caracteres
-"Isso é uma string"[0] # => 'I'
-
-# .format pode ser usado para formatar strings, dessa forma:
-"{} podem ser {}".format("Strings", "interpoladas") # => "Strings podem ser interpoladas"
-
-# Você pode repetir os argumentos para digitar menos.
-"Seja ágil {0}, seja rápido {0}, salte sobre o {1} {0}".format("Jack", "castiçal")
-# => "Seja ágil Jack, seja rápido Jack, salte sobre o castiçal Jack."
-
-# Você pode usar palavras-chave se quiser contar.
-"{nome} quer comer {comida}".format(nome="Beto", comida="lasanha") # => "Beto quer comer lasanha"
-
-# Se você precisa executar seu código Python3 com um interpretador Python 2.5 ou acima, você pode usar a velha forma para formatação de texto:
-"%s podem ser %s da forma %s" % ("Strings", "interpoladas", "antiga") # => "Strings podem ser interpoladas da forma antiga"
-
-
-# None é um objeto
-None # => None
-
-# Não use o operador de igualdade "==" para comparar objetos com None
-# Use "is" para isso. Ele checará pela identidade dos objetos.
-"etc" is None # => False
-None is None # => True
-
-# None, 0, e strings/listas/dicionários vazios todos retornam False.
-# Qualquer outra coisa retorna True
-bool(0) # => False
-bool("") # => False
-bool([]) # => False
-bool({}) # => False
-
-
-####################################################
-## 2. Variáveis e coleções
-####################################################
-
-# Python tem uma função print
-print("Eu sou o Python. Prazer em conhecer!") # => Eu sou o Python. Prazer em conhecer!
-
-# Por padrão a função print também imprime o caractere de nova linha ao final.
-# Use o argumento opcional end para mudar o caractere final.
-print("Olá, Mundo", end="!") # => Olá, Mundo!
-
-# Forma simples para capturar dados de entrada via console
-input_string_var = input("Digite alguma coisa: ") # Retorna o que foi digitado em uma string
-# Observação: Em versões antigas do Python, o método input() era chamado raw_input()
-
-# Não é necessário declarar variáveis antes de iniciá-las
-# È uma convenção usar letras_minúsculas_com_sublinhados
-alguma_variavel = 5
-alguma_variavel # => 5
-
-# Acessar uma variável que não tenha sido inicializada gera uma exceção.
-# Veja Controle de Fluxo para aprender mais sobre tratamento de exceções.
-alguma_variavel_nao_inicializada # Gera a exceção NameError
-
-# Listas armazenam sequencias
-li = []
-# Você pode iniciar com uma lista com alguns valores
-outra_li = [4, 5, 6]
-
-# Adicionar conteúdo ao fim da lista com append
-li.append(1) # li agora é [1]
-li.append(2) # li agora é [1, 2]
-li.append(4) # li agora é [1, 2, 4]
-li.append(3) # li agora é [1, 2, 4, 3]
-# Remover do final da lista com pop
-li.pop() # => 3 e agora li é [1, 2, 4]
-# Vamos colocá-lo lá novamente!
-li.append(3) # li agora é [1, 2, 4, 3] novamente.
-
-# Acessar uma lista da mesma forma que você faz com um array
-li[0] # => 1
-# Acessa o último elemento
-li[-1] # => 3
-
-# Acessando além dos limites gera um IndexError
-li[4] # Gera o IndexError
-
-# Você pode acessar vários elementos com a sintaxe de limites
-# (É um limite fechado, aberto pra você que gosta de matemática.)
-li[1:3] # => [2, 4]
-# Omitindo o final
-li[2:] # => [4, 3]
-# Omitindo o início
-li[:3] # => [1, 2, 4]
-# Selecione cada segunda entrada
-li[::2] # => [1, 4]
-# Tenha uma cópia em ordem invertida da lista
-li[::-1] # => [3, 4, 2, 1]
-# Use qualquer combinação dessas para indicar limites complexos
-# li[inicio:fim:passo]
-
-# Faça uma cópia profunda de um nível usando limites
-li2 = li[:] # => li2 = [1, 2, 4, 3] mas (li2 is li) resultará em False.
-
-# Apague elementos específicos da lista com "del"
-del li[2] # li agora é [1, 2, 3]
-
-# Você pode somar listas
-# Observação: valores em li e other_li não são modificados.
-li + other_li # => [1, 2, 3, 4, 5, 6]
-
-# Concatene listas com "extend()"
-li.extend(other_li) # Agora li é [1, 2, 3, 4, 5, 6]
-
-# Verifique se algo existe na lista com "in"
-1 in li # => True
-
-# Examine tamanho com "len()"
-len(li) # => 6
-
-
-# Tuplas são como l istas, mas imutáveis.
-tup = (1, 2, 3)
-tup[0] # => 1
-tup[0] = 3 # Gera um TypeError
-
-# Observe que uma tupla de tamanho um precisa ter uma vírgula depois do
-# último elemento mas tuplas de outros tamanhos, mesmo vazias, não precisa,.
-type((1)) # => <class 'int'>
-type((1,)) # => <class 'tuple'>
-type(()) # => <class 'tuple'>
-
-# Você pode realizar com tuplas a maior parte das operações que faz com listas
-len(tup) # => 3
-tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
-tup[:2] # => (1, 2)
-2 in tup # => True
-
-# Você pode desmembrar tuplas (ou listas) em variáveis.
-a, b, c = (1, 2, 3) # a é 1, b é 2 e c é 3
-# Por padrão, tuplas são criadas se você não coloca parêntesis.
-d, e, f = 4, 5, 6
-# Veja como é fácil permutar dois valores
-e, d = d, e # d é 5, e é 4
-
-# Dicionários armazenam mapeamentos
-empty_dict = {}
-# Aqui está um dicionário preenchido na definição da referência
-filled_dict = {"um": 1, "dois": 2, "três": 3}
-
-# Observe que chaves para dicionários devem ser tipos imutáveis. Isto é para
-# assegurar que a chave pode ser convertida para uma valor hash constante para
-# buscas rápidas.
-# Tipos imutáveis incluem inteiros, flotas, strings e tuplas.
-invalid_dict = {[1,2,3]: "123"} # => Gera um TypeError: unhashable type: 'list'
-valid_dict = {(1,2,3):[1,2,3]} # Já os valores, podem ser de qualquer tipo.
-
-# Acesse valores com []
-filled_dict["um"] # => 1
-
-# Acesse todas as chaves como um iterável com "keys()". É necessário encapsular
-# a chamada com um list() para transformá-las em uma lista. Falaremos sobre isso
-# mais adiante. Observe que a ordem de uma chave de dicionário não é garantida.
-# Por isso, os resultados aqui apresentados podem não ser exatamente como os
-# aqui apresentados.
-list(filled_dict.keys()) # => ["três", "dois", "um"]
-
-
-# Acesse todos os valores de um iterável com "values()". Novamente, é
-# necessário encapsular ele com list() para não termos um iterável, e sim os
-# valores. Observe que, como foi dito acima, a ordem dos elementos não é
-# garantida.
-list(filled_dict.values()) # => [3, 2, 1]
-
-
-# Verifique a existência de chaves em um dicionário com "in"
-"um" in filled_dict # => True
-1 in filled_dict # => False
-
-# Acessar uma chave inexistente gera um KeyError
-filled_dict["quatro"] # KeyError
-
-# Use o método "get()" para evitar um KeyError
-filled_dict.get("um") # => 1
-filled_dict.get("quatro") # => None
-# O método get permite um parâmetro padrão para quando não existir a chave
-filled_dict.get("um", 4) # => 1
-filled_dict.get("quatro", 4) # => 4
-
-# "setdefault()" insere em dicionário apenas se a dada chave não existir
-filled_dict.setdefault("cinco", 5) # filled_dict["cinco"] tem valor 5
-filled_dict.setdefault("cinco", 6) # filled_dict["cinco"] continua 5
-
-# Inserindo em um dicionário
-filled_dict.update({"quatro":4}) # => {"um": 1, "dois": 2, "três": 3, "quatro": 4}
-#filled_dict["quatro"] = 4 #outra forma de inserir em um dicionário
-
-# Remova chaves de um dicionário com del
-del filled_dict["um"] # Remove a chave "um" de filled_dict
-
-
-# Armazenamento em sets... bem, são conjuntos
-empty_set = set()
-# Inicializa um set com alguns valores. Sim, ele parece um dicionário. Desculpe.
-some_set = {1, 1, 2, 2, 3, 4} # some_set agora é {1, 2, 3, 4}
-
-# Da mesma forma que chaves em um dicionário, elementos de um set devem ser
-# imutáveis.
-invalid_set = {[1], 1} # => Gera um TypeError: unhashable type: 'list'
-valid_set = {(1,), 1}
-
-# Pode definir novas variáveis para um conjunto
-filled_set = some_set
-
-# Inclua mais um item no set
-filled_set.add(5) # filled_set agora é {1, 2, 3, 4, 5}
-
-# Faça interseção de conjuntos com &
-other_set = {3, 4, 5, 6}
-filled_set & other_set # => {3, 4, 5}
-
-# Faça união de conjuntos com |
-filled_set | other_set # => {1, 2, 3, 4, 5, 6}
-
-# Faça a diferença entre conjuntos com -
-{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
-
-# Verifique a existência em um conjunto com in
-2 in filled_set # => True
-10 in filled_set # => False
-
-
-
-####################################################
-## 3. Controle de fluxo e iteráveis
-####################################################
-
-# Iniciemos um variável
-some_var = 5
-
-# Aqui está uma expressão if. Indentação é significante em python!
-# imprime "somevar é menor que10"
-if some_var > 10:
- print("some_var é absolutamente maior que 10.")
-elif some_var < 10: # Esta cláusula elif é opcional.
- print("some_var é menor que 10.")
-else: # Isto também é opcional.
- print("some_var é, de fato, 10.")
-
-
-"""
-Laços for iteram sobre listas
-imprime:
- cachorro é um mamífero
- gato é um mamífero
- rato é um mamífero
-"""
-for animal in ["cachorro", "gato", "rato"]:
- # Você pode usar format() para interpolar strings formatadas
- print("{} é um mamífero".format(animal))
-
-"""
-"range(número)" retorna um iterável de números
-de zero até o número escolhido
-imprime:
- 0
- 1
- 2
- 3
-"""
-for i in range(4):
- print(i)
-
-"""
-"range(menor, maior)" gera um iterável de números
-começando pelo menor até o maior
-imprime:
- 4
- 5
- 6
- 7
-"""
-for i in range(4, 8):
- print(i)
-
-"""
-"range(menor, maior, passo)" retorna um iterável de números
-começando pelo menor número até o maior númeno, pulando de
-passo em passo. Se o passo não for indicado, o valor padrão é um.
-imprime:
- 4
- 6
-"""
-for i in range(4, 8, 2):
- print(i)
-"""
-
-Laços while executam até que a condição não seja mais válida.
-imprime:
- 0
- 1
- 2
- 3
-"""
-x = 0
-while x < 4:
- print(x)
- x += 1 # Maneira mais curta para for x = x + 1
-
-# Lide com exceções com um bloco try/except
-try:
- # Use "raise" para gerar um erro
- raise IndexError("Isto é um erro de índice")
-except IndexError as e:
- pass # Pass é um não-operador. Normalmente você usa algum código de recuperação aqui.
-except (TypeError, NameError):
- pass # Varias exceções podem ser gerenciadas, se necessário.
-else: # Cláusula opcional para o bloco try/except. Deve estar após todos os blocos de exceção.
- print("Tudo certo!") # Executa apenas se o código em try não gera exceção
-finally: # Sempre é executado
- print("Nós podemos fazer o código de limpeza aqui.")
-
-# Ao invés de try/finally para limpeza você pode usar a cláusula with
-with open("myfile.txt") as f:
- for line in f:
- print(line)
-
-# Python provê uma abstração fundamental chamada Iterável.
-# Um iterável é um objeto que pode ser tratado como uma sequência.
-# O objeto retornou a função range, um iterável.
-
-filled_dict = {"um": 1, "dois": 2, "três": 3}
-our_iterable = filled_dict.keys()
-print(our_iterable) # => range(1,10). Esse é um objeto que implementa nossa interface iterável.
-
-# Nós podemos percorrê-la.
-for i in our_iterable:
- print(i) # Imprime um, dois, três
-
-# Mas não podemos acessar os elementos pelo seu índice.
-our_iterable[1] # Gera um TypeError
-
-# Um iterável é um objeto que sabe como criar um iterador.
-our_iterator = iter(our_iterable)
-
-# Nosso iterador é um objeto que pode lembrar o estado enquanto nós o percorremos.
-# Nós acessamos o próximo objeto com "next()".
-next(our_iterator) # => "um"
-
-# Ele mantém o estado enquanto nós o percorremos.
-next(our_iterator) # => "dois"
-next(our_iterator) # => "três"
-
-# Após o iterador retornar todos os seus dados, ele gera a exceção StopIterator
-next(our_iterator) # Gera StopIteration
-
-# Você pode capturar todos os elementos de um iterador aplicando list() nele.
-list(filled_dict.keys()) # => Retorna ["um", "dois", "três"]
-
-
-####################################################
-## 4. Funções
-####################################################
-
-# Use "def" para criar novas funções.
-def add(x, y):
- print("x é {} e y é {}".format(x, y))
- return x + y # Retorne valores com a cláusula return
-
-# Chamando funções com parâmetros
-add(5, 6) # => imprime "x é 5 e y é 6" e retorna 11
-
-# Outro meio de chamar funções é com argumentos nomeados
-add(y=6, x=5) # Argumentos nomeados podem aparecer em qualquer ordem.
-
-# Você pode definir funções que pegam um número variável de argumentos
-# posicionais
-def varargs(*args):
- return args
-
-varargs(1, 2, 3) # => (1, 2, 3)
-
-# Você pode definir funções que pegam um número variável de argumentos nomeados
-# também
-def keyword_args(**kwargs):
- return kwargs
-
-# Vamos chamá-lo para ver o que acontece
-keyword_args(peh="grande", lago="ness") # => {"peh": "grande", "lago": "ness"}
-
-
-# Você pode fazer ambos simultaneamente, se você quiser
-def all_the_args(*args, **kwargs):
- print(args)
- print(kwargs)
-"""
-all_the_args(1, 2, a=3, b=4) imprime:
- (1, 2)
- {"a": 3, "b": 4}
-"""
-
-# Quando chamar funções, você pode fazer o oposto de args/kwargs!
-# Use * para expandir tuplas e use ** para expandir dicionários!
-args = (1, 2, 3, 4)
-kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # equivalente a foo(1, 2, 3, 4)
-all_the_args(**kwargs) # equivalente a foo(a=3, b=4)
-all_the_args(*args, **kwargs) # equivalente a foo(1, 2, 3, 4, a=3, b=4)
-
-# Retornando múltiplos valores (com atribuição de tuplas)
-def swap(x, y):
- return y, x # Retorna múltiplos valores como uma tupla sem os parêntesis.
- # (Observação: os parêntesis foram excluídos mas podem estar
- # presentes)
-
-x = 1
-y = 2
-x, y = swap(x, y) # => x = 2, y = 1
-# (x, y) = swap(x,y) # Novamente, os parêntesis foram excluídos mas podem estar presentes.
-
-# Escopo de função
-x = 5
-
-def setX(num):
- # A variável local x não é a mesma variável global x
- x = num # => 43
- print (x) # => 43
-
-def setGlobalX(num):
- global x
- print (x) # => 5
- x = num # variável global x agora é 6
- print (x) # => 6
-
-setX(43)
-setGlobalX(6)
-
-
-# Python tem funções de primeira classe
-def create_adder(x):
- def adder(y):
- return x + y
- return adder
-
-add_10 = create_adder(10)
-add_10(3) # => 13
-
-# Também existem as funções anônimas
-(lambda x: x > 2)(3) # => True
-(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
-
-# TODO - Fix for iterables
-# Existem funções internas de alta ordem
-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]
-
-# Nós podemos usar compreensão de lista para interessantes mapas e filtros
-# Compreensão de lista armazena a saída como uma lista que pode ser uma lista
-# aninhada
-[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
-[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
-
-####################################################
-## 5. Classes
-####################################################
-
-
-# Nós usamos o operador "class" para ter uma classe
-class Human:
-
- # Um atributo de classe. Ele é compartilhado por todas as instâncias dessa
- # classe.
- species = "H. sapiens"
-
- # Construtor básico, é chamado quando esta classe é instanciada.
- # Note que dois sublinhados no início e no final de uma identificados
- # significa objetos ou atributos que são usados pelo python mas vivem em
- # um namespace controlado pelo usuário. Métodos (ou objetos ou atributos)
- # como: __init__, __str__, __repr__, etc. são chamados métodos mágicos (ou
- # algumas vezes chamados métodos dunder - "double underscore")
- # Você não deve usar nomes assim por sua vontade.
- def __init__(self, name):
- @ Atribui o argumento ao atributo da instância
- self.name = name
-
- # Um método de instância. Todos os métodos tem "self" como primeiro
- # argumento
- def say(self, msg):
- return "{name}: {message}".format(name=self.name, message=msg)
-
- # Um método de classe é compartilhado por todas as instâncias
- # Eles são chamados com a classe requisitante como primeiro argumento
- @classmethod
- def get_species(cls):
- return cls.species
-
- # Um método estático é chamado sem uma referência a classe ou instância
- @staticmethod
- def grunt():
- return "*grunt*"
-
-
-# Instancie uma classe
-i = Human(name="Ian")
-print(i.say("oi")) # imprime "Ian: oi"
-
-j = Human("Joel")
-print(j.say("olá")) # imprime "Joel: olá"
-
-# Chama nosso método de classe
-i.get_species() # => "H. sapiens"
-
-# Altera um atributo compartilhado
-Human.species = "H. neanderthalensis"
-i.get_species() # => "H. neanderthalensis"
-j.get_species() # => "H. neanderthalensis"
-
-# Chama o método estático
-Human.grunt() # => "*grunt*"
-
-
-####################################################
-## 6. Módulos
-####################################################
-
-# Você pode importar módulos
-import math
-print(math.sqrt(16)) # => 4
-
-# Você pode importar apenas funções específicas de um módulo
-from math import ceil, floor
-print(ceil(3.7)) # => 4.0
-print(floor(3.7)) # => 3.0
-
-# Você pode importar todas as funções de um módulo para o namespace atual
-# Atenção: isso não é recomendado
-from math import *
-
-# Você pode encurtar o nome dos módulos
-import math as m
-math.sqrt(16) == m.sqrt(16) # => True
-
-# Módulos python são apenas arquivos python comuns. Você
-# pode escrever os seus, e importá-los. O nome do
-# módulo é o mesmo nome do arquivo.
-
-# Você pode procurar que atributos e funções definem um módulo.
-import math
-dir(math)
-
-
-####################################################
-## 7. Avançado
-####################################################
-
-# Geradores podem ajudar você a escrever código "preguiçoso"
-def double_numbers(iterable):
- for i in iterable:
- yield i + i
-
-# Um gerador cria valores conforme necessário.
-# Ao invés de gerar e retornar todos os valores de uma só vez ele cria um em
-# cada interação. Isto significa que valores maiores que 15 não serão
-# processados em double_numbers.
-# Nós usamos um sublinhado ao final do nome das variáveis quando queremos usar
-# um nome que normalmente colide com uma palavra reservada do python.
-range_ = range(1, 900000000)
-# Multiplica por 2 todos os números até encontrar um resultado >= 30
-for i in double_numbers(range_):
- print(i)
- if i >= 30:
- break
-
-
-# Decoradores
-# Neste exemplo beg encapsula say
-# beg irá chamar say. Se say_please é verdade então ele irá mudar a mensagem
-# retornada
-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, "Por favor! Eu sou pobre :(")
- return msg
-
- return wrapper
-
-
-@beg
-def say(say_please=False):
- msg = "Você me paga uma cerveja?"
- return msg, say_please
-
-
-print(say()) # Você me paga uma cerveja?
-print(say(say_please=True)) # Você me paga uma cerveja? Por favor! Eu sou pobre :(
-```
-
-## Pronto para mais?
-
-### Free Online
-
-* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
-* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
-* [Dive Into Python](http://www.diveintopython.net/)
-* [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/)
-* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
-* [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/)
-
-### Dead Tree
-
-* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
-* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
-* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
diff --git a/pt-br/pythonlegacy-pt.html.markdown b/pt-br/pythonlegacy-pt.html.markdown
new file mode 100644
index 00000000..572bb787
--- /dev/null
+++ b/pt-br/pythonlegacy-pt.html.markdown
@@ -0,0 +1,509 @@
+---
+language: Python 2 (legacy)
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+translators:
+ - ["Vilson Vieira", "http://automata.cc"]
+lang: pt-br
+filename: learnpythonlegacy-pt.py
+---
+
+Python foi criado por Guido Van Rossum no começo dos anos 90. Atualmente é uma
+das linguagens de programação mais populares. Eu me apaixonei por Python, por
+sua clareza de sintaxe. É basicamente pseudocódigo executável.
+
+Comentários serão muito apreciados! Você pode me contactar em
+[@louiedinh](http://twitter.com/louiedinh) ou louiedinh [arroba]
+[serviço de email do google]
+
+Nota: Este artigo usa Python 2.7 especificamente, mas deveria ser aplicável a
+qualquer Python 2.x. Logo haverá uma versão abordando Python 3!
+
+```python
+# Comentários de uma linha começam com cerquilha (ou sustenido)
+""" Strings de várias linhas podem ser escritas
+ usando três ", e são comumente usadas
+ como comentários
+"""
+
+####################################################
+## 1. Tipos de dados primitivos e operadores
+####################################################
+
+# Você usa números normalmente
+3 #=> 3
+
+# Operadores matemáticos são aqueles que você já está acostumado
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# A divisão é um pouco estranha. A divisão de números inteiros arredonda
+# para baixo o resultado, automaticamente
+5 / 2 #=> 2
+
+# Para concertar a divisão, precisamos aprender sobre números de ponto
+# flutuante (conhecidos como 'float').
+2.0 # Isso é um 'float'
+11.0 / 4.0 #=> 2.75 ahhh... muito melhor
+
+# Forçamos a precedência de operadores usando parênteses
+(1 + 3) * 2 #=> 8
+
+# Valores booleanos (ou 'boolean') são também tipos primitivos
+True
+False
+
+# Negamos usando 'not'
+not True #=> False
+not False #=> True
+
+# Testamos igualdade usando '=='
+1 == 1 #=> True
+2 == 1 #=> False
+
+# E desigualdade com '!='
+1 != 1 #=> False
+2 != 1 #=> True
+
+# Mais comparações
+1 < 10 #=> True
+1 > 10 #=> False
+2 <= 2 #=> True
+2 >= 2 #=> True
+
+# As comparações podem ser encadeadas!
+1 < 2 < 3 #=> True
+2 < 3 < 2 #=> False
+
+# Strings são criadas com " ou '
+"Isso é uma string."
+'Isso também é uma string.'
+
+# Strings podem ser somadas (ou melhor, concatenadas)!
+"Olá " + "mundo!" #=> "Olá mundo!"
+
+# Uma string pode ser tratada como uma lista de caracteres
+"Esta é uma string"[0] #=> 'E'
+
+# O caractere % pode ser usado para formatar strings, desta forma:
+"%s podem ser %s" % ("strings", "interpoladas")
+
+# Um jeito novo de formatar strings é usando o método 'format'.
+# Esse método é o jeito mais usado
+"{0} podem ser {1}".format("strings", "formatadas")
+# Você pode usar palavras-chave (ou 'keywords') se você não quiser contar.
+"{nome} quer comer {comida}".format(nome="João", comida="lasanha")
+
+# 'None' é um objeto
+None #=> None
+
+# Não use o operador de igualdade `==` para comparar objetos com 'None'
+# Ao invés disso, use `is`
+"etc" is None #=> False
+None is None #=> True
+
+# O operador 'is' teste a identidade de um objeto. Isso não é
+# muito útil quando estamos lidando com valores primitivos, mas é
+# muito útil quando lidamos com objetos.
+
+# None, 0, e strings/listas vazias são todas interpretadas como 'False'.
+# Todos os outros valores são 'True'
+0 == False #=> True
+"" == False #=> True
+
+
+####################################################
+## 2. Variáveis e Coleções
+####################################################
+
+# Imprimir na tela é muito fácil
+print "Eu sou o Python. Prazer em te conhecer!"
+
+
+# Nós não precisamos declarar variáveis antes de usá-las, basta usar!
+alguma_variavel = 5 # A convenção é usar caixa_baixa_com_sobrescritos
+alguma_variavel #=> 5
+
+# Acessar uma variável que não teve nenhum valor atribuído anteriormente é
+# uma exceção.
+# Veja a seção 'Controle' para aprender mais sobre tratamento de exceção.
+outra_variavel # Gera uma exceção de erro de nome
+
+# 'if' pode ser usado como uma expressão
+"uepa!" if 3 > 2 else 2 #=> "uepa!"
+
+# Listas armazenam sequências de elementos
+lista = []
+# Você pode inicializar uma lista com valores
+outra_lista = [4, 5, 6]
+
+# Adicione elementos no final da lista usando 'append'
+lista.append(1) # lista é agora [1]
+lista.append(2) # lista é agora [1, 2]
+lista.append(4) # lista é agora [1, 2, 4]
+lista.append(3) # lista é agora [1, 2, 4, 3]
+# Remova elementos do fim da lista usando 'pop'
+lista.pop() #=> 3 e lista é agora [1, 2, 4]
+# Vamos adicionar o elemento novamente
+lista.append(3) # lista agora é [1, 2, 4, 3] novamente.
+
+# Acesse elementos de uma lista através de seu índices
+lista[0] #=> 1
+# Acesse o último elemento com índice negativo!
+lista[-1] #=> 3
+
+# Tentar acessar um elemento fora dos limites da lista gera uma exceção
+# do tipo 'IndexError'
+lista[4] # Gera uma exceção 'IndexError'
+
+# Você pode acessar vários elementos ao mesmo tempo usando a sintaxe de
+# limites
+# (Para quem gosta de matemática, isso é um limite fechado/aberto)
+lista[1:3] #=> [2, 4]
+# Você pode omitir o fim se quiser os elementos até o final da lista
+lista[2:] #=> [4, 3]
+# O mesmo para o início
+lista[:3] #=> [1, 2, 4]
+
+# Remova um elemento qualquer de uma lista usando 'del'
+del lista[2] # lista agora é [1, 2, 3]
+
+# Você pode somar listas (obs: as listas originais não são modificadas)
+lista + outra_lista #=> [1, 2, 3, 4, 5, 6]
+
+# Você também pode concatenar usando o método 'extend' (lista será modificada!)
+lista.extend(outra_lista) # Agora lista é [1, 2, 3, 4, 5, 6]
+
+# Para checar se um elemento pertence a uma lista, use 'in'
+1 in lista #=> True
+
+# Saiba quantos elementos uma lista possui com 'len'
+len(lista) #=> 6
+
+
+# Tuplas são iguais a listas, mas são imutáveis
+tup = (1, 2, 3)
+tup[0] #=> 1
+tup[0] = 3 # Isso gera uma exceção do tipo TypeError
+
+# Você pode fazer nas tuplas todas aquelas coisas fez com a lista
+len(tup) #=> 3
+tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
+tup[:2] #=> (1, 2)
+2 in tup #=> True
+
+# Você pode 'desempacotar' tuplas (ou listas) em variáveis, associando cada
+# elemento da tupla/lista a uma variável correspondente
+a, b, c = (1, 2, 3) # a agora é 1, b agora é 2, c agora é 3
+# Tuplas são criadas por padrão, mesmo se você não usar parênteses
+d, e, f = 4, 5, 6
+# Sabendo disso, veja só como é fácil trocar os valores de duas variáveis!
+e, d = d, e # d agora é 5, e agora é 4
+
+
+# Dicionários armazenam 'mapeamentos' (do tipo chave-valor)
+dicionario_vazio = {}
+# Aqui criamos um dicionário já contendo valores
+dicionario = {"um": 1, "dois": 2, "três": 3}
+
+# Acesse valores usando []
+dicionario["um"] #=> 1
+
+# Retorna uma lista com todas as chaves do dicionário
+dicionario.keys() #=> ["três", "dois", "um"]
+# Nota: A ordem das chaves não é garantida.
+# O resultado no seu interpretador não necessariamente será igual a esse.
+
+# Retorna uma lista com todos os valores do dicionário
+dicionario.values() #=> [3, 2, 1]
+# Nota: A mesma nota acima sobre a ordenação é válida aqui.
+
+# Veja se uma chave qualquer está em um dicionário usando 'in'
+"um" in dicionario #=> True
+1 in dicionario #=> False
+
+# Tentar acessar uma chave que não existe gera uma exceção do tipo 'KeyError'
+dicionario["quatro"] # Gera uma exceção KeyError
+
+# Você pode usar o método 'get' para evitar gerar a exceção 'KeyError'.
+# Ao invés de gerar essa exceção, irá retornar 'None' se a chave não existir.
+dicionario.get("um") #=> 1
+dicionario.get("quatro") #=> None
+# O método 'get' suporta um argumento que diz qual valor deverá ser
+# retornado se a chave não existir (ao invés de 'None').
+dicionario.get("um", 4) #=> 1
+dicionario.get("quatro", 4) #=> 4
+
+# O método 'setdefault' é um jeito seguro de adicionar um novo par
+# chave-valor a um dicionário, associando um valor padrão imutável à uma chave
+dicionario.setdefault("cinco", 5) # dicionario["cinco"] é definido como 5
+dicionario.setdefault("cinco", 6) # dicionario["cinco"] ainda é igual a 5
+
+
+# Conjuntos (ou sets) armazenam ... bem, conjuntos
+# Nota: lembre-se que conjuntos não admitem elementos repetidos!
+conjunto_vazio = set()
+# Podemos inicializar um conjunto com valores
+conjunto = set([1, 2, 2, 3, 4]) # conjunto é set([1, 2, 3, 4]), sem repetição!
+
+# Desde o Python 2.7, {} pode ser usado para declarar um conjunto
+conjunto = {1, 2, 2, 3, 4} # => {1 2 3 4}
+
+# Adicione mais ítens a um conjunto com 'add'
+conjunto.add(5) # conjunto agora é {1, 2, 3, 4, 5}
+
+# Calcule a intersecção de dois conjuntos com &
+outro_conj = {3, 4, 5, 6}
+conjunto & outro_conj #=> {3, 4, 5}
+
+# Calcule a união de dois conjuntos com |
+conjunto | outro_conj #=> {1, 2, 3, 4, 5, 6}
+
+# E a diferença entre dois conjuntos com -
+{1,2,3,4} - {2,3,5} #=> {1, 4}
+
+# Veja se um elemento existe em um conjunto usando 'in'
+2 in conjunto #=> True
+10 in conjunto #=> False
+
+
+####################################################
+## 3. Controle
+####################################################
+
+# Para começar, vamos apenas criar uma variável
+alguma_var = 5
+
+# Aqui está uma expressão 'if'. Veja como a identação é importante em Python!
+# Esses comandos irão imprimir "alguma_var é menor que 10"
+if alguma_var > 10:
+ print "some_var é maior que 10."
+elif some_var < 10: # Esse 'elif' é opcional
+ print "some_var é menor que 10."
+else: # Esse 'else' também é opcional
+ print "some_var é igual a 10."
+
+
+"""
+Laços (ou loops) 'for' iteram em listas.
+Irá imprimir:
+ cachorro é um mamífero
+ gato é um mamífero
+ rato é um mamífero
+"""
+for animal in ["cachorro", "gato", "rato"]:
+ # Você pode usar % para interpolar strings formatadas
+ print "%s é um mamífero" % animal
+
+"""
+A função `range(um número)` retorna uma lista de números
+do zero até o número dado.
+Irá imprimir:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+Laços 'while' executam enquanto uma condição dada for verdadeira.
+Irá imprimir:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # Isso é um atalho para a expressão x = x + 1
+
+# Tratamos excessões usando o bloco try/except
+# Funciona em Python 2.6 e versões superiores:
+
+try:
+ # Use 'raise' para gerar um erro
+ raise IndexError("Isso é um erro de índice")
+except IndexError as e:
+ pass # Pass é um operador que não faz nada, deixa passar.
+ # Usualmente você iria tratar a exceção aqui...
+
+
+####################################################
+## 4. Funções
+####################################################
+
+# Use 'def' para definir novas funções
+def soma(x, y):
+ print "x é %s e y é %s" % (x, y)
+ return x + y # Retorne valores usando 'return'
+
+# Chamando funções com parâmetros
+soma(5, 6) #=> imprime "x é 5 e y é 6" e retorna o valor 11
+
+# Um outro jeito de chamar funções é especificando explicitamente os valores
+# de cada parâmetro com chaves
+soma(y=6, x=5) # Argumentos com chaves podem vir em qualquer ordem.
+
+# Você pode definir funções que recebem um número qualquer de argumentos
+# (respeitando a sua ordem)
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) #=> (1,2,3)
+
+
+# Você também pode definir funções que recebem um número qualquer de argumentos
+# com chaves
+def args_com_chaves(**ch_args):
+ return ch_args
+
+# Vamos chamar essa função para ver o que acontece
+args_com_chaves(pe="grande", lago="Ness") #=> {"pe": "grande", "lago": "Ness"}
+
+# Você pode fazer as duas coisas ao mesmo tempo, se desejar
+def todos_args(*args, **ch_wargs):
+ print args
+ print ch_args
+"""
+todos_args(1, 2, a=3, b=4) imprime:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Quando você chamar funções, pode fazer o oposto do que fizemos até agora!
+# Podemos usar * para expandir tuplas de argumentos e ** para expandir
+# dicionários de argumentos com chave.
+args = (1, 2, 3, 4)
+ch_args = {"a": 3, "b": 4}
+todos_args(*args) # equivalente a todos_args(1, 2, 3, 4)
+todos_args(**ch_args) # equivalente a todos_args(a=3, b=4)
+todos_args(*args, **ch_args) # equivalente a todos_args(1, 2, 3, 4, a=3, b=4)
+
+# Em Python, funções são elementos de primeira ordem (são como objetos,
+# strings ou números)
+def cria_somador(x):
+ def somador(y):
+ return x + y
+ return somador
+
+soma_10 = cria_somador(10)
+soma_10(3) #=> 13
+
+# Desta forma, existem também funções anônimas
+(lambda x: x > 2)(3) #=> True
+
+# E existem funções de alta ordem por padrão
+map(soma_10, [1,2,3]) #=> [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+reduce(lambda x, y: x + y, [3, 4, 5, 6, 7]) #=> 25
+
+# Nós podemos usar compreensão de listas para mapear e filtrar também
+[soma_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
+
+####################################################
+## 5. Classes
+####################################################
+
+# Para criar uma nova classe, devemos herdar de 'object'
+class Humano(object):
+
+ # Um atributo de classe. Ele é compartilhado por todas as instâncias dessa
+ # classe
+ especie = "H. sapiens"
+
+ # Definimos um inicializador básico
+ def __init__(self, nome):
+ # Atribui o valor de argumento dado a um atributo da instância
+ self.nome = nome
+
+ # Um método de instância. Todos os métodos levam 'self' como primeiro
+ # argumento
+ def diga(self, msg):
+ return "%s: %s" % (self.nome, msg)
+
+ # Um método de classe é compartilhado por todas as instâncias
+ # Eles são chamados passando o nome da classe como primeiro argumento
+ @classmethod
+ def get_especie(cls):
+ return cls.especie
+
+ # Um método estático é chamado sem uma referência a classe ou instância
+ @staticmethod
+ def ronca():
+ return "*arrrrrrr*"
+
+
+# Instancie uma classe
+i = Humano(nome="Ivone")
+print i.diga("oi") # imprime "Ivone: oi"
+
+j = Human("Joel")
+print j.say("olá") #prints out "Joel: olá"
+
+# Chame nosso método de classe
+i.get_especie() #=> "H. sapiens"
+
+# Modifique um atributo compartilhado
+Humano.especie = "H. neanderthalensis"
+i.get_especie() #=> "H. neanderthalensis"
+j.get_especie() #=> "H. neanderthalensis"
+
+# Chame o método estático
+Humano.ronca() #=> "*arrrrrrr*"
+
+
+####################################################
+## 6. Módulos
+####################################################
+
+# Você pode importar módulos
+import math
+print math.sqrt(16) #=> 4.0
+
+# Você pode importar funções específicas de um módulo
+from math import ceil, floor
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
+
+# Você também pode importar todas as funções de um módulo
+# Atenção: isso não é recomendado!
+from math import *
+
+# Você pode usar apelidos para os módulos, encurtando seus nomes
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
+
+# Módulos em Python são apenas arquivos Python. Você
+# pode escrever o seu próprio módulo e importá-lo. O nome do
+# módulo será o mesmo que o nome do arquivo.
+
+# Você pode descobrir quais funções e atributos
+# estão definidos em um módulo qualquer.
+import math
+dir(math)
+
+
+```
+
+## Pronto para mais?
+
+### Online e gratuito
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+
+### Livros impressos
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+
diff --git a/pt-br/qt-pt.html.markdown b/pt-br/qt-pt.html.markdown
new file mode 100644
index 00000000..99579c35
--- /dev/null
+++ b/pt-br/qt-pt.html.markdown
@@ -0,0 +1,174 @@
+---
+category: tool
+tool: Qt Framework
+language: c++
+filename: learnqt-pt.cpp
+contributors:
+ - ["Aleksey Kholovchuk", "https://github.com/vortexxx192"]
+translators:
+ - ["Lucas Pugliesi", "https://github.com/fplucas"]
+lang: pt-br
+---
+
+**Qt** é amplamente conhecido como um framework para desenvolvimento de
+software multi-plataforma que pode rodar em vários outras plataformas de
+softwares e hardwares com pouca ou nenhuma alteração no código, enquanto mantém
+o poder e a velocidade de uma aplicação nativa. Embora o **Qt** tenha sido
+originalmente escrito em *C++*, é possível utilizá-lo em outras linguagens:
+*[PyQt](https://learnxinyminutes.com/docs/pyqt/)*, *QtRuby*, *PHP-Qt*, etc.
+
+**Qt** é ótimo para criar aplicações com interface gráfica (GUI). Esse tutorial
+será feito em *C++*.
+
+```c++
+/*
+ * Vamos começar
+ */
+
+// Todos as dependências do framework Qt iniciam com a letra 'Q' maiúscula
+#include <QApplication>
+#include <QLineEdit>
+
+int main(int argc, char *argv[]) {
+ // Cria um objeto para utilizar todos os recursos da aplicação
+ QApplication app(argc, argv);
+
+ // Cria um widget com linha editável e exibe na tela
+ QLineEdit lineEdit("Hello world!");
+ lineEdit.show();
+
+ // Inicia a aplicação em um evento de loop
+ return app.exec();
+}
+```
+
+A parte gráfica do **Qt** é toda composta de *widgets* e *conexões* entre eles.
+
+[LEIA MAIS SOBRE WIDGETS](http://doc.qt.io/qt-5/qtwidgets-index.html)
+
+```c++
+/*
+ * Vamos criar um label e um botão.
+ * Um label irá aparecer quando o botão for clicado
+ *
+ * O próprio código do Qt é autoexplicativo.
+ */
+
+#include <QApplication>
+#include <QDialog>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QLabel>
+
+int main(int argc, char *argv[]) {
+ QApplication app(argc, argv);
+
+ QDialog dialogWindow;
+ dialogWindow.show();
+
+ // Adiciona um layout vertical
+ QVBoxLayout layout;
+ dialogWindow.setLayout(&layout);
+
+ QLabel textLabel("Thanks for pressing that button");
+ layout.addWidget(&textLabel);
+ textLabel.hide();
+
+ QPushButton button("Press me");
+ layout.addWidget(&button);
+
+ // Exibe o label oculto quando o botão é clicado
+ QObject::connect(&button, &QPushButton::pressed,
+ &textLabel, &QLabel::show);
+
+ return app.exec();
+}
+```
+
+Veja o *QObject::connect*. O método é usado para conectar o *SINAL* de um objeto
+ao *ENCAIXE* outro.
+
+**Sinais** são emitidos quando algo ocorre com o objeto, como quando o sinal de
+*clique* é acionado apertando o QPushButton.
+
+**Encaixes** são *ações* que são executadas em resposta aos sinais recebidos.
+
+[LEIA MAIS SOBRE SINAIS E ENCAIXES](http://doc.qt.io/qt-5/signalsandslots.html)
+
+
+A seguir vamos aprender como usar não somente o comportamento padrão dos
+widgets, mas também extender seus comportamentos usando herança. Vamos criar um
+botão e contar quantas vezes é pressionado. Para esse propósito definiremos
+nossa própria classe *CounterLabel*. Ela deve ser declarada em um arquivo
+diferente devido a estrutura específica do Qt.
+
+```c++
+// counterlabel.hpp
+
+#ifndef COUNTERLABEL
+#define COUNTERLABEL
+
+#include <QLabel>
+
+class CounterLabel : public QLabel {
+ Q_OBJECT // Define os macros presente em todo objeto Qt
+
+public:
+ CounterLabel() : counter(0) {
+ setText("Counter has not been increased yet"); // método do QLabel
+ }
+
+public slots:
+ // Ação que será chamada em resposta ao clique do botão
+ void increaseCounter() {
+ setText(QString("Counter value: %1").arg(QString::number(++counter)));
+ }
+
+private:
+ int counter;
+};
+
+#endif // COUNTERLABEL
+```
+
+```c++
+// main.cpp
+// Quase igual ao exemplo anterior
+
+#include <QApplication>
+#include <QDialog>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QString>
+#include "counterlabel.hpp"
+
+int main(int argc, char *argv[]) {
+ QApplication app(argc, argv);
+
+ QDialog dialogWindow;
+ dialogWindow.show();
+
+ QVBoxLayout layout;
+ dialogWindow.setLayout(&layout);
+
+ CounterLabel counterLabel;
+ layout.addWidget(&counterLabel);
+
+ QPushButton button("Push me once more");
+ layout.addWidget(&button);
+ QObject::connect(&button, &QPushButton::pressed,
+ &counterLabel, &CounterLabel::increaseCounter);
+
+ return app.exec();
+}
+```
+
+É isso! Claro, o framework Qt é muito maior do que exemplificamos no tutorial,
+então esteja preparado para ler e praticar mais.
+
+## Leitura complementar
+
+- [Tutoriais Qt 4.8](http://doc.qt.io/qt-4.8/tutorials.html)
+- [Tutoriais Qt 5](http://doc.qt.io/qt-5/qtexamplesandtutorials.html)
+
+Boa sorte e divirta-se!
diff --git a/pt-br/ruby-pt.html.markdown b/pt-br/ruby-pt.html.markdown
index 1078f6c5..7ae28ac2 100644
--- a/pt-br/ruby-pt.html.markdown
+++ b/pt-br/ruby-pt.html.markdown
@@ -71,7 +71,7 @@ false.class #=> FalseClass
2 <= 2 #=> true
2 >= 2 #=> true
-# Strings são objects
+# Strings são objetos
'Eu sou uma string'.class #=> String
"Eu também sou uma string".class #=> String
diff --git a/rust-pt.html.markdown b/pt-br/rust-pt.html.markdown
index 79f69269..b2bab214 100644
--- a/rust-pt.html.markdown
+++ b/pt-br/rust-pt.html.markdown
@@ -3,15 +3,15 @@ language: rust
filename: rust-pt.rs
contributors:
- ["Paulo Henrique Rodrigues Pinheiro", "https://about.me/paulohrpinheiro"]
-filename: learnrust.rs
lang: pt-br
+
---
Rust é uma linguagem de programação desenvolvida pelo Mozilla Research. Rust
combina controle de baixo nível sobre o desempenho com facilidades de alto
nível e garantias de segurança.
-Ele atinge esse objetico sem necessitar de um coletor de lixo ou um processo
+Ele atinge esse objetivo sem necessitar de um coletor de lixo ou um processo
*runtime*, permitindo que se use bibliotecas Rust em substituição a bibliotecas
em C.
@@ -27,7 +27,7 @@ noite. Rust adotou um modelo de versões *train-based* com novas versões
regularmente liberadas a cada seis semanas. A versão 1.1 beta de Rust foi
disponibilizada ao mesmo tempo que a versão 1.0.
-Apesar de Rust ser uma linguagem mais e baixo nível, Rust tem alguns conceitos
+Apesar de Rust ser uma linguagem mais de baixo nível, Rust tem alguns conceitos
funcionais geralmente encontradas em linguagens de alto nível. Isso faz Rust
não apenas rápido, mas também fácil e eficiente para programar.
@@ -68,7 +68,7 @@ fn main() {
// Em geral, o compilador Rust consegue inferir qual o tipo de uma
// variável, então você não tem que escrever uma anotação explícita de tipo.
// Ao longo desse tutorial, os tipos serão explicitamente anotados em
- // muitos lugares, mas apenas com propóstico demonstrativo. A inferência de
+ // muitos lugares, mas apenas com propósito demonstrativo. A inferência de
// tipos pode gerenciar isso na maioria das vezes.
let implicit_x = 1;
let implicit_f = 1.3;
diff --git a/pt-br/sass-pt.html.markdown b/pt-br/sass-pt.html.markdown
index 3d91f1ca..28df3c59 100644
--- a/pt-br/sass-pt.html.markdown
+++ b/pt-br/sass-pt.html.markdown
@@ -56,19 +56,19 @@ body {
}
-/ * Este é muito mais fácil de manter do que ter de mudar a cor
-cada vez que aparece em toda a sua folha de estilo. * /
+/* Este é muito mais fácil de manter do que ter de mudar a cor
+cada vez que aparece em toda a sua folha de estilo. */
-/*Mixins
+/* Mixins
==============================*/
-/* Se você achar que você está escrevendo o mesmo código para mais de um
-elemento, você pode querer armazenar esse código em um mixin.
+/* Se você achar que está escrevendo o mesmo código para mais de um
+elemento, você pode armazenar esse código em um mixin.
Use a diretiva '@mixin', além de um nome para o seu mixin. */
@@ -87,7 +87,7 @@ div {
background-color: $primary-color;
}
-/* Apoś compilar ficaria assim: */
+/* Após compilar ficaria assim: */
div {
display: block;
margin-left: auto;
@@ -128,7 +128,7 @@ div {
-/*Funções
+/* Funções
==============================*/
@@ -138,6 +138,7 @@ div {
/* Funções pode ser chamado usando seu nome e passando o
    argumentos necessários */
+
body {
width: round(10.25px);
}
@@ -156,14 +157,14 @@ body {
background-color: rgba(0, 0, 0, 0.75);
}
-/* Você também pode definir suas próprias funções. As funções são muito semelhantes aos
-   mixins. Ao tentar escolher entre uma função ou um mixin, lembre-
-   que mixins são os melhores para gerar CSS enquanto as funções são melhores para
-   lógica que pode ser usado em todo o seu código Sass. Os exemplos
-   seção Operadores Math 'são candidatos ideais para se tornar um reutilizável
-   função. */
+/* Você também pode definir suas próprias funções. As funções são muito semelhantes
+ aos mixins. Ao tentar escolher entre uma função ou um mixin, lembre
+ que mixins são os melhores para gerar CSS enquanto as funções são melhores para
+ lógica que pode ser usado em todo o seu código Sass. Os exemplos na
+ seção "Operações Math" são candidatos ideais para se tornar um função
+ reutilizável. */
-/* Esta função terá um tamanho de destino eo tamanho do pai e calcular
+/* Esta função terá um tamanho de destino e o tamanho do pai (parent), calcular
   e voltar a percentagem */
@function calculate-percentage($target-size, $parent-size) {
@@ -220,21 +221,21 @@ $main-content: calculate-percentage(600px, 960px);
border-color: #22df56;
}
-/* Ampliando uma declaração CSS é preferível a criação de um mixin
-   por causa da maneira agrupa as classes que todos compartilham
+/* Ao ampliar uma declaração CSS é preferível a criação de um mixin,
+   por causa da maneira em que agrupa as classes com todos que compartilham
   o mesmo estilo base. Se isso for feito com um mixin, a largura,
   altura, e a borda seria duplicado para cada instrução que
   o chamado mixin. Enquanto isso não irá afetar o seu fluxo de trabalho, será
-   adicionar inchaço desnecessário para os arquivos criados pelo compilador Sass. */
+   adicionado inchaço desnecessário para os arquivos criados pelo compilador Sass. */
-/*Assentamento
+/* Assentamento
==============================*/
-/ * Sass permite seletores ninhos dentro seletores * /
+/* Sass permite seletores ninhos dentro seletores */
ul {
list-style-type: none;
@@ -245,7 +246,7 @@ ul {
}
}
-/* '&' será substituído pelo selector pai. */
+/* '&' será substituído pelo selector pai (parent). */
/* Você também pode aninhar pseudo-classes. */
/* Tenha em mente que o excesso de nidificação vai fazer seu código menos sustentável.
Essas práticas também recomendam não vai mais de 3 níveis de profundidade quando nidificação.
@@ -290,7 +291,7 @@ ul li a {
-/*Parciais e Importações
+/* Parciais e Importações
==============================*/
@@ -313,7 +314,7 @@ ol {
/* Sass oferece @import que pode ser usado para importar parciais em um arquivo.
   Isso difere da declaração CSS @import tradicional, que faz
   outra solicitação HTTP para buscar o arquivo importado. Sass converte os
-   importadas arquivo e combina com o código compilado. */
+   arquivo importados e combina com o código compilado. */
@import 'reset';
@@ -322,7 +323,7 @@ body {
font-family: Helvetica, Arial, Sans-serif;
}
-/* Compiles to: */
+/* Compila para: */
html, body, ul, ol {
margin: 0;
@@ -336,14 +337,14 @@ body {
-/*Placeholder Selectors
+/* Placeholder Selectors
==============================*/
-/* Os espaços reservados são úteis na criação de uma declaração CSS para ampliar. Se você
-   queria criar uma instrução CSS que foi usado exclusivamente com @extend,
-   Você pode fazer isso usando um espaço reservado. Espaços reservados começar com um '%' em vez
-   de '.' ou '#'. Espaços reservados não aparece no CSS compilado. * /
+/* Os Placeholders são úteis na criação de uma declaração CSS para ampliar. Se você
+   deseja criar uma instrução CSS que foi usado exclusivamente com @extend,
+   você pode fazer isso usando um Placeholder. Placeholder começar com um '%' em vez
+   de '.' ou '#'. Placeholder não aparece no CSS compilado. */
%content-window {
font-size: 14px;
@@ -372,14 +373,14 @@ body {
-/*Operações Math
-============================== * /
+/* Operações Math
+============================== */
/* Sass fornece os seguintes operadores: +, -, *, /, e %. estes podem
-   ser úteis para calcular os valores diretamente no seu Sass arquivos em vez
-   de usar valores que você já calculados pela mão. Abaixo está um exemplo
-   de uma criação de um projeto simples de duas colunas. * /
+   ser úteis para calcular os valores diretamente no seu arquivos Sass em vez
+ de usar valores que você já calculados manualmente. O exemplo abaixo é
+ de um projeto simples de duas colunas. */
$content-area: 960px;
$main-content: 600px;
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/pt-br/self-pt.html.markdown b/pt-br/self-pt.html.markdown
index 2fb2953b..eb821474 100644
--- a/pt-br/self-pt.html.markdown
+++ b/pt-br/self-pt.html.markdown
@@ -147,7 +147,7 @@ o objeto '10' no slot 'x' e retornará o objeto original"
# Protótipos
-Não existem classes em Self. A maneira de obter um objeto é encontrar um protótipo e copia-lo.
+Não existem classes em Self. A maneira de obter um objeto é encontrar um protótipo e copiá-lo.
```
| d |
diff --git a/pt-br/solidity-pt.html.markdown b/pt-br/solidity-pt.html.markdown
new file mode 100644
index 00000000..d4555fa7
--- /dev/null
+++ b/pt-br/solidity-pt.html.markdown
@@ -0,0 +1,914 @@
+---
+language: Solidity
+filename: learnSolidity-br.sol
+contributors:
+ - ["Nemil Dalal", "https://www.nemil.com"]
+ - ["Joseph Chow", ""]
+translators:
+ - ["João Farias", "http://thatsabug.com/"]
+lang: pt-br
+---
+
+Solidity permite você programar para a [Ethereum]
+(https://www.ethereum.org/), uma máquina virtual baseada na tecnologia blockhain
+para criação e execução de contratos inteligentes, sem necessidade de partes
+centralizadas ou de confiança.
+
+Solidity é uma linguagem de contratos estaticamente tipaada com similaridade com
+Javascript e C. Como objetos em programação orientada a objetos, cada contrato
+possue variáveis de estado, funções e tipos de dados comuns. Funcionalidades
+particulares de contratados incluem cláusuras modificadoras (guarda), notifica
+dores de eventos para listerners e variáveis globais customizadas.
+
+
+Exemplos de contratos Ethereum incluem crowdfunding, votações e audições cegas.
+
+Erros em código Solidity causam grandes riscos e custos; portanto, você
+deve ser muito cuidado com teste e divulgação. DEVIDO ÀS CONSTANTES MUDANÇAS
+NO ETHEREUM, ESTE DOCUMENTOS PROVAVELMENTE NÃO ESTARÁ ATUALIZADO, VOCÊ DEVE
+ACOMPANHAR A CHATROOM DO SOLIDITY E O BLOG DO ETHEREUM PARA NOTÍCIAS ATUALIZADAS.
+TODO CÓDIGO AQUI É ENTREGUE COMO ESTÁ, COM SUBSTANCIAL RISCO DE ERRROS E PADRÕES
+DE CÓDIGO DEPRECADOS.
+
+Diferentemente de outros tipo de código, você também deve adicionar padrões
+como pausa, deprecação e retração para reduzir riscos. Este documento discute
+sintaxe, então, muito padrões populares são excluídos.
+
+Como Solidity e Ethereum ainda estão sob desenvolvimento, funcionalidades beta
+e experimentais são tipicamente marcadas e sujeitas à mudanças. Pull requests
+são bem-vindos.
+
+```javascript
+// Primeiramente, um contrato de um Banco simples
+// Permite depósitos, retiradas e checagens de saldo
+
+// banco_simples.sol (note a extensão .sol)
+
+/* **** INCICIO DO EXEMPLO **** */
+
+// Declare a versão do compilador.
+pragma solidity ^0.4.2;
+
+// Inicie com comentários Natspec (as três barras)
+// usados para documentação - e como dados descritivos para elementos/ação de UI
+
+/// @title BancoSimples
+/// @author nemild
+
+/* 'contrato' tem similadirades com 'classes' em outras linguagens (variáveis de
+class, herança, etc.) */
+
+contract BancoSimples { // CamelCase
+ // Declare variáveis de estado fora da função, para persistí-la durante a
+ // duração do contrato
+
+ // dicionário que mapeia endereços para saldos
+ // tenha cuidado sobre ataques de overflow com números
+
+ mapping (address => uint) private saldos;
+
+ // "private" significa que outros contratos não podem acessar saldos
+ // diretamente, mas o dado ainda é visível para outras partes da blockchain
+
+ address public dono;
+
+ // ´public´ é legível (mas sem acesso de escrita) por usuários e contratos
+
+ // Eventos - ações públicas para ouvintes externo
+ event LogRealizacaoDeDeposito(address numeroDaConta, uint quantidade);
+
+ // Construtor, pode receber uma ou várias variáveis; apenas uma opção é
+ // permitidas
+
+ function BancoSimples() {
+ // msg dá detalhes sobre a mensagem mandada pelo contrato
+ // msg.sender é um chamador do contrato (endereço do criador do
+ // contrato)
+
+ dono = msg.sender;
+ }
+
+ /// @notice Deposita ether no banco
+ /// @return O saldo do usuário após o depósito
+
+ function deposito() public returns (uint) {
+ saldos[msg.sender] += msg.value;
+
+ // Sem necessidade de "this." ou "self." para variáveis de estado
+ // todos as variáveis são inciadas com seu valor default
+
+ LogRealizacaoDeDeposito(msg.sender, msg.value); // dispara evento
+
+ return saldos[msg.sender];
+ }
+
+ /// @notice Retira ether do banco
+ /// @dev Isto não retorna nenhum ether excendente
+ /// @param quantidadeDeRetirada quantidade que você quer retirar
+ /// @return O saldo restante do usuário
+ function retirada(uint quantidadeDeRetirada) public returns (uint saldoRestate) {
+ if(saldos[msg.sender] >= quantidadeDeRetirada) {
+
+ // Observe como deduzimos o saldo imediatamente, antes de enviar -
+ // devido ao risco de uma chamada recursiva que permite o chamador
+ // pedir um valor maior que seu saldo
+
+ saldos[msg.sender] -= quantidadeDeRetirada;
+
+ if (!msg.sender.send(quantidadeDeRetirada)) {
+ // incremente de volta só se falhar, como pode estar enviando
+ // para o contrato que substituiu 'enviar' no final
+ // do recebimento
+ saldos[msg.sender] += quantidadeDeRetirada;
+ }
+ }
+
+ return saldos[msg.sender];
+ }
+
+ /// @notice Retorna o saldo
+ /// @return O saldo do usuário
+ // 'constant' evita que a função edite variáveis de estado
+ // permite a função executar localmente/fora da blockchain
+ function saldo() constant returns (uint) {
+ return saldos[msg.sender];
+ }
+
+ // Função de fallback - Chamada se outras funções não forem chamadas ou
+ // se ether sem dados forem enviados
+ // Tipicamente chamada quando dados inválidos são enviados
+ // Adicionada para que ether enviado neste contrato seja revertido se o
+ // contrato falhar. Se não existisse, o dinheiro do enviante é transferido
+ // para o contrato
+ function () {
+ throw; // 'throw' reverte o estao para antes da chamada
+ }
+}
+// ** FIM DO EXEMPLO **
+
+// Agora, o básico de Solidity
+
+
+//1 TIPO DE DADOS E MÉTODOS ASSOCIADOS
+// uint é usado para quantidade de moeda (não existem doubles ou floats)
+// e para datas (no sistema de tempo Unix)
+
+uint x;
+
+// int de 256 bits, não pode ser mudado após sua instanciação
+int constant a = 8;
+int256 constant a = 8; // mesmo efeito, mas aqui os 256 bits são explícitos
+uint constant VERSÃO_ID = 0x123A1; // uma constante hexadecimal
+
+// com 'constant', o compilador substitui cada ocorrência com o valor
+
+// Para int e uint, é possível determinar o espaço explicitamente, em intervalos
+// de 8 a 256, e.g., int8, int16, int24
+uint8 b;
+int64 c;
+uint248 e;
+
+// Cuidado contra overflows, e proteja-se contra esse tipo de ataque
+
+// Não há funções randômicas padrão, use outros contratos para este objetivo
+
+// Casting de tipo
+int x = int(b);
+
+bool b = true; // ou então 'var b = true;' para inferição de tipo
+
+// Endereços - comportam 20 bytes/160 bits endereços Ethereum
+// Não permite operações aritiméticas
+address public dono;
+
+// Tipos de contas:
+// Conta de contrato: endereço criado ao criar (função do endereço do criador,
+// número da transação)
+// Conta externa: (pessoa/entidade externa): endereç criado a partir de chave
+// pública
+
+// Adicione o campo 'public' para indicar visibilidade pública/externa
+// um getter é automaticamente criado, mas NÃO um setter
+
+// Todos os endereços podem enviar ether
+dono.send(ALGUM_SALDO); // returna falso caso falhe
+if (dono.send) {} // LEMBRE-SE: encapsule num 'if', dado que endereços de
+// contrato tem funções executadas no envio e estas podem falhar
+//Também certifique-se que os saldos deduzidos ANTES de tentar enviar, dado que
+// há um risco de chamada recursiva que pode drenar um contrato
+
+// pode sobrescrever seu próprio
+
+// Pode verificar o saldo
+dona.balance; // o saldo do dono (usuário ou contrato)
+
+// Bytes permitidos de 1 a 32
+byte a; // byte é o mesmo que bytes1
+bytes2 b;
+bytes32 c;
+
+// Bytes dinamicamente criados
+
+bytes m; // Um array especial, mesmo que byte[] (mas mais comprimido)
+
+// Mais custoso que byte1-byte32, então, prefira estes quando possível
+
+// mesmo que bytes, mas não permite verificar tamanho ou acesso por indíce (por
+// enquanto)
+
+string n = "oi"; // guardado em UTF8, note as aspas duplas, não simples
+
+// funções de string serão adicionadas no futuro
+// prefira bytes32/bytes, dado que UTF8 usa mais espaço
+
+// Inferência de tipo
+// var não infere tipos baseados na primeira atribuição,
+// não pode ser usado em paramêtros de funções
+
+var a = true;
+
+// use com cuidado, inferência pode resultar em tipos errados
+// e.g., um int8, quando um contador precisa de int16
+
+// var pode ser usado para assinalar uma função a uma variável
+function a(uint x) returns (uint) {
+ return x * 2;
+}
+var f = a;
+f(22); // chamada
+
+// por padrão, todos os valores são inicializados com 0
+
+// Delete pode ser chamada na maioria dos tipos
+// (NÃO destroi o valor, mas retorna para o valor 0, o incial)
+
+uint x = 5;
+
+// Desestruturação/Tuplas
+(x, y) = (2, 7); // assinada/troca múltiplos valores
+
+// 2. ESTRUTURAS DE DADOS
+// Arrays
+
+bytes32[5] apelidos; // array estático
+bytes32[] nomes; // array dinâmico
+uint novoTamanho = nomes.push("João"); // adicionando retorna o novo tamanho do
+
+// Tamanho
+nomes.length; // pega o tamanho
+nomes.length = 1; // tamanhos pode ser alterados (para arrays dinâmicos)
+
+// arrays multidimensionais
+uint x[][5]; // array com 5 arrays dinâmicos como elementos (ordem da maioria
+// das linguagens)
+
+// Dicionários (qualquer tipo para qualquer tipo)
+mapping (string => uint) public saldos;
+saldos["charles"] = 1;
+console.log(saldos["ada"]); // é 0, toda chave não assinalada retorna zero
+// 'public' permite o seguinte contrato
+nomeDoContrato.saldos("charles"); // retorna 1
+// 'public' cria um getter (mas não um setter) como o seguinte
+function saldos(string _conta) returns (uint saldo) {
+ return saldos[_conta];
+}
+
+// Mapeamentos aninhados
+mapping (endereco => mapping (endereco => uint)) public guardioes;
+
+// Para deletar
+delete saldos["John"];
+delete saldos; // assinala zero para todas as chaves
+
+// Diferentemente de outras linguages, NÃO É POSSÍVEL iterar sobre todos os
+// elementos de um mapeamento, sem saber previamente as chaves - é possível
+// construir estruturas de dados personalizadas para fazer isso
+
+// Structs e enums
+struct Banco {
+ address dono;
+ uint saldo;
+}
+Banco b = Banco({
+ dono: msg.sender,
+ saldo: 5
+});
+// ou
+Banco c = Banco(msg.sender, 5);
+
+c.quantidade = 5; // cria novo valor
+delete b;
+// assinala todos os valores do enum para zero, exceto mapeamentos
+
+// Enums
+enum Estado { Criado, Travado, Inativo }; // geralmente usado para máquina de
+// estados
+Estado public estado; // Declara variável para enum
+estado = Estado.Criado;
+// enums podem ser explicitamente convertidas em ints
+uint estadoCriado = uint(Estado.Criado); // 0
+
+// Localização de dados: Memória vs. disco vs. pilha - todos os tipos complexos
+// (arrays, structs) tem uma localização de dados
+// 'memória' não é persistida, 'disco' é
+// Padrão é 'disco' para variáveis locais e de estado; 'memória' para paramêtros
+// de função. Pilha guarda pequena variáveis locais
+
+// a maioria dos tipos podem ter sua localização de dados explicitamente assinalos
+
+// 3. Operações simples
+// Comparações, operadores binários e aritimétricos são providos
+// exponenciação: **
+// ou exclusivo: ^
+// negação binária: ~
+
+// 4. Variáveis Globais de nota
+// ** this **
+this; // endereço do contrato
+// geralmente usado no final do contrato para enviar o saldo restante às partes
+this.balance;
+this.algumFuncao(); // chamada de função externa via call, não via jump interno
+
+// ** msg - Mensagem corrente recebida pelo contrato ** **
+msg.sender; // endereço do enviador
+msg.value; // quantidade de ether provida para este contrato em wei
+msg.data; // bytes, todos os dados da chamada
+msg.gas; // gas restante
+
+// ** tx - Esta transação **
+tx.origin; // endereço do enviador da transação
+tx.gasprice; // valor do gas da transação
+
+// ** block - Informação do bloco corrente **
+now; // tempo corrente (aproxiamdo), substituto para block.timestamp
+//(usa tempo do Unix)
+block.number; // número do bloco corrente
+block.difficulty; // dificuldade do bloco corrente
+block.blockhash(1); // retorna bytes32, só funciona para os 256 blocos mais
+//recentes
+block.gasLimit();
+
+// ** storage - Hash de disco persistente **
+storage['abc'] = 'def'; // mapea palavras de 256 bits em palavras de 256 bits
+
+
+// 4. FUNÇÕES E MAIS
+// A. Funções
+// Funções simples
+function incremento(uint x) returns (uint) {
+ x += 1;
+ return x;
+}
+
+// Funções podem retornar muito argumentos, e podem especificar argumentos
+// retornados sem necessidade de explicitamente usar return
+function incremento(uint x, uint y) returns (uint x, uint y) {
+ x += 1;
+ y += 1;
+}
+// Chamando a função anterior
+uint (a,b) = incremento(1,1);
+
+// 'constant' indica que uam função não altera variáveis persistidas
+// Funções constantes são executadas localmente, não na blockchain
+uint y;
+
+function incremento(uint x) constant returns (uint x) {
+ x += 1;
+ y += 1; // Esta linha deve falhar
+ // y é uma variável de estado e não pode ser alterada por uma função local
+}
+
+// 'Especificadores de visibilidade de funções'
+// Estes podem substituitir 'constante', incluíndo:
+// public - visbilidade externa e interna (padrão)
+// private - apenas visível no contrato corrente
+// internal - apenas visível no contrato corrente e seus derivados
+
+// Functions hosteada - e pode ser assinalada para variável
+function a() {
+ var z = b;
+ b();
+}
+
+function b() {
+
+}
+
+// Prefira loops sobre recursões (pilha de chamada é no máximo 1024)
+
+// B. Eventos
+// Eventos podem notificar partes externas; facilmente buscáveis e acessáveis
+// de fora da blockchain (com clientes leves)
+// tipicamente declarados após os parâmetros do contrato
+
+// Tipicamente, com letra maiúscula - e adicione Log na frente para
+// ser explicito e previnir confusão na chamada da função
+
+// Declaração
+event LogEnvio(address indexed de, address indexed para, uint quantidade);
+// Observe a letra maíscula no início do nome
+
+// Chamada
+Envio(de, para, quantidade);
+
+// Para partes externas (um contrato ou entidade externo), observe:
+Coin.Envio().watch({}, '', function(erro, resultado) {
+ if (!erro) {
+ console.log("Moeda transferida: " + resultado.args.quantidade +
+ " moedas enviadas de " + resultado.args.de +
+ " para " + resultado.args.para + ".");
+ console.log("Saldo atual:\n" +
+ "Enviador: " + Coin.balances.call(resultado.args.de) +
+ "Recebedor: " + Coin.balances.call(resultado.args.para));
+ }
+}
+// Paradigma comum para um contrato depender de outro (e.g., um contrato que
+// depende da taxa de troca provida por outro)
+
+// C. ModifiCadores
+// MOdificadores validam entradas de funções, como saldo mínimo e autorização
+// do usuário; semelhantes a guardas em outras linguagens
+
+// '_' (subtraço) geralmente incluído como última linha do corpo, indica que a
+// função sendo chamada deve ser colocada ali
+modifier apenasDepois(uint _tempo) { if (agora <= _tempo) throw; _ }
+modifier apenasDono { if (msg.sender == dono) _ }
+// geralmente usado para máquina de estado
+modifier apenasSeEmEstado (Estado estadoCorrente)
+{ if (estadoCorrente != Estado.A) _ }
+
+// Concatenado logo após a chamada da função
+function mudeDona(novoDono)
+apenasDepois(algumTempo)
+apenasDono()
+apenasSeEmEstado(Estado.A)
+{
+ dono = novoDono;
+}
+
+// subtração pode ser incluído antes do final do corpo, mas retorno explícitos
+// pode ser ignorado, então, tome cuidado
+modifier chequeValor(uint quantidade) {
+ _
+ if (msg.value > quantidade) {
+ uint quantidadeASerDevolvida = quantidade - msg.value;
+ if (!msg.sender.send(quantidadeASerDevolvida)) {
+ throw;
+ }
+ }
+}
+
+// 6. BRANCHES E LOOPS
+
+// Todas as lógicas básicas de bloco funcionam - incluindo if/else,
+// while, break, continue, return - mas não há switch
+
+// A sintaxe é semelhante a Javascript, mas sem conversão de tipos
+// de não-booleanos para booleanos (operadores de comparação precisam
+// utilizar valores booleanos)
+
+// Loops que dependem o comportamento do usuário exigem cuidado - dado
+// que contratos tem uma quantidade máxima de gas para cada bloco de
+// de código - falhas acontecerão caso ele seja excedido
+// Por exemplo:
+for(uint x = 0; x < listaDeEnderecoDeRefundo.length; x++) {
+ if (!listaDeEnderecoDeRefundo[x].send(ALGUMA_QUANTIDADE)) {
+ throw;
+ }
+}
+
+// Dois erros acima:
+// 1. Uma falha no enviar para o loop completamente, travando dinheiro
+// 2. Este loop pode ser abitrariamente longo (basado na quando que
+// o usuário precisa de refundo), portanto, pode falhar quando exceder
+// a quantidade máxima de gas do bloco
+// Ao invés disso, você deve deixar as pessoas retirarem
+// individualmente de suas subcontas e marcarem a retirada
+
+
+// 7. OBJETOS/CONTRATOS
+
+// A. Chamando um contrato externo
+contract FonteDeInformacoes {
+ function info() returns (uint ret) { return 42; }
+}
+
+contract Consumidor {
+ FonteDeInformacoes fonte; // aponta para um contrato na blockchain
+
+ // Assinala variável para uma instância do contrato
+ function setFonte(address endereco) {
+ // Cast automático, cuidado; construtor não é chamado
+ fonte = FonteDeInformacoes(endereco);
+ }
+
+ // Assinala variável para uma nova instância do contrato
+ function createNewFeed() {
+ fonte = new FonteDeInformacoes(); // nova instância criada
+ // construtor é chamado
+ }
+
+ function chameFonte() {
+ // último parenteses chama o contrato, podendo adicionar
+ // opcionalmente valores ou gas
+ fonte.info.value(10).gas(800)();
+ }
+}
+
+// B. Herança
+
+// Ordem importa, último contrato herdado (i.e., 'def') pode
+// sobrescrever partes de contratos previamente herdados
+contract MeuContratdo is abc, def("um argumento personalizado def") {
+
+// sobrescrevendo função
+ function z() {
+ if (msg.sender == dono) {
+ def.z(); // chama função sobrescrita de def
+ super.z(); // chama função do pai imeadiato
+ }
+ }
+}
+
+// função abstrata
+function umaFuncaoAbstrata(uint x);
+// não pode ser compilada, usada em contratos base/abstratos que
+// então, a implementam
+
+// C. Import
+
+import "filename";
+import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol";
+
+// 'Import' está sobre desenvolvimento
+// Atualmente não pode ser usada na linha de comando
+
+
+// 8.OUTRAS PALAVRAS-CHAVE
+
+// A. Throwing
+// Throwing
+throw; // reverte estado e dinheiro NÃO-USADO é devolvido ao usuários
+// Atualmente não pode ser capturado
+
+// Um padrão de design comum é:
+if (!endereco.send(123)) {
+ throw;
+}
+
+// B. Selfdestruct
+// auto-destroe o contrato corrente, enviando fundos para o endereço
+// (geralmente o criador)
+selfdestruct(ALGUM_ENDERECO);
+
+// remove disco/código dos blocos corrente e futuros
+// ajuda clientes leves, mas dados persistidos continuam no blockchain
+
+// Padrão comum, permite ao dono finalizar o contrato e receber fundos
+// restantes
+function remover() {
+ if(msg.sender == criador) { // Apenas o criador do contrato pode
+ // fazer isso
+ selfdestruct(criador); // Inativa o contrato e retorna os fundos
+ }
+}
+
+// Talvez queria desativar o contrato manualmente, ao invés de usar
+// selfdestruct (ether enviado para contratos selfdestructed é perdido)
+
+
+// 9. NOTAS SOBRE DESIGN DE CONTRATOS
+
+// A. Obfuscação
+// Todas as variáveis são publicamente visíveis na blockchain, então
+// qualquer coisa privada precisa ser obfuscada (e.g., hash com segredo)
+
+// Passo-a-pass: 1. Comprometa-se com algo, 2. Revele compromisso
+sha3("quantidade_de_lance", "algum segredo"); // compromisso
+
+// chame a função reveal (revelar) do contrato no futuros
+// mostrando o lance mais o segredo para foi hasheado com SHA3
+reveal(100, "meuSegredo");
+
+// B. Otimização de disco
+// Escrever na blockchain pode ser caro, dado que os dados são guardados
+// para sempre. É encorajado que contratos inteligentes usem memória (
+// enventualmente, compilação será melhor, mas por enquanto é benéfico
+// usar estruturas de dados simples - armazenando minimamente na
+// blockchain)
+
+// Custo pode ser alto para item como arrays multidimensionais
+// (custo para guardar os dados - não declarar variáveis)
+
+// C. Acesso de dados da blockchain
+
+// Não pode restringir humanos ou computadores de ler os conteúdos
+// de transações ou estado de transações
+
+// Enquanto 'private' previne outros *contratos* de ler dados ]
+// diretamente - qualquer outra parte ainda pode ler dados da blockchain
+
+// Todos os dados são armazedos na blockchain, para que qualquer um
+// possa observar dados antigos e mudanças
+
+// D. Jobs Cron
+// Contratos deve ser manualmente chamados para lidar com agendamentos
+// baseados em tempo; podendo criar código externo para pingar
+// regularmente ou prover incentivos (ether) para outros fazê-lo
+
+// E. Padrão Observador
+// O Padrão Observador permite que você registre um inscritor e
+// registre uma função a ser chamada pelo Oráculo (nota, Oráculos pagam
+// pela ação executada). Similarmente à subscrição em Pub/sub
+
+// Este é um contrato abstrato, tanto as classes cliente como a
+// servidor importam o cliente que deve ser implementado
+contract AlgumOraculoCallback {
+ function OraculoCallback(int _valor, uint _tempo, bytes32 info) external;
+}
+
+contract AlgumOráculo {
+ AlgumOraculoCallback[] callbacks; // array com todos os inscritos
+
+ // Registra inscrito
+ function addInscrito(AlgumOraculoCallback a) {
+ callbacks.push(a);
+ }
+
+ function notificar(valor, tempo, info) private {
+ for(uint i = 0;i < callbacks.length; i++) {
+ // todos os inscritos precisam implementar AlgumOraculoCallback
+ callbacks[i].OraculoCallback(valor, tempo, info);
+ }
+ }
+
+ function facaAlgo() public {
+ // Código para fazer algo
+
+ // Notifica todos os inscrito
+ notificar(_valor, _tempo, _info);
+ }
+}
+
+// Agora, seu contrato cliente pode addInscrito importando
+// AlgumOraculoCallback e registrando algum Oráculo
+
+// F. Máquinas de estado
+// veja o exemplo abaixo para o enum Estado e o modificador noEstado
+
+// *** EXEMPLO: Um exemplo de crowdfunding example (similar ao
+// Kickstarter) ***
+// ** INCIO DO EXEMPLO **
+
+// FundadorDoCrowdFunding.sol
+
+/// @title FundadorDoCrowdFunding
+/// @author nemild
+contract FundadorDoCrowdFunding {
+ // Variáveis assinaladas na crição pelo criador
+ address public criador;
+ address public recipiente; // criador pode ser diferente do Recipiente
+ uint public minALevantar; // requisito para pagar, pelo contrário
+ // os doadores recebem o dinheiro de volta
+ string urlDaCampanha;
+ byte constant versao = 1;
+
+ // Estruturas de dados
+ enum Estado {
+ LevantandoFundos,
+ RefundoExpirado,
+ Sucesso
+ }
+ struct Contribuicao {
+ uint quantidade;
+ address contribuidor;
+ }
+
+ // Variáveis de Estado
+ State public estado = Estado.LevantandoFundos; // incializado na criação
+ uint public totalLevantado;
+ uint public levantadoPor;
+ uint public completadoEm;
+ Contribution[] contribuidores;
+
+ event LogRecebimentoDeFundos(address endereco,
+ uint quantidade,
+ uint totalAtual);
+ event LogFundosPagos(address enderecoDoRecebedor);
+
+ modifier noEstado(Estado _estado) {
+ if (estado != _estado) throw;
+ _
+ }
+
+ modifier eOCriador() {
+ if (msg.sender != criador) throw;
+ _
+ }
+
+ // Aguarda 6 meses após o final do contrato para destruí-lo
+ modifier noFimDoContrato() {
+ if(!((estado == Estado.RefundoExpirado || estado == Estado.Sucesso) &&
+ completadoEm + 6 months < now)) {
+ throw;
+ }
+ _
+ }
+
+ function FundadorDoCrowdFunding(
+ uint tempoEmHorasParaFundraising,
+ string _urlDaCampanha,
+ address _recipiente,
+ uint _minALevantar)
+ {
+ criador = msg.sender;
+ recipiente = _recipiente;
+ urlDaCampanha = _urlDaCampanha;
+ minALevantar = _minALevantar;
+ levantadoPor = now + (tempoEmHorasParaFundraising * 1 hours);
+ }
+
+ function contribuir()
+ public
+ noEstado(Estado.LevantandoFundos)
+ {
+ contribuidores.push(
+ Contribuicao({
+ quantidade: msg.value,
+ contribuidor: msg.sender
+ }) // use array, para podermos iterar
+ );
+ totalLevantado += msg.value;
+
+ LogRecebimentoDeFundos(msg.sender, msg.value, totalRaised);
+
+ verifiqueSeLevantamentoFoiCompletadoOuExpirado();
+ return contribuicoes.length - 1; // retorna id
+ }
+
+ function verifiqueSeLevantamentoFoiCompletadoOuExpirado() {
+ if (totalLevantado > minALevantar) {
+ estado = Estado.Sucesso;
+ pagar();
+
+ // pode incentivar enviador que iniciou a mudanção de estado
+ } else if ( now > levantadoPor ) {
+ estado = Estado.RefundoExpirado; // backers podem coletar
+ // o fundo chamando receberRefundo(id)
+ }
+ completadoEm = now;
+ }
+
+ function pagar()
+ public
+ emEstado(Estado.Sucesso)
+ {
+ if(!recipiente.send(this.balance)) {
+ throw;
+ }
+
+
+ LogFundosPagos(fundRecipient);
+ }
+
+ function receberRefundo(id)
+ public
+ emEstado(Estado.RefundoExpirado)
+ {
+ if (contribuicoes.length <= id || id < 0 || contribuicoes[id].amount == 0 ) {
+ throw;
+ }
+
+ uint quantidadeDeRefundo = contribuicoes[id].amount;
+ contribuicoes[id].amount = 0;
+
+ if(!contribuicoes[id].contribuidor.send(quantidadeParaEnviar)) {
+ contribuicoes[id].amount = quantidadeParaEnviar;
+ return false;
+ }
+
+ return true;
+ }
+
+ function removerContrato()
+ public
+ eOCriador()
+ noFimDoContrato()
+ {
+ selfdestruct(msg.sender);
+ // criador recebe todo o dinheiro restante{
+
+ }
+
+ function () { throw; }
+}
+// ** FIM DO EXEMPLO **
+
+// 10. OUTRAS FUNÇÕES NATIVAS
+
+// Unidades monetárias
+// Moeda é definida usando wei, menor quantidade de ether
+uint quantidadeMin = 1 wei;
+uint a = 1 finney; // 1 ether == 1000 finney
+// Para outras unidades, veja: http://ether.fund/tool/converter
+
+// Unidades temporais
+1 == 1 second // segundos
+1 minutes == 60 seconds // Minutos
+
+// Pode multiplicar uma variável de tempo, dado que unidades não são guardadas
+// na variável
+uint x = 5;
+(x * 1 days); // 5 dias
+
+// Cuidado com o salto de segundos / anos com declarações de igualdade para o tempo
+// (em vez disso, prefira maior que / menor que)
+
+// Criptografia
+// Todas as string passadas são concatenadas antes de realizar hashing
+sha3("ab", "cd");
+ripemd160("abc");
+sha256("def");
+
+// 11. Segurança
+
+// Bugs são desastrosos para contratos Ethereum - até padrões Solidity populares
+// podem ser considerados anti-padrões
+
+// Veja links para segurança no final deste documento
+
+// 12. FUNÇÕES DE BAIXO NÍVELS
+// call - baixo nível, geralmente não usada, não tem segurança de tipos
+booleanSucesso = algumEnderecoDeContrato.call('nome_da_funcao', 'arg1', 'arg2');
+
+// callcode - Código no endereço alvo executado no *contexto* do contrato
+// de chamada. Fornece funcionalidade de biblioteca
+algumEnderecoDeContrato.callcode('nome_da_funcao');
+
+
+// 13. NOTAS DE ESTILO
+// Baseado no guia de estilo PEP8 do Python
+
+// Resumo rápido:
+// 4 espaços para identação
+// Duas linhas separam declaração de contratos (e outras declarações de alto nível)
+// Evite espaços estranhos entre parênteses
+// Pode omitir chaves curly para uma declaração de linha(if, for, etc)
+// else deve ser colocado na própria linha
+
+
+// 14. COMENTÁRIOS NATSPEC
+// usado para documentação, comentários e UIs externos
+
+// Contrato natspec - sempre acima da definição do contrato
+/// @title Título do Contrato
+/// @author Nome do autor
+
+// Função natspec
+/// @notice informações sobre o que funciona; mostrado quando a função é executada
+/// @dev Documentação de função para desenvolvedor
+
+// Parâmetro de função / valor de retorno natspec
+/// @param algumParametro Alguma descrição do que o parametro faz
+/// @return Descrição do valor de retorno
+```
+
+## Recursos adicionais
+- [Documetanção Solidity](https://solidity.readthedocs.org/en/latest/)
+- [Guia de Estilo do Solidity](https://ethereum.github.io/solidity//docs/style-guide/):
+ O guia de estilo Ethereum é derivado do guia de estilo do Python [pep8](https://www.python.org/dev/peps/pep-0008/).
+- [Editor de Browser Solidity](http://chriseth.github.io/browser-solidity/)
+- [Gitter Solidity Chat room](https://gitter.im/ethereum/solidity)
+- [Estratégias de projeto modular para contratos Ethereum](https://docs.erisindustries.com/tutorials/solidity/)
+
+## Contratos de Exemplo
+- [Dapp Bin](https://github.com/ethereum/dapp-bin)
+- [Solidity Baby Step Contracts](https://github.com/fivedogit/solidity-baby-steps/tree/master/contracts)
+- [ConsenSys Contracts](https://github.com/ConsenSys/dapp-store-contracts)
+- [State of Dapps](http://dapps.ethercasts.com/)
+
+## Segurança
+- [Thinking About Smart Contract Security](https://blog.ethereum.org/2016/06/19/thinking-smart-contract-security/)
+- [Smart Contract Security](https://blog.ethereum.org/2016/06/10/smart-contract-security/)
+- [Hacking Distributed Blog](http://hackingdistributed.com/)
+
+## Informação excluída intencionalmente
+- Libraries
+
+## Estilo
+- [PEP8](https://www.python.org/dev/peps/pep-0008/) é usado como guia de estilo,
+ incluindo sua filosofia geral
+
+## Editores
+- [Vim Solidity](https://github.com/tomlion/vim-solidity)
+- Snippets de Editores ([Ultisnips format](https://gist.github.com/nemild/98343ce6b16b747788bc))
+
+## Trabalhos Futuros
+- Novas palavras-chave: protected, inheritable
+- Lista de padrões de design comuns (throttling, RNG, atualização de versão)
+- Padrões anti-segurança comuns
+
+
+Sinta-se a vontade para enviar um pull request com quaisquer edições - ou email
+para nemild - / at- / gmail
diff --git a/pt-br/stylus-pt.html.markdown b/pt-br/stylus-pt.html.markdown
new file mode 100755
index 00000000..40c3c02c
--- /dev/null
+++ b/pt-br/stylus-pt.html.markdown
@@ -0,0 +1,228 @@
+---
+language: stylus
+filename: learnStylus-pt.styl
+contributors:
+ - ["Salomão Neto", "https://github.com/salomaosnff"]
+ - ["Isaac Henrique", "https://github.com/Isaachi1"]
+lang: pt-br
+---
+
+Stylus tem como propósito, adicionar funcionalidades às suas folhas de estilos CSS que te ajudam no desenvolvimento, sem que haja a quebra de compartibilidade entre os navegadores Web.
+Entre elas estão variáveis, aninhamento, mixins, funções e muito mais.
+
+A sintaxe do Stylus é muito flexivel podendo utilizar a sintaxe padrão do CSS e deixando opcional o ponto e vírgula (;), dois pontos (:) e até mesmo as chaves ({ e }), tornando assim o seu código ainda mais legível.
+
+Stylus não fornece novas opções de estilos, mas dá funcionalidades que permitem deixar seu CSS muito mais dinâmico.
+
+
+```scss
+
+/* Estilo de código
+==============================*/
+
+/* As chaves, ponto e vírgula, e dois pontos são opcionais no Stylus. */
+
+body {
+ background: #000;
+}
+
+body {
+ background: #000
+}
+
+body {
+ background #000
+}
+
+body
+ background #000
+
+body
+ background: #000;
+
+body
+ background: #000
+
+
+// Comentários de linha única são removidos quando Stylus é compilado para CSS.
+
+/* Comentários multi-line são preservados. */
+
+
+/* Seletores
+==============================*/
+
+/* Selecionando elementos dentro de outro elemento */
+body {
+ background: #000000;
+ h1 {
+ color: #FF0000;
+ }
+}
+
+/* Ou se preferir... */
+body
+ background #000000
+ h1
+ color #FF0000
+
+
+/* Obtendo a referência do elemento pai
+==============================*/
+a {
+ color: #0088dd;
+ &:hover {
+ color: #DD8800;
+ }
+}
+
+
+/*Variáveis
+==============================*/
+
+
+/*
+ É possível armazenar um valor CSS (tais como a cor) de uma variável.
+ Embora seja opcional, é recomendado adicionar $ antes de um nome de variável
+ para que você possa distinguir uma variável de outro valor CSS.
+*/
+
+$primary-color = #A3A4FF
+$secondary-color = #51527F
+$body-font = 'Roboto', sans-serif
+
+/* Você pode usar as variáveis em toda a sua folha de estilo.
+Agora, se você quer mudar a cor, você só tem que fazer a mudança uma vez. */
+
+body
+ background-color $primary-color
+ color $secondary-color
+ font-family $body-font
+
+/* Quando compilar ficaria assim: */
+body {
+ background-color: #A3A4FF;
+ color: #51527F;
+ font-family: 'Roboto', sans-serif;
+}
+
+/ *
+Este é muito mais fácil de manter do que ter de mudar a cor
+cada vez que aparece em toda a sua folha de estilo.
+* /
+
+
+
+/*Mixins
+==============================*/
+
+/* Se você achar que você está escrevendo o mesmo código para mais de um
+elemento, você pode querer armazenar esse código em um mixin.
+
+center()
+ display block
+ margin-left auto
+ margin-right auto
+ left 0
+ right 0
+
+/* Utilizando um mixin */
+body {
+ center()
+ background-color: $primary-color
+}
+
+/* Após compilar ficaria assim: */
+div {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+ background-color: #A3A4FF;
+}
+
+/* Você pode usar mixins para criar uma propriedade estenográfica. */
+
+size($width, $height)
+ width $width
+ height $height
+
+.rectangle
+ size(100px, 60px)
+
+.square
+ size(40px, 40px)
+
+/* Você pode usar um mixin como uma propriedade CSS. */
+circle($ratio)
+ width $ratio * 2
+ height $ratio * 2
+ border-radius $ratio
+
+.ball
+ circle 25px
+
+
+/* Interpolação
+==============================*/
+
+vendor(prop, args)
+ -webkit-{prop} args
+ -moz-{prop} args
+ {prop} args
+
+border-radius()
+ vendor('border-radius', arguments)
+
+box-shadow()
+ vendor('box-shadow', arguments)
+
+button
+ border-radius 1px 2px / 3px 4px
+
+/* Funções
+==============================*/
+
+/* Funções no Stylus permitem fazer uma variedade de tarefas, como por exemplo, manipular algum dado. */
+
+body {
+ background darken(#0088DD, 50%) // Escurece a cor #0088DD em 50%
+}
+
+/* Criando sua própria função */
+somar(a, b)
+ a + b
+
+body
+ padding somar(10px, 5)
+
+/* Condições
+==============================*/
+comparar(a, b)
+ if a > b
+ maior
+ else if a < b
+ menor
+ else
+ igual
+
+comparar(5, 2) // => maior
+comparar(1, 5) // => menor
+comparar(10, 10) // => igual
+
+/* Iterações
+==============================*/
+
+/**
+Sintaxe de laço de repetição for:
+for <val-name> [, <key-name>] in <expression>
+**/
+
+for $item in (1..2) /* Repete o bloco 12 vezes */
+ .col-{$item}
+ width ($item / 12) * 100% /* Calcula a largura pelo número da coluna*
+
+```
+
+Agora que você conhece um pouco sobre esse poderoso pré-processador de CSS, você está pronto para criar folhas de estilos mais dinâmicas. Para aprofundar seus conhecimentos visite a documentação oficial do stylus em http://stylus-lang.com.
diff --git a/pt-br/swift-pt.html.markdown b/pt-br/swift-pt.html.markdown
index 4ad67a06..bf410352 100644
--- a/pt-br/swift-pt.html.markdown
+++ b/pt-br/swift-pt.html.markdown
@@ -1,12 +1,13 @@
---
language: swift
+filename: learnswift-pt.swift
contributors:
- ["Grant Timmerman", "http://github.com/grant"]
- ["Christopher Bess", "http://github.com/cbess"]
translators:
- ["Mariane Siqueira Machado", "https://twitter.com/mariane_sm"]
lang: pt-br
-filename: learnswift.swift
+
---
Swift é uma linguagem de programação para desenvolvimento de aplicações no iOS e OS X criada pela Apple. Criada para
@@ -388,13 +389,13 @@ if mySquare === mySquare {
// Podem conter métodos do mesmo jeito que classes.
enum Suit {
- case Spades, Hearts, Diamonds, Clubs
+ case spades, hearts, diamonds, clubs
func getIcon() -> String {
switch self {
- case .Spades: return "♤"
- case .Hearts: return "♡"
- case .Diamonds: return "♢"
- case .Clubs: return "♧"
+ case .spades: return "♤"
+ case .hearts: return "♡"
+ case .diamonds: return "♢"
+ case .clubs: return "♧"
}
}
}
diff --git a/pt-br/typescript-pt.html.markdown b/pt-br/typescript-pt.html.markdown
index f072b257..ed76959c 100644
--- a/pt-br/typescript-pt.html.markdown
+++ b/pt-br/typescript-pt.html.markdown
@@ -8,20 +8,13 @@ translators:
lang: pt-br
---
-TypeScript is a language that aims at easing development of large scale applications written in JavaScript.
-TypeScript adds common concepts such as classes, modules, interfaces, generics and (optional) static typing to JavaScript.
-It is a superset of JavaScript: all JavaScript code is valid TypeScript code so it can be added seamlessly to any project. The TypeScript compiler emits JavaScript.
-
-This article will focus only on TypeScript extra syntax, as opposed to [JavaScript] (../javascript/).
-
-
Typescript é uma linguagem que visa facilitar o desenvolvimento de aplicações em grande escala escritos em JavaScript.
Typescript acrescenta conceitos comuns como classes, módulos, interfaces, genéricos e (opcional) tipagem estática para JavaScript.
-É um super conjunto de JavaScript: todo o código JavaScript é o código do texto dactilografado válido para que possa ser adicionados diretamente a qualquer projeto. O compilador emite typescript JavaScript.
+É um super conjunto de JavaScript: todo o código JavaScript é TypeScript válido então ele pode ser adicionado diretamente a qualquer projeto. O compilador emite TypeScript JavaScript.
-Este artigo irá se concentrar apenas em texto datilografado sintaxe extra, ao contrário de [JavaScript](javascript-pt.html.markdown).
+Este artigo irá se concentrar apenas na sintaxe extra do TypeScript, ao contrário de [JavaScript](javascript-pt.html.markdown).
-Para testar compilador do texto datilografado, de cabeça para o [Parque](http://www.typescriptlang.org/Playground), onde você vai ser capaz de escrever código, ter auto conclusão e ver diretamente o JavaScript emitida.
+Para testar o compilador TypeScript, vá para o [Playground](http://www.typescriptlang.org/Playground), onde você vai ser capaz de escrever código, ter auto conclusão e ver diretamente o JavaScript emitido.
```js
// Existem 3 tipos básicos no TypeScript
@@ -29,7 +22,7 @@ var isDone: boolean = false;
var lines: number = 42;
var name: string = "Anders";
-// Quando é impossível saber, há o "Qualquer" tipo
+// Quando é impossível saber, há o tipo "Qualquer"
var notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // Ok, definitivamente um boolean
@@ -51,13 +44,13 @@ function bigHorribleAlert(): void {
// Funções são cidadãos de primeira classe, apoiar a sintaxe lambda "seta gordura" e
// Tipo de uso inferência
-// A seguir são equivalentes, a mesma assinatura será inferido pelo
-// Compilador, e mesmo JavaScript será emitido
+// A seguir são equivalentes, a mesma assinatura será inferida pelo
+// Compilador, e o mesmo JavaScript será emitido
var f1 = function(i: number): number { return i * i; }
-// Tipo de retorno inferida
+// Tipo de retorno inferido
var f2 = function(i: number) { return i * i; }
var f3 = (i: number): number => { return i * i; }
-// Tipo de retorno inferida
+// Tipo de retorno inferido
var f4 = (i: number) => { return i * i; }
// Tipo de retorno inferido, one-liner significa nenhuma palavra-chave retorno necessário
var f5 = (i: number) => i * i;
@@ -72,7 +65,7 @@ interface Person {
move(): void;
}
-// Objeto que implementa a "Pessoa" Interface
+// Objeto que implementa a Interface "Pessoa"
// Pode ser tratado como uma pessoa desde que tem o nome e mover propriedades
var p: Person = { name: "Bobby", move: () => {} };
// Os objetos que têm a propriedade opcional:
@@ -95,7 +88,7 @@ class Point {
// Propriedades
x: number;
- // Construtor - the public/private keywords in this context will generate
+ // Construtor - as palavras-chave public/private nesse contexto irão gerar
// o código clichê para a propriedade e a inicialização no
// construtor.
// Neste exemplo, "y" será definida como "X" é, mas com menos código
diff --git a/pt-br/vim-pt.html.markdown b/pt-br/vim-pt.html.markdown
index 4f70079a..cc304381 100644
--- a/pt-br/vim-pt.html.markdown
+++ b/pt-br/vim-pt.html.markdown
@@ -5,15 +5,16 @@ contributors:
- ["RadhikaG", "https://github.com/RadhikaG"]
translators:
- ["David Lima", "https://github.com/davelima"]
+ - ["Raul Almeida", "https://github.com/almeidaraul"]
lang: pt-br
filename: LearnVim-pt.txt
---
-[Vim](www.vim.org)
+[Vim](http://www.vim.org)
(Vi IMproved - Vi Melhorado) é um clone do editor vi para Unix. Ele é um
editor de texto projetado para ter velocidade e produtividade, e está presente
-na maioria dos systemas UNIX. O editor tem um grande número de atalhos de teclado
+na maioria dos sistemas UNIX. O editor tem um grande número de atalhos de teclado
para agilizar a navegação para pontos específicos no arquivo, além de edição rápida.
## Navegação do Vim: o básico
@@ -24,8 +25,9 @@ para agilizar a navegação para pontos específicos no arquivo, além de ediç
:w # Salva o arquivo atual
:wq # Salva o arquivo e fecha o vim
:q! # Fecha o vim e descarta as alterações no arquivo
+ # ! depois de qualquer comando força a sua execução
# ! *força* :q a executar, fechando o vim sem salvar antes
- :x # Salvar o arquivo e fechao vim (atalho para :wq)
+ :x # Salva o arquivo e fecha o vim (atalho para :wq)
u # Desfazer
CTRL+R # Refazer
@@ -62,7 +64,7 @@ para agilizar a navegação para pontos específicos no arquivo, além de ediç
# Movendo por palavras
- w # Move o cursor uma palavra a diante
+ w # Move o cursor uma palavra adiante
b # Move o cursor uma palavra atrás
e # Move o cursor ao fim da palavra atual
@@ -158,7 +160,15 @@ Alguns exemplos importantes de 'Verbos', 'Modificadores' e 'Nomes':
:earlier 15m # Reverte o documento para como ele estava há 15 minutos atrás
:later 15m # Reverte o comando acima
ddp # Troca linhas consecutivas de posição, dd e depois p
+ xp # Permuta caractere atual e o seguinte
+ Xp # Permuta caractere atual e o anterior
. # Repete a última ação
+
+ # Em geral, o usuário pode associar um comando em maísculas (exemplo: D) com
+ # "executar este comando até o final da linha"
+
+ # Usar a tecla de um comando duas vezes geralmente significa executar este
+ # comando sobre toda a linha (exemplo: dd apaga a linha inteira)
```
## Macros
@@ -172,6 +182,7 @@ exatamente a mesma sequencia de ações e comandos na seleção atual.
qa # Inicia a gravação de uma macro chamado 'a'
q # Para a gravação
@a # Executa a macro
+ @@ # Executa a última macro executada
```
### Configurando o ~/.vimrc
diff --git a/pt-br/visualbasic-pt.html.markdown b/pt-br/visualbasic-pt.html.markdown
index 76cca567..2a7205cd 100644
--- a/pt-br/visualbasic-pt.html.markdown
+++ b/pt-br/visualbasic-pt.html.markdown
@@ -8,16 +8,16 @@ lang: pt-br
filename: learnvisualbasic-pt.vb
---
-```vb
+```
Module Module1
module Module1
Sub Main ()
' Uma visão geral de console de aplicativos do Visual Basic antes de
- ' mergulharmos mais profundamente na linguagem
+ ' mergulharmos mais profundamente na linguagem.
' Aspas simples começam comentários.
- ' Para Navegar este tutorial dentro do compilador do Visual Basic,
+ ' Para navegar neste tutorial dentro do compilador do Visual Basic,
' eu criei um sistema de navegação.
' Este sistema de navegação vai ser explicado conforme avançarmos no
' tutorial, e você vai entender o que isso significa.
@@ -93,16 +93,16 @@ module Module1
Private Sub HelloWorldInput ()
Console.Title = " Olá Mundo YourName | Saiba X em Y Minutes"
' Variáveis
- 'Os dados inseridos por um usuário precisa ser armazenada .
+ 'Os dados inseridos por um usuário precisam ser armazenados.
' As variáveis ​​também começar com um Dim e terminar com um Como VariableType .
- ' Neste tutorial, nós queremos saber o que o seu nome, e faça o programa
+ ' Neste tutorial, nós queremos saber qual é o seu nome, e faça o programa
' Responder ao que é dito.
Nome de usuário Dim As String
" Nós usamos string como string é uma variável de texto baseado .
Console.WriteLine (" Olá, Qual é o seu nome? ") ' Peça ao usuário seu nome.
- username = Console.ReadLine () ' armazena o nome usuários.
- Console.WriteLine (" Olá " + nome do usuário) " A saída é Olá ' Seu nome '
+ username = Console.ReadLine () ' armazena o nome do usuário.
+ Console.WriteLine (" Olá " + username) ' A saída é "Olá < seu nome >".
Console.ReadLine () ' Outsputs acima.
' O código acima irá lhe fazer uma pergunta seguiu imprimindo sua resposta.
" Outras variáveis ​​incluem Integer e usamos inteiro para números inteiros.
diff --git a/pt-br/whip-pt.html.markdown b/pt-br/whip-pt.html.markdown
new file mode 100644
index 00000000..b11faf28
--- /dev/null
+++ b/pt-br/whip-pt.html.markdown
@@ -0,0 +1,247 @@
+---
+language: whip
+contributors:
+ - ["Tenor Biel", "http://github.com/L8D"]
+ - ["Saurabh Sandav", "http://github.com/SaurabhSandav"]
+author: Tenor Biel
+author_url: http://github.com/L8D
+translators:
+ - ["Paulo Henrique Rodrigues Pinheiro", "https://github.com/paulohrpinheiro"]
+lang: pt-br
+filename: whip-pt.lisp
+---
+
+Whip é um dialeto de Lisp feito para construir scripts e trabalhar com
+conceitos mais simples.
+Ele também copia muitas funções e sintaxe de Haskell (uma linguagem não correlata)
+
+Esse documento foi escrito pelo próprio autor da linguagem. Então é isso.
+
+```scheme
+; Comentário são como em Lisp. Pontos-e-vírgulas...
+
+; A maioria das declarações de primeiro nível estão dentro de "listas"
+; que nada mais são que coisas entre parênteses separadas por espaços em branco
+nao_é_uma_lista
+(uma lista)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 1. Números, texto e operadores
+
+; Whip tem um tipo numérico (que é um double de 64 bits IEE 754, do JavaScript)
+3 ; => 3
+1.5 ; => 1.5
+
+; Funções são chamadas se elas são o primeiro elemento em uma lista
+(funcao_chamada argumentos)
+
+; A maioria das operações são feitas com funções
+; Todas as funções aritméticas básicas são bem diretas
+(+ 1 1) ; => 2
+(- 2 1) ; => 1
+(* 1 2) ; => 2
+(/ 2 1) ; => 2
+; até mesmo o módulo
+(% 9 4) ; => 1
+; Divisão não inteira ao estilo JavaScript.
+(/ 5 2) ; => 2.5
+
+; Aninhamento de listas funciona como esperado.
+(* 2 (+ 1 3)) ; => 8
+
+; Há um tipo boleano.
+true
+false
+
+; Textos são criados com ".
+"Hello, world"
+
+; Caracteres são criados com '.
+'a'
+
+; Para negação usa-se a função 'not'.
+(not true) ; => false
+(not false) ; => true
+
+; Mas a maioria das funções não-haskell tem atalhos
+; o atalho para "não" é um '!'.
+(! (! true)) ; => true
+
+; Igualdade é `equal` ou `=`.
+(= 1 1) ; => true
+(equal 2 1) ; => false
+
+; Por exemplo, desigualdade pode ser verificada combinando as funções
+;`not` e `equal`.
+(! (= 2 1)) ; => true
+
+; Mais comparações
+(< 1 10) ; => true
+(> 1 10) ; => false
+; e suas contra partes para texto.
+(lesser 1 10) ; => true
+(greater 1 10) ; => false
+
+; Texto pode ser concatenado com +.
+(+ "Hello " "world!") ; => "Hello world!"
+
+; Você pode usar as características comparativas do JavaScript.
+(< 'a' 'b') ; => true
+; ... e coerção de tipos
+(= '5' 5)
+
+; As funções `at` ou `@` acessarão caracteres de um texto, começando em 0.
+(at 0 'a') ; => 'a'
+(@ 3 "foobar") ; => 'b'
+
+; Também existem as variáveis `null` e `undefined`.
+null ; usada para indicar a ausência de algum valor
+undefined ; usada para indicar que um valor não foi informado
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 2. Variáveis, matrizes e dicionários
+
+; Variáveis são declaradas com as funções `def` ou `let`.
+; Variáveis que não tiveram valor atribuído serão `undefined`.
+(def some_var 5)
+; `def` deixará a variável no contexto global.
+; `let` deixará a variável no contexto local, e tem uma sintaxe estranha.
+(let ((a_var 5)) (+ a_var 5)) ; => 10
+(+ a_var 5) ; = undefined + 5 => undefined
+
+; Matrizes são listas de valores de qualquer tipo.
+; Elas basicamente são listas sem funções no início
+(1 2 3) ; => [1, 2, 3] (sintaxe JavaScript)
+
+; Dicionários em Whip são o equivalente a 'object' em JavaScript ou
+; 'dict' em python ou 'hash' em Ruby: eles são uma coleção desordenada
+de pares chave-valor.
+{"key1" "value1" "key2" 2 3 3}
+
+; Chaves podem ser apenas identificadores, números ou texto.
+(def my_dict {my_key "my_value" "my other key" 4})
+; Mas em Whip, dicionários são parceados como: valor, espaço, valor;
+; com mais espaço entre cada. Então isso significa que
+{"key" "value"
+"another key"
+1234
+}
+é avaliado da mesma forma que
+{"key" "value" "another key" 1234}
+
+; Dicionários podem ser acessados usando a função `at`
+; (como em texto e listas)
+(@ "my other key" my_dict) ; => 4
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 3. Lógica e controle de fluxo
+
+; A função `if` é muito simples, ainda que muito diferente do que em muitas
+linguagens imperativas.
+(if true "returned if first arg is true" "returned if first arg is false")
+; => "returned if first arg is true"
+
+; E por conta do legado operador ternário
+; `?` é o atalho não utilizado para `if`.
+(? false true false) ; => false
+
+; `both` é uma declaração lógica `and`, e `either` é o `or` lógico.
+(both true true) ; => true
+(both true false) ; => false
+(either true false) ; => true
+(either false false) ; => false
+; E seus atalhos são
+; & => both
+; ^ => either
+(& true true) ; => true
+(^ false true) ; => true
+
+;;;;;;;;;
+; Lambdas
+
+; Lambdas em Whip são declaradas com as funções `lambda` ou `->`.
+; E funções são na verdade lambdas com nomes.
+(def my_function (-> (x y) (+ (+ x y) 10)))
+; | | | |
+; | | | valor retornado (com escopo contento argumentos)
+; | | argumentos
+; | declaração de funções lambda
+; |
+; nome do lambda a ser declarado
+
+(my_function 10 10) ; = (+ (+ 10 10) 10) => 30
+
+; Obviamente, todos os lambdas por definição são anônimos e
+; tecnicamente sempre usados anonimamente. Redundância.
+((lambda (x) x) 10) ; => 10
+
+;;;;;;;;;;;;;;;;
+; Comprehensions
+
+; `range` or `..` geram uma lista dos números para
+; cada número entre seus dois argumentos.
+(range 1 5) ; => (1 2 3 4 5)
+(.. 0 2) ; => (0 1 2)
+
+; `map` aplica seu primeiro argumento (que deve ser um lambda/função)
+; a cada item dos argumentos seguintes (que precisa ser uma lista)
+(map (-> (x) (+ x 1)) (1 2 3)) ; => (2 3 4)
+
+; Reduce
+(reduce + (.. 1 5))
+; equivalente a
+((+ (+ (+ 1 2) 3) 4) 5)
+
+; Nota: map e reduce não possuem atalhos
+
+; `slice` ou `\` é similar ao .slice() do JavaScript
+; mas veja que ele pega uma lista como primeiro argumento, não o último.
+(slice (.. 1 5) 2) ; => (3 4 5)
+(\ (.. 0 100) -5) ; => (96 97 98 99 100)
+
+; `append` ou `<<` são auto explicativos
+(append 4 (1 2 3)) ; => (1 2 3 4)
+(<< "bar" ("foo")) ; => ("foo" "bar")
+
+; Length é auto explicativo.
+(length (1 2 3)) ; => 3
+(_ "foobar") ; => 6
+
+;;;;;;;;;;;;;;;
+; Delicadezas Haskell
+
+; Primeiro item de uma lista
+(head (1 2 3)) ; => 1
+; Pega do segundo ao último elemento de uma lista
+(tail (1 2 3)) ; => (2 3)
+; Último item de uma lista
+(last (1 2 3)) ; => 3
+; Contrário de `tail`
+(init (1 2 3)) ; => (1 2)
+; Pega do primeiro até o elemento especificado da lista
+(take 1 (1 2 3 4)) ; (1 2)
+; Contrário de `take`
+(drop 1 (1 2 3 4)) ; (3 4)
+; Menor valor em uma lista
+(min (1 2 3 4)) ; 1
+; Maior valor em uma lista
+(max (1 2 3 4)) ; 4
+; Verifica se o valor está em uma lista ou objeto
+(elem 1 (1 2 3)) ; true
+(elem "foo" {"foo" "bar"}) ; true
+(elem "bar" {"foo" "bar"}) ; false
+; Inverte a ordem de uma lista
+(reverse (1 2 3 4)) ; => (4 3 2 1)
+; Verifica se o valor é par ou ímpar
+(even 1) ; => false
+(odd 1) ; => true
+; Separa um texto cortando por espaço em branco
+(words "foobar nachos cheese") ; => ("foobar" "nachos" "cheese")
+; Junta lista de textos
+(unwords ("foo" "bar")) ; => "foobar"
+; Sucessor e predecessor
+(pred 21) ; => 20
+(succ 20) ; => 21
+```
+
+Para mais informação, verifique o [repositório](http://github.com/L8D/whip)
diff --git a/pt-br/xml-pt.html.markdown b/pt-br/xml-pt.html.markdown
index f347f8ef..6710b387 100644
--- a/pt-br/xml-pt.html.markdown
+++ b/pt-br/xml-pt.html.markdown
@@ -10,8 +10,7 @@ lang: pt-br
XML é uma linguagem de marcação projetada para armazenar e transportar dados.
-Ao contrário de HTML, XML não especifica como exibir ou formatar os dados,
-basta carregá-lo.
+Ao contrário de HTML, XML não especifica como exibir ou formatar os dados, apenas o transporta.
* Sintaxe XML
diff --git a/pt-br/yaml-pt.html.markdown b/pt-br/yaml-pt.html.markdown
index 341ae675..21e9b4bb 100644
--- a/pt-br/yaml-pt.html.markdown
+++ b/pt-br/yaml-pt.html.markdown
@@ -1,7 +1,7 @@
---
language: yaml
contributors:
- - ["Adam Brenecki", "https://github.com/adambrenecki"]
+ - ["Leigh Brenecki", "https://github.com/adambrenecki"]
translators:
- ["Rodrigo Russo", "https://github.com/rodrigozrusso"]
filename: learnyaml-pt.yaml
@@ -11,12 +11,10 @@ lang: pt-br
YAML é uma linguagem de serialização de dados projetado para ser diretamente gravável e
legível por seres humanos.
-É um estrito subconjunto de JSON, com a adição de sintaticamente
-novas linhas e recuo significativos, como Python. Ao contrário de Python, no entanto,
-YAML não permite caracteres de tabulação literais em tudo.
+É um superconjunto de JSON, com a adição de identação e quebras de linhas sintaticamente significativas, como Python. Ao contrário de Python, entretanto, YAML não permite o caracter literal tab para identação.
```yaml
-# Commentários em YAML são como este.
+# Comentários em YAML são como este.
###################
# TIPOS ESCALARES #
@@ -35,7 +33,7 @@ chave com espaco: valor
porem: "Uma string, entre aspas."
"Chaves podem estar entre aspas tambem.": "É útil se você quiser colocar um ':' na sua chave."
-# Seqüências de várias linhas podem ser escritos como um 'bloco literal' (utilizando |),
+# Seqüências de várias linhas podem ser escritas como um 'bloco literal' (utilizando |),
# ou em um 'bloco compacto' (utilizando '>').
bloco_literal: |
Todo esse bloco de texto será o valor da chave 'bloco_literal',
@@ -78,7 +76,7 @@ um_mapa_aninhado:
# também permite tipos de coleção de chaves, mas muitas linguagens de programação
# vão reclamar.
-# Sequências (equivalente a listas ou arrays) semelhante à isso:
+# Sequências (equivalente a listas ou arrays) semelhante a isso:
uma_sequencia:
- Item 1
- Item 2
@@ -120,7 +118,7 @@ datetime: 2001-12-15T02: 59: 43.1Z
datetime_com_espacos 2001/12/14: 21: 59: 43.10 -5
Data: 2002/12/14
-# A tag !!binary indica que a string é na verdade um base64-encoded (condificado)
+# A tag !!binary indica que a string é na verdade um base64-encoded (codificado)
# representação de um blob binário.
gif_file: !!binary |
R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
diff --git a/pt-pt/bf.html.markdown b/pt-pt/bf-pt.html.markdown
index da4c787f..13c22387 100644
--- a/pt-pt/bf.html.markdown
+++ b/pt-pt/bf-pt.html.markdown
@@ -1,5 +1,6 @@
---
language: brainfuck
+filename: brainfuck-pt.bf
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
diff --git a/pt-pt/swift.html.markdown b/pt-pt/swift-pt.html.markdown
index 9462ee1c..6b263942 100644
--- a/pt-pt/swift.html.markdown
+++ b/pt-pt/swift-pt.html.markdown
@@ -445,49 +445,49 @@ if let circle = myEmptyCircle {
// Enums pode opcionalmente ser um tipo especifico ou não.
// Enums podem conter métodos tal como as classes.
-enum Suit {
- case Spades, Hearts, Diamonds, Clubs
+enum suit {
+ case spades, hearts, diamonds, clubs
func getIcon() -> String {
switch self {
- case .Spades: return "♤"
- case .Hearts: return "♡"
- case .Diamonds: return "♢"
- case .Clubs: return "♧"
+ case .spades: return "♤"
+ case .hearts: return "♡"
+ case .diamonds: return "♢"
+ case .clubs: return "♧"
}
}
}
// Os valores de Enum permitem syntax reduzida, não é preciso escrever o tipo do enum
// quando a variável é explicitamente definida.
-var suitValue: Suit = .Hearts
+var suitValue: Suit = .hearts
// Enums que não sejam inteiros obrigam a atribuições valor bruto (raw value) diretas
enum BookName: String {
- case John = "John"
- case Luke = "Luke"
+ case john = "John"
+ case luke = "Luke"
}
-print("Name: \(BookName.John.rawValue)")
+print("Name: \(BookName.john.rawValue)")
// Enum com valores associados
enum Furniture {
// Associar com um inteiro (Int)
- case Desk(height: Int)
+ case desk(height: Int)
// Associar com uma String e um Int
- case Chair(String, Int)
+ case chair(String, Int)
func description() -> String {
switch self {
- case .Desk(let height):
+ case .desk(let height):
return "Desk with \(height) cm"
- case .Chair(let brand, let height):
+ case .chair(let brand, let height):
return "Chair of \(brand) with \(height) cm"
}
}
}
-var desk: Furniture = .Desk(height: 80)
+var desk: Furniture = .desk(height: 80)
print(desk.description()) // "Desk with 80 cm"
-var chair = Furniture.Chair("Foo", 40)
+var chair = Furniture.chair("Foo", 40)
print(chair.description()) // "Chair of Foo with 40 cm"
diff --git a/pug.html.markdown b/pug.html.markdown
new file mode 100644
index 00000000..0187f1e0
--- /dev/null
+++ b/pug.html.markdown
@@ -0,0 +1,204 @@
+---
+language: Pug
+contributors:
+ - ["Michael Warner", "https://github.com/MichaelJGW"]
+filename: index.pug
+---
+
+## Getting Started with Pug
+
+Pug is a little language that compiles into the HTML. It has cleaner syntax
+with additional features like if statements and loops. It can also be used
+as a server side templating language for server languages like NodeJS.
+
+### The Language
+```pug
+
+//- Single Line Comment
+
+//- Multi Line
+ Comment
+
+//- ---TAGS---
+//- Basic
+div
+//- <div></div>
+h1
+//- <h1></h1>
+my-customTag
+//- <my-customTag></my-customTag>
+
+//- Sibling
+div
+div
+//- <div></div>
+ <div></div>
+
+//- Child
+div
+ div
+//- <div>
+ <div></div>
+ </div>
+
+//- Text
+h1 Hello there
+//- <h1>Hello there</h1>
+
+//- Multi Line Text
+div.
+ Hello
+ There
+//- <div>
+ Hello
+ There
+ </div>
+
+//- ---ATTRIBUTES---
+div(class="my-class" id="my-id" my-custom-attrs="data" enabled)
+//- <div class="my-class" id="my-id" my-custom-attrs="data" enabled></div>
+
+//- Short Hand
+span.my-class
+//- <span class="my-class"></span>
+.my-class
+//- <div class="my-class"></div>
+div#my-id
+//- <div id="my-id"></div>
+div#my-id.my-class
+//- <div class="my-class" id="my-id"></div>
+
+
+//- ---JS---
+- const lang = "pug";
+
+//- Multi Line JS
+-
+ const lang = "pug";
+ const awesome = true;
+
+//- JS Classes
+- const myClass = ['class1', 'class2', 'class3']
+div(class=myClass)
+//- <div class="class1 class2 class3"></div>
+
+//- JS Styles
+- const myStyles = {'color':'white', 'background-color':'blue'}
+div(styles=myStyles)
+//- <div styles="{&quot;color&quot;:&quot;white&quot;,&quot;background-color&quot;:&quot;blue&quot;}"></div>
+
+//- JS Attributes
+- const myAttributes = {"src": "photo.png", "alt": "My Photo"}
+img&attributes(myAttributes)
+//- <img src="photo.png" alt="My Photo">
+- let disabled = false
+input(type="text" disabled=disabled)
+//- <input type="text">
+- disabled = true
+input(type="text" disabled=disabled)
+//- <input type="text" disabled>
+
+//- JS Templating
+- const name = "Bob";
+h1 Hi #{name}
+h1= name
+//- <h1>Hi Bob</h1>
+//- <h1>Bob</h1>
+
+//- ---LOOPS---
+
+//- 'each' and 'for' do the same thing we will use 'each' only.
+
+each value, i in [1,2,3]
+ p=value
+//-
+ <p>1</p>
+ <p>2</p>
+ <p>3</p>
+
+each value, index in [1,2,3]
+ p=value + '-' + index
+//-
+ <p>1-0</p>
+ <p>2-1</p>
+ <p>3-2</p>
+
+each value in []
+ p=value
+//-
+
+each value in []
+ p=value
+else
+ p No Values are here
+
+//- <p>No Values are here</p>
+
+//- ---CONDITIONALS---
+
+- const number = 5
+if number < 5
+ p number is less then 5
+else if number > 5
+ p number is greater then 5
+else
+ p number is 5
+//- <p>number is 5</p>
+
+- const orderStatus = "Pending";
+case orderStatus
+ when "Pending"
+ p.warn Your order is pending
+ when "Completed"
+ p.success Order is Completed.
+ when -1
+ p.error Error Occurred
+ default
+ p No Order Record Found
+//- <p class="warn">Your order is pending</p>
+
+//- --INCLUDE--
+//- File path -> "includes/nav.png"
+h1 Company Name
+nav
+ a(href="index.html") Home
+ a(href="about.html") About Us
+
+//- File path -> "index.png"
+html
+ body
+ include includes/nav.pug
+//-
+ <html>
+ <body>
+ <h1>Company Name</h1>
+ <nav><a href="index.html">Home</a><a href="about.html">About Us</a></nav>
+ </body>
+ </html>
+
+//- Importing JS and CSS
+script
+ include scripts/index.js
+style
+ include styles/theme.css
+
+//- ---MIXIN---
+mixin basic()
+ div Hello
++basic("Bob")
+//- <div>Hello</div>
+
+mixin comment(name, comment)
+ div
+ span.comment-name= name
+ div.comment-text= comment
++comment("Bob", "This is Awesome")
+//- <div>Hello</div>
+
+```
+
+
+### Additional Resources
+- [The Site](https://pugjs.org/)
+- [The Docs](https://pugjs.org/api/getting-started.html)
+- [Github Repo](https://github.com/pugjs/pug)
diff --git a/purescript.html.markdown b/purescript.html.markdown
index b413a9e3..6b74ac64 100644
--- a/purescript.html.markdown
+++ b/purescript.html.markdown
@@ -1,5 +1,6 @@
---
language: purescript
+filename: purescript.purs
contributors:
- ["Fredrik Dyrkell", "http://www.lexicallyscoped.com"]
- ["Thimoteus", "https://github.com/Thimoteus"]
@@ -65,12 +66,13 @@ true && (9 >= 19 || 1 < 2) -- true
"""Hello
world""" -- "Hello\nworld"
-- Concatenate
-"such " ++ "amaze" -- "such amaze"
+"such " <> "amaze" -- "such amaze"
--
-- 2. Arrays are Javascript arrays, but must be homogeneous
-[1,1,2,3,5,8] :: Array Number -- [1,1,2,3,5,8]
+[1,1,2,3,5,8] :: Array Int -- [1,1,2,3,5,8]
+[1.2,2.0,3.14] :: Array Number -- [1.2,2.0,3.14]
[true, true, false] :: Array Boolean -- [true,true,false]
-- [1,2, true, "false"] won't work
-- `Cannot unify Prim.Int with Prim.Boolean`
@@ -85,7 +87,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..e21d7dde 100644
--- a/python.html.markdown
+++ b/python.html.markdown
@@ -1,29 +1,22 @@
---
-language: python
+language: Python
contributors:
- - ["Louie Dinh", "http://ldinh.ca"]
- - ["Amin Bandali", "http://aminbandali.com"]
+ - ["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"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
+ - ["Roberto Fernandez Diaz", "https://github.com/robertofd1995"]
+ - ["caminsha", "https://github.com/caminsha"]
filename: learnpython.py
---
-Python was created by Guido Van Rossum in the early 90s. It is now one of the
-most popular languages in existence. I fell in love with Python for its
-syntactic clarity. It's basically executable pseudocode.
+Python was created by Guido van Rossum in the early 90s. It is now one of the most popular
+languages in existence. I fell in love with Python for its syntactic clarity. It's basically
+executable pseudocode.
-Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh)
-or louiedinh [at] [google's email service]
-
-Note: This article applies to Python 2.7 specifically, but should be applicable
-to Python 2.x. Python 2.7 is reaching end of life and will stop being
-maintained in 2020, it is though recommended to start learning Python with
-Python 3. For Python 3.x, take a look at the [Python 3 tutorial](http://learnxinyminutes.com/docs/python3/).
-
-It is also possible to write Python code which is compatible with Python 2.7
-and 3.x at the same time, using Python [`__future__` imports](https://docs.python.org/2/library/__future__.html). `__future__` imports
-allow you to write Python 3 code that will run on Python 2, so check out the
-Python 3 tutorial.
+Note: This article applies to Python 3 specifically. Check out [here](http://learnxinyminutes.com/docs/pythonlegacy/) if you want to learn the old Python 2.7
```python
@@ -31,10 +24,9 @@ Python 3 tutorial.
""" Multiline strings can be written
using three "s, and are often used
- as comments
+ as documentation.
"""
-
####################################################
## 1. Primitive Datatypes and Operators
####################################################
@@ -43,56 +35,64 @@ Python 3 tutorial.
3 # => 3
# Math is what you would expect
-1 + 1 # => 2
-8 - 1 # => 7
+1 + 1 # => 2
+8 - 1 # => 7
10 * 2 # => 20
-35 / 5 # => 7
+35 / 5 # => 7.0
-# Division is a bit tricky. It is integer division and floors the results
-# automatically.
-5 / 2 # => 2
+# Integer division rounds down for both positive and negative numbers.
+5 // 3 # => 1
+-5 // 3 # => -2
+5.0 // 3.0 # => 1.0 # works on floats too
+-5.0 // 3.0 # => -2.0
-# To fix division we need to learn about floats.
-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 # => -2
--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
+# The result of division is always a float
+10.0 / 3 # => 3.3333333333333335
# Modulo operation
-7 % 3 # => 1
+7 % 3 # => 1
+# i % j have the same sign as j, unlike C
+-7 % 3 # => 2
-# Exponentiation (x to the yth power)
-2**4 # => 16
+# Exponentiation (x**y, x to the yth power)
+2**3 # => 8
# Enforce precedence with parentheses
+1 + 3 * 2 # => 7
(1 + 3) * 2 # => 8
-# Boolean Operators
-# Note "and" and "or" are case-sensitive
-True and False #=> False
-False or True #=> True
-
-# Note using Bool operators with ints
-0 and 2 #=> 0
--5 or 0 #=> -5
-0 == False #=> True
-2 == True #=> False
-1 == True #=> True
+# Boolean values are primitives (Note: the capitalization)
+True # => True
+False # => False
# negate with not
-not True # => False
+not True # => False
not False # => True
+# Boolean Operators
+# Note "and" and "or" are case-sensitive
+True and False # => False
+False or True # => True
+
+# True and False are actually 1 and 0 but with different keywords
+True + True # => 2
+True * 8 # => 8
+False - 5 # => -5
+
+# Comparison operators look at the numerical value of True and False
+0 == False # => True
+1 == True # => True
+2 == True # => False
+-5 != False # => True
+
+# Using boolean logical operators on ints casts them to booleans for evaluation, but their non-cast value is returned
+# Don't mix up with bool(ints) and bitwise and/or (&,|)
+bool(0) # => False
+bool(4) # => True
+bool(-6) # => True
+0 and 2 # => 0
+-5 or 0 # => -5
+
# Equality is ==
1 == 1 # => True
2 == 1 # => False
@@ -107,93 +107,86 @@ not False # => True
2 <= 2 # => True
2 >= 2 # => True
-# Comparisons can be chained!
+# Seeing whether a value is in a range
+1 < 2 and 2 < 3 # => True
+2 < 3 and 3 < 2 # => False
+# Chaining makes this look nicer
1 < 2 < 3 # => True
2 < 3 < 2 # => False
+# (is vs. ==) is checks if two variables refer to the same object, but == checks
+# if the objects pointed to have the same values.
+a = [1, 2, 3, 4] # Point a at a new list, [1, 2, 3, 4]
+b = a # Point b at what a is pointing to
+b is a # => True, a and b refer to the same object
+b == a # => True, a's and b's objects are equal
+b = [1, 2, 3, 4] # Point b at a new list, [1, 2, 3, 4]
+b is a # => False, a and b do not refer to the same object
+b == a # => True, a's and b's objects are equal
+
# Strings are created with " or '
"This is a string."
'This is also a string.'
-# Strings can be added too!
+# Strings can be added too
"Hello " + "world!" # => "Hello world!"
-# Strings can be added without using '+'
-"Hello " "world!" # => "Hello world!"
-
-# ... or multiplied
-"Hello" * 3 # => "HelloHelloHello"
+# String literals (but not variables) can be concatenated without using '+'
+"Hello " "world!" # => "Hello world!"
# A string can be treated like a list of characters
-"This is a string"[0] # => 'T'
+"Hello world!"[0] # => 'H'
# 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.
-x = 'apple'
-y = 'lemon'
-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
-"{} is a {}".format("This", "placeholder")
-"{0} can be {1}".format("strings", "formatted")
-# You can use keywords if you don't want to count.
-"{name} wants to eat {food}".format(name="Bob", food="lasagna")
+# You can also format using f-strings or formatted string literals (in Python 3.6+)
+name = "Reiko"
+f"She said her name is {name}." # => "She said her name is Reiko"
+# You can basically put any Python expression inside the braces and it will be output in the string.
+f"{name} is {len(name)} characters long." # => "Reiko is 5 characters long."
# None is an object
None # => None
# Don't use the equality "==" symbol to compare objects to None
-# Use "is" instead
+# Use "is" instead. This checks for equality of object identity.
"etc" is None # => False
-None is None # => True
-
-# The 'is' operator tests for object identity. This isn't
-# very useful when dealing with primitive values, but is
-# very useful when dealing with objects.
-
-# Any object can be used in a Boolean context.
-# The following values are considered falsey:
-# - None
-# - zero of any numeric type (e.g., 0, 0L, 0.0, 0j)
-# - empty sequences (e.g., '', (), [])
-# - empty containers (e.g., {}, set())
-# - instances of user-defined classes meeting certain conditions
-# see: https://docs.python.org/2/reference/datamodel.html#object.__nonzero__
-#
-# All other values are truthy (using the bool() function on them returns True).
-bool(0) # => False
-bool("") # => False
+None is None # => True
+# 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
####################################################
-# Python has a print statement
-print "I'm Python. Nice to meet you!" # => I'm Python. Nice to meet you!
+# Python has a print function
+print("I'm Python. Nice to meet you!") # => I'm Python. Nice to meet you!
+
+# By default the print function also prints out a newline at the end.
+# Use the optional argument end to change the end string.
+print("Hello, World", end="!") # => Hello, World!
# 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
-# Warning: Caution is recommended for input() method usage
-# Note: In python 3, input() is deprecated and raw_input() is renamed to input()
+input_string_var = input("Enter some data: ") # Returns the data as a string
-# No need to declare variables before assigning to them.
-some_var = 5 # Convention is to use lower_case_with_underscores
+# There are no declarations, only assignments.
+# Convention is to use lower_case_with_underscores
+some_var = 5
some_var # => 5
# Accessing a previously unassigned variable is an exception.
# See Control Flow to learn more about exception handling.
-some_other_var # Raises a name error
+some_unknown_var # Raises a NameError
# if can be used as an expression
# Equivalent of C's '?:' ternary operator
-"yahoo!" if 3 > 2 else 2 # => "yahoo!"
-
+"yay!" if 0 > 1 else "nay!" # => "nay!"
# Lists store sequences
li = []
@@ -211,11 +204,7 @@ li.pop() # => 3 and li is now [1, 2, 4]
li.append(3) # li is now [1, 2, 4, 3] again.
# Access a list like you would any array
-li[0] # => 1
-# Assign new values to indexes that have already been initialized with =
-li[0] = 42
-li[0] # => 42
-li[0] = 1 # Note: setting it back to the original value
+li[0] # => 1
# Look at the last element
li[-1] # => 3
@@ -223,134 +212,159 @@ li[-1] # => 3
li[4] # Raises an IndexError
# You can look at ranges with slice syntax.
+# The start index is included, the end index is not
# (It's a closed/open range for you mathy types.)
-li[1:3] # => [2, 4]
-# Omit the beginning
-li[2:] # => [4, 3]
-# Omit the end
-li[:3] # => [1, 2, 4]
-# Select every second entry
-li[::2] # =>[1, 4]
-# Reverse a copy of the list
-li[::-1] # => [3, 4, 2, 1]
+li[1:3] # Return list from index 1 to 3 => [2, 4]
+li[2:] # Return list starting from index 2 => [4, 3]
+li[:3] # Return list from beginning until index 3 => [1, 2, 4]
+li[::2] # Return list selecting every second entry => [1, 4]
+li[::-1] # Return list in reverse order => [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]
-
-# You can add lists
-li + other_li # => [1, 2, 3, 4, 5, 6]
-# Note: values for li and for other_li are not modified.
+# Make a one layer deep copy using slices
+li2 = li[:] # => li2 = [1, 2, 4, 3] but (li2 is li) will result in false.
-# Concatenate lists with "extend()"
-li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
+# Remove arbitrary elements from a list with "del"
+del li[2] # li is now [1, 2, 3]
# Remove first occurrence of a value
-li.remove(2) # li is now [1, 3, 4, 5, 6]
+li.remove(2) # li is now [1, 3]
li.remove(2) # Raises a ValueError as 2 is not in the list
# Insert an element at a specific index
-li.insert(1, 2) # li is now [1, 2, 3, 4, 5, 6] again
+li.insert(1, 2) # li is now [1, 2, 3] again
-# Get the index of the first item found
+# Get the index of the first item found matching the argument
li.index(2) # => 1
-li.index(7) # Raises a ValueError as 7 is not in the list
+li.index(4) # Raises a ValueError as 4 is not in the list
+
+# You can add lists
+# Note: values for li and for other_li are not modified.
+li + other_li # => [1, 2, 3, 4, 5, 6]
+
+# Concatenate lists with "extend()"
+li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
# 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
+# Note that a tuple of length one has to have a comma after the last element but
+# tuples of other lengths, even zero, do not.
+type((1)) # => <class 'int'>
+type((1,)) # => <class 'tuple'>
+type(()) # => <class 'tuple'>
+
+# You can do most of the list operations on tuples too
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+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
+# You can also do extended unpacking
+a, *b, c = (1, 2, 3, 4) # a is now 1, b is now [2, 3] and c is now 4
# Tuples are created by default if you leave out the parentheses
-g = 4, 5, 6 # => (4, 5, 6)
+d, e, f = 4, 5, 6 # tuple 4, 5, 6 is unpacked into variables d, e and f
+# respectively such that d = 4, e = 5 and f = 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
+# Dictionaries store mappings from keys to values
empty_dict = {}
# Here is a prefilled dictionary
filled_dict = {"one": 1, "two": 2, "three": 3}
+# Note keys for dictionaries have to be immutable types. This is to ensure that
+# the key can be converted to a constant hash value for quick look-ups.
+# Immutable types include ints, floats, strings, tuples.
+invalid_dict = {[1,2,3]: "123"} # => Raises a TypeError: unhashable type: 'list'
+valid_dict = {(1,2,3):[1,2,3]} # Values can be of any type, however.
+
# 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"]
-# Note - Dictionary key ordering is not guaranteed.
-# Your results might not match this exactly.
+# Get all keys as an iterable with "keys()". We need to wrap the call in list()
+# to turn it into a list. We'll talk about those later. Note - for Python
+# versions <3.7, dictionary key ordering is not guaranteed. Your results might
+# not match the example below exactly. However, as of Python 3.7, dictionary
+# items maintain the order at which they are inserted into the dictionary.
+list(filled_dict.keys()) # => ["three", "two", "one"] in Python <3.7
+list(filled_dict.keys()) # => ["one", "two", "three"] in Python 3.7+
-# Get all values as a list with "values()"
-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)]
+# Get all values as an iterable with "values()". Once again we need to wrap it
+# in list() to get it out of the iterable. Note - Same as above regarding key
+# ordering.
+list(filled_dict.values()) # => [3, 2, 1] in Python <3.7
+list(filled_dict.values()) # => [1, 2, 3] in Python 3.7+
# 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
-# note that filled_dict.get("four") is still => None
-# (get doesn't set the value in the dictionary)
-
-# set the value of a key with a syntax similar to lists
-filled_dict["four"] = 4 # now, filled_dict["four"] => 4
+filled_dict.get("four", 4) # => 4
# "setdefault()" inserts into a dictionary only if the given key isn't present
filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5
filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5
+# Adding to a dictionary
+filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4}
+filled_dict["four"] = 4 # another way to add to dict
+
+# Remove keys from a dictionary with del
+del filled_dict["one"] # Removes the key "one" from filled dict
+
+# From Python 3.5 you can also use the additional unpacking options
+{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2}
+{'a': 1, **{'a': 2}} # => {'a': 2}
+
-# 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])
-# 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])
+# Sets store ... well sets
+empty_set = set()
+# Initialize a set with a bunch of values. Yeah, it looks a bit like a dict. Sorry.
+some_set = {1, 1, 2, 2, 3, 4} # some_set is now {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}
+# Similar to keys of a dictionary, elements of a set have to be immutable.
+invalid_set = {[1], 1} # => Raises a TypeError: unhashable type: 'list'
+valid_set = {(1,), 1}
-# Add more items to a set
-filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
+# Add one more item to the set
+filled_set = some_set
+filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
+# Sets do not have duplicate elements
+filled_set.add(5) # it remains as before {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}
@@ -363,24 +377,29 @@ filled_set | other_set # => {1, 2, 3, 4, 5, 6}
# Check for existence in a set with in
2 in filled_set # => True
-10 in filled_set # => False
+10 in filled_set # => False
+
+# Make a one layer deep copy
+filled_set = some_set.copy() # filled_set is {1, 2, 3, 4, 5}
+filled_set is some_set # => False
####################################################
-## 3. Control Flow
+## 3. Control Flow and Iterables
####################################################
# Let's just make a variable
some_var = 5
-# Here is an if statement. Indentation is significant in python!
-# prints "some_var is smaller than 10"
+# Here is an if statement. Indentation is significant in Python!
+# Convention is to use four spaces, not tabs.
+# This prints "some_var is smaller than 10"
if some_var > 10:
- print "some_var is totally bigger than 10."
+ print("some_var is totally bigger than 10.")
elif some_var < 10: # This elif clause is optional.
- print "some_var is smaller than 10."
-else: # This is optional too.
- print "some_var is indeed 10."
+ print("some_var is smaller than 10.")
+else: # This is optional too.
+ print("some_var is indeed 10.")
"""
@@ -391,11 +410,11 @@ prints:
mouse is a mammal
"""
for animal in ["dog", "cat", "mouse"]:
- # You can use {0} to interpolate formatted strings. (See above.)
- print "{0} is a mammal".format(animal)
+ # You can use format() to interpolate formatted strings
+ print("{} is a mammal".format(animal))
"""
-"range(number)" returns a list of numbers
+"range(number)" returns an iterable of numbers
from zero to the given number
prints:
0
@@ -404,10 +423,10 @@ prints:
3
"""
for i in range(4):
- print i
+ print(i)
"""
-"range(lower, upper)" returns a list of numbers
+"range(lower, upper)" returns an iterable of numbers
from the lower number to the upper number
prints:
4
@@ -416,7 +435,29 @@ prints:
7
"""
for i in range(4, 8):
- print i
+ print(i)
+
+"""
+"range(lower, upper, step)" returns an iterable of numbers
+from the lower number to the upper number, while incrementing
+by step. If step is not indicated, the default value is 1.
+prints:
+ 4
+ 6
+"""
+for i in range(4, 8, 2):
+ print(i)
+
+"""
+To loop over a list, and retrieve both the index and the value of each item in the list
+prints:
+ 0 dog
+ 1 cat
+ 2 mouse
+"""
+animals = ["dog", "cat", "mouse"]
+for i, value in enumerate(animals):
+ print(i, value)
"""
While loops go until a condition is no longer met.
@@ -428,28 +469,84 @@ prints:
"""
x = 0
while x < 4:
- print x
+ print(x)
x += 1 # Shorthand for x = x + 1
# Handle exceptions with a try/except block
-
-# Works on Python 2.6 and up:
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
- print "We can clean up resources here"
+ 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
with open("myfile.txt") as f:
for line in f:
- print line
+ print(line)
+
+# Writing to a file
+contents = {"aa": 12, "bb": 21}
+with open("myfile1.txt", "w+") as file:
+ file.write(str(contents)) # writes a string to a file
+
+with open("myfile2.txt", "w+") as file:
+ file.write(json.dumps(contents)) # writes an object to a file
+
+# Reading from a file
+with open('myfile1.txt', "r+") as file:
+ contents = file.read() # reads a string from a file
+print(contents)
+# print: {"aa": 12, "bb": 21}
+
+with open('myfile2.txt', "r+") as file:
+ contents = json.load(file) # reads a json object from a file
+print(contents)
+# print: {"aa": 12, "bb": 21}
+
+
+# Python offers a fundamental abstraction called the Iterable.
+# An iterable is an object that can be treated as a sequence.
+# The object returned by the range function, is an iterable.
+
+filled_dict = {"one": 1, "two": 2, "three": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) # => dict_keys(['one', 'two', 'three']). This is an object that implements our Iterable interface.
+
+# We can loop over it.
+for i in our_iterable:
+ print(i) # Prints one, two, three
+
+# However we cannot address elements by index.
+our_iterable[1] # Raises a TypeError
+
+# An iterable is an object that knows how to create an iterator.
+our_iterator = iter(our_iterable)
+
+# Our iterator is an object that can remember the state as we traverse through it.
+# We get the next object with "next()".
+next(our_iterator) # => "one"
+
+# It maintains state as we iterate.
+next(our_iterator) # => "two"
+next(our_iterator) # => "three"
+
+# After the iterator has returned all of its data, it raises a StopIteration exception
+next(our_iterator) # Raises StopIteration
+
+# We can also loop over it, in fact, "for" does this implicitly!
+our_iterator = iter(our_iterable)
+for i in our_iterator:
+ print(i) # Prints one, two, three
+
+# You can grab all the elements of an iterable or iterator by calling list() on it.
+list(our_iterable) # => Returns ["one", "two", "three"]
+list(our_iterator) # => Returns [] because state is saved
####################################################
@@ -458,36 +555,35 @@ with open("myfile.txt") as f:
# 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
+ print("x is {} and y is {}".format(x, y))
+ 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
-# positional args, which will be interpreted as a tuple by using *
+# positional arguments
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 **
+# keyword arguments, as well
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
+ print(args)
+ print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) prints:
(1, 2)
@@ -495,37 +591,41 @@ all_the_args(1, 2, a=3, b=4) prints:
"""
# When calling functions, you can do the opposite of args/kwargs!
-# Use * to expand positional args and use ** to expand keyword args.
+# Use * to expand tuples and use ** to expand kwargs.
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 all_the_args(1, 2, 3, 4)
+all_the_args(**kwargs) # equivalent to all_the_args(a=3, b=4)
+all_the_args(*args, **kwargs) # equivalent to all_the_args(1, 2, 3, 4, a=3, b=4)
+
+# Returning multiple values (with tuple assignments)
+def swap(x, y):
+ return y, x # Return multiple values as a tuple without the parenthesis.
+ # (Note: parenthesis have been excluded but can be included)
-# you can pass args and kwargs along to other functions that take args/kwargs
-# by expanding them with * and ** respectively
-def pass_all_the_args(*args, **kwargs):
- all_the_args(*args, **kwargs)
- print varargs(*args)
- print keyword_args(**kwargs)
+x = 1
+y = 2
+x, y = swap(x, y) # => x = 2, y = 1
+# (x, y) = swap(x,y) # Again parenthesis have been excluded but can be included.
# 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):
@@ -536,49 +636,92 @@ add_10 = create_adder(10)
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]
+list(map(add_10, [1, 2, 3])) # => [11, 12, 13]
+list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+list(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]
+# List comprehension stores the output as a list which can itself be a nested list
+[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
# You can construct set and dict comprehensions as well.
-{x for x in 'abcddeef' if x in 'abc'} # => {'d', 'e', 'f'}
+{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. Classes
+## 5. Modules
####################################################
-# We subclass from object to get a class.
-class Human(object):
+# You can import modules
+import math
+print(math.sqrt(16)) # => 4.0
+
+# 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
+
+# You can import all functions from a module.
+# Warning: this is not recommended
+from math import *
+
+# You can shorten module names
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
+
+# Python modules are just ordinary Python files. You
+# can write your own, and import them. The name of the
+# module is the same as the name of the file.
+
+# You can find out which functions and attributes
+# are defined in 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.
+# This happens because the local folder has priority
+# over Python's built-in libraries.
+
+
+####################################################
+## 6. Classes
+####################################################
+
+# We use the "class" statement to create a class
+class Human:
# A class attribute. It is shared by all instances of this class
species = "H. sapiens"
# Basic initializer, this is called when this class is instantiated.
# Note that the double leading and trailing underscores denote objects
- # or attributes that are used by python but that live in user-controlled
- # namespaces. You should not invent such names on your own.
+ # or attributes that are used by Python but that live in user-controlled
+ # namespaces. Methods(or objects or attributes) like: __init__, __str__,
+ # __repr__ etc. are called special methods (or sometimes called dunder methods)
+ # You should not invent such names on your own.
def __init__(self, name):
# Assign the argument to the instance's name attribute
self.name = name
# Initialize property
- self.age = 0
-
+ 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)
+ print("{name}: {message}".format(name=self.name, message=msg))
+
+ # Another instance method
+ def sing(self):
+ return 'yo... yo... microphone check... one two... one two...'
# A class method is shared among all instances
# They are called with the calling class as the first argument
@@ -592,8 +735,8 @@ class Human(object):
return "*grunt*"
# A property is just like a getter.
- # It turns the method age() into an read-only attribute
- # of the same name.
+ # It turns the method age() into an read-only attribute of the same name.
+ # There's no need to write trivial getters and setters in Python, though.
@property
def age(self):
return self._age
@@ -609,118 +752,238 @@ class Human(object):
del self._age
-# Instantiate a class
-i = Human(name="Ian")
-print i.say("hi") # prints out "Ian: hi"
+# When a Python interpreter reads a source file it executes all its code.
+# This __name__ check makes sure this code block is only executed when this
+# module is the main program.
+if __name__ == '__main__':
+ # Instantiate a class
+ i = Human(name="Ian")
+ i.say("hi") # "Ian: hi"
+ j = Human("Joel")
+ j.say("hello") # "Joel: hello"
+ # i and j are instances of type Human, or in other words: they are Human objects
+
+ # Call our class method
+ i.say(i.get_species()) # "Ian: H. sapiens"
+ # Change the shared attribute
+ Human.species = "H. neanderthalensis"
+ i.say(i.get_species()) # => "Ian: H. neanderthalensis"
+ j.say(j.get_species()) # => "Joel: H. neanderthalensis"
+
+ # Call the static method
+ print(Human.grunt()) # => "*grunt*"
+
+ # Static methods can be called by instances too
+ print(i.grunt()) # => "*grunt*"
+
+ # Update the property for this instance
+ i.age = 42
+ # Get the property
+ i.say(i.age) # => "Ian: 42"
+ j.say(j.age) # => "Joel: 0"
+ # Delete the property
+ del i.age
+ # i.age # => this would raise an AttributeError
+
+
+####################################################
+## 6.1 Inheritance
+####################################################
+
+# Inheritance allows new child classes to be defined that inherit methods and
+# variables from their parent class.
+
+# Using the Human class defined above as the base or parent class, we can
+# define a child class, Superhero, which inherits the class variables like
+# "species", "name", and "age", as well as methods, like "sing" and "grunt"
+# from the Human class, but can also have its own unique properties.
+
+# To take advantage of modularization by file you could place the classes above in their own files,
+# say, human.py
+
+# To import functions from other files use the following format
+# from "filename-without-extension" import "function-or-class"
+
+from human import Human
+
+
+# Specify the parent class(es) as parameters to the class definition
+class Superhero(Human):
+
+ # If the child class should inherit all of the parent's definitions without
+ # any modifications, you can just use the "pass" keyword (and nothing else)
+ # but in this case it is commented out to allow for a unique child class:
+ # pass
+
+ # Child classes can override their parents' attributes
+ species = 'Superhuman'
+
+ # Children automatically inherit their parent class's constructor including
+ # its arguments, but can also define additional arguments or definitions
+ # and override its methods such as the class constructor.
+ # This constructor inherits the "name" argument from the "Human" class and
+ # adds the "superpower" and "movie" arguments:
+ def __init__(self, name, movie=False,
+ superpowers=["super strength", "bulletproofing"]):
+
+ # add additional class attributes:
+ self.fictional = True
+ self.movie = movie
+ # be aware of mutable default values, since defaults are shared
+ self.superpowers = superpowers
-j = Human("Joel")
-print j.say("hello") # prints out "Joel: hello"
+ # The "super" function lets you access the parent class's methods
+ # that are overridden by the child, in this case, the __init__ method.
+ # This calls the parent class constructor:
+ super().__init__(name)
-# Call our class method
-i.get_species() # => "H. sapiens"
+ # override the sing method
+ def sing(self):
+ return 'Dun, dun, DUN!'
-# Change the shared attribute
-Human.species = "H. neanderthalensis"
-i.get_species() # => "H. neanderthalensis"
-j.get_species() # => "H. neanderthalensis"
+ # add an additional instance method
+ def boast(self):
+ for power in self.superpowers:
+ print("I wield the power of {pow}!".format(pow=power))
-# Call the static method
-Human.grunt() # => "*grunt*"
-# Update the property
-i.age = 42
+if __name__ == '__main__':
+ sup = Superhero(name="Tick")
-# Get the property
-i.age # => 42
+ # Instance type checks
+ if isinstance(sup, Human):
+ print('I am human')
+ if type(sup) is Superhero:
+ print('I am a superhero')
-# Delete the property
-del i.age
-i.age # => raises an AttributeError
+ # Get the Method Resolution search Order used by both getattr() and super()
+ # This attribute is dynamic and can be updated
+ print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
+ # => <class 'human.Human'>, <class 'object'>)
+ # Calls parent method but uses its own class attribute
+ print(sup.get_species()) # => Superhuman
+
+ # Calls overridden method
+ print(sup.sing()) # => Dun, dun, DUN!
+
+ # Calls method from Human
+ sup.say('Spoon') # => Tick: Spoon
+
+ # Call method that exists only in Superhero
+ sup.boast() # => I wield the power of super strength!
+ # => I wield the power of bulletproofing!
+
+ # Inherited class attribute
+ sup.age = 31
+ print(sup.age) # => 31
+
+ # Attribute that only exists within Superhero
+ print('Am I Oscar eligible? ' + str(sup.movie))
####################################################
-## 6. Modules
+## 6.2 Multiple Inheritance
####################################################
-# You can import modules
-import math
-print math.sqrt(16) # => 4
+# Another class definition
+# bat.py
+class Bat:
-# 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
+ species = 'Baty'
-# You can import all functions from a module.
-# Warning: this is not recommended
-from math import *
+ def __init__(self, can_fly=True):
+ self.fly = can_fly
-# You can shorten module names
-import math as m
-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
+ # This class also has a say method
+ def say(self, msg):
+ msg = '... ... ...'
+ return msg
-# Python modules are just ordinary python files. You
-# can write your own, and import them. The name of the
-# module is the same as the name of the file.
+ # And its own method as well
+ def sonar(self):
+ return '))) ... ((('
-# You can find out which functions and attributes
-# defines a module.
-import math
-dir(math)
+if __name__ == '__main__':
+ b = Bat()
+ print(b.say('hello'))
+ print(b.fly)
+
+
+# And yet another class definition that inherits from Superhero and Bat
+# superhero.py
+from superhero import Superhero
+from bat import Bat
+
+# Define Batman as a child that inherits from both Superhero and Bat
+class Batman(Superhero, Bat):
+
+ def __init__(self, *args, **kwargs):
+ # Typically to inherit attributes you have to call super:
+ # super(Batman, self).__init__(*args, **kwargs)
+ # However we are dealing with multiple inheritance here, and super()
+ # only works with the next base class in the MRO list.
+ # So instead we explicitly call __init__ for all ancestors.
+ # The use of *args and **kwargs allows for a clean way to pass arguments,
+ # with each parent "peeling a layer of the onion".
+ Superhero.__init__(self, 'anonymous', movie=True,
+ superpowers=['Wealthy'], *args, **kwargs)
+ Bat.__init__(self, *args, can_fly=False, **kwargs)
+ # override the value for the name attribute
+ self.name = 'Sad Affleck'
+
+ def sing(self):
+ return 'nan nan nan nan nan batman!'
+
+
+if __name__ == '__main__':
+ sup = Batman()
+
+ # Get the Method Resolution search Order used by both getattr() and super().
+ # This attribute is dynamic and can be updated
+ print(Batman.__mro__) # => (<class '__main__.Batman'>,
+ # => <class 'superhero.Superhero'>,
+ # => <class 'human.Human'>,
+ # => <class 'bat.Bat'>, <class 'object'>)
+
+ # Calls parent method but uses its own class attribute
+ print(sup.get_species()) # => Superhuman
+
+ # Calls overridden method
+ print(sup.sing()) # => nan nan nan nan nan batman!
+
+ # Calls method from Human, because inheritance order matters
+ sup.say('I agree') # => Sad Affleck: I agree
+
+ # Call method that exists only in 2nd ancestor
+ print(sup.sonar()) # => ))) ... (((
+
+ # Inherited class attribute
+ sup.age = 100
+ print(sup.age) # => 100
+
+ # Inherited attribute from 2nd ancestor whose default value was overridden.
+ print('Can I fly? ' + str(sup.fly)) # => Can I fly? False
-# 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.
-# This happens because the local folder has priority
-# over Python's built-in libraries.
####################################################
## 7. Advanced
####################################################
-# Generators
-# A generator "generates" values as they are requested instead of storing
-# everything up front
-
-# The following method (*NOT* a generator) will double all values and store it
-# in `double_arr`. For large size of iterables, that might get huge!
+# Generators help you make lazy code.
def double_numbers(iterable):
- double_arr = []
- for i in iterable:
- double_arr.append(i + i)
-
-# Running the following would mean we'll double all values first and return all
-# of them back to be checked by our condition
-for value in double_numbers(range(1000000)): # `test_non_generator`
- print value
- 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
-# loop and don't need to double most of the values sent in (MUCH FASTER!)
-for value in double_numbers_generator(xrange(1000000)): # `test_generator`
- print value
- if value > 5:
+# Generators are memory-efficient because they only load the data needed to
+# process the next value in the iterable. This allows them to perform
+# operations on otherwise prohibitively large value ranges.
+# NOTE: `range` replaces `xrange` in Python 3.
+for i in double_numbers(range(1, 900000000)): # `range` is a generator.
+ print(i)
+ if i >= 30:
break
-# BTW: did you notice the use of `range` in `test_non_generator` and `xrange` in `test_generator`?
-# Just as `double_numbers_generator` is the generator version of `double_numbers`
-# We have `xrange` as the generator version of `range`
-# `range` would return back and array with 1000000 values for us to use
-# `xrange` would generate 1000000 values for us as we request / iterate over those items
-
# 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])
@@ -734,11 +997,11 @@ 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
+# In this example `beg` wraps `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,13 +1012,15 @@ 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 :(
+
+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?
@@ -763,18 +1028,16 @@ print say(say_please=True) # Can you buy me a beer? Please! I am poor :(
### Free Online
* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
-* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
-* [Dive Into Python](http://www.diveintopython.net/)
-* [The Official Docs](http://docs.python.org/2/)
-* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
-* [Python Module of the Week](http://pymotw.com/2/)
-* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+* [Ideas for Python Projects](http://pythonpracticeprojects.com)
+* [The Official Docs](https://docs.python.org/3/)
+* [Hitchhiker's Guide to Python](https://docs.python-guide.org/en/latest/)
+* [Python Course](https://www.python-course.eu)
* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
-* [LearnPython](http://www.learnpython.org/)
-* [Fullstack Python](https://www.fullstackpython.com/)
-
-### Dead Tree
-
-* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
-* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
-* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+* [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](https://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](https://cscircles.cemc.uwaterloo.ca/)
+* [Dive Into Python 3](https://www.diveintopython3.net/index.html)
+* [A Crash Course in Python for Scientists](https://nbviewer.jupyter.org/gist/anonymous/5924718)
+* [Python Tutorial for Intermediates](https://pythonbasics.org/)
+* [Build a Desktop App with Python](https://pythonpyqt.com/)
diff --git a/python3.html.markdown b/python3.html.markdown
deleted file mode 100644
index 839d66fd..00000000
--- a/python3.html.markdown
+++ /dev/null
@@ -1,903 +0,0 @@
----
-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"]
-filename: learnpython3.py
----
-
-Python was created by Guido Van Rossum in the early 90s. It is now one of the most popular
-languages in existence. I fell in love with Python for its syntactic clarity. It's basically
-executable pseudocode.
-
-Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh) or louiedinh [at] [google's email service]
-
-Note: This article applies to Python 3 specifically. Check out [here](http://learnxinyminutes.com/docs/python/) if you want to learn the old Python 2.7
-
-```python
-
-# Single line comments start with a number symbol.
-
-""" Multiline strings can be written
- using three "s, and are often used
- as comments
-"""
-
-####################################################
-## 1. Primitive Datatypes and Operators
-####################################################
-
-# You have numbers
-3 # => 3
-
-# Math is what you would expect
-1 + 1 # => 2
-8 - 1 # => 7
-10 * 2 # => 20
-35 / 5 # => 7.0
-
-# Result of integer division truncated down both for positive and negative.
-5 // 3 # => 1
-5.0 // 3.0 # => 1.0 # works on floats too
--5 // 3 # => -2
--5.0 // 3.0 # => -2.0
-
-# The result of division is always a float
-10.0 / 3 # => 3.3333333333333335
-
-# Modulo operation
-7 % 3 # => 1
-
-# Exponentiation (x**y, x to the yth power)
-2**4 # => 16
-
-# Enforce precedence with parentheses
-(1 + 3) * 2 # => 8
-
-# Boolean values are primitives (Note: the capitalization)
-True
-False
-
-# negate with not
-not True # => False
-not False # => True
-
-# Boolean Operators
-# Note "and" and "or" are case-sensitive
-True and False # => False
-False or True # => True
-
-# Note using Bool operators with ints
-0 and 2 # => 0
--5 or 0 # => -5
-0 == False # => True
-2 == True # => False
-1 == True # => True
-
-# Equality is ==
-1 == 1 # => True
-2 == 1 # => False
-
-# Inequality is !=
-1 != 1 # => False
-2 != 1 # => True
-
-# More comparisons
-1 < 10 # => True
-1 > 10 # => False
-2 <= 2 # => True
-2 >= 2 # => True
-
-# Comparisons can be chained!
-1 < 2 < 3 # => True
-2 < 3 < 2 # => False
-
-# (is vs. ==) is checks if two variables refer to the same object, but == checks
-# if the objects pointed to have the same values.
-a = [1, 2, 3, 4] # Point a at a new list, [1, 2, 3, 4]
-b = a # Point b at what a is pointing to
-b is a # => True, a and b refer to the same object
-b == a # => True, a's and b's objects are equal
-b = [1, 2, 3, 4] # Point b at a new list, [1, 2, 3, 4]
-b is a # => False, a and b do not refer to the same object
-b == a # => True, a's and b's objects are equal
-
-# Strings are created with " or '
-"This is a string."
-'This is also a string.'
-
-# Strings can be added too! But try not to do this.
-"Hello " + "world!" # => "Hello world!"
-# Strings can be added without using '+'
-"Hello " "world!" # => "Hello world!"
-
-# A string can be treated like a list of characters
-"This is a string"[0] # => 'T'
-
-# You can find the length of a string
-len("This is a string") # => 16
-
-# .format can be used to format strings, like this:
-"{} can be {}".format("Strings", "interpolated") # => "Strings can be interpolated"
-
-# You can repeat the formatting arguments to save some typing.
-"{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"
-
-# You can use keywords if you don't want to count.
-"{name} wants to eat {food}".format(name="Bob", food="lasagna") # => "Bob wants to eat lasagna"
-
-# If your Python 3 code also needs to run on Python 2.5 and below, you can also
-# still use the old style of formatting:
-"%s can be %s the %s way" % ("Strings", "interpolated", "old") # => "Strings can be interpolated the old way"
-
-
-# None is an object
-None # => None
-
-# Don't use the equality "==" symbol to compare objects to None
-# Use "is" instead. This checks for equality of object identity.
-"etc" is None # => False
-None is None # => True
-
-# None, 0, and empty strings/lists/dicts all evaluate to False.
-# All other values are True
-bool(0) # => False
-bool("") # => False
-bool([]) # => False
-bool({}) # => False
-
-
-####################################################
-## 2. Variables and Collections
-####################################################
-
-# Python has a print function
-print("I'm Python. Nice to meet you!") # => I'm Python. Nice to meet you!
-
-# By default the print function also prints out a newline at the end.
-# Use the optional argument end to change the end character.
-print("Hello, World", end="!") # => Hello, World!
-
-# Simple way to get input data from console
-input_string_var = input("Enter some data: ") # Returns the data as a string
-# Note: In earlier versions of Python, input() method was named as raw_input()
-
-# No need to declare variables before assigning to them.
-# Convention is to use lower_case_with_underscores
-some_var = 5
-some_var # => 5
-
-# Accessing a previously unassigned variable is an exception.
-# See Control Flow to learn more about exception handling.
-some_unknown_var # Raises a NameError
-
-# if can be used as an expression
-# 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]
-# Remove from the end with pop
-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.
-
-# Access a list like you would any array
-li[0] # => 1
-# Look at the last element
-li[-1] # => 3
-
-# Looking out of bounds is an IndexError
-li[4] # Raises an IndexError
-
-# You can look at ranges with slice syntax.
-# (It's a closed/open range for you mathy types.)
-li[1:3] # => [2, 4]
-# Omit the beginning
-li[2:] # => [4, 3]
-# Omit the end
-li[:3] # => [1, 2, 4]
-# Select every second entry
-li[::2] # =>[1, 4]
-# Return a reversed copy of the list
-li[::-1] # => [3, 4, 2, 1]
-# Use any combination of these to make advanced slices
-# li[start:end:step]
-
-# Make a one layer deep copy using slices
-li2 = li[:] # => li2 = [1, 2, 4, 3] but (li2 is li) will result in false.
-
-# Remove arbitrary elements from a list with "del"
-del li[2] # li is now [1, 2, 3]
-
-# Remove first occurrence of a value
-li.remove(2) # li is now [1, 3]
-li.remove(2) # Raises a ValueError as 2 is not in the list
-
-# Insert an element at a specific index
-li.insert(1, 2) # li is now [1, 2, 3] again
-
-# Get the index of the first item found matching the argument
-li.index(2) # => 1
-li.index(4) # Raises a ValueError as 4 is not in the list
-
-# You can add lists
-# Note: values for li and for other_li are not modified.
-li + other_li # => [1, 2, 3, 4, 5, 6]
-
-# Concatenate lists with "extend()"
-li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
-
-# Check for existence in a list with "in"
-1 in li # => True
-
-# Examine the length with "len()"
-len(li) # => 6
-
-
-# Tuples are like lists but are immutable.
-tup = (1, 2, 3)
-tup[0] # => 1
-tup[0] = 3 # Raises a TypeError
-
-# Note that a tuple of length one has to have a comma after the last element but
-# tuples of other lengths, even zero, do not.
-type((1)) # => <class 'int'>
-type((1,)) # => <class 'tuple'>
-type(()) # => <class 'tuple'>
-
-# You can do most of the list operations on tuples too
-len(tup) # => 3
-tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
-tup[:2] # => (1, 2)
-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
-# You can also do extended unpacking
-a, *b, c = (1, 2, 3, 4) # a is now 1, b is now [2, 3] and c is now 4
-# Tuples are created by default if you leave out the parentheses
-d, e, f = 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
-
-
-# Dictionaries store mappings
-empty_dict = {}
-# Here is a prefilled dictionary
-filled_dict = {"one": 1, "two": 2, "three": 3}
-
-# Note keys for dictionaries have to be immutable types. This is to ensure that
-# the key can be converted to a constant hash value for quick look-ups.
-# Immutable types include ints, floats, strings, tuples.
-invalid_dict = {[1,2,3]: "123"} # => Raises a TypeError: unhashable type: 'list'
-valid_dict = {(1,2,3):[1,2,3]} # Values can be of any type, however.
-
-# Look up values with []
-filled_dict["one"] # => 1
-
-# Get all keys as an iterable with "keys()". We need to wrap the call in list()
-# to turn it into a list. We'll talk about those later. Note - Dictionary key
-# ordering is not guaranteed. Your results might not match this exactly.
-list(filled_dict.keys()) # => ["three", "two", "one"]
-
-
-# Get all values as an iterable with "values()". Once again we need to wrap it
-# in list() to get it out of the iterable. Note - Same as above regarding key
-# ordering.
-list(filled_dict.values()) # => [3, 2, 1]
-
-
-# Check for existence of keys in a dictionary with "in"
-"one" in filled_dict # => True
-1 in filled_dict # => False
-
-# Looking up a non-existing key is a KeyError
-filled_dict["four"] # KeyError
-
-# Use "get()" method to avoid the KeyError
-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
-
-# "setdefault()" inserts into a dictionary only if the given key isn't present
-filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5
-filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5
-
-# Adding to a dictionary
-filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4}
-#filled_dict["four"] = 4 #another way to add to dict
-
-# Remove keys from a dictionary with del
-del filled_dict["one"] # Removes the key "one" from filled dict
-
-# From Python 3.5 you can also use the additional unpacking options
-{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2}
-{'a': 1, **{'a': 2}} # => {'a': 2}
-
-
-
-# Sets store ... well sets
-empty_set = set()
-# Initialize a set with a bunch of values. Yeah, it looks a bit like a dict. Sorry.
-some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4}
-
-# Similar to keys of a dictionary, elements of a set have to be immutable.
-invalid_set = {[1], 1} # => Raises a TypeError: unhashable type: 'list'
-valid_set = {(1,), 1}
-
-# Can set new variables to a set
-filled_set = some_set
-
-# Add one more item to the set
-filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
-
-# Do set intersection with &
-other_set = {3, 4, 5, 6}
-filled_set & other_set # => {3, 4, 5}
-
-# Do set union with |
-filled_set | other_set # => {1, 2, 3, 4, 5, 6}
-
-# Do set difference with -
-{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
-
-# Check if set on the left is a subset of set on the right
-{1, 2} <= {1, 2, 3} # => True
-
-# Check for existence in a set with in
-2 in filled_set # => True
-10 in filled_set # => False
-
-
-
-####################################################
-## 3. Control Flow and Iterables
-####################################################
-
-# Let's just make a variable
-some_var = 5
-
-# Here is an if statement. Indentation is significant in python!
-# 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.
- print("some_var is smaller than 10.")
-else: # This is optional too.
- print("some_var is indeed 10.")
-
-
-"""
-For loops iterate over lists
-prints:
- dog is a mammal
- cat is a mammal
- mouse is a mammal
-"""
-for animal in ["dog", "cat", "mouse"]:
- # You can use format() to interpolate formatted strings
- print("{} is a mammal".format(animal))
-
-"""
-"range(number)" returns an iterable of numbers
-from zero to the given number
-prints:
- 0
- 1
- 2
- 3
-"""
-for i in range(4):
- print(i)
-
-"""
-"range(lower, upper)" returns an iterable of numbers
-from the lower number to the upper number
-prints:
- 4
- 5
- 6
- 7
-"""
-for i in range(4, 8):
- print(i)
-
-"""
-"range(lower, upper, step)" returns an iterable of numbers
-from the lower number to the upper number, while incrementing
-by step. If step is not indicated, the default value is 1.
-prints:
- 4
- 6
-"""
-for i in range(4, 8, 2):
- print(i)
-"""
-
-While loops go until a condition is no longer met.
-prints:
- 0
- 1
- 2
- 3
-"""
-x = 0
-while x < 4:
- print(x)
- x += 1 # Shorthand for x = x + 1
-
-# Handle exceptions with a try/except block
-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.
-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
- print("We can clean up resources here")
-
-# Instead of try/finally to cleanup resources you can use a with statement
-with open("myfile.txt") as f:
- for line in f:
- print(line)
-
-# Python offers a fundamental abstraction called the Iterable.
-# An iterable is an object that can be treated as a sequence.
-# The object returned the range function, is an iterable.
-
-filled_dict = {"one": 1, "two": 2, "three": 3}
-our_iterable = filled_dict.keys()
-print(our_iterable) # => dict_keys(['one', 'two', 'three']). This is an object that implements our Iterable interface.
-
-# We can loop over it.
-for i in our_iterable:
- print(i) # Prints one, two, three
-
-# However we cannot address elements by index.
-our_iterable[1] # Raises a TypeError
-
-# An iterable is an object that knows how to create an iterator.
-our_iterator = iter(our_iterable)
-
-# Our iterator is an object that can remember the state as we traverse through it.
-# We get the next object with "next()".
-next(our_iterator) # => "one"
-
-# It maintains state as we iterate.
-next(our_iterator) # => "two"
-next(our_iterator) # => "three"
-
-# After the iterator has returned all of its data, it gives you a StopIterator Exception
-next(our_iterator) # Raises StopIteration
-
-# You can grab all the elements of an iterator by calling list() on it.
-list(filled_dict.keys()) # => Returns ["one", "two", "three"]
-
-
-####################################################
-## 4. Functions
-####################################################
-
-# Use "def" to create new functions
-def add(x, y):
- print("x is {} and y is {}".format(x, y))
- 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
-
-# Another way to call functions is with keyword arguments
-add(y=6, x=5) # Keyword arguments can arrive in any order.
-
-# You can define functions that take a variable number of
-# positional arguments
-def varargs(*args):
- return args
-
-varargs(1, 2, 3) # => (1, 2, 3)
-
-# You can define functions that take a variable number of
-# keyword arguments, as well
-def keyword_args(**kwargs):
- return kwargs
-
-# Let's call it to see what happens
-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)
- {"a": 3, "b": 4}
-"""
-
-# When calling functions, you can do the opposite of args/kwargs!
-# Use * to expand tuples and use ** to expand kwargs.
-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)
-
-# Returning multiple values (with tuple assignments)
-def swap(x, y):
- return y, x # Return multiple values as a tuple without the parenthesis.
- # (Note: parenthesis have been excluded but can be included)
-
-x = 1
-y = 2
-x, y = swap(x, y) # => x = 2, y = 1
-# (x, y) = swap(x,y) # Again parenthesis have been excluded but can be included.
-
-# Function Scope
-x = 5
-
-def set_x(num):
- # Local var x not the same as global variable x
- 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
-
-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
-
-# There are also anonymous functions
-(lambda x: x > 2)(3) # => True
-(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
-
-# There are built-in higher order functions
-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]
-
-# We can use list comprehensions for nice maps and filters
-# List comprehension stores the output as a list which can itself be a nested list
-[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
-[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
-
-# You can construct set and dict comprehensions as well.
-{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. Modules
-####################################################
-
-# You can import modules
-import math
-print(math.sqrt(16)) # => 4.0
-
-# 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
-
-# You can import all functions from a module.
-# Warning: this is not recommended
-from math import *
-
-# You can shorten module names
-import math as m
-math.sqrt(16) == m.sqrt(16) # => True
-
-# Python modules are just ordinary python files. You
-# can write your own, and import them. The name of the
-# module is the same as the name of the file.
-
-# 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.
-# This happens because the local folder has priority
-# over Python's built-in libraries.
-
-
-####################################################
-## 6. Classes
-####################################################
-
-# We use the "class" operator to get a class
-class Human:
-
- # A class attribute. It is shared by all instances of this class
- species = "H. sapiens"
-
- # Basic initializer, this is called when this class is instantiated.
- # Note that the double leading and trailing underscores denote objects
- # or attributes that are used by python but that live in user-controlled
- # namespaces. Methods(or objects or attributes) like: __init__, __str__,
- # __repr__ etc. are called magic methods (or sometimes called dunder methods)
- # You should not invent such names on your own.
- def __init__(self, name):
- # Assign the argument to the instance's name attribute
- self.name = name
-
- # Initialize property
- self.age = 0
-
- # An instance method. All methods take "self" as the first argument
- def say(self, msg):
- print ("{name}: {message}".format(name=self.name, message=msg))
-
- # Another instance method
- def sing(self):
- return 'yo... yo... microphone check... one two... one two...'
-
- # A class method is shared among all instances
- # They are called with the calling class as the first argument
- @classmethod
- def get_species(cls):
- return cls.species
-
- # A static method is called without a class or instance reference
- @staticmethod
- def grunt():
- return "*grunt*"
-
- # A property is just like a getter.
- # It turns the method age() into an read-only attribute
- # of the same name.
- @property
- def age(self):
- return self._age
-
- # This allows the property to be set
- @age.setter
- def age(self, age):
- self._age = age
-
- # This allows the property to be deleted
- @age.deleter
- def age(self):
- del self._age
-
-
-# When a Python interpreter reads a source file it executes all its code.
-# This __name__ check makes sure this code block is only executed when this
-# module is the main program.
-if __name__ == '__main__':
- # Instantiate a class
- i = Human(name="Ian")
- i.say("hi") # "Ian: hi"
- j = Human("Joel")
- j.say("hello") # "Joel: hello"
- # i and j are instances of type Human, or in other words: they are Human objects
-
- # Call our class method
- i.say(i.get_species()) # "Ian: H. sapiens"
- # Change the shared attribute
- Human.species = "H. neanderthalensis"
- i.say(i.get_species()) # => "Ian: H. neanderthalensis"
- j.say(j.get_species()) # => "Joel: H. neanderthalensis"
-
- # Call the static method
- print(Human.grunt()) # => "*grunt*"
- print(i.grunt()) # => "*grunt*"
-
- # Update the property for this instance
- i.age = 42
- # Get the property
- i.say(i.age) # => 42
- j.say(j.age) # => 0
- # Delete the property
- del i.age
- # i.age # => this would raise an AttributeError
-
-
-####################################################
-## 6.1 Multiple Inheritance
-####################################################
-
-# Another class definition
-class Bat:
-
- species = 'Baty'
-
- def __init__(self, can_fly=True):
- self.fly = can_fly
-
- # This class also has a say method
- def say(self, msg):
- msg = '... ... ...'
- return msg
-
- # And its own method as well
- def sonar(self):
- return '))) ... ((('
-
-if __name__ == '__main__':
- b = Bat()
- print(b.say('hello'))
- print(b.fly)
-
-# To take advantage of modularization by file you could place the classes above in their own files,
-# say, human.py and bat.py
-
-# to import functions from other files use the following format
-# from "filename-without-extension" import "function-or-class"
-
-# superhero.py
-from human import Human
-from bat import Bat
-
-# Batman inherits from both Human and Bat
-class Batman(Human, Bat):
-
- # Batman has its own value for the species class attribute
- species = 'Superhero'
-
- def __init__(self, *args, **kwargs):
- # Typically to inherit attributes you have to call super:
- #super(Batman, self).__init__(*args, **kwargs)
- # However we are dealing with multiple inheritance here, and super()
- # only works with the next base class in the MRO list.
- # So instead we explicitly call __init__ for all ancestors.
- # The use of *args and **kwargs allows for a clean way to pass arguments,
- # with each parent "peeling a layer of the onion".
- Human.__init__(self, 'anonymous', *args, **kwargs)
- Bat.__init__(self, *args, can_fly=False, **kwargs)
- # override the value for the name attribute
- self.name = 'Sad Affleck'
-
- def sing(self):
- return 'nan nan nan nan nan batman!'
-
-
-if __name__ == '__main__':
- sup = Batman()
-
- # Instance type checks
- 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')
-
- # Get the Method Resolution search Order used by both getattr() and super().
- # This attribute is dynamic and can be updated
- print(Batman.__mro__) # => (<class '__main__.Batman'>, <class 'human.Human'>, <class 'bat.Bat'>, <class 'object'>)
-
- # Calls parent method but uses its own class attribute
- print(sup.get_species()) # => Superhero
-
- # Calls overloaded method
- print(sup.sing()) # => nan nan nan nan nan batman!
-
- # Calls method from Human, because inheritance order matters
- sup.say('I agree') # => Sad Affleck: I agree
-
- # Call method that exists only in 2nd ancestor
- print(sup.sonar()) # => ))) ... (((
-
- # Inherited class attribute
- sup.age = 100
- print(sup.age)
-
- # Inherited attribute from 2nd ancestor whose default value was overridden.
- print('Can I fly? ' + str(sup.fly))
-
-
-
-####################################################
-## 7. Advanced
-####################################################
-
-# Generators help you make lazy code.
-def double_numbers(iterable):
- for i in iterable:
- yield i + i
-
-# Generators are memory-efficient because they only load the data needed to
-# process the next value in the iterable. This allows them to perform
-# operations on otherwise prohibitively large value ranges.
-# NOTE: `range` replaces `xrange` in Python 3.
-for i in double_numbers(range(1, 900000000)): # `range` is a generator.
- print(i)
- if i >= 30:
- break
-
-# 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])
-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])
-gen_to_list = list(values)
-print(gen_to_list) # => [-1, -2, -3, -4, -5]
-
-
-# Decorators
-# In this example `beg` wraps `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):
- 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/pythonlegacy.html.markdown b/pythonlegacy.html.markdown
new file mode 100644
index 00000000..95d6aa63
--- /dev/null
+++ b/pythonlegacy.html.markdown
@@ -0,0 +1,827 @@
+---
+language: Python 2 (legacy)
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+ - ["Amin Bandali", "https://aminb.org"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+ - ["evuez", "http://github.com/evuez"]
+ - ["asyne", "https://github.com/justblah"]
+ - ["habi", "http://github.com/habi"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
+filename: learnpythonlegacy.py
+---
+
+Python was created by Guido Van Rossum in the early 90s. It is now one of the
+most popular languages in existence. I fell in love with Python for its
+syntactic clarity. It's basically executable pseudocode.
+
+Feedback would be highly appreciated! You can reach me at [@louiedinh](http://twitter.com/louiedinh)
+or louiedinh [at] [google's email service]
+
+Note: This article applies to Python 2.7 specifically, but should be applicable
+to Python 2.x. Python 2.7 is reaching end of life and will stop being
+maintained in 2020, it is though recommended to start learning Python with
+Python 3. For Python 3.x, take a look at the [Python 3 tutorial](http://learnxinyminutes.com/docs/python/).
+
+It is also possible to write Python code which is compatible with Python 2.7
+and 3.x at the same time, using Python [`__future__` imports](https://docs.python.org/2/library/__future__.html). `__future__` imports
+allow you to write Python 3 code that will run on Python 2, so check out the
+Python 3 tutorial.
+
+```python
+
+# Single line comments start with a number symbol.
+
+""" Multiline strings can be written
+ using three "s, and are often used
+ as comments
+"""
+
+####################################################
+# 1. Primitive Datatypes and Operators
+####################################################
+
+# You have numbers
+3 # => 3
+
+# Math is what you would expect
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7
+
+# Division is a bit tricky. It is integer division and floors the results
+# automatically.
+5 / 2 # => 2
+
+# To fix division we need to learn about floats.
+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 # => -2
+-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
+
+# Modulo operation
+7 % 3 # => 1
+
+# Exponentiation (x to the yth power)
+2 ** 4 # => 16
+
+# Enforce precedence with parentheses
+(1 + 3) * 2 # => 8
+
+# Boolean Operators
+# Note "and" and "or" are case-sensitive
+True and False # => False
+False or True # => True
+
+# Note using Bool operators with ints
+0 and 2 # => 0
+-5 or 0 # => -5
+0 == False # => True
+2 == True # => False
+1 == True # => True
+
+# negate with not
+not True # => False
+not False # => True
+
+# Equality is ==
+1 == 1 # => True
+2 == 1 # => False
+
+# Inequality is !=
+1 != 1 # => False
+2 != 1 # => True
+
+# More comparisons
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# Comparisons can be chained!
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# Strings are created with " or '
+"This is a string."
+'This is also a string.'
+
+# Strings can be added too!
+"Hello " + "world!" # => "Hello world!"
+# Strings can be added without using '+'
+"Hello " "world!" # => "Hello world!"
+
+# ... or multiplied
+"Hello" * 3 # => "HelloHelloHello"
+
+# A string can be treated like a list of characters
+"This is a string"[0] # => 'T'
+
+# 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.
+x = 'apple'
+y = 'lemon'
+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
+"{} is a {}".format("This", "placeholder")
+"{0} can be {1}".format("strings", "formatted")
+# You can use keywords if you don't want to count.
+"{name} wants to eat {food}".format(name="Bob", food="lasagna")
+
+# None is an object
+None # => None
+
+# Don't use the equality "==" symbol to compare objects to None
+# Use "is" instead
+"etc" is None # => False
+None is None # => True
+
+# The 'is' operator tests for object identity. This isn't
+# very useful when dealing with primitive values, but is
+# very useful when dealing with objects.
+
+# Any object can be used in a Boolean context.
+# The following values are considered falsey:
+# - None
+# - zero of any numeric type (e.g., 0, 0L, 0.0, 0j)
+# - empty sequences (e.g., '', (), [])
+# - empty containers (e.g., {}, set())
+# - instances of user-defined classes meeting certain conditions
+# see: https://docs.python.org/2/reference/datamodel.html#object.__nonzero__
+#
+# All other values are truthy (using the bool() function on them returns True).
+bool(0) # => False
+bool("") # => False
+
+
+####################################################
+# 2. Variables and Collections
+####################################################
+
+# Python has a print statement
+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
+# 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
+
+# Accessing a previously unassigned variable is an exception.
+# See Control Flow to learn more about exception handling.
+some_other_var # Raises a name error
+
+# if can be used as an expression
+# 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]
+# Remove from the end with pop
+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.
+
+# Access a list like you would any array
+li[0] # => 1
+# Assign new values to indexes that have already been initialized with =
+li[0] = 42
+li[0] # => 42
+li[0] = 1 # Note: setting it back to the original value
+# Look at the last element
+li[-1] # => 3
+
+# Looking out of bounds is an IndexError
+li[4] # Raises an IndexError
+
+# You can look at ranges with slice syntax.
+# (It's a closed/open range for you mathy types.)
+li[1:3] # => [2, 4]
+# Omit the beginning
+li[2:] # => [4, 3]
+# Omit the end
+li[:3] # => [1, 2, 4]
+# Select every second entry
+li[::2] # =>[1, 4]
+# Reverse a copy of the list
+li[::-1] # => [3, 4, 2, 1]
+# Use any combination of these to make advanced slices
+# li[start:end:step]
+
+# Remove arbitrary elements from a list with "del"
+del li[2] # li is now [1, 2, 3]
+
+# You can add lists
+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]
+
+# Remove first occurrence of a value
+li.remove(2) # li is now [1, 3, 4, 5, 6]
+li.remove(2) # Raises a ValueError as 2 is not in the list
+
+# Insert an element at a specific index
+li.insert(1, 2) # li is now [1, 2, 3, 4, 5, 6] again
+
+# Get the index of the first item found
+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
+
+# Examine the length with "len()"
+len(li) # => 6
+
+# Tuples are like lists but are immutable.
+tup = (1, 2, 3)
+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
+
+# 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
+# Tuples are created by default if you leave out the parentheses
+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
+
+# Dictionaries store mappings
+empty_dict = {}
+# Here is a prefilled dictionary
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Look up values with []
+filled_dict["one"] # => 1
+
+# Get all keys as a list with "keys()"
+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]
+# Note - Same as above regarding key ordering.
+
+# Get all key-value pairs as a list of tuples with "items()"
+filled_dict.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
+
+# Looking up a non-existing key is a KeyError
+filled_dict["four"] # KeyError
+
+# Use "get()" method to avoid the KeyError
+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
+# note that filled_dict.get("four") is still => None
+# (get doesn't set the value in the dictionary)
+
+# set the value of a key with a syntax similar to lists
+filled_dict["four"] = 4 # now, filled_dict["four"] => 4
+
+# "setdefault()" inserts into a dictionary only if the given key isn't present
+filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5
+filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5
+
+# You can declare sets (which are like unordered lists that cannot contain
+# duplicate values) using the set object.
+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])
+
+# 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}
+
+# Add more items to a set
+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}
+
+# Do set union with |
+filled_set | other_set # => {1, 2, 3, 4, 5, 6}
+
+# Do set difference with -
+{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
+
+# Check if set on the left is a subset of set on the right
+{1, 2} <= {1, 2, 3} # => True
+
+# Check for existence in a set with in
+2 in filled_set # => True
+10 in filled_set # => False
+10 not in filled_set # => True
+
+# Check data type of variable
+type(li) # => list
+type(filled_dict) # => dict
+type(5) # => int
+
+
+####################################################
+# 3. Control Flow
+####################################################
+
+# Let's just make a variable
+some_var = 5
+
+# Here is an if statement. Indentation is significant in python!
+# 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.
+ print "some_var is smaller than 10."
+else: # This is optional too.
+ print "some_var is indeed 10."
+
+"""
+For loops iterate over lists
+prints:
+ dog is a mammal
+ cat is a mammal
+ mouse is a mammal
+"""
+for animal in ["dog", "cat", "mouse"]:
+ # You can use {0} to interpolate formatted strings. (See above.)
+ print "{0} is a mammal".format(animal)
+
+"""
+"range(number)" returns a list of numbers
+from zero to the given number
+prints:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+"range(lower, upper)" returns a list of numbers
+from the lower number to the upper number
+prints:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print i
+
+"""
+While loops go until a condition is no longer met.
+prints:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # Shorthand for x = x + 1
+
+# Handle exceptions with a try/except block
+
+# Works on Python 2.6 and up:
+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.
+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
+ print "We can clean up resources here"
+
+# Instead of try/finally to cleanup resources you can use a with statement
+with open("myfile.txt") as f:
+ for line in f:
+ print line
+
+
+####################################################
+# 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
+
+
+# Calling functions with parameters
+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.
+
+
+# You can define functions that take a variable number of
+# positional args, which will be interpreted as a tuple by using *
+def varargs(*args):
+ return args
+
+
+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"}
+
+
+# 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)
+ {"a": 3, "b": 4}
+"""
+
+# When calling functions, you can do the opposite of args/kwargs!
+# 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 all_the_args(1, 2, 3, 4)
+all_the_args(**kwargs) # equivalent to all_the_args(a=3, b=4)
+all_the_args(*args, **kwargs) # equivalent to all_the_args(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
+def pass_all_the_args(*args, **kwargs):
+ 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
+
+
+def set_global_x(num):
+ global x
+ 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
+
+# There are also anonymous functions
+(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]
+
+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]
+
+# You can construct set and dict comprehensions as well.
+{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
+####################################################
+
+# 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"
+
+ # Basic initializer, this is called when this class is instantiated.
+ # Note that the double leading and trailing underscores denote objects
+ # or attributes that are used by python but that live in user-controlled
+ # namespaces. You should not invent such names on your own.
+ def __init__(self, name):
+ # Assign the argument to the instance's name attribute
+ self.name = name
+
+ # 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)
+
+ # A class method is shared among all instances
+ # They are called with the calling class as the first argument
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # A static method is called without a class or instance reference
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+ # A property is just like a getter.
+ # It turns the method age() into an read-only attribute
+ # of the same name.
+ @property
+ def age(self):
+ return self._age
+
+ # This allows the property to be set
+ @age.setter
+ def age(self, age):
+ self._age = age
+
+ # This allows the property to be deleted
+ @age.deleter
+ def age(self):
+ del self._age
+
+
+# Instantiate a class
+i = Human(name="Ian")
+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"
+
+# Change the shared attribute
+Human.species = "H. neanderthalensis"
+i.get_species() # => "H. neanderthalensis"
+j.get_species() # => "H. neanderthalensis"
+
+# Call the static method
+Human.grunt() # => "*grunt*"
+
+# Update the property
+i.age = 42
+
+# Get the property
+i.age # => 42
+
+# Delete the property
+del i.age
+i.age # => raises an AttributeError
+
+####################################################
+# 6. Modules
+####################################################
+
+# You can import modules
+import math
+
+print math.sqrt(16) # => 4.0
+
+# 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
+
+# You can import all functions from a module.
+# Warning: this is not recommended
+from math import *
+
+# You can shorten module names
+import math as m
+
+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
+# can write your own, and import them. The name of the
+# module is the same as the name of the file.
+
+# 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.
+# This happens because the local folder has priority
+# over Python's built-in libraries.
+
+
+####################################################
+# 7. Advanced
+####################################################
+
+# Generators
+# A generator "generates" values as they are requested instead of storing
+# everything up front
+
+# The following method (*NOT* a generator) will double all values and store it
+# in `double_arr`. For large size of iterables, that might get huge!
+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
+for value in double_numbers(range(1000000)): # `test_non_generator`
+ print value
+ 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
+# loop and don't need to double most of the values sent in (MUCH FASTER!)
+for value in double_numbers_generator(xrange(1000000)): # `test_generator`
+ print value
+ if value > 5:
+ break
+
+# BTW: did you notice the use of `range` in `test_non_generator` and `xrange` in `test_generator`?
+# Just as `double_numbers_generator` is the generator version of `double_numbers`
+# We have `xrange` as the generator version of `range`
+# `range` would return back and array with 1000000 values for us to use
+# `xrange` would generate 1000000 values for us as we request / iterate over those items
+
+# 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])
+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])
+gen_to_list = list(values)
+print(gen_to_list) # => [-1, -2, -3, -4, -5]
+
+# Decorators
+# A decorator is a higher order function, which accepts and returns a function.
+# Simple usage example – add_apples decorator will add 'Apple' element into
+# fruits list returned by get_fruits target function.
+def add_apples(func):
+ def get_fruits():
+ fruits = func()
+ fruits.append('Apple')
+ return fruits
+ return get_fruits
+
+@add_apples
+def get_fruits():
+ return ['Banana', 'Mango', 'Orange']
+
+# Prints out the list of fruits with 'Apple' element in it:
+# Banana, Mango, Orange, Apple
+print ', '.join(get_fruits())
+
+# 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):
+ 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)
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
+* [LearnPython](http://www.learnpython.org/)
+* [Fullstack Python](https://www.fullstackpython.com/)
+
+### Dead Tree
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
diff --git a/pythonstatcomp.html.markdown b/pythonstatcomp.html.markdown
index 8ee3aa64..4cff3535 100644
--- a/pythonstatcomp.html.markdown
+++ b/pythonstatcomp.html.markdown
@@ -13,10 +13,11 @@ This is a tutorial on how to do some typical statistical programming tasks using
# 0. Getting set up ====
-""" Get set up with IPython and pip install the following: numpy, scipy, pandas,
+""" To get started, pip install the following: jupyter, numpy, scipy, pandas,
matplotlib, seaborn, requests.
- Make sure to do this tutorial in the IPython notebook so that you get
- the inline plots and easy documentation lookup.
+ Make sure to do this tutorial in a Jupyter notebook so that you get
+ the inline plots and easy documentation lookup. The shell command to open
+ one is simply `jupyter notebook`, then click New -> Python.
"""
# 1. Data acquisition ====
@@ -37,18 +38,16 @@ r.text # raw page source
print(r.text) # prettily formatted
# save the page source in a file:
os.getcwd() # check what's the working directory
-f = open("learnxinyminutes.html", "wb")
-f.write(r.text.encode("UTF-8"))
-f.close()
+with open("learnxinyminutes.html", "wb") as f:
+ f.write(r.text.encode("UTF-8"))
# downloading a csv
fp = "https://raw.githubusercontent.com/adambard/learnxinyminutes-docs/master/"
fn = "pets.csv"
r = requests.get(fp + fn)
print(r.text)
-f = open(fn, "wb")
-f.write(r.text.encode("UTF-8"))
-f.close()
+with open(fn, "wb") as f:
+ f.write(r.text.encode("UTF-8"))
""" for more on the requests module, including APIs, see
http://docs.python-requests.org/en/latest/user/quickstart/
@@ -70,8 +69,8 @@ pets
# 1 vesuvius 6 23 fish
# 2 rex 5 34 dog
-""" R users: note that Python, like most normal programming languages, starts
- indexing from 0. R is the unusual one for starting from 1.
+""" R users: note that Python, like most C-influenced programming languages, starts
+ indexing from 0. R starts indexing at 1 due to Fortran influence.
"""
# two different ways to print out a column
@@ -104,7 +103,7 @@ import matplotlib as mpl
import matplotlib.pyplot as plt
%matplotlib inline
-# To do data vizualization in Python, use matplotlib
+# To do data visualization in Python, use matplotlib
plt.hist(pets.age);
@@ -147,7 +146,7 @@ ggplot(aes(x="age",y="weight"), data=pets) + geom_point() + labs(title="pets")
"""
# load some data on Holy Roman Emperors
-url = "https://raw.githubusercontent.com/e99n09/R-notes/master/data/hre.csv"
+url = "https://raw.githubusercontent.com/adambard/learnxinyminutes-docs/master/hre.csv"
r = requests.get(url)
fp = "hre.csv"
with open(fp, "wb") as f:
@@ -157,26 +156,19 @@ hre = pd.read_csv(fp)
hre.head()
"""
- Ix Dynasty Name Birth Death Election 1
-0 NaN Carolingian Charles I 2 April 742 28 January 814 NaN
-1 NaN Carolingian Louis I 778 20 June 840 NaN
-2 NaN Carolingian Lothair I 795 29 September 855 NaN
-3 NaN Carolingian Louis II 825 12 August 875 NaN
-4 NaN Carolingian Charles II 13 June 823 6 October 877 NaN
-
- Election 2 Coronation 1 Coronation 2 Ceased to be Emperor
-0 NaN 25 December 800 NaN 28 January 814
-1 NaN 11 September 813 5 October 816 20 June 840
-2 NaN 5 April 823 NaN 29 September 855
-3 NaN Easter 850 18 May 872 12 August 875
-4 NaN 29 December 875 NaN 6 October 877
-
- Descent from whom 1 Descent how 1 Descent from whom 2 Descent how 2
-0 NaN NaN NaN NaN
-1 Charles I son NaN NaN
-2 Louis I son NaN NaN
-3 Lothair I son NaN NaN
-4 Louis I son NaN NaN
+ Ix Dynasty Name Birth Death
+0 NaN Carolingian Charles I 2 April 742 28 January 814
+1 NaN Carolingian Louis I 778 20 June 840
+2 NaN Carolingian Lothair I 795 29 September 855
+3 NaN Carolingian Louis II 825 12 August 875
+4 NaN Carolingian Charles II 13 June 823 6 October 877
+
+ Coronation 1 Coronation 2 Ceased to be Emperor
+0 25 December 800 NaN 28 January 814
+1 11 September 813 5 October 816 20 June 840
+2 5 April 823 NaN 29 September 855
+3 Easter 850 18 May 872 12 August 875
+4 29 December 875 NaN 6 October 877
"""
# clean the Birth and Death columns
@@ -194,6 +186,8 @@ rx = re.compile(r'\d+$') # match trailing digits
- http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.html
"""
+from functools import reduce
+
def extractYear(v):
return(pd.Series(reduce(lambda x, y: x + y, map(rx.findall, v), [])).astype(int))
@@ -204,7 +198,7 @@ hre["DeathY"] = extractYear(hre.Death)
hre["EstAge"] = hre.DeathY.astype(int) - hre.BirthY.astype(int)
# simple scatterplot, no trend line, color represents dynasty
-sns.lmplot("BirthY", "EstAge", data=hre, hue="Dynasty", fit_reg=False);
+sns.lmplot("BirthY", "EstAge", data=hre, hue="Dynasty", fit_reg=False)
# use scipy to run a linear regression
from scipy import stats
@@ -221,7 +215,7 @@ rval**2 # 0.020363950027333586
pval # 0.34971812581498452
# use seaborn to make a scatterplot and plot the linear regression trend line
-sns.lmplot("BirthY", "EstAge", data=hre);
+sns.lmplot("BirthY", "EstAge", data=hre)
""" For more information on seaborn, see
- http://web.stanford.edu/~mwaskom/software/seaborn/
diff --git a/qsharp.html.markdown b/qsharp.html.markdown
new file mode 100644
index 00000000..b256043c
--- /dev/null
+++ b/qsharp.html.markdown
@@ -0,0 +1,204 @@
+---
+language: Q#
+contributors:
+ - ["Vincent van Wingerden", "https://github.com/vivanwin"]
+ - ["Mariia Mykhailova", "https://github.com/tcNickolas"]
+ - ["Andrew Ryan Davis", "https://github.com/AndrewDavis1191"]
+filename: LearnQSharp.qs
+---
+
+Q# is a high-level domain-specific language which enables developers to write quantum algorithms. Q# programs can be executed on a quantum simulator running on a classical computer and (in future) on quantum computers.
+
+```C#
+// Single-line comments start with //
+
+
+/////////////////////////////////////
+// 1. Quantum data types and operators
+
+// The most important part of quantum programs is qubits.
+// In Q# type Qubit represents the qubits which can be used.
+// This will allocate an array of two new qubits as the variable qs.
+using (qs = Qubit[2]) {
+
+ // The qubits have internal state that you cannot access to read or modify directly.
+ // You can inspect the current state of your quantum program
+ // if you're running it on a classical simulator.
+ // Note that this will not work on actual quantum hardware!
+ DumpMachine();
+
+ // If you want to change the state of a qubit
+ // you have to do this by applying quantum gates to the qubit.
+ H(q[0]); // This changes the state of the first qubit
+ // from |0⟩ (the initial state of allocated qubits)
+ // to (|0⟩ + |1⟩) / sqrt(2).
+ // q[1] = |1⟩; - this does NOT work, you have to manipulate a qubit by using gates.
+
+ // You can apply multi-qubit gates to several qubits.
+ CNOT(qs[0], qs[1]);
+
+ // You can also apply a controlled version of a gate:
+ // a gate that is applied if all control qubits are in |1⟩ state.
+ // The first argument is an array of control qubits,
+ // the second argument is the target qubit.
+ Controlled Y([qs[0]], qs[1]);
+
+ // If you want to apply an anti-controlled gate
+ // (a gate that is applied if all control qubits are in |0⟩ state),
+ // you can use a library function.
+ ApplyControlledOnInt(0, X, [qs[0]], qs[1]);
+
+ // To read the information from the quantum system, you use measurements.
+ // Measurements return a value of Result data type: Zero or One.
+ // You can print measurement results as a classical value.
+ Message($"Measured {M(qs[0])}, {M(qs[1])}");
+}
+
+
+/////////////////////////////////////
+// 2. Classical data types and operators
+
+// Numbers in Q# can be stored in Int, BigInt or Double.
+let i = 1; // This defines an Int variable i equal to 1
+let bi = 1L; // This defines a BigInt variable bi equal to 1
+let d = 1.0; // This defines a Double variable d equal to 1
+
+// Arithmetic is done as expected, as long as the types are the same
+let n = 2 * 10; // = 20
+// Q# does not have implicit type cast,
+// so to perform arithmetic on values of different types,
+// you need to cast type explicitly
+let nd = IntAsDouble(2) * 1.0; // = 20.0
+
+// Boolean type is called Bool
+let trueBool = true;
+let falseBool = false;
+
+// Logic operators work as expected
+let andBool = true and false;
+let orBool = true or false;
+let notBool = not false;
+
+// Strings
+let str = "Hello World!";
+
+// Equality is ==
+let x = 10 == 15; // is false
+
+// Range is a sequence of integers and can be defined like: start..step..stop
+let xi = 1..2..7; // Gives the sequence 1,3,5,7
+
+// Assigning new value to a variable:
+// by default all Q# variables are immutable;
+// if the variable was defined using let, you cannot reassign its value.
+
+// When you want to make a variable mutable, you have to declare it as such,
+// and use the set word to update value
+mutable xii = true;
+set xii = false;
+
+// You can create an array for any data type like this
+let xiii = new Double[10];
+
+// Getting an element from an array
+let xiv = xiii[8];
+
+// Assigning a new value to an array element
+mutable xv = new Double[10];
+set xv w/= 5 <- 1;
+
+
+/////////////////////////////////////
+// 3. Control flow
+
+// If structures work a little different than most languages
+if (a == 1) {
+ // ...
+} elif (a == 2) {
+ // ...
+} else {
+ // ...
+}
+
+// Foreach loops can be used to iterate over an array
+for (qubit in qubits) {
+ X(qubit);
+}
+
+// Regular for loops can be used to iterate over a range of numbers
+for (index in 0 .. Length(qubits) - 1) {
+ X(qubits[index]);
+}
+
+// While loops are restricted for use in classical context only
+mutable index = 0;
+while (index < 10) {
+ set index += 1;
+}
+
+// Quantum equivalent of a while loop is a repeat-until-success loop.
+// Because of the probabilistic nature of quantum computing sometimes
+// you want to repeat a certain sequence of operations
+// until a specific condition is achieved; you can use this loop to express this.
+repeat {
+ // Your operation here
+}
+until (success criteria) // This could be a measurement to check if the state is reached
+fixup {
+ // Resetting to the initial conditions, if required
+}
+
+
+/////////////////////////////////////
+// 4. Putting it all together
+
+// Q# code is written in operations and functions
+operation ApplyXGate(source : Qubit) : Unit {
+ X(source);
+}
+
+// If the operation implements a unitary transformation, you can define
+// adjoint and controlled variants of it.
+// The easiest way to do that is to add "is Adj + Ctl" after Unit.
+// This will tell the compiler to generate the variants automatically.
+operation ApplyXGateCA (source : Qubit) : Unit is Adj + Ctl {
+ X(source);
+}
+
+// Now you can call Adjoint ApplyXGateCA and Controlled ApplyXGateCA.
+
+
+// To run Q# code, you can put @EntryPoint() before the operation you want to run first
+@EntryPoint()
+operation XGateDemo() : Unit {
+ using (q = Qubit()) {
+ ApplyXGate(q);
+ }
+}
+
+// Here is a simple example: a quantum random number generator.
+// We will generate a classical array of random bits using quantum code.
+@EntryPoint()
+operation QRNGDemo() : Unit {
+ mutable bits = new Int[5]; // Array we'll use to store bits
+ using (q = Qubit()) { // Allocate a qubit
+ for (i in 0 .. 4) { // Generate each bit independently
+ H(q); // Hadamard gate sets equal superposition
+ let result = M(q); // Measure qubit gets 0|1 with 50/50 prob
+ let bit = result == Zero ? 0 | 1; // Convert measurement result to integer
+ set bits w/= i <- bit; // Write generated bit to an array
+ }
+ }
+ Message($"{bits}"); // Print the result
+}
+```
+
+
+## Further Reading
+
+The [Quantum Katas][1] offer great self-paced tutorials and programming exercises to learn quantum computing and Q#.
+
+[Q# Documentation][2] is official Q# documentation, including language reference and user guides.
+
+[1]: https://github.com/microsoft/QuantumKatas
+[2]: https://docs.microsoft.com/quantum/
diff --git a/qt.html.markdown b/qt.html.markdown
index a9c855a6..0db75726 100644
--- a/qt.html.markdown
+++ b/qt.html.markdown
@@ -5,7 +5,7 @@ language: c++
filename: learnqt.cpp
contributors:
- ["Aleksey Kholovchuk", "https://github.com/vortexxx192"]
-lang: en
+
---
**Qt** is a widely-known framework for developing cross-platform software that can be run on various software and hardware platforms with little or no change in the code, while having the power and speed of native applications. Though **Qt** was originally written in *C++*, there are its ports to other languages: *[PyQt](https://learnxinyminutes.com/docs/pyqt/)*, *QtRuby*, *PHP-Qt*, etc.
@@ -14,7 +14,7 @@ lang: en
```c++
/*
- * Let's start clasically
+ * Let's start classically
*/
// all headers from Qt framework start with capital letter 'Q'
@@ -79,7 +79,7 @@ int main(int argc, char *argv[]) {
Notice that *QObject::connect* part. This method is used to connect *SIGNALS* of one objects to *SLOTS* of another.
-**Signals** are being emited when certain things happen with objects, like *pressed* signal is emited when user presses on QPushButton object.
+**Signals** are being emitted when certain things happen with objects, like *pressed* signal is emitted when user presses on QPushButton object.
**Slots** are *actions* that might be performed in response to received signals.
diff --git a/r.html.markdown b/r.html.markdown
index 8539b10e..79af40ce 100644
--- a/r.html.markdown
+++ b/r.html.markdown
@@ -192,7 +192,7 @@ class(-Inf) # "numeric"
2.0 * 2L # 4 # numeric times integer gives numeric
3L / 4 # 0.75 # integer over numeric gives numeric
3 %% 2 # 1 # the remainder of two numerics is another numeric
-# Illegal arithmetic yeilds you a "not-a-number":
+# Illegal arithmetic yields you a "not-a-number":
0 / 0 # NaN
class(NaN) # "numeric"
# You can do arithmetic on two vectors with length greater than 1,
@@ -255,16 +255,16 @@ c('Z', 'o', 'r', 'r', 'o') == "Z" # TRUE FALSE FALSE FALSE FALSE
# FACTORS
# The factor class is for categorical data
-# Factors can be ordered (like childrens' grade levels) or unordered (like gender)
-factor(c("female", "female", "male", NA, "female"))
-# female female male <NA> female
-# Levels: female male
+# Factors can be ordered (like childrens' grade levels) or unordered (like colors)
+factor(c("blue", "blue", "green", NA, "blue"))
+# blue blue green <NA> blue
+# Levels: blue green
# The "levels" are the values the categorical data can take
# Note that missing data does not enter the levels
-levels(factor(c("male", "male", "female", NA, "female"))) # "female" "male"
+levels(factor(c("green", "green", "blue", NA, "blue"))) # "blue" "green"
# If a factor vector has length 1, its levels will have length 1, too
-length(factor("male")) # 1
-length(levels(factor("male"))) # 1
+length(factor("green")) # 1
+length(levels(factor("green"))) # 1
# Factors are commonly seen in data frames, a data structure we will cover later
data(infert) # "Infertility after Spontaneous and Induced Abortion"
levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs"
@@ -662,8 +662,9 @@ require(plyr)
#########################
# "pets.csv" is a file on the internet
-# (but it could just as easily be be a file on your own computer)
-pets <- read.csv("http://learnxinyminutes.com/docs/pets.csv")
+# (but it could just as easily be a file on your own computer)
+require(RCurl)
+pets <- read.csv(textConnection(getURL("https://learnxinyminutes.com/docs/pets.csv")))
pets
head(pets, 2) # first two rows
tail(pets, 1) # last row
@@ -788,7 +789,7 @@ install.packages("ggplot2")
require(ggplot2)
?ggplot2
pp <- ggplot(students, aes(x=house))
-pp + geom_histogram()
+pp + geom_bar()
ll <- as.data.table(list1)
pp <- ggplot(ll, aes(x=time,price))
pp + geom_point()
diff --git a/racket.html.markdown b/racket.html.markdown
index 96dcaf25..60a895e0 100644
--- a/racket.html.markdown
+++ b/racket.html.markdown
@@ -147,8 +147,8 @@ my-pet ; => #<dog>
(struct rgba-color (red green blue alpha) #:mutable)
(define burgundy
(rgba-color 144 0 32 1.0))
-(set-color-green! burgundy 10)
-(color-green burgundy) ; => 10
+(set-rgba-color-green! burgundy 10)
+(rgba-color-green burgundy) ; => 10
;;; Pairs (immutable)
;; `cons' constructs pairs, `car' and `cdr' extract the first
@@ -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
@@ -242,7 +249,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d'
(hash-remove m 'a) ; => '#hash((b . 2) (c . 3))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 3. Functions
+;; 4. Functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Use `lambda' to create functions.
@@ -312,7 +319,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d'
; => "Hi Finn, 6 extra args"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 4. Equality
+;; 5. Equality
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; for numbers use `='
@@ -362,7 +369,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d'
(equal? (list 3) (list 3)) ; => #t
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 5. Control Flow
+;; 6. Control Flow
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Conditionals
@@ -498,7 +505,7 @@ m ; => '#hash((b . 2) (a . 1) (c . 3)) <-- no `d'
(+ 1 (raise 2))) ; => 2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 6. Mutation
+;; 7. Mutation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Use `set!' to assign a new value to an existing variable
@@ -534,7 +541,7 @@ vec ; => #(1 2 3 4)
(hash-remove! m3 'a)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 7. Modules
+;; 8. Modules
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Modules let you organize code into multiple files and reusable
@@ -561,7 +568,7 @@ vec ; => #(1 2 3 4)
; (show "~a" 1 #\A) ; => error, `show' was not exported
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 8. Classes and Objects
+;; 9. Classes and Objects
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Create a class fish% (-% is idiomatic for class bindings)
@@ -602,7 +609,7 @@ vec ; => #(1 2 3 4)
(send (new (add-color fish%) [size 10] [color 'red]) get-color)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 9. Macros
+;; 10. Macros
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Macros let you extend the syntax of the language
@@ -644,7 +651,7 @@ vec ; => #(1 2 3 4)
;; it, the compiler will get in an infinite loop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 10. Contracts
+;; 11. Contracts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Contracts impose constraints on values exported from modules
@@ -671,7 +678,7 @@ vec ; => #(1 2 3 4)
;; more details....
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; 11. Input & output
+;; 12. Input & output
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Racket has this concept of "port", which is very similar to file
diff --git a/raku-pod.html.markdown b/raku-pod.html.markdown
new file mode 100644
index 00000000..7e9b6fc3
--- /dev/null
+++ b/raku-pod.html.markdown
@@ -0,0 +1,622 @@
+---
+language: Pod
+contributors:
+ - ["Luis F. Uceta", "https://uzluisf.gitlab.io/"]
+filename: learnpod.pod6
+---
+
+Pod is an easy-to-use and purely descriptive mark-up language,
+with no presentational components. Besides its use for documenting
+Raku programs and modules, Pod can be utilized to write language
+documentation, blogs, and other types of document composition as well.
+
+Pod documents can be easily converted to HTML and many other formats
+(e.g., Markdown, Latex, plain text, etc.) by using the corresponding
+variant of the `Pod::To` modules (e.g. `Pod::To::HTML` for HTML conversion).
+
+- [General Info](#general-info)
+- [Pod Basics](#pod-basics)
+ - [Basic Text Formatting](#basic-text-formatting)
+ - [Headings](#headings)
+ - [Ordinary Paragraphs](#ordinary-paragraphs)
+ - [Lists](#lists)
+ - [Code Blocks](#code-blocks)
+ - [Comments](#comments)
+ - [Links](#links)
+ - [Tables](#tables)
+- [Block Structures](#block-structures)
+ - [Abbreviated Blocks](#abbreviated-blocks)
+ - [Delimited Blocks](#delimited-blocks)
+ - [Paragraph Blocks](#paragraph-blocks)
+- [Configuration Data](#configuration-data)
+ - [Standard Configuration Options](#standard-configuration-options)
+ - [Block Pre-configuration](#block-pre-configuration)
+- [Semantic Blocks](#semantic-blocks)
+- [Miscellaneous](#miscellaneous)
+ - [Notes](#notes)
+ - [Keyboard Input](#keyboard-input)
+ - [Terminal Output](#terminal-output)
+ - [Unicode](#unicode)
+- [Rendering Pod](#rendering-pod)
+- [Accessing Pod](#accessing-pod)
+
+## General Info
+
+Every Pod document has to begin with `=begin pod` and end with `=end pod`.
+Everything between these two delimiters will be processed and used to
+generate documentation.
+
+```
+=begin pod
+
+A very simple Raku Pod document. All the other directives go here!
+
+=end pod
+```
+
+Pod documents usually coexist with Raku code. If by themselves,
+Pod files often have the `.pod6` suffix. Moving forward, it's assumed that
+the constructs being discussed are surrounded by the `=begin pod ... =end pod`
+directives.
+
+## Pod Basics
+
+### Basic Text Formatting
+
+Text can be easily styled as bold, italic, underlined or verbatim (for code
+formatting) using the following formatting codes: `B<>`, `I<>`, `U<>`
+and `C<>`.
+
+```
+B<This text is in Bold.>
+
+I<This text is in Italics.>
+
+U<This text is Underlined.>
+
+The function C<sub sum { $^x + $^y}> is treated as verbatim.
+```
+
+There are more formatting codes (e.g., `L<>`, `T<>`, etc.) but they'll be
+discussed later throughout the document. You'll recognize them because they're
+just a single capital letter followed immediately by a set of single or double
+angle brackets. The Unicode variant («») of the angle brackets can also be
+used.
+
+### Headings
+
+Headings are created by using the `=headN` directive where `N` is the
+heading level.
+
+```
+=head1 This is level 1
+=head2 This is level 2
+=head3 This is level 3
+=head4 This is level 4
+=head5 This is level 5
+=head6 This is level 6
+```
+
+### Ordinary Paragraphs
+
+Ordinary paragraphs consist of one or more adjacent lines of text, each of
+which starts with a non-whitespace character. Any paragraph is terminated
+by the first blank line or block directive.
+
+```
+=head1 First level heading block
+
+=head2 Paragraph 1
+
+This is an ordinary paragraph. Its text will be squeezed and
+short lines filled. It is terminated by the first blank line.
+
+=head2 Paragraph 2
+
+This is another ordinary paragraph albeit shorter.
+```
+
+Alternatively, the `=para` directive can be used to explicitly mark adjacent
+lines of text as a paragraph.
+
+```
+=head1 First level heading block
+
+=head2 Paragraph 1
+
+=para
+This is an ordinary paragraph. Its text will be squeezed and
+short lines filled. It is terminated by the first blank line.
+
+=head2 Paragraph 2
+
+=para
+This is another ordinary paragraph albeit shorter.
+```
+
+### Lists
+
+Unordered lists can be created using the `=item` directive.
+
+```
+=item Item
+=item Item
+=item Another item
+```
+
+Sublists are achieved with items at each level specified using the `=item1`,
+`=item2`, `=item3`, `...`, `=itemN` etc. directives. The `=item` directive
+defaults to `=item1`.
+
+```
+=item1 Item one
+=item1 Item two
+=item1 Item three
+ =item2 Sub-item
+ =item2 Sub-item
+=item1 Item four
+```
+
+Definition lists that define terms or commands use the `=defn` directive.
+This is equivalent to the `<dl>` element in HTML.
+
+```
+=defn Beast of Bodmin
+A large feline inhabiting Bodmin Moor.
+
+=defn Morgawr
+A sea serpent.
+
+=defn Owlman
+A giant owl-like creature.
+```
+
+### Code Blocks
+
+A code block is created (which uses the HTML `<code>` element) by starting each
+line with one or more whitespace characters.
+
+```
+ #`( this is comment )
+ my $sum = -> $x, $y { $x + $y }
+ say $sum(12, 5);
+```
+
+As shown in the [Basic Text Formatting](#basic-text-formatting) section,
+inline code can be created using the `C<>` code.
+
+```
+In Raku, there are several functions/methods to output text. Some of them
+are C<print>, C<put> and C<say>.
+```
+
+### Comments
+
+Although Pod blocks are ignored by the Rakudo Raku compiler, everything
+indentified as a Pod block will be read and interpreted by Pod renderers. In
+order to prevent Pod blocks from being rendered by any renderer, use the
+`=comment` directive.
+
+```
+=comment Add more here about the algorithm.
+
+=comment Pod comments are great for documenting the documentation.
+```
+
+To create inline comments, use the `Z<>` code.
+
+```
+Pod is awesome Z<Of course it is!>. And Raku too!
+```
+
+Given that the Raku interpreter never executes embedded Pod blocks,
+comment blocks can also be used as an alternative form of nestable block
+comments.
+
+### Links
+
+Creating links in Pod is quite easy and is done by enclosing them in
+a `L<>` code. The general format is `L<Label|Url>` with `Label`
+being optional.
+
+```
+Raku homepage is L<https://raku.org>.
+L<Click me!|http://link.org/>.
+```
+
+Relative paths work too.
+
+```
+L<Go to music|/music/>.
+```
+
+Linking to a section in the same document works as well.
+
+```
+L<Link to Headings|#Headings>
+```
+
+### Tables
+
+The Pod specifications are not completely handled properly yet and this
+includes the handling of table. For simplicity's sake, only one way of
+constructing tables is shown here. To learn about good practices and see
+examples of both good and bad tables, please visit
+<https://docs.raku.org/language/tables>.
+
+```
+=begin table
+Option | Description
+============|================
+data | path to data files.
+engine | engine to be used for processing templates.
+ext | extension to be used for dest files.
+=end table
+```
+
+## Block Structures
+
+As mentioned earlier, Pod documents are specified using directives, which are
+used to delimit blocks of textual content and declare optional
+[configuration information](#configuration-data). Every directive starts with
+an equals sign (`=`) in the first column. The content of a document is
+specified within one or more blocks. Every Pod block may be declared in any of
+three equivalent forms: delimited style, paragraph style, or abbreviated style.
+
+Up to this point, we have only used the abbreviated style for the block
+types (e.g., `=head1`, `=para`, `=comment`, `=item`, etc).
+
+### Abbreviated Blocks
+
+Abbreviated blocks are introduced by an `=` sign in the first column, which
+is followed immediately by the `typename` of the block and then the content.
+The rest of the line is treated as block data, rather than as configuration.
+The content terminates at the next Pod directive or the first blank line
+(which is not part of the block data). The general syntax is
+
+```
+=BLOCK_TYPE BLOCK_DATA
+```
+For example:
+
+```
+=head1 Top level heading
+```
+
+### Delimited Blocks
+
+Delimited blocks are bounded by `=begin` and `=end` markers, both of which are
+followed by a valid Pod identifier, which is the `typename` of the block.
+The general syntax is
+
+```
+=begin BLOCK_TYPE
+BLOCK_DATA
+=end BLOCK_TYPE
+```
+
+For example:
+
+```
+=begin head1
+Top level heading
+=end head1
+```
+
+This type of blocks is useful for creating headings, list items, code blocks,
+etc. with multiple paragraphs. For example,
+
+* a multiline item of a list
+
+```
+=begin item
+This is a paragraph in list item.
+
+This is another paragraph in the same list item.
+=end item
+```
+
+* a code block
+
+```
+=begin code
+#`(
+A non-efficient recursive implementation of a power function using multi subs.
+)
+
+multi pow( Real $base, 0 ) { 1 }
+
+multi pow( Real $base, Int $exp where * ≥ 0) {
+ $base * pow($base, $exp - 1)
+}
+
+multi pow( Real $base ) {
+ pow($base, 2)
+}
+
+say pow(3, 0); #=> 1
+say pow(4.2, 2); #=> 17.64
+say pow(6); #=> 36
+=end code
+```
+
+### Paragraph Blocks
+
+Paragraph blocks are introduced by a `=for` marker and terminated by
+the next Pod directive or the first blank line (which is not considered to
+be part of the block's contents). The `=for` marker is followed by the
+`typename` of the block. The general syntax is
+
+```
+=for BLOCK_TYPE
+BLOCK DATA
+```
+
+For example:
+
+```
+=for head1
+Top level heading
+```
+
+## Configuration Data
+
+Except for abbreviated blocks, both delimited blocks and paragraph
+blocks can be supplied with configuration information about their
+contents right after the `typename` of the block. Thus the following
+are more general syntaxes for these blocks:
+
+* Delimited blocks
+
+```
+=begin BLOCK_TYPE OPTIONAL_CONFIG_INFO
+= ADDITIONAL_CONFIG_INFO
+BLOCK_DATA
+=end BLOCK_TYPE
+```
+
+* Paragraph blocks
+
+```
+=for BLOCK_TYPE OPTIONAL_CONFIG_INFO
+= ADDITIONAL_CONFIG_INFO
+BLOCK DATA
+```
+
+The configuration information is provided in a format akin to the
+["colon pair"](https://docs.raku.org/language/glossary#index-entry-Colon_Pair)
+syntax in Raku. The following table is a simplified version of the
+different ways in which configuration info can be supplied. Please go to
+<https://docs.raku.org/language/pod#Configuration_information> for a more
+thorough treatment of the subject.
+
+| Value | Specify with... | Example |
+| :-------- | :------ | :------ |
+| List | :key($elem1, $elem2, ...) | :tags('Pod', 'Raku') |
+| Hash | :key{$key1 => $value1, ...} | :feeds{url => 'raku.org'} |
+| Boolean | :key/:key(True) | :skip-test(True) |
+| Boolean | :!key/:key(False) | :!skip-test |
+| String | :key('string') | :nonexec-reason('SyntaxError') |
+| Int | :key(2) | :post-number(6) |
+
+
+### Standard Configuration Options
+
+Pod provides a small number of standard configuration options that can
+be applied uniformly to built-in block types. Some of them are:
+
+* `:numbered`
+
+This option specifies that the block is to be numbered. The most common
+use of this option is to create numbered headings and ordered lists, but it
+can be applied to any block.
+
+For example:
+
+```
+=for head1 :numbered
+The Problem
+=for head1 :numbered
+The Solution
+=for head2 :numbered
+Analysis
+=for head3 :numbered
+Overview
+```
+
+* `:allow`
+
+The value of the `:allow` option must be a list of the (single-letter) names
+of one or more formatting codes. Those codes will then remain active inside
+the code block. The option is most often used on `=code` blocks to allow
+mark-up within those otherwise verbatim blocks, though it can be used in any
+block that contains verbatim text.
+
+Given the following snippet:
+
+```
+=begin code :allow('B', 'I')
+B<sub> greet( $name ) {
+ B<say> "Hello, $nameI<!>";
+}
+=end code
+```
+
+we get the following output:
+
+<pre><strong>sub</strong> greet( $name ) {
+ <strong>say</strong> &quot;Hello, $name<em>!</em>&quot;;
+}
+</pre>
+
+This is highly dependent on the format output. For example, while this works
+when Pod is converted to HTML, it might not be preserved when converted
+to Markdown.
+
+### Block Pre-configuration
+
+The `=config` directive allows you to prespecify standard configuration
+information that is applied to every block of a particular type.
+The general syntax for configuration directives is:
+
+```
+=config BLOCK_TYPE CONFIG OPTIONS
+= ADDITIONAL_CONFIG_INFO
+```
+
+For example, to specify that every heading level 1 be numbered, bold
+and underlined, you preconfigure the `=head1` as follows:
+
+```
+=config head1 :formatted('B', 'U') :numbered
+```
+
+## Semantic Blocks
+
+All uppercase block typenames are reserved for specifying standard
+documentation, publishing, source components, or meta-information.
+Some of them are:
+
+```
+=NAME
+=AUTHOR
+=VERSION
+=CREATED
+=SYNOPSIS
+=DESCRIPTION
+=USAGE
+```
+
+Most of these blocks would typically be used in their full
+delimited forms. For example,
+
+```
+=NAME B<Doc::Magic>
+
+=begin DESCRIPTION
+This module helps you generate documentation automagically.
+Not source code needed! Most of it is outsourced from a black hole.
+=end DESCRIPTION
+
+=begin SYNOPSIS
+=begin code
+ use Doc::Magic;
+
+ my Doc::Magic $doc .= new();
+
+ my $result = $doc.create-documentation($fh);
+=end code
+=end SYNOPSIS
+
+=AUTHOR Authorius Docus
+=VERSION 42
+```
+
+## Miscellaneous
+
+### Notes
+
+Notes are rendered as footnotes and created by enclosing a note in a
+`N<>` code.
+
+```
+In addition, the language is also multi-paradigmatic N<According to Wikipedia,
+this means that it supports procedural, object-oriented, and functional
+programming.>
+```
+
+### Keyboard Input
+
+To flag text as keyboard input enclose it in a `K<>` code.
+
+```
+Enter your name K<John Doe>
+```
+
+### Terminal Output
+
+To flag text as terminal output enclose it in `T<>` code.
+
+```
+Hello, T<John Doe>
+```
+
+### Unicode
+
+To include Unicode code points or HTML5 character references in
+a Pod document, enclose them in a `E<>` code.
+
+For example:
+
+```
+Raku makes considerable use of the E<171> and E<187> characters.
+Raku makes considerable use of the E<laquo> and E<raquo> characters.
+```
+
+is rendered as:
+
+Raku makes considerable use of the « and » characters.
+Raku makes considerable use of the « and » characters.
+
+## Rendering Pod
+
+To generate any output (i.e., Markdown, HTML, Text, etc.), you need to
+have the Rakudo Raku compiler installed. In addition, you must install
+a module (e.g., `Pod::To::Markdown`, `Pod::To::HTML`, `Pod::To::Text`, etc.)
+that generates your desired output from Pod.
+
+For instructions about installing Rakudo for running raku programs,
+[look here](https://raku.org/downloads/).
+
+Run the following command to generate a certain output:
+
+```
+raku --doc=TARGET input.pod6 > output.html
+```
+
+with `TARGET` being `Markdown`, `HTML`, `Text`, etc. Thus to generate
+Markdown from Pod, run this:
+
+```
+raku --doc=Markdown input.pod6 > output.html
+```
+
+## Accessing Pod
+
+In order to access Pod documentation from within a Raku program,
+it is required to use the special `=` twigil (e.g., `$=pod`, `$=SYNOPSIS`,etc).
+
+The `$=` construct provides the introspection over the Pod structure,
+producing a `Pod::Block` tree root from which it is possible to access
+the whole structure of the Pod document.
+
+If we place the following piece of Raku code and the Pod documentation
+in the section [Semantic blocks](#semantic-blocks) in the same file:
+
+```
+my %used-directives;
+for $=pod -> $pod-item {
+ for $pod-item.contents -> $pod-block {
+ next unless $pod-block ~~ Pod::Block::Named;
+ %used-directives{$pod-block.name} = True;
+ }
+}
+
+say %used-directives.keys.join("\n");
+```
+
+we get the following output:
+
+```
+SYNOPSIS
+NAME
+VERSION
+AUTHOR
+DESCRIPTION
+```
+
+## Additional Information
+
+* <https://docs.raku.org/language/pod> for the Pod documentation.
+* <https://docs.raku.org/language/tables> for advices about Pod tables.
+* <https://design.raku.org/S26.html> for the Pod specification.
diff --git a/raku.html.markdown b/raku.html.markdown
new file mode 100644
index 00000000..16035615
--- /dev/null
+++ b/raku.html.markdown
@@ -0,0 +1,2411 @@
+---
+category: language
+language: Raku
+filename: learnraku.raku
+contributors:
+ - ["vendethiel", "http://github.com/vendethiel"]
+ - ["Samantha McVey", "https://cry.nu"]
+---
+
+Raku (formerly Perl 6) is a highly capable, feature-rich programming language
+made for at least the next hundred years.
+
+The primary Raku compiler is called [Rakudo](http://rakudo.org), which runs on
+the JVM and the [MoarVM](http://moarvm.com).
+
+Meta-note:
+
+* Although the pound sign (`#`) is used for sentences and notes, Pod-styled
+ comments (more below about them) are used whenever it's convenient.
+* `# OUTPUT:` is used to represent the output of a command to any standard
+ stream. If the output has a newline, it's represented by the `␤` symbol.
+ The output is always enclosed by angle brackets (`«` and `»`).
+* `#=>` represents the value of an expression, return value of a sub, etc.
+ In some cases, the value is accompanied by a comment.
+* Backticks are used to distinguish and highlight the language constructs
+ from the text.
+
+```perl6
+####################################################
+# 0. Comments
+####################################################
+
+# Single line comments start with a pound sign.
+
+#`( Multiline comments use #` and a quoting construct.
+ (), [], {}, 「」, etc, will work.
+)
+
+=for comment
+Use the same syntax for multiline comments to embed comments.
+for #`(each element in) @array {
+ put #`(or print element) $_ #`(with newline);
+}
+
+# You can also use Pod-styled comments. For example:
+
+=comment This is a comment that extends until an empty
+newline is found.
+
+=comment
+The comment doesn't need to start in the same line as the directive.
+
+=begin comment
+This comment is multiline.
+
+Empty newlines can exist here too!
+=end comment
+
+####################################################
+# 1. Variables
+####################################################
+
+# In Raku, you declare a lexical variable using the `my` keyword:
+my $variable;
+
+# Raku has 3 basic types of variables: scalars, arrays, and hashes.
+
+#
+# 1.1 Scalars
+#
+
+# Scalars represent a single value. They start with the `$` sigil:
+my $str = 'String';
+
+# Double quotes allow for interpolation (which we'll see later):
+my $str2 = "$str";
+
+# Variable names can contain but not end with simple quotes and dashes,
+# and can contain (and end with) underscores:
+my $person's-belongings = 'towel'; # this works!
+
+my $bool = True; # `True` and `False` are Raku's boolean values.
+my $inverse = !$bool; # Invert a bool with the prefix `!` operator.
+my $forced-bool = so $str; # And you can use the prefix `so` operator
+$forced-bool = ?$str; # to turn its operand into a Bool. Or use `?`.
+
+#
+# 1.2 Arrays and Lists
+#
+
+# Arrays represent multiple values. An array variable starts with the `@`
+# sigil. Unlike lists, from which arrays inherit, arrays are mutable.
+
+my @array = 'a', 'b', 'c';
+# equivalent to:
+my @letters = <a b c>;
+# In the previous statement, we use the quote-words (`<>`) term for array
+# of words, delimited by space. Similar to perl's qw, or Ruby's %w.
+
+@array = 1, 2, 4;
+
+# Array indices start at 0. Here the third element is being accessed.
+say @array[2]; # OUTPUT: «4␤»
+
+say "Interpolate an array using []: @array[]";
+# OUTPUT: «Interpolate an array using []: 1 2 3␤»
+
+@array[0] = -1; # Assigning a new value to an array index
+@array[0, 1] = 5, 6; # Assigning multiple values
+
+my @keys = 0, 2;
+@array[@keys] = @letters; # Assignment using an array containing index values
+say @array; # OUTPUT: «a 6 b␤»
+
+#
+# 1.3 Hashes, or key-value Pairs.
+#
+
+=begin comment
+Hashes are pairs of keys and values. You can construct a `Pair` object
+using the syntax `key => value`. Hash tables are very fast for lookup,
+and are stored unordered. Keep in mind that keys get "flattened" in hash
+context, and any duplicated keys are deduplicated.
+=end comment
+my %hash = 'a' => 1, 'b' => 2;
+
+# Keys get auto-quoted when the fat comman (`=>`) is used. Trailing commas are
+# okay.
+%hash = a => 1, b => 2, ;
+
+# Even though hashes are internally stored differently than arrays,
+# Raku allows you to easily create a hash from an even numbered array:
+%hash = <key1 value1 key2 value2>; # Or:
+%hash = "key1", "value1", "key2", "value2";
+
+%hash = key1 => 'value1', key2 => 'value2'; # same result as above
+
+# You can also use the "colon pair" syntax. This syntax is especially
+# handy for named parameters that you'll see later.
+%hash = :n(2), # equivalent to `n => 2`
+ :is-even, # equivalent to `:is-even(True)` or `is-even => True`
+ :!is-odd, # equivalent to `:is-odd(False)` or `is-odd => False`
+;
+# The `:` (as in `:is-even`) and `:!` (as `:!is-odd`) constructs are known
+# as the `True` and `False` shortcuts respectively.
+
+=begin comment
+As demonstrated in the example below, you can use {} to get the value from a key.
+If it's a string without spaces, you can actually use the quote-words operator
+(`<>`). Since Raku doesn't have barewords, as Perl does, `{key1}` doesn't work
+though.
+=end comment
+say %hash{'n'}; # OUTPUT: «2␤», gets value associated to key 'n'
+say %hash<is-even>; # OUTPUT: «True␤», gets value associated to key 'is-even'
+
+####################################################
+# 2. Subroutines
+####################################################
+
+# Subroutines, or functions as most other languages call them, are
+# created with the `sub` keyword.
+sub say-hello { say "Hello, world" }
+
+# You can provide (typed) arguments. If specified, the type will be checked
+# at compile-time if possible, otherwise at runtime.
+sub say-hello-to( Str $name ) {
+ say "Hello, $name !";
+}
+
+# A sub returns the last value of the block. Similarly, the semicolon in
+# the last expression can be omitted.
+sub return-value { 5 }
+say return-value; # OUTPUT: «5␤»
+
+sub return-empty { }
+say return-empty; # OUTPUT: «Nil␤»
+
+# Some control flow structures produce a value, for instance `if`:
+sub return-if {
+ if True { "Truthy" }
+}
+say return-if; # OUTPUT: «Truthy␤»
+
+# Some don't, like `for`:
+sub return-for {
+ for 1, 2, 3 { 'Hi' }
+}
+say return-for; # OUTPUT: «Nil␤»
+
+=begin comment
+Positional arguments are required by default. To make them optional, use
+the `?` after the parameters' names.
+
+In the following example, the sub `with-optional` returns `(Any)` (Perl's
+null-like value) if no argument is passed. Otherwise, it returns its argument.
+=end comment
+sub with-optional( $arg? ) {
+ $arg;
+}
+with-optional; # returns Any
+with-optional(); # returns Any
+with-optional(1); # returns 1
+
+=begin comment
+You can also give provide a default value when they're not passed. Doing
+this make said parameter optional. Required parameters must come before
+optional ones.
+
+In the sub `greeting`, the parameter `$type` is optional.
+=end comment
+sub greeting( $name, $type = "Hello" ) {
+ say "$type, $name!";
+}
+
+greeting("Althea"); # OUTPUT: «Hello, Althea!␤»
+greeting("Arthur", "Good morning"); # OUTPUT: «Good morning, Arthur!␤»
+
+=begin comment
+You can also, by using a syntax akin to the one of hashes (yay unified syntax!),
+declared named parameters and thus pass named arguments to a subroutine.
+By default, named parameter are optional and will default to `Any`.
+=end comment
+sub with-named( $normal-arg, :$named ) {
+ say $normal-arg + $named;
+}
+with-named(1, named => 6); # OUTPUT: «7␤»
+
+=begin comment
+There's one gotcha to be aware of, here: If you quote your key, Raku
+won't be able to see it at compile time, and you'll have a single `Pair`
+object as a positional parameter, which means the function subroutine
+`with-named(1, 'named' => 6);` fails.
+=end comment
+with-named(2, :named(5)); # OUTPUT: «7␤»
+
+# Similar to positional parameters, you can provide your named arguments with
+# default values.
+sub named-def( :$def = 5 ) {
+ say $def;
+}
+named-def; # OUTPUT: «5»
+named-def(def => 15); # OUTPUT: «15»
+
+=begin comment
+In order to make a named parameter mandatory, you can append `!` to the
+parameter. This is the inverse of `?`, which makes a required parameter
+optional.
+=end comment
+
+sub with-mandatory-named( :$str! ) {
+ say "$str!";
+}
+with-mandatory-named(str => "My String"); # OUTPUT: «My String!␤»
+# with-mandatory-named; # runtime error: "Required named parameter not passed"
+# with-mandatory-named(3);# runtime error: "Too many positional parameters passed"
+
+=begin comment
+If a sub takes a named boolean argument, you can use the same "short boolean"
+hash syntax we discussed earlier.
+=end comment
+sub takes-a-bool( $name, :$bool ) {
+ say "$name takes $bool";
+}
+takes-a-bool('config', :bool); # OUTPUT: «config takes True␤»
+takes-a-bool('config', :!bool); # OUTPUT: «config takes False␤»
+
+=begin comment
+Since parenthesis can be omitted when calling a subroutine, you need to use
+`&` in order to distinguish between a call to a sub with no arguments and
+the code object.
+
+For instance, in this example we must use `&` to store the sub `say-hello`
+(i.e., the sub's code object) in a variable, not a subroutine call.
+=end comment
+my &s = &say-hello;
+my &other-s = sub { say "Anonymous function!" }
+
+=begin comment
+A sub can have a "slurpy" parameter, or what one'd call a
+"doesn't-matter-how-many" parameter. This is Raku's way of supporting variadic
+functions. For this, you must use `*@` (slurpy) which will "take everything
+else". You can have as many parameters *before* a slurpy one, but not *after*.
+=end comment
+sub as-many($head, *@rest) {
+ @rest.join(' / ') ~ " !";
+}
+say as-many('Happy', 'Happy', 'Birthday'); # OUTPUT: «Happy / Birthday !␤»
+say as-many('Happy', ['Happy', 'Birthday'], 'Day'); # OUTPUT: «Happy / Birthday / Day !␤»
+
+# Note that the splat (the *) did not consume the parameter before it.
+
+=begin comment
+There are other two variations of slurpy parameters in Raku. The previous one
+(namely, `*@`), known as flattened slurpy, flattens passed arguments. The other
+two are `**@` and `+@` known as unflattened slurpy and "single argument rule"
+slurpy respectively. The unflattened slurpy doesn't flatten its listy
+arguments (or Iterable ones).
+=end comment
+sub b(**@arr) { @arr.perl.say };
+b(['a', 'b', 'c']); # OUTPUT: «[["a", "b", "c"],]»
+b(1, $('d', 'e', 'f'), [2, 3]); # OUTPUT: «[1, ("d", "e", "f"), [2, 3]]»
+b(1, [1, 2], ([3, 4], 5)); # OUTPUT: «[1, [1, 2], ([3, 4], 5)]␤»
+
+=begin comment
+On the other hand, the "single argument rule" slurpy follows the "single argument
+rule" which dictates how to handle the slurpy argument based upon context and
+roughly states that if only a single argument is passed and that argument is
+Iterable, that argument is used to fill the slurpy parameter array. In any
+other case, `+@` works like `**@`.
+=end comment
+sub c(+@arr) { @arr.perl.say };
+c(['a', 'b', 'c']); # OUTPUT: «["a", "b", "c"]␤»
+c(1, $('d', 'e', 'f'), [2, 3]); # OUTPUT: «[1, ("d", "e", "f"), [2, 3]]␤»
+c(1, [1, 2], ([3, 4], 5)); # OUTPUT: «[1, [1, 2], ([3, 4], 5)]␤»
+
+=begin comment
+You can call a function with an array using the "argument list flattening"
+operator `|` (it's not actually the only role of this operator,
+but it's one of them).
+=end comment
+sub concat3($a, $b, $c) {
+ say "$a, $b, $c";
+}
+concat3(|@array); # OUTPUT: «a, b, c␤»
+ # `@array` got "flattened" as a part of the argument list
+
+####################################################
+# 3. Containers
+####################################################
+
+=begin comment
+In Raku, values are actually stored in "containers". The assignment
+operator asks the container on the left to store the value on its right.
+When passed around, containers are marked as immutable which means that,
+in a function, you'll get an error if you try to mutate one of your
+arguments. If you really need to, you can ask for a mutable container by
+using the `is rw` trait.
+=end comment
+sub mutate( $n is rw ) {
+ $n++; # postfix ++ operator increments its argument but returns its old value
+}
+my $m = 42;
+mutate $m; #=> 42, the value is incremented but the old value is returned
+say $m; # OUTPUT: «43␤»
+
+=begin comment
+This works because we are passing the container $m to the `mutate` sub.
+If we try to just pass a number instead of passing a variable, it won't work
+because there is no container being passed and integers are immutable by
+themselves:
+
+mutate 42; # Parameter '$n' expected a writable container, but got Int value
+=end comment
+
+=begin comment
+Similar error would be obtained, if a bound variable is passed to
+to the subroutine. In Raku, you bind a value to a variable using the binding
+operator `:=`.
+=end comment
+my $v := 50; # binding 50 to the variable $v
+# mutate $v; # Parameter '$n' expected a writable container, but got Int value
+
+=begin comment
+If what you want is a copy instead, use the `is copy` trait which will
+cause the argument to be copied and allow you to modify the argument
+inside the routine without modifying the passed argument.
+
+A sub itself returns a container, which means it can be marked as `rw`.
+Alternatively, you can explicitly mark the returned container as mutable
+by using `return-rw` instead of `return`.
+=end comment
+my $x = 42;
+my $y = 45;
+sub x-store is rw { $x }
+sub y-store { return-rw $y }
+
+# In this case, the parentheses are mandatory or else Raku thinks that
+# `x-store` and `y-store` are identifiers.
+x-store() = 52;
+y-store() *= 2;
+
+say $x; # OUTPUT: «52␤»
+say $y; # OUTPUT: «90␤»
+
+####################################################
+# 4.Control Flow Structures
+####################################################
+
+#
+# 4.1 if/if-else/if-elsif-else/unless
+#
+
+=begin comment
+Before talking about `if`, we need to know which values are "truthy"
+(represent `True`), and which are "falsey" (represent `False`). Only these
+values are falsey: 0, (), {}, "", Nil, a type (like `Str`, `Int`, etc.) and
+of course, `False` itself. Any other value is truthy.
+=end comment
+my $number = 5;
+if $number < 5 {
+ say "Number is less than 5"
+}
+elsif $number == 5 {
+ say "Number is equal to 5"
+}
+else {
+ say "Number is greater than 5"
+}
+
+unless False {
+ say "It's not false!";
+}
+
+# `unless` is the equivalent of `if not (X)` which inverts the sense of a
+# conditional statement. However, you cannot use `else` or `elsif` with it.
+
+# As you can see, you don't need parentheses around conditions. However, you
+# do need the curly braces around the "body" block. For example,
+# `if (True) say 'It's true';` doesn't work.
+
+# You can also use their statement modifier (postfix) versions:
+say "Quite truthy" if True; # OUTPUT: «Quite truthy␤»
+say "Quite falsey" unless False; # OUTPUT: «Quite falsey␤»
+
+=begin comment
+The ternary operator (`??..!!`) is structured as follows `condition ??
+expression1 !! expression2` and it returns expression1 if the condition is
+true. Otherwise, it returns expression2.
+=end comment
+my $age = 30;
+say $age > 18 ?? "You are an adult" !! "You are under 18";
+# OUTPUT: «You are an adult␤»
+
+#
+# 4.2 with/with-else/with-orwith-else/without
+#
+
+=begin comment
+The `with` statement is like `if`, but it tests for definedness rather than
+truth, and it topicalizes on the condition, much like `given` which will
+be discussed later.
+=end comment
+my $s = "raku";
+with $s.index("r") { say "Found a at $_" }
+orwith $s.index("k") { say "Found c at $_" }
+else { say "Didn't find r or k" }
+
+# Similar to `unless` that checks un-truthiness, you can use `without` to
+# check for undefined-ness.
+my $input01;
+without $input01 {
+ say "No input given."
+}
+# OUTPUT: «No input given.␤»
+
+# There are also statement modifier versions for both `with` and `without`.
+my $input02 = 'Hello';
+say $input02 with $input02; # OUTPUT: «Hello␤»
+say "No input given." without $input02;
+
+#
+# 4.3 given/when, or Raku's switch construct
+#
+
+=begin comment
+`given...when` looks like other languages' `switch`, but is much more
+powerful thanks to smart matching and Raku's "topic variable", `$_`.
+
+The topic variable `$_ `contains the default argument of a block, a loop's
+current iteration (unless explicitly named), etc.
+
+`given` simply puts its argument into `$_` (like a block would do),
+ and `when` compares it using the "smart matching" (`~~`) operator.
+
+Since other Raku constructs use this variable (as said before, like `for`,
+blocks, `with` statement etc), this means the powerful `when` is not only
+applicable along with a `given`, but instead anywhere a `$_` exists.
+=end comment
+
+given "foo bar" {
+ say $_; # OUTPUT: «foo bar␤»
+
+ # Don't worry about smart matching yet. Just know `when` uses it. This is
+ # equivalent to `if $_ ~~ /foo/`.
+ when /foo/ {
+ say "Yay !";
+ }
+
+ # smart matching anything with `True` is `True`, i.e. (`$a ~~ True`)
+ # so you can also put "normal" conditionals. For example, this `when` is
+ # equivalent to this `if`: `if $_ ~~ ($_.chars > 50) {...}`
+ # which means: `if $_.chars > 50 {...}`
+ when $_.chars > 50 {
+ say "Quite a long string !";
+ }
+
+ # same as `when *` (using the Whatever Star)
+ default {
+ say "Something else"
+ }
+}
+
+#
+# 4.4 Looping constructs
+#
+
+# The `loop` construct is an infinite loop if you don't pass it arguments, but
+# can also be a C-style `for` loop:
+loop {
+ say "This is an infinite loop !";
+ last;
+}
+# In the previous example, `last` breaks out of the loop very much
+# like the `break` keyword in other languages.
+
+# The `next` keyword skips to the next iteration, like `continue` in other
+# languages. Note that you can also use postfix conditionals, loops, etc.
+loop (my $i = 0; $i < 5; $i++) {
+ next if $i == 3;
+ say "This is a C-style for loop!";
+}
+
+# The `for` constructs iterates over a list of elements.
+my @odd-array = 1, 3, 5, 7, 9;
+
+# Accessing the array's elements with the topic variable $_.
+for @odd-array {
+ say "I've got $_ !";
+}
+
+# Accessing the array's elements with a "pointy block", `->`.
+# Here each element is read-only.
+for @odd-array -> $variable {
+ say "I've got $variable !";
+}
+
+# Accessing the array's elements with a "doubly pointy block", `<->`.
+# Here each element is read-write so mutating `$variable` mutates
+# that element in the array.
+for @odd-array <-> $variable {
+ say "I've got $variable !";
+}
+
+# As we saw with `given`, a `for` loop's default "current iteration" variable
+# is `$_`. That means you can use `when` in a `for`loop just like you were
+# able to in a `given`.
+for @odd-array {
+ say "I've got $_";
+
+ # This is also allowed. A dot call with no "topic" (receiver) is sent to
+ # `$_` (topic variable) by default.
+ .say;
+
+ # This is equivalent to the above statement.
+ $_.say;
+}
+
+for @odd-array {
+ # You can...
+ next if $_ == 3; # Skip to the next iteration (`continue` in C-like lang.)
+ redo if $_ == 4; # Re-do iteration, keeping the same topic variable (`$_`)
+ last if $_ == 5; # Or break out of loop (like `break` in C-like lang.)
+}
+
+# The "pointy block" syntax isn't specific to the `for` loop. It's just a way
+# to express a block in Raku.
+sub long-computation { "Finding factors of large primes" }
+if long-computation() -> $result {
+ say "The result is $result.";
+}
+
+####################################################
+# 5. Operators
+####################################################
+
+=begin comment
+Since Perl languages are very much operator-based languages, Raku
+operators are actually just funny-looking subroutines, in syntactic
+categories, like infix:<+> (addition) or prefix:<!> (bool not).
+
+The categories are:
+ - "prefix": before (like `!` in `!True`).
+ - "postfix": after (like `++` in `$a++`).
+ - "infix": in between (like `*` in `4 * 3`).
+ - "circumfix": around (like `[`-`]` in `[1, 2]`).
+ - "post-circumfix": around, after another term (like `{`-`}` in
+ `%hash{'key'}`)
+
+The associativity and precedence list are explained below.
+
+Alright, you're set to go!
+=end comment
+
+#
+# 5.1 Equality Checking
+#
+
+# `==` is numeric comparison
+say 3 == 4; # OUTPUT: «False␤»
+say 3 != 4; # OUTPUT: «True␤»
+
+# `eq` is string comparison
+say 'a' eq 'b'; # OUTPUT: «False␤»
+say 'a' ne 'b'; # OUTPUT: «True␤», not equal
+say 'a' !eq 'b'; # OUTPUT: «True␤», same as above
+
+# `eqv` is canonical equivalence (or "deep equality")
+say (1, 2) eqv (1, 3); # OUTPUT: «False␤»
+say (1, 2) eqv (1, 2); # OUTPUT: «True␤»
+say Int === Int; # OUTPUT: «True␤»
+
+# `~~` is the smart match operator which aliases the left hand side to $_ and
+# then evaluates the right hand side.
+# Here are some common comparison semantics:
+
+# String or numeric equality
+say 'Foo' ~~ 'Foo'; # OUTPUT: «True␤», if strings are equal.
+say 12.5 ~~ 12.50; # OUTPUT: «True␤», if numbers are equal.
+
+# Regex - For matching a regular expression against the left side.
+# Returns a `Match` object, which evaluates as True if regexp matches.
+my $obj = 'abc' ~~ /a/;
+say $obj; # OUTPUT: «「a」␤»
+say $obj.WHAT; # OUTPUT: «(Match)␤»
+
+# Hashes
+say 'key' ~~ %hash; # OUTPUT: «True␤», if key exists in hash.
+
+# Type - Checks if left side "is of type" (can check superclasses and roles).
+say 1 ~~ Int; # OUTPUT: «True␤»
+
+# Smart-matching against a boolean always returns that boolean (and will warn).
+say 1 ~~ True; # OUTPUT: «True␤», smartmatch against True always matches
+say False.so ~~ True; # OUTPUT: «True␤», use .so for truthiness
+
+# General syntax is `$arg ~~ &bool-returning-function;`. For a complete list
+# of combinations, refer to the table at:
+# https://docs.raku.org/language/operators#index-entry-smartmatch_operator
+
+# Of course, you also use `<`, `<=`, `>`, `>=` for numeric comparison.
+# Their string equivalent are also available: `lt`, `le`, `gt`, `ge`.
+say 3 > 4; # OUTPUT: «False␤»
+say 3 >= 4; # OUTPUT: «False␤»
+say 3 < 4; # OUTPUT: «True␤»
+say 3 <= 4; # OUTPUT: «True␤»
+say 'a' gt 'b'; # OUTPUT: «False␤»
+say 'a' ge 'b'; # OUTPUT: «False␤»
+say 'a' lt 'b'; # OUTPUT: «True␤»
+say 'a' le 'b'; # OUTPUT: «True␤»
+
+#
+# 5.2 Range constructor
+#
+
+say 3 .. 7; # OUTPUT: «3..7␤», both included.
+say 3 ..^ 7; # OUTPUT: «3..^7␤», exclude right endpoint.
+say 3 ^.. 7; # OUTPUT: «3^..7␤», exclude left endpoint.
+say 3 ^..^ 7; # OUTPUT: «3^..^7␤», exclude both endpoints.
+
+# The range 3 ^.. 7 is similar like 4 .. 7 when we only consider integers.
+# But when we consider decimals:
+
+say 3.5 ~~ 4 .. 7; # OUTPUT: «False␤»
+say 3.5 ~~ 3 ^.. 7; # OUTPUT: «True␤»,
+
+# This is because the range `3 ^.. 7` only excludes anything strictly
+# equal to 3. Hence, it contains decimals greater than 3. This could
+# mathematically be described as 3.5 ∈ (3,7] or in set notation,
+# 3.5 ∈ { x | 3 < x ≤ 7 }.
+
+say 3 ^.. 7 ~~ 4 .. 7; # OUTPUT: «False␤»
+
+# This also works as a shortcut for `0..^N`:
+say ^10; # OUTPUT: «^10␤», which means 0..^10
+
+# This also allows us to demonstrate that Raku has lazy/infinite arrays,
+# using the Whatever Star:
+my @natural = 1..*; # 1 to Infinite! Equivalent to `1..Inf`.
+
+# You can pass ranges as subscripts and it'll return an array of results.
+say @natural[^10]; # OUTPUT: «1 2 3 4 5 6 7 8 9 10␤», doesn't run out of memory!
+
+=begin comment
+NOTE: when reading an infinite list, Raku will "reify" the elements
+it needs, then keep them in memory. They won't be calculated more than once.
+It also will never calculate more elements that are needed.
+=end comment
+
+# An array subscript can also be a closure. It'll be called with the array's
+# length as the argument. The following two examples are equivalent:
+say join(' ', @array[15..*]); # OUTPUT: «15 16 17 18 19␤»
+say join(' ', @array[-> $n { 15..$n }]); # OUTPUT: «15 16 17 18 19␤»
+
+# NOTE: if you try to do either of those with an infinite array, you'll
+# trigger an infinite loop (your program won't finish).
+
+# You can use that in most places you'd expect, even when assigning to an array:
+my @numbers = ^20;
+
+# Here the numbers increase by 6, like an arithmetic sequence; more on the
+# sequence (`...`) operator later.
+my @seq = 3, 9 ... * > 95; # 3 9 15 21 27 [...] 81 87 93 99;
+
+# In this example, even though the sequence is infinite, only the 15
+# needed values will be calculated.
+@numbers[5..*] = 3, 9 ... *;
+say @numbers; # OUTPUT: «0 1 2 3 4 3 9 15 21 [...] 81 87␤», only 20 values
+
+#
+# 5.3 and (&&), or (||)
+#
+
+# Here `and` calls `.Bool` on both 3 and 4 and gets `True` so it returns
+# 4 since both are `True`.
+say (3 and 4); # OUTPUT: «4␤», which is truthy.
+say (3 and 0); # OUTPUT: «0␤»
+say (0 and 4); # OUTPUT: «0␤»
+
+# Here `or` calls `.Bool` on `0` and `False` which are both `False`
+# so it returns `False` since both are `False`.
+say (0 or False); # OUTPUT: «False␤».
+
+# Both `and` and `or` have tighter versions which also shortcut circuits.
+# They're `&&` and `||` respectively.
+
+# `&&` returns the first operand that evaluates to `False`. Otherwise,
+# it returns the last operand.
+my ($a, $b, $c, $d, $e) = 1, 0, False, True, 'pi';
+say $a && $b && $c; # OUTPUT: «0␤», the first falsey value
+say $a && $b && $c; # OUTPUT: «False␤», the first falsey value
+say $a && $d && $e; # OUTPUT: «pi␤», last operand since everthing before is truthy
+
+# `||` returns the first argument that evaluates to `True`.
+say $b || $a || $d; # OUTPUT: «1␤»
+say $e || $d || $a; # OUTPUT: «pi␤»
+
+# And because you're going to want them, you also have compound assignment
+# operators:
+$a *= 2; # multiply and assignment. Equivalent to $a = $a * 2;
+$b %%= 5; # divisible by and assignment. Equivalent to $b = $b %% 2;
+$c div= 3; # return divisor and assignment. Equivalent to $c = $c div 3;
+$d mod= 4; # return remainder and assignment. Equivalent to $d = $d mod 4;
+@array .= sort; # calls the `sort` method and assigns the result back
+
+####################################################
+# 6. More on subs!
+####################################################
+
+# As we said before, Raku has *really* powerful subs. We're going
+# to see a few more key concepts that make them better than in any
+# other language :-).
+
+#
+# 6.1 Unpacking!
+#
+
+# Unpacking is the ability to "extract" arrays and keys
+# (AKA "destructuring"). It'll work in `my`s and in parameter lists.
+my ($f, $g) = 1, 2;
+say $f; # OUTPUT: «1␤»
+my ($, $, $h) = 1, 2, 3; # keep the non-interesting values anonymous (`$`)
+say $h; # OUTPUT: «3␤»
+
+my ($head, *@tail) = 1, 2, 3; # Yes, it's the same as with "slurpy subs"
+my (*@small) = 1;
+
+sub unpack_array( @array [$fst, $snd] ) {
+ say "My first is $fst, my second is $snd! All in all, I'm @array[].";
+ # (^ remember the `[]` to interpolate the array)
+}
+unpack_array(@tail);
+# OUTPUT: «My first is 2, my second is 3! All in all, I'm 2 3.␤»
+
+# If you're not using the array itself, you can also keep it anonymous,
+# much like a scalar:
+sub first-of-array( @ [$fst] ) { $fst }
+first-of-array(@small); #=> 1
+
+# However calling `first-of-array(@tail);` will throw an error ("Too many
+# positional parameters passed"), which means the `@tail` has too many
+# elements.
+
+# You can also use a slurpy parameter. You could keep `*@rest` anonymous
+# Here, `@rest` is `(3,)`, since `$fst` holds the `2`. This results
+# since the length (.elems) of `@rest` is 1.
+sub slurp-in-array(@ [$fst, *@rest]) {
+ say $fst + @rest.elems;
+}
+slurp-in-array(@tail); # OUTPUT: «3␤»
+
+# You could even extract on a slurpy (but it's pretty useless ;-).)
+sub fst(*@ [$fst]) { # or simply: `sub fst($fst) { ... }`
+ say $fst;
+}
+fst(1); # OUTPUT: «1␤»
+
+# Calling `fst(1, 2);` will throw an error ("Too many positional parameters
+# passed") though. After all, the `fst` sub declares only a single positional
+# parameter.
+
+=begin comment
+You can also destructure hashes (and classes, which you'll learn about later).
+The syntax is basically the same as
+`%hash-name (:key($variable-to-store-value-in))`.
+The hash can stay anonymous if you only need the values you extracted.
+
+In order to call the function, you must supply a hash wither created with
+curly braces or with `%()` (recommended). Alternatively, you can pass
+a variable that contains a hash.
+=end comment
+
+sub key-of( % (:value($val), :qua($qua)) ) {
+ say "Got value $val, $qua time" ~~
+ $qua == 1 ?? '' !! 's';
+}
+
+my %foo-once = %(value => 'foo', qua => 1);
+key-of({value => 'foo', qua => 2}); # OUTPUT: «Got val foo, 2 times.␤»
+key-of(%(value => 'foo', qua => 0)); # OUTPUT: «Got val foo, 0 times.␤»
+key-of(%foo-once); # OUTPUT: «Got val foo, 1 time.␤»
+
+# The last expression of a sub is returned automatically (though you may
+# indicate explicitly by using the `return` keyword, of course):
+sub next-index( $n ) {
+ $n + 1;
+}
+my $new-n = next-index(3); # $new-n is now 4
+
+=begin comment
+This is true for everything, except for the looping constructs (due to
+performance reasons): there's no reason to build a list if we're just going to
+discard all the results. If you still want to build one, you can use the
+`do` statement prefix or the `gather` prefix, which we'll see later:
+=end comment
+
+sub list-of( $n ) {
+ do for ^$n { $_ }
+}
+my @list3 = list-of(3); #=> (0, 1, 2)
+
+#
+# 6.2 Lambdas (or anonymous subroutines)
+#
+
+# You can create a lambda by using a pointy block (`-> {}`), a
+# block (`{}`) or creating a `sub` without a name.
+
+my &lambda1 = -> $argument {
+ "The argument passed to this lambda is $argument"
+}
+
+my &lambda2 = {
+ "The argument passed to this lambda is $_"
+}
+
+my &lambda3 = sub ($argument) {
+ "The argument passed to this lambda is $argument"
+}
+
+=begin comment
+Both pointy blocks and blocks are pretty much the same thing, except that
+the former can take arguments, and that the latter can be mistaken as
+a hash by the parser. That being said, blocks can declare what's known
+as placeholders parameters through the twigils `$^` (for positional
+parameters) and `$:` (for named parameters). More on them later on.
+=end comment
+
+my &mult = { $^numbers * $:times }
+say mult 4, :times(6); #=> «24␤»
+
+# Both pointy blocks and blocks are quite versatile when working with functions
+# that accepts other functions such as `map`, `grep`, etc. For example,
+# we add 3 to each value of an array using the `map` function with a lambda:
+my @nums = 1..4;
+my @res1 = map -> $v { $v + 3 }, @nums; # pointy block, explicit parameter
+my @res2 = map { $_ + 3 }, @nums; # block using an implicit parameter
+my @res3 = map { $^val + 3 }, @nums; # block with placeholder parameter
+
+=begin comment
+A sub (`sub {}`) has different semantics than a block (`{}` or `-> {}`):
+A block doesn't have a "function context" (though it can have arguments),
+which means that if you return from it, you're going to return from the
+parent function.
+=end comment
+
+# Compare:
+sub is-in( @array, $elem ) {
+ say map({ return True if $_ == $elem }, @array);
+ say 'Hi';
+}
+
+# with:
+sub truthy-array( @array ) {
+ say map sub ($i) { $i ?? return True !! return False }, @array;
+ say 'Hi';
+}
+
+=begin comment
+In the `is-in` sub, the block will `return` out of the `is-in` sub once the
+condition evaluates to `True`, the loop won't be run anymore and the
+following statement won't be executed. The last statement is only executed
+if the block never returns.
+
+On the contrary, the `truthy-array` sub will produce an array of `True` and
+`False`, which will printed, and always execute the last execute statement.
+Thus, the `return` only returns from the anonymous `sub`
+=end comment
+
+=begin comment
+The `anon` declarator can be used to create an anonymous sub from a
+regular subroutine. The regular sub knows its name but its symbol is
+prevented from getting installed in the lexical scope, the method table
+and everywhere else.
+=end comment
+my $anon-sum = anon sub summation(*@a) { [+] @a }
+say $anon-sum.name; # OUTPUT: «summation␤»
+say $anon-sum(2, 3, 5); # OUTPUT: «10␤»
+#say summation; # Error: Undeclared routine: ...
+
+# You can also use the Whatever Star to create an anonymous subroutine.
+# (it'll stop at the furthest operator in the current expression).
+# The following is the same as `{$_ + 3 }`, `-> { $a + 3 }`,
+# `sub ($a) { $a + 3 }`, or even `{$^a + 3}` (more on this later).
+my @arrayplus3v0 = map * + 3, @nums;
+
+# The following is the same as `-> $a, $b { $a + $b + 3 }`,
+# `sub ($a, $b) { $a + $b + 3 }`, or `{ $^a + $^b + 3 }` (more on this later).
+my @arrayplus3v1 = map * + * + 3, @nums;
+
+say (*/2)(4); # OUTPUT: «2␤», immediately execute the Whatever function created.
+say ((*+3)/5)(5); # OUTPUT: «1.6␤», it works even in parens!
+
+# But if you need to have more than one argument (`$_`) in a block (without
+# wanting to resort to `-> {}`), you can also either `$^` and `$:` which
+# declared placeholder parameters or self-declared positional/named parameters.
+say map { $^a + $^b + 3 }, @nums;
+
+# which is equivalent to the following which uses a `sub`:
+map sub ($a, $b) { $a + $b + 3 }, @nums;
+
+# Placeholder parameters are sorted lexicographically so the following two
+# statements are equivalent:
+say sort { $^b <=> $^a }, @nums;
+say sort -> $a, $b { $b <=> $a }, @nums;
+
+#
+# 6.3 Multiple Dispatch
+#
+
+# Raku can decide which variant of a `sub` to call based on the type of the
+# arguments, or on arbitrary preconditions, like with a type or `where`:
+
+# with types:
+multi sub sayit( Int $n ) { # note the `multi` keyword here
+ say "Number: $n";
+}
+multi sayit( Str $s ) { # a multi is a `sub` by default
+ say "String: $s";
+}
+sayit "foo"; # OUTPUT: «String: foo␤»
+sayit 25; # OUTPUT: «Number: 25␤»
+sayit True; # fails at *compile time* with "calling 'sayit' will never
+ # work with arguments of types ..."
+
+# with arbitrary preconditions (remember subsets?):
+multi is-big(Int $n where * > 50) { "Yes!" } # using a closure
+multi is-big(Int $n where {$_ > 50}) { "Yes!" } # similar to above
+multi is-big(Int $ where 10..50) { "Quite." } # Using smart-matching
+multi is-big(Int $) { "No" }
+
+subset Even of Int where * %% 2;
+multi odd-or-even(Even) { "Even" } # Using the type. We don't name the argument.
+multi odd-or-even($) { "Odd" } # "everything else" hence the $ variable
+
+# You can even dispatch based on the presence of positional and named arguments:
+multi with-or-without-you($with) {
+ say "I wish I could but I can't";
+}
+multi with-or-without-you(:$with) {
+ say "I can live! Actually, I can't.";
+}
+multi with-or-without-you {
+ say "Definitely can't live.";
+}
+
+=begin comment
+This is very, very useful for many purposes, like `MAIN` subs (covered
+later), and even the language itself uses it in several places.
+
+For example, the `is` trait is actually a `multi sub` named `trait_mod:<is>`,
+and it works off that. Thus, `is rw`, is simply a dispatch to a function with
+this signature `sub trait_mod:<is>(Routine $r, :$rw!) {}`
+=end comment
+
+####################################################
+# 7. About types...
+####################################################
+
+=begin comment
+Raku is gradually typed. This means you can specify the type of your
+variables/arguments/return types, or you can omit the type annotations in
+in which case they'll default to `Any`. Obviously you get access to a few
+base types, like `Int` and `Str`. The constructs for declaring types are
+`subset`, `class`, `role`, etc. which you'll see later.
+
+For now, let us examine `subset` which is a "sub-type" with additional
+checks. For example, "a very big integer is an `Int` that's greater than 500".
+You can specify the type you're subtyping (by default, `Any`), and add
+additional checks with the `where` clause.
+=end comment
+subset VeryBigInteger of Int where * > 500;
+
+# Or the set of the whole numbers:
+subset WholeNumber of Int where * >= 0;
+my WholeNumber $whole-six = 6; # OK
+#my WholeNumber $nonwhole-one = -1; # Error: type check failed...
+
+# Or the set of Positive Even Numbers whose Mod 5 is 1. Notice we're
+# using the previously defined WholeNumber subset.
+subset PENFO of WholeNumber where { $_ %% 2 and $_ mod 5 == 1 };
+my PENFO $yes-penfo = 36; # OK
+#my PENFO $no-penfo = 2; # Error: type check failed...
+
+####################################################
+# 8. Scoping
+####################################################
+
+=begin comment
+In Raku, unlike many scripting languages, (such as Python, Ruby, PHP),
+you must declare your variables before using them. The `my` declarator
+we've used so far uses "lexical scoping". There are a few other declarators,
+(`our`, `state`, ..., ) which we'll see later. This is called
+"lexical scoping", where in inner blocks, you can access variables from
+outer blocks.
+=end comment
+
+my $file_scoped = 'Foo';
+sub outer {
+ my $outer_scoped = 'Bar';
+ sub inner {
+ say "$file_scoped $outer_scoped";
+ }
+ &inner; # return the function
+}
+outer()(); # OUTPUT: «Foo Bar␤»
+
+# As you can see, `$file_scoped` and `$outer_scoped` were captured.
+# But if we were to try and use `$outer_scoped` outside the `outer` sub,
+# the variable would be undefined (and you'd get a compile time error).
+
+####################################################
+# 9. Twigils
+####################################################
+
+=begin comment
+There are many special `twigils` (composed sigils) in Raku. Twigils
+define a variable's scope.
+The `*` and `?` twigils work on standard variables:
+ * for dynamic variables
+ ? for compile-time variables
+
+The `!` and the `.` twigils are used with Raku's objects:
+ ! for attributes (instance attribute)
+ . for methods (not really a variable)
+=end comment
+
+#
+# `*` twigil: Dynamic Scope
+#
+
+# These variables use the `*` twigil to mark dynamically-scoped variables.
+# Dynamically-scoped variables are looked up through the caller, not through
+# the outer scope.
+
+my $*dyn_scoped_1 = 1;
+my $*dyn_scoped_2 = 10;
+
+sub say_dyn {
+ say "$*dyn_scoped_1 $*dyn_scoped_2";
+}
+
+sub call_say_dyn {
+ # Defines $*dyn_scoped_1 only for this sub.
+ my $*dyn_scoped_1 = 25;
+
+ # Will change the value of the file scoped variable.
+ $*dyn_scoped_2 = 100;
+
+ # $*dyn_scoped 1 and 2 will be looked for in the call.
+ say_dyn(); # OUTPUT: «25 100␤»
+
+ # The call to `say_dyn` uses the value of $*dyn_scoped_1 from inside
+ # this sub's lexical scope even though the blocks aren't nested (they're
+ # call-nested).
+}
+say_dyn(); # OUTPUT: «1 10␤»
+
+# Uses $*dyn_scoped_1 as defined in `call_say_dyn` even though we are calling it
+# from outside.
+call_say_dyn(); # OUTPUT: «25 100␤»
+
+# We changed the value of $*dyn_scoped_2 in `call_say_dyn` so now its
+# value has changed.
+say_dyn(); # OUTPUT: «1 100␤»
+
+# TODO: Add information about remaining twigils
+
+####################################################
+# 10. Object Model
+####################################################
+
+=begin comment
+To call a method on an object, add a dot followed by the method name:
+`$object.method`
+
+Classes are declared with the `class` keyword. Attributes are declared
+with the `has` keyword, and methods declared with the `method` keyword.
+
+Every attribute that is private uses the `!` twigil. For example: `$!attr`.
+Immutable public attributes use the `.` twigil which creates a read-only
+method named after the attribute. In fact, declaring an attribute with `.`
+is equivalent to declaring the same attribute with `!` and then creating
+a read-only method with the attribute's name. However, this is done for us
+by Raku automatically. The easiest way to remember the `$.` twigil is
+by comparing it to how methods are called.
+
+Raku's object model ("SixModel") is very flexible, and allows you to
+dynamically add methods, change semantics, etc... Unfortunately, these will
+not all be covered here, and you should refer to:
+https://docs.raku.org/language/objects.html.
+=end comment
+
+class Human {
+ has Str $.name; # `$.name` is immutable but with an accessor method.
+ has Str $.bcountry; # Use `$!bcountry` to modify it inside the class.
+ has Str $.ccountry is rw; # This attribute can be modified from outside.
+ has Int $!age = 0; # A private attribute with default value.
+
+ method birthday {
+ $!age += 1; # Add a year to human's age
+ }
+
+ method get-age {
+ return $!age;
+ }
+
+ # This method is private to the class. Note the `!` before the
+ # method's name.
+ method !do-decoration {
+ return "$!name born in $!bcountry and now lives in $!ccountry."
+ }
+
+ # This method is public, just like `birthday` and `get-age`.
+ method get-info {
+ # Invoking a method on `self` inside the class.
+ # Use `self!priv-method` for private method.
+ say self!do-decoration;
+
+ # Use `self.public-method` for public method.
+ say "Age: ", self.get-age;
+ }
+};
+
+# Create a new instance of Human class.
+# NOTE: Only attributes declared with the `.` twigil can be set via the
+# default constructor (more later on). This constructor only accepts named
+# arguments.
+my $person1 = Human.new(
+ name => "Jord",
+ bcountry => "Togo",
+ ccountry => "Togo"
+);
+
+# Make human 10 years old.
+$person1.birthday for 1..10;
+
+say $person1.name; # OUTPUT: «Jord␤»
+say $person1.bcountry; # OUTPUT: «Togo␤»
+say $person1.ccountry; # OUTPUT: «Togo␤»
+say $person1.get-age; # OUTPUT: «10␤»
+
+# This fails, because the `has $.bcountry`is immutable. Jord can't change
+# his birthplace.
+# $person1.bcountry = "Mali";
+
+# This works because the `$.ccountry` is mutable (`is rw`). Now Jord's
+# current country is France.
+$person1.ccountry = "France";
+
+# Calling methods on the instance objects.
+$person1.birthday; #=> 1
+$person1.get-info; #=> Jord born in Togo and now lives in France. Age: 10
+# $person1.do-decoration; # This fails since the method `do-decoration` is private.
+
+#
+# 10.1 Object Inheritance
+#
+
+=begin comment
+Raku also has inheritance (along with multiple inheritance). While
+methods are inherited, submethods are not. Submethods are useful for
+object construction and destruction tasks, such as `BUILD`, or methods that
+must be overridden by subtypes. We will learn about `BUILD` later on.
+=end comment
+
+class Parent {
+ has $.age;
+ has $.name;
+
+ # This submethod won't be inherited by the Child class.
+ submethod favorite-color {
+ say "My favorite color is Blue";
+ }
+
+ # This method is inherited
+ method talk { say "Hi, my name is $!name" }
+}
+
+# Inheritance uses the `is` keyword
+class Child is Parent {
+ method talk { say "Goo goo ga ga" }
+ # This shadows Parent's `talk` method.
+ # This child hasn't learned to speak yet!
+}
+
+my Parent $Richard .= new(age => 40, name => 'Richard');
+$Richard.favorite-color; # OUTPUT: «My favorite color is Blue␤»
+$Richard.talk; # OUTPUT: «Hi, my name is Richard␤»
+# $Richard is able to access the submethod and he knows how to say his name.
+
+my Child $Madison .= new(age => 1, name => 'Madison');
+$Madison.talk; # OUTPUT: «Goo goo ga ga␤», due to the overridden method.
+# $Madison.favorite-color # does not work since it is not inherited.
+
+=begin comment
+When you use `my T $var`, `$var` starts off with `T` itself in it, so you can
+call `new` on it. (`.=` is just the dot-call and the assignment operator).
+Thus, `$a .= b` is the same as `$a = $a.b`. Also note that `BUILD` (the method
+called inside `new`) will set parent's properties too, so you can pass `val =>
+5`.
+=end comment
+
+#
+# 10.2 Roles, or Mixins
+#
+
+# Roles are supported too (which are called Mixins in other languages)
+role PrintableVal {
+ has $!counter = 0;
+ method print {
+ say $.val;
+ }
+}
+
+# you "apply" a role (or mixin) with the `does` keyword:
+class Item does PrintableVal {
+ has $.val;
+
+ =begin comment
+ When `does`-ed, a `role` literally "mixes in" the class:
+ the methods and attributes are put together, which means a class
+ can access the private attributes/methods of its roles (but
+ not the inverse!):
+ =end comment
+ method access {
+ say $!counter++;
+ }
+
+ =begin comment
+ However, this: method print {} is ONLY valid when `print` isn't a `multi`
+ with the same dispatch. This means a parent class can shadow a child class's
+ `multi print() {}`, but it's an error if a role does)
+
+ NOTE: You can use a role as a class (with `is ROLE`). In this case,
+ methods will be shadowed, since the compiler will consider `ROLE`
+ to be a class.
+ =end comment
+}
+
+####################################################
+# 11. Exceptions
+####################################################
+
+=begin comment
+Exceptions are built on top of classes, in the package `X` (like `X::IO`).
+In Raku, exceptions are automatically 'thrown':
+
+open 'foo'; # OUTPUT: «Failed to open file foo: no such file or directory␤»
+
+It will also print out what line the error was thrown at
+and other error info.
+=end comment
+
+# You can throw an exception using `die`. Here it's been commented out to
+# avoid stopping the program's execution:
+# die 'Error!'; # OUTPUT: «Error!␤»
+
+# Or more explicitly (commented out too):
+# X::AdHoc.new(payload => 'Error!').throw; # OUTPUT: «Error!␤»
+
+=begin comment
+In Raku, `orelse` is similar to the `or` operator, except it only matches
+undefined variables instead of anything evaluating as `False`.
+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:
+=end comment
+my $uninitialized;
+say $uninitialized.defined; # OUTPUT: «False␤»
+
+=begin comment
+When using `orelse` it will disarm the exception and alias $_ to that
+failure. This will prevent it to being automatically handled and printing
+lots of scary error messages to the screen. We can use the `exception`
+method on the `$_` variable to access the exception
+=end comment
+open 'foo' orelse say "Something happened {.exception}";
+
+# This also works:
+open 'foo' orelse say "Something happened $_";
+# OUTPUT: «Something happened Failed to open file foo: no such file or directory␤»
+
+=begin comment
+Both of those above work but in case we get an object from the left side
+that is not a failure we will probably get a warning. We see below how we
+can use try` and `CATCH` to be more specific with the exceptions we catch.
+=end comment
+
+#
+# 11.1 Using `try` and `CATCH`
+#
+
+=begin comment
+By using `try` and `CATCH` you can contain and handle exceptions without
+disrupting the rest of the program. The `try` block will set the last
+exception to the special variable `$!` (known as the error variable).
+NOTE: This has no relation to $!variables seen inside class definitions.
+=end comment
+
+try open 'foo';
+say "Well, I tried! $!" if defined $!;
+# OUTPUT: «Well, I tried! Failed to open file foo: no such file or directory␤»
+
+=begin comment
+Now, what if we want more control over handling the exception?
+Unlike many other languages, in Raku, you put the `CATCH` block *within*
+the block to `try`. Similar to how the `$_` variable was set when we
+'disarmed' the exception with `orelse`, we also use `$_` in the CATCH block.
+NOTE: The `$!` variable is only set *after* the `try` block has caught an
+exception. By default, a `try` block has a `CATCH` block of its own that
+catches any exception (`CATCH { default {} }`).
+=end comment
+
+try {
+ my $a = (0 %% 0);
+ CATCH {
+ default { say "Something happened: $_" }
+ }
+}
+# OUTPUT: «Something happened: Attempt to divide by zero using infix:<%%>␤»
+
+# You can redefine it using `when`s (and `default`) to handle the exceptions
+# you want to catch explicitly:
+
+try {
+ open 'foo';
+ CATCH {
+ # In the `CATCH` block, the exception is set to the $_ variable.
+ when X::AdHoc {
+ say "Error: $_"
+ }
+ when X::Numeric::DivideByZero {
+ say "Error: $_";
+ }
+
+ =begin comment
+ Any other exceptions will be re-raised, since we don't have a `default`.
+ Basically, if a `when` matches (or there's a `default`), the
+ exception is marked as "handled" so as to prevent its re-throw
+ from the `CATCH` block. You still can re-throw the exception
+ (see below) by hand.
+ =end comment
+ default {
+ say "Any other error: $_"
+ }
+ }
+}
+# OUTPUT: «Failed to open file /dir/foo: no such file or directory␤»
+
+=begin comment
+There are also some subtleties to exceptions. Some Raku subs return a
+`Failure`, which is a wrapper around an `Exception` object which is
+"unthrown". They're not thrown until you try to use the variables containing
+them unless you call `.Bool`/`.defined` on them - then they're handled.
+(the `.handled` method is `rw`, so you can mark it as `False` back yourself)
+You can throw a `Failure` using `fail`. Note that if the pragma `use fatal`
+is on, `fail` will throw an exception (like `die`).
+=end comment
+
+my $value = 0/0; # We're not trying to access the value, so no problem.
+try {
+ say 'Value: ', $value; # Trying to use the value
+ CATCH {
+ default {
+ say "It threw because we tried to get the fail's value!"
+ }
+ }
+}
+
+=begin comment
+There is also another kind of exception: Control exceptions. Those are "good"
+exceptions, which happen when you change your program's flow, using operators
+like `return`, `next` or `last`. You can "catch" those with `CONTROL` (not 100%
+working in Rakudo yet).
+=end comment
+
+####################################################
+# 12. Packages
+####################################################
+
+=begin comment
+Packages are a way to reuse code. Packages are like "namespaces", and any
+element of the six model (`module`, `role`, `class`, `grammar`, `subset` and
+`enum`) are actually packages. (Packages are the lowest common denominator)
+Packages are important - especially as Perl is well-known for CPAN,
+the Comprehensive Perl Archive Network.
+=end comment
+
+# You can use a module (bring its declarations into scope) with `use`:
+use JSON::Tiny; # if you installed Rakudo* or Panda, you'll have this module
+say from-json('[1]').perl; # OUTPUT: «[1]␤»
+
+=begin comment
+You should not declare packages using the `package` keyword (unlike Perl).
+Instead, use `class Package::Name::Here;` to declare a class, or if you only
+want to export variables/subs, you can use `module` instead.
+=end comment
+
+# If `Hello` doesn't exist yet, it'll just be a "stub", that can be redeclared
+# as something else later.
+module Hello::World { # bracketed form
+ # declarations here
+}
+
+# The file-scoped form which extends until the end of the file. For
+# instance, `unit module Parse::Text;` will extend until of the file.
+
+# A grammar is a package, which you could `use`. You will learn more about
+# grammars in the regex section.
+grammar Parse::Text::Grammar {
+}
+
+# As said before, any part of the six model is also a package.
+# Since `JSON::Tiny` uses its own `JSON::Tiny::Actions` class, you can use it:
+my $actions = JSON::Tiny::Actions.new;
+
+# We'll see how to export variables and subs in the next part.
+
+####################################################
+# 13. Declarators
+####################################################
+
+=begin comment
+In Raku, you get different behaviors based on how you declare a variable.
+You've already seen `my` and `has`, we'll now explore the others.
+
+`our` - these declarations happen at `INIT` time -- (see "Phasers" below).
+It's like `my`, but it also creates a package variable. All packagish
+things such as `class`, `role`, etc. are `our` by default.
+=end comment
+
+module Var::Increment {
+ # NOTE: `our`-declared variables cannot be typed.
+ our $our-var = 1;
+ my $my-var = 22;
+
+ our sub Inc {
+ our sub available { # If you try to make inner `sub`s `our`...
+ # ... Better know what you're doing (Don't !).
+ say "Don't do that. Seriously. You'll get burned.";
+ }
+
+ my sub unavailable { # `sub`s are `my`-declared by default
+ say "Can't access me from outside, I'm 'my'!";
+ }
+ say ++$our-var; # Increment the package variable and output its value
+ }
+
+}
+
+say $Var::Increment::our-var; # OUTPUT: «1␤», this works!
+say $Var::Increment::my-var; # OUTPUT: «(Any)␤», this will not work!
+
+say Var::Increment::Inc; # OUTPUT: «2␤»
+say Var::Increment::Inc; # OUTPUT: «3␤», notice how the value of $our-var was retained.
+
+# Var::Increment::unavailable; # OUTPUT: «Could not find symbol '&unavailable'␤»
+
+# `constant` - these declarations happen at `BEGIN` time. You can use
+# the `constant` keyword to declare a compile-time variable/symbol:
+constant Pi = 3.14;
+constant $var = 1;
+
+# And if you're wondering, yes, it can also contain infinite lists.
+constant why-not = 5, 15 ... *;
+say why-not[^5]; # OUTPUT: «5 15 25 35 45␤»
+
+# `state` - these declarations happen at run time, but only once. State
+# variables are only initialized one time. In other languages such as C
+# they exist as `static` variables.
+sub fixed-rand {
+ state $val = rand;
+ say $val;
+}
+fixed-rand for ^10; # will print the same number 10 times
+
+# Note, however, that they exist separately in different enclosing contexts.
+# If you declare a function with a `state` within a loop, it'll re-create the
+# variable for each iteration of the loop. See:
+for ^5 -> $a {
+ sub foo {
+ # This will be a different value for every value of `$a`
+ state $val = rand;
+ }
+ for ^5 -> $b {
+ # This will print the same value 5 times, but only 5. Next iteration
+ # will re-run `rand`.
+ say foo;
+ }
+}
+
+####################################################
+# 14. Phasers
+####################################################
+
+=begin comment
+Phasers in Raku are blocks that happen at determined points of time in
+your program. They are called phasers because they mark a change in the
+phase of a program. For example, when the program is compiled, a for loop
+runs, you leave a block, or an exception gets thrown (The `CATCH` block is
+actually a phaser!). Some of them can be used for their return values,
+some of them can't (those that can have a "[*]" in the beginning of their
+explanation text). Let's have a look!
+=end comment
+
+#
+# 14.1 Compile-time phasers
+#
+BEGIN { say "[*] Runs at compile time, as soon as possible, only once" }
+CHECK { say "[*] Runs at compile time, as late as possible, only once" }
+
+#
+# 14.2 Run-time phasers
+#
+INIT { say "[*] Runs at run time, as soon as possible, only once" }
+END { say "Runs at run time, as late as possible, only once" }
+
+#
+# 14.3 Block phasers
+#
+ENTER { say "[*] Runs every time you enter a block, repeats on loop blocks" }
+LEAVE {
+ say "Runs every time you leave a block, even when an exception
+ happened. Repeats on loop blocks."
+}
+
+PRE {
+ say "Asserts a precondition at every block entry,
+ before ENTER (especially useful for loops)";
+ say "If this block doesn't return a truthy value,
+ an exception of type X::Phaser::PrePost is thrown.";
+}
+
+# Example (commented out):
+for 0..2 {
+ # PRE { $_ > 1 } # OUTPUT: «Precondition '{ $_ > 1 }' failed
+}
+
+POST {
+ say "Asserts a postcondition at every block exit,
+ after LEAVE (especially useful for loops)";
+ say "If this block doesn't return a truthy value,
+ an exception of type X::Phaser::PrePost is thrown, like PRE.";
+}
+
+# Example (commented out):
+for 0..2 {
+ # POST { $_ < 1 } # OUTPUT: «Postcondition '{ $_ < 1 }' failed
+}
+
+#
+# 14.4 Block/exceptions phasers
+#
+{
+ KEEP { say "Runs when you exit a block successfully
+ (without throwing an exception)" }
+ UNDO { say "Runs when you exit a block unsuccessfully
+ (by throwing an exception)" }
+}
+
+#
+# 14.5 Loop phasers
+#
+for ^5 {
+ FIRST { say "[*] The first time the loop is run, before ENTER" }
+ NEXT { say "At loop continuation time, before LEAVE" }
+ LAST { say "At loop termination time, after LEAVE" }
+}
+
+#
+# 14.6 Role/class phasers
+#
+COMPOSE {
+ say "When a role is composed into a class. /!\ NOT YET IMPLEMENTED"
+}
+
+# They allow for cute tricks or clever code...:
+say "This code took " ~ (time - CHECK time) ~ "s to compile";
+
+# ... or clever organization:
+class DB {
+ method start-transaction { say "Starting transaction!" }
+ method commit { say "Committing transaction..." }
+ method rollback { say "Something went wrong. Rolling back!" }
+}
+
+sub do-db-stuff {
+ my DB $db .= new;
+ $db.start-transaction; # start a new transaction
+ KEEP $db.commit; # commit the transaction if all went well
+ UNDO $db.rollback; # or rollback if all hell broke loose
+}
+
+do-db-stuff();
+
+####################################################
+# 15. Statement prefixes
+####################################################
+
+=begin comment
+Those act a bit like phasers: they affect the behavior of the following
+code. Though, they run in-line with the executable code, so they're in
+lowercase. (`try` and `start` are theoretically in that list, but explained
+elsewhere) NOTE: all of these (except start) don't need explicit curly
+braces `{` and `}`.
+
+=end comment
+
+#
+# 15.1 `do` - It runs a block or a statement as a term.
+#
+
+# Normally you cannot use a statement as a value (or "term"). `do` helps
+# us do it. With `do`, an `if`, for example, becomes a term returning a value.
+=for comment :reason<this fails since `if` is a statement>
+my $value = if True { 1 }
+
+# this works!
+my $get-five = do if True { 5 }
+
+#
+# 15.1 `once` - makes sure a piece of code only runs once.
+#
+for ^5 {
+ once say 1
+};
+# OUTPUT: «1␤», only prints ... once
+
+# Similar to `state`, they're cloned per-scope.
+for ^5 {
+ sub { once say 1 }()
+};
+# OUTPUT: «1 1 1 1 1␤», prints once per lexical scope.
+
+#
+# 15.2 `gather` - co-routine thread.
+#
+
+# The `gather` constructs allows us to `take` several values from an array/list,
+# much like `do`.
+say gather for ^5 {
+ take $_ * 3 - 1;
+ take $_ * 3 + 1;
+}
+# OUTPUT: «-1 1 2 4 5 7 8 10 11 13␤»
+
+say join ',', gather if False {
+ take 1;
+ take 2;
+ take 3;
+}
+# Doesn't print anything.
+
+#
+# 15.3 `eager` - evaluates a statement eagerly (forces eager context).
+
+# Don't try this at home. This will probably hang for a while (and might crash)
+# so commented out.
+# eager 1..*;
+
+# But consider, this version which doesn't print anything
+constant thricev0 = gather for ^3 { say take $_ };
+# to:
+constant thricev1 = eager gather for ^3 { say take $_ }; # OUTPUT: «0 1 2␤»
+
+####################################################
+# 16. Iterables
+####################################################
+
+# Iterables are objects that can be iterated over for things such as
+# the `for` construct.
+
+#
+# 16.1 `flat` - flattens iterables.
+#
+say (1, 10, (20, 10) ); # OUTPUT: «(1 10 (20 10))␤», notice how nested
+ # lists are preserved
+say (1, 10, (20, 10) ).flat; # OUTPUT: «(1 10 20 10)␤», now the iterable is flat
+
+#
+# 16.2 `lazy` - defers actual evaluation until value is fetched by forcing lazy context.
+#
+my @lazy-array = (1..100).lazy;
+say @lazy-array.is-lazy; # OUTPUT: «True␤», check for laziness with the `is-lazy` method.
+
+say @lazy-array; # OUTPUT: «[...]␤», List has not been iterated on!
+
+# This works and will only do as much work as is needed.
+for @lazy-array { .print };
+
+# (**TODO** explain that gather/take and map are all lazy)
+
+#
+# 16.3 `sink` - an `eager` that discards the results by forcing sink context.
+#
+constant nilthingie = sink for ^3 { .say } #=> 0 1 2
+say nilthingie.perl; # OUTPUT: «Nil␤»
+
+#
+# 16.4 `quietly` - suppresses warnings in blocks.
+#
+quietly { warn 'This is a warning!' }; # No output
+
+####################################################
+# 17. More operators thingies!
+####################################################
+
+# Everybody loves operators! Let's get more of them.
+
+# The precedence list can be found here:
+# https://docs.raku.org/language/operators#Operator_Precedence
+# But first, we need a little explanation about associativity:
+
+#
+# 17.1 Binary operators
+#
+
+my ($p, $q, $r) = (1, 2, 3);
+
+=begin comment
+Given some binary operator § (not a Raku-supported operator), then:
+
+$p § $q § $r; # with a left-associative §, this is ($p § $q) § $r
+$p § $q § $r; # with a right-associative §, this is $p § ($q § $r)
+$p § $q § $r; # with a non-associative §, this is illegal
+$p § $q § $r; # with a chain-associative §, this is ($p § $q) and ($q § $r)§
+$p § $q § $r; # with a list-associative §, this is `infix:<>`
+=end comment
+
+#
+# 17.2 Unary operators
+#
+
+=begin comment
+Given some unary operator § (not a Raku-supported operator), then:
+§$p§ # with left-associative §, this is (§$p)§
+§$p§ # with right-associative §, this is §($p§)
+§$p§ # with non-associative §, this is illegal
+=end comment
+
+#
+# 17.3 Create your own operators!
+#
+
+=begin comment
+Okay, you've been reading all of that, so you might want to try something
+more exciting?! I'll tell you a little secret (or not-so-secret):
+In Raku, all operators are actually just funny-looking subroutines.
+
+You can declare an operator just like you declare a sub. In the following
+example, `prefix` refers to the operator categories (prefix, infix, postfix,
+circumfix, and post-circumfix).
+=end comment
+sub prefix:<win>( $winner ) {
+ say "$winner Won!";
+}
+win "The King"; # OUTPUT: «The King Won!␤»
+
+# you can still call the sub with its "full name":
+say prefix:<!>(True); # OUTPUT: «False␤»
+prefix:<win>("The Queen"); # OUTPUT: «The Queen Won!␤»
+
+sub postfix:<!>( Int $n ) {
+ [*] 2..$n; # using the reduce meta-operator... See below ;-)!
+}
+say 5!; # OUTPUT: «120␤»
+
+# Postfix operators ('after') have to come *directly* after the term.
+# No whitespace. You can use parentheses to disambiguate, i.e. `(5!)!`
+
+sub infix:<times>( Int $n, Block $r ) { # infix ('between')
+ for ^$n {
+ # You need the explicit parentheses to call the function in `$r`,
+ # else you'd be referring at the code object itself, like with `&r`.
+ $r();
+ }
+}
+3 times -> { say "hello" }; # OUTPUT: «hello␤hello␤hello␤»
+
+# It's recommended to put spaces around your infix operator calls.
+
+# For circumfix and post-circumfix ones
+multi circumfix:<[ ]>( Int $n ) {
+ $n ** $n
+}
+say [5]; # OUTPUT: «3125␤»
+
+# Circumfix means 'around'. Again, no whitespace.
+
+multi postcircumfix:<{ }>( Str $s, Int $idx ) {
+ $s.substr($idx, 1);
+}
+say "abc"{1}; # OUTPUT: «b␤», after the term `"abc"`, and around the index (1)
+
+# Post-circumfix is 'after a term, around something'
+
+=begin comment
+This really means a lot -- because everything in Raku uses this.
+For example, to delete a key from a hash, you use the `:delete` adverb
+(a simple named argument underneath). For instance, the following statements
+are equivalent.
+=end comment
+my %person-stans =
+ 'Giorno Giovanna' => 'Gold Experience',
+ 'Bruno Bucciarati' => 'Sticky Fingers';
+my $key = 'Bruno Bucciarati';
+%person-stans{$key}:delete;
+postcircumfix:<{ }>( %person-stans, 'Giorno Giovanna', :delete );
+# (you can call operators like this)
+
+=begin comment
+It's *all* using the same building blocks! Syntactic categories
+(prefix infix ...), named arguments (adverbs), ..., etc. used to build
+the language - are available to you. Obviously, you're advised against
+making an operator out of *everything* -- with great power comes great
+responsibility.
+=end comment
+
+#
+# 17.4 Meta operators!
+#
+
+=begin comment
+Oh boy, get ready!. Get ready, because we're delving deep into the rabbit's
+hole, and you probably won't want to go back to other languages after
+reading this. (I'm guessing you don't want to go back at this point but
+let's continue, for the journey is long and enjoyable!).
+
+Meta-operators, as their name suggests, are *composed* operators. Basically,
+they're operators that act on another operators.
+
+The reduce meta-operator is a prefix meta-operator that takes a binary
+function and one or many lists. If it doesn't get passed any argument,
+it either returns a "default value" for this operator (a meaningless value)
+or `Any` if there's none (examples below). Otherwise, it pops an element
+from the list(s) one at a time, and applies the binary function to the last
+result (or the first element of a list) and the popped element.
+=end comment
+
+# To sum a list, you could use the reduce meta-operator with `+`, i.e.:
+say [+] 1, 2, 3; # OUTPUT: «6␤», equivalent to (1+2)+3.
+
+# To multiply a list
+say [*] 1..5; # OUTPUT: «120␤», equivalent to ((((1*2)*3)*4)*5).
+
+# You can reduce with any operator, not just with mathematical ones.
+# For example, you could reduce with `//` to get first defined element
+# of a list:
+say [//] Nil, Any, False, 1, 5; # OUTPUT: «False␤»
+ # (Falsey, but still defined)
+# Or with relational operators, i.e., `>` to check elements of a list
+# are ordered accordingly:
+say [>] 234, 156, 6, 3, -20; # OUTPUT: «True␤»
+
+# Default value examples:
+say [*] (); # OUTPUT: «1␤», empty product
+say [+] (); # OUTPUT: «0␤», empty sum
+say [//]; # OUTPUT: «(Any)␤»
+ # There's no "default value" for `//`.
+
+# You can also use it with a function you made up,
+# You can also surround using double brackets:
+sub add($a, $b) { $a + $b }
+say [[&add]] 1, 2, 3; # OUTPUT: «6␤»
+
+=begin comment
+The zip meta-operator is an infix meta-operator that also can be used as a
+"normal" operator. It takes an optional binary function (by default, it
+just creates a pair), and will pop one value off of each array and call
+its binary function on these until it runs out of elements. It returns an
+array with all of these new elements.
+=end comment
+say (1, 2) Z (3, 4); # OUTPUT: «((1, 3), (2, 4))␤»
+say 1..3 Z+ 4..6; # OUTPUT: «(5, 7, 9)␤»
+
+# Since `Z` is list-associative (see the list above), you can use it on more
+# than one list.
+(True, False) Z|| (False, False) Z|| (False, False); # (True, False)
+
+# And, as it turns out, you can also use the reduce meta-operator with it:
+[Z||] (True, False), (False, False), (False, False); # (True, False)
+
+# And to end the operator list:
+
+=begin comment
+The sequence operator (`...`) is one of Raku's most powerful features:
+It's composed by the list (which might include a closure) you want Raku to
+deduce from on the left and a value (or either a predicate or a Whatever Star
+for a lazy infinite list) on the right that states when to stop.
+=end comment
+
+# Basic arithmetic sequence
+my @listv0 = 1, 2, 3...10;
+
+# This dies because Raku can't figure out the end
+# my @list = 1, 3, 6...10;
+
+# As with ranges, you can exclude the last element (the iteration ends when
+# the predicate matches).
+my @listv1 = 1, 2, 3...^10;
+
+# You can use a predicate (with the Whatever Star).
+my @listv2 = 1, 3, 9...* > 30;
+
+# Equivalent to the example above but using a block here.
+my @listv3 = 1, 3, 9 ... { $_ > 30 };
+
+# Lazy infinite list of fibonacci sequence, computed using a closure!
+my @fibv0 = 1, 1, *+* ... *;
+
+# Equivalent to the above example but using a pointy block.
+my @fibv1 = 1, 1, -> $a, $b { $a + $b } ... *;
+
+# Equivalent to the above example but using a block with placeholder parameters.
+my @fibv2 = 1, 1, { $^a + $^b } ... *;
+
+=begin comment
+In the examples with explicit parameters (i.e., $a and $b), $a and $b
+will always take the previous values, meaning that for the Fibonacci sequence,
+they'll start with $a = 1 and $b = 1 (values we set by hand), then $a = 1
+and $b = 2 (result from previous $a + $b), and so on.
+=end comment
+
+=begin comment
+# In the example we use a range as an index to access the sequence. However,
+# it's worth noting that for ranges, once reified, elements aren't re-calculated.
+# That's why, for instance, `@primes[^100]` will take a long time the first
+# time you print it but then it will be instateneous.
+=end comment
+say @fibv0[^10]; # OUTPUT: «1 1 2 3 5 8 13 21 34 55␤»
+
+####################################################
+# 18. Regular Expressions
+####################################################
+
+=begin comment
+I'm sure a lot of you have been waiting for this one. Well, now that you know
+a good deal of Raku already, we can get started. First off, you'll have to
+forget about "PCRE regexps" (perl-compatible regexps).
+
+IMPORTANT: Don't skip them because you know PCRE. They're different. Some
+things are the same (like `?`, `+`, and `*`), but sometimes the semantics
+change (`|`). Make sure you read carefully, because you might trip over a
+new behavior.
+
+Raku has many features related to RegExps. After all, Rakudo parses itself.
+We're first going to look at the syntax itself, then talk about grammars
+(PEG-like), differences between `token`, `regex` and `rule` declarators,
+and some more. Side note: you still have access to PCRE regexps using the
+`:P5` modifier which we won't be discussing this in this tutorial, though.
+
+In essence, Raku natively implements PEG ("Parsing Expression Grammars").
+The pecking order for ambiguous parses is determined by a multi-level
+tie-breaking test:
+ - Longest token matching: `foo\s+` beats `foo` (by 2 or more positions)
+ - Longest literal prefix: `food\w*` beats `foo\w*` (by 1)
+ - Declaration from most-derived to less derived grammars
+ (grammars are actually classes)
+ - Earliest declaration wins
+=end comment
+say so 'a' ~~ /a/; # OUTPUT: «True␤»
+say so 'a' ~~ / a /; # OUTPUT: «True␤», more readable with some spaces!
+
+=begin comment
+In all our examples, we're going to use the smart-matching operator against
+a regexp. We're converting the result using `so` to a Boolean value because,
+in fact, it's returning a `Match` object. They know how to respond to list
+indexing, hash indexing, and return the matched string. The results of the
+match are available in the `$/` variable (implicitly lexically-scoped). You
+can also use the capture variables which start at 0: `$0`, `$1', `$2`...
+
+You can also note that `~~` does not perform start/end checking, meaning
+the regexp can be matched with just one character of the string. We'll
+explain later how you can do it.
+
+In Raku, you can have any alphanumeric as a literal, everything else has
+to be escaped by using a backslash or quotes.
+=end comment
+say so 'a|b' ~~ / a '|' b /; # OUTPUT: «True␤», it wouldn't mean the same
+ # thing if `|` wasn't escaped.
+say so 'a|b' ~~ / a \| b /; # OUTPUT: «True␤», another way to escape it.
+
+# The whitespace in a regex is actually not significant, unless you use the
+# `:s` (`:sigspace`, significant space) adverb.
+say so 'a b c' ~~ / a b c /; #=> `False`, space is not significant here!
+say so 'a b c' ~~ /:s a b c /; #=> `True`, we added the modifier `:s` here.
+
+# If we use only one space between strings in a regex, Raku will warn us
+# about space being not signicant in the regex:
+say so 'a b c' ~~ / a b c /; # OUTPUT: «False␤»
+say so 'a b c' ~~ / a b c /; # OUTPUT: «False»
+
+=begin comment
+NOTE: Please use quotes or `:s` (`:sigspace`) modifier (or, to suppress this
+warning, omit the space, or otherwise change the spacing). To fix this and make
+the spaces less ambiguous, either use at least two spaces between strings
+or use the `:s` adverb.
+=end comment
+
+# As we saw before, we can embed the `:s` inside the slash delimiters, but we
+# can also put it outside of them if we specify `m` for 'match':
+say so 'a b c' ~~ m:s/a b c/; # OUTPUT: «True␤»
+
+# By using `m` to specify 'match', we can also use other delimiters:
+say so 'abc' ~~ m{a b c}; # OUTPUT: «True␤»
+say so 'abc' ~~ m[a b c]; # OUTPUT: «True␤»
+
+# `m/.../` is equivalent to `/.../`:
+say 'raku' ~~ m/raku/; # OUTPUT: «True␤»
+say 'raku' ~~ /raku/; # OUTPUT: «True␤»
+
+# Use the `:i` adverb to specify case insensitivity:
+say so 'ABC' ~~ m:i{a b c}; # OUTPUT: «True␤»
+
+# However, whitespace is important as for how modifiers are applied
+# (which you'll see just below) ...
+
+#
+# 18.1 Quantifiers - `?`, `+`, `*` and `**`.
+#
+
+# `?` - zero or one match
+say so 'ac' ~~ / a b c /; # OUTPUT: «False␤»
+say so 'ac' ~~ / a b? c /; # OUTPUT: «True␤», the "b" matched 0 times.
+say so 'abc' ~~ / a b? c /; # OUTPUT: «True␤», the "b" matched 1 time.
+
+# ... As you read before, whitespace is important because it determines which
+# part of the regex is the target of the modifier:
+say so 'def' ~~ / a b c? /; # OUTPUT: «False␤», only the "c" is optional
+say so 'def' ~~ / a b? c /; # OUTPUT: «False␤», whitespace is not significant
+say so 'def' ~~ / 'abc'? /; # OUTPUT: «True␤», the whole "abc" group is optional
+
+# Here (and below) the quantifier applies only to the "b"
+
+# `+` - one or more matches
+say so 'ac' ~~ / a b+ c /; # OUTPUT: «False␤», `+` wants at least one 'b'
+say so 'abc' ~~ / a b+ c /; # OUTPUT: «True␤», one is enough
+say so 'abbbbc' ~~ / a b+ c /; # OUTPUT: «True␤», matched 4 "b"s
+
+# `*` - zero or more matches
+say so 'ac' ~~ / a b* c /; # OUTPUT: «True␤», they're all optional
+say so 'abc' ~~ / a b* c /; # OUTPUT: «True␤»
+say so 'abbbbc' ~~ / a b* c /; # OUTPUT: «True␤»
+say so 'aec' ~~ / a b* c /; # OUTPUT: «False␤», "b"(s) are optional, not replaceable.
+
+# `**` - (Unbound) Quantifier
+# If you squint hard enough, you might understand why exponentation is used
+# for quantity.
+say so 'abc' ~~ / a b**1 c /; # OUTPUT: «True␤», exactly one time
+say so 'abc' ~~ / a b**1..3 c /; # OUTPUT: «True␤», one to three times
+say so 'abbbc' ~~ / a b**1..3 c /; # OUTPUT: «True␤»
+say so 'abbbbbbc' ~~ / a b**1..3 c /; # OUTPUT: «Fals␤», too much
+say so 'abbbbbbc' ~~ / a b**3..* c /; # OUTPUT: «True␤», infinite ranges are ok
+
+#
+# 18.2 `<[]>` - Character classes
+#
+
+# Character classes are the equivalent of PCRE's `[]` classes, but they use a
+# more raku-ish syntax:
+say 'fooa' ~~ / f <[ o a ]>+ /; # OUTPUT: «fooa␤»
+
+# You can use ranges (`..`):
+say 'aeiou' ~~ / a <[ e..w ]> /; # OUTPUT: «ae␤»
+
+# Just like in normal regexes, if you want to use a special character, escape
+# it (the last one is escaping a space which would be equivalent to using
+# ' '):
+say 'he-he !' ~~ / 'he-' <[ a..z \! \ ]> + /; # OUTPUT: «he-he !␤»
+
+# You'll get a warning if you put duplicate names (which has the nice effect
+# of catching the raw quoting):
+'he he' ~~ / <[ h e ' ' ]> /;
+# Warns "Repeated character (') unexpectedly found in character class"
+
+# You can also negate character classes... (`<-[]>` equivalent to `[^]` in PCRE)
+say so 'foo' ~~ / <-[ f o ]> + /; # OUTPUT: «False␤»
+
+# ... and compose them:
+# any letter except "f" and "o"
+say so 'foo' ~~ / <[ a..z ] - [ f o ]> + /; # OUTPUT: «False␤»
+
+# no letter except "f" and "o"
+say so 'foo' ~~ / <-[ a..z ] + [ f o ]> + /; # OUTPUT: «True␤»
+
+# the + doesn't replace the left part
+say so 'foo!' ~~ / <-[ a..z ] + [ f o ]> + /; # OUTPUT: «True␤»
+
+#
+# 18.3 Grouping and capturing
+#
+
+# Group: you can group parts of your regexp with `[]`. Unlike PCRE's `(?:)`,
+# these groups are *not* captured.
+say so 'abc' ~~ / a [ b ] c /; # OUTPUT: «True␤», the grouping does nothing
+say so 'foo012012bar' ~~ / foo [ '01' <[0..9]> ] + bar /; # OUTPUT: «True␤»
+
+# The previous line returns `True`. The regex matches "012" one or more time
+# (achieved by the the `+` applied to the group).
+
+# But this does not go far enough, because we can't actually get back what
+# we matched.
+
+# Capture: The results of a regexp can be *captured* by using parentheses.
+say so 'fooABCABCbar' ~~ / foo ( 'A' <[A..Z]> 'C' ) + bar /; # OUTPUT: «True␤»
+# (using `so` here, see `$/` below)
+
+# So, starting with the grouping explanations. As we said before, our `Match`
+# object is stored inside the `$/` variable:
+say $/; # Will either print the matched object or `Nil` if nothing matched.
+
+# As we also said before, it has array indexing:
+say $/[0]; # OUTPUT: «「ABC」 「ABC」␤»,
+
+# The corner brackets (「..」) represent (and are) `Match` objects. In the
+# previous example, we have an array of them.
+
+say $0; # The same as above.
+
+=begin comment
+Our capture is `$0` because it's the first and only one capture in the
+regexp. You might be wondering why it's an array, and the answer is simple:
+Some captures (indexed using `$0`, `$/[0]` or a named one) will be an array
+if and only if they can have more than one element. Thus any capture with
+`*`, `+` and `**` (whatever the operands), but not with `?`.
+Let's use examples to see that:
+
+NOTE: We quoted A B C to demonstrate that the whitespace between them isn't
+significant. If we want the whitespace to *be* significant there, we can use the
+`:sigspace` modifier.
+=end comment
+say so 'fooABCbar' ~~ / foo ( "A" "B" "C" )? bar /; # OUTPUT: «True␤»
+say $/[0]; # OUTPUT: «「ABC」␤»
+say $0.WHAT; # OUTPUT: «(Match)␤»
+ # There can't be more than one, so it's only a single match object.
+
+say so 'foobar' ~~ / foo ( "A" "B" "C" )? bar /; # OUTPUT: «True␤»
+say $0.WHAT; # OUTPUT: «(Any)␤», this capture did not match, so it's empty.
+
+say so 'foobar' ~~ / foo ( "A" "B" "C" ) ** 0..1 bar /; #=> OUTPUT: «True␤»
+say $0.WHAT; # OUTPUT: «(Array)␤», A specific quantifier will always capture
+ # an Array, be a range or a specific value (even 1).
+
+# The captures are indexed per nesting. This means a group in a group will be
+# nested under its parent group: `$/[0][0]`, for this code:
+'hello-~-world' ~~ / ( 'hello' ( <[ \- \~ ]> + ) ) 'world' /;
+say $/[0].Str; # OUTPUT: «hello~␤»
+say $/[0][0].Str; # OUTPUT: «~␤»
+
+=begin comment
+This stems from a very simple fact: `$/` does not contain strings, integers
+or arrays, it only contains `Match` objects. These contain the `.list`, `.hash`
+and `.Str` methods but you can also just use `match<key>` for hash access
+and `match[idx]` for array access.
+
+In the following example, we can see `$_` is a list of `Match` objects.
+Each of them contain a wealth of information: where the match started/ended,
+the "ast" (see actions later), etc. You'll see named capture below with
+grammars.
+=end comment
+say $/[0].list.perl; # OUTPUT: «(Match.new(...),).list␤»
+
+# Alternation - the `or` of regexes
+# WARNING: They are DIFFERENT from PCRE regexps.
+say so 'abc' ~~ / a [ b | y ] c /; # OUTPUT: «True␤», Either "b" or "y".
+say so 'ayc' ~~ / a [ b | y ] c /; # OUTPUT: «True␤», Obviously enough...
+
+# The difference between this `|` and the one you're used to is
+# LTM ("Longest Token Matching") strategy. This means that the engine will
+# always try to match as much as possible in the string.
+say 'foo' ~~ / fo | foo /; # OUTPUT: «foo», instead of `fo`, because it's longer.
+
+=begin comment
+To decide which part is the "longest", it first splits the regex in two parts:
+
+ * The "declarative prefix" (the part that can be statically analyzed)
+ which includes alternations (`|`), conjunctions (`&`), sub-rule calls (not
+ yet introduced), literals, characters classes and quantifiers.
+
+ * The "procedural part" includes everything else: back-references,
+ code assertions, and other things that can't traditionally be represented
+ by normal regexps.
+
+Then, all the alternatives are tried at once, and the longest wins.
+=end comment
+
+# Examples:
+# DECLARATIVE | PROCEDURAL
+/ 'foo' \d+ [ <subrule1> || <subrule2> ] /;
+
+# DECLARATIVE (nested groups are not a problem)
+/ \s* [ \w & b ] [ c | d ] /;
+
+# However, closures and recursion (of named regexes) are procedural.
+# There are also more complicated rules, like specificity (literals win
+# over character classes).
+
+# NOTE: The alternation in which all the branches are tried in order
+# until the first one matches still exists, but is now spelled `||`.
+say 'foo' ~~ / fo || foo /; # OUTPUT: «fo␤», in this case.
+
+####################################################
+# 19. Extra: the MAIN subroutine
+####################################################
+
+=begin comment
+The `MAIN` subroutine is called when you run a Raku file directly. It's
+very powerful, because Raku actually parses the arguments and pass them
+as such to the sub. It also handles named argument (`--foo`) and will even
+go as far as to autogenerate a `--help` flag.
+=end comment
+
+sub MAIN($name) {
+ say "Hello, $name!";
+}
+=begin comment
+Supposing the code above is in file named cli.raku, then running in the command
+line (e.g., $ raku cli.raku) produces:
+Usage:
+ cli.raku <name>
+=end comment
+
+=begin comment
+And since MAIN is a regular Raku sub, you can have multi-dispatch:
+(using a `Bool` for the named argument so that we can do `--replace`
+instead of `--replace=1`. The presence of `--replace` indicates truthness
+while its absence falseness). For example:
+
+ # convert to IO object to check the file exists
+ subset File of Str where *.IO.d;
+
+ multi MAIN('add', $key, $value, Bool :$replace) { ... }
+ multi MAIN('remove', $key) { ... }
+ multi MAIN('import', File, Str :$as) { ... } # omitting parameter name
+
+Thus $ raku cli.raku produces:
+Usage:
+ cli.raku [--replace] add <key> <value>
+ cli.raku remove <key>
+ cli.raku [--as=<Str>] import <File>
+
+As you can see, this is *very* powerful. It even went as far as to show inline
+the constants (the type is only displayed if the argument is `$`/is named).
+=end comment
+
+####################################################
+# 20. APPENDIX A:
+####################################################
+
+=begin comment
+It's assumed by now you know the Raku basics. This section is just here to
+list some common operations, but which are not in the "main part" of the
+tutorial to avoid bloating it up.
+=end comment
+
+#
+# 20.1 Operators
+#
+
+# Sort comparison - they return one value of the `Order` enum: `Less`, `Same`
+# and `More` (which numerify to -1, 0 or +1 respectively).
+say 1 <=> 4; # OUTPUT: «More␤», sort comparison for numerics
+say 'a' leg 'b'; # OUTPUT: «Lessre␤», sort comparison for string
+say 1 eqv 1; # OUTPUT: «Truere␤», sort comparison using eqv semantics
+say 1 eqv 1.0; # OUTPUT: «False␤»
+
+# Generic ordering
+say 3 before 4; # OUTPUT: «True␤»
+say 'b' after 'a'; # OUTPUT: «True␤»
+
+# Short-circuit default operator - similar to `or` and `||`, but instead
+# returns the first *defined* value:
+say Any // Nil // 0 // 5; # OUTPUT: «0␤»
+
+# Short-circuit exclusive or (XOR) - returns `True` if one (and only one) of
+# its arguments is true
+say True ^^ False; # OUTPUT: «True␤»
+
+=begin comment
+Flip flops. These operators (`ff` and `fff`, equivalent to P5's `..`
+and `...`) are operators that take two predicates to test: They are `False`
+until their left side returns `True`, then are `True` until their right
+side returns `True`. Similar to ranges, you can exclude the iteration when
+it become `True`/`False` by using `^` on either side. Let's start with an
+example :
+=end comment
+
+for <well met young hero we shall meet later> {
+ # by default, `ff`/`fff` smart-match (`~~`) against `$_`:
+ if 'met' ^ff 'meet' { # Won't enter the if for "met"
+ .say # (explained in details below).
+ }
+
+ if rand == 0 ff rand == 1 { # compare variables other than `$_`
+ say "This ... probably will never run ...";
+ }
+}
+
+=begin comment
+This will print "young hero we shall meet" (excluding "met"): the flip-flop
+will start returning `True` when it first encounters "met" (but will still
+return `False` for "met" itself, due to the leading `^` on `ff`), until it
+sees "meet", which is when it'll start returning `False`.
+=end comment
+
+=begin comment
+The difference between `ff` (awk-style) and `fff` (sed-style) is that `ff`
+will test its right side right when its left side changes to `True`, and can
+get back to `False` right away (*except* it'll be `True` for the iteration
+that matched) while `fff` will wait for the next iteration to try its right
+side, once its left side changed:
+=end comment
+
+# The output is due to the right-hand-side being tested directly (and returning
+# `True`). "B"s are printed since it matched that time (it just went back to
+# `False` right away).
+.say if 'B' ff 'B' for <A B C B A>; # OUTPUT: «B B␤»,
+
+# In this case the right-hand-side wasn't tested until `$_` became "C"
+# (and thus did not match instantly).
+.say if 'B' fff 'B' for <A B C B A>; #=> «B C B␤»,
+
+# A flip-flop can change state as many times as needed:
+for <test start print it stop not printing start print again stop not anymore> {
+ # exclude both "start" and "stop",
+ .say if $_ eq 'start' ^ff^ $_ eq 'stop'; # OUTPUT: «print it print again␤»
+}
+
+# You might also use a Whatever Star, which is equivalent to `True` for the
+# left side or `False` for the right, as shown in this example.
+# NOTE: the parenthesis are superfluous here (sometimes called "superstitious
+# parentheses"). Once the flip-flop reaches a number greater than 50, it'll
+# never go back to `False`.
+for (1, 3, 60, 3, 40, 60) {
+ .say if $_ > 50 ff *; # OUTPUT: «60␤3␤40␤60␤»
+}
+
+# You can also use this property to create an `if` that'll not go through the
+# first time. In this case, the flip-flop is `True` and never goes back to
+# `False`, but the `^` makes it *not run* on the first iteration
+for <a b c> { .say if * ^ff *; } # OUTPUT: «b␤c␤»
+
+# The `===` operator, which uses `.WHICH` on the objects to be compared, is
+# the value identity operator whereas the `=:=` operator, which uses `VAR()` on
+# the objects to compare them, is the container identity operator.
+```
+
+If you want to go further and learn more about Raku, you can:
+
+- Read the [Raku Docs](https://docs.raku.org/). This is a great
+resource on Raku. If you are looking for something, use the search bar.
+This will give you a dropdown menu of all the pages referencing your search
+term (Much better than using Google to find Raku documents!).
+
+- Read the [Raku Advent Calendar](https://rakuadventcalendar.wordpress.com/). This
+is a great source of Raku snippets and explanations. If the docs don't
+describe something well enough, you may find more detailed information here.
+This information may be a bit older but there are many great examples and
+explanations. Posts stopped at the end of 2015 when the language was declared
+stable and `Raku v6.c` was released.
+
+- Come along on `#raku` at [`irc.freenode.net`](https://webchat.freenode.net/?channels=#raku). The folks here are
+always helpful.
+
+- Check the [source of Raku's functions and
+classes](https://github.com/rakudo/rakudo/tree/master/src/core.c). Rakudo is
+mainly written in Raku (with a lot of NQP, "Not Quite Perl", a Raku subset
+easier to implement and optimize).
+
+- Read [the language design documents](https://design.raku.org/). They explain
+Raku from an implementor point-of-view, but it's still very interesting.
diff --git a/raylib.html.markdown b/raylib.html.markdown
new file mode 100644
index 00000000..0afc6e03
--- /dev/null
+++ b/raylib.html.markdown
@@ -0,0 +1,146 @@
+---
+category: tool
+tool: raylib
+filename: learnraylib.c
+contributors:
+ - ["Nikolas Wipper", "https://notnik.cc"]
+---
+
+**raylib** is a cross-platform easy-to-use graphics library, built around
+OpenGL 1.1, 2.1, 3.3 and OpenGL ES 2.0. Even though it is written in C
+it has bindings to over 50 different languages. This tutorial will use C,
+more specifically C99.
+
+```c
+#include <raylib.h>
+
+int main(void)
+{
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ // Before initialising raylib we can set configuration flags
+ SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT);
+
+ // raylib doesn't require us to store any instance structures
+ // At the moment raylib can handle only one window at a time
+ InitWindow(screenWidth, screenHeight, "MyWindow");
+
+ // Set our game to run at 60 frames-per-second
+ SetTargetFPS(60);
+
+ // Set a key that closes the window
+ // Could be 0 for no key
+ SetExitKey(KEY_DELETE);
+
+ // raylib defines two types of cameras: Camera3D and Camera2D
+ // Camera is a typedef for Camera3D
+ Camera camera = {
+ .position = {0.0f, 0.0f, 0.0f},
+ .target = {0.0f, 0.0f, 1.0f},
+ .up = {0.0f, 1.0f, 0.0f},
+ .fovy = 70.0f,
+ .type = CAMERA_PERSPECTIVE
+ };
+
+ // raylib supports loading of models, animations, images and sounds
+ // from various different file formats
+ Model myModel = LoadModel("my_model.obj");
+ Font someFont = LoadFont("some_font.ttf");
+
+ // Creates a 100x100 render texture
+ RenderTexture renderTexture = LoadRenderTexture(100, 100);
+
+ // WindowShouldClose checks if the user is closing the window
+ // This might happen using a shortcut, window controls
+ // or the key we set earlier
+ while (!WindowShouldClose())
+ {
+
+ // BeginDrawing needs to be called before any draw call
+ BeginDrawing();
+ {
+
+ // Sets the background to a certain color
+ ClearBackground(BLACK);
+
+ if (IsKeyDown(KEY_SPACE))
+ DrawCircle(400, 400, 30, GREEN);
+
+ // Simple draw text
+ DrawText("Congrats! You created your first window!",
+ 190, // x
+ 200, // y
+ 20, // font size
+ LIGHTGRAY
+ );
+
+ // For most functions there are several versions
+ // These are usually postfixed with Ex, Pro, V
+ // or sometimes Rec, Wires (only for 3D), Lines (only for 2D)
+ DrawTextEx(someFont,
+ "Text in another font",
+ (Vector2) {10, 10},
+ 20, // font size
+ 2, // spacing
+ LIGHTGRAY);
+
+ // Required for drawing 3D, has 2D equivalent
+ BeginMode3D(camera);
+ {
+
+ DrawCube((Vector3) {0.0f, 0.0f, 3.0f},
+ 1.0f, 1.0f, 1.0f, RED);
+
+ // White tint when drawing will keep the original color
+ DrawModel(myModel, (Vector3) {0.0f, 0.0f, 3.0f},
+ 1.0f, //Scale
+ WHITE);
+
+ }
+ // End 3D mode so we can draw normally again
+ EndMode3D();
+
+ // Start drawing onto render texture
+ BeginTextureMode(renderTexture);
+ {
+
+ // It behaves the same as if we just called `BeginDrawing()`
+
+ ClearBackground(RAYWHITE);
+
+ BeginMode3D(camera);
+ {
+
+ DrawGrid(10, // Slices
+ 1.0f // Spacing
+ );
+
+ }
+ EndMode3D();
+
+ }
+ EndTextureMode();
+
+ // render textures have a Texture2D field
+ DrawTexture(renderTexture.texture, 40, 378, BLUE);
+
+ }
+ EndDrawing();
+ }
+
+ // Unloading loaded objects
+ UnloadFont(someFont);
+ UnloadModel(myModel);
+
+ // Close window and OpenGL context
+ CloseWindow();
+
+ return 0;
+}
+
+```
+
+## Further reading
+raylib has some [great examples](https://www.raylib.com/examples.html)
+If you don't like C check out the [raylib bindings](https://github.com/raysan5/raylib/blob/master/BINDINGS.md) \ No newline at end of file
diff --git a/reason.html.markdown b/reason.html.markdown
new file mode 100644
index 00000000..b8a2215d
--- /dev/null
+++ b/reason.html.markdown
@@ -0,0 +1,544 @@
+---
+language: reason
+filename: reason.re
+contributors:
+ - ["Seth Corker", "https://sethcorker.com"]
+---
+
+Reason is a syntax over OCaml that is easier to get started for programmers who are familiar with C-style syntax like JavaScript. BuckleScript is part of the toolchain which compiles Reason to JavaScript so you can write statically typed code for anywhere that JavaScript runs.
+
+```javascript
+/* Comments start with slash-star, and end with star-slash */
+
+/*----------------------------------------------
+ * Variable and function declaration
+ *----------------------------------------------
+ * Variables and functions use the let keyword and end with a semi-colon
+ * `let` bindings are immutable
+ */
+
+let x = 5;
+/* - Notice we didn't add a type, Reason will infer x is an int */
+
+/* A function like this, take two arguments and add them together */
+let add = (a, b) => a + b;
+/* - This doesn't need a type annotation either! */
+
+/*----------------------------------------------
+ * Type annotation
+ *----------------------------------------------
+ * Types don't need to be explicitly annotated in most cases but when you need
+ * to, you can add the type after the name
+ */
+
+/* A type can be explicitly written like so */
+let x: int = 5;
+
+/* The add function from before could be explicitly annotated too */
+let add2 = (a: int, b: int): int => a + b;
+
+/* A type can be aliased using the type keyword */
+type companyId = int;
+let myId: companyId = 101;
+
+/* Mutation is not encouraged in Reason but it's there if you need it
+ If you need to mutate a let binding, the value must be wrapped in a `ref()`*/
+let myMutableNumber = ref(120);
+
+/* To access the value (and not the ref container), use `^` */
+let copyOfMyMutableNumber = myMutableNumber^;
+
+/* To assign a new value, use the `:=` operator */
+myMutableNumber := 240;
+
+/*----------------------------------------------
+ * Basic types and operators
+ *----------------------------------------------
+ */
+
+/* > String */
+
+/* Use double quotes for strings */
+let greeting = "Hello world!";
+
+/* A string can span multiple lines */
+let aLongerGreeting = "Look at me,
+I'm a multi-line string
+";
+
+/* A quoted string can be used for string interpolation and special chars
+ Use the `js` annotation for unicode */
+let world = {js|🌍|js};
+
+/* The `j` annotation is used for string interpolation */
+let helloWorld = {j|hello, $world|j};
+
+/* Concatenate strings with ++ */
+let name = "John " ++ "Wayne";
+let emailSubject = "Hi " ++ name ++ ", you're a valued customer";
+
+/* > Char */
+
+/* Use a single character for the char type */
+let lastLetter = 'z';
+/* - Char doesn't support Unicode or UTF-8 */
+
+/* > Boolean */
+
+/* A boolean can be either true or false */
+let isLearning = true;
+
+true && false; /* - : bool = false; Logical and */
+true || true; /* - : bool = true; Logical or */
+!true; /* - : bool = false; Logical not */
+
+/* Greater than `>`, or greater than or equal to `>=` */
+'a' > 'b'; /* - bool : false */
+
+/* Less than `<`, or less than or equal to `<=` */
+1 < 5; /* - : bool = true */
+
+/* Structural equal */
+"hello" == "hello"; /* - : bool = true */
+
+/* Referential equal */
+"hello" === "hello"; /* - : bool = false */
+/* - This is false because they are two different "hello" string literals */
+
+/* Structural unequal */
+lastLetter != 'a'; /* -: bool = true */
+
+/* Referential unequal */
+lastLetter !== lastLetter; /* - : bool = false */
+
+/* > Integer */
+/* Perform math operations on integers */
+
+1 + 1; /* - : int = 2 */
+25 - 11; /* - : int = 11 */
+5 * 2 * 3; /* - : int = 30 */
+8 / 2; /* - : int = 4 */
+
+/* > Float */
+/* Operators on floats have a dot after them */
+
+1.1 +. 1.5; /* - : float = 2.6 */
+18.0 -. 24.5; /* - : float = -6.5 */
+2.5 *. 2.0; /* - : float = 5. */
+16.0 /. 4.0; /* - : float = 4. */
+
+/* > Tuple
+ * Tuples have the following attributes
+ - immutable
+ - ordered
+ - fix-sized at creation time
+ - heterogeneous (can contain different types of values)
+ A tuple is 2 or more values */
+
+let teamMember = ("John", 25);
+
+/* Type annotation matches the values */
+let position2d: (float, float) = (9.0, 12.0);
+
+/* Pattern matching is a great tool to retrieve just the values you care about
+ If we only want the y value, let's use `_` to ignore the value */
+let (_, y) = position2d;
+y +. 1.0; /* - : float = 13. */
+
+/* > Record */
+
+/* A record has to have an explicit type */
+type trainJourney = {
+ destination: string,
+ capacity: int,
+ averageSpeed: float,
+};
+
+/* Once the type is declared, Reason can infer it whenever it comes up */
+let firstTrip = {destination: "London", capacity: 45, averageSpeed: 120.0};
+
+/* Access a property using dot notation */
+let maxPassengers = firstTrip.capacity;
+
+/* If you define the record type in a different file, you have to reference the
+ filename, if trainJourney was in a file called Trips.re */
+let secondTrip: Trips.trainJourney = {
+ destination: "Paris",
+ capacity: 50,
+ averageSpeed: 150.0,
+};
+
+/* Records are immutable by default */
+/* But the contents of a record can be copied using the spread operator */
+let newTrip = {...secondTrip, averageSpeed: 120.0};
+
+/* A record property can be mutated explicitly with the `mutable` keyword */
+type breakfastCereal = {
+ name: string,
+ mutable amount: int,
+};
+
+let tastyMuesli = {name: "Tasty Muesli TM", amount: 500};
+
+tastyMuesli.amount = 200;
+/* - tastyMuesli now has an amount of 200 */
+
+/* Punning is used to avoid redundant typing */
+let name = "Just As Good Muesli";
+let justAsGoodMuesli = {name, amount: 500};
+/* - justAsGoodMuesli.name is now "Just As Good Muesli", it's equivalent
+ to { name: name, amount: 500 } */
+
+/* > Variant
+ Mutually exclusive states can be expressed with variants */
+
+type authType =
+ | GitHub
+ | Facebook
+ | Google
+ | Password;
+/* - The constructors must be capitalized like so */
+/* - Like records, variants should be named if declared in a different file */
+
+let userPreferredAuth = GitHub;
+
+/* Variants work great with a switch statement */
+let loginMessage =
+ switch (userPreferredAuth) {
+ | GitHub => "Login with GitHub credentials."
+ | Facebook => "Login with your Facebook account."
+ | Google => "Login with your Google account"
+ | Password => "Login with email and password."
+ };
+
+/* > Option
+ An option can be None or Some('a) where 'a is the type */
+
+let userId = Some(23);
+
+/* A switch handles the two cases */
+let alertMessage =
+ switch (userId) {
+ | Some(id) => "Welcome, your ID is" ++ string_of_int(id)
+ | None => "You don't have an account!"
+ };
+/* - Missing a case, `None` or `Some`, would cause an error */
+
+/* > List
+ * Lists have the following attributes
+ - immutable
+ - ordered
+ - fast at prepending items
+ - fast at splitting
+
+ * Lists in Reason are linked lists
+ */
+
+/* A list is declared with square brackets */
+let userIds = [1, 4, 8];
+
+/* The type can be explicitly set with list('a) where 'a is the type */
+type idList = list(int);
+type attendanceList = list(string);
+
+/* Lists are immutable */
+/* But the contents of a list can be copied using the spread operator */
+let newUserIds = [101, 102, ...userIds];
+
+/* > Array
+ * Arrays have the following attributes
+ - mutable
+ - fast at random access & updates */
+
+/* An array is declared with `[|` and ends with `|]` */
+let languages = [|"Reason", "JavaScript", "OCaml"|];
+
+/*----------------------------------------------
+ * Function
+ *----------------------------------------------
+ */
+
+/* Reason functions use the arrow syntax, the expression is returned */
+let signUpToNewsletter = email => "Thanks for signing up " ++ email;
+
+/* Call a function like this */
+signUpToNewsletter("hello@reason.org");
+
+/* For longer functions, use a block */
+let getEmailPrefs = email => {
+ let message = "Update settings for " ++ email;
+ let prefs = ["Weekly News", "Daily Notifications"];
+
+ (message, prefs);
+};
+/* - the final tuple is implicitly returned */
+
+/* > Labeled Arguments */
+
+/* Arguments can be labeled with the ~ symbol */
+let moveTo = (~x, ~y) => {/* Move to x,y */};
+
+moveTo(~x=7.0, ~y=3.5);
+
+/* Labeled arguments can also have a name used within the function */
+let getMessage = (~message as msg) => "==" ++ msg ++ "==";
+
+getMessage(~message="You have a message!");
+/* - The caller specifies ~message but internally the function can make use */
+
+/* The following function also has explicit types declared */
+let showDialog = (~message: string): unit => {
+ () /* Show the dialog */;
+};
+/* - The return type is `unit`, this is a special type that is equivalent to
+ specifying that this function doesn't return a value
+ the `unit` type can also be represented as `()` */
+
+/* > Currying
+ Functions can be curried and are partially called, allowing for easy reuse */
+
+let div = (denom, numr) => numr / denom;
+let divBySix = div(6);
+let divByTwo = div(2);
+
+div(3, 24); /* - : int = 8 */
+divBySix(128); /* - : int = 21 */
+divByTwo(10); /* - : int = 5 */
+
+/* > Optional Labeled Arguments */
+
+/* Use `=?` syntax for optional labeled arguments */
+let greetPerson = (~name, ~greeting=?, ()) => {
+ switch (greeting) {
+ | Some(greet) => greet ++ " " ++ name
+ | None => "Hi " ++ name
+ };
+};
+/* - The third argument, `unit` or `()` is required because if we omitted it,
+ the function would be curried so greetPerson(~name="Kate") would create
+ a partial function, to fix this we add `unit` when we declare and call it */
+
+/* Call greetPerson without the optional labeled argument */
+greetPerson(~name="Kate", ());
+
+/* Call greetPerson with all arguments */
+greetPerson(~name="Marco", ~greeting="How are you today,");
+
+/* > Pipe */
+/* Functions can be called with the pipeline operator */
+
+/* Use `->` to pass in the first argument (pipe-first) */
+3->div(24); /* - : int = 8 */
+/* - This is equivalent to div(3, 24); */
+
+36->divBySix; /* - : int = 6 */
+/* - This is equivalent to divBySix(36); */
+
+/* Use `|>` to pass in the last argument (pipe-last) */
+24 |> div(3); /* - : int = 8 */
+/* - This is equivalent to div(3, 24); */
+
+36 |> divBySix; /* - : int = 6 */
+/* - This is equivalent to divBySix(36); */
+
+/* Pipes make it easier to chain code together */
+let addOne = a => a + 1;
+let divByTwo = a => a / 2;
+let multByThree = a => a * 3;
+
+let pipedValue = 3->addOne->divByTwo->multByThree; /* - : int = 6 */
+
+/*----------------------------------------------
+ * Control Flow & Pattern Matching
+ *----------------------------------------------
+ */
+
+/* > If-else */
+/* In Reason, `If` is an expression when evaluate will return the result */
+
+/* greeting will be "Good morning!" */
+let greeting = if (true) {"Good morning!"} else {"Hello!"};
+
+/* Without an else branch the expression will return `unit` or `()` */
+if (false) {
+ showDialog(~message="Are you sure you want to leave?");
+};
+/* - Because the result will be of type `unit`, both return types should be of
+ the same type if you want to assign the result. */
+
+/* > Destructuring */
+/* Extract properties from data structures easily */
+
+let aTuple = ("Teacher", 101);
+
+/* We can extract the values of a tuple */
+let (name, classNum) = aTuple;
+
+/* The properties of a record can be extracted too */
+type person = {
+ firstName: string,
+ age: int,
+};
+let bjorn = {firstName: "Bjorn", age: 28};
+
+/* The variable names have to match with the record property names */
+let {firstName, age} = bjorn;
+
+/* But we can rename them like so */
+let {firstName: bName, age: bAge} = bjorn;
+
+let {firstName: cName, age: _} = bjorn;
+
+/* > Switch
+ Pattern matching with switches is an important tool in Reason
+ It can be used in combination with destructuring for an expressive and
+ concise tool */
+
+/* Lets take a simple list */
+let firstNames = ["James", "Jean", "Geoff"];
+
+/* We can pattern match on the names for each case we want to handle */
+switch (firstNames) {
+| [] => "No names"
+| [first] => "Only " ++ first
+| [first, second] => "A couple of names " ++ first ++ "," ++ second
+| [first, second, third] =>
+ "Three names, " ++ first ++ ", " ++ second ++ ", " ++ third
+| _ => "Lots of names"
+};
+/* - The `_` is a catch all at the end, it signifies that we don't care what
+ the value is so it will match every other case */
+
+/* > When clause */
+
+let isJohn = a => a == "John";
+let maybeName = Some("John");
+
+/* When can add more complex logic to a simple switch */
+let aGreeting =
+ switch (maybeName) {
+ | Some(name) when isJohn(name) => "Hi John! How's it going?"
+ | Some(name) => "Hi " ++ name ++ ", welcome."
+ | None => "No one to greet."
+ };
+
+/* > Exception */
+
+/* Define a custom exception */
+exception Under_Age;
+
+/* Raise an exception within a function */
+let driveToTown = (driver: person) =>
+ if (driver.age >= 15) {
+ "We're in town";
+ } else {
+ raise(Under_Age);
+ };
+
+let evan = {firstName: "Evan", age: 14};
+
+/* Pattern match on the exception Under_Age */
+switch (driveToTown(evan)) {
+| status => print_endline(status)
+| exception Under_Age =>
+ print_endline(evan.firstName ++ " is too young to drive!")
+};
+
+/* Alternatively, a try block can be used */
+/* - With Reason exceptions can be avoided with optionals and are seldom used */
+let messageToEvan =
+ try (driveToTown(evan)) {
+ | Under_Age => evan.firstName ++ " is too young to drive!"
+ };
+
+/*----------------------------------------------
+ * Object
+ *----------------------------------------------
+ * Objects are similar to Record types but aren't as rigid
+ * An object resembles a class
+ */
+
+/* An object may be typed like a record but contains a dot */
+type surfaceComputer = {
+ .
+ color: string,
+ capacity: int,
+};
+/* - A single dot signifies a closed object, an object that uses this type
+ must have the exact shape */
+
+let surfaceBook: surfaceComputer = {pub color = "blue"; pub capacity = 512};
+
+/* But an object doesn't require a type */
+let house = {
+ /* A private property */
+ val temp = ref(18.0);
+ /* Public properties */
+ pub temperature = temp;
+ /* A private method only accessible from within house */
+ pri setThermostat = v => temp := v;
+ /* A public method that calls the private setThermostat method */
+ pub arriveHome = () => this#setThermostat(22.0)
+};
+
+house#temperature; /* - : float = 18. */
+house#arriveHome();
+house#temperature; /* - : float = 22. */
+
+/*----------------------------------------------
+ * Module
+ *----------------------------------------------
+ * Modules are used to organize your code and provide namespacing.
+ * Each file is a module by default
+ */
+
+/* Create a module */
+module Staff = {
+ type role =
+ | Delivery
+ | Sales
+ | Other;
+ type member = {
+ name: string,
+ role,
+ };
+
+ let getRoleDirectionMessage = staff =>
+ switch (staff.role) {
+ | Delivery => "Deliver it like you mean it!"
+ | Sales => "Sell it like only you can!"
+ | Other => "You're an important part of the team!"
+ };
+};
+
+/* A module can be accessed with dot notation */
+let newEmployee: Staff.member = {name: "Laura", role: Staff.Delivery};
+
+/* Using the module name can be tiresome so the module's contents can be opened
+ into the current scope with `open` */
+open Staff;
+
+let otherNewEmployee: member = {name: "Fred", role: Other};
+
+/* A module can be extended using the `include` keyword, include copies
+ the contents of the module into the scope of the new module */
+module SpecializedStaff = {
+ include Staff;
+
+ /* `member` is included so there's no need to reference it explicitly */
+ let ceo: member = {name: "Reggie", role: Other};
+
+ let getMeetingTime = staff =>
+ switch (staff) {
+ | Other => 11_15 /* - : int = 1115; Underscores are for formatting only */
+ | _ => 9_30
+ };
+};
+```
+
+## Further Reading
+
+- [Official Reason Docs](https://reasonml.github.io/docs/en/what-and-why)
+- [Official BuckleScript Docs](https://bucklescript.github.io/docs/en/what-why)
+- [Try Reason](https://reasonml.github.io/en/try)
+- [Get Started with Reason by Nik Graf](https://egghead.io/courses/get-started-with-reason)
diff --git a/red.html.markdown b/red.html.markdown
index 6d10fe8f..34c4bcd9 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
@@ -50,7 +51,7 @@ comment {
; no need to restrict this to a 'main' function.
; Valid variable names start with a letter and can contain numbers,
-; variables containing only capital A thru F and numbers and ending with 'h'
+; variables containing only capital A through F and numbers and ending with 'h'
; are forbidden, because that is how hexadecimal numbers are expressed in Red
; and Red/System.
@@ -102,7 +103,8 @@ type? my-integer
integer!
; A variable can be initialized using another variable that gets initialized
-; at the same time.
+; at the same time. Initialize here refers to both declaring a variable and
+; assigning a value to it.
i2: 1 + i1: 1
; Arithmetic is straightforward
@@ -112,12 +114,12 @@ i2 * i1 ; result 2
i1 / i2 ; result 0 (0.5, but truncated towards 0)
; Comparison operators are probably familiar, and unlike in other languages
-; you only need a single '=' sign for comparison.
+; you only need a single '=' sign for comparison. Inequality is '<>' like in Pascal.
; There is a boolean like type in Red. It has values true and false, but also
; the values on/off or yes/no can be used
3 = 2 ; result false
-3 != 2 ; result true
+3 <> 2 ; result true
3 > 2 ; result true
3 < 2 ; result false
2 <= 2 ; result true
@@ -127,22 +129,22 @@ i1 / i2 ; result 0 (0.5, but truncated towards 0)
; Control Structures
;
; if
-; Evaluate a block of code if a given condition is true. IF does not return
-; any value, so cannot be used in an expression.
+; Evaluate a block of code if a given condition is true. IF returns
+; the resulting value of the block or 'none' if the condition was false.
if a < 0 [print "a is negative"]
; either
; Evaluate a block of code if a given condition is true, else evaluate an
; alternative block of code. If the last expressions in both blocks have the
; same type, EITHER can be used inside an expression.
-either a < 0 [
+either a > 0 [
+ msg: "positive"
+][
either a = 0 [
msg: "zero"
][
msg: "negative"
]
-][
- msg: "positive"
]
print ["a is " msg lf]
@@ -150,20 +152,20 @@ print ["a is " msg lf]
; There is an alternative way to write this
; (Which is allowed because all code paths return a value of the same type):
-msg: either a < 0 [
+msg: either a > 0 [
+ "positive"
+][
either a = 0 [
"zero"
][
"negative"
]
- ][
- "positive"
]
print ["a is " msg lf]
; until
; Loop over a block of code until the condition at end of block, is met.
-; UNTIL does not return any value, so it cannot be used in an expression.
+; UNTIL always returns the 'true' value from the final evaluation of the last expression.
c: 5
until [
prin "o"
@@ -214,7 +216,7 @@ The Red/System language specification can be found [here](http://static.red-lang
To learn more about Rebol and Red join the [chat on Gitter](https://gitter.im/red/red). And if that is not working for you drop a mail to us on the [Red mailing list](mailto: red-langNO_SPAM@googlegroups.com) (remove NO_SPAM).
-Browse or ask questions on [Stack Overflow](stackoverflow.com/questions/tagged/red).
+Browse or ask questions on [Stack Overflow](https://stackoverflow.com/questions/tagged/red).
Maybe you want to try Red right away? That is possible on the [try Rebol and Red site](http://tryrebol.esperconsultancy.nl).
diff --git a/ro-ro/elixir-ro.html.markdown b/ro-ro/elixir-ro.html.markdown
new file mode 100644
index 00000000..10fec3c5
--- /dev/null
+++ b/ro-ro/elixir-ro.html.markdown
@@ -0,0 +1,459 @@
+---
+language: elixir
+contributors:
+ - ["Joao Marques", "http://github.com/mrshankly"]
+ - ["Dzianis Dashkevich", "https://github.com/dskecse"]
+ - ["Ryan Plant", "https://github.com/ryanplant-au"]
+ - ["Ev Bogdanov", "https://github.com/evbogdanov"]
+translators:
+ - ["Vitalie Lazu", "https://github.com/vitaliel"]
+lang: ro-ro
+filename: learnelixir-ro.ex
+---
+
+Elixir este un limbaj funcțional modern construit pe baza mașinii virtuale Erlang.
+E total compatibil cu Erlang, dar are o sintaxă mai prietenoasă și propune mai multe
+posibilități.
+
+```elixir
+
+# Comentariile de o linie încep cu simbolul diez.
+
+# Pentru comentarii pe mai multe linii nu există sintaxă separată,
+# de aceea folosiți mai multe linii cu comentarii.
+
+# Pentru a folosi shell-ul elixir utilizați comanda `iex`.
+# Compilați modulele cu comanda `elixirc`.
+
+# Ambele comenzi vor lucra în terminal, dacă ați instalat Elixir corect.
+
+## ---------------------------
+## -- Tipuri de bază
+## ---------------------------
+
+# Numere
+3 # număr întreg
+0x1F # număr întreg
+3.0 # număr cu virgulă mobilă
+
+# Atomii, sunt constante nenumerice. Ei încep cu `:`.
+:salut # atom
+
+# Tuplele sunt păstrate în memorie consecutiv.
+{1,2,3} # tuple
+
+# Putem accesa elementul tuplelui folosind funcția `elem`:
+elem({1, 2, 3}, 0) #=> 1
+
+# Listele sunt implementate ca liste înlănțuite.
+[1,2,3] # listă
+
+# Fiecare listă ne vidă are cap (primul element al listei)
+# și coadă (restul elementelor).
+# Putem accesa capul și coada listei cum urmează:
+[cap | coadă] = [1,2,3]
+cap #=> 1
+coadă #=> [2, 3]
+
+# În Elixir, ca și în Erlang, simbolul `=` denotă potrivirea șabloanelor și
+# nu atribuire.
+#
+# Aceasta înseamnă că expresia din stînga (șablonul) se potrivește cu
+# expresia din dreaptă.
+#
+# În modul acesta exemplul de mai sus lucrează accesînd capul și coada unei liste.
+
+# Potrivirea șablonului va da eroare cînd expresiile din stînga și dreapta nu se
+# potrivesc, în exemplu acesta tuplele au lungime diferită.
+{a, b, c} = {1, 2} #=> ** (MatchError)
+
+# Există și date binare
+<<1,2,3>>
+
+# Sunt două tipuri de șiruri de caractere
+"salut" # șir de caractere Elixir
+'salut' # listă de caractere Erlang
+
+# Șir de caractere pe mai multe linii
+"""
+Sunt un șir de caractere
+pe mai multe linii.
+"""
+#=> "Sunt un șir de caractere\npe mai multe linii..\n"
+
+# Șirurile de caractere sunt codificate în UTF-8:
+"Bună dimineața" #=> "Bună dimineața"
+
+# Șirurile de caractere sunt date binare, listele de caractere doar liste.
+<<?a, ?b, ?c>> #=> "abc"
+[?a, ?b, ?c] #=> 'abc'
+
+# `?a` în Elixir întoarce codul ASCII pentru litera `a`
+?a #=> 97
+
+# Pentru a concatena listele folosiți `++`, pentru date binare - `<>`
+[1,2,3] ++ [4,5] #=> [1,2,3,4,5]
+'Salut ' ++ 'lume' #=> 'Salut lume'
+
+<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
+"Salut " <> "lume" #=> "Salut lume"
+
+# Diapazoanele sunt reprezentate ca `început..sfîrșit` (inclusiv)
+1..10 #=> 1..10
+început..sfîrșit = 1..10 # Putem folosi potrivirea șabloanelor cu diapazoane de asemenea
+[început, sfîrșit] #=> [1, 10]
+
+# Dicţionarele stochează chei şi o valoare pentru fiecare cheie
+genuri = %{"Ion" => "bărbat", "Maria" => "femeie"}
+genuri["Ion"] #=> "bărbat"
+
+# Dicționare cu chei de tip atom au sintaxă specială
+genuri = %{ion: "bărbat", maria: "femeie"}
+genuri.ion #=> "bărbat"
+
+## ---------------------------
+## -- Operatori
+## ---------------------------
+
+# Operații matematice
+1 + 1 #=> 2
+10 - 5 #=> 5
+5 * 2 #=> 10
+10 / 2 #=> 5.0
+
+# În Elixir operatorul `/` întotdeauna întoarce un număr cu virgulă mobilă.
+
+# Folosiți `div` pentru împărțirea numerelor întregi
+div(10, 2) #=> 5
+
+# Pentru a obține restul de la împărțire utilizați `rem`
+rem(10, 3) #=> 1
+
+# Există și operatori booleni: `or`, `and` and `not`.
+# Acești operatori așteaptă ca primul argument o expresie booleană.
+true and true #=> true
+false or true #=> true
+1 and true #=> ** (BadBooleanError)
+
+# Elixir de asemenea oferă `||`, `&&` și `!` care acceptă argumente de orice tip.
+# Toate valorile în afară de `false` și `nil` se vor evalua ca `true`.
+1 || true #=> 1
+false && 1 #=> false
+nil && 20 #=> nil
+!true #=> false
+
+# Operatori de comparație: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` și `>`
+1 == 1 #=> true
+1 != 1 #=> false
+1 < 2 #=> true
+
+# `===` și `!==` au strictețe mai mare cînd comparăm numere întregi și reale:
+1 == 1.0 #=> true
+1 === 1.0 #=> false
+
+# Putem compara de asemenea și date de diferite tipuri:
+1 < :salut #=> true
+
+# La compararea diferitor tipuri folosiți următoare prioritate:
+# număr < atom < referință < funcție < port < proces < tuple < listă < șir de caractere
+
+# Cităm pe Joe Armstrong în acest caz: "Ordinea actuală nu e importantă,
+dar că ordinea totală este bine definită este important."
+
+## ---------------------------
+## -- Ordinea execuției
+## ---------------------------
+
+# expresia `if`
+if false do
+ "Aceasta nu veți vedea niciodată"
+else
+ "Aceasta veți vedea"
+end
+
+# expresia opusă `unless`
+unless true do
+ "Aceasta nu veți vedea niciodată"
+else
+ "Aceasta veți vedea"
+end
+
+# Țineți minte potrivirea șabloanelor? Multe structuri în Elixir se bazează pe ea.
+
+# `case` ne permite să comparăm o valoare cu multe șabloane:
+case {:unu, :doi} do
+ {:patru, :cinci} ->
+ "Aceasta nu se potrivește"
+ {:unu, x} ->
+ "Aceasta se potrivește și atribuie lui `x` `:doi` în acest bloc"
+ _ ->
+ "Aceasta se va potrivi cu orice valoare"
+end
+
+# Simbolul `_` se numește variabila anonimă.
+# Folosiți-l pentru valori ce nu vă interesează.
+# De exemplu, dacă doar capul listei ne intereseaza:
+[cap | _] = [1,2,3]
+cap #=> 1
+
+# Pentru o citire mai bună putem scri:
+[cap | _coadă] = [:a, :b, :c]
+cap #=> :a
+
+# `cond` ne permite să verificăm multe condiții de odată.
+# Folosiți `cond` în schimbul la multe expresii `if`.
+cond do
+ 1 + 1 == 3 ->
+ "Aceasta nu veți vedea niciodată"
+ 2 * 5 == 12 ->
+ "Pe mine la fel"
+ 1 + 2 == 3 ->
+ "Aceasta veți vedea"
+end
+
+# Este obușnuit de setat ultima condiție cu `true`, care se va potrivi întotdeauna.
+cond do
+ 1 + 1 == 3 ->
+ "Aceasta nu veți vedea niciodată"
+ 2 * 5 == 12 ->
+ "Pe mine la fel"
+ true ->
+ "Aceasta veți vedea (este else în esență)"
+end
+
+# Blocul `try/catch` se foloște pentru prelucrarea excepțiilor.
+# Elixir suportă blocul `after` care se execută în orice caz.
+try do
+ throw(:salut)
+catch
+ mesaj -> "Am primit #{mesaj}."
+after
+ IO.puts("Sunt în blocul after.")
+end
+#=> Sunt în blocul after.
+# "Am primit salut"
+
+## ---------------------------
+## -- Module și Funcții
+## ---------------------------
+
+# Funcții anonime (atenție la punct la apelarea funcției)
+square = fn(x) -> x * x end
+square.(5) #=> 25
+
+# Ele de asemenea aceptă multe clauze și expresii de gardă.
+# Expresiile de gardă vă permit să acordați potrivirea șabloanelor,
+# ele sunt indicate după cuvîntul cheie `when`:
+f = fn
+ x, y when x > 0 -> x + y
+ x, y -> x * y
+end
+
+f.(1, 3) #=> 4
+f.(-1, 3) #=> -3
+
+# Elixir de asemenea oferă multe funcții incorporate.
+# Ele sunt accesibile în scopul curent.
+is_number(10) #=> true
+is_list("salut") #=> false
+elem({1,2,3}, 0) #=> 1
+
+# Puteți grupa cîteva funcții într-un modul. În interiorul modulului folosiți `def`
+# pentru a defini funcțiile necesare.
+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
+
+# Pentru a compila modulul nostru simplu Math îl salvăm ca `math.ex` și utilizăm `elixirc`.
+# în terminal: elixirc math.ex
+
+# În interiorul modulului putem defini funcții cu `def` și funcții private cu `defp`.
+defmodule PrivateMath do
+ # O funcție definită cu `def` este accesibilă pentru apelare din alte module,
+ def sum(a, b) do
+ do_sum(a, b)
+ end
+
+ # O funcție privată poate fi apelată doar local.
+ defp do_sum(a, b) do
+ a + b
+ end
+end
+
+PrivateMath.sum(1, 2) #=> 3
+PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
+
+# Declarația funcției de asemenea suportă expresii de gardă și multe clauze:
+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)
+
+# Din cauza variabilelor imutabile, un rol important îl ocupă funcțiile recursive
+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
+
+# Modulele în Elixir suportă atribute, există atribute incorporate și
+# puteți adăuga altele.
+defmodule MyMod do
+ @moduledoc """
+ Este un atribut incorporat
+ """
+
+ @my_data 100 # Acesta e atributul nostru
+ IO.inspect(@my_data) #=> 100
+end
+
+# Operatorul |> permite transferarea rezultatului unei expresii din stînga
+# ca primul argument al unei funcții din dreapta.
+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]
+
+## ---------------------------
+## -- Structuri și Excepții
+## ---------------------------
+
+# Structurile sunt extensii a dicționarelor ce au valori implicite,
+# verificări în timpul compilării și polimorfism
+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"}
+
+# Acesarea cîmpului din structură
+joe_info.name #=> "Joe"
+
+# Actualizarea valorii cîmpului
+older_joe_info = %{ joe_info | age: 31 }
+#=> %Person{age: 31, height: 180, name: "Joe"}
+
+# Blocul `try` cu cuvîntul cheie `rescue` e folosit pentru a prinde excepții
+try do
+ raise "o eroare"
+rescue
+ RuntimeError -> "a fost prinsă o eroare runtime"
+ _error -> "aici vor fi prinse toate erorile"
+end
+#=> "a fost prinsă o eroare runtime"
+
+# Toate excepțiile au un mesaj
+try do
+ raise "o eroare"
+rescue
+ x in [RuntimeError] ->
+ x.message
+end
+#=> "o eroare"
+
+## ---------------------------
+## -- Concurența
+## ---------------------------
+
+# Concurența în Elixir se bazează pe modelul actor. Pentru a scrie programe
+# concurente avem nevoie de trei lucruri:
+# 1. Crearea proceselor
+# 2. Trimiterea mesajelor
+# 3. Primirea mesajelor
+
+# Un nou proces se crează folosind funcția `spawn`, care primește o funcție
+# ca argument.
+f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
+spawn(f) #=> #PID<0.40.0>
+
+# `spawn` întoarce identificatorul procesului pid, îl puteți folosi pentru
+# a trimite mesaje procesului. Mesajele se transmit folosind operatorul `send`.
+# Pentru primirea mesajelor se folosește mecanismul `receive`:
+
+# Blocul `receive do` este folosit pentru așteptarea mesajelor și prelucrarea lor
+# cînd au fost primite. Blocul `receive do` va procesa doar un singur mesaj primit.
+# Pentru a procesa mai multe mesaje, funcția cu blocul `receive do` trebuie
+# recursiv să se auto apeleze.
+
+defmodule Geometry do
+ def area_loop do
+ receive do
+ {:rectangle, w, h} ->
+ IO.puts("Aria = #{w * h}")
+ area_loop()
+ {:circle, r} ->
+ IO.puts("Aria = #{3.14 * r * r}")
+ area_loop()
+ end
+ end
+end
+
+# Compilați modulul și creați un proces
+pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
+# Un alt mod
+pid = spawn(Geometry, :area_loop, [])
+
+# Trimiteți un mesaj către `pid` care se va potrivi cu un șablon din blocul `receive`
+send pid, {:rectangle, 2, 3}
+#=> Aria = 6
+# {:rectangle,2,3}
+
+send pid, {:circle, 2}
+#=> Aria = 12.56000000000000049738
+# {:circle,2}
+
+# Interpretatorul este de asemenea un proces, puteți folosi `self`
+# pentru a primi identificatorul de proces:
+self() #=> #PID<0.27.0>
+
+## ---------------------------
+## -- Agenții
+## ---------------------------
+
+# Un agent este un proces care urmărește careva valori ce se schimbă.
+
+# Creați un agent cu `Agent.start_link`, transmițînd o funcție.
+# Stare inițială a agentului va fi rezultatul funcției.
+{ok, my_agent} = Agent.start_link(fn -> ["roșu", "verde"] end)
+
+# `Agent.get` primește numele agentului și o `fn` care primește starea curentă
+# Orice va întoarce `fn` este ceea ce veți primi înapoi:
+Agent.get(my_agent, fn colors -> colors end) #=> ["roșu", "verde"]
+
+# Actualizați starea agentului în acelaș mod:
+Agent.update(my_agent, fn colors -> ["albastru" | colors] end)
+```
+
+## Link-uri utile
+
+* [Primii pași](http://elixir-lang.org/getting-started/introduction.html) de pe [situl Elixir](http://elixir-lang.org)
+* [Documentația oficială Elixir](http://elixir-lang.org/docs/master/)
+* [Un mic conspect pe Elixir](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf)
+* [Cartea "Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) de Dave Thomas
+* [Cartea "Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) de Fred Hebert
+* [Cartea "Programming Erlang: Software for a Concurrent World"](https://pragprog.com/book/jaerlang2/programming-erlang) de Joe Armstrong
diff --git a/ro-ro/haskell-ro.html.markdown b/ro-ro/haskell-ro.html.markdown
index 082f138b..b0cc4099 100644
--- a/ro-ro/haskell-ro.html.markdown
+++ b/ro-ro/haskell-ro.html.markdown
@@ -66,7 +66,7 @@ not False -- True
----------------------------------------------------
--- Liste si tupli
+-- 2. Liste si tupli
----------------------------------------------------
-- Fiecare element dintr-o lista trebuie sa aiba acelasi tip.
diff --git a/ro-ro/python-ro.html.markdown b/ro-ro/pythonlegacy-ro.html.markdown
index c96e30dc..a368ff99 100644
--- a/ro-ro/python-ro.html.markdown
+++ b/ro-ro/pythonlegacy-ro.html.markdown
@@ -1,10 +1,10 @@
---
-language: python
+language: Python 2 (legacy)
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
translators:
- ["Ovidiu Ciule", "https://github.com/ociule"]
-filename: learnpython-ro.py
+filename: learnpythonlegacy-ro.py
lang: ro-ro
---
@@ -449,7 +449,7 @@ Om.exclama() #=> "*Aaaaaah*"
# Pentru a folosi un modul, trebuie importat
import math
-print math.sqrt(16) #=> 4
+print math.sqrt(16) #=> 4.0
# Putem importa doar anumite funcţii dintr-un modul
from math import ceil, floor
diff --git a/rst.html.markdown b/rst.html.markdown
index 161a0610..56d54501 100644
--- a/rst.html.markdown
+++ b/rst.html.markdown
@@ -1,13 +1,14 @@
---
-language: restructured text
+language: restructured text (RST)
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, Restructured Text, is a file format created by the Python community to write documentation. It is part of [Docutils](https://docutils.sourceforge.io/rst.html).
-RST files are simple text files with lightweight syntaxe (comparing to HTML).
+RST is a markdown language like HTML but is much more lightweight and easier to read.
## Installation
@@ -20,48 +21,55 @@ 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 each character, including spaces, needs an equals sign above and below.
-Title are underlined with equals signs too
-==========================================
+Titles also use equals signs but are only underneath
+====================================================
Subtitles with dashes
---------------------
-And sub-subtitles with tilde
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+You can put text in *italic* or in **bold**, you can "mark" text as code with double backquote ``print()``.
+
+Special characters can be escaped using a backslash, e.g. \\ or \*.
-You can put text in *italic* or in **bold**, you can "mark" text as code with double backquote ``: ``print()``.
+Lists are similar to Markdown, but a little more involved.
-Lists are as simple as markdown:
+Remember to line up list symbols (like - or \*) with the left edge of the previous text block, and remember to use blank lines to separate new lists from parent lists:
- First item
- Second item
- - Sub item
+
+ - Sub item
+
+- Third item
or
* First item
* Second item
- * Sub item
+
+ * Sub item
+
+* Third item
Tables are really easy to write:
@@ -72,22 +80,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 tables 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 of not inserting unnecessary URLs in the visible 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/
+.. _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 +103,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/.directory b/ru-ru/.directory
deleted file mode 100644
index 4d20336b..00000000
--- a/ru-ru/.directory
+++ /dev/null
@@ -1,4 +0,0 @@
-[Dolphin]
-SortRole=size
-Timestamp=2015,10,31,18,6,13
-Version=3
diff --git a/ru-ru/asymptotic-notation-ru.html.markdown b/ru-ru/asymptotic-notation-ru.html.markdown
new file mode 100644
index 00000000..7fd02c47
--- /dev/null
+++ b/ru-ru/asymptotic-notation-ru.html.markdown
@@ -0,0 +1,225 @@
+---
+category: Algorithms & Data Structures
+name: Asymptotic Notation
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+ - ["Divay Prakash", "http://github.com/divayprakash"]
+translators:
+ - ["pru-mike", "http://github.com/pru-mike"]
+lang: ru-ru
+---
+
+# О-символика
+
+## Что это такое?
+
+О-символика, или асимптотическая запись, — это система символов, позволяющая
+оценить время выполнения алгоритма, устанавливая зависимость времени выполнения
+от увеличения объёма входных данных. Она также известна как оценка
+сложности алгоритмов. Станет ли алгоритм невероятно медленным, когда
+объём входных данных увеличится? Будет ли алгоритм выполняться достаточно быстро,
+если объём входных данных возрастёт? О-символика позволяет ответить на эти
+вопросы.
+
+## Можно ли по-другому найти ответы на эти вопросы?
+
+Один способ — это подсчитать число элементарных операций в зависимости от
+различных объёмов входных данных. Хотя это и приемлемое решение, тот объём
+работы, которого оно потребует, даже для простых алгоритмов делает его
+использование неоправданным.
+
+Другой способ — это измерить, какое время алгоритм потребует для завершения на
+различных объёмах входных данных. В то же время, точность и относительность
+этого метода (полученное время будет относиться только к той машине, на которой
+оно вычислено) зависит от среды выполнения: компьютерного аппаратного
+обеспечения, мощности процессора и т.д.
+
+## Виды О-символики
+
+В первом разделе этого документа мы определили, что О-символика
+позволяет оценивать алгоритмы в зависимости от изменения размера входных
+данных. Представим, что алгоритм — это функция f, n — размер входных данных и
+f(n) — время выполнения. Тогда для данного алгоритма f с размером входных
+данных n получим какое-то результирующее время выполнения f(n).
+Из этого можно построить график, где ось y — время выполнения, ось x — размер входных
+данных, а точки на графике — это время выполнения для заданного размера входных
+данных.
+
+С помощью О-символики можно оценить функцию или алгоритм
+несколькими различными способами. Например, можно оценить алгоритм исходя
+из нижней оценки, верхней оценки, тождественной оценки. Чаще всего встречается
+анализ на основе верхней оценки. Как правило не используется нижняя оценка,
+потому что она не подходит под планируемые условия. Отличный пример — алгоритмы
+сортировки, особенно добавление элементов в древовидную структуру. Нижняя оценка
+большинства таких алгоритмов может быть дана как одна операция. В то время как в
+большинстве случаев добавляемые элементы должны быть отсортированы
+соответствующим образом при помощи дерева, что может потребовать обхода целой
+ветви. Это и есть худший случай, для которого планируется верхняя оценка.
+
+### Виды функций, пределы и упрощения
+
+```
+Логарифмическая функция — log n
+Линейная функция — an + b
+Квадратичная функция — an^2 + bn +c
+Степенная функция — an^z + . . . + an^2 + a*n^1 + a*n^0, где z — константа
+Показательная функция — a^n, где a — константа
+```
+
+Приведены несколько базовых функций, используемых при определении сложности в
+различных оценках. Список начинается с самой медленно возрастающей функции
+(логарифм, наиболее быстрое время выполнения) и следует до самой быстро
+возрастающей функции (экспонента, самое медленное время выполнения). Отметим,
+что в то время, как «n», или размер входных данных, возрастает в каждой из этих функций,
+результат намного быстрее возрастает в квадратичной, степенной
+и показательной по сравнению с логарифмической и линейной.
+
+Крайне важно понимать, что при использовании описанной далее нотации необходимо
+использовать упрощённые выражения.
+Это означает, что необходимо отбрасывать константы и слагаемые младших порядков,
+потому что если размер входных данных (n в функции f(n) нашего примера)
+увеличивается до бесконечности (в пределе), тогда слагаемые младших порядков
+и константы становятся пренебрежительно малыми. Таким образом, если есть
+константа, например, размера 2^9001 или любого другого невообразимого размера,
+надо понимать, что её упрощение внесёт значительные искажения в точность
+оценки.
+
+Т.к. нам нужны упрощённые выражения, немного скорректируем нашу таблицу...
+
+```
+Логарифм — log n
+Линейная функция — n
+Квадратичная функция — n^2
+Степенная функция — n^z, где z — константа
+Показательная функция — a^n, где a — константа
+```
+
+### О Большое
+О Большое, записывается как **О**, — это асимптотическая запись для оценки худшего
+случая, или для ограничения заданной функции сверху. Это позволяет сделать
+_**асимптотическую оценку верхней границы**_ скорости роста времени выполнения
+алгоритма. Пусть `f(n)` — время выполнения алгоритма, а `g(n)` — заданная временная
+сложность, которая проверяется для алгоритма. Тогда `f(n)` — это O(g(n)), если
+существуют действительные константы c (c > 0) и n<sub>0</sub>, такие,
+что `f(n)` <= `c g(n)` выполняется для всех n, начиная с некоторого n<sub>0</sub> (n > n<sub>0</sub>).
+
+*Пример 1*
+
+```
+f(n) = 3log n + 100
+g(n) = log n
+```
+
+Является ли `f(n)` O(g(n))?
+Является ли `3 log n + 100` O(log n)?
+Посмотрим на определение О Большого:
+
+```
+3log n + 100 <= c * log n
+```
+
+Существуют ли константы c и n<sub>0</sub>, такие, что выражение верно для всех n > n<sub>0</sub>?
+
+```
+3log n + 100 <= 150 * log n, n > 2 (не определенно для n = 1)
+```
+
+Да! По определению О Большого `f(n)` является O(g(n)).
+
+*Пример 2*
+
+```
+f(n) = 3 * n^2
+g(n) = n
+```
+
+Является ли `f(n)` O(g(n))?
+Является ли `3 * n^2` O(n)?
+Посмотрим на определение О Большого:
+
+```
+3 * n^2 <= c * n
+```
+
+Существуют ли константы c и n<sub>0</sub>, такие, что выражение верно для всех n > n<sub>0</sub>?
+Нет, не существуют. `f(n)` НЕ ЯВЛЯЕТСЯ O(g(n)).
+
+### Омега Большое
+Омега Большое, записывается как **Ω**, — это асимптотическая запись для оценки
+лучшего случая, или для ограничения заданной функции снизу. Это позволяет сделать
+_**асимптотическую оценку нижней границы**_ скорости роста времени выполнения
+алгоритма.
+
+`f(n)` является Ω(g(n)), если существуют действительные константы
+c (c > 0) и n<sub>0</sub> (n<sub>0</sub> > 0), такие, что `f(n)` >= `c g(n)` для всех n > n<sub>0</sub>.
+
+### Примечание
+
+Асимптотические оценки, сделаные при помощи О Большого и Омега Большого, могут
+как являться, так и не являться точными. Для того, чтобы обозначить, что границы не
+являются асимптотически точными, используются записи О Малое и Омега Малое.
+
+### О Малое
+O Малое, записывается как **о**, — это асимптотическая запись для оценки верхней
+границы времени выполнения алгоритма при условии, что граница не является
+асимптотически точной.
+
+`f(n)` является o(g(n)), если можно подобрать такие действительные константы,
+что для всех c (c > 0) найдётся n<sub>0</sub> (n<sub>0</sub> > 0), так
+что `f(n)` < `c g(n)` выполняется для всех n (n > n<sub>0</sub>).
+
+Определения О-символики для О Большого и О Малого похожи. Главное отличие в том,
+что если f(n) = O(g(n)), тогда условие f(n) <= c g(n) выполняется, если _**существует**_
+константа c > 0, но если f(n) = o(g(n)), тогда условие f(n) < c g(n) выполняется
+для _**всех**_ констант c > 0.
+
+### Омега Малое
+Омега Малое, записывается как **ω**, — это асимптотическая запись для оценки
+верхней границы времени выполнения алгоритма при условии, что граница не является
+асимптотически точной.
+
+`f(n)` является ω(g(n)), если можно подобрать такие действительные константы,
+что для всех c (c > 0) найдётся n<sub>0</sub> (n<sub>0</sub> > 0), так
+что `f(n)` > `c g(n)` выполняется для всех n (n > n<sub>0</sub>).
+
+Определения Ω-символики и ω-символики похожи. Главное отличие в том, что
+если f(n) = Ω(g(n)), тогда условие f(n) >= c g(n) выполняется, если _**существует**_
+константа c > 0, но если f(n) = ω(g(n)), тогда условие f(n) > c g(n)
+выполняется для _**всех**_ констант c > 0.
+
+### Тета
+Тета, записывается как **Θ**, — это асимптотическая запись для оценки
+_***асимптотически точной границы***_ времени выполнения алгоритма.
+
+`f(n)` является Θ(g(n)), если для некоторых действительных
+констант c1, c2 и n<sub>0</sub> (c1 > 0, c2 > 0, n<sub>0</sub> > 0)
+`c1 g(n)` < `f(n)` < `c2 g(n)` для всех n (n > n<sub>0</sub>).
+
+∴ `f(n)` является Θ(g(n)) означает, что `f(n)` является O(g(n))
+и `f(n)` является Ω(g(n)).
+
+О Большое — основной инструмент для анализа сложности алгоритмов.
+Также см. примеры по ссылкам.
+
+### Заключение
+Такую тему сложно изложить кратко, поэтому обязательно стоит пройти по ссылкам и
+посмотреть дополнительную литературу. В ней даётся более глубокое описание с
+определениями и примерами.
+
+
+## Дополнительная литература
+
+* [Алгоритмы на Java](https://www.ozon.ru/context/detail/id/18319699/)
+* [Алгоритмы. Построение и анализ](https://www.ozon.ru/context/detail/id/33769775/)
+
+## Ссылки
+
+* [Оценки времени исполнения. Символ O()](http://algolist.manual.ru/misc/o_n.php)
+* [Асимптотический анализ и теория вероятностей](https://www.lektorium.tv/course/22903)
+
+## Ссылки (англ.)
+
+* [Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1)
+* [Cheatsheet 1](http://web.mit.edu/broder/Public/asymptotics-cheatsheet.pdf)
+* [Cheatsheet 2](http://bigocheatsheet.com/)
+
diff --git a/ru-ru/bash-ru.html.markdown b/ru-ru/bash-ru.html.markdown
index 5e99afc2..ce918340 100644
--- a/ru-ru/bash-ru.html.markdown
+++ b/ru-ru/bash-ru.html.markdown
@@ -11,29 +11,40 @@ contributors:
- ["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"]
+ - ["Harry Mumford-Turner", "https://github.com/harrymt"]
+ - ["Martin Nicholson", "https://github.com/mn113"]
translators:
- ["Andrey Samsonov", "https://github.com/kryzhovnik"]
- - ["Andre Polykanine", "https://github.com/Oire"]
+ - ["Andre Polykanine", "https://github.com/Menelion"]
filename: LearnBash-ru.sh
lang: ru-ru
---
-Bash - это командная оболочка unix (unix shell), которая распространялась как оболочка для операционной системы GNU и используется в качестве оболочки по умолчанию для Linux и Mac OS X.
-Почти все нижеприведенные примеры могут быть частью shell-скриптов или исполнены напрямую в shell.
+Bash — это командная оболочка unix, которая распространялась как оболочка
+для операционной системы GNU и используется в качестве оболочки по умолчанию
+для Linux и Mac OS X.
+Почти все нижеприведённые примеры могут быть частью shell-скриптов
+или исполнены напрямую в shell.
[Подробнее.](http://www.gnu.org/software/bash/manual/bashref.html)
```bash
#!/bin/bash
-# Первая строка скрипта - это shebang, который сообщает системе, как исполнять
-# этот скрипт: http://en.wikipedia.org/wiki/Shebang_(Unix)
-# Как вы уже поняли, комментарии начинаются с #. Shebang - тоже комментарий.
+# Первая строка скрипта — это шебанг, который сообщает системе, как исполнять
+# этот скрипт: https://ru.wikipedia.org/wiki/Шебанг_(Unix)
+# Как вы уже поняли, комментарии начинаются с «#». Шебанг — тоже комментарий.
# Простой пример hello world:
echo Hello world!
# Отдельные команды начинаются с новой строки или разделяются точкой с запятой:
echo 'Это первая строка'; echo 'Это вторая строка'
+# => Это первая строка
+# => Это вторая строка
# Вот так объявляется переменная:
VARIABLE="Просто строка"
@@ -41,103 +52,234 @@ VARIABLE="Просто строка"
# но не так:
VARIABLE = "Просто строка"
# Bash решит, что VARIABLE - это команда, которую он должен исполнить,
-# и выдаст ошибку, потому что не сможет найти ее.
+# и выдаст ошибку, потому что не сможет найти её.
# и не так:
VARIABLE= 'Просто строка'
-# Тут Bash решит, что 'Просто строка' - это команда, которую он должен исполнить,
-# и выдаст ошибку, потому что не сможет найти такой команды
+# Тут Bash решит, что 'Просто строка' — это команда, которую он должен
+# исполнить, и выдаст ошибку, потому что не сможет найти такой команды
# (здесь 'VARIABLE=' выглядит как присвоение значения переменной,
# но только в контексте исполнения команды 'Просто строка').
# Использование переменой:
-echo $VARIABLE
-echo "$VARIABLE"
-echo '$VARIABLE'
-# Когда вы используете переменную - присваиваете, экспортируете и т.д. -
+echo $VARIABLE # => Просто строка
+echo "$VARIABLE" # => Просто строка
+echo '$VARIABLE' # => $Variable
+# Когда вы используете переменную — присваиваете, экспортируете и т.д. —
# пишите её имя без $. А для получения значения переменной используйте $.
# Заметьте, что ' (одинарные кавычки) не раскрывают переменные в них.
-# Подстановка строк в переменные
-echo ${VARIABLE/Просто/A}
-# Это выражение заменит первую встреченную подстроку "Просто" на "A"
+# Раскрытие параметров ${ }:
+echo ${Variable} # => Просто строка
+# Это простое использование раскрытия параметров
+# Раскрытие параметров получает значение переменной.
+# Оно «раскрывает», или печатает это значение.
+# ̶Значение можно изменить во время раскрытия.
+# Ниже приведены другие модификации при раскрытии параметров.
+
+# Замена подстрок в переменных
+echo ${Variable/Просто/Это} # => Это строка
+# Заменит первое вхождение «Просто» на «Это»
# Взять подстроку из переменной
LENGTH=7
-echo ${VARIABLE:0:LENGTH}
-# Это выражение вернет только первые 7 символов переменной VARIABLE
+echo ${VARIABLE:0:LENGTH} # => Просто
+# Это выражение вернёт только первые 7 символов переменной VARIABLE
+echo ${Variable: -5} # => трока
+# Вернёт последние 5 символов (обратите внимание на пробел перед «-5»)
+
+# Длина строки
+echo ${#Variable} # => 13
-# Значение по умолчанию
-echo ${FOO:-"DefaultValueIfFOOIsMissingOrEmpty"}
+# Значение переменной по умолчанию
+echo ${FOO:-"ЗначениеПоУмолчаниюЕслиFooПустаИлиНеНайдена"}
+# => ЗначениеПоУмолчаниюЕслиFooПустаИлиНеНайдена
# Это сработает при отсутствующем значении (FOO=) и пустой строке (FOO="");
-# ноль (FOO=0) вернет 0.
-# Заметьте, что в любом случае значение самой переменной FOO не изменится.
+# ноль (FOO=0) вернёт 0.
+# Заметьте, что в любом случае это лишь вернёт значение по умолчанию,
+# а значение самой переменной FOO не изменится.
+
+# Объявить массив из 6 элементов
+array0=(один два три четыре пять шесть)
+# Вывести первый элемент
+echo $array0 # => "один"
+# Вывести первый элемент
+echo ${array0[0]} # => "один"
+# Вывести все элементы
+echo ${array0[@]} # => "один два три четыре пять шесть"
+# Вывести число элементов
+echo ${#array0[@]} # => "6"
+# Вывести число символов в третьем элементе
+echo ${#array0[2]} # => "3"
+# Вывести 2 элемента, начиная с четвёртого
+echo ${array0[@]:3:2} # => "четыре пять"
+# Вывести все элементы, каждый на своей строке
+for i in "${array0[@]}"; do
+ echo "$i"
+done
+
+# Раскрытие скобок { }
+# Используется для создания произвольных строк
+echo {1..10} # => 1 2 3 4 5 6 7 8 9 10
+echo {a..z} # => a b c d e f g h i j k l m n o p q r s t u v w x y z
+# Выведет диапазон от начального до конечного значения
# Встроенные переменные:
# В bash есть полезные встроенные переменные, например
-echo "Последнее возвращенное значение: $?"
-echo "PID скрипта: $$"
-echo "Количество аргументов: $#"
-echo "Аргументы скрипта: $@"
+echo "Значение, возвращённое последней программой: $?"
+echo "Идентификатор процесса скрипта: $$"
+echo "Число аргументов, переданных скрипту: $#"
+echo "Все аргументы, переданные скрипту: $@"
echo "Аргументы скрипта, распределённые по отдельным переменным: $1 $2..."
-# Чтение аргументов из устройста ввода:
+# Теперь, когда мы знаем, как выводить и использовать переменные,
+# давайте изучим некоторые другие основы Bash!
+
+# Текущая директория доступна по команде `pwd`.
+# `pwd` расшифровывается как «print working directory», т.е.
+# «напечатать рабочую директорию».
+# Мы также можем использовать встроенную переменную `$PWD`.
+# Заметьте, следующие выражения эквивалентны:
+echo "Я в $(pwd)" # выполняет `pwd` и раскрывает вывод
+echo "Я в $PWD" # раскрывает переменную
+
+# Если вы получаете слишком много информации в терминале или из скрипта,
+# команда `clear` очистит экран
+clear
+# Очистить экран можно также с помощью Ctrl+L
+
+# Чтение аргументов с устройства ввода:
echo "Как Вас зовут?"
read NAME # Обратите внимание, что нам не нужно определять новую переменную
echo Привет, $NAME!
# У нас есть обычная структура if:
# наберите 'man test' для получения подробной информации о форматах условия
-if [ $NAME -ne $USER ]
+if [ $NAME != $USER ]
then
echo "Имя не совпадает с именем пользователя"
else
echo "Имя совпадает с именем пользователя"
fi
+# Истинно, если значение $Name не совпадает с текущим именем пользователя
-# Примечание: если $Name пустой, bash интерпретирует код как:
-if [ -ne $USER ]
+# Примечание: если $Name пуста, bash интерпретирует код так:
+if [ != $USER ]
# а это ошибочная команда
-# поэтому такие переменные нужно использовать так:
-if [ "$Name" -ne $USER ] ...
-# когда $Name пустой, bash видит код как:
-if [ "" -ne $USER ] ...
+# поэтому «безопасный» способ использовать пустые переменные в Bash таков:
+if [ "$Name" != $USER ] ...
+# при этом, когда $Name пуста, bash видит код так:
+if [ "" != $USER ] ...
# что работает правильно
# Также есть условное исполнение
echo "Исполнится всегда" || echo "Исполнится, если первая команда завершится ошибкой"
+# => Исполнится всегда
echo "Исполнится всегда" && echo "Исполнится, если первая команда выполнится удачно"
+# => Исполнится всегда
+# => Исполнится, если первая команда выполнится удачно
-# Можно использовать && и || в выражениях if, когда нужно несколько пар скобок:
-if [ $NAME == "Steve" ] && [ $AGE -eq 15 ]
+
+# Чтобы использовать && и || в выражениях if, нужно несколько пар скобок:
+if [ $NAME == "Стив" ] && [ $AGE -eq 15 ]
+then
+ echo "Исполнится, если $NAME равно Стив И $AGE равно 15."
+fi
+
+if [ $NAME == "Дания" ] || [ $NAME == "Зак" ]
then
- echo "Исполнится, если $NAME равно Steve И $AGE равно 15."
+ echo "Исполнится, если $NAME равно Дания ИЛИ Зак."
fi
-if [ $NAME == "Daniya" ] || [ $NAME == "Zach" ]
+# Есть ещё оператор «=~», который проверяет строку
+# на соответствие регулярному выражению:
+Email=me@example.com
+if [[ "$Email" =~ [a-z]+@[a-z]{2,}\.(com|net|org) ]]
then
- echo "Исполнится, если $NAME равно Daniya ИЛИ Zach."
+ echo "адрес корректный!"
fi
+# Обратите внимание, что =~ работает только внутри
+# двойных квадратных скобок [[ ]],
+# которые несколько отличаются от одинарных скобок [ ].
+# Для более подробной информации см. http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs.
+
+# Переопределить команду «ping» как псевдоним для отправки только пяти пакетов
+alias ping='ping -c 5'
+# Экранировать псевдоним и использовать команду под своим именем вместо него
+\ping 192.168.1.1
+# Вывести все псевдонимы
+alias -p
# Выражения обозначаются таким форматом:
-echo $(( 10 + 5 ))
+echo $(( 10 + 5 )) # => 15
-# В отличие от других языков программирования, Bash - это командная оболочка,
+# В отличие от других языков программирования, Bash — это командная оболочка,
# а значит, работает в контексте текущей директории.
# Вы можете просматривать файлы и директории в текущей директории командой ls:
-ls
+ls # перечисляет файлы и поддиректории в текущей директории
-# У этой команды есть опции:
+# У этой команды есть параметры:
ls -l # Показать каждый файл и директорию на отдельной строке
+ls -t # сортирует содержимое по дате последнего изменения (в обратном порядке)
+ls -R # Рекурсивно выполняет `ls` по данной директории и всем её поддиректориям
# Результат предыдущей команды может быть направлен на вход следующей.
# Команда grep фильтрует ввод по шаблону.
-# Так мы можем просмотреть только *.txt файлы в текущей директории:
+# Так мы можем просмотреть только *.txt-файлы в текущей директории:
ls -l | grep "\.txt"
+# Для вывода файлов в стандартный поток используйте `cat`:
+cat file.txt
+
+# С помощью `cat` мы также можем читать файлы:
+Contents=$(cat file.txt)
+echo "НАЧАЛО ФАЙЛА\n$Contents\nКОНЕЦ ФАЙЛА" # «\n» выводит символ перевода на новую строку
+# => НАЧАЛО ФАЙЛА
+# => [Содержимое file.txt]
+# => КОНЕЦ ФАЙЛА
+
+# Для копирования файлов и директорий из одного места в другое используйте `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 # Извините, тут были Leet-хакеры...
+
+# Поскольку Bash работает в контексте текущей директории, вам может понадобиться
+# запустить команду в другой директории.
+# Для изменения местоположения у нас есть `cd`:
+cd ~ # Перейти в домашнюю директорию
+cd # Также переходит в домашнюю директорию
+cd .. # Перейти на уровень вверх
+ # (например, из /home/username/Downloads в /home/username)
+cd /home/username/Documents # перейти в указанную директорию
+cd ~/Documents/.. # Всё ещё в домашней директории. Так ведь??
+cd - # Перейти в последнюю директорию
+# => /home/username/Documents
+
+# Для работы по директориям используйте субоболочки
+(echo "Сначала я здесь: $PWD") && (cd someDir; echo "А теперь я тут: $PWD")
+pwd # всё ещё в первой директории
+
+# Для создания новых директорий используйте `mkdir`.
+mkdir myNewDir
+# Флаг `-p` указывает, что нужно создать все промежуточные директории, если нужно.
+mkdir -p myNewDir/with/intermediate/directories
+# Если промежуточные директории до этого не существовали,
+# вышеприведённая команда без флага `-p` вернёт ошибку
+
# Вы можете перенаправить ввод и вывод команды (stdin, stdout и stderr).
-# Следующая команда означает: читать из stdin, пока не встретится ^EOF$, и
-# перезаписать hello.py следующим строками (до строки "EOF"):
+# Прочитать из stdin, пока не встретится ^EOF$, и
+# перезаписать hello.py следующими строками (до строки "EOF"):
cat > hello.py << EOF
#!/usr/bin/env python
from __future__ import print_function
@@ -147,23 +289,25 @@ print("#stderr", file=sys.stderr)
for line in sys.stdin:
print(line, file=sys.stdout)
EOF
+# Если первый «EOF» не заключён в кавычки, переменные будут раскрыты
# Запуск hello.py с разными вариантами перенаправления потоков
# стандартных ввода, вывода и ошибок:
-python hello.py < "input.in"
-python hello.py > "output.out"
-python hello.py 2> "error.err"
-python hello.py > "output-and-error.log" 2>&1
-python hello.py > /dev/null 2>&1
+python hello.py < "input.in" # передать input.in в качестве ввода в скрипт
+python hello.py > "output.out" # передать вывод скрипта в output.out
+python hello.py 2> "error.err" # передать вывод ошибок в error.err
+python hello.py > "output-and-error.log" 2>&1 # передать вывод скрипта и ошибок в output-and-error.log
+python hello.py > /dev/null 2>&1 # передать вывод скрипта и ошибок в «чёрную дыру» /dev/null, т.е., без вывода
# Поток ошибок перезапишет файл, если этот файл существует,
-# поэтому, если вы хотите дописывать файл, используйте ">>":
+# поэтому, если вы хотите дописывать файл, используйте «>>»:
python hello.py >> "output.out" 2>> "error.err"
-# Переписать output.txt, дописать error.err и сосчитать строки:
+# Перезаписать output.txt, дописать error.err и сосчитать строки:
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
wc -l output.out error.err
-# Запустить команду и вывести ее файловый дескриптор (смотрите: man fd)
+# Запустить команду и вывести её файловый дескриптор (например, /dev/fd/123)
+# См. man fd
echo <(echo "#helloworld")
# Перезаписать output.txt строкой "#helloworld":
@@ -172,40 +316,49 @@ echo "#helloworld" > output.out
echo "#helloworld" | cat > output.out
echo "#helloworld" | tee output.out >/dev/null
-# Подчистить временные файлы с подробным выводом ('-i' - интерактивый режим)
+# Подчистить временные файлы с подробным выводом ('-i' — интерактивный режим)
+# ВНИМАНИЕ: команду `rm` отменить нельзя
rm -v output.out error.err output-and-error.log
+rm -r tempDir/ # рекурсивное удаление
# Команды могут быть подставлены в строку с помощью $( ):
# следующие команды выводят число файлов и директорий в текущей директории.
echo "Здесь $(ls | wc -l) элементов."
-# То же самое можно сделать с использованием обратных кавычек,
+# То же самое можно сделать с использованием обратных кавычек «``»,
# но они не могут быть вложенными, поэтому предпочтительно использовать $( ).
echo "Здесь `ls | wc -l` элементов."
# В Bash есть структура case, которая похожа на switch в Java и C++:
case "$VARIABLE" in
- # Перечислите шаблоны для условий, которые хотите отловить
+ # Перечислите шаблоны для условий, которые хотите выполнить
0) echo "Тут ноль.";;
1) echo "Тут один.";;
*) echo "Это не пустое значение.";;
esac
-# Цикл for перебирает элементы переданные в аргументе:
+# Цикл for перебирает элементы по количеству аргументов:
# Содержимое $VARIABLE будет напечатано три раза.
for VARIABLE in {1..3}
do
echo "$VARIABLE"
done
+# => 1
+# => 2
+# => 3
+
-# Или с использованием "традиционного" синтаксиса цикла for:
+# Или с использованием «традиционного» синтаксиса цикла for:
for ((a=1; a <= 3; a++))
do
echo $a
done
+# => 1
+# => 2
+# => 3
# Цикл for можно использовать для действий с файлами.
-# Запустим команду 'cat' для файлов file1 и file2
+# Запустим команду «cat» для файлов file1 и file2
for VARIABLE in file1 file2
do
cat "$VARIABLE"
@@ -221,52 +374,89 @@ done
# Цикл while:
while [ true ]
do
- echo "тело цикла здесь..."
+ echo "Здесь тело цикла..."
break
done
+# => Здесь тело цикла...
-# Вы можете определять функции
+# Вы также можете определять функции
# Определение:
function foo ()
{
- echo "Аргументы работают также, как аргументы скрипта: $@"
- echo "и: $1 $2..."
+ echo "Аргументы работают так же, как и аргументы скрипта: $@"
+ echo "И так: $1 $2..."
echo "Это функция"
return 0
}
+# Вызовем функцию `foo` с двумя аргументами, arg1 и arg2:
+foo arg1 arg2
+# => Аргументы работают так же, как и аргументы скрипта: arg1 arg2
+# => И так: arg1 arg2...
+# => Это функция
# или просто
bar ()
{
- echo "Другой способ определить функцию!"
+ echo "Другой способ определять функции!"
return 0
}
+# Вызовем функцию `bar` без аргументов:
+bar # => Другой способ определять функции!
# Вызов функции
-foo "Мое имя" $NAME
+foo "Меня зовут" $NAME
# Есть много полезных команд, которые нужно знать:
# напечатать последние 10 строк файла file.txt
tail -n 10 file.txt
+
# напечатать первые 10 строк файла file.txt
head -n 10 file.txt
+
# отсортировать строки file.txt
sort file.txt
-# отобрать или наоборот пропустить повторяющиеся строки (с опцией -d отбирает)
+
+# отобрать или наоборот пропустить повторяющиеся строки (с параметром `-d` отбирает строки)
uniq -d file.txt
-# напечатать только первую колонку перед символом ','
+
+# напечатать только первый столбец перед символом «,»
cut -d ',' -f 1 file.txt
-# заменить каждое 'okay' на 'great' в файле file.txt (regex поддерживается)
-sed -i 's/okay/great/g' file.txt
-# вывести в stdout все строки из file.txt, совпадающие с шаблоном regex;
-# этот пример выводит строки, которые начинаются на "foo" и оканчиваются "bar"
+
+# заменить каждое вхождение «хорошо» на «прекрасно» в файле file.txt
+# (поддерживаются регулярные выражения)
+sed -i 's/хорошо/прекрасно/g' file.txt
+
+# вывести в stdout все строки из file.txt, соответствующие регулярному выражению
+# этот пример выводит строки, которые начинаются на «foo» и оканчиваются на «bar»
grep "^foo.*bar$" file.txt
-# передайте опцию -c чтобы вывести число строк, в которых совпал шаблон
+
+# Передайте параметр `-c`, чтобы вывести лишь число строк,
+# соответствующих регулярному выражению
grep -c "^foo.*bar$" file.txt
-# чтобы искать по строке, а не шаблону regex, используйте fgrep (или grep -F)
+
+# Ниже приведены другие полезные параметры:
+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 "^foo.*bar$" file.txt
-# Читайте встроенную документацию оболочки Bash командой 'help':
+# Команда `trap` позволяет выполнить некую команду, когда ваш скрипт
+# принимает определённый Posix-сигнал. В следующем примере `trap` выполнит `rm`,
+# если скрипт примет один из трёх перечисленных сигналов.
+trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM
+
+# `sudo` используется для выполнения команд с правами суперпользователя
+NAME1=$(whoami)
+NAME2=$(sudo whoami)
+echo "Был $NAME1, затем стал более мощным $NAME2"
+
+# Читайте встроенную документацию оболочки Bash командой `help`:
help
help help
help for
@@ -274,18 +464,18 @@ help return
help source
help .
-# Читайте Bash man-документацию
+# Читайте man-документацию Bash командой `man`:
apropos bash
man 1 bash
man bash
-# Читайте документацию info (? для помощи)
+# Читайте документацию info (? для справки)
apropos info | grep '^info.*('
man info
info info
info 5 info
-# Читайте bash info документацию:
+# Читайте info-документацию Bash:
info bash
info bash 'Bash Features'
info bash 6
diff --git a/ru-ru/bf.html.markdown b/ru-ru/bf.html.markdown
index 20f0fa56..d2e74e8f 100644
--- a/ru-ru/bf.html.markdown
+++ b/ru-ru/bf.html.markdown
@@ -1,5 +1,6 @@
---
language: bf
+filename: learnbf-ru.bf
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
diff --git a/ru-ru/c++-ru.html.markdown b/ru-ru/c++-ru.html.markdown
index 0cf580d5..3acfafa3 100644
--- a/ru-ru/c++-ru.html.markdown
+++ b/ru-ru/c++-ru.html.markdown
@@ -43,11 +43,11 @@ int main(int argc, char** argv)
// Аргументы командной строки, переданные в программу, хранятся в переменных
// argc и argv, так же, как и в C.
// argc указывает на количество аргументов,
- // а argv является массивом C-подобных строк (char*), который непосредсвенно
+ // а argv является массивом C-подобных строк (char*), который непосредственно
// содержит аргументы.
// Первым аргументом всегда передается имя программы.
- // argc и argv могут быть опущены, если вы не планируете работать с аругментами
- // коммандной строки.
+ // argc и argv могут быть опущены, если вы не планируете работать с аргументами
+ // командной строки.
// Тогда сигнатура функции будет иметь следующий вид: int main()
// Возвращаемое значение 0 указывает на успешное завершение программы.
@@ -162,7 +162,7 @@ void foo()
int main()
{
- // Включает все функци из пространства имен Second в текущую область видимости.
+ // Включает все функции из пространства имен Second в текущую область видимости.
// Обратите внимание, что простой вызов foo() больше не работает,
// так как теперь не ясно, вызываем ли мы foo из пространства имен Second, или
// из глобальной области видимости.
@@ -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() {
@@ -471,6 +471,7 @@ int main() {
// членам\методам без открытых или защищенных методов для этого.
class OwnedDog : public Dog {
+public:
void setOwner(const std::string& dogsOwner);
// Переопределяем поведение функции печати для всех OwnedDog. Смотрите
@@ -521,7 +522,7 @@ public:
// по умолчанию (0, 0)
Point() { };
- // Следующий синтаксис известен как список инициализации и является верным способом
+ // Следующий синтаксис известен как список инициализации и является верным способом
// инициализировать значения членов класса.
Point (double a, double b) :
x(a),
@@ -582,10 +583,10 @@ public:
// Во время компиляции компилятор фактически генерирует копии каждого шаблона
// с замещенными параметрами, поэтому полное определение класса должно присутствовать
-// при каждом вызове. Именно поэтому классы шаблонов полностью определены в
+// при каждом вызове. Именно поэтому шаблоны классов полностью определены в
// заголовочных файлах.
-// Чтобы создать экземпляр класса шаблона на стеке:
+// Чтобы создать экземпляр шаблона класса на стеке:
Box<int> intBox;
// и вы можете использовать его, как и ожидалось:
@@ -605,7 +606,7 @@ boxOfBox.insert(intBox);
// http://en.wikipedia.org/wiki/Typename
// (да-да, это ключевое слово имеет собственную страничку на вики).
-// Аналогичным образом, шаблонная функция:
+// Аналогичным образом, шаблон функции:
template<class T>
void barkThreeTimes(const T& input)
{
@@ -622,7 +623,7 @@ Dog fluffy;
fluffy.setName("Fluffy");
barkThreeTimes(fluffy); // Печатает "Fluffy barks" три раза.
-//Параметры шаблона не должны быть классами:
+// Параметры шаблона не должны быть классами:
template<int Y>
void printMessage() {
cout << "Learn C++ in " << Y << " minutes!" << endl;
@@ -680,7 +681,7 @@ catch (...)
// некоторого ресурса неразрывно совмещается с инициализацией, а освобождение -
// с уничтожением объекта.
-// Чтобы понять, на сколько это полезно,
+// Чтобы понять, насколько это полезно,
// рассмотрим функцию, которая использует обработчик файлов в С:
void doSomethingWithAFile(const char* filename)
{
@@ -793,10 +794,10 @@ void doSomethingWithAFile(const std::string& filename)
// Весь идиоматический код на С++ широко использует RAII для всех ресурсов.
// Дополнительные примеры включат:
// - Использование памяти unique_ptr и shared_ptr
-// - Контейнеры - стандартная библиотека связанных списков, векторы
+// - Контейнеры - стандартная библиотека связанных списков, векторы
// (т.е. самоизменяемые массивы), хэш-таблицы и все остальное автоматически
// уничтожается сразу же, когда выходит за пределы области видимости.
-// - Ипользование мьютексов lock_guard и unique_lock
+// - Использование мьютексов lock_guard и unique_lock
// Контейнеры с пользовательскими классами в качестве ключей требуют
// сравнивающих функций в самом объекте или как указатель на функцию. Примитивы
@@ -853,7 +854,7 @@ pt2 = nullptr; // Устанавливает pt2 в null.
// '=' != '=' != '='!
// Вызывает Foo::Foo(const Foo&) или некий вариант (смотрите "move semantics")
-// копирования конструктора.
+// конструктора копирования.
Foo f2;
Foo f1 = f2;
@@ -886,7 +887,6 @@ v.swap(vector<Foo>());
```
## Дальнейшее чтение:
-Наиболее полное и обновленное руководство по С++ можно найти на
-<http://cppreference.com/w/cpp>
-
-Дополнительные ресурсы могут быть найдены на <http://cplusplus.com>
+* Наиболее полное и обновленное руководство по С++ можно найти на [CPP Reference](http://cppreference.com/w/cpp).
+* Дополнительные ресурсы могут быть найдены на [CPlusPlus](http://cplusplus.com).
+* Учебник, посвященный основам языка и настройке среды кодирования, доступен в [TheChernoProject - C ++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb).
diff --git a/ru-ru/c-ru.html.markdown b/ru-ru/c-ru.html.markdown
index ab4be57e..cc68d620 100644
--- a/ru-ru/c-ru.html.markdown
+++ b/ru-ru/c-ru.html.markdown
@@ -11,7 +11,7 @@ lang: ru-ru
Что ж, Си всё ещё является лидером среди современных высокопроизводительных языков.
-Для большинствоа программистов, Си – это самый низкоуровневый язык на котором они когда-либо писали,
+Для большинства программистов, Си – это самый низкоуровневый язык на котором они когда-либо писали,
но этот язык даёт больше, чем просто повышение производительности.
Держите это руководство в памяти и вы сможете использовать Си максимально эффективно.
@@ -77,7 +77,7 @@ int main() {
// sizeof(obj) возвращает размер объекта obj в байтах.
printf("%zu\n", sizeof(int)); // => 4 (на большинстве машин int занимает 4 байта)
- // Если аргуметом sizeof будет выражение, то этот аргумент вычисляется
+ // Если аргументом sizeof будет выражение, то этот аргумент вычисляется
// ещё во время компиляции кода (кроме динамических массивов).
int a = 1;
// size_t это беззнаковый целый тип который использует как минимум 2 байта
@@ -170,7 +170,7 @@ int main() {
!0; // => 1
1 && 1; // => 1 (логическое И)
0 && 1; // => 0
- 0 || 1; // => 1 (лигическое ИЛИ)
+ 0 || 1; // => 1 (логическое ИЛИ)
0 || 0; // => 0
// Битовые операторы
@@ -229,7 +229,7 @@ int main() {
switch (some_integral_expression) {
case 0: // значения должны быть целыми константами (и могут быть выражениями)
do_stuff();
- break; // если не написать break; то управление будет передено следующему блоку
+ break; // если не написать break; то управление будет передано следующему блоку
case 1:
do_something_else();
break;
@@ -247,7 +247,7 @@ int main() {
// Каждое выражение в Си имеет тип, но вы можете привести один тип к другому,
// если хотите (с некоторыми искажениями).
- int x_hex = 0x01; // Вы можете назначать переменные с помощью шеснадцатеричного кода.
+ int x_hex = 0x01; // Вы можете назначать переменные с помощью шестнадцатеричного кода.
// Приведение типов будет пытаться сохранять цифровые значения.
printf("%d\n", x_hex); // => Prints 1
@@ -288,14 +288,14 @@ int main() {
// Для того, чтобы получить значение по адресу, напечатайте * перед именем.
// Да, * используется при объявлении указателя и для получении значения по адресу
// немного запутано, но вы привыкнете.
- printf("%d\n", *px); // => Напечаатет 0, значение перемененной x
+ printf("%d\n", *px); // => Напечатает 0, значение перемененной x
// Вы также можете изменять значение, на которое указывает указатель.
(*px)++; // Инкрементирует значение на которое указывает px на единицу
printf("%d\n", *px); // => Напечатает 1
printf("%d\n", x); // => Напечатает 1
- // Массивы удобно использовать для болшого количества однотипных данных.
+ // Массивы удобно использовать для большого количества однотипных данных.
int x_array[20];
int xx;
for (xx = 0; xx < 20; xx++) {
@@ -308,7 +308,7 @@ int main() {
// Это работает, потому что при обращении к имени массива возвращается
// указатель на первый элемент.
// Например, когда массив передаётся в функцию или присваивается указателю, он
- // невявно преобразуется в указатель.
+ // неявно преобразуется в указатель.
// Исключения: когда массив является аргументом для оператор '&':
int arr[10];
int (*ptr_to_arr)[10] = &arr; // &arr не является 'int *'!
@@ -335,7 +335,7 @@ int main() {
// Работа с памятью с помощью указателей может давать неожиданные и
// непредсказуемые результаты.
- printf("%d\n", *(my_ptr + 21)); // => Напечатает кто-нибудь-знает-что?
+ printf("%d\n", *(my_ptr + 21)); // => Напечатает кто-нибудь знает, что?
// Скорей всего программа вылетит.
// Когда вы закончили работать с памятью, которую ранее выделили, вам необходимо
@@ -353,7 +353,7 @@ int main() {
// Это не работает, если строка является массивом
// (потенциально задаваемой с помощью строкового литерала)
- // который находиться в перезаписываемой части памяти:
+ // который находится в перезаписываемой части памяти:
char foo[] = "foo";
foo[0] = 'a'; // это выполнится и строка теперь "aoo"
@@ -426,7 +426,7 @@ void function_1() {
// Можно получить доступ к структуре и через указатель
(*my_rec_ptr).width = 30;
- // ... или ещё лучше: используйте оператор -> для лучшей читабельночти
+ // ... или ещё лучше: используйте оператор -> для лучшей читабельности
my_rec_ptr->height = 10; // то же что и "(*my_rec_ptr).height = 10;"
}
@@ -457,7 +457,7 @@ int area(const rect *r) {
void str_reverse_through_pointer(char *str_in) {
// Определение функции через указатель.
- void (*f)(char *); // Сигнатура должна полность совпадать с целевой функцией.
+ void (*f)(char *); // Сигнатура должна полностью совпадать с целевой функцией.
f = &str_reverse; // Присвоить фактический адрес (во время исполнения)
// "f = str_reverse;" тоже будет работать.
//Имя функции (как и массива) возвращает указатель на начало.
@@ -471,13 +471,13 @@ void str_reverse_through_pointer(char *str_in) {
Лучше всего найдите копию [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language)
Это **книга** написанная создателями Си. Но будьте осторожны, она содержит идеи которые больше не считаются хорошими.
-Другой хороший ресурс: [Learn C the hard way](http://c.learncodethehardway.org/book/).
+Другой хороший ресурс: [Learn C the hard way](http://learncodethehardway.org/c/).
Если у вас появился вопрос, почитайте [compl.lang.c Frequently Asked Questions](http://c-faq.com).
Очень важно использовать правильные отступы и ставить пробелы в нужных местах.
Читаемый код лучше чем красивый или быстрый код.
-Чтобы научиться писать хороший код, почитайте [Linux kernel coding stlye](https://www.kernel.org/doc/Documentation/CodingStyle).
+Чтобы научиться писать хороший код, почитайте [Linux kernel coding style](https://www.kernel.org/doc/Documentation/CodingStyle).
Также не забывайте, что [Google](http://google.com) и [Яндекс](http://yandex.ru) – ваши хорошие друзья.
diff --git a/ru-ru/clojure-ru.html.markdown b/ru-ru/clojure-ru.html.markdown
index 451da312..19233d23 100644
--- a/ru-ru/clojure-ru.html.markdown
+++ b/ru-ru/clojure-ru.html.markdown
@@ -8,9 +8,9 @@ translators:
lang: ru-ru
---
-Clojure, это представитель семейства Lisp-подобных языков, разработанный
+Clojure — это представитель семейства Lisp-подобных языков, разработанный
для Java Virtual Machine. Язык идейно гораздо ближе к чистому
-[функциональному программированию](https://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) чем его прародитель Common Lisp, но в то же время обладает набором инструментов для работы с состоянием,
+[функциональному программированию](https://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5), чем его прародитель Common Lisp, но в то же время обладает набором инструментов для работы с состоянием,
таких как [STM](https://ru.wikipedia.org/wiki/Software_transactional_memory).
Благодаря такому сочетанию технологий в одном языке, разработка программ,
@@ -23,9 +23,9 @@ Clojure, это представитель семейства Lisp-подобн
```clojure
; Комментарии начинаются символом ";".
-; Код на языке Clojure записывается в виде "форм",
+; Код на языке Clojure записывается в виде «форм»,
; которые представляют собой обычные списки элементов, разделенных пробелами,
-; заключённые в круглые скобки
+; заключённые в круглые скобки.
;
; Clojure Reader (инструмент языка, отвечающий за чтение исходного кода),
; анализируя форму, предполагает, что первым элементом формы (т.е. списка)
@@ -76,32 +76,32 @@ Clojure, это представитель семейства Lisp-подобн
'(+ 1 2) ; => (+ 1 2)
; ("'", это краткая запись формы (quote (+ 1 2))
-; "Квотированный" список можно вычислить, передав его функции eval
+; «Квотированный» список можно вычислить, передав его функции eval
(eval '(+ 1 2)) ; => 3
; Коллекции и Последовательности
;;;;;;;;;;;;;;;;;;;
-; Списки (Lists) в clojure структурно представляют собой "связанные списки",
+; Списки (Lists) в clojure структурно представляют собой «связанные списки»,
; тогда как Векторы (Vectors), устроены как массивы.
; Векторы и Списки тоже являются классами Java!
(class [1 2 3]); => clojure.lang.PersistentVector
(class '(1 2 3)); => clojure.lang.PersistentList
-; Список может быть записан, как (1 2 3), но в этом случае
+; Список может быть записан как (1 2 3), но в этом случае
; он будет воспринят reader`ом, как вызов функции.
; Есть два способа этого избежать:
; '(1 2 3) - квотирование,
; (list 1 2 3) - явное конструирование списка с помощью функции list.
-; "Коллекции", это некие наборы данных
+; «Коллекции» — это некие наборы данных.
; И списки, и векторы являются коллекциями:
(coll? '(1 2 3)) ; => true
(coll? [1 2 3]) ; => true
-; "Последовательности" (seqs), это абстракция над наборами данных,
+; «Последовательности» (seqs) — это абстракция над наборами данных,
; элементы которых "упакованы" последовательно.
-; Списки - последовательности, а вектора - нет.
+; Списки — последовательности, а векторы — нет.
(seq? '(1 2 3)) ; => true
(seq? [1 2 3]) ; => false
@@ -119,7 +119,7 @@ Clojure, это представитель семейства Lisp-подобн
; Функция conj добавляет элемент в коллекцию
; максимально эффективным для неё способом.
-; Для списков эффективно добавление в начло, а для векторов - в конец.
+; Для списков эффективно добавление в начло, а для векторов — в конец.
(conj [1 2 3] 4) ; => [1 2 3 4]
(conj '(1 2 3) 4) ; => (4 1 2 3)
@@ -130,7 +130,7 @@ Clojure, это представитель семейства Lisp-подобн
(map inc [1 2 3]) ; => (2 3 4)
(filter even? [1 2 3]) ; => (2)
-; reduce поможет "свернуть" коллекцию
+; reduce поможет «свернуть» коллекцию
(reduce + [1 2 3 4])
; = (+ (+ (+ 1 2) 3) 4)
; => 10
@@ -144,12 +144,12 @@ Clojure, это представитель семейства Lisp-подобн
;;;;;;;;;;;;;;;;;;;;;
; Функция создается специальной формой fn.
-; "Тело" функции может состоять из нескольких форм,
+; «Тело» функции может состоять из нескольких форм,
; но результатом вызова функции всегда будет результат вычисления
; последней из них.
(fn [] "Hello World") ; => fn
-; (Вызов функции требует "оборачивания" fn-формы в форму вызова)
+; (Вызов функции требует «оборачивания» fn-формы в форму вызова)
((fn [] "Hello World")) ; => "Hello World"
; Назначить значению имя можно специальной формой def
@@ -160,7 +160,7 @@ x ; => 1
(def hello-world (fn [] "Hello World"))
(hello-world) ; => "Hello World"
-; Поскольку именование функций - очень частая операция,
+; Поскольку именование функций — очень частая операция,
; clojure позволяет, сделать это проще:
(defn hello-world [] "Hello World")
@@ -211,7 +211,7 @@ x ; => 1
; Отображения могут использовать в качестве ключей любые хэшируемые значения,
; однако предпочтительными являются ключи,
-; являющиеся "ключевыми словами" (keywords)
+; являющиеся «ключевыми словами» (keywords)
(class :a) ; => clojure.lang.Keyword
(def stringmap {"a" 1, "b" 2, "c" 3})
@@ -263,7 +263,7 @@ keymap ; => {:a 1, :b 2, :c 3} - оригинал не был затронут
; Исключаются - посредством disj
(disj #{1 2 3} 1) ; => #{2 3}
-; Вызов множества, как функции, позволяет проверить
+; Вызов множества как функции позволяет проверить
; принадлежность элемента этому множеству:
(#{1 2 3} 1) ; => 1
(#{1 2 3} 4) ; => nil
@@ -274,8 +274,8 @@ keymap ; => {:a 1, :b 2, :c 3} - оригинал не был затронут
; Полезные формы
;;;;;;;;;;;;;;;;;
-; Конструкции ветвления в clojure, это обычные макросы
-; и подобны их собратьям в других языках:
+; Конструкции ветвления в clojure — это обычные макросы,
+; они подобны своим собратьям в других языках:
(if false "a" "b") ; => "b"
(if false "a") ; => nil
@@ -285,7 +285,7 @@ keymap ; => {:a 1, :b 2, :c 3} - оригинал не был затронут
(let [a 1 b 2]
(> a b)) ; => false
-; Несколько форм можно объединить в одну форму посредством do
+; Несколько форм можно объединить в одну форму посредством do.
; Значением do-формы будет значение последней формы из списка вложенных в неё:
(do
(print "Hello")
@@ -298,7 +298,7 @@ keymap ; => {:a 1, :b 2, :c 3} - оригинал не был затронут
(str "Hello " name))
(print-and-say-hello "Jeff") ;=> "Hello Jeff" (prints "Saying hello to Jeff")
-; Ещё один пример - let:
+; Ещё один пример — let:
(let [name "Urkel"]
(print "Saying hello to " name)
(str "Hello " name)) ; => "Hello Urkel" (prints "Saying hello to Urkel")
@@ -306,7 +306,7 @@ keymap ; => {:a 1, :b 2, :c 3} - оригинал не был затронут
; Модули
;;;;;;;;;
-; Форма "use" позволяет добавить в текущее пространство имен
+; Форма use позволяет добавить в текущее пространство имен
; все имена (вместе со значениями) из указанного модуля:
(use 'clojure.set)
@@ -321,7 +321,7 @@ keymap ; => {:a 1, :b 2, :c 3} - оригинал не был затронут
; Также модуль может быть импортирован формой require
(require 'clojure.string)
-; После этого модуль становится доступе в текущем пространстве имен,
+; После этого модуль становится доступен в текущем пространстве имен,
; а вызов его функций может быть осуществлен указанием полного имени функции:
(clojure.string/blank? "") ; => true
@@ -392,7 +392,7 @@ keymap ; => {:a 1, :b 2, :c 3} - оригинал не был затронут
my-atom ;=> Atom<#...> (Возвращает объект типа Atom)
@my-atom ; => {:a 1 :b 2}
-; Пример реализации счётчика на атоме
+; Пример реализации счётчика на атоме:
(def counter (atom 0))
(defn inc-counter []
(swap! counter inc))
@@ -414,13 +414,13 @@ my-atom ;=> Atom<#...> (Возвращает объект типа Atom)
Это руководство не претендует на полноту, но мы смеем надеяться, способно вызвать интерес к дальнейшему изучению языка.
-Clojure.org - сайт содержит большое количество статей по языку:
+Сайт Clojure.org содержит большое количество статей по языку:
[http://clojure.org/](http://clojure.org/)
-Clojuredocs.org - сайт документации языка с примерами использования функций:
+Clojuredocs.org — сайт документации языка с примерами использования функций:
[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
-4Clojure - отличный способ закрепить навыки программирования на clojure, решая задачи вместе с коллегами со всего мира:
+4Clojure — отличный способ закрепить навыки программирования на clojure, решая задачи вместе с коллегами со всего мира:
[http://www.4clojure.com/](http://www.4clojure.com/)
Clojure-doc.org (да, именно) неплохой перечень статей для начинающих:
diff --git a/ru-ru/common-lisp-ru.html.markdown b/ru-ru/common-lisp-ru.html.markdown
new file mode 100644
index 00000000..d5f9bf0e
--- /dev/null
+++ b/ru-ru/common-lisp-ru.html.markdown
@@ -0,0 +1,704 @@
+---
+
+language: "Common Lisp"
+filename: commonlisp.lisp
+contributors:
+ - ["Paul Nathan", "https://github.com/pnathan"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
+translators:
+ - ["Michael Filonenko", "https://github.com/filonenko-mikhail"]
+lang: ru-ru
+---
+
+Common Lisp - мультипарадигменный язык программирования общего назначения, подходящий для широкого
+спектра задач.
+Его частенько называют программируемым языком программирования.
+
+Идеальная отправная точка - книга [Common Lisp на практике (перевод)](http://lisper.ru/pcl/).
+Ещё одна популярная книга [Land of Lisp](http://landoflisp.com/).
+И одна из последних книг [Common Lisp Recipes](http://weitz.de/cl-recipes/) вобрала в себя лучшие
+архитектурные решения на основе опыта коммерческой работки автора.
+
+
+
+```common-lisp
+
+;;;-----------------------------------------------------------------------------
+;;; 0. Синтаксис
+;;;-----------------------------------------------------------------------------
+
+;;; Основные формы
+
+;;; Существует два фундамента CL: АТОМ и S-выражение.
+;;; Как правило, сгруппированные S-выражения называют `формами`.
+
+10 ; атом; вычисляется в самого себя
+:thing ; другой атом; вычисляется в символ :thing
+t ; ещё один атом, обозначает `истину` (true)
+(+ 1 2 3 4) ; s-выражение
+'(4 :foo t) ; ещё одно s-выражение
+
+;;; Комментарии
+
+;;; Однострочные комментарии начинаются точкой с запятой. Четыре знака подряд
+;;; используют для комментария всего файла, три для раздела, два для текущего
+;;; определения; один для текущей строки. Например:
+
+;;;; life.lisp
+
+;;; То-сё - пятое-десятое. Оптимизировано для максимального бадабума и ччччч.
+;;; Требуется для функции PoschitatBenzinIsRossiiVBelarus
+
+(defun meaning (life)
+ "Возвращает смысл Жизни"
+ (let ((meh "abc"))
+ ;; Вызывает бадабум
+ (loop :for x :across meh
+ :collect x))) ; сохранить значения в x, и потом вернуть
+
+;;; А вот целый блок комментария можно использовать как угодно.
+;;; Для него используются #| и |#
+
+#| Целый блок комментария, который размазан
+ на несколько строк
+ #|
+ которые могут быть вложенными!
+ |#
+|#
+
+;;; Чем пользоваться
+
+;;; Существует несколько реализаций: и коммерческих, и открытых.
+;;; Все они максимально соответствуют стандарту языка.
+;;; SBCL, например, добротен. А за дополнительными библиотеками
+;;; нужно ходить в Quicklisp
+
+;;; Обычно разработка ведется в текстовом редакторе с запущенным в цикле
+;;; интерпретатором (в CL это Read Eval Print Loop). Этот цикл (REPL)
+;;; позволяет интерактивно выполнять части программы вживую сразу наблюдая
+;;; результат.
+
+;;;-----------------------------------------------------------------------------
+;;; 1. Базовые типы и операторы
+;;;-----------------------------------------------------------------------------
+
+;;; Символы
+
+'foo ; => FOO Символы автоматически приводятся к верхнему регистру.
+
+;;; INTERN создаёт символ из строки.
+
+(intern "AAAA") ; => AAAA
+(intern "aaa") ; => |aaa|
+
+;;; Числа
+
+9999999999999999999999 ; целые
+#b111 ; двоичные => 7
+#o111 ; восьмеричные => 73
+#x111 ; шестнадцатиричные => 273
+3.14159s0 ; с плавающей точкой
+3.14159d0 ; с плавающей точкой с двойной точностью
+1/2 ; рациональные)
+#C(1 2) ; комплексные
+
+;;; Вызов функции пишется как s-выражение (f x y z ....), где f это функция,
+;;; x, y, z, ... аругменты.
+
+(+ 1 2) ; => 3
+
+;;; Если вы хотите просто представить код как данные, воспользуйтесь формой QUOTE
+;;; Она не вычисляет аргументы, а возвращает их как есть.
+;;; Она даёт начало метапрограммированию
+
+(quote (+ 1 2)) ; => (+ 1 2)
+(quote a) ; => A
+
+;;; QUOTE можно сокращенно записать знаком '
+
+'(+ 1 2) ; => (+ 1 2)
+'a ; => A
+
+;;; Арифметические операции
+
+(+ 1 1) ; => 2
+(- 8 1) ; => 7
+(* 10 2) ; => 20
+(expt 2 3) ; => 8
+(mod 5 2) ; => 1
+(/ 35 5) ; => 7
+(/ 1 3) ; => 1/3
+(+ #C(1 2) #C(6 -4)) ; => #C(7 -2)
+
+;;; Булевые
+
+t ; истина; любое не-NIL значение `истинно`
+nil ; ложь; а ещё пустой список () тоже `ложь`
+(not nil) ; => T
+(and 0 t) ; => T
+(or 0 nil) ; => 0
+
+;;; Строковые символы
+
+#\A ; => #\A
+#\λ ; => #\GREEK_SMALL_LETTER_LAMDA
+#\u03BB ; => #\GREEK_SMALL_LETTER_LAMDA
+
+;;; Строки это фиксированные массивы символов
+
+"Hello, world!"
+"Тимур \"Каштан\" Бадтрудинов" ; экранировать двойную кавычку обратным слешом
+
+;;; Строки можно соединять
+
+(concatenate 'string "ПРивет, " "мир!") ; => "ПРивет, мир!"
+
+;;; Можно пройтись по строке как по массиву символов
+
+(elt "Apple" 0) ; => #\A
+
+;;; Для форматированного вывода используется FORMAT. Он умеет выводить, как просто значения,
+;;; так и производить циклы и учитывать условия. Первый агрумент указывает куда отправить
+;;; результат. Если NIL, FORMAT вернет результат как строку, если T результат отправиться
+;;; консоль вывода а форма вернет NIL.
+
+(format nil "~A, ~A!" "Привет" "мир") ; => "Привет, мир!"
+(format t "~A, ~A!" "Привет" "мир") ; => NIL
+
+
+;;;-----------------------------------------------------------------------------
+;;; 2. Переменные
+;;;-----------------------------------------------------------------------------
+
+;;; С помощью DEFVAR и DEFPARAMETER вы можете создать глобальную (динамческой видимости)
+;;; переменную.
+;;; Имя переменной может состоять из любых символов кроме: ()",'`;#|\
+
+;;; Разница между DEFVAR и DEFPARAMETER в том, что повторное выполнение DEFVAR
+;;; переменную не поменяет. А вот DEFPARAMETER меняет переменную при каждом вызове.
+
+;;; Обычно глобальные (динамически видимые) переменные содержат звездочки в имени.
+
+(defparameter *some-var* 5)
+*some-var* ; => 5
+
+;;; Можете использовать unicode.
+(defparameter *КУКУ* nil)
+
+;;; Доступ к необъявленной переменной - это непредсказуемое поведение. Не делайте так.
+
+;;; С помощью LET можете сделать локальное связывание.
+;;; В следующем куске кода, `я` связывается с "танцую с тобой" только
+;;; внутри формы (let ...). LET всегда возвращает значение последней формы.
+
+(let ((я "танцую с тобой")) я) ; => "танцую с тобой"
+
+
+;;;-----------------------------------------------------------------------------;
+;;; 3. Структуры и коллекции
+;;;-----------------------------------------------------------------------------;
+
+
+;;; Структуры
+
+(defstruct dog name breed age)
+(defparameter *rover*
+ (make-dog :name "rover"
+ :breed "collie"
+ :age 5))
+*rover* ; => #S(DOG :NAME "rover" :BREED "collie" :AGE 5)
+(dog-p *rover*) ; => T
+(dog-name *rover*) ; => "rover"
+
+;;; DEFSTRUCT автоматически создала DOG-P, MAKE-DOG, и DOG-NAME
+
+
+;;; Пары (cons-ячейки)
+
+;;; CONS создаёт пары. CAR и CDR возвращают начало и конец CONS-пары.
+
+(cons 'SUBJECT 'VERB) ; => '(SUBJECT . VERB)
+(car (cons 'SUBJECT 'VERB)) ; => SUBJECT
+(cdr (cons 'SUBJECT 'VERB)) ; => VERB
+
+
+;;; Списки
+
+;;; Списки это связанные CONS-пары, в конце самой последней из которых стоит NIL
+;;; (или '() ).
+
+(cons 1 (cons 2 (cons 3 nil))) ; => '(1 2 3)
+
+;;; Списки с произвольным количеством элементов удобно создавать с помощью LIST
+
+(list 1 2 3) ; => '(1 2 3)
+
+;;; Если первый аргумент для CONS это атом и второй аргумент список, CONS
+;;; возвращает новую CONS-пару, которая представляет собой список
+
+(cons 4 '(1 2 3)) ; => '(4 1 2 3)
+
+;;; Чтобы объединить списки, используйте APPEND
+
+(append '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;;; Или CONCATENATE
+
+(concatenate 'list '(1 2) '(3 4)) ; => '(1 2 3 4)
+
+;;; Списки это самый используемый элемент языка. Поэтому с ними можно делать
+;;; многие вещи. Вот несколько примеров:
+
+(mapcar #'1+ '(1 2 3)) ; => '(2 3 4)
+(mapcar #'+ '(1 2 3) '(10 20 30)) ; => '(11 22 33)
+(remove-if-not #'evenp '(1 2 3 4)) ; => '(2 4)
+(every #'evenp '(1 2 3 4)) ; => NIL
+(some #'oddp '(1 2 3 4)) ; => T
+(butlast '(subject verb object)) ; => (SUBJECT VERB)
+
+
+;;; Вектора
+
+;;; Вектора заданные прямо в коде - это массивы с фиксированной длинной.
+
+#(1 2 3) ; => #(1 2 3)
+
+;;; Для соединения векторов используйте CONCATENATE
+
+(concatenate 'vector #(1 2 3) #(4 5 6)) ; => #(1 2 3 4 5 6)
+
+
+;;; Массивы
+
+;;; И вектора и строки это подмножества массивов.
+
+;;; Двухмерные массивы
+
+(make-array (list 2 2)) ; => #2A((0 0) (0 0))
+(make-array '(2 2)) ; => #2A((0 0) (0 0))
+(make-array (list 2 2 2)) ; => #3A(((0 0) (0 0)) ((0 0) (0 0)))
+
+;;; Внимание: значение по-умолчанию элемента массива зависит от реализации.
+;;; Лучше явно указывайте:
+
+(make-array '(2) :initial-element 'unset) ; => #(UNSET UNSET)
+
+;;; Для доступа к элементу в позиции 1, 1, 1:
+
+(aref (make-array (list 2 2 2)) 1 1 1) ; => 0
+
+
+;;; Вектора с изменяемой длиной
+
+;;; Вектора с изменяемой длиной при выводе на консоль выглядят также,
+;;; как и вектора, с константной длиной
+
+(defparameter *adjvec* (make-array '(3) :initial-contents '(1 2 3)
+ :adjustable t :fill-pointer t))
+*adjvec* ; => #(1 2 3)
+
+;;; Добавление новых элементов
+
+(vector-push-extend 4 *adjvec*) ; => 3
+*adjvec* ; => #(1 2 3 4)
+
+
+;;; Множества, это просто списки:
+
+(set-difference '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1)
+(intersection '(1 2 3 4) '(4 5 6 7)) ; => 4
+(union '(1 2 3 4) '(4 5 6 7)) ; => (3 2 1 4 5 6 7)
+(adjoin 4 '(1 2 3 4)) ; => (1 2 3 4)
+
+;;; Несмотря на все, для действительно больших объемов данных, вам нужно что-то
+;;; лучше, чем просто связанные списки
+
+;;; Словари представлены хеш таблицами.
+
+;;; Создание хеш таблицы:
+
+(defparameter *m* (make-hash-table))
+
+;;; Установка пары ключ-значение
+
+(setf (gethash 'a *m*) 1)
+
+;;; Возврат значения по ключу
+
+(gethash 'a *m*) ; => 1, T
+
+;;; CL выражения умеют возвращать сразу несколько значений.
+
+(values 1 2) ; => 1, 2
+
+;;; которые могут быть распределены по переменным с помощью MULTIPLE-VALUE-BIND
+
+(multiple-value-bind (x y)
+ (values 1 2)
+ (list y x))
+
+; => '(2 1)
+
+;;; GETHASH как раз та функция, которая возвращает несколько значений. Первое
+;;; значение - это значение по ключу в хеш таблицу. Если ключ не был найден,
+;;; возвращает NIL.
+
+;;; Второе возвращаемое значение, указывает был ли ключ в хеш таблице. Если ключа
+;;; не было, то возвращает NIL. Таким образом можно проверить, это значение
+;;; NIL, или ключа просто не было.
+
+;;; Вот возврат значений, в случае когда ключа в хеш таблице не было:
+
+(gethash 'd *m*) ;=> NIL, NIL
+
+;;; Можете задать значение по умолчанию.
+
+(gethash 'd *m* :not-found) ; => :NOT-FOUND
+
+;;; Давайте обработаем возврат несколько значений.
+
+(multiple-value-bind (a b)
+ (gethash 'd *m*)
+ (list a b))
+; => (NIL NIL)
+
+(multiple-value-bind (a b)
+ (gethash 'a *m*)
+ (list a b))
+; => (1 T)
+
+
+;;;-----------------------------------------------------------------------------
+;;; 3. Функции
+;;;-----------------------------------------------------------------------------
+
+;;; Для создания анонимных функций используйте LAMBDA. Функций всегда возвращают
+;;; значение последнего своего выражения. Как выглядит функция при выводе в консоль
+;;; зависит от реализации.
+
+(lambda () "Привет Мир") ; => #<FUNCTION (LAMBDA ()) {1004E7818B}>
+
+;;; Для вызова анонимной функции пользуйтесь FUNCALL
+
+(funcall (lambda () "Привет Мир")) ; => "Привет мир"
+(funcall #'+ 1 2 3) ; => 6
+
+;;; FUNCALL сработает и тогда, когда анонимная функция стоит в начале
+;;; неэкранированного списка
+
+((lambda () "Привет Мир")) ; => "Привет Мир"
+((lambda (val) val) "Привет Мир") ; => "Привет Мир"
+
+;;; FUNCALL используется, когда аргументы заранее известны.
+;;; В противном случае используйте APPLY
+
+(apply #'+ '(1 2 3)) ; => 6
+(apply (lambda () "Привет Мир") nil) ; => "Привет Мир"
+
+;;; Для обычной функции с именем используйте DEFUN
+
+(defun hello-world () "Привет Мир")
+(hello-world) ; => "Привет Мир"
+
+;;; Выше видно пустой список (), это место для определения аргументов
+
+(defun hello (name) (format nil "Hello, ~A" name))
+(hello "Григорий") ; => "Привет, Григорий"
+
+;;; Можно указать необязательные аргументы. По умолчанию они будут NIL
+
+(defun hello (name &optional from)
+ (if from
+ (format t "Приветствие для ~A от ~A" name from)
+ (format t "Привет, ~A" name)))
+
+(hello "Георгия" "Василия") ; => Приветствие для Георгия от Василия
+
+;;; Можно явно задать значения по умолчанию
+
+(defun hello (name &optional (from "Мира"))
+ (format nil "Приветствие для ~A от ~A" name from))
+
+(hello "Жоры") ; => Приветствие для Жоры от Мира
+(hello "Жоры" "альпаки") ; => Приветствие для Жоры от альпаки
+
+;;; Можно также задать именованные параметры
+
+(defun generalized-greeter (name &key (from "Мира") (honorific "Господин"))
+ (format t "Здравствуйте, ~A ~A, от ~A" honorific name from))
+
+(generalized-greeter "Григорий")
+; => Здравствуйте, Господин Григорий, от Мира
+
+(generalized-greeter "Григорий" :from "альпаки" :honorific "гражданин")
+; => Здравствуйте, Гражданин Григорий, от альпаки
+
+
+;;;-----------------------------------------------------------------------------
+;;; 4. Равенство или эквивалентность
+;;;-----------------------------------------------------------------------------
+
+;;; У CL сложная система эквивалентности. Взглянем одним глазом.
+
+;;; Для чисел используйте `='
+(= 3 3.0) ; => T
+(= 2 1) ; => NIL
+
+;;; Для идентичености объектов используйте EQL
+(eql 3 3) ; => T
+(eql 3 3.0) ; => NIL
+(eql (list 3) (list 3)) ; => NIL
+
+;;; Для списков, строк, и битовых векторов - EQUAL
+(equal (list 'a 'b) (list 'a 'b)) ; => T
+(equal (list 'a 'b) (list 'b 'a)) ; => NIL
+
+
+;;;-----------------------------------------------------------------------------
+;;; 5. Циклы и ветвления
+;;;-----------------------------------------------------------------------------
+
+;;; Ветвления
+
+(if t ; проверямое значение
+ "случилась истина" ; если, оно было истинно
+ "случилась ложь") ; иначе, когда оно было ложно
+; => "случилась истина"
+
+;;; В форме ветвления if, все не-NIL значения это `истина`
+
+(member 'Groucho '(Harpo Groucho Zeppo)) ; => '(GROUCHO ZEPPO)
+(if (member 'Groucho '(Harpo Groucho Zeppo))
+ 'yep
+ 'nope)
+; => 'YEP
+
+;;; COND это цепочка проверок для нахождения искомого
+(cond ((> 2 2) (error "мимо!"))
+ ((< 2 2) (error "опять мимо!"))
+ (t 'ok)) ; => 'OK
+
+;;; TYPECASE выбирает ветку исходя из типа выражения
+(typecase 1
+ (string :string)
+ (integer :int))
+; => :int
+
+
+;;; Циклы
+
+;;; С рекурсией
+
+(defun fact (n)
+ (if (< n 2)
+ 1
+ (* n (fact(- n 1)))))
+
+(fact 5) ; => 120
+
+;;; И без
+
+(defun fact (n)
+ (loop :for result = 1 :then (* result i)
+ :for i :from 2 :to n
+ :finally (return result)))
+
+(fact 5) ; => 120
+
+(loop :for x :across "abc" :collect x)
+; => (#\a #\b #\c #\d)
+
+(dolist (i '(1 2 3 4))
+ (format t "~A" i))
+; => 1234
+
+
+;;;-----------------------------------------------------------------------------
+;;; 6. Установка значений в переменные (и не только)
+;;;-----------------------------------------------------------------------------
+
+;;; Для присвоения переменной нового значения используйте SETF. Это уже было
+;;; при работе с хеш таблицами.
+
+(let ((variable 10))
+ (setf variable 2))
+; => 2
+
+;;; Для функционального подхода в программировании, старайтесь избегать измений
+;;; в переменных.
+
+;;;-----------------------------------------------------------------------------
+;;; 7. Классы и объекты
+;;;-----------------------------------------------------------------------------
+
+;;; Никаких больше животных в примерах. Берем устройства приводимые в движение
+;;; мускульной силой человека.
+
+(defclass human-powered-conveyance ()
+ ((velocity
+ :accessor velocity
+ :initarg :velocity)
+ (average-efficiency
+ :accessor average-efficiency
+ :initarg :average-efficiency))
+ (:documentation "Устройство движимое человеческой силой"))
+
+;;; Аргументы DEFCLASS:
+;;; 1. Имя класса
+;;; 2. Список родительских классов
+;;; 3. Список полей
+;;; 4. Необязательная метаинформация
+
+;;; Если родительские классы не заданы, используется "стандартный" класс
+;;; Это можно *изменить*, но хорошенько подумайте прежде. Если все-таки
+;;; решились вам поможет "Art of the Metaobject Protocol"
+
+(defclass bicycle (human-powered-conveyance)
+ ((wheel-size
+ :accessor wheel-size
+ :initarg :wheel-size
+ :documentation "Diameter of the wheel.")
+ (height
+ :accessor height
+ :initarg :height)))
+
+(defclass recumbent (bicycle)
+ ((chain-type
+ :accessor chain-type
+ :initarg :chain-type)))
+
+(defclass unicycle (human-powered-conveyance) nil)
+
+(defclass canoe (human-powered-conveyance)
+ ((number-of-rowers
+ :accessor number-of-rowers
+ :initarg :number-of-rowers)))
+
+;;; Если вызвать DESCRIBE для HUMAN-POWERED-CONVEYANCE то получите следующее:
+
+(describe 'human-powered-conveyance)
+
+; COMMON-LISP-USER::HUMAN-POWERED-CONVEYANCE
+; [symbol]
+;
+; HUMAN-POWERED-CONVEYANCE names the standard-class #<STANDARD-CLASS
+; HUMAN-POWERED-CONVEYANCE>:
+; Documentation:
+; A human powered conveyance
+; Direct superclasses: STANDARD-OBJECT
+; Direct subclasses: UNICYCLE, BICYCLE, CANOE
+; Not yet finalized.
+; Direct slots:
+; VELOCITY
+; Readers: VELOCITY
+; Writers: (SETF VELOCITY)
+; AVERAGE-EFFICIENCY
+; Readers: AVERAGE-EFFICIENCY
+; Writers: (SETF AVERAGE-EFFICIENCY)
+
+;;; CL задизайнен как интерактивная система. В рантайме доступна информация о
+;;; типе объектов.
+
+;;; Давайте посчитаем расстояние, которое пройдет велосипед за один оборот колеса
+;;; по формуле C = d * pi
+
+(defmethod circumference ((object bicycle))
+ (* pi (wheel-size object)))
+
+;;; PI - это константа в CL
+
+;;; Предположим мы нашли, что критерий эффективности логарифмически связан
+;;; с гребцами каноэ. Тогда вычисление можем сделать сразу при инициализации.
+
+;;; Инициализируем объект после его создания:
+
+(defmethod initialize-instance :after ((object canoe) &rest args)
+ (setf (average-efficiency object) (log (1+ (number-of-rowers object)))))
+
+
+;;; Давайте проверим что получилось с этой самой эффективностью...
+
+(average-efficiency (make-instance 'canoe :number-of-rowers 15))
+; => 2.7725887
+
+
+;;;-----------------------------------------------------------------------------
+;;; 8. Макросы
+;;;-----------------------------------------------------------------------------
+
+;;; Макросы позволяют расширить синаксис языка. В CL нет например цикла WHILE,
+;;; но его проще простого реализовать на макросах. Если мы отбросим наши
+;;; ассемблерные (или алгольные) инстинкты, мы взлетим на крыльях:
+
+(defmacro while (condition &body body)
+ "Пока `условие` истинно, выполняется `тело`.
+`Условие` проверяется перед каждым выполнением `тела`"
+ (let ((block-name (gensym)) (done (gensym)))
+ `(tagbody
+ ,block-name
+ (unless ,condition
+ (go ,done))
+ (progn
+ ,@body)
+ (go ,block-name)
+ ,done)))
+
+;;; Взглянем на более высокоуровневую версию этого макроса:
+
+(defmacro while (condition &body body)
+ "Пока `условие` истинно, выполняется `тело`.
+`Условие` проверяется перед каждым выполнением `тела`"
+ `(loop while ,condition
+ do
+ (progn
+ ,@body)))
+
+;;; В современных комиляторах LOOP так же эффективен как и приведенный
+;;; выше код. Поэтому используйте его, его проще читать.
+
+;;; В макросах используются символы ```, `,` и `@`. ``` - это оператор
+;;; квазиквотирования - это значит что форма исполнятся не будет, а вернется
+;;; как данные. Оператаор `,` позволяет исполнить форму внутри
+;;; квазиквотирования. Оператор `@` исполняет форму внутри квазиквотирования
+;;; но полученный список вклеивает по месту.
+
+;;; GENSYM создаёт уникальный символ, который гарантировано больше нигде в
+;;; системе не используется. Так надо потому, что макросы разворачиваются
+;;; во время компиляции и переменные объявленные в макросе могут совпасть
+;;; по имени с переменными в обычном коде.
+
+;;; Дальнйешую информацию о макросах ищите в книгах Practical Common Lisp
+;;; и On Lisp
+```
+
+## Для чтения
+
+На русском
+- [Practical Common Lisp](http://www.gigamonkeys.com/book/)
+
+На английском
+- [Practical Common Lisp](http://www.gigamonkeys.com/book/)
+- [Common Lisp: A Gentle Introduction to Symbolic Computation](https://www.cs.cmu.edu/~dst/LispBook/book.pdf)
+
+
+## Дополнительная информация
+
+На русском
+
+- [Lisper.ru](http://lisper.ru/)
+
+На английском
+
+- [CLiki](http://www.cliki.net/)
+- [common-lisp.net](https://common-lisp.net/)
+- [Awesome Common Lisp](https://github.com/CodyReichert/awesome-cl)
+- [Lisp Lang](http://lisp-lang.org/)
+
+
+## Благодарности в английской версии
+
+Спасибо людям из Scheme за отличную статью, взятую за основу для
+Common Lisp.
+
+
+- [Paul Khuong](https://github.com/pkhuong) за хорошую вычитку.
diff --git a/ru-ru/crystal-ru.html.markdown b/ru-ru/crystal-ru.html.markdown
new file mode 100644
index 00000000..87d12f23
--- /dev/null
+++ b/ru-ru/crystal-ru.html.markdown
@@ -0,0 +1,584 @@
+---
+language: crystal
+filename: learncrystal-ru.cr
+contributors:
+ - ["Vitalii Elenhaupt", "http://veelenga.com"]
+ - ["Arnaud Fernandés", "https://github.com/TechMagister/"]
+translators:
+ - ["Den Patin", "https://github.com/denpatin"]
+lang: ru-ru
+---
+
+```crystal
+# — так начинается комментарий
+
+
+# Всё является объектом
+nil.class #=> Nil
+100.class #=> Int32
+true.class #=> Bool
+
+# Возвращают false только nil, false и пустые указатели
+!nil #=> true : Bool
+!false #=> true : Bool
+!0 #=> false : Bool
+
+
+# Целые числа
+
+1.class #=> Int32
+
+# Четыре типа целых чисел со знаком
+1_i8.class #=> Int8
+1_i16.class #=> Int16
+1_i32.class #=> Int32
+1_i64.class #=> Int64
+
+# Четыре типа целых чисел без знака
+1_u8.class #=> UInt8
+1_u16.class #=> UInt16
+1_u32.class #=> UInt32
+1_u64.class #=> UInt64
+
+2147483648.class #=> Int64
+9223372036854775808.class #=> UInt64
+
+# Двоичные числа
+0b1101 #=> 13 : Int32
+
+# Восьмеричные числа
+0o123 #=> 83 : Int32
+
+# Шестнадцатеричные числа
+0xFE012D #=> 16646445 : Int32
+0xfe012d #=> 16646445 : Int32
+
+# Числа с плавающей точкой
+
+1.0.class #=> Float64
+
+# Два типа чисел с плавающей запятой
+1.0_f32.class #=> Float32
+1_f32.class #=> Float32
+
+1e10.class #=> Float64
+1.5e10.class #=> Float64
+1.5e-7.class #=> Float64
+
+
+# Символьные литералы
+
+'a'.class #=> Char
+
+# Восьмеричный код символа
+'\101' #=> 'A' : Char
+
+# Код символа Unicode
+'\u0041' #=> 'A' : Char
+
+
+# Строки
+
+"s".class #=> String
+
+# Строки неизменяемы
+s = "hello, " #=> "hello, " : String
+s.object_id #=> 134667712 : UInt64
+s += "Crystal" #=> "hello, Crystal" : String
+s.object_id #=> 142528472 : UInt64
+
+# Поддерживается интерполяция строк
+"sum = #{1 + 2}" #=> "sum = 3" : String
+
+# Поддерживается многострочность
+"This is
+ multiline string"
+
+# Строка с двойными кавычками
+%(hello "world") #=> "hello \"world\""
+
+
+# Символы — константы без значения, определяемые только именем. Часто
+# используются вместо часто используемых строк для лучшей производительности.
+# На внутреннем уровне они представлены как Int32.
+
+:symbol.class #=> Symbol
+
+sentence = :question? # :"question?" : Symbol
+
+sentence == :question? #=> true : Bool
+sentence == :exclamation! #=> false : Bool
+sentence == "question?" #=> false : Bool
+
+
+# Массивы
+
+[1, 2, 3].class #=> Array(Int32)
+[1, "hello", 'x'].class #=> Array(Int32 | String | Char)
+
+# При объявлении пустого массива необходимо указать тип его элементов
+[] # Syntax error: for empty arrays use '[] of ElementType'
+[] of Int32 #=> [] : Array(Int32)
+Array(Int32).new #=> [] : Array(Int32)
+
+# Элементы внутри массива имеют свои индексы
+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)
+
+# Можно получать элементы по индексу с конца
+array[-1] #=> 5
+
+# С начала и с указанием размера итогового массива
+array[2, 3] #=> [3, 4, 5]
+
+# Или посредством указания диапазона
+array[1..3] #=> [2, 3, 4]
+
+# Добавление в массив
+array << 6 #=> [1, 2, 3, 4, 5, 6]
+
+# Удаление элемента из конца массива
+array.pop #=> 6
+array #=> [1, 2, 3, 4, 5]
+
+# Удаление элемента из начала массива
+array.shift #=> 1
+array #=> [2, 3, 4, 5]
+
+# Проверка на наличие элемента в массиве
+array.includes? 3 #=> true
+
+# Синтаксический сахар для массива строк и символов
+%w(one two three) #=> ["one", "two", "three"] : Array(String)
+%i(one two three) #=> [:one, :two, :three] : Array(Symbol)
+
+# Массивоподобный синтаксис используется и для других типов, только если для
+# них определены методы .new и #<<
+set = Set{1, 2, 3} #=> [1, 2, 3]
+set.class #=> Set(Int32)
+
+# Вышеприведенное эквивалентно следующему
+set = Set(typeof(1, 2, 3)).new
+set << 1
+set << 2
+set << 3
+
+
+# Хэши
+
+{1 => 2, 3 => 4}.class #=> Hash(Int32, Int32)
+{1 => 2, 'a' => 3}.class #=> Hash(Int32 | Char, Int32)
+
+# При объявлении пустого хэша необходимо указать типы ключа и значения
+{} # Syntax error
+{} of Int32 => Int32 # {}
+Hash(Int32, Int32).new # {}
+
+# Значения в хэше легко найти по ключу
+hash = {"color" => "green", "number" => 5}
+hash["color"] #=> "green"
+hash["no_such_key"] #=> Missing hash key: "no_such_key" (KeyError)
+hash["no_such_key"]? #=> nil
+
+# Проверка наличия ключа в хэше
+hash.has_key? "color" #=> true
+
+# Синтаксический сахар для символьных и строковых ключей
+{key1: 'a', key2: 'b'} # {:key1 => 'a', :key2 => 'b'}
+{"key1": 'a', "key2": 'b'} # {"key1" => 'a', "key2" => 'b'}
+
+# Хэшеподобный синтаксис используется и для других типов, только если для них
+# определены методы .new и #[]=
+class MyType
+ def []=(key, value)
+ puts "do stuff"
+ end
+end
+
+MyType{"foo" => "bar"}
+
+# Вышеприведенное эквивалентно следующему
+tmp = MyType.new
+tmp["foo"] = "bar"
+tmp
+
+
+# Диапазоны
+
+1..10 #=> Range(Int32, Int32)
+Range.new(1, 10).class #=> Range(Int32, Int32)
+
+# Включающий и исключающий диапазоны
+(3..5).to_a #=> [3, 4, 5]
+(3...5).to_a #=> [3, 4]
+
+# Проверка на вхождение в диапазон
+(1..8).includes? 2 #=> true
+
+
+# Кортежи
+# Неизменяемые последовательности фиксированного размера, содержащие,
+# как правило, элементы разных типов
+
+{1, "hello", 'x'}.class #=> Tuple(Int32, String, Char)
+
+# Доступ к элементам осуществляется по индексу
+tuple = {:key1, :key2}
+tuple[1] #=> :key2
+tuple[2] #=> syntax error : Index out of bound
+
+# Элементы кортежей можно попарно присвоить переменным
+a, b, c = {:a, 'b', "c"}
+a #=> :a
+b #=> 'b'
+c #=> "c"
+
+
+# Процедуры
+# Указатели на функцию с необязательным содержимым (замыкание).
+# Обычно создаётся с помощью специального литерала ->
+
+proc = ->(x : Int32) { x.to_s }
+proc.class # Proc(Int32, String)
+# Или посредством метода .new
+Proc(Int32, String).new { |x| x.to_s }
+
+# Вызываются посредством метода .call
+proc.call 10 #=> "10"
+
+
+# Управляющие операторы
+
+if true
+ "if statement"
+elsif false
+ "else-if, optional"
+else
+ "else, also optional"
+end
+
+puts "if as a suffix" if true
+
+# if как часть выражения
+a = if 2 > 1
+ 3
+ else
+ 4
+ end
+
+a #=> 3
+
+# Тернарный if
+a = 1 > 2 ? 3 : 4 #=> 4
+
+# Оператор выбора
+cmd = "move"
+
+action = case cmd
+ when "create"
+ "Creating..."
+ when "copy"
+ "Copying..."
+ when "move"
+ "Moving..."
+ when "delete"
+ "Deleting..."
+end
+
+action #=> "Moving..."
+
+
+# Циклы
+
+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
+
+# Но лучше использовать each
+(1..3).each do |index|
+ puts "Index: #{index}"
+end
+# Index: 1
+# Index: 2
+# Index: 3
+
+# Тип переменной зависит от типа выражения
+if a < 3
+ a = "hello"
+else
+ a = true
+end
+typeof a #=> (Bool | String)
+
+if a && b
+ # здесь гарантируется, что и a, и b — не nil
+end
+
+if a.is_a? String
+ a.class #=> String
+end
+
+
+# Методы
+
+def double(x)
+ x * 2
+end
+
+# Методы (а также любые блоки) всегда возвращают значение последнего выражения
+double(2) #=> 4
+
+# Скобки можно опускать, если вызов метода не вносит двусмысленности
+double 3 #=> 6
+
+double double 3 #=> 12
+
+def sum(x, y)
+ x + y
+end
+
+# Параметры методов перечисляются через запятую
+sum 3, 4 #=> 7
+
+sum sum(3, 4), 5 #=> 12
+
+
+# yield
+
+# У всех методов есть неявный необязательный параметр блока, который можно
+# вызвать ключевым словом yield
+
+def surround
+ puts '{'
+ yield
+ puts '}'
+end
+
+surround { puts "hello world" }
+
+# {
+# hello world
+# }
+
+# Методу можно передать блок
+# & — ссылка на переданный блок
+def guests(&block)
+ block.call "some_argument"
+end
+
+# Методу можно передать список параметров, доступ к ним будет как к массиву
+# Для этого используется оператор *
+def guests(*array)
+ array.each { |guest| puts guest }
+end
+
+# Если метод возвращает массив, можно попарно присвоить значение каждого из его
+# элементов переменным
+def foods
+ ["pancake", "sandwich", "quesadilla"]
+end
+breakfast, lunch, dinner = foods
+breakfast #=> "pancake"
+dinner #=> "quesadilla"
+
+# По соглашению название методов, возвращающих булево значение, должно
+# оканчиваться вопросительным знаком
+5.even? # false
+5.odd? # true
+
+# Если название метода оканчивается восклицательным знаком, по соглашению это
+# означает, что метод делает что-то необратимое, например изменяет получателя.
+# Некоторые методы имеют две версии: "опасную" версию с !, которая что-то
+# меняет, и "безопасную", которая просто возвращает новое значение
+company_name = "Dunder Mifflin"
+company_name.gsub "Dunder", "Donald" #=> "Donald Mifflin"
+company_name #=> "Dunder Mifflin"
+company_name.gsub! "Dunder", "Donald"
+company_name #=> "Donald Mifflin"
+
+
+# Классы
+# Определяются с помощью ключевого слова class
+
+class Human
+
+ # Переменная класса является общей для всех экземпляров этого класса
+ @@species = "H. sapiens"
+
+ # Объявление типа переменной name экземпляра класса
+ @name : String
+
+ # Базовый конструктор
+ # Значением первого параметра инициализируем переменную @name.
+ # То же делаем и со вторым параметром — переменная @age. В случае, если мы
+ # не передаём второй параметр, для инициализации @age будет взято значение
+ # по умолчанию (в данном случае — 0)
+ def initialize(@name, @age = 0)
+ end
+
+ # Базовый метод установки значения переменной
+ def name=(name)
+ @name = name
+ end
+
+ # Базовый метод получения значения переменной
+ def name
+ @name
+ end
+
+ # Синтаксический сахар одновременно для двух методов выше
+ property :name
+
+ # А также по отдельности
+ getter :name
+ setter :name
+
+ # Метод класса определяется ключевым словом self, чтобы его можно было
+ # различить с методом экземпляра класса. Такой метод можно вызвать только
+ # на уровне класса, а не экземпляра.
+ def self.say(msg)
+ puts msg
+ end
+
+ def species
+ @@species
+ end
+end
+
+
+# Создание экземпляра класса
+jim = Human.new("Jim Halpert")
+
+dwight = Human.new("Dwight K. Schrute")
+
+# Вызов методов экземпляра класса
+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"
+
+# Вызов метода класса
+Human.say("Hi") #=> выведет "Hi" и вернёт nil
+
+# Переменные экземпляра класса (@) видно только в пределах экземпляра
+class TestClass
+ @var = "I'm an instance var"
+end
+
+# Переменные класса (@) видны как в экземплярах класса, так и в самом классе
+class TestClass
+ @@var = "I'm a class var"
+end
+
+# Переменные с большой буквы — это константы
+Var = "I'm a constant"
+Var = "can't be updated" # Error: already initialized constant Var
+
+# Примеры
+
+# Базовый класс
+class Human
+ @@foo = 0
+
+ def self.foo
+ @@foo
+ end
+
+ def self.foo=(value)
+ @@foo = value
+ end
+end
+
+# Класс-потомок
+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
+
+# Подключение модуля в класс добавляет его методы в экземпляр класса
+# Расширение модуля добавляет его методы в сам класс
+
+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
+
+
+# Обработка исключений
+
+# Создание пользовательского типа исключения
+class MyException < Exception
+end
+
+# Ещё одного
+class MyAnotherException < Exception; end
+
+ex = begin
+ raise MyException.new
+rescue ex1 : IndexError
+ "ex1"
+rescue ex2 : MyException | MyAnotherException
+ "ex2"
+rescue ex3 : Exception
+ "ex3"
+rescue ex4 # без указания конкретного типа исключения будут "отлавливаться" все
+ "ex4"
+end
+
+ex #=> "ex2"
+
+```
+
+## Дополнительная информация
+
+### На русском
+
+- [Официальная документация](http://ru.crystal-lang.org/docs/)
+
+### На английском
+
+- [Official Documentation](http://crystal-lang.org/)
diff --git a/ru-ru/css-ru.html.markdown b/ru-ru/css-ru.html.markdown
index 2e2d40b7..e0e5e30b 100644
--- a/ru-ru/css-ru.html.markdown
+++ b/ru-ru/css-ru.html.markdown
@@ -116,7 +116,7 @@ element:visited {}
/* или еще не проходил по ней */
element:link {}
-/* выбранное поле воода (input) */
+/* выбранное поле ввода (input) */
element:focus {}
@@ -132,7 +132,7 @@ selector {
width: 200px; /* пиксели */
font-size: 20pt; /* пункты */
width: 5cm; /* сантиметры */
- min-width: 50mm; /* милиметры */
+ min-width: 50mm; /* миллиметры */
max-width: 5in; /* дюймы */
height: 0.2vh; /* умножается на высоту окна браузера (CSS3) */
width: 0.4vw; /* умножается на ширину окна браузера (CSS3) */
@@ -235,7 +235,7 @@ p { property: value !important; }
## Совместимость
-Несмотря на то, что большая часть функций CSS2 (а также CSS3) подеррживается всеми
+Несмотря на то, что большая часть функций CSS2 (а также CSS3) поддерживается всеми
браузерами и устройствами, не забывайте проверять совместимость CSS-правил
с современными браузерами.
diff --git a/ru-ru/elixir-ru.html.markdown b/ru-ru/elixir-ru.html.markdown
new file mode 100644
index 00000000..c8c2c060
--- /dev/null
+++ b/ru-ru/elixir-ru.html.markdown
@@ -0,0 +1,467 @@
+---
+language: elixir
+contributors:
+ - ["Joao Marques", "http://github.com/mrshankly"]
+ - ["Dzianis Dashkevich", "https://github.com/dskecse"]
+ - ["Ryan Plant", "https://github.com/ryanplant-au"]
+translator:
+ - ["Ev Bogdanov", "https://github.com/evbogdanov"]
+filename: learnelixir-ru.ex
+lang: ru-ru
+---
+
+Elixir — современный функциональный язык программирования, который работает на
+виртуальной машине Erlang. Elixir полностью совместим с Erlang, но обладает
+дружелюбным синтаксисом и предлагает больше возможностей.
+
+```elixir
+
+# Однострочные комментарии начинаются с символа решётки.
+
+# Для многострочных комментариев отдельного синтаксиса нет,
+# поэтому просто используйте несколько однострочных комментариев.
+
+# Запустить интерактивную Elixir-консоль (аналог `irb` в Ruby) можно
+# при помощи команды `iex`.
+# Чтобы скомпилировать модуль, воспользуйтесь командой `elixirc`.
+
+# Обе команды будут работать из терминала, если вы правильно установили Elixir.
+
+## ---------------------------
+## -- Базовые типы
+## ---------------------------
+
+# Числа
+3 # целое число
+0x1F # целое число
+3.0 # число с плавающей запятой
+
+# Атомы, которые являются нечисловыми константами. Они начинаются с символа `:`.
+:hello # атом
+
+# Кортежи, которые хранятся в памяти последовательно.
+{1,2,3} # кортеж
+
+# Получить доступ к элементу кортежа мы можем с помощью функции `elem`:
+elem({1, 2, 3}, 0) #=> 1
+
+# Списки, которые реализованы как связные списки.
+[1,2,3] # список
+
+# У каждого непустого списка есть голова (первый элемент списка)
+# и хвост (все остальные элементы списка):
+[head | tail] = [1,2,3]
+head #=> 1
+tail #=> [2,3]
+
+# В Elixir, как и в Erlang, знак `=` служит для сопоставления с образцом,
+# а не для операции присваивания.
+#
+# Это означает, что выражение слева от знака `=` (образец) сопоставляется с
+# выражением справа.
+#
+# Сопоставление с образцом позволило нам получить голову и хвост списка
+# в примере выше.
+
+# Если выражения слева и справа от знака `=` не удаётся сопоставить, будет
+# брошена ошибка. Например, если кортежи разных размеров.
+{a, b, c} = {1, 2} #=> ** (MatchError)
+
+# Бинарные данные
+<<1,2,3>>
+
+# Вы столкнётесь с двумя видами строк:
+"hello" # Elixir-строка (заключена в двойные кавычки)
+'hello' # Erlang-строка (заключена в одинарные кавычки)
+
+# Все строки представлены в кодировке UTF-8:
+"привет" #=> "привет"
+
+# Многострочный текст
+"""
+Я текст на несколько
+строк.
+"""
+#=> "Я текст на несколько\nстрок.\n"
+
+# Чем Elixir-строки отличаются от Erlang-строк? Elixir-строки являются бинарными
+# данными.
+<<?a, ?b, ?c>> #=> "abc"
+# Erlang-строка — это на самом деле список.
+[?a, ?b, ?c] #=> 'abc'
+
+# Оператор `?` возвращает целое число, соответствующее данному символу.
+?a #=> 97
+
+# Для объединения бинарных данных (и Elixir-строк) используйте `<>`
+<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
+"hello " <> "world" #=> "hello world"
+
+# Для объединения списков (и Erlang-строк) используйте `++`
+[1,2,3] ++ [4,5] #=> [1,2,3,4,5]
+'hello ' ++ 'world' #=> 'hello world'
+
+# Диапазоны записываются как `начало..конец` (оба включительно)
+1..10 #=> 1..10
+
+# Сопоставление с образцом применимо и для диапазонов:
+lower..upper = 1..10
+[lower, upper] #=> [1, 10]
+
+# Карты (известны вам по другим языкам как ассоциативные массивы, словари, хэши)
+genders = %{"david" => "male", "gillian" => "female"}
+genders["david"] #=> "male"
+
+# Для карт, где ключами выступают атомы, доступен специальный синтаксис
+genders = %{david: "male", gillian: "female"}
+genders.gillian #=> "female"
+
+## ---------------------------
+## -- Операторы
+## ---------------------------
+
+# Математические операции
+1 + 1 #=> 2
+10 - 5 #=> 5
+5 * 2 #=> 10
+10 / 2 #=> 5.0
+
+# В Elixir оператор `/` всегда возвращает число с плавающей запятой.
+
+# Для целочисленного деления применяйте `div`
+div(10, 2) #=> 5
+
+# Для получения остатка от деления к вашим услугам `rem`
+rem(10, 3) #=> 1
+
+# Булевые операторы: `or`, `and`, `not`.
+# В качестве первого аргумента эти операторы ожидают булевое значение.
+true and true #=> true
+false or true #=> true
+1 and true #=> ** (BadBooleanError)
+
+# Elixir также предоставляет `||`, `&&` и `!`, которые принимают аргументы
+# любого типа. Всё, кроме `false` и `nil`, считается `true`.
+1 || true #=> 1
+false && 1 #=> false
+nil && 20 #=> nil
+!true #=> false
+
+# Операторы сравнения: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<`, `>`
+1 == 1 #=> true
+1 != 1 #=> false
+1 < 2 #=> true
+
+# Операторы `===` и `!==` более строгие. Разница заметна, когда мы сравниваем
+# числа целые и с плавающей запятой:
+1 == 1.0 #=> true
+1 === 1.0 #=> false
+
+# Elixir позволяет сравнивать значения разных типов:
+1 < :hello #=> true
+
+# При сравнении разных типов руководствуйтесь следующим правилом:
+# число < атом < ссылка < функция < порт < процесс < кортеж < список < строка
+
+## ---------------------------
+## -- Порядок выполнения
+## ---------------------------
+
+# Условный оператор `if`
+if false do
+ "Вы этого никогда не увидите"
+else
+ "Вы увидите это"
+end
+
+# Противоположный ему условный оператор `unless`
+unless true do
+ "Вы этого никогда не увидите"
+else
+ "Вы увидите это"
+end
+
+# Помните сопоставление с образцом?
+# Многие конструкции в Elixir построены вокруг него.
+
+# `case` позволяет сравнить выражение с несколькими образцами:
+case {:one, :two} do
+ {:four, :five} ->
+ "Этот образец не совпадёт"
+ {:one, x} ->
+ "Этот образец совпадёт и присвоит переменной `x` значение `:two`"
+ _ ->
+ "Этот образец совпадёт с чем угодно"
+end
+
+# Символ `_` называется анонимной переменной. Используйте `_` для значений,
+# которые в текущем выражении вас не интересуют. Например, вам интересна лишь
+# голова списка, а хвост вы желаете проигнорировать:
+[head | _] = [1,2,3]
+head #=> 1
+
+# Для лучшей читаемости вы можете написать:
+[head | _tail] = [:a, :b, :c]
+head #=> :a
+
+# `cond` позволяет проверить сразу несколько условий за раз.
+# Используйте `cond` вместо множественных операторов `if`.
+cond do
+ 1 + 1 == 3 ->
+ "Вы меня никогда не увидите"
+ 2 * 5 == 12 ->
+ "И меня"
+ 1 + 2 == 3 ->
+ "Вы увидите меня"
+end
+
+# Обычно последним условием идёт `true`, которое выполнится, если все предыдущие
+# условия оказались ложны.
+cond do
+ 1 + 1 == 3 ->
+ "Вы меня никогда не увидите"
+ 2 * 5 == 12 ->
+ "И меня"
+ true ->
+ "Вы увидите меня (по сути, это `else`)"
+end
+
+# Обработка ошибок происходит в блоках `try/catch`.
+# Elixir также поддерживает блок `after`, который выполнится в любом случае.
+try do
+ throw(:hello)
+catch
+ message -> "Поймана ошибка с сообщением #{message}."
+after
+ IO.puts("Я выполнюсь всегда")
+end
+#=> Я выполнюсь всегда
+# "Поймана ошибка с сообщением hello."
+
+## ---------------------------
+## -- Модули и функции
+## ---------------------------
+
+# Анонимные функции (обратите внимание на точку при вызове функции)
+square = fn(x) -> x * x end
+square.(5) #=> 25
+
+# Анонимные функции принимают клозы и гарды.
+#
+# Клозы (от англ. clause) — варианты исполнения функции.
+#
+# Гарды (от англ. guard) — охранные выражения, уточняющие сопоставление с
+# образцом в функциях. Гарды следуют после ключевого слова `when`.
+f = fn
+ x, y when x > 0 -> x + y
+ x, y -> x * y
+end
+
+f.(1, 3) #=> 4
+f.(-1, 3) #=> -3
+
+# В Elixir много встроенных функций.
+# Они доступны в текущей области видимости.
+is_number(10) #=> true
+is_list("hello") #=> false
+elem({1,2,3}, 0) #=> 1
+
+# Вы можете объединить несколько функций в модуль. Внутри модуля используйте `def`,
+# чтобы определить свои функции.
+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
+
+# Чтобы скомпилировать модуль Math, сохраните его в файле `math.ex`
+# и наберите в терминале: `elixirc math.ex`
+
+defmodule PrivateMath do
+ # Публичные функции начинаются с `def` и доступны из других модулей.
+ def sum(a, b) do
+ do_sum(a, b)
+ end
+
+ # Приватные функции начинаются с `defp` и доступны только внутри своего модуля.
+ defp do_sum(a, b) do
+ a + b
+ end
+end
+
+PrivateMath.sum(1, 2) #=> 3
+PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
+
+# Функции внутри модуля тоже принимают клозы и гарды
+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)
+
+# Из-за неизменяемых переменных в 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
+
+# Модули в Elixir поддерживают атрибуты.
+# Атрибуты бывают как встроенные, так и ваши собственные.
+defmodule MyMod do
+ @moduledoc """
+ Это встроенный атрибут
+ """
+
+ @my_data 100 # А это ваш атрибут
+ IO.inspect(@my_data) #=> 100
+end
+
+# Одна из фишек языка — оператор `|>`
+# Он передаёт выражение слева в качестве первого аргумента функции справа:
+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]
+
+## ---------------------------
+## -- Структуры и исключения
+## ---------------------------
+
+# Структуры — это расширения поверх карт, привносящие в 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"}
+
+# Доступ к полю структуры
+joe_info.name #=> "Joe"
+
+# Обновление поля структуры
+older_joe_info = %{ joe_info | age: 31 }
+#=> %Person{age: 31, height: 180, name: "Joe"}
+
+# Блок `try` с ключевым словом `rescue` используется для обработки исключений
+try do
+ raise "какая-то ошибка"
+rescue
+ RuntimeError -> "перехвачена ошибка рантайма"
+ _error -> "перехват любой другой ошибки"
+end
+#=> "перехвачена ошибка рантайма"
+
+# У каждого исключения есть сообщение
+try do
+ raise "какая-то ошибка"
+rescue
+ x in [RuntimeError] ->
+ x.message
+end
+#=> "какая-то ошибка"
+
+## ---------------------------
+## -- Параллелизм
+## ---------------------------
+
+# Параллелизм в Elixir построен на модели акторов. Для написания
+# параллельной программы нам понадобятся три вещи:
+# 1. Создание процессов
+# 2. Отправка сообщений
+# 3. Приём сообщений
+
+# Новый процесс создаётся функцией `spawn`, которая принимает функцию
+# в качестве аргумента.
+f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
+spawn(f) #=> #PID<0.40.0>
+
+# `spawn` возвращает идентификатор процесса (англ. process identifier, PID).
+# Вы можете использовать PID для отправки сообщений этому процессу. Сообщения
+# отправляются через оператор `send`. А для приёма сообщений используется
+# механизм `receive`:
+
+# Блок `receive do` ждёт сообщений и обработает их, как только получит. Блок
+# `receive do` обработает лишь одно полученное сообщение. Чтобы обработать
+# несколько сообщений, функция, содержащая блок `receive do`, должна рекурсивно
+# вызывать себя.
+
+defmodule Geometry do
+ def area_loop do
+ receive do
+ {:rectangle, w, h} ->
+ IO.puts("Площадь = #{w * h}")
+ area_loop()
+ {:circle, r} ->
+ IO.puts("Площадь = #{3.14 * r * r}")
+ area_loop()
+ end
+ end
+end
+
+# Скомпилируйте модуль и создайте процесс
+pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
+# Альтернативно
+pid = spawn(Geometry, :area_loop, [])
+
+# Отправьте сообщение процессу
+send pid, {:rectangle, 2, 3}
+#=> Площадь = 6
+# {:rectangle,2,3}
+
+send pid, {:circle, 2}
+#=> Площадь = 12.56
+# {:circle,2}
+
+# Кстати, интерактивная консоль — это тоже процесс.
+# Чтобы узнать текущий PID, воспользуйтесь встроенной функцией `self`
+self() #=> #PID<0.27.0>
+
+## ---------------------------
+## -- Агенты
+## ---------------------------
+
+# Агент — это процесс, который следит за некоторым изменяющимся значением.
+
+# Создайте агента через `Agent.start_link`, передав ему функцию.
+# Начальным состоянием агента будет значение, которое эта функция возвращает.
+{ok, my_agent} = Agent.start_link(fn -> ["красный", "зелёный"] end)
+
+# `Agent.get` принимает имя агента и анонимную функцию `fn`, которой будет
+# передано текущее состояние агента. В результате вы получите то, что вернёт
+# анонимная функция.
+Agent.get(my_agent, fn colors -> colors end) #=> ["красный", "зелёный"]
+
+# Похожим образом вы можете обновить состояние агента
+Agent.update(my_agent, fn colors -> ["синий" | colors] end)
+```
+
+## Ссылки
+
+* [Официальный сайт](http://elixir-lang.org)
+* [Шпаргалка по языку](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf)
+* [Книга "Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir)
+* [Книга "Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/)
+* [Книга "Programming Erlang: Software for a Concurrent World"](https://pragprog.com/book/jaerlang2/programming-erlang)
diff --git a/ru-ru/go-ru.html.markdown b/ru-ru/go-ru.html.markdown
index 6c8622cc..37592258 100644
--- a/ru-ru/go-ru.html.markdown
+++ b/ru-ru/go-ru.html.markdown
@@ -35,7 +35,7 @@ package main
// Import предназначен для указания зависимостей этого файла.
import (
"fmt" // Пакет в стандартной библиотеке Go
- "io/ioutil" // Реализация функций ввод/ввывода.
+ "io/ioutil" // Реализация функций ввод/вывода.
"net/http" // Да, это веб-сервер!
"strconv" // Конвертирование типов в строки и обратно
m "math" // Импортировать math под локальным именем m.
@@ -270,7 +270,7 @@ func learnErrorHandling() {
// c – это тип данных channel (канал), объект для конкурентного взаимодействия.
func inc(i int, c chan int) {
- c <- i + 1 // когда channel слева, <- являтся оператором "отправки".
+ c <- i + 1 // когда channel слева, <- является оператором "отправки".
}
// Будем использовать функцию inc для конкурентной инкрементации чисел.
diff --git a/ru-ru/haml-ru.html.markdown b/ru-ru/haml-ru.html.markdown
new file mode 100644
index 00000000..c2f8852e
--- /dev/null
+++ b/ru-ru/haml-ru.html.markdown
@@ -0,0 +1,233 @@
+---
+language: haml
+filename: learnhaml-ru.haml
+contributors:
+ - ["Simon Neveu", "https://github.com/sneveu"]
+ - ["Vasiliy Petrov", "https://github.com/Saugardas"]
+translators:
+ - ["Vasiliy Petrov", "https://github.com/Saugardas"]
+lang: ru-ru
+---
+
+Haml - язык разметки (в основном используемый с Ruby), с помощью которого могут быть легко описаны HTML-документы.
+Он является популярной альтернативой используемому в Rails шаблонизатору (.erb), и позволяет вставлять Ruby-код в вашу разметку.
+
+Haml убирает избыточность закрывающих тегов благодаря отступам.
+В результате получается меньшая по размерам, хорошо структурированная, логичная и читаемая разметка.
+
+Вы можете использовать Haml и вне Ruby-проекта. Установите гем Haml и используйте командную строку для конвертирования html-файлов:
+
+```shell
+$ haml input_file.haml output_file.html
+```
+
+
+```haml
+/ -------------------------------------------
+/ Отступы
+/ -------------------------------------------
+
+/
+ Отступы являются важным элементом синтаксиса, поэтому они должны быть
+ одинаковыми во всём документе. Обычно используют два пробела,
+ но это не является обязательным правилом - можно использовать любое
+ количество пробелов для отступов. Главное, чтобы это количество было
+ одинаковым во всём документе.
+
+
+/ -------------------------------------------
+/ Комментарии
+/ -------------------------------------------
+
+/ Комментари начинается с символа косой черты.
+
+/
+ Для написания многострочного комментария расположите ваш комментарий
+ на следующем уровне вложенности от символа косой черты
+
+-# "Скрытый" комментарий. Этот комментарий не попадёт в результирующий документ
+
+
+/ -------------------------------------------
+/ Элементы HTML
+/ -------------------------------------------
+
+/ Чтобы написать тег, используйте символ процента (%) и название тега
+%body
+ %header
+ %nav
+
+/ Обратите внимание на отсутствие закрывающих тегов. Код выше выведет:
+ <body>
+ <header>
+ <nav></nav>
+ </header>
+ </body>
+
+/
+ Так как тег div используется очень часто, его можно опустить.
+ Можно указать только имя класса или идентификатора (. или #)
+ Например код:
+
+%div.my_class
+ %div#my_id
+
+/ Можно записать:
+.my_class
+ #my_id
+
+/ Для добавления контента в тег, просто добавьте текст после объявления тега
+%h1 Заголовок
+
+/ Для многострочного содержания используйте отступы
+%p
+ Многострочное содержание
+ в две строки.
+
+/
+ Амперсанд - равно (&=) обрабатывают Ruby код также, как и без амперсанда,
+ но HTML-символы в результате будут экранированы. Например:
+
+%p
+ &= "Да & да"
+
+/ выведет 'Да &amp; да'
+
+/
+ Чтобы выполнять Ruby-код без экранрования, можно использовать
+ "восклицательный знак" и "равно" (!=)
+
+%p
+ != "Тег абзаца <p></p>"
+
+/ выведет 'Тег абзаца <p></p>'
+
+/ CSS - классы могут быть добавлены через точку от определения тега
+%div.foo.bar
+
+/ Или с помощью хеша атрибутов
+%div{ :class => 'foo bar' }
+
+/ Хеш атрибутов может быть добавлен для любого тега
+%a{ :href => '#', :class => 'bar', :title => 'Bar' }
+
+/ Для булевых атрибутов просто присвойте значение 'true'
+%input{ :selected => true }
+
+/ Для data - атрибутов присвойте ключу :data хеш с данными
+%div{ :data => { :attribute => 'foo' } }
+
+/ Для Ruby версии 1.9 или выше, можно использовать новый синтаксис хешей
+%div{ data: { attribute: 'foo' } }
+
+/ Также можно использовать HTML-синтаксис атрибутов
+%a(href='#' title='bar')
+
+/ Можно использовать оба варианта одновременно
+%a(href='#'){ title: @my_class.title }
+
+
+/ -------------------------------------------
+/ Включение Ruby
+/ -------------------------------------------
+
+/ Для включения Ruby кода используйте знак "равно"
+
+%h1= book.name
+
+%p
+ = book.author
+ = book.publisher
+
+
+/ Для выполнения Ruby кода без вывода в HTML, используйте знак дефиса
+- books = ['book 1', 'book 2', 'book 3']
+
+/
+ Можно выполнять любой Ruby код, например с блоками.
+ Закрывающий "end" не нужен, так как они будут закрыты автоматически,
+ основываясь на вложенности.
+
+- books.shuffle.each_with_index do |book, index|
+ %h1= book
+
+ - if book do
+ %p This is a book
+
+/ Добавление списка
+%ul
+ %li
+ =item1
+ =item2
+
+/ -------------------------------------------
+/ Пример таблицы с классами Bootstrap'a
+/ -------------------------------------------
+
+%table.table.table-hover
+ %thead
+ %tr
+ %th Header 1
+ %th Header 2
+
+ %tr
+ %td Value1
+ %td value2
+
+ %tfoot
+ %tr
+ %td
+ Foot value
+
+
+/ -------------------------------------------
+/ Интерполяция Ruby кода
+/ -------------------------------------------
+
+/ Ruby код может быть интерполирован в текст с помощью #{}
+%p Ваша самая любимая игра - #{best_game}
+
+/ Тоже самое, что и:
+%p= "Ваша самая любимая игра - #{best_game}"
+
+
+/ -------------------------------------------
+/ Фильтры
+/ -------------------------------------------
+
+/
+ Фильтры передают связанный блок текста в соотвествующую
+ фильтрующую программу и возвращают результат в Haml
+ Фильтр обозначается двоеточием и названием фильтра:
+
+/ Markdown filter
+:markdown
+ # Заголовк
+
+ Текст **внутри** *блока*
+
+/ Код выше будет скомпилирован в
+<h1>Заголовок</h1>
+
+<p>Текст <strong>внутри</strong> <em>блока</em></p>
+
+/ Javascript - фильтр
+:javascript
+ console.log('This is inline <script>');
+
+/ скомпилируется в:
+<script>
+ console.log('This is inline <script>');
+</script>
+
+/
+ Существует множество типов фильров (:markdown, :javascript, :coffee,
+ :css, :ruby и так далее). Вы можете определить собственный фильтр c
+ помощью Haml::Filters.
+
+```
+
+## Дополнительные ресурсы
+
+- [О Haml](https://haml.ru) - Хорошее введение, описывает преимущества Haml.
+- [Документация](https://haml.ru/documentation/) - Документация Haml на русском языке.
diff --git a/ru-ru/haskell-ru.html.markdown b/ru-ru/haskell-ru.html.markdown
index e15fe6b7..b1b8eb79 100644
--- a/ru-ru/haskell-ru.html.markdown
+++ b/ru-ru/haskell-ru.html.markdown
@@ -1,5 +1,6 @@
---
language: Haskell
+filename: haskell-ru.hs
contributors:
- ["Adit Bhargava", "http://adit.io"]
translators:
@@ -66,7 +67,7 @@ not False -- True
----------------------------------------------------
--- Списки и Кортежи
+-- 2. Списки и Кортежи
----------------------------------------------------
-- Все элементы списка в Haskell
diff --git a/ru-ru/html-ru.html.markdown b/ru-ru/html-ru.html.markdown
index 5cf95fc4..120981b9 100644
--- a/ru-ru/html-ru.html.markdown
+++ b/ru-ru/html-ru.html.markdown
@@ -1,10 +1,11 @@
---
language: html
-filename: learnhtml.html
+filename: learnhtml-ru.html
contributors:
- ["Christophe THOMAS", "https://github.com/WinChris"]
translators:
- ["Lana Tim", "https://github.com/LanaTim"]
+lang: ru-ru
---
HTML расшифровывается как Hypertext Markup Language(гипертекстовый язык разметки).
diff --git a/ru-ru/java-ru.html.markdown b/ru-ru/java-ru.html.markdown
index a1a5cdfc..1aff801c 100644
--- a/ru-ru/java-ru.html.markdown
+++ b/ru-ru/java-ru.html.markdown
@@ -1,12 +1,13 @@
---
language: java
+filename: LearnJava-ru.java
contributors:
- ["Jake Prather", "http://github.com/JakeHP"]
- ["Madison Dickson", "http://github.com/mix3d"]
translators:
- ["Sergey Gaykov", "https://github.com/gaykov"]
-filename: LearnJavaRu.java
lang: ru-ru
+
---
Java - это объектно-ориентированный язык программирования общего назначения,
diff --git a/ru-ru/javascript-ru.html.markdown b/ru-ru/javascript-ru.html.markdown
index 1f1ffce6..c31c6994 100644
--- a/ru-ru/javascript-ru.html.markdown
+++ b/ru-ru/javascript-ru.html.markdown
@@ -1,7 +1,7 @@
---
language: javascript
contributors:
- - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Leigh Brenecki", "https://leigh.net.au"]
- ["Ariel Krakowski", "http://www.learneroo.com"]
filename: javascript-ru.js
translators:
@@ -420,7 +420,7 @@ myObj.__proto__ = myPrototype;
myObj.meaningOfLife; // = 42
// Для функций это тоже работает.
-myObj.myFunc(); // = "Привет, мир!"
+myObj.myFunc(); // = "привет, мир!"
// Если интерпретатор не найдёт свойство в прототипе, то продожит поиск
// в прототипе прототипа и так далее.
diff --git a/ru-ru/jquery-ru.html.markdown b/ru-ru/jquery-ru.html.markdown
new file mode 100644
index 00000000..471b4e24
--- /dev/null
+++ b/ru-ru/jquery-ru.html.markdown
@@ -0,0 +1,127 @@
+---
+category: tool
+tool: jquery
+contributors:
+ - ["Sawyer Charles", "https://github.com/xssc"]
+translators:
+ - ["Ev Bogdanov", "https://github.com/evbogdanov"]
+lang: ru-ru
+filename: jquery-ru.js
+---
+
+jQuery — это библиотека JavaScript, которая помогает "делать больше, писать меньше". Она выполняет множество типичных JavaScript-задач, упрощая написание кода. jQuery используется крупными компаниями и разработчиками со всего мира. Она упрощает и ускоряет работу с AJAX, с событиями, с DOM и со многим другим.
+
+Поскольку jQuery является библиотекой JavaScript, вам следует начать с [изучения JavaScript](https://learnxinyminutes.com/docs/ru-ru/javascript-ru/).
+
+```js
+
+
+///////////////////////////////////
+// 1. Селекторы
+
+// Для получения элемента в jQuery используются селекторы
+var page = $(window); // Получить страницу целиком
+
+// В качестве селектора может выступать CSS-селектор
+var paragraph = $('p'); // Получить все <p> элементы
+var table1 = $('#table1'); // Получить элемент с идентификатором 'table1'
+var squares = $('.square'); // Получить все элементы с классом 'square'
+var square_p = $('p.square') // Получить <p> элементы с классом 'square'
+
+
+///////////////////////////////////
+// 2. События и эффекты
+// jQuery прекрасно справляется с обработкой событий
+// Часто используемое событие — это событие документа 'ready'
+// Вы можете использовать метод 'ready', который сработает, как только документ полностью загрузится
+$(document).ready(function(){
+ // Код не выполнится до тех пор, пока документ не будет загружен
+});
+// Обработку события можно вынести в отдельную функцию
+function onAction() {
+ // Код выполнится, когда произойдёт событие
+}
+$('#btn').click(onAction); // Обработчик события сработает при клике
+
+// Другие распространённые события:
+$('#btn').dblclick(onAction); // Двойной клик
+$('#btn').hover(onAction); // Наведение курсора
+$('#btn').focus(onAction); // Фокус
+$('#btn').blur(onAction); // Потеря фокуса
+$('#btn').submit(onAction); // Отправка формы
+$('#btn').select(onAction); // Когда выбрали элемент
+$('#btn').keydown(onAction); // Когда нажали клавишу
+$('#btn').keyup(onAction); // Когда отпустили клавишу
+$('#btn').keypress(onAction); // Когда нажали символьную клавишу (нажатие привело к появлению символа)
+$('#btn').mousemove(onAction); // Когда переместили курсор мыши
+$('#btn').mouseenter(onAction); // Когда навели курсор на элемент
+$('#btn').mouseleave(onAction); // Когда сдвинули курсор с элемента
+
+
+// Вы можете не только обрабатывать события, но и вызывать их
+$('#btn').dblclick(); // Вызвать двойной клик на элементе
+
+// Для одного селектора возможно назначить несколько обработчиков событий
+$('#btn').on(
+ {dblclick: myFunction1} // Обработать двойной клик
+ {blur: myFunction1} // Обработать исчезновение фокуса
+);
+
+// Вы можете перемещать и прятать элементы с помощью методов-эффектов
+$('.table').hide(); // Спрятать элемент(ы)
+
+// Обратите внимание: вызов функции в этих методах всё равно спрячет сам элемент
+$('.table').hide(function(){
+ // Сначала спрятать элемент, затем вызвать функцию
+});
+
+// Вы можете хранить селекторы в переменных
+var tables = $('.table');
+
+// Некоторые основные методы для манипуляций с документом:
+tables.hide(); // Спрятать элемент(ы)
+tables.show(); // Показать элемент(ы)
+tables.toggle(); // Спрятать/показать
+tables.fadeOut(); // Плавное исчезновение
+tables.fadeIn(); // Плавное появление
+tables.fadeToggle(); // Плавное исчезновение или появление
+tables.fadeTo(0.5); // Изменение прозрачности
+tables.slideUp(); // Свернуть элемент
+tables.slideDown(); // Развернуть элемент
+tables.slideToggle(); // Свернуть или развернуть
+
+// Все эти методы принимают скорость (в миллисекундах) и функцию обратного вызова
+tables.hide(1000, myFunction); // Анимация длится 1 секунду, затем вызов функции
+
+// В методе 'fadeTo' вторым параметром обязательно идёт прозрачность
+tables.fadeTo(2000, 0.1, myFunction); // Прозрачность меняется в течение 2 секунд до 0.1, затем вызывается функция
+
+// Метод 'animate' позволяет делать более продвинутую анимацию
+tables.animate({"margin-top": "+=50", height: "100px"}, 500, myFunction);
+
+
+///////////////////////////////////
+// 3. Манипуляции
+
+// Манипуляции похожи на эффекты, но позволяют добиться большего
+$('div').addClass('taming-slim-20'); // Добавить класс 'taming-slim-20' ко всем <div> элементам
+
+// Часто встречающиеся методы манипуляций
+$('p').append('Hello world'); // Добавить в конец элемента
+$('p').attr('class'); // Получить атрибут
+$('p').attr('class', 'content'); // Установить атрибут
+$('p').hasClass('taming-slim-20'); // Проверить наличие класса
+$('p').height(); // Получить или установить высоту элемента
+
+
+// Во многих методах вам доступна информация ТОЛЬКО о первом элементе из выбранных
+$('p').height(); // Вы получите высоту только для первого <p> элемента
+
+// Метод 'each' позволяет это исправить и пройтись по всем выбранным вами элементам
+var heights = [];
+$('p').each(function() {
+ heights.push($(this).height()); // Добавить высоту всех <p> элементов в массив
+});
+
+
+```
diff --git a/ru-ru/kotlin-ru.html.markdown b/ru-ru/kotlin-ru.html.markdown
new file mode 100644
index 00000000..85f44c96
--- /dev/null
+++ b/ru-ru/kotlin-ru.html.markdown
@@ -0,0 +1,375 @@
+---
+language: kotlin
+filename: LearnKotlin-ru.kt
+lang: ru-ru
+contributors:
+ - ["S Webber", "https://github.com/s-webber"]
+translators:
+ - ["Vadim Toptunov", "https://github.com/VadimToptunov"]
+---
+
+Kotlin - статически типизированный язык для JVM, Android и браузера. Язык полностью совместим c Java.
+[Более детальная информация здесь.](https://kotlinlang.org/)
+
+```kotlin
+// Однострочные комментарии начинаются с //
+/*
+А вот так выглядят многострочные комментарии.
+*/
+
+// Ключевое слово "package" действует и используется // абсолютно также, как и в Java.
+package com.learnxinyminutes.kotlin
+
+/*
+Точкой входа в программу на языке Kotlin является функция "main".
+Приведенная ниже функция передает массив, содержащий любые аргументы из командной строки.
+*/
+fun main(args: Array<String>) {
+ /*
+ Объявление значений производится с помощью или "var", или "val".
+ Значения объявленные с помощью "val" не могут быть изменены или перезаписаны, в то время как объявленные с помощью "var" - могут.
+ */
+ 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)
+
+ /*
+ Необработанная строка разделяется тройной кавычкой (""").
+ Необработанные строки могут содержать символы новой строки и любые другие символы.
+ */
+ val fooRawString = """
+fun helloWorld(val name : String) {
+ println("Hello, world!")
+}
+"""
+ println(fooRawString)
+
+ /*
+ Строки могут содержать в себе шаблонные выражения.
+ Шаблонные выражения начинаются со знака доллара ($).
+ */
+ val fooTemplateString = "$fooString has ${fooString.length} characters"
+ println(fooTemplateString)
+
+ /*
+ Переменная, которая содержит null должна быть явно обозначена как nullable.
+ Переменная может быть обозначена как 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() // => Argument has 0 elements
+ varargExample(1) // => Argument has 1 elements
+ varargExample(1, 2, 3) // => Argument has 3 elements
+
+ /*
+ Если функция состоит из одиночного выражения, фигурные скобки могут быть опущены. Тело функции указывается после знака = .
+ */
+ 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)
+ // Lambda-выражения могут быть определены в качестве аргументов.
+ val notZero = not {n -> n == 0}
+ /*
+ Если lambda-выражение имеет только один параметр, то ее определение может быть опущено (вместе с ->).
+ Имя этого единственного параметра будет "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)
+ // Функции-члены могут быть вызваны с использованием точечной нотации.
+ println(fooExampleClass.memberFunction(4)) // => 11
+ /*
+ В случае, если функция была помечена ключевым словом "infix", она может быть вызвана с помощью инфиксной нотации.
+ */
+ println(fooExampleClass infixMemberFunction 4) // => 28
+
+ /*
+ Data-классы - это компактный способ создать классы, которые лишь хранят данные.
+ Методы "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)
+
+ // Data-классы обладают функцией "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" аналогична оператору "with" в JavaScript.
+ data class MutableDataClassExample (var x: Int, var y: Int, var z: Int)
+ val fooMutableData = MutableDataClassExample(7, 4, 9)
+ with (fooMutableData) {
+ x -= 2
+ y += 2
+ z--
+ }
+ println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8)
+
+ /*
+ Можно создать список с помощью функции "ListOf".
+ Этот список будет неизменяемым, т.е. элементы не могут быть удалены или добавлены в него.
+ */
+ val fooList = listOf("a", "b", "c")
+ println(fooList.size) // => 3
+ println(fooList.first()) // => a
+ println(fooList.last()) // => c
+ // Элементы списка доступны по их индексу в нем.
+ println(fooList[1]) // => b
+
+ // Изменяемый список может быть создан спомощью функции "mutableListOf".
+ val fooMutableList = mutableListOf("a", "b", "c")
+ fooMutableList.add("d")
+ println(fooMutableList.last()) // => d
+ println(fooMutableList.size) // => 4
+
+ // Мы можем создать набор, используя функцию "setOf".
+ val fooSet = setOf("a", "b", "c")
+ println(fooSet.contains("a")) // => true
+ println(fooSet.contains("z")) // => false
+
+ // Мы можем создать отображение (map), используя функцию "mapOf".
+ val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9)
+ // Получить доступ к значениям отображения (map) можно с помощью их ключа.
+ println(fooMap["a"]) // => 8
+
+ /*
+ Последовательности представляют собой коллекции с ленивой оценкой.
+ Мы можем создать последовательность, используя функцию "generateSequence".
+ */
+ 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 предоставляет функции высшего порядка для работы с коллекциями.
+ 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".
+ Если объект проходит проверку типа, то он может использоваться как этот тип без явной его передачи.
+ */
+ 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
+
+ // Smartcast также работает с блоком "when"
+ fun smartCastWhenExample(x: Any) = when (x) {
+ is Boolean -> x
+ is Int -> x > 0
+ is String -> x.isNotEmpty()
+ else -> false
+ }
+
+ /*
+ Расширения - это способ добавить новый функционал к классу.
+ Это то же самое, что методы расширений в 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 в Java.
+enum class EnumExample {
+ A, B, C
+}
+
+/*
+Ключевое слово "object" может использоваться для создания одноэлементных объектов.
+Мы не можем его инстанцировать, но можем вызывать его уникальный экземпляр по имени.
+Это похоже на одиночные объекты Scala.
+*/
+object ObjectExample {
+ fun hello(): String {
+ return "hello"
+ }
+}
+
+fun useObject() {
+ ObjectExample.hello()
+ val someRef: Any = ObjectExample // we use objects name just as is
+}
+
+```
+
+### Дальнейшее чтение:
+
+* [Учебные материалы по Kotlin](https://kotlinlang.org/docs/tutorials/)
+* [Попробуй Kotlin в своем браузере](http://try.kotlinlang.org/)
+* [Список ресурсов по языку Kotlin](http://kotlin.link/)
diff --git a/ru-ru/learnvisualbasic-ru.html.markdown b/ru-ru/learnvisualbasic-ru.html.markdown
new file mode 100644
index 00000000..72e1358c
--- /dev/null
+++ b/ru-ru/learnvisualbasic-ru.html.markdown
@@ -0,0 +1,284 @@
+---
+language: Visual Basic
+contributors:
+ - ["Brian Martin", "http://brianmartin.biz"]
+translators:
+ - ["satory-ra", "https://github.com/satory-ra"]
+filename: learnvisualbasic-ru.vb
+lang: ru-ru
+---
+
+```vbnet
+Module Module1
+
+ Sub Main()
+ 'Краткий обзор консольных приложений Visual Basic перед более
+ 'глубоким изучением.
+ 'Апостроф начинает строку комментария.
+ 'Чтобы изучить это руководство в компиляторе Visual Basic,
+ 'я создал систему навигации.
+ 'Эта система будет объяснена при прохождении этого урока.
+ 'Постепенно вы всё поймете.
+ Console.Title = ("Выучи Х за Y минут")
+ Console.WriteLine("НАВИГАЦИЯ") 'Display
+ Console.WriteLine("")
+ Console.ForegroundColor = ConsoleColor.Green
+ Console.WriteLine("1. Вывод данных")
+ Console.WriteLine("2. Ввод данных")
+ Console.WriteLine("3. Расчёт целых чисел")
+ Console.WriteLine("4. Расчёт десятичных дробей")
+ Console.WriteLine("5. Калькулятор")
+ Console.WriteLine("6. Использование циклов Do While")
+ Console.WriteLine("7. Использование циклов For")
+ Console.WriteLine("8. Условные выражения")
+ Console.WriteLine("9. Выберите напиток")
+ Console.WriteLine("50. О приложении")
+ Console.WriteLine("Выберите номер из списка")
+ Dim selection As String = Console.ReadLine
+ '«Case» в операторе Select не является обязательным.
+ 'Например, "Select selection" вместо "Select Case selection"
+ 'также будет работать.
+ Select Case selection
+ Case "1" 'Вывод данных
+ Console.Clear() 'Очищает окно консоли
+ HelloWorldOutput() 'Открывает приватную подпрограмму.
+ Case "2" 'Ввод данных
+ Console.Clear()
+ HelloWorldInput()
+ Case "3" 'Расчёт целых чисел
+ Console.Clear()
+ CalculatingWholeNumbers()
+ Case "4" 'Расчёт десятичных дробей
+ Console.Clear()
+ CalculatingDecimalNumbers()
+ Case "5" 'Калькулятор
+ Console.Clear()
+ WorkingCalculator()
+ Case "6" 'Использование циклов Do While
+ Console.Clear()
+ UsingDoWhileLoops()
+ Case "7" 'Использование циклов For
+ Console.Clear()
+ UsingForLoops()
+ Case "8" 'Условные выражения
+ Console.Clear()
+ ConditionalStatement()
+ Case "9" 'Выражения If/Else
+ Console.Clear()
+ IfElseStatement() 'Выберите напиток
+ Case "50" 'Окно сообщения «О приложении»
+ Console.Clear()
+ Console.Title = ("Выучи Х за Y минут :: О приложении")
+ MsgBox("Это руководство от Брайана Мартина (@BrianMartinn")
+ Console.Clear()
+ Main()
+ Console.ReadLine()
+
+ End Select
+ End Sub
+
+ 'Один - Я использую эти цифры для того, чтобы было проще
+ 'соотносить код с системой навигации.
+
+ 'Мы используем частные подпрограммы для разделения различных
+ 'разделов программы.
+ Private Sub HelloWorldOutput()
+ 'Название консольного приложения
+ Console.Title = "Вывод данных | Выучи Х за Y минут"
+ 'Используйте Console.Write ("") или Console.WriteLine ("")
+ 'для отображения результатов.
+ 'Затем следует Console.Read () или Console.Readline ()
+ 'Console.ReadLine () показывает вывод в консоли.
+ Console.WriteLine("Hello World")
+ Console.ReadLine()
+ End Sub
+
+ 'Два
+ Private Sub HelloWorldInput()
+ Console.Title = "Ввод данных | Выучи Х за Y минут"
+ 'Переменная
+ 'используется для хранения пользовательских данных.
+ 'Объявление переменных начинается с Dim и заканчиваются
+ 'As VariableType (тип переменной).
+
+ 'В этом уроке мы хотим узнать ваше имя и заставить программу
+ 'реагировать на это.
+ Dim username As String
+ 'Мы используем тип «string», так как ваше имя - это текстовая переменная.
+ Console.WriteLine("Привет, как тебя зовут? ") 'Просит ввести имя.
+ username = Console.ReadLine() 'Сохраняет имя в переменной username.
+ Console.WriteLine("Пирвет, " + username) 'Выводит: «Привет, 'имя'»
+ Console.ReadLine() 'Отображает вышеуказанный вывод.
+
+ 'Вышеуказанная программа спросит ваше имя и скажет вам привет.
+ 'Есть и другие типы переменных, такие как целые числа (Integer),
+ 'мы используем Integer для обработки целых чисел.
+ End Sub
+
+ 'Три
+ Private Sub CalculatingWholeNumbers()
+ Console.Title = "Расчёт целых чисел | Выучи Х за Y минут"
+ Console.Write("Первое число: ") 'Введите первое целое число: 1, 2, 50, 104 и т.д.
+ Dim a As Integer = Console.ReadLine()
+ Console.Write("Второе число: ") 'Введите второе целое число.
+ Dim b As Integer = Console.ReadLine()
+ Dim c As Integer = a + b
+ Console.WriteLine(c)
+ Console.ReadLine()
+ 'Приведенная программа сумирует два целых числа
+ End Sub
+
+ 'Четыре
+ Private Sub CalculatingDecimalNumbers()
+ Console.Title = "Расчёт десятичных дробей | Выучи Х за Y минут"
+ 'Мы также должны уметь обрабатывать десятичные дроби.
+ 'Просто измените тип переменной с Integer на Double.
+
+ 'Введите число с плавающей точкой: 1.2, 2.4, 50.1, 104.9 и т.д.
+ Console.Write("Первое число: ")
+ Dim a As Double = Console.ReadLine
+ Console.Write("Второе число: ") 'Введите второе число с плавающей точкой.
+ Dim b As Double = Console.ReadLine
+ Dim c As Double = a + b
+ Console.WriteLine(c)
+ Console.ReadLine()
+ 'Приведенный выше код может сложить две десятичных дроби.
+ End Sub
+
+ 'Пять
+ Private Sub WorkingCalculator()
+ Console.Title = "Калькулятор | Выучи Х за Y минут"
+ 'Но что, если вам нужен калькулятор, который может обрабатывать сложение,
+ 'вычитание, умножение и деление?
+ 'Просто скопируйте и вставьте приведенный код.
+ Console.Write("Первое число: ")
+ Dim a As Double = Console.ReadLine
+ Console.Write("Второе число: ")
+ Dim b As Double = Console.ReadLine
+ Dim c As Double = a + b
+ Dim d As Double = a * b
+ Dim e As Double = a - b
+ Dim f As Double = a / b
+
+ 'С помощью следующего кода мы можем вывести результат сложения,
+ 'вычитания, умножения и деления, рассчитанный выше, на экран.
+ Console.Write(a.ToString() + " + " + b.ToString())
+ 'Мы хотим, чтобы в начале ответа было 3 пробела, для этого
+ 'вы можете использовать метод String.PadLeft (3).
+ Console.WriteLine(" = " + c.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " * " + b.ToString())
+ Console.WriteLine(" = " + d.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " - " + b.ToString())
+ Console.WriteLine(" = " + e.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " / " + b.ToString())
+ Console.WriteLine(" = " + f.ToString.PadLeft(3))
+ Console.ReadLine()
+
+ End Sub
+
+ 'Шесть
+ Private Sub UsingDoWhileLoops()
+ 'Код такой же, как и в предидущей подпрограмме
+ 'На этот раз мы спрашиваем, хочет ли пользователь продолжить (да или нет?)
+ 'Мы будем использовать цикл Do While, потому что не знаем,
+ 'понадобиться ли пользователю калькулятор болше одного раза.
+ Console.Title = "Использование циклов Do While | Выучи Х за Y минут"
+ Dim answer As String
+ 'Мы используем тип переменной "String", так как её значение текст.
+ Do 'Мы начаем программу с
+ Console.Write("Первое число: ")
+ Dim a As Double = Console.ReadLine
+ Console.Write("Второе число: ")
+ Dim b As Double = Console.ReadLine
+ Dim c As Double = a + b
+ Dim d As Double = a * b
+ Dim e As Double = a - b
+ Dim f As Double = a / b
+
+ Console.Write(a.ToString() + " + " + b.ToString())
+ Console.WriteLine(" = " + c.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " * " + b.ToString())
+ Console.WriteLine(" = " + d.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " - " + b.ToString())
+ Console.WriteLine(" = " + e.ToString.PadLeft(3))
+ Console.Write(a.ToString() + " / " + b.ToString())
+ Console.WriteLine(" = " + f.ToString.PadLeft(3))
+ Console.ReadLine()
+ 'Спросите пользователя, хочет ли он продолжить,
+ 'в ответе учитывается регистр букв.
+ Console.Write("Желаете ли вы продолжить? (да / нет)")
+ 'Программа берет значение и записывает в переменную answer.
+ answer = Console.ReadLine()
+ 'Когда пользователь вводит «да», программа переходит к Do и снова запускается.
+ Loop While answer = "yes"
+
+ End Sub
+
+ 'Семь
+ Private Sub UsingForLoops()
+ 'Иногда программу нужно запускать только один раз.
+ 'В этой программе мы осуществим обратный отсчет от 10.
+
+ Console.Title = "Использование циклов For | Выучи Х за Y минут"
+ 'Объявите переменные и Step (размер шага, то есть скорость уменьшения,
+ 'например, -1, -2, -3 и т.д.).
+ For i As Integer = 10 To 0 Step -1
+ Console.WriteLine(i.ToString) 'Показывает значение счетчика.
+ Next i 'Рассчитать новое значение i.
+ Console.WriteLine("Поехали")
+ Console.ReadLine()
+ End Sub
+
+ 'Восемь
+ Private Sub ConditionalStatement()
+ Console.Title = "Условные выражения | Выучи Х за Y минут"
+ Dim userName As String
+ Console.WriteLine("Привет, как тебя зовут? ") 'Спросите имя пользователя.
+ userName = Console.ReadLine() 'Записать имя в переменную userName.
+ If userName = "Адам" Then
+ Console.WriteLine("Привет, Адам")
+ Console.WriteLine("Спасибо за создание этого полезного сайта")
+ Console.ReadLine()
+ Else
+ Console.WriteLine("Привет " + userName)
+ Console.WriteLine("Вы заглянули на сайт www.learnxinyminutes.com")
+ Console.ReadLine() 'Программа останавливается и выводит вышеуказанный текст.
+ End If
+ End Sub
+
+ 'Девять
+ Private Sub IfElseStatement()
+ Console.Title = "Выражения If/Else | Выучи Х за Y минут"
+ 'Иногда важно рассмотреть более двух альтернатив.
+ 'Иногда некоторые из них лучше других.
+ 'Когда это произойдет, нам потребуется более одного утверждения «if» (если).
+ 'Оператор «if» подобен торговому автомату.
+ 'В котором пользователь пишет код (A1, A2, A3 и т.д.), чтобы выбрать элементы.
+ 'Все варианты могут быть объединены в одном утверждении «if».
+
+ Dim selection As String 'Объявить переменную для выбора
+ Console.WriteLine("Пожалуйста, выберите продукт из нашего прекрасного торгового автомата.")
+ Console.WriteLine("A1. для 7Up")
+ Console.WriteLine("A2. для Fanta")
+ Console.WriteLine("A3. для Dr. Pepper")
+ Console.WriteLine("A4. для Diet Coke")
+
+ selection = Console.ReadLine() 'Сохранить выбор пользователя
+ If selection = "A1" Then
+ Console.WriteLine("7up")
+ ElseIf selection = "A2" Then
+ Console.WriteLine("Fanta")
+ ElseIf selection = "A3" Then
+ Console.WriteLine("Dr. Pepper")
+ ElseIf selection = "A4" Then
+ Console.WriteLine("Diet Coke")
+ Else
+ Console.WriteLine("Извините, у меня нет " + selection)
+ End If
+ Console.ReadLine()
+
+ End Sub
+
+End Module
+
+```
diff --git a/ru-ru/linker-ru.html.markdown b/ru-ru/linker-ru.html.markdown
new file mode 100644
index 00000000..7df29c23
--- /dev/null
+++ b/ru-ru/linker-ru.html.markdown
@@ -0,0 +1,203 @@
+---
+category: tool
+tool: linker
+contributors:
+ - ["Alexander Kovalchuk", "https://github.com/Zamuhrishka"]
+translators:
+ - ["Alexander Kovalchuk", "https://github.com/Zamuhrishka"]
+lang: ru-ru
+---
+
+# Основные понятия и определения
+**Счетчик позиций** - у компоновщика есть специальная переменная
+"." (точка) всегда содержит текущую позицию вывода.
+
+# Функции
+**ADDR(section)** - возвращает абсолютный адрес указанной секции. Однако
+данная секция должна быть определенна до использования функции ADDR.
+
+**ALIGN(exp)** - возвращает значение счетчика позиций, выравненное на границу
+следующего за exp выражения.
+
+**SIZEOF(section)** - возвращает размер секции в байтах.
+
+**FILL(param)** - определяет образец заполнения для текущей секции. Все
+остальные неуказанные регионы внутри секции заполняются значением указанными
+в аргументе функции.
+
+**KEEP(param)** - используется чтобы помечать param как неустранимый.
+
+**ENTRY(func)** - определяет функцию, которая будет являться точкой входа
+в программу.
+
+```bash
+# Определяем точку входа в программу
+ENTRY(Reset_Handler)
+
+# Определяем перемнную которая содержит адрес вершины стека
+_estack = 0x20020000;
+# Определяем перемнную которая содержит значение размера кучи
+_Min_Heap_Size = 0x200;
+# Определяем перемнную которая содержит значение размера стека
+_Min_Stack_Size = 0x400;
+
+# Описание карты памяти доступной для данного процессора
+# MEMORY
+# {
+# ИМЯ_ОБЛАСТИ_ПАМЯТИ (права доступа) : ORIGIN = АДРЕС_НАЧАЛА, LENGTH = РАЗМЕР
+# }
+# В нашем примере контроллер содержит три области памяти:
+# RAM - начинается с адреса 0x20000000 и занимает 128 Кбайт;
+# CCMRAM - начинается с адреса 0x10000000и занимает 64 Кбайт;
+# FLASH - начинается с адреса 0x8000000 занимает 1024 Кбайт;
+# Причем RAM память доступка для чтения, записи и исполнения.
+# CCMRAM память доступна только на чтение и запись.
+# FLASH память доступна на чтение и исполнение.
+MEMORY
+{
+ RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
+ CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
+ FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
+}
+
+# Описываем выходные секции
+SECTIONS
+{
+ # Первая секция содержит таблицу векторов прерываний
+ .isr_vector :
+ {
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Существует опция --gc-sections, которая позволяет собирать мусор из неиспользуемых
+ # входных разделов. И если есть разделы, которые сборщик муссора не должен трогать,
+ # то их необходимо указать в качестве аргумента функции KEEP() (аналог ключевого слова
+ # volatile).
+ # Запись (*(.isr_vector)) означает разделы .isr_vector во всех объектных файлах. Т.к.
+ # обращение к разделу в общем виде выглядит так: (ИМЯ_ФАЙЛА(ИМЯ_РАЗДЕЛА))
+ KEEP(*(.isr_vector))
+
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Выражение ">ОБЛАСТЬ_ПАМЯТИ" указывает в какую именно область памяти будет помещенна
+ # данная секция. В нашем слущае секция .isr_vector будет размещена во FLASH памяти.
+ } >FLASH
+
+# ИТОГО: Секция .isr_vector, которая содержит таблицу векторов прерываний выравнивается
+# по границе 4-х байт, помечается как недоступная для сборщика мусора и размещается в начале
+# FLASH памяти микроконтроллера.
+
+ # Вторая секция содержит код программы.
+ .text :
+ {
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Указываем, что в данной секции будут хранится области .text всех
+ # объектных файлов
+ *(.text)
+ *(.text*)
+
+ # Защищаем от сборщика мусора секции .init и .fini
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Определяется переменная _etext, которая хранит в себе адрес конца секции .text и которая
+ # может быть доступна в исходном тексте программы через объявление
+ # volaile unsigned int extern _etext;
+ _etext = .;
+ } >FLASH
+
+# ИТОГО: Секция .text, которая содержит код программы выравнивается по границе 4-х байт,
+# включает в себя: все секции с кодом программы во всех объектных файлах и защищенные
+от сборщика муссора секции .init и .fini во всех объектных файлах, распологается во FLASH
+памяти микроконтроллера сразу за таблицей векторов.
+Секции text, .init и .fini. располагаются в памяти в той последовательности в которой они
+объявлены в скрипте.
+
+ # Третья секция содержит константные данные.
+ .rodata :
+ {
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Указываем, что в данной секции будут хранится области .rodataвсех
+ # объектных файлов
+ *(.rodata)
+ *(.rodata*)
+
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+ } >FLASH
+
+ # Сохраняем в переменной _sidata абсолютный адрес секции .data
+ _sidata = LOADADDR(.data);
+
+ # Четвертая секция содержит инициализированные переменные.
+ .data :
+ {
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Сохраняем в переменной _sdata адрес текущей позиции (начала секции)
+ _sdata = .;
+
+ # Указываем, что в данной секции будут хранится области .data всех
+ # объектных файлов
+ *(.data)
+ *(.data*)
+
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Сохраняем в переменной _sdata адрес текущей позиции (конец секции)
+ _edata = .;
+
+ # Функция AT указывает на то, что данный сектор хранится в одной области памяти
+ # (в нашем случае FLASH), а исполняться будет из другой обасти памяти (в нашем случае RAM).
+ # Есть два типа адрессов:
+ # * VMA (Virtual memory address) - это run-time адрес по которому уомпилятор ожидает
+ # видеть данные.
+ # * LMA (Load memory address) - это адрес по которому линкер хранит данные.
+
+ #Startup должен код скопировать секцию .data из адрессов LMA в адресса VMA.
+
+ } >RAM AT> FLASH
+
+ # Пятая секция содержит инициализированные нулем переменные.
+ .bss :
+ {
+ # Сохраняем в переменной _sbss и __bss_start__ адрес текущей позиции (начала секции)
+ _sbss = .;
+ __bss_start__ = _sbss;
+
+ # Указываем, что в данной секции будут хранится области .bss всех
+ # объектных файлов
+ *(.bss)
+ *(.bss*)
+
+ # Выравниваем текущую позицию на границу 4-х байт.
+ . = ALIGN(4);
+
+ # Сохраняем в переменной _ebss и __bss_end__ адрес текущей позиции (начала секции)
+ _ebss = .;
+ __bss_end__ = _ebss;
+ } >RAM
+
+ # Шестая секция содержит кучу и стек. Размещается в самом конце RAM.
+ ._user_heap_stack :
+ {
+ . = ALIGN(4);
+ PROVIDE ( end = . );
+ PROVIDE ( _end = . );
+ . = . + _Min_Heap_Size;
+ . = . + _Min_Stack_Size;
+ . = ALIGN(4);
+ } >RAM
+}
+```
+
diff --git a/ru-ru/markdown-ru.html.markdown b/ru-ru/markdown-ru.html.markdown
index ff7a0cc3..579a9a20 100644
--- a/ru-ru/markdown-ru.html.markdown
+++ b/ru-ru/markdown-ru.html.markdown
@@ -36,13 +36,14 @@ lang: ru-ru
Markdown является надмножеством HTML, поэтому любой HTML-файл является
корректным документом Markdown.
- ```markdown
+ ```md
<!-- Это позволяет использовать напрямую
любые элементы HTML-разметки, такие, например, как этот комментарий.
Встроенные в документ HTML-элементы не затрагиваются парсером Markdown
и попадают в итоговый HTML без изменений. Однако следует понимать,
что эта же особенность не позволяет использовать разметку Markdown внутри
HTML-элементов -->
+```
## Заголовки
@@ -50,7 +51,7 @@ HTML-элементы от <h1> до <h6> размечаются очень пр
текст, который должен стать заголовком, предваряется
соответствующим количеством символов "#":
-```markdown
+```md
# Это заголовок h1
## Это заголовок h2
### Это заголовок h3
@@ -60,7 +61,7 @@ HTML-элементы от <h1> до <h6> размечаются очень пр
```
Markdown позволяет размечать заголовки <h1> и <h2> ещё одним способом:
-```markdown
+```md
Это заголовок h1
================
@@ -72,7 +73,7 @@ Markdown позволяет размечать заголовки <h1> и <h2>
Текст легко сделать полужирным и/или курсивным:
-```markdown
+```md
*Этот текст будет выведен курсивом.*
_Так же, как этот._
@@ -87,7 +88,7 @@ __И этот тоже.__
В Github Flavored Markdown, стандарте, который используется в Github,
текст также можно сделать зачёркнутым:
-```markdown
+```md
~~Зачёркнутый текст.~~
```
@@ -96,7 +97,7 @@ __И этот тоже.__
Абзацами являются любые строки, следующие друг за другом.
Разделяются же абзацы одной или несколькими пустыми строками:
-```markdown
+```md
Это абзац. Я печатаю в абзаце, разве это не прикольно?
А тут уже абзац №2.
@@ -108,7 +109,7 @@ __И этот тоже.__
Для вставки принудительных переносов можно завершить абзац двумя дополнительными пробелами:
-```markdown
+```md
Эта строка завершается двумя пробелами (выделите, чтобы увидеть!).
Над этой строкой есть <br />!
@@ -116,7 +117,7 @@ __И этот тоже.__
Цитаты размечаются с помощью символа «>»:
-```markdown
+```md
> Это цитата. В цитатах можно
> принудительно переносить строки, вставляя «>» в начало каждой следующей строки. А можно просто оставлять их достаточно длинными, и такие длинные строки будут перенесены автоматически.
> Разницы между этими двумя подходами к переносу строк нет, коль скоро
@@ -133,7 +134,7 @@ __И этот тоже.__
одного из символов «*», «+» или «-»:
(символ должен быть одним и тем же для всех элементов)
-```markdown
+```md
* Список,
* Размеченный
* Звёздочками
@@ -154,7 +155,7 @@ __И этот тоже.__
В нумерованных списках каждая строка начинается
с числа и точки вслед за ним:
-```markdown
+```md
1. Первый элемент
2. Второй элемент
3. Третий элемент
@@ -164,7 +165,7 @@ __И этот тоже.__
любое число в начале каждого элемента, и парсер пронумерует элементы сам!
Правда, злоупотреблять этим не стоит :)
-```markdown
+```md
1. Первый элемент
1. Второй элемент
1. Третий элемент
@@ -173,7 +174,7 @@ __И этот тоже.__
Списки могут быть вложенными:
-```markdown
+```md
1. Введение
2. Начало работы
3. Примеры использования
@@ -184,7 +185,7 @@ __И этот тоже.__
Можно даже делать списки задач. Блок ниже создаёт HTML-флажки.
-```markdown
+```md
Для отметки флажка используйте «x»
- [ ] Первая задача
- [ ] Вторая задача
@@ -197,7 +198,7 @@ __И этот тоже.__
Фрагменты исходного кода (обычно отмечаемые тегом `<code>`) выделяются просто:
каждая строка блока должна иметь отступ в четыре пробела либо в один символ табуляции.
-```markdown
+```md
Это код,
причём многострочный
```
@@ -205,7 +206,7 @@ __И этот тоже.__
Вы также можете делать дополнительные отступы, добавляя символы табуляции
или по четыре пробела:
-```markdown
+```md
my_array.each do |item|
puts item
end
@@ -215,7 +216,7 @@ __И этот тоже.__
не выделяя код в блок. Для этого фрагменты кода нужно обрамлять
символами «`»:
-```markdown
+```md
Ваня даже не знал, что делает функция `go_to()`!
```
@@ -237,7 +238,7 @@ end
Разделители (`<hr>`) добавляются вставкой строки из трёх и более
(одинаковых) символов «*» или «-», с пробелами или без них:
-```markdown
+```md
***
---
- - -
@@ -251,18 +252,18 @@ end
текст ссылки, заключив его в квадратные скобки,
и сразу после — URL-адрес, заключенный в круглые
-```markdown
+```md
[Ссылка!](http://test.com/)
```
Также для ссылки можно указать всплывающую подсказку (`title`), используя
кавычки внутри круглых скобок:
-```markdown
+```md
[Ссылка!](http://test.com/ "Ссылка на Test.com")
```
Относительные пути тоже возможны:
-```markdown
+```md
[Перейти к музыке](/music/).
```
@@ -290,7 +291,7 @@ Markdown также позволяет размечать ссылку в вид
Разметка изображений очень похожа на разметку ссылок.
Нужно всего лишь добавить перед ссылкой восклицательный знак!
-```markdown
+```md
![Альтернативный текст для изображения](http://imgur.com/myimage.jpg "Подсказка")
```
Изображения тоже могут быть оформлены, как сноски.
@@ -301,20 +302,20 @@ Markdown также позволяет размечать ссылку в вид
## Разное
### Автоссылки
-```markdown
+```md
Ссылка вида <http://testwebsite.com/> эквивалентна
[http://testwebsite.com/](http://testwebsite.com/)
```
### Автоссылки для адресов электронной почты
-```markdown
+```md
<foo@bar.com>
```
### Экранирование символов
-```markdown
+```md
Я хочу напечатать *текст, заключённый в звёздочки*, но я не хочу,
чтобы он был курсивным. Тогда я делаю так:
\*Текст, заключённый в звёздочки\*
@@ -324,7 +325,7 @@ Markdown также позволяет размечать ссылку в вид
В Github Flavored Markdown для представления клавиш на клавиатуре
вы можете использовать тег `<kbd>`.
-```markdown
+```md
Ваш компьютер завис? Попробуйте нажать
<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd>
```
@@ -334,7 +335,7 @@ Markdown также позволяет размечать ссылку в вид
да и синтаксис имеют не слишком удобный.
Но если очень нужно, размечайте таблицы так:
-```markdown
+```md
| Столбец 1 | Столбец 2 | Столбец 3 |
| :----------- | :----------: | -----------: |
| Выравнивание | Выравнивание | Выравнивание |
@@ -342,7 +343,7 @@ Markdown также позволяет размечать ссылку в вид
```
Или более компактно
-```markdown
+```md
Столбец 1|Столбец 2|Столбец 3
:--|:-:|--:
Выглядит|это|страшновато...
diff --git a/ru-ru/nim-ru.html.markdown b/ru-ru/nim-ru.html.markdown
new file mode 100644
index 00000000..0e08f1bf
--- /dev/null
+++ b/ru-ru/nim-ru.html.markdown
@@ -0,0 +1,285 @@
+---
+language: Nim
+filename: learnNim-ru.nim
+contributors:
+ - ["Jason J. Ayala P.", "http://JasonAyala.com"]
+ - ["Dennis Felsing", "http://felsin9.de/nnis/"]
+translators:
+ - ["Nomadic", "https://github.com/n0madic"]
+ - ["dvska", "https://github.com/dvska"]
+lang: ru-ru
+---
+
+Nim (ранее известный, как Nimrod) — язык программирования со статической
+типизацией, поддерживающий процедурный, объектно-ориентированный,
+функциональный и обобщённый стили программирования.
+
+Nim эффективный, выразительный и элегантный.
+
+```nim
+var # Объявление (и присваивание) переменных,
+ буква: char = 'n' # с указанием типа или без
+ язык = "N" & "im"
+ nLength : int = len(язык)
+ boat: float
+ правда: bool = false
+
+let # Используйте let *сразу* для объявления и связывания переменных.
+ ноги = 400 # ноги неизменяемый.
+ руки = 2_000 # Символ _ игнорируется и удобен для длинных чисел.
+ почтиПи = 3.15
+
+const # Константы вычисляются во время компиляции. Это обеспечивает
+ debug = true # производительность и полезно в выражениях этапа компиляции.
+ компилироватьПлохойКод = false
+
+when компилироватьПлохойКод: # `when` это `if` этапа компиляции.
+ ноги = ноги + 1 # Эта ошибка никогда не будет скомпилирована.
+ const ввод = readline(stdin) # Значения констант должны быть известны во
+ # время компиляции.
+
+discard 1 > 2 # Примечание. Компилятор будет жаловаться, если результат
+ # выражения не используется. `discard` обходит это.
+
+discard """
+Это может использоваться как многострочный комментарий.
+Или для не поддающегося синтаксическому анализу, сломанного кода
+"""
+
+#
+# Структуры данных
+#
+
+# Кортежи
+
+var
+ дитя: tuple[имя: string, возраст: int] # Кортежи определяют *как* имя поля
+ сегодня: tuple[солнце: string, температура: float] # так *и* порядок полей.
+
+дитя = (имя: "Rudiger", возраст: 2) # Присвоить все сразу литералом ()
+сегодня.солнце = "Пасмурно" # или отдельно по полям.
+сегодня.температура = 20.1
+
+# Последовательности
+
+var
+ напитки: seq[string]
+
+напитки = @["Вода", "Сок", "Какао"] # @[V1,..,Vn] является литералом
+ # последовательности
+
+напитки.add("Молоко")
+
+if "Молоко" in напитки:
+ echo "У нас тут Молоко и ещё", напитки.len - 1, " напиток(ов)"
+
+let мойНапиток = напитки[2]
+
+#
+# Определение типов
+#
+
+# Определение собственных типов позволяет компилятору работать на вас.
+# Это то, что делает статическую типизацию мощной и полезной.
+
+type
+ Имя = string # Псевдоним типа дает вам новый тип, который равнозначен
+ Возраст = int # старому типу, но более нагляден.
+ Человек = tuple[имя: Имя, возраст: Возраст] # Определение структур данных.
+ АльтернативныйСинтаксис = tuple
+ fieldOne: string
+ secondField: int
+
+var
+ джон: Человек = (имя: "John B.", возраст: 17)
+ новыйВозраст: int = 18 # Было бы лучше использовать Возраст, чем int
+
+джон.возраст = новыйВозраст # Но это все же работает, потому что int и Возраст синонимы.
+
+type
+ Нал = distinct int # `distinct` делает новый тип несовместимым с его
+ Описание = distinct string # базовым типом.
+
+var
+ money: Нал = 100.Нал # `.Нал` преобразует int в наш тип
+ описание: Описание = "Interesting".Описание
+
+when компилироватьПлохойКод:
+ джон.возраст = money # Error! возраст is of type int and money is Нал
+ джон.имя = описание # Компилятор говорит: "Нельзя!"
+
+#
+# Дополнительные типы и структуры данных
+#
+
+# Перечисления позволяют типу иметь одно из ограниченного числа значений
+
+type
+ Цвет = enum цКрасный, цГолубой, цЗеленый
+ Направление = enum # Альтернативный формат
+ нСевер
+ нЗапад
+ нВосток
+ нЮг
+var
+ напр = нСевер # `напр` имеет тип Направление, со значением `нСевер`
+ точка = цЗеленый # `точка` имеет тип Цвет, со значением `цЗеленый`
+
+discard нСевер > нВосток # Перечисления обычно являются "порядковыми" типами
+
+# Поддиапазоны определяют ограниченный допустимый диапазон
+
+type
+ Кости = range[1..20] # 🎲 Допустимым значением являются только int от 1 до 20
+var
+ мой_бросок: Кости = 13
+
+when компилироватьПлохойКод:
+ мой_бросок = 23 # Error!
+
+# Массивы
+
+type
+ СчетчикБросков = array[Кости, int] # Массивы фиксированной длины и
+ ИменаНаправлений = array[Направление, string] # индексируются любым порядковым типом.
+ Истины = array[42..44, bool]
+var
+ счетчик: СчетчикБросков
+ направления: ИменаНаправлений
+ возможны: Истины
+
+возможны = [false, false, false] # Массивы создаются литералом [V1,..,Vn]
+возможны[42] = true
+
+направления[нСевер] = "ОО. Великий белый Север!"
+направления[нЗапад] = "Нет, не иди туда."
+
+мой_бросок = 13
+счетчик[мой_бросок] += 1
+счетчик[мой_бросок] += 1
+
+var ещеМассив = ["Идекс по умолчанию", "начинается с", "0"]
+
+# Доступны другие структуры данных, в том числе таблицы, множества,
+# списки, очереди и crit-bit деревья.
+# http://nim-lang.org/docs/lib.html#collections-and-algorithms (EN)
+
+#
+# IO и поток управления выполнением
+#
+
+# `case`, `readLine()`
+
+echo "Читали какие-нибудь хорошие книги в последнее время?"
+
+case readLine(stdin)
+of "нет", "Нет":
+ echo "Пойдите в свою местную библиотеку."
+of "да", "Да":
+ echo "Тогда продолжим"
+else:
+ echo "Здорово!"
+
+# `while`, `if`, `continue`, `break`
+
+import strutils as str # http://nim-lang.org/docs/strutils.html (EN)
+echo "Я загадало число между 41 и 43. Отгадай!"
+let число: int = 42
+var
+ ввод_догадка: string
+ догадка: int
+
+while догадка != число:
+ ввод_догадка = readLine(stdin)
+
+ if ввод_догадка == "": continue # Пропустить эту итерацию
+
+ догадка = str.parseInt(ввод_догадка)
+
+ if догадка == 1001:
+ echo("AAAAAAGGG!")
+ break
+ elif догадка > число:
+ echo("Неа. Слишком большое.")
+ elif догадка < число:
+ echo(догадка, " это слишком мало")
+ else:
+ echo("Точнооооо!")
+
+#
+# Итерации (циклы)
+#
+
+for i, элем in ["Да", "Нет", "Может быть"]: # Или просто `for элем in`
+ echo(элем, " по индексу: ", i)
+
+for ключ, значение in items(@[(человек: "You", сила: 100), (человек: "Me", сила: 9000)]):
+ echo значение
+
+let мояСтрока = """
+<пример>
+`строки` для
+тренировки
+""" # Многострочная "сырая" строка
+
+for строка in splitLines(мояСтрока):
+ echo(строка)
+
+for i, симв in мояСтрока: # Индекс и символ. Или `for j in` только для символов
+ if i mod 2 == 0: continue # Компактная форма `if`
+ elif симв == 'X': break
+ else: echo(симв)
+
+#
+# Процедуры
+#
+
+type Ответ = enum оДа, оНет
+
+proc спрос(вопрос: string): Ответ =
+ echo(вопрос, " (д/н)")
+ while true:
+ case readLine(stdin)
+ of "д", "Д", "да", "Да":
+ return Ответ.оДа # Перечисления могут быть квалифицированы
+ of "н", "Н", "нет", "Нет":
+ return Ответ.оНет
+ else: echo("Поточнее, да или нет")
+
+proc добавьСахар(количество: int = 2) = # Значение по умолчанию 2, ничего не возвращает
+ assert(количество > 0 and количество < 9000, "Диабет ☠")
+ for a in 1..количество:
+ echo(a, " кубик...")
+
+case спрос("Сахарку?")
+of оДа:
+ добавьСахар(3)
+of оНет:
+ echo "Ну немнооожко!"
+ добавьСахар()
+# Здесь нет необходимости в `else`. Возможны только `да` и `нет`.
+
+#
+# FFI (интерфейс внешних функций)
+#
+
+# Так как Nim компилируется в C, то FFI делается очень просто:
+
+proc strcmp(a, b: cstring): cint {.importc: "strcmp", nodecl.}
+
+let cmp = strcmp("C?", "Легко!")
+```
+
+Кроме того, Nim выделяется среди себе подобных метапрограммированием,
+производительностью, функциями этапа компиляции.
+
+## Дальнейшее чтение (EN)
+
+* [Домашняя страница](http://nim-lang.org)
+* [Скачать](http://nim-lang.org/download.html)
+* [Сообщество](http://nim-lang.org/community.html)
+* [FAQ](http://nim-lang.org/question.html)
+* [Документация](http://nim-lang.org/documentation.html)
+* [Руководство](http://nim-lang.org/docs/manual.html)
+* [Стандартная библиотека](http://nim-lang.org/docs/lib.html)
+* [Rosetta Code](http://rosettacode.org/wiki/Category:Nim)
diff --git a/ru-ru/objective-c-ru.html.markdown b/ru-ru/objective-c-ru.html.markdown
index d60db1d8..3baa15f8 100644
--- a/ru-ru/objective-c-ru.html.markdown
+++ b/ru-ru/objective-c-ru.html.markdown
@@ -781,7 +781,7 @@ MyClass *newVar = [classVar retain]; // Если classVar освободится
// автоматический подсчет ссылок (ARC).
// ARC - это особенность компилятора, который помещает "retain", "release"
// и "autorelease" автоматически за вас тогда, когда используется ARC,
-// вам не нужно больше обращаться к "retain", "relase" или "autorelease"
+// вам не нужно больше обращаться к "retain", "release" или "autorelease"
MyClass *arcMyClass = [[MyClass alloc] init];
// ... код, использующий объект arcMyClass
// Без ARC, вам нужно было бы вызвать: [arcMyClass release] после того, как вы
diff --git a/ru-ru/pascal-ru.html.markdown b/ru-ru/pascal-ru.html.markdown
new file mode 100644
index 00000000..5ea856bc
--- /dev/null
+++ b/ru-ru/pascal-ru.html.markdown
@@ -0,0 +1,217 @@
+---
+language: Pascal
+filename: learnpascal-ru.pas
+contributors:
+ - ["Ganesha Danu", "http://github.com/blinfoldking"]
+ - ["Keith Miyake", "https://github.com/kaymmm"]
+translators:
+ - ["Anton 'Dart' Nikolaev", "https://github.com/dartfnm"]
+lang: ru-ru
+---
+
+
+>Pascal - это процедурный язык программирования, который Никлаус Вирт разработал в 1968–69 годах и опубликовал в 1970 году как небольшой эффективный язык, предназначенный для поощрения хороших методов программирования с использованием структурированного программирования и структурирования данных. Он назван в честь французского математика, философа и физика Блеза Паскаля.
+>
+>source : [wikipedia](https://ru.wikipedia.org/wiki/Паскаль_(язык_программирования)))
+
+
+
+Для компиляции и запуска программы на языке Паскаль вы можете использовать бесплатный компилятор FreePascal. [Скачать здесь](https://www.freepascal.org/)
+
+Либо современный бесплатный компилятор Паскаля нового поколения под платформу .Net [PascalABC.NET](http://pascalabc.net)
+
+```pascal
+// это комментарий
+{
+ а вот это:
+ - комментарий на несколько строк
+}
+
+//объявляем имя программы
+program learn_pascal; //<-- не забываем ставить точку с запятой (;)
+
+const
+ {
+ это секция в которой вы должны объявлять константы
+ }
+type
+ {
+ здесь вы можете объявлять собственные типы данных
+ }
+var
+ {
+ секция для объявления переменных
+ }
+
+begin //начало основной программы
+ {
+ тело вашей программы
+ }
+end. // В конце основной программы обязательно должна стоять точка "."
+```
+
+```pascal
+//объявление переменных
+//вы можете сделать так
+var a:integer;
+var b:integer;
+//или так
+var
+ a : integer;
+ b : integer;
+//или даже так
+var a,b : integer;
+```
+
+```pascal
+program Learn_More;
+
+// Познакомимся с типами данных и с их операциями
+const
+ PI = 3.141592654;
+ GNU = 'GNU''s Not Unix';
+ // имена константам принято давать ЗАГЛАВНЫМИ_БУКВАМИ (в верхнем регистре)
+ // их значения фиксированны т.е никогда не меняются во время выполнения программы
+ // содержат любой стандартный тип данных (integer, real, boolean, char, string)
+
+type
+ ch_array : array [0..255] of char;
+ // массивы - это составной тип данных
+ // мы указываем индекс первого и последнего элемента массива ([0..255])
+ // здесь мы объявили новый тип данных содержащий 255 символов 'char'
+ // (по сути, это просто строка - string[256])
+
+ md_array : array of array of integer;
+ // массив в массиве - по сути является двумерным массивом
+ // можно задать массив нулевой (0) длины, а потом динамически расширить его
+ // это двумерный массив целых чисел
+
+//Объявление переменных
+var
+ int, c, d : integer;
+ // три переменные, которые содержат целые числа
+ // Тип "integer" это 16-битное число в диапазоне [-32,768..32,767]
+ r : real;
+ // переменная типа "real" принимает вещественные (дробные) значения
+ // в диапазоне [3.4E-38..3.4E38]
+ bool : boolean;
+ // переменная логического типа, принимающая булевы-значения: True/False (Правда/Ложь)
+ ch : char;
+ // эта переменная содержит значение кода одного символа
+ // тип 'char' это 8-битное число (1 байт), так что никакого Юникода
+ str : string;
+ // это переменная составного типа, являющееся строкой
+ // по сути, строка это массив в 255 символов длиною, по умолчанию
+
+ s : string[50];
+ // эта строка может содержать максимум 50 символов
+ // вы можете сами указать длину строки, чтобы минимизировать использование памяти
+ my_str: ch_array;
+ // вы можете объявлять переменные собственных типов
+ my_2d : md_array;
+ // динамически расширяемые массивы требуют указания длины перед их использованием.
+
+ // дополнительные целочисленные типы данных
+ b : byte; // диапазон [0..255]
+ shi : shortint; // диапазон [-128..127]
+ smi : smallint; // диапазон [-32,768..32,767] (стандартный Integer)
+ w : word; // диапазон [0..65,535]
+ li : longint; // диапазон [-2,147,483,648..2,147,483,647]
+ lw : longword; // диапазон [0..4,294,967,295]
+ c : cardinal; // тоже что и longword
+ i64 : int64; // диапазон [-9223372036854775808..9223372036854775807]
+ qw : qword; // диапазон [0..18,446,744,073,709,551,615]
+
+ // дополнительные вещественные типы данных (дробные)
+ rr : real; // диапазон зависит от платформы (т.е. 8-бит, 16-бит и т.д.)
+ rs : single; // диапазон [1.5E-45..3.4E38]
+ rd : double; // диапазон [5.0E-324 .. 1.7E308]
+ re : extended; // диапазон [1.9E-4932..1.1E4932]
+ rc : comp; // диапазон [-2E64+1 .. 2E63-1]
+
+Begin
+ int := 1; // так мы присваиваем значение переменной
+ r := 3.14;
+ ch := 'a';
+ str := 'apple';
+ bool := true;
+ // Паскаль не чувствителен к регистру
+
+ // арифметические операции
+ int := 1 + 1; // int = 2; заменяет предыдущее значение
+ int := int + 1; // int = 2 + 1 = 3;
+ int := 4 div 2; //int = 2; 'div' операция деления, с отбрасыванием дробной части
+ int := 3 div 2; //int = 1;
+ int := 1 div 2; //int = 0;
+
+ bool := true or false; // bool = true
+ bool := false and true; // bool = false
+ bool := true xor true; // bool = false
+
+ r := 3 / 2; // деления вещественных чисел с дробной частью
+ r := int; // вещественной переменной можно присвоить целочисленное значение, но не наоборот
+
+ my_str[0] := 'a'; // для доступа к элементу массива нужно указать его индекс в квадратных скобках ([0])
+
+ c := str[1]; // первая буква во всех Строках находится по индексу [1]
+ str := 'hello' + 'world'; //объединяем 2 строки в одну
+
+ SetLength(my_2d,10,10); // инициализируем динамически расширяемый массив
+ // задаём размер 2х-мерного массива 10×10
+
+ // первый элемент массива лежит в индексе [0], последний [длина_массива-1]
+ for c := 0 to 9 do
+ for d := 0 to 9 do // переменные для счетчиков циклов должны быть объявлены
+ my_2d[c,d] := c * d;
+ // обращаться к многомерным массивам нужно с помощью одного набора скобок
+
+End.
+```
+
+```pascal
+program Functional_Programming;
+
+Var
+ i, dummy : integer;
+
+function factorial_recursion(const a: integer) : integer;
+{ Функция расчёта Факториала целочисленного параметра 'a', рекурсивно. Возвращает целое значение }
+
+// Мы можем объявлять локальные переменные внутри своей функции:
+// Var
+// local_a : integer;
+
+Begin
+ If a >= 1 Then
+ factorial_recursion := a * factorial_recursion(a-1)
+ // возвращаем результат, присваивая найденное значение переменной с тем же именем, как у функции
+ Else
+ factorial_recursion := 1;
+End; // Для завершения функции, используется символ ";" после оператора "End;"
+
+
+
+procedure get_integer( var i : integer; dummy : integer );
+{ Эта процедура ждёт от пользователя ввода целого числа и возвращает его значение через параметр i.
+ Если параметр функции начинается с 'var', это означает, что его значение было передано, по ссылке, то есть, оно может использоваться не только как входное значение, но и для возвращения дополнительных результатов работы функции.
+ Параметры функции (без 'var'), (такие как "dummy" (пустышка)), передаются по значению, и по сути являются - локальными переменными, таким образом изменения, внесенные внутри функции/процедуры, не влияют на значение переменной за её пределами.
+}
+Begin // начало процедуры
+ write('Введите целое число: ');
+ readln(i); // число, введённое пользователем, сохранится в переменной i
+ // и её значение будет доступно вызывающей подпрограмме
+
+ dummy := 4; // значение 'dummy' не будет влиять на значения переменной вне процедуры
+End; // конец процедуры
+
+Begin // главный блок программы
+ dummy := 3;
+ get_integer(i, dummy); // вызываем процедуру получения числа от пользователя
+ writeln(i, '! = ', factorial_recursion(i)); // ввыводим значение факториала от i
+
+ writeln('dummy = ', dummy);
+ // всегда выводит "3", поскольку фиктивная переменная не изменяется.
+End. // конец программы
+
+```
+
diff --git a/ru-ru/perl-ru.html.markdown b/ru-ru/perl-ru.html.markdown
index a907ba41..a9bb683b 100644
--- a/ru-ru/perl-ru.html.markdown
+++ b/ru-ru/perl-ru.html.markdown
@@ -9,12 +9,12 @@ translators:
lang: ru-ru
---
-Perl 5 -- высокоуровневый мощный язык с 25-летней историей.
-Особенно хорош для обработки разнообразных текстовых данных.
+Perl -- высокоуровневый мощный язык с 25-летней историей.
+Особенно хорош для обработки разнообразных текстовых данных.
-Perl 5 работает более чем на 100 платформах, от портативных устройств
-до мейнфреймов, и подходит как для быстрого прототипирования,
-так и для крупных проектов.
+Perl работает более чем на 100 платформах, от портативных устройств
+до мейнфреймов, и подходит как для быстрого прототипирования,
+так и для крупных проектов.
```perl
# Комментарии начинаются с символа решетки.
@@ -23,8 +23,8 @@ Perl 5 работает более чем на 100 платформах, от п
#### Типы переменных в Perl
# Скалярные переменные начинаются с знака доллара $.
-# Имя переменной состоит из букв, цифр и знаков подчеркивания,
-# начиная с буквы или подчеркивания.
+# Имя переменной состоит из букв, цифр и знаков подчеркивания,
+# начиная с буквы или подчеркивания.
### В Perl три основных типа переменных: скаляры, массивы, хеши.
@@ -55,7 +55,7 @@ my %fruit_color = (
banana => "yellow",
);
-# Важно: вставка и поиск в хеше выполняются за константное время,
+# Важно: вставка и поиск в хеше выполняются за константное время,
# независимо от его размера.
# Скаляры, массивы и хеши подробно описаны в разделе perldata
@@ -81,7 +81,7 @@ unless ( condition ) {
}
# Это более читаемый вариант для "if (!condition)"
-# Специфические Perl-овые пост-условия:
+# Специфические Perl-овые пост-условия:
print "Yow!" if $zippy;
print "We have no bananas" unless $bananas;
@@ -129,7 +129,7 @@ open(my $out, ">", "output.txt") or die "Can't open output.txt: $!";
open(my $log, ">>", "my.log") or die "Can't open my.log: $!";
# Читать из файлового дескриптора можно с помощью оператора "<>".
-# В скалярном контексте он читает одну строку из файла, в списковом --
+# В скалярном контексте он читает одну строку из файла, в списковом --
# читает сразу весь файл, сохраняя по одной строке в элементе массива:
my $line = <$in>;
@@ -152,13 +152,13 @@ logger("We have a logger subroutine!");
#### Perl-модули
-Perl-овые модули предоставляют широкий набор функциональности,
-так что вы можете не изобретать заново велосипеды, а просто скачать
-нужный модуль с CPAN (http://www.cpan.org/).
-Некоторое количество самых полезных модулей включено в стандартную
+Perl-овые модули предоставляют широкий набор функциональности,
+так что вы можете не изобретать заново велосипеды, а просто скачать
+нужный модуль с CPAN (http://www.cpan.org/).
+Некоторое количество самых полезных модулей включено в стандартную
поставку Perl.
-Раздел документации perlfaq содержит вопросы и ответы о многих частых
+Раздел документации perlfaq содержит вопросы и ответы о многих частых
задачах, и часто предлагает подходящие CPAN-модули.
diff --git a/ru-ru/php-composer-ru.html.markdown b/ru-ru/php-composer-ru.html.markdown
new file mode 100644
index 00000000..4bdf1029
--- /dev/null
+++ b/ru-ru/php-composer-ru.html.markdown
@@ -0,0 +1,197 @@
+---
+category: tool
+tool: composer
+contributors:
+ - ["Brett Taylor", "https://github.com/glutnix"]
+translators:
+ - ["Aleksey Lysenko", "https://github.com/nasgul"]
+filename: LearnComposer-ru.sh
+lang: ru-ru
+---
+
+[Composer](https://getcomposer.org/) — это инструмент управления зависимостями в PHP.
+Он позволяет вам декларировать библиотеки, от которых зависит ваш проект,
+и он будет управлять ими, то есть устанавливать/обновлять их для вас.
+
+# Установка
+
+```sh
+# Устанавливаем composer.phar в текущую папку
+curl -sS https://getcomposer.org/installer | php
+# Если вы используете этот подход, вам нужно будет вызвать Composer следующим образом:
+php composer.phar about
+
+# Устанавливаем бинарный файл в ~/bin/composer
+# Примечание: убедитесь, что ~/bin находится в переменной PATH вашего окружения
+curl -sS https://getcomposer.org/installer | php -- --install-dir=~/bin --filename=composer
+```
+
+Пользователи Windows должны следовать
+[Инструкциям по установке в Windows ](https://getcomposer.org/doc/00-intro.md#installation-windows)
+
+## Подтверждение установки
+
+```sh
+# # Проверить версию и перечислить параметры
+composer
+
+# Получить дополнительную помощь для параметров
+composer help require
+
+# Проверить, способен ли Composer делать то, что ему нужно, и обновлён ли он
+composer diagnose
+composer diag # краткий вариант
+
+# Обновление Composer до последней версии
+composer self-update
+composer self # краткий вариант
+```
+
+# Использование
+
+Composer сохраняет ваши зависимости проекта в `composer.json`.
+Вы можете отредактировать этот файл, но лучше всего позволить Composer управлять им за вас.
+
+```sh
+# Создать новый проект в текущей папке
+composer init
+# запускается интерактивная анкета с просьбой предоставить подробную информацию о вашем проекте.
+# Вы прекрасно можете оставить ответы пустыми, если не делаете другие проекты
+# зависимыми от создаваемого проекта.
+
+# Если файл composer.json уже существует, загрузите зависимости
+composer install
+
+# Чтобы загрузить только зависимости для готового продукта, т.е.
+# исключая зависимости для разработки
+composer install --no-dev
+
+# Добавить зависимость для готового продукта к этому проекту
+composer require guzzlehttp/guzzle
+# выяснит, какая существует последняя версия guzzlehttp / guzzle,
+# загрузит её и добавит новую зависимость в поле require файла composer.json.
+
+composer require guzzlehttp/guzzle:6.0.*
+# Загрузит последнюю версию, соответствующую шаблону (например, 6.0.2),
+# и добавит зависимость к полю require файла composer.json
+
+composer require --dev phpunit/phpunit:~4.5.0
+# Добавит как зависимость для разработки.
+# Будет использовать последнюю версию> = 4.5.0 и <4.6.0
+
+composer require-dev phpunit/phpunit:^4.5.0
+# Добавит как зависимость для разработки.
+# Будет использовать последнюю версию> = 4.5.0 и <5.0
+
+# Для получения дополнительной информации о совместимости версий Composer см.
+# [Документацию Composer по версиям] (https://getcomposer.org/doc/articles/versions.md)
+
+# Чтобы узнать, какие пакеты доступны для установки и в настоящее время установлены
+composer show
+
+# Чтобы узнать, какие пакеты в настоящее время установлены
+composer show --installed
+
+# Чтобы найти пакет со строкой «mailgun» в названии или описании
+composer search mailgun
+```
+
+[Packagist.org](https://packagist.org/) является основным хранилищем для пакетов Composer.
+Существующие сторонние пакеты ищите там.
+
+## composer.json` и `composer.lock`
+
+Файл `composer.json` хранит параметры допустимых версий каждой зависимости
+вашего проекта, а также другую информацию.
+
+
+Файл `composer.lock` хранит точную загруженную версию каждой зависимости.
+Никогда не редактируйте этот файл.
+
+Если вы включите файл `composer.lock` в свой Git-репозиторий,
+каждый разработчик установит версии зависимостей, которые вы используете.
+Даже когда будет выпущена новая версия зависимости, Composer продолжит загрузку версии,
+записанной в lock-файле.
+
+```sh
+# Если вы хотите обновить все зависимости до новейших версий,
+# которые по-прежнему соответствуют вашим предпочтениям для версий
+composer update
+
+# Если вам нужна новая версия определённой зависимости:
+composer update phpunit/phpunit
+
+# Если вы хотите перенести пакет на более новую версию
+#с изменением предпочитаемой версии,
+# вам может потребоваться сначала удалить старый пакет и его зависимости.
+composer remove --dev phpunit/phpunit
+composer require --dev phpunit/phpunit:^5.0
+```
+
+## Автозагрузчик
+
+Composer создаёт класс автозагрузки, который вы можете вызвать
+из своего приложения. Вы можете создавать экземпляры классов через пространство имён.
+
+```php
+require __DIR__ . '/vendor/autoload.php';
+
+$mailgun = new Mailgun\Mailgun("key");
+```
+
+### PSR-4-совместимый автозагрузчик
+
+
+Вы можете добавить в автозагрузчик свои собственные пространства имён.
+
+Добавьте поле `autoload` в `composer.json`:
+
+```json
+{
+ "autoload": {
+ "psr-4": {"Acme\\": "src/"}
+ }
+}
+```
+Это скажет автозагрузчику искать что-либо в пространстве имён `\Acme` в папке `src`.
+
+Вы также можете использовать
+[PSR-0, карту классов или просто список файлов для включения](https://getcomposer.org/doc/04-schema.md#autoload).
+Также существует поле `autoload-dev` для пространств имён, предназначенных только для разработки.
+
+При добавлении или изменении ключа автозагрузки вам необходимо перестроить автозагрузчик:
+
+```sh
+composer dump-autoload
+composer dump # краткий вариант
+
+# Оптимизирует пакеты PSR0 и PSR4 для загрузки классов с помощью карты классов.
+# Медленно запускается, но улучшает производительность готового продукта.
+composer dump-autoload --optimize --no-dev
+```
+
+# Кэш Composer
+
+```sh
+# Composer хранит загруженные пакеты для использования в будущем. Очистите кэш с помощью:
+composer clear-cache
+```
+
+# Устранение неполадок
+
+```sh
+composer diagnose
+composer self-update
+composer clear-cache
+```
+
+## Темы, которые ещё (пока) не включены в этот учебник
+
+* Создание и распространение ваших собственных пакетов на Packagist.org или в другом репозитории
+* Предварительные и пост-скриптовые перехватчики: запуск задач,
+когда происходят определенные события Composer
+
+### Ссылки
+
+* [Composer - Dependency Manager for PHP](https://getcomposer.org/)
+* [Packagist.org](https://packagist.org/)
diff --git a/ru-ru/php-ru.html.markdown b/ru-ru/php-ru.html.markdown
index 181368de..af77a9ca 100644
--- a/ru-ru/php-ru.html.markdown
+++ b/ru-ru/php-ru.html.markdown
@@ -61,6 +61,8 @@ $int4 = 0x0F; // => 15 (ведущие символы 0x означают шес
// Двоичная запись integer доступна начиная с PHP 5.4.0.
$int5 = 0b11111111; // 255 (0b в начале означает двоичное число)
+// Удаление переменной
+unset($int1);
// Дробные числа
$float = 1.234;
@@ -128,7 +130,7 @@ define("FOO", "something");
// Доступ к константе возможен через прямое указание её имени без знака $
echo FOO; // печатает 'something'
-echo 'This outputs ' . FOO; // печатает 'This ouputs something'
+echo 'This outputs ' . FOO; // печатает 'This outputs something'
/********************************
* Массивы
@@ -687,45 +689,6 @@ use My\Namespace as SomeOtherNamespace;
$cls = new SomeOtherNamespace\MyClass();
-*//**********************
-* Позднее статическое связывание.
-*
-*/
-
-class ParentClass
-{
- public static function who()
- {
- echo "I'm a " . __CLASS__ . "\n";
- }
-
- public static function test()
- {
- // self ссылается на класс в котором определен метод.
- self::who();
- // static ссылается на класс в котором метод вызван.
- static::who();
- }
-}
-
-ParentClass::test();
-/*
-I'm a ParentClass
-I'm a ParentClass
-*/
-
-class ChildClass extends ParentClass
-{
- public static function who()
- {
- echo "But I'm " . __CLASS__ . "\n";
- }
-}
-
-ChildClass::test();
-/*
-I'm a ParentClass
-But I'm ChildClass
/**********************
* Позднее статическое связывание.
diff --git a/ru-ru/pyqt-ru.html.markdown b/ru-ru/pyqt-ru.html.markdown
new file mode 100644
index 00000000..24afc03d
--- /dev/null
+++ b/ru-ru/pyqt-ru.html.markdown
@@ -0,0 +1,86 @@
+---
+category: tool
+tool: PyQT
+lang: ru-ru
+filename: learnpyqt-ru.py
+contributors:
+ - ["Nathan Hughes", "https://github.com/sirsharpest"]
+translators:
+ - ["Vadim Toptunov", "https://github.com/VadimToptunov"]
+---
+
+**Qt** - широко известный кросс-платформенный фреймворк для разработки программного обеспечения,
+который может быть использован на различных софтварных и хардварных платформах без какого-либо
+изменения в коде. Данный фреймворк при этом обладает мощью и скоростью нативных приложений.
+Qt и был изначально написан на *C++*.
+
+Данный текст является адаптацией введения в Qt на C++ под авторством Алексея Ковальчука для pyqt.
+
+
+```python
+
+def window():
+ # Создайте объект приложения
+ app = QtGui.QApplication(sys.argv)
+ # Создайте виджет, где будет находиться наш лейбл
+ w = QtGui.QWidget()
+ # Добавьте лейбл в виджет
+ b = QtGui.QLabel(w)
+ # Задайте текст для лейбла
+ b.setText("Hello World!")
+ # Задайте информация о размере и расположении
+ w.setGeometry(100, 100, 200, 50)
+ b.move(50, 20)
+ # Задайте заголовок окна
+ w.setWindowTitle("PyQt")
+ # Все ранее написанное выводится на экран
+ w.show()
+ # Настройка
+ sys.exit(app.exec_())
+
+if __name__ == '__main__':
+ window()
+
+```
+
+Для того, чтобы получить более продвинутые функции приложения в pyqt, нам необходимо
+обратить внимание на создание дополнительных элементов. Ниже представлено создание всплывающего диалогового окна, которое просит пользователя подтвердить его решение или предоставить какую-либо
+информацию.
+
+```Python
+import sys
+from PyQt4.QtGui import *
+from PyQt4.QtCore import *
+
+
+def window():
+ app = QApplication(sys.argv)
+ w = QWidget()
+ # Создайте кнопку и прикрепите ее к виджету w
+ b = QPushButton(w)
+ b.setText("Press me")
+ b.move(50, 50)
+ # Укажите b вызвать эту функцию при клике мышкой
+ # Заметьте, что в вызове функции отсутствуют "()"
+ b.clicked.connect(showdialog)
+ w.setWindowTitle("PyQt Dialog")
+ w.show()
+ sys.exit(app.exec_())
+
+Данная функция должна создавать диалоговое окно с кнопкой, которая ждет клика по себе
+и затем завершает программу.
+
+def showdialog():
+ d = QDialog()
+ b1 = QPushButton("ok", d)
+ b1.move(50, 50)
+ d.setWindowTitle("Dialog")
+ # Эта модальность сообщает всплывающему окну блокировать родительский элемент, пока он активен
+ d.setWindowModality(Qt.ApplicationModal)
+ # Процесс завершается по клику мышкой
+ b1.clicked.connect(sys.exit)
+ d.exec_()
+
+if __name__ == '__main__':
+ window()
+```
diff --git a/ru-ru/python-ru.html.markdown b/ru-ru/python-ru.html.markdown
index 43142eff..e0e53b9c 100644
--- a/ru-ru/python-ru.html.markdown
+++ b/ru-ru/python-ru.html.markdown
@@ -1,27 +1,30 @@
---
-language: python
+language: Python
lang: ru-ru
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
+ - ["Steven Basart", "http://github.com/xksteven"]
translators:
- - ["Yury Timofeev", "http://twitter.com/gagar1n"]
- ["Andre Polykanine", "https://github.com/Oire"]
+ - ["Anton Grouchtchak", "https://github.com/Teraskull"]
filename: learnpython-ru.py
---
Язык Python был создан Гвидо ван Россумом в начале 90-х. Сейчас это один из
самых популярных языков. Я влюбился в Python за понятный и доходчивый синтаксис — это
-почти исполняемый псевдокод.
+почти что исполняемый псевдокод.
С благодарностью жду ваших отзывов: [@louiedinh](http://twitter.com/louiedinh)
или louiedinh [at] [почтовый сервис Google]
-Замечание: Эта статья относится к Python 2.7, но должно работать и в других версиях Python 2.x.
-Чтобы изучить Python 3.x, обратитесь к статье по Python 3.
+Замечание: Эта статья относится только к Python 3.
+Если вы хотите изучить Python 2.7, обратитесь к другой статье.
```python
+
# Однострочные комментарии начинаются с символа решётки.
-""" Многострочный текст может быть
+
+""" Многострочный текст может быть
записан, используя 3 знака " и обычно используется
в качестве встроенной документации
"""
@@ -31,323 +34,397 @@ filename: learnpython-ru.py
####################################################
# У вас есть числа
-3 #=> 3
+3 # => 3
# Математика работает вполне ожидаемо
-1 + 1 #=> 2
-8 - 1 #=> 7
-10 * 2 #=> 20
-35 / 5 #=> 7
-
-# А вот деление немного сложнее. В этом случае происходит деление
-# целых чисел, и результат автоматически округляется в меньшую сторону.
-5 / 2 #=> 2
-
-# Чтобы делить правильно, сначала нужно немного узнать о числах
-# с плавающей запятой.
-2.0 # Это число с плавающей запятой
-11.0 / 4.0 #=> 2.75 Вооот... Так гораздо лучше
+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 // 3 # => 1
+-5 // 3 # => -2
+5.0 // 3.0 # => 1.0 # работает и для чисел с плавающей запятой
-5.0 // 3.0 # => -2.0
+# # Результат деления возвращает число с плавающей запятой
+10.0 / 3 # => 3.3333333333333335
+
# Остаток от деления
-7 % 3 # => 1
+7 % 3 # => 1
# Возведение в степень
-2**4 # => 16
+2**3 # => 8
# Приоритет операций указывается скобками
-(1 + 3) * 2 #=> 8
+1 + 3 * 2 # => 7
+(1 + 3) * 2 # => 8
-# Логические операторы
-# Обратите внимание: ключевые слова «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
+# Булевы значения - примитивы (Обратите внимание на заглавную букву)
+True # => True
+False # => False
# Для отрицания используется ключевое слово not
-not True #=> False
-not False #=> True
+not True # => False
+not False # => True
+
+# Булевы операторы
+# Обратите внимание: ключевые слова "and" и "or" чувствительны к регистру букв
+True and False # => False
+False or True # => True
+
+# True и False на самом деле 1 и 0, но с разными ключевыми словами
+True + True # => 2
+True * 8 # => 8
+False - 5 # => -5
+
+# Операторы сравнения обращают внимание на числовое значение True и False
+0 == False # => True
+1 == True # => True
+2 == True # => False
+-5 != False # => True
+
+# Использование булевых логических операторов на типах int превращает их в булевы значения, но возвращаются оригинальные значения
+# Не путайте с bool(ints) и bitwise and/or (&,|)
+bool(0) # => False
+bool(4) # => True
+bool(-6) # => True
+0 and 2 # => 0
+-5 or 0 # => -5
# Равенство — это ==
-1 == 1 #=> True
-2 == 1 #=> False
+1 == 1 # => True
+2 == 1 # => False
# Неравенство — это !=
-1 != 1 #=> False
-2 != 1 #=> True
+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
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# Проверка, находится ли значение в диапазоне
+1 < 2 and 2 < 3 # => True
+2 < 3 and 3 < 2 # => False
+
+# Сравнения могут быть записаны цепочкой
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# (is vs. ==) ключевое слово is проверяет, относятся ли две переменные к одному и тому же объекту, но == проверяет если указанные объекты имеют одинаковые значения.
+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 равны
# Строки определяются символом " или '
"Это строка."
'Это тоже строка.'
-# И строки тоже можно складывать!
-"Привет " + "мир!" #=> "Привет мир!"
+# И строки тоже могут складываться! Хотя лучше не злоупотребляйте этим.
+"Привет " + "мир!" # => "Привет мир!"
-# ... или умножать
-"Привет" * 3 # => "ПриветПриветПривет"
+# Строки (но не переменные) могут быть объединены без использования '+'
+"Привет " "мир!" # => "Привет мир!"
# Со строкой можно работать, как со списком символов
-"Это строка"[0] #=> 'Э'
+"Привет мир!"[0] # => 'П'
-# Символ % используется для форматирования строк, например:
-"%s могут быть %s" % ("строки", "интерполированы")
+# Вы можете найти длину строки
+len("Это строка") # => 10
-# Новый способ форматирования строк — использование метода format.
-# Это предпочитаемый способ.
-"{0} могут быть {1}".format("строки", "форматированы")
+# Вы также можете форматировать, используя f-строки (в Python 3.6+)
+name = "Рейко"
+f"Она сказала, что ее зовут {name}." # => "Она сказала, что ее зовут Рейко"
+# Вы можете поместить любой оператор Python в фигурные скобки, и он будет выведен в строке.
+f"{name} состоит из {len(name)} символов." # => "Рэйко состоит из 5 символов."
-# Если вы не хотите считать, можете использовать ключевые слова.
-"{name} хочет есть {food}".format(name="Боб", food="лазанью")
# None является объектом
-None #=> None
+None # => None
-# Не используйте оператор равенства '=='' для сравнения
-# объектов с None. Используйте для этого «is»
-"etc" is None #=> False
-None is None #=> True
+# Не используйте оператор равенства "==" для сравнения
+# объектов с None. Используйте для этого "is"
+"etc" is None # => False
+None is None # => True
-# Оператор 'is' проверяет идентичность объектов. Он не
-# очень полезен при работе с примитивными типами, но
-# зато просто незаменим при работе с объектами.
-
-# None, 0 и пустые строки/списки равны False.
+# None, 0 и пустые строки/списки/словари/кортежи приводятся к False.
# Все остальные значения равны True
-0 == False #=> True
-"" == False #=> True
+bool(0) # => False
+bool("") # => False
+bool([]) # => False
+bool({}) # => False
+bool(()) # => False
####################################################
-## 2. Переменные и коллекции
+## 2. Переменные и Коллекции
####################################################
-# В Python есть оператор print, доступный в версиях 2.x, но удалённый в версии 3
-print "Я Python. Приятно познакомиться!"
-# В Python также есть функция print(), доступная в версиях 2.7 и 3,
-# Но для версии 2.7 нужно добавить следующий импорт модуля (раскомментируйте)):
-# from __future__ import print_function
-print("Я тоже Python! ")
+# В Python есть функция Print
+print("Я Python. Приятно познакомиться!") # => Я Python. Приятно познакомиться!
+
+# По умолчанию функция, print() также выводит новую строку в конце.
+# Используйте необязательный аргумент end, чтобы изменить последнюю строку.
+print("Привет мир", end="!") # => Привет мир!
+
+# Простой способ получить входные данные из консоли
+input_string_var = input("Введите данные: ") # Возвращает данные в виде строки
+# Примечание: в более ранних версиях Python метод input() назывался raw_input()
# Объявлять переменные перед инициализацией не нужно.
-some_var = 5 # По соглашению используется нижний_регистр_с_подчёркиваниями
-some_var #=> 5
+# По соглашению используется нижний_регистр_с_подчёркиваниями
+some_var = 5
+some_var # => 5
-# При попытке доступа к неинициализированной переменной
-# выбрасывается исключение.
-# См. раздел «Поток управления» для информации об исключениях.
-some_other_var # Выбрасывает ошибку именования
+# При попытке доступа к неинициализированной переменной выбрасывается исключение.
+# Об исключениях см. раздел "Поток управления и итерируемые объекты".
+some_unknown_var # Выбрасывает ошибку NameError
-# if может быть использован как выражение
-"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+# if можно использовать как выражение
+# Эквивалент тернарного оператора '?:' в C
+"да!" if 0 > 1 else "нет!" # => "нет!"
# Списки хранят последовательности
li = []
# Можно сразу начать с заполненного списка
other_li = [4, 5, 6]
-# строка разделена в список
-a="adambard"
-list(a) #=> ['a','d','a','m','b','a','r','d']
-
-# Объекты добавляются в конец списка методом append
-li.append(1) # [1]
-li.append(2) # [1, 2]
-li.append(4) # [1, 2, 4]
-li.append(3) # [1, 2, 4, 3]
-# И удаляются с конца методом pop
-li.pop() #=> возвращает 3 и li становится равен [1, 2, 4]
+# Объекты добавляются в конец списка методом append()
+li.append(1) # [1]
+li.append(2) # [1, 2]
+li.append(4) # [1, 2, 4]
+li.append(3) # [1, 2, 4, 3]
+# И удаляются с конца методом pop()
+li.pop() # => возвращает 3 и li становится равен [1, 2, 4]
# Положим элемент обратно
-li.append(3) # [1, 2, 4, 3].
+li.append(3) # [1, 2, 4, 3].
# Обращайтесь со списком, как с обычным массивом
-li[0] #=> 1
-# Присваивайте новые значения уже инициализированным индексам с помощью =
-li[0] = 42
-li[0] # => 42
-li[0] = 1 # Обратите внимание: возвращаемся на исходное значение
+li[0] # => 1
+
# Обратимся к последнему элементу
-li[-1] #=> 3
+li[-1] # => 3
# Попытка выйти за границы массива приведёт к ошибке индекса
-li[4] # Выдаёт IndexError
+li[4] # Выбрасывает ошибку IndexError
# Можно обращаться к диапазону, используя так называемые срезы
# (Для тех, кто любит математику, это называется замкнуто-открытый интервал).
-li[1:3] #=> [2, 4]
-# Опускаем начало
-li[2:] #=> [4, 3]
-# Опускаем конец
-li[:3] #=> [1, 2, 4]
-# Выбираем каждый второй элемент
-li[::2] # =>[1, 4]
-# Переворачиваем список
-li[::-1] # => [3, 4, 2, 1]
+li[1:3] # Вернуть список из индекса с 1 по 3 => [2, 4]
+li[2:] # Вернуть список, начиная с индекса 2 => [4, 3]
+li[:3] # Вернуть список с начала до индекса 3 => [1, 2, 4]
+li[::2] # Вернуть список, выбирая каждую вторую запись => [1, 4]
+li[::-1] # Вернуть список в обратном порядке => [3, 4, 2, 1]
# Используйте сочетания всего вышеназванного для выделения более сложных срезов
# li[начало:конец:шаг]
+# Сделать однослойную глубокую копию, используя срезы
+li2 = li[:] # => li2 = [1, 2, 4, 3], но (li2 is li) вернет False.
+
# Удаляем произвольные элементы из списка оператором del
-del li[2] # li теперь [1, 2, 3]
+del li[2] # [1, 2, 3]
+
+# Удалить первое вхождение значения
+li.remove(2) # [1, 3]
+li.remove(2) # Выбрасывает ошибку ValueError поскольку 2 нет в списке
+
+# Вставить элемент по определенному индексу
+li.insert(1, 2) # [1, 2, 3]
+
+# Получить индекс первого найденного элемента, соответствующего аргументу
+li.index(2) # => 1
+li.index(4) # Выбрасывает ошибку ValueError поскольку 4 нет в списке
# Вы можете складывать, или, как ещё говорят, конкатенировать списки
-li + other_li #=> [1, 2, 3, 4, 5, 6] — Замечание: li и other_li не изменяются
# Обратите внимание: значения li и other_li при этом не изменились.
+li + other_li # => [1, 2, 3, 4, 5, 6]
-# Объединять списки можно методом extend
+# Объединять списки можно методом extend()
li.extend(other_li) # Теперь li содержит [1, 2, 3, 4, 5, 6]
-# Проверить элемент на вхождение в список можно оператором in
-1 in li #=> True
+# Проверить элемент на наличие в списке можно оператором in
+1 in li # => True
# Длина списка вычисляется функцией len
-len(li) #=> 6
+len(li) # => 6
-# Кортежи — это такие списки, только неизменяемые
+# Кортежи похожи на списки, только неизменяемые
tup = (1, 2, 3)
-tup[0] #=> 1
-tup[0] = 3 # Выдаёт TypeError
+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
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
# Вы можете распаковывать кортежи (или списки) в переменные
-a, b, c = (1, 2, 3) # a == 1, b == 2 и c == 3
+a, b, c = (1, 2, 3) # a == 1, b == 2 и c == 3
+# Вы также можете сделать расширенную распаковку
+a, *b, c = (1, 2, 3, 4) # a теперь 1, b теперь [2, 3] и c теперь 4
# Кортежи создаются по умолчанию, если опущены скобки
-d, e, f = 4, 5, 6
+d, e, f = 4, 5, 6 # кортеж 4, 5, 6 распаковывается в переменные d, e и f
+# соответственно, d = 4, e = 5 и f = 6
# Обратите внимание, как легко поменять местами значения двух переменных
-e, d = d, e # теперь d == 5, а e == 4
+e, d = d, e # теперь d == 5, а e == 4
-# Словари содержат ассоциативные массивы
+
+# Словари содержат ассоциативные массивы
empty_dict = {}
# Вот так описывается предзаполненный словарь
filled_dict = {"one": 1, "two": 2, "three": 3}
-# Значения извлекаются так же, как из списка, с той лишь разницей,
-# что индекс — у словарей он называется ключом — не обязан быть числом
-filled_dict["one"] #=> 1
+# Обратите внимание, что ключи для словарей должны быть неизменяемыми типами. Это
+# сделано для того, чтобы ключ может быть преобразован в хеш для быстрого поиска.
+# Неизменяемые типы включают целые числа, числа с плавающей запятой, строки, кортежи.
+invalid_dict = {[1,2,3]: "123"} # => Выбрасывает ошибку TypeError: unhashable type: 'list'
+valid_dict = {(1,2,3):[1,2,3]} # Однако значения могут быть любого типа.
+
+# Поиск значений с помощью []
+filled_dict["one"] # => 1
-# Можно получить все ключи в виде списка с помощью метода keys
-filled_dict.keys() #=> ["three", "two", "one"]
-# Замечание: сохранение порядка ключей в словаре не гарантируется
-# Ваши результаты могут не совпадать с этими.
+# Все ключи в виде списка получаются с помощью метода keys().
+# Его вызов нужно обернуть в list(), так как обратно мы получаем
+# итерируемый объект, о которых поговорим позднее. Примечание - для Python
+# версии <3.7, порядок словарных ключей не гарантируется. Ваши результаты могут
+# не точно соответствовать приведенному ниже примеру. Однако, начиная с Python 3.7
+# элементы в словаре сохраняют порядок, в котором они вставляются в словарь.
+list(filled_dict.keys()) # => ["three", "two", "one"] в Python <3.7
+list(filled_dict.keys()) # => ["one", "two", "three"] в Python 3.7+
-# Можно получить и все значения в виде списка, используйте метод values
-filled_dict.values() #=> [3, 2, 1]
+
+# Все значения в виде списка можно получить с помощью values().
+# И снова нам нужно обернуть вызов в list(), чтобы превратить
+# итерируемый объект в список.
# То же самое замечание насчёт порядка ключей справедливо и здесь
+list(filled_dict.values()) # => [3, 2, 1] в Python <3.7
+list(filled_dict.values()) # => [1, 2, 3] в Python 3.7+
-# При помощи оператора in можно проверять ключи на вхождение в словарь
-"one" in filled_dict #=> True
-1 in filled_dict #=> False
+# При помощи ключевого слова in можно проверять наличие ключей в словаре
+"one" in filled_dict # => True
+1 in filled_dict # => False
-# Попытка получить значение по несуществующему ключу выбросит ошибку ключа
-filled_dict["four"] # KeyError
+# Попытка получить значение по несуществующему ключу выбросит ошибку KeyError
+filled_dict["four"] # Выбрасывает ошибку KeyError
# Чтобы избежать этого, используйте метод get()
-filled_dict.get("one") #=> 1
-filled_dict.get("four") #=> None
-# Метод get также принимает аргумент по умолчанию, значение которого будет
-# возвращено при отсутствии указанного ключа
-filled_dict.get("one", 4) #=> 1
-filled_dict.get("four", 4) #=> 4
-# Обратите внимание, что filled_dict.get("four") всё ещё => None
-# (get не устанавливает значение элемента словаря)
-
-# Присваивайте значение ключам так же, как и в списках
-filled_dict["four"] = 4 # теперь filled_dict["four"] => 4
+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.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}
+
# Множества содержат... ну, в общем, множества
-# (которые похожи на списки, только в них не может быть дублирующихся элементов)
empty_set = set()
-# Инициализация множества набором значений
-some_set = set([1,2,2,3,4]) # some_set теперь равно set([1, 2, 3, 4])
-
-# Порядок сортировки не гарантируется, хотя иногда они выглядят отсортированными
-another_set = set([4, 3, 2, 2, 1]) # another_set теперь set([1, 2, 3, 4])
+# Инициализация множества набором значений.
+# Да, оно выглядит примерно как словарь. Ну извините, так уж вышло.
+filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
-# Начиная с Python 2.7, вы можете использовать {}, чтобы объявить множество
-filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
+# Similar to keys of a dictionary, elements of a set have to be immutable.
+# Как и ключи словаря, элементы множества должны быть неизменяемыми.
+invalid_set = {[1], 1} # => Выбрасывает ошибку TypeError: unhashable type: 'list'
+valid_set = {(1,), 1}
-# Добавление новых элементов в множество
-filled_set.add(5) # filled_set равно {1, 2, 3, 4, 5}
+# Множеству можно назначать новую переменную
+filled_set = some_set
+filled_set.add(5) # {1, 2, 3, 4, 5}
+# В множествах нет повторяющихся элементов
+filled_set.add(5) # {1, 2, 3, 4, 5}
# Пересечение множеств: &
other_set = {3, 4, 5, 6}
-filled_set & other_set #=> {3, 4, 5}
+filled_set & other_set # => {3, 4, 5}
# Объединение множеств: |
-filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+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}
-# Проверка на вхождение во множество: in
-2 in filled_set #=> True
-10 in filled_set #=> False
+# Симметричная разница: ^
+{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
+
+# Сделать однослойную глубокую копию
+filled_set = some_set.copy() # {1, 2, 3, 4, 5}
+filled_set is some_set # => False
####################################################
-## 3. Поток управления
+## 3. Поток управления и итерируемые объекты
####################################################
-# Для начала заведём переменную
+# Для начала создадим переменную
some_var = 5
# Так выглядит выражение if. Отступы в python очень важны!
-# результат: «some_var меньше, чем 10»
+# Конвенция заключается в использовании четырех пробелов, а не табуляции.
+# Pезультат: "some_var меньше, чем 10"
if some_var > 10:
- print("some_var намного больше, чем 10.")
-elif some_var < 10: # Выражение elif необязательно.
+ print("some_var точно больше, чем 10.")
+elif some_var < 10: # Выражение elif необязательно.
print("some_var меньше, чем 10.")
-else: # Это тоже необязательно.
+else: # Это тоже необязательно.
print("some_var равно 10.")
"""
-Циклы For проходят по спискам
-
-Результат:
+Циклы For проходят по спискам.
+Выводит:
собака — это млекопитающее
кошка — это млекопитающее
мышь — это млекопитающее
"""
for animal in ["собака", "кошка", "мышь"]:
- # Можете использовать оператор % для интерполяции форматированных строк
- print("%s — это млекопитающее" % animal)
-
+ # Можете использовать format() для интерполяции форматированных строк
+ print("{} — это млекопитающее".format(animal))
+
"""
-«range(число)» возвращает список чисел
+"range(число)" возвращает список чисел
от нуля до заданного числа
-Результат:
+Выводит:
0
1
2
@@ -357,8 +434,42 @@ for i in range(4):
print(i)
"""
+"range(нижнее, верхнее)" возвращает список чисел
+от нижнего числа к верхнему
+Выводит:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print(i)
+
+"""
+"range(нижнее, верхнее, шаг)" возвращает список чисел
+от нижнего числа к верхнему, от нижнего числа к верхнему, увеличивая
+шаг за шагом. Если шаг не указан, значение по умолчанию - 1.
+Выводит:
+ 4
+ 6
+"""
+for i in range(4, 8, 2):
+ print(i)
+
+"""
+Чтобы перебрать список и получить индекс и значение каждого элемента в списке
+Выводит:
+ 0 собака
+ 1 кошка
+ 2 мышь
+"""
+animals = ["собака", "кошка", "мышь"]
+for i, value in enumerate(animals):
+ print(i, value)
+
+"""
Циклы while продолжаются до тех пор, пока указанное условие не станет ложным.
-Результат:
+Выводит:
0
1
2
@@ -370,20 +481,81 @@ while x < 4:
x += 1 # Краткая запись для x = x + 1
# Обрабатывайте исключения блоками try/except
-
-# Работает в Python 2.6 и выше:
try:
# Чтобы выбросить ошибку, используется raise
raise IndexError("Это ошибка индекса")
except IndexError as e:
- # pass — это просто отсутствие оператора. Обычно здесь происходит
- # восстановление после ошибки.
- pass
+ pass # pass — это просто отсутствие оператора. Обычно здесь происходит восстановление после ошибки.
except (TypeError, NameError):
- pass # Несколько исключений можно обработать вместе, если нужно.
-else: # Необязательное выражение. Должно следовать за последним блоком except
- print("Всё хорошо!") # Выполнится, только если не было никаких исключений
+ pass # Несколько исключений можно обработать вместе, если нужно.
+else: # Необязательное выражение. Должно следовать за последним блоком except
+ print("Всё хорошо!") # Выполнится, только если не было никаких исключений
+finally: # Выполнить при любых обстоятельствах
+ print("Мы можем очистить ресурсы здесь")
+
+# Вместо try/finally чтобы очистить ресурсы, можно использовать оператор with
+with open("myfile.txt") as f:
+ for line in f:
+ print(line)
+
+# Запись в файл
+contents = {"aa": 12, "bb": 21}
+with open("myfile1.txt", "w+") as file:
+ file.write(str(contents)) # Записывает строку в файл
+
+with open("myfile2.txt", "w+") as file:
+ file.write(json.dumps(contents)) # Записывает объект в файл
+
+# Чтение из файла
+with open('myfile1.txt', "r+") as file:
+ contents = file.read() # Читает строку из файла
+print(contents)
+# print: {"aa": 12, "bb": 21}
+
+with open('myfile2.txt', "r+") as file:
+ contents = json.load(file) # Читает объект json из файла
+print(contents)
+# print: {"aa": 12, "bb": 21}
+
+
+# Python предоставляет фундаментальную абстракцию,
+# которая называется итерируемым объектом (Iterable).
+# Итерируемый объект — это объект, который воспринимается как последовательность.
+# Объект, который возвратила функция range(), итерируемый.
+
+filled_dict = {"one": 1, "two": 2, "three": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) # => dict_keys(['one', 'two', 'three']). Это объект, реализующий интерфейс Iterable
+
+# Мы можем проходить по нему циклом.
+for i in our_iterable:
+ print(i) # Выводит one, two, three
+
+# Но мы не можем обращаться к элементу по индексу.
+our_iterable[1] # Выбрасывает ошибку TypeError
+
+# Итерируемый объект знает, как создавать итератор.
+our_iterator = iter(our_iterable)
+
+# Итератор может запоминать состояние при проходе по объекту.
+# Мы получаем следующий объект, вызывая функцию next().
+next(our_iterator) # => "one"
+# Он сохраняет состояние при вызове next().
+next(our_iterator) # => "two"
+next(our_iterator) # => "three"
+
+# Возвратив все данные, итератор выбрасывает исключение StopIterator
+next(our_iterator) # Выбрасывает исключение StopIteration
+
+# Мы можем проходить по нему циклом.
+our_iterator = iter(our_iterable)
+for i in our_iterator:
+ print(i) # Выводит one, two, three
+
+# Вы можете получить сразу все элементы итератора, вызвав на нём функцию list().
+list(our_iterable) # => Возвращает ["one", "two", "three"]
+list(our_iterator) # => Возвращает [] потому что состояние сохраняется
####################################################
@@ -393,30 +565,28 @@ else: # Необязательное выражение. Должно след
# Используйте def для создания новых функций
def add(x, y):
print("x равен %s, а y равен %s" % (x, y))
- return x + y # Возвращайте результат с помощью ключевого слова return
+ return x + y # Возвращайте результат с помощью ключевого слова return
# Вызов функции с аргументами
-add(5, 6) #=> выводит «x равен 5, а y равен 6» и возвращает 11
+add(5, 6) # => Выводит "x равен 5, а y равен 6" и возвращает 11
# Другой способ вызова функции — вызов с именованными аргументами
-add(y=6, x=5) # Именованные аргументы можно указывать в любом порядке.
+add(y=6, x=5) # Именованные аргументы можно указывать в любом порядке.
-# Вы можете определить функцию, принимающую переменное число аргументов,
-# которые будут интерпретированы как кортеж, если вы не используете *
+# Вы можете определить функцию, принимающую переменное число аргументов
def varargs(*args):
return args
-varargs(1, 2, 3) #=> (1,2,3)
+varargs(1, 2, 3) # => (1,2,3)
# А также можете определить функцию, принимающую переменное число
-# именованных аргументов, которые будут интерпретированы как словарь,
-# если вы не используете **
+# именованных аргументов
def keyword_args(**kwargs):
return kwargs
# Вызовем эту функцию и посмотрим, что из этого получится
-keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
# Если хотите, можете использовать оба способа одновременно
def all_the_args(*args, **kwargs):
@@ -432,77 +602,134 @@ all_the_args(1, 2, a=3, b=4) выводит:
# Используйте символ * для распаковки кортежей и ** для распаковки словарей
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # эквивалентно foo(1, 2, 3, 4)
-all_the_args(**kwargs) # эквивалентно foo(a=3, b=4)
-all_the_args(*args, **kwargs) # эквивалентно foo(1, 2, 3, 4, a=3, b=4)
-
-# вы можете передавать переменное число позиционных или именованных аргументов
-# другим функциям, которые их принимают, распаковывая их с помощью
-# * или ** соответственно
-def pass_all_the_args(*args, **kwargs):
- all_the_args(*args, **kwargs)
- print varargs(*args)
- print keyword_args(**kwargs)
+all_the_args(*args) # эквивалентно all_the_args(1, 2, 3, 4)
+all_the_args(**kwargs) # эквивалентно all_the_args(a=3, b=4)
+all_the_args(*args, **kwargs) # эквивалентно all_the_args(1, 2, 3, 4, a=3, b=4)
+
+# Возврат нескольких значений (с назначением кортежей)
+def swap(x, y):
+ return y, x # Возвращает несколько значений в виде кортежа без скобок.
+ # (Примечание: скобки исключены, но могут быть включены)
+
+x = 1
+y = 2
+x, y = swap(x, y) # => x = 2, y = 1
+# (x, y) = swap(x,y) # Снова, скобки были исключены, но могут быть включены.
# Область определения функций
x = 5
-def setX(num):
+def set_x(num):
# Локальная переменная x — это не то же самое, что глобальная переменная x
- x = num # => 43
- print (x) # => 43
-
-def setGlobalX(num):
+ x = num # => 43
+ print(x) # => 43
+
+def set_global_x(num):
global x
- print (x) # => 5
- x = num # Глобальная переменная x теперь равна 6
- print (x) # => 6
+ print(x) # => 5
+ x = num # Глобальная переменная x теперь равна 6
+ print(x) # => 6
-setX(43)
-setGlobalX(6)
+set_x(43)
+set_global_x(6)
-# В Python функции — «объекты первого класса»
+# Python имеет функции первого класса
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
# Также есть и анонимные функции
-(lambda x: x > 2)(3) #=> True
+(lambda x: x > 2)(3) # => True
+(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
# Есть встроенные функции высшего порядка
-map(add_10, [1,2,3]) #=> [11, 12, 13]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+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]
+
+# Для удобного отображения и фильтрации можно использовать списочные интерпретации
+# Интерпретация списка сохраняет вывод в виде списка, который сам может быть вложенным списком
+[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 '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}
-# Для удобного отображения и фильтрации можно использовать списочные включения
-[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
-[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
####################################################
-## 5. Классы
+## 5. Модули
####################################################
-# Чтобы получить класс, мы наследуемся от object.
-class Human(object):
+# Вы можете импортировать модули
+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
+
+# Вы можете импортировать все функции из модуля.
+# Предупреждение: это не рекомендуется
+from math import *
- # Атрибут класса. Он разделяется всеми экземплярами этого класса
- species = "H. sapiens"
+# Вы можете сократить имена модулей
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
+
+# Модули Python - это обычные файлы Python. Вы
+# можете писать свои собственные и импортировать их. Имя
+# модуля совпадает с именем файла.
+
+# Вы можете узнать, какие функции и атрибуты
+# определены в модуле.
+import math
+dir(math)
+
+# Если у вас есть скрипт Python с именем math.py в той же папке,
+# что и ваш текущий скрипт, файл math.py будет
+# будет загружен вместо встроенного модуля Python.
+# Это происходит потому, что локальная папка имеет приоритет
+# над встроенными библиотеками Python.
+
+
+####################################################
+## 6. Классы
+####################################################
+
+# Мы используем оператор class для создания класса
+class Human:
+
+ # Атрибут класса. Он используется всеми экземплярами этого класса
+ species = "Гомосапиенс"
# Обычный конструктор, вызывается при инициализации экземпляра класса
# Обратите внимание, что двойное подчёркивание в начале и в конце имени
# означает объекты и атрибуты, которые используются Python, но находятся
# в пространствах имён, управляемых пользователем.
+ # Методы (или объекты или атрибуты), например:
+ # __init__, __str__, __repr__ и т. д. называются специальными методами.
# Не придумывайте им имена самостоятельно.
def __init__(self, name):
- # Присваивание значения аргумента атрибуту класса name
+ # Присваивание значения аргумента атрибуту
self.name = name
+ # Инициализация свойства
+ self._age = 0
+
# Метод экземпляра. Все методы принимают self в качестве первого аргумента
def say(self, msg):
- return "%s: %s" % (self.name, msg)
+ return "{name}: {message}".format(name=self.name, message=msg)
+
+ # Другой метод экземпляра
+ def sing(self):
+ return 'йо... йо... проверка микрофона... раз, два... раз, два...'
# Метод класса разделяется между всеми экземплярами
# Они вызываются с указыванием вызывающего класса в качестве первого аргумента
@@ -515,58 +742,242 @@ class Human(object):
def grunt():
return "*grunt*"
+ # property похоже на геттер.
+ # Оно превращает метод age() в одноименный атрибут только для чтения.
+ # Однако нет необходимости писать тривиальные геттеры и сеттеры в Python.
+ @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="Иван")
+ i.say("привет") # Выводит: "Иван: привет"
+ j = Human("Пётр")
+ j.say("привет") # Выводит: "Пётр: привет"
+ # i и j являются экземплярами типа Human, или другими словами: они являются объектами Human
+
+ # Вызов метода класса
+ i.say(i.get_species()) # "Иван: Гомосапиенс"
+ # Изменение разделяемого атрибута
+ Human.species = "Неандертальец"
+ i.say(i.get_species()) # => "Иван: Неандертальец"
+ j.say(j.get_species()) # => "Пётр: Неандертальец"
+
+ # Вызов статического метода
+ print(Human.grunt()) # => "*grunt*"
+
+ # Невозможно вызвать статический метод с экземпляром объекта
+ # потому что i.grunt() автоматически поместит "self" (объект i) в качестве аргумента
+ print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
+
+ # Обновить свойство для этого экземпляра
+ i.age = 42
+ # Получить свойство
+ i.say(i.age) # => "Иван: 42"
+ j.say(j.age) # => "Пётр: 0"
+ # Удалить свойство
+ del i.age
+ # i.age # => это выбрасило бы ошибку AttributeError
+
+
+####################################################
+## 6.1 Наследование
+####################################################
+
+# Наследование позволяет определять новые дочерние классы, которые наследуют методы и
+# переменные от своего родительского класса.
+
+# Используя класс Human, определенный выше как базовый или родительский класс, мы можем
+# определить дочерний класс Superhero, который наследует переменные класса, такие как
+# "species", "name" и "age", а также методы, такие как "sing" и "grunt" из класса Human,
+# но также может иметь свои уникальные свойства.
+
+# Чтобы воспользоваться преимуществами модульности по файлам, вы можете поместить
+# вышеперечисленные классы в их собственные файлы, например, human.py
+
+# Чтобы импортировать функции из других файлов, используйте следующий формат
+# from "имя-файла-без-расширения" import "функция-или-класс"
+
+from human import Human
+
+
+# Укажите родительский класс(ы) как параметры определения класса
+class Superhero(Human):
+
+ # Если дочерний класс должен наследовать все определения родителя без каких-либо
+ # изменений, вы можете просто использовать ключевое слово pass (и ничего больше),
+ # но в этом случае оно закомментировано, чтобы разрешить уникальный дочерний класс:
+ # pass
+
+ # Дочерние классы могут переопределять атрибуты своих родителей
+ species = 'Сверхчеловек'
+
+ # Дочерние классы автоматически наследуют конструктор родительского класса, включая
+ # его аргументы, но также могут определять дополнительные аргументы или определения
+ # и переопределять его методы, такие как конструктор класса.
+ # Этот конструктор наследует аргумент "name" от класса "Human"
+ # и добавляет аргументы "superpower" и "movie":
+ def __init__(self, name, movie=False,
+ superpowers=["сверхсила", "пуленепробиваемость"]):
+
+ # добавить дополнительные атрибуты класса:
+ self.fictional = True
+ self.movie = movie
+ # помните об изменяемых значениях по умолчанию,
+ # поскольку значения по умолчанию являются общими
+ self.superpowers = superpowers
+
+ # Функция "super" позволяет вам получить доступ к методам родительского класса,
+ # которые переопределяются дочерним, в данном случае, методом __init__.
+ # Это вызывает конструктор родительского класса:
+ super().__init__(name)
+
+ # переопределить метод sing
+ def sing(self):
+ return 'Бам, бам, БАМ!'
+
+ # добавить дополнительный метод экземпляра
+ def boast(self):
+ for power in self.superpowers:
+ print("Я обладаю силой '{pow}'!".format(pow=power))
+
-# Инициализация экземпляра класса
-i = Human(name="Иван")
-print(i.say("привет")) # Выводит: «Иван: привет»
+if __name__ == '__main__':
+ sup = Superhero(name="Тик")
-j = Human("Пётр")
-print(j.say("Привет")) # Выводит: «Пётр: привет»
+ # Проверка типа экземпляра
+ if isinstance(sup, Human):
+ print('Я человек')
+ if type(sup) is Superhero:
+ print('Я супергерой')
-# Вызов метода класса
-i.get_species() #=> "H. sapiens"
+ # Получить порядок поиска разрешения метода (MRO),
+ # используемый как getattr(), так и super()
+ # Этот атрибут является динамическим и может быть обновлен
+ print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
+ # => <class 'human.Human'>, <class 'object'>)
-# Изменение разделяемого атрибута
-Human.species = "H. neanderthalensis"
-i.get_species() #=> "H. neanderthalensis"
-j.get_species() #=> "H. neanderthalensis"
+ # Вызывает родительский метод, но использует свой собственный атрибут класса
+ print(sup.get_species()) # => Сверхчеловек
-# Вызов статического метода
-Human.grunt() #=> "*grunt*"
+ # Вызов переопределенного метода
+ print(sup.sing()) # => Бам, бам, БАМ!
+
+ # Вызывает метод из Human
+ sup.say('Ложка') # => Тик: Ложка
+
+ # Метод вызова, существующий только в Superhero
+ sup.boast() # => Я обладаю силой 'сверхсила'!
+ # => Я обладаю силой 'пуленепробиваемость'!
+
+ # Атрибут унаследованного класса
+ sup.age = 31
+ print(sup.age) # => 31
+
+ # Атрибут, который существует только в Superhero
+ print('Достоин ли я Оскара? ' + str(sup.movie))
####################################################
-## 6. Модули
+## 6.2 Множественное наследование
####################################################
-# Вы можете импортировать модули
-import math
-print(math.sqrt(16)) #=> 4
+# Eще одно определение класса
+# bat.py
+class Bat:
-# Вы можете импортировать отдельные функции модуля
-from math import ceil, floor
-print(ceil(3.7)) #=> 4.0
-print(floor(3.7)) #=> 3.0
+ species = 'Летучая мышь'
-# Можете импортировать все функции модуля.
-# (Хотя это и не рекомендуется)
-from math import *
+ def __init__(self, can_fly=True):
+ self.fly = can_fly
-# Можете сокращать имена модулей
-import math as m
-math.sqrt(16) == m.sqrt(16) #=> True
-# Вы также можете убедиться, что функции эквивалентны
-from math import sqrt
-math.sqrt == m.sqrt == sqrt # => True
+ # В этом классе также есть метод say
+ def say(self, msg):
+ msg = '... ... ...'
+ return msg
-# Модули в Python — это обычные Python-файлы. Вы
-# можете писать свои модули и импортировать их. Название
-# модуля совпадает с названием файла.
+ # И свой метод тоже
+ def sonar(self):
+ return '))) ... ((('
+
+if __name__ == '__main__':
+ b = Bat()
+ print(b.say('привет'))
+ print(b.fly)
+
+
+# И еще одно определение класса, унаследованное от Superhero и Bat
+# superhero.py
+from superhero import Superhero
+from bat import Bat
+
+# Определите Batman как дочерний класс, унаследованный от Superhero и Bat
+class Batman(Superhero, Bat):
+
+ def __init__(self, *args, **kwargs):
+ # Обычно для наследования атрибутов необходимо вызывать super:
+ # super(Batman, self).__init__(*args, **kwargs)
+ # Однако здесь мы имеем дело с множественным наследованием, а super()
+ # работает только со следующим базовым классом в списке MRO.
+ # Поэтому вместо этого мы вызываем __init__ для всех родителей.
+ # Использование *args и **kwargs обеспечивает чистый способ передачи
+ # аргументов, когда каждый родитель "очищает слой луковицы".
+ Superhero.__init__(self, 'анонимный', movie=True,
+ superpowers=['Богатый'], *args, **kwargs)
+ Bat.__init__(self, *args, can_fly=False, **kwargs)
+ # переопределить значение атрибута name
+ self.name = 'Грустный Бен Аффлек'
+
+ def sing(self):
+ return 'на на на на на бэтмен!'
+
+
+if __name__ == '__main__':
+ sup = Batman()
+
+ # Получить порядок поиска разрешения метода (MRO),
+ # используемый как getattr(), так и super()
+ # Этот атрибут является динамическим и может быть обновлен
+ print(Batman.__mro__) # => (<class '__main__.Batman'>,
+ # => <class 'superhero.Superhero'>,
+ # => <class 'human.Human'>,
+ # => <class 'bat.Bat'>, <class 'object'>)
+
+ # Вызывает родительский метод, но использует свой собственный атрибут класса
+ print(sup.get_species()) # => Сверхчеловек
+
+ # Вызов переопределенного метода
+ print(sup.sing()) # => на на на на на бэтмен!
+
+ # Вызывает метод из Human, потому что порядок наследования имеет значение
+ sup.say('Я согласен') # => Грустный Бен Аффлек: Я согласен
+
+ # Вызов метода, существующий только во втором родителе
+ print(sup.sonar()) # => ))) ... (((
+
+ # Атрибут унаследованного класса
+ sup.age = 100
+ print(sup.age) # => 100
+
+ # Унаследованный атрибут от второго родителя,
+ # значение по умолчанию которого было переопределено.
+ print('Могу ли я летать? ' + str(sup.fly)) # => Могу ли я летать? False
-# Вы можете узнать, какие функции и атрибуты определены
-# в модуле
-import math
-dir(math)
####################################################
## 7. Дополнительно
@@ -577,28 +988,30 @@ def double_numbers(iterable):
for i in iterable:
yield i + i
-# Генератор создаёт значения на лету.
-# Он не возвращает все значения разом, а создаёт каждое из них при каждой
-# итерации. Это значит, что значения больше 15 в double_numbers
-# обработаны не будут.
-# Обратите внимание: xrange — это генератор, который делает то же, что и range.
-# Создание списка чисел от 1 до 900000000 требует много места и времени.
-# xrange создаёт объект генератора, а не список сразу, как это делает range.
-# Если нам нужно имя переменной, совпадающее с ключевым словом Python,
-# мы используем подчёркивание в конце
-xrange_ = xrange(1, 900000000)
-
-# Будет удваивать все числа, пока результат не превысит 30
-for i in double_numbers(xrange_):
+# Генераторы эффективны с точки зрения памяти, потому что они загружают только данные,
+# необходимые для обработки следующего значения в итерации.
+# Это позволяет им выполнять операции с недопустимо большими диапазонами значений.
+# ПРИМЕЧАНИЕ: "range" заменяет "xrange" в Python 3.
+for i in double_numbers(range(1, 900000000)): # "range" - генератор.
print(i)
if i >= 30:
break
+# Так же, как вы можете создать интерпретации списков, вы можете создать и
+# интерпретации генераторов.
+values = (-x for x in [1,2,3,4,5])
+for x in values:
+ print(x) # Выводит -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
-# Метод beg вызовет say. Если say_please равно True,
-# он изменит возвращаемое сообщение
+# В этом примере "beg" оборачивает "say".
+# Если say_please равно True, он изменит возвращаемое сообщение.
from functools import wraps
@@ -607,7 +1020,7 @@ def beg(target_function):
def wrapper(*args, **kwargs):
msg, say_please = target_function(*args, **kwargs)
if say_please:
- return "{} {}".format(msg, " Пожалуйста! У меня нет денег :(")
+ return "{} {}".format(msg, "Пожалуйста! У меня нет денег :(")
return msg
return wrapper
@@ -619,8 +1032,8 @@ def say(say_please=False):
return msg, say_please
-print(say()) # Вы не купите мне пива?
-print(say(say_please=True)) # Вы не купите мне пива? Пожалуйста! У меня нет денег :(
+print(say()) # Вы не купите мне пива?
+print(say(say_please=True)) # Вы не купите мне пива? Пожалуйста! У меня нет денег :(
```
@@ -628,16 +1041,18 @@ print(say(say_please=True)) # Вы не купите мне пива? Пожал
### Бесплатные онлайн-материалы
-* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
-* [Dive Into Python](http://www.diveintopython.net/)
-* [Официальная документация](http://docs.python.org/2.6/)
+* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
+* [Ideas for Python Projects](http://pythonpracticeprojects.com)
+* [Официальная документация](http://docs.python.org/3/)
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
-* [Python Module of the Week](http://pymotw.com/2/)
-* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
-
-### Платные
-
-* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
-* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
-* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+* [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)
+* [Python Tutorial for Intermediates](https://pythonbasics.org/)
+* [Build a Desktop App with Python](https://pythonpyqt.com/)
diff --git a/ru-ru/python3-ru.html.markdown b/ru-ru/pythonlegacy-ru.html.markdown
index 2b6b59a7..ead2af3d 100644
--- a/ru-ru/python3-ru.html.markdown
+++ b/ru-ru/pythonlegacy-ru.html.markdown
@@ -1,23 +1,23 @@
---
-language: python3
+language: Python 2 (legacy)
lang: ru-ru
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
- - ["Steven Basart", "http://github.com/xksteven"]
translators:
+ - ["Yury Timofeev", "http://twitter.com/gagar1n"]
- ["Andre Polykanine", "https://github.com/Oire"]
-filename: learnpython3-ru.py
+filename: learnpythonlegacy-ru.py
---
Язык Python был создан Гвидо ван Россумом в начале 90-х. Сейчас это один из
самых популярных языков. Я влюбился в Python за понятный и доходчивый синтаксис — это
-почти что исполняемый псевдокод.
+почти исполняемый псевдокод.
С благодарностью жду ваших отзывов: [@louiedinh](http://twitter.com/louiedinh)
или louiedinh [at] [почтовый сервис Google]
-Замечание: Эта статья относится только к Python 3.
-Если вы хотите изучить Python 2.7, обратитесь к другой статье.
+Замечание: Эта статья относится к Python 2.7, но должно работать и в других версиях Python 2.x.
+Чтобы изучить Python 3.x, обратитесь к статье по Python 3.
```python
# Однострочные комментарии начинаются с символа решётки.
@@ -37,9 +37,16 @@ filename: learnpython3-ru.py
1 + 1 #=> 2
8 - 1 #=> 7
10 * 2 #=> 20
+35 / 5 #=> 7
-# Кроме деления, которое по умолчанию возвращает число с плавающей запятой
-35 / 5 # => 7.0
+# А вот деление немного сложнее. В этом случае происходит деление
+# целых чисел, и результат автоматически округляется в меньшую сторону.
+5 / 2 #=> 2
+
+# Чтобы делить правильно, сначала нужно немного узнать о числах
+# с плавающей запятой.
+2.0 # Это число с плавающей запятой
+11.0 / 4.0 #=> 2.75 Вооот... Так гораздо лучше
# Результат целочисленного деления округляется в меньшую сторону
# как для положительных, так и для отрицательных чисел.
@@ -48,10 +55,6 @@ filename: learnpython3-ru.py
-5 // 3 # => -2
-5.0 // 3.0 # => -2.0
-# Когда вы используете числа с плавающей запятой,
-# результатом будет также число с плавающей запятой
-3 * 2.0 # => 6.0
-
# Остаток от деления
7 % 3 # => 1
@@ -61,14 +64,6 @@ filename: learnpython3-ru.py
# Приоритет операций указывается скобками
(1 + 3) * 2 #=> 8
-# Для логических (булевых) значений существует отдельный примитивный тип
-True
-False
-
-# Для отрицания используется ключевое слово not
-not True #=> False
-not False #=> True
-
# Логические операторы
# Обратите внимание: ключевые слова «and» и «or» чувствительны к регистру букв
True and False #=> False
@@ -81,6 +76,10 @@ False or True #=> True
2 == True #=> False
1 == True #=> True
+# Для отрицания используется ключевое слово not
+not True #=> False
+not False #=> True
+
# Равенство — это ==
1 == 1 #=> True
2 == 1 #=> False
@@ -95,7 +94,7 @@ False or True #=> True
2 <= 2 #=> True
2 >= 2 #=> True
-# Сравнения могут быть записаны цепочкой:
+# Сравнения могут быть записаны цепочкой!
1 < 2 < 3 #=> True
2 < 3 < 2 #=> False
@@ -103,67 +102,75 @@ False or True #=> True
"Это строка."
'Это тоже строка.'
-# И строки тоже могут складываться! Хотя лучше не злоупотребляйте этим.
+# И строки тоже можно складывать!
"Привет " + "мир!" #=> "Привет мир!"
+# ... или умножать
+"Привет" * 3 # => "ПриветПриветПривет"
+
# Со строкой можно работать, как со списком символов
"Это строка"[0] #=> 'Э'
-# Метод format используется для форматирования строк:
+# Символ % используется для форматирования строк, например:
+"%s могут быть %s" % ("строки", "интерполированы")
+
+# Новый способ форматирования строк — использование метода format.
+# Это предпочитаемый способ.
"{0} могут быть {1}".format("строки", "форматированы")
-# Вы можете повторять аргументы форматирования, чтобы меньше печатать.
-"Ехал {0} через реку, видит {0} - в реке {1}! Сунул {0} руку в реку, {1} за руку греку цап!".format("грека", "рак")
-#=> "Ехал грека через реку, видит грека - в реке рак! Сунул грека руку в реку, рак за руку греку цап!"
# Если вы не хотите считать, можете использовать ключевые слова.
"{name} хочет есть {food}".format(name="Боб", food="лазанью")
-# Если ваш код на Python 3 нужно запускать также и под Python 2.5 и ниже,
-# вы также можете использовать старый способ форматирования:
-"%s можно %s %s способом" % ("строки", "интерполировать", "старым")
-
# None является объектом
None #=> None
-# Не используйте оператор равенства '==' для сравнения
-# объектов с None. Используйте для этого 'is'
+# Не используйте оператор равенства '=='' для сравнения
+# объектов с None. Используйте для этого «is»
"etc" is None #=> False
None is None #=> True
-# Оператор «is» проверяет идентичность объектов. Он не
+# Оператор 'is' проверяет идентичность объектов. Он не
# очень полезен при работе с примитивными типами, но
# зато просто незаменим при работе с объектами.
-# None, 0 и пустые строки/списки/словари приводятся к False.
+# None, 0 и пустые строки/списки равны False.
# Все остальные значения равны True
-bool(0) # => False
-bool("") # => False
-bool([]) #=> False
-bool({}) #=> False
+0 == False #=> True
+"" == False #=> True
####################################################
## 2. Переменные и коллекции
####################################################
-# В Python есть функция Print
-print("Я Python. Приятно познакомиться!")
+# В Python есть оператор print, доступный в версиях 2.x, но удалённый в версии 3
+print "Я Python. Приятно познакомиться!"
+# В Python также есть функция print(), доступная в версиях 2.7 и 3,
+# Но для версии 2.7 нужно добавить следующий импорт модуля (раскомментируйте)):
+# from __future__ import print_function
+print("Я тоже Python! ")
# Объявлять переменные перед инициализацией не нужно.
-# По соглашению используется нижний_регистр_с_подчёркиваниями
-some_var = 5
+some_var = 5 # По соглашению используется нижний_регистр_с_подчёркиваниями
some_var #=> 5
# При попытке доступа к неинициализированной переменной
# выбрасывается исключение.
-# Об исключениях см. раздел «Поток управления и итерируемые объекты».
-some_unknown_var # Выбрасывает ошибку именования
+# См. раздел «Поток управления» для информации об исключениях.
+some_other_var # Выбрасывает ошибку именования
+
+# if может быть использован как выражение
+"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
# Списки хранят последовательности
li = []
# Можно сразу начать с заполненного списка
other_li = [4, 5, 6]
+# строка разделена в список
+a="adambard"
+list(a) #=> ['a','d','a','m','b','a','r','d']
+
# Объекты добавляются в конец списка методом append
li.append(1) # [1]
li.append(2) # [1, 2]
@@ -176,6 +183,10 @@ li.append(3) # [1, 2, 4, 3].
# Обращайтесь со списком, как с обычным массивом
li[0] #=> 1
+# Присваивайте новые значения уже инициализированным индексам с помощью =
+li[0] = 42
+li[0] # => 42
+li[0] = 1 # Обратите внимание: возвращаемся на исходное значение
# Обратимся к последнему элементу
li[-1] #=> 3
@@ -197,11 +208,11 @@ li[::-1] # => [3, 4, 2, 1]
# li[начало:конец:шаг]
# Удаляем произвольные элементы из списка оператором del
-del li[2] # [1, 2, 3]
+del li[2] # li теперь [1, 2, 3]
# Вы можете складывать, или, как ещё говорят, конкатенировать списки
-# Обратите внимание: значения li и other_li при этом не изменились.
li + other_li #=> [1, 2, 3, 4, 5, 6] — Замечание: li и other_li не изменяются
+# Обратите внимание: значения li и other_li при этом не изменились.
# Объединять списки можно методом extend
li.extend(other_li) # Теперь li содержит [1, 2, 3, 4, 5, 6]
@@ -231,7 +242,6 @@ d, e, f = 4, 5, 6
# Обратите внимание, как легко поменять местами значения двух переменных
e, d = d, e # теперь d == 5, а e == 4
-
# Словари содержат ассоциативные массивы
empty_dict = {}
# Вот так описывается предзаполненный словарь
@@ -241,17 +251,13 @@ filled_dict = {"one": 1, "two": 2, "three": 3}
# что индекс — у словарей он называется ключом — не обязан быть числом
filled_dict["one"] #=> 1
-# Все ключи в виде списка получаются с помощью метода keys().
-# Его вызов нужно обернуть в list(), так как обратно мы получаем
-# итерируемый объект, о которых поговорим позднее.
-list(filled_dict.keys()) # => ["three", "two", "one"]
+# Можно получить все ключи в виде списка с помощью метода keys
+filled_dict.keys() #=> ["three", "two", "one"]
# Замечание: сохранение порядка ключей в словаре не гарантируется
# Ваши результаты могут не совпадать с этими.
-# Все значения в виде списка можно получить с помощью values().
-# И снова нам нужно обернуть вызов в list(), чтобы превратить
-# итерируемый объект в список.
-list(filled_dict.values()) # => [3, 2, 1]
+# Можно получить и все значения в виде списка, используйте метод values
+filled_dict.values() #=> [3, 2, 1]
# То же самое замечание насчёт порядка ключей справедливо и здесь
# При помощи оператора in можно проверять ключи на вхождение в словарь
@@ -268,27 +274,28 @@ filled_dict.get("four") #=> None
# возвращено при отсутствии указанного ключа
filled_dict.get("one", 4) #=> 1
filled_dict.get("four", 4) #=> 4
+# Обратите внимание, что filled_dict.get("four") всё ещё => None
+# (get не устанавливает значение элемента словаря)
-# Метод setdefault вставляет пару ключ-значение, только если такого ключа нет
+# Присваивайте значение ключам так же, как и в списках
+filled_dict["four"] = 4 # теперь filled_dict["four"] => 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» из словаря
-
# Множества содержат... ну, в общем, множества
+# (которые похожи на списки, только в них не может быть дублирующихся элементов)
empty_set = set()
-# Инициализация множества набором значений.
-# Да, оно выглядит примерно как словарь… ну извините, так уж вышло.
-filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
+# Инициализация множества набором значений
+some_set = set([1,2,2,3,4]) # some_set теперь равно set([1, 2, 3, 4])
+
+# Порядок сортировки не гарантируется, хотя иногда они выглядят отсортированными
+another_set = set([4, 3, 2, 2, 1]) # another_set теперь set([1, 2, 3, 4])
-# Множеству можно назначать новую переменную
-filled_set = some_set
+# Начиная с Python 2.7, вы можете использовать {}, чтобы объявить множество
+filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
# Добавление новых элементов в множество
filled_set.add(5) # filled_set равно {1, 2, 3, 4, 5}
@@ -309,7 +316,7 @@ filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
####################################################
-## 3. Поток управления и итерируемые объекты
+## 3. Поток управления
####################################################
# Для начала заведём переменную
@@ -325,13 +332,17 @@ else: # Это тоже необязательно.
print("some_var равно 10.")
-# Циклы For проходят по спискам. Результат:
- # собака — это млекопитающее
- # кошка — это млекопитающее
- # мышь — это млекопитающее
+"""
+Циклы For проходят по спискам
+
+Результат:
+ собака — это млекопитающее
+ кошка — это млекопитающее
+ мышь — это млекопитающее
+"""
for animal in ["собака", "кошка", "мышь"]:
- # Можете использовать format() для интерполяции форматированных строк
- print("{} — это млекопитающее".format(animal))
+ # Можете использовать оператор % для интерполяции форматированных строк
+ print("%s — это млекопитающее" % animal)
"""
«range(число)» возвращает список чисел
@@ -359,6 +370,8 @@ while x < 4:
x += 1 # Краткая запись для x = x + 1
# Обрабатывайте исключения блоками try/except
+
+# Работает в Python 2.6 и выше:
try:
# Чтобы выбросить ошибку, используется raise
raise IndexError("Это ошибка индекса")
@@ -371,37 +384,6 @@ except (TypeError, NameError):
else: # Необязательное выражение. Должно следовать за последним блоком except
print("Всё хорошо!") # Выполнится, только если не было никаких исключений
-# Python предоставляет фундаментальную абстракцию,
-# которая называется итерируемым объектом (an iterable).
-# Итерируемый объект — это объект, который воспринимается как последовательность.
-# Объект, который возвратила функция range(), итерируемый.
-filled_dict = {"one": 1, "two": 2, "three": 3}
-our_iterable = filled_dict.keys()
-print(our_iterable) #=> range(1,10). Это объект, реализующий интерфейс iterable
-
-# Мы можем проходить по нему циклом.
-for i in our_iterable:
- print(i) # Выводит one, two, three
-
-# Но мы не можем обращаться к элементу по индексу.
-our_iterable[1] # Выбрасывает ошибку типа
-
-# Итерируемый объект знает, как создавать итератор.
-our_iterator = iter(our_iterable)
-
-# Итератор может запоминать состояние при проходе по объекту.
-# Мы получаем следующий объект, вызывая функцию __next__.
-our_iterator.__next__() #=> "one"
-
-# Он сохраняет состояние при вызове __next__.
-our_iterator.__next__() #=> "two"
-our_iterator.__next__() #=> "three"
-
-# Возвратив все данные, итератор выбрасывает исключение StopIterator
-our_iterator.__next__() # Выбрасывает исключение остановки итератора
-
-# Вы можете получить сразу все элементы итератора, вызвав на нём функцию list().
-list(filled_dict.keys()) #=> Возвращает ["one", "two", "three"]
####################################################
@@ -419,7 +401,8 @@ add(5, 6) #=> выводит «x равен 5, а y равен 6» и возвр
# Другой способ вызова функции — вызов с именованными аргументами
add(y=6, x=5) # Именованные аргументы можно указывать в любом порядке.
-# Вы можете определить функцию, принимающую переменное число аргументов
+# Вы можете определить функцию, принимающую переменное число аргументов,
+# которые будут интерпретированы как кортеж, если вы не используете *
def varargs(*args):
return args
@@ -427,7 +410,8 @@ varargs(1, 2, 3) #=> (1,2,3)
# А также можете определить функцию, принимающую переменное число
-# именованных аргументов
+# именованных аргументов, которые будут интерпретированы как словарь,
+# если вы не используете **
def keyword_args(**kwargs):
return kwargs
@@ -452,6 +436,14 @@ 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 pass_all_the_args(*args, **kwargs):
+ all_the_args(*args, **kwargs)
+ print varargs(*args)
+ print keyword_args(**kwargs)
+
# Область определения функций
x = 5
@@ -510,7 +502,7 @@ class Human(object):
# Метод экземпляра. Все методы принимают self в качестве первого аргумента
def say(self, msg):
- return "{name}: {message}".format(name=self.name, message=msg)
+ return "%s: %s" % (self.name, msg)
# Метод класса разделяется между всеми экземплярами
# Они вызываются с указыванием вызывающего класса в качестве первого аргумента
@@ -563,6 +555,9 @@ from math import *
# Можете сокращать имена модулей
import math as m
math.sqrt(16) == m.sqrt(16) #=> True
+# Вы также можете убедиться, что функции эквивалентны
+from math import sqrt
+math.sqrt == m.sqrt == sqrt # => True
# Модули в Python — это обычные Python-файлы. Вы
# можете писать свои модули и импортировать их. Название
@@ -586,14 +581,15 @@ def double_numbers(iterable):
# Он не возвращает все значения разом, а создаёт каждое из них при каждой
# итерации. Это значит, что значения больше 15 в double_numbers
# обработаны не будут.
-# Обратите внимание: range — это тоже генератор.
+# Обратите внимание: xrange — это генератор, который делает то же, что и range.
# Создание списка чисел от 1 до 900000000 требует много места и времени.
+# xrange создаёт объект генератора, а не список сразу, как это делает range.
# Если нам нужно имя переменной, совпадающее с ключевым словом Python,
# мы используем подчёркивание в конце
-range_ = range(1, 900000000)
+xrange_ = xrange(1, 900000000)
# Будет удваивать все числа, пока результат не превысит 30
-for i in double_numbers(range_):
+for i in double_numbers(xrange_):
print(i)
if i >= 30:
break
@@ -634,10 +630,9 @@ print(say(say_please=True)) # Вы не купите мне пива? Пожал
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
* [Dive Into Python](http://www.diveintopython.net/)
-* [Ideas for Python Projects](http://pythonpracticeprojects.com)
-* [Официальная документация](http://docs.python.org/3/)
+* [Официальная документация](http://docs.python.org/2.6/)
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
-* [Python Module of the Week](http://pymotw.com/3/)
+* [Python Module of the Week](http://pymotw.com/2/)
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
### Платные
diff --git a/ru-ru/ruby-ru.html.markdown b/ru-ru/ruby-ru.html.markdown
index 69b5fb46..8b263be6 100644
--- a/ru-ru/ruby-ru.html.markdown
+++ b/ru-ru/ruby-ru.html.markdown
@@ -10,6 +10,7 @@ contributors:
- ["Nick LaMuro", "https://github.com/NickLaMuro"]
translators:
- ["Alexey Makarov", "https://github.com/Anakros"]
+ - ["Vasiliy Petrov", "https://github.com/Saugardas"]
---
```ruby
@@ -35,6 +36,13 @@ translators:
8 - 1 #=> 7
10 * 2 #=> 20
35 / 5 #=> 7
+2**5 #=> 32
+5 % 3 #=> 2
+
+# Побитовые операторы
+3 & 5 #=> 1
+3 | 5 #=> 7
+3 ^ 5 #=> 6
# Арифметика -- это синтаксический сахар
# над вызовом метода для объекта
@@ -57,8 +65,6 @@ false.class #=> FalseClass
# Операция неравенства
1 != 1 #=> false
2 != 1 #=> true
-!true #=> false
-!false #=> true
# nil -- имеет такое же логическое значение, как и false
@@ -72,6 +78,26 @@ false.class #=> FalseClass
2 <= 2 #=> true
2 >= 2 #=> true
+# Оператор сравнения <=>
+1 <=> 10 #=> -1
+10 <=> 1 #=> 1
+1 <=> 1 #=> 0
+
+# Булевы операторы
+true && false #=> false
+true || false #=> true
+!true #=> false
+
+# Существуют альтернативные версии логических операторов с гораздо меньшим
+# приоритетом. Они используются для связывания операций, пока одна из них
+# не вернёт false или true
+
+# `do_something_else` будет вызван если `do_something` вернёт истинное значение
+do_something() and do_something_else()
+# `log_error` будет вызван если `do_something` вернёт (nil/false)
+do_something() or log_error()
+
+
# Строки -- это объекты
'Я строка'.class #=> String
@@ -82,6 +108,16 @@ placeholder = "использовать интерполяцию строк"
#=> "Я могу использовать интерполяцию строк,
# когда создаю строку с двойными кавычками"
+# Конкатенация строк
+'hello ' + 'world' #=> "hello world"
+'hello ' + 3 #=> TypeError: can't convert Fixnum into String
+'hello ' + 3.to_s #=> "hello 3"
+
+# Умножение строк
+'hello ' * 3 #=> "hello hello hello "
+
+# Добавление к строке
+'hello' << ' world' #=> "hello world"
# печатать в стандартный вывод
puts "Я печатаюсь!"
@@ -134,6 +170,7 @@ array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
# Значение в массиве можно получить по индексу с левой границы
array[0] #=> 1
+array.first #=> 1
array[12] #=> nil
# Как и арифметика, доступ к значению в массиве
@@ -143,15 +180,26 @@ array.[] 12 #=> nil
# Также, можно получить по индексу с правой границы
array[-1] #=> 5
+array.last #=> 5
-# С заданными левой и правой границами индексов
-array[2, 4] #=> [3, 4, 5]
+# Задавая индекс и количество элементов
+array[0,2] #=> [1, 2]
+array[0,999] #=> [1, 2, 3, 4, 5]
# Или с использованием диапазона значений
array[1..3] #=> [2, 3, 4]
+# Перестановка элементов в обратном порядке
+a = [1, 2, 3]
+a.reverse #=> [3, 2, 1]
+
# Вот так можно добавить значение в массив
array << 6 #=> [1, 2, 3, 4, 5, 6]
+# Или так
+array.push(6) #=> [1, 2, 3, 4, 5, 6]
+
+# Проверка включения элемента в массив
+array.include?(1) #=> true
# Хэши -- это массив пар "ключ => значение".
# Хэши объявляются с использованием фигурных скобок:
@@ -174,19 +222,33 @@ new_hash = { defcon: 3, action: true}
new_hash.keys #=> [:defcon, :action]
+# Проверка существования ключа и значения в хеше
+new_hash.key?(:defcon) #=> true
+new_hash.value?(3) #=> true
+
# Массивы и Хэши -- перечисляемые типы данных
# У них есть много полезных методов, например: each, map, count и другие
# Управление ходом выполнения (Управляющие структуры)
+# Условия
if true
- "Если истина"
+ 'Если истина'
elsif false
- "Иначе, если ложь (опционально)"
+ 'Иначе, если ложь (опционально)'
else
- "Во всех других случаях"
+ 'Во всех других случаях (тоже опционально)'
end
+# Если условие контролирует выполнение не блока кода, а единственного выражения,
+# можно использовать постфиксную запись условного оператора
+warnings = ['Отсутствует отчество', 'Слишком короткий адрес']
+puts("Обратите внимание:\n" + warnings.join("\n")) if !warnings.empty?
+
+# Иногда условие лучше звучит с `unless`, чем с `if`
+puts("Обратите внимание:\n" + warnings.join("\n")) unless warnings.empty?
+
+# Циклы
for counter in 1..5
puts "итерация #{counter}"
end
@@ -220,7 +282,7 @@ end
#=> итерация 5
# Вы также можете ограничивать блоки фигурными скобками:
-(1..5).each {|counter| puts "итерация #{counter}"}
+(1..5).each { |counter| puts "итерация #{counter}" }
# Содержимое структурных данных также можно перебирать используя "each":
array.each do |element|
@@ -230,6 +292,21 @@ hash.each do |key, value|
puts "#{key} -- это #{value}"
end
+# Если вам нужен индекс вы можете использовать "each_with_index"
+# В этом случае индекс будет начинаться с 0
+array.each_with_index do |element, index|
+ puts "#{element} is number #{index} in the array"
+end
+
+# Если индекс должен начинаться с произвольного значения,
+# используйте "each.with_index"
+[:q, :w, :e].each.with_index(100) do |element, index|
+ puts "#{element} -> #{index}"
+end
+#=> :q -> 100
+#=> :w -> 101
+#=> :e -> 102
+
counter = 1
while counter <= 5 do
puts "итерация #{counter}"
@@ -241,22 +318,65 @@ end
#=> итерация 4
#=> итерация 5
+# Существует большое количество других полезных функций,
+# например "map", "reduce", "inject", и так далее. Например, "map"
+# выполняет связанный с ним блок для каждого элемента перечисляемого объекта,
+# возвращая массив результатов.
+array = [1, 2, 3, 4, 5]
+doubled = array.map do |element|
+ element * 2
+end
+puts doubled
+#=> [2, 4, 6, 8, 10]
+puts array
+#=> [1, 2, 3, 4, 5]
+
grade = 'B'
case grade
when 'A'
- puts "Так держать, детка!"
+ puts 'Так держать, детка!'
when 'B'
- puts "Тебе повезёт в следующий раз"
+ puts 'Тебе повезёт в следующий раз'
when 'C'
- puts "Ты можешь сделать лучше"
+ puts 'Ты можешь сделать лучше'
when 'D'
- puts "Выскоблил последнее"
+ puts 'Выскоблил последнее'
when 'F'
- puts "Ты провалился!"
+ puts 'Ты провалился!'
else
- puts "Альтернативная система оценок, да?"
+ puts 'Альтернативная система оценок, да?'
end
+#=> 'Тебе повезёт в следующий раз'
+
+# в when также можно использовать диапазоны
+grade = 82
+case grade
+when 90..100
+ puts 'Ура!'
+when 80...90
+ puts 'Хорошая работа!'
+else
+ puts 'Вы не справились!'
+end
+#=> 'Хорошая работа!'
+
+# Обработка исключений
+begin
+ # здесь код, который может вызвать исключение
+ raise NoMemoryError, 'У вас закончилась память.'
+rescue NoMemoryError => exception_variable
+ puts 'Был вызван NoMemoryError', exception_variable
+rescue RuntimeError => other_exception_variable
+ puts 'Был вызван RuntimeError'
+else
+ puts 'Этот код будет выполнятся, если исключения не были вызваны'
+ensure
+ puts 'Этот код выполняется всегда'
+end
+#=> Был вызван NoMemoryError
+#=> У вас закончилась память.
+#=> Этот код выполняется всегда
# Функции
@@ -298,6 +418,43 @@ surround { puts 'hello world' }
# }
+# Вы можете передать блок методу
+# "&" отмечает ссылку на переданный блок
+def guests(&block)
+ block.call 'some_argument'
+end
+
+# Чтобы метод принимал произвольное количество аргументов, спереди
+# одного из параметров ставится префикс "*"
+def method(first, *rest)
+ p rest
+end
+method(1, 2, 3, 4) #=> [2, 3, 4]
+
+# Если метод возвращает массив. можно использовать множественное присваивание
+def foods
+ ['pancake', 'sandwich', 'quesadilla']
+end
+breakfast, lunch, dinner = foods
+breakfast #=> 'pancake'
+dinner #=> 'quesadilla'
+
+# По соглашению, все методы, возвращающие булево значение
+# оканчиваются символом "?"
+5.even? #=> false
+5.odd? #=> true
+
+# Если метод заканчивается восклицательным знаком, значит он делает что-то
+# опасное или необратимое, например изменяет внутреннее состояние объекта.
+# Многие из таких методов-мутаторов часто имеют "безопасную" версию без "!"
+# которая возвращает новое значение
+company_name = "Dunder Mifflin"
+company_name.upcase #=> "DUNDER MIFFLIN"
+company_name #=> "Dunder Mifflin"
+company_name.upcase! # Изменяем зачение company_name!
+company_name #=> "DUNDER MIFFLIN"
+
+
# Определение класса с помощью ключевого слова "class"
class Human
@@ -323,6 +480,13 @@ class Human
@name
end
+ # Тоже самое можно определить с помощью attr_accessor
+ attr_accessor :name
+
+ # Также можно создать методы только для записи или чтения
+ attr_reader :name
+ attr_writer :name
+
# Метод класса определяется с ключевым словом "self",
# чтобы можно было отличить его от метода экземпляра класса.
# Он может быть вызван только на уровне класса, но не экземпляра.
diff --git a/ru-ru/rust-ru.html.markdown b/ru-ru/rust-ru.html.markdown
new file mode 100644
index 00000000..9293a40e
--- /dev/null
+++ b/ru-ru/rust-ru.html.markdown
@@ -0,0 +1,313 @@
+---
+language: rust
+
+filename: learnrust-ru.rs
+contributors:
+ - ["P1start", "http://p1start.github.io/"]
+translators:
+ - ["Anatolii Kosorukov", "https://github.com/java1cprog"]
+ - ["Vasily Starostin", "https://github.com/Basil22"]
+lang: ru-ru
+
+---
+
+Язык Rust разработан в Mozilla Research. Он сочетает низкоуровневую производительность с удобством языка высокого уровня и одновременно гарантирует безопасность памяти.
+
+Он достигает этих целей без сборщика мусора или сложной среды выполнения, что позволяет использовать библиотеки Rust как прямую замену
+C-библиотек. И наоборот, Rust умеет использовать готовые С-библиотеки как есть, без накладных расходов.
+
+Первый выпуск Rust, 0.1, произошел в январе 2012 года. В течение 3 лет развитие продвигалось настолько быстро, что язык серьезно менялся без сохранения совместимости. Это дало возможность обкатать и отполировать синтаксис и возможности языка.
+
+15 мая 2015 года был выпущен Rust 1.0 с полной гарантией обратной совместимости. Сборка поставляется в трех вариантах: стабильная версия, бета-версия, ночная версия. Все нововведения языка сперва обкатываются на ночной и бета-версиях, и только потом попадают в стабильную. Выход очередной версии происходит раз в 6 недель. В 2018 году вышло второе большое обновление языка, добавившее ему новых возможностей.
+
+Хотя Rust является языком относительно низкого уровня, он имеет все возможности высокоуровневых языков: процедурное, объектное, функциональное, шаблонное и другие виды программирования. На данный момент Rust является одним из самых мощных (а может быть и самым) по возможностям среди статически типизированных языков. Это делает Rust не только быстрым, но и простым и эффективным для разработки сложного кода.
+
+
+```rust
+// Это однострочный комментарий
+//
+
+/// Так выглядит комментарий для документации
+/// # Examples
+///
+/// ```
+/// let seven = 7
+/// ```
+
+///////////////
+// 1. Основы //
+///////////////
+
+// Функции
+// `i32` это целочисленный знаковый тип 32-bit
+#[allow(dead_code)]
+fn add2(x: i32, y: i32) -> i32 {
+ // метод возвращает сумму x и y
+ x + y
+}
+
+// Главная функция программы
+#[allow(unused_variables)]
+#[allow(unused_assignments)]
+#[allow(dead_code)]
+fn main() {
+ // Числа //
+
+ // неизменяемая переменная
+ let x: i32 = 1;
+
+ // Суффиксы целое/дробное
+ let y: i32 = 13i32;
+ let f: f64 = 1.3f64;
+
+ // Автоматическое выведение типа данных
+ // В большинстве случаев компилятор Rust может вычислить
+ // тип переменной, поэтому вам не нужно явно указывать тип.
+
+ let implicit_x = 1;
+ let implicit_f = 1.3;
+
+ // Арифметика
+ let sum = x + y + 13;
+
+ // Изменяемая переменная
+ let mut mutable = 1;
+ mutable = 4;
+ mutable += 2;
+
+ // Строки //
+
+ // Строковые литералы
+ let x: &str = "hello world!";
+
+ // Печать на консоль
+ println!("{} {}", f, x); // 1.3 hello world
+
+ // `String` – изменяемая строка
+ let s: String = "hello world".to_string();
+
+ // Строковый срез - неизменяемое представление части строки
+ // Представляет собой пару из указателя на начало фрагмента и его длины
+
+ let s_slice: &str = &s;
+
+ println!("{} {}", s, s_slice); // hello world hello world
+
+ // Vectors/arrays //
+
+ // фиксированный массив
+ let four_ints: [i32; 4] = [1, 2, 3, 4];
+
+ // динамический массив
+ let mut vector: Vec<i32> = vec![1, 2, 3, 4];
+ vector.push(5);
+
+ // Срез - неизменяемое представление значений вектора
+ let slice: &[i32] = &vector;
+
+ // Используйте шаблон `{:?}`для печати отладочной информации структур с данными
+ println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
+
+ // Кортежи //
+
+ // Кортеж - это фиксированный набор.
+ // В нём могут находиться значения разных типов данных.
+ let x: (i32, &str, f64) = (1, "hello", 3.4);
+
+ // Инициализация группы переменных `let`
+ let (a, b, c) = x;
+ println!("{} {} {}", a, b, c); // 1 hello 3.4
+
+ // Доступ по индексу
+ println!("{}", x.1); // hello
+
+ //////////////
+ // 2. Типы //
+ //////////////
+
+ // Структура
+ struct Point {
+ x: i32,
+ y: i32,
+ }
+
+ let origin: Point = Point { x: 0, y: 0 };
+
+ // Структуры могут быть с безымянными полями ‘tuple struct’
+ struct Point2(i32, i32);
+
+ let origin2 = Point2(0, 0);
+
+ // Перечисление
+ enum Direction {
+ Left,
+ Right,
+ Up,
+ Down,
+ }
+
+ let up = Direction::Up;
+
+ // Перечисление с полями
+ // В отличие от C и C++ компилятор автоматически следит за тем,
+ // какой именно тип хранится в перечислении.
+ enum OptionalI32 {
+ AnI32(i32),
+ Nothing,
+ }
+
+ let two: OptionalI32 = OptionalI32::AnI32(2);
+ let nothing = OptionalI32::Nothing;
+
+ // Обобщенные типы данных //
+
+ struct Foo<T> { bar: T }
+
+ // Частоиспользуемое перечисление стандартной библиотеки `Option`
+ enum Optional<T> {
+ SomeVal(T),
+ NoVal,
+ }
+
+ // Методы //
+
+ impl<T> Foo<T> {
+ fn get_bar(self) -> T {
+ self.bar
+ }
+ }
+
+ let a_foo = Foo { bar: 1 };
+ println!("{}", a_foo.get_bar()); // 1
+
+ // Типаж
+
+ trait Frobnicate<T> {
+ fn frobnicate(self) -> Option<T>;
+ }
+
+ impl<T> Frobnicate<T> for Foo<T> {
+ fn frobnicate(self) -> Option<T> {
+ Some(self.bar)
+ }
+ }
+
+ let another_foo = Foo { bar: 1 };
+ println!("{:?}", another_foo.frobnicate()); // Some(1)
+
+ /////////////////////////////////
+ // 3. Сопоставление по шаблону //
+ /////////////////////////////////
+
+ let foo = OptionalI32::AnI32(1);
+ match foo {
+ OptionalI32::AnI32(n) => println!("it’s an i32: {}", n),
+ OptionalI32::Nothing => println!("it’s nothing!"),
+ }
+
+ // Более сложный пример
+ struct FooBar { x: i32, y: OptionalI32 }
+ let bar = FooBar { x: 15, y: OptionalI32::AnI32(32) };
+
+ match bar {
+ FooBar { x: 0, y: OptionalI32::AnI32(0) } =>
+ println!("The numbers are zero!"),
+ FooBar { x: n, y: OptionalI32::AnI32(m) } if n == m =>
+ println!("The numbers are the same"),
+ FooBar { x: n, y: OptionalI32::AnI32(m) } =>
+ println!("Different numbers: {} {}", n, m),
+ FooBar { x: _, y: OptionalI32::Nothing } =>
+ println!("The second number is Nothing!"),
+ }
+
+ //////////////////////////////////////////////
+ // 4. Управление ходом выполнения программы //
+ //////////////////////////////////////////////
+
+ // `for` loops/iteration
+ let array = [1, 2, 3];
+ for i in array.iter() {
+ println!("{}", i);
+ }
+
+ // Диапазоны
+ for i in 0u32..10 {
+ print!("{} ", i);
+ }
+ println!("");
+ // prints `0 1 2 3 4 5 6 7 8 9 `
+
+ // `if`
+ if 1 == 1 {
+ println!("Maths is working!");
+ } else {
+ println!("Oh no...");
+ }
+
+ // `if` as expression
+ let value = if true {
+ "good"
+ } else {
+ "bad"
+ };
+
+ // `while` loop
+ while 1 == 1 {
+ println!("The universe is operating normally.");
+ break;
+ }
+
+ // Infinite loop
+ loop {
+ println!("Hello!");
+ break;
+ }
+
+ //////////////////////////////////
+ // 5. Защита памяти и указатели //
+ //////////////////////////////////
+
+ // Владеющий указатель – такой указатель может быть только один
+ // Это значит, что при выходе из блока переменная автоматически становится недействительной.
+ let mut mine: Box<i32> = Box::new(3);
+ *mine = 5; // dereference
+ // Здесь, `now_its_mine` получает во владение `mine`. Т.е. `mine` была перемещена.
+ let mut now_its_mine = mine;
+ *now_its_mine += 2;
+
+ println!("{}", now_its_mine); // 7
+ // println!("{}", mine);
+
+ // Ссылки - это неизменяемые указатели
+ // Если ссылка получает значения, то говорят, что она заимствует это значение.
+ // Такое значение не может быть изменено или перемещено.
+ let mut var = 4;
+ var = 3;
+ let ref_var: &i32 = &var;
+
+ println!("{}", var);
+ println!("{}", *ref_var);
+ // var = 5; // не скомпилируется
+ // *ref_var = 6; // и это
+
+ // Изменяемые ссылки
+ //
+ let mut var2 = 4;
+ let ref_var2: &mut i32 = &mut var2;
+ *ref_var2 += 2; // '*' используется для изменения значения
+
+ println!("{}", *ref_var2); // 6 , // var2 would not compile.
+ // ref_var2 имеет тип &mut i32, т.е. он содержит ссылку на i32, а не значение.
+ // var2 = 2; // не скомпилируется, т.к. эта переменная уже была заимствована ранее
+}
+
+```
+
+## Более подробная информация о языке
+
+Уже есть хорошие книги для изучающих Rust. Основным источником остаётся
+[The Rust Programming Language](http://doc.rust-lang.org/book/index.html)
+
+Для компиляции программ при изучении языка весьма удобно использовать
+[Rust playpen](http://play.rust-lang.org).
+Множество ресурсов на разных языках можно найти в [этом проекте](https://github.com/ctjhoa/rust-learning).
diff --git a/ru-ru/sql-ru.html.markdown b/ru-ru/sql-ru.html.markdown
new file mode 100644
index 00000000..7353a175
--- /dev/null
+++ b/ru-ru/sql-ru.html.markdown
@@ -0,0 +1,120 @@
+---
+language: SQL
+filename: learnsql-ru.sql
+contributors:
+ - ["Bob DuCharme", "http://bobdc.com/"]
+translators:
+ - ["Shaltaev", "https://github.com/shaltaev"]
+ - ["Andre Polykanine", "https://github.com/Menelion"]
+lang: ru-ru
+---
+
+Язык структурированных запросов (SQL) — это стандартный язык ISO для создания
+и работы с базами данных, хранящимися в наборе таблиц. Реализации обычно
+добавляют свои собственные расширения к языку;
+[Сравнение различных реализаций SQL](http://troels.arvin.dk/db/rdbms/) — хороший справочник по различиям в продуктах.
+
+Реализации обычно предоставляют приглашение командной строки, где вы можете
+вводить команды, описанные ниже, в интерактивном режиме, также есть способ
+выполнить серию таких команд, сохранённых в файле скрипта.
+(Результат того, что вы сделали с помощью интерактивного режима, является
+хорошим примером того, что не стандартизировано, — большинство реализаций SQL
+поддерживают ключевые слова QUIT, EXIT или оба).
+
+Некоторые команды ниже предполагают использование
+[демонстрационного образца базы данных сотрудников от MySQL](https://dev.mysql.com/doc/employee/en/), доступного на [Github](https://github.com/datacharmer/test_db).
+Следовательно, для повторения команд в локальном окружении он должен быть загружен.
+Файлы на github — это скрипты с командами, которые схожи с командами ниже,
+которые создают и манипулируют таблицами и данными о сотрудниках вымышленной
+компании. Синтаксис для запуска этих скриптов будет зависеть от используемой
+вами реализации SQL. Обычно используется утилита, запускаемая из командной
+строки в вашей операционной системе.
+
+```sql
+-- Комментарии начинаются с двух дефисов. Завершайте каждую команду
+-- точкой с запятой.
+
+-- SQL не учитывает регистр букв для ключевых слов. Примеры команд здесь
+-- следуют соглашению о написании в верхнем регистре, потому что
+-- это позволяет легче отличить их от имён баз, таблиц и колонок.
+
+-- Создание и удаление базы данных. Имена базы и таблицы чувствительны
+-- к регистру букв.
+CREATE DATABASE someDatabase;
+DROP DATABASE someDatabase;
+
+-- Список доступных баз.
+SHOW DATABASES;
+
+-- Выбор базы для работы.
+USE employees;
+
+-- Выбрать все строки и колонки из таблицы «departments» (отделы) текущей базы.
+-- В интерактивном режиме обыч но результат будет выведен на экран.
+SELECT * FROM departments;
+
+-- Тот же запрос, что и выше, но выбор только колонок «dept_no» и «dept_name».
+-- Разбиение команд на несколько строк допустимо.
+SELECT dept_no,
+ dept_name FROM departments;
+
+-- В данном случае будут выбраны все колонки, но только первые 5 строк.
+SELECT * FROM departments LIMIT 5;
+
+-- Выбор названий отделов, содержащих подстроку «en».
+SELECT dept_name FROM departments WHERE dept_name LIKE '%en%';
+
+-- Выбор всех колонок, где названия отделов начинаются на «S»,
+-- после которой идёт ровно четыре символа.
+SELECT * FROM departments WHERE dept_name LIKE 'S____';
+
+-- Выбор всех должностей из таблицы «titles», но без повторений.
+SELECT DISTINCT title FROM titles;
+
+-- В дополнение к предыдущему запросу результат будет отсортирован
+-- в алфавитном порядке (с учётом регистра).
+SELECT DISTINCT title FROM titles ORDER BY title;
+
+-- Показать число строк в таблице отделов.
+SELECT COUNT(*) FROM departments;
+
+-- Показать число строк, где название отдела содержит подстроку «en»
+SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%';
+
+-- Объединение информации из нескольких таблиц:
+-- В таблице «titles» перечислены должности, кто их занимал по номеру сотрудника,
+-- а также с какой даты по какую. Получим эту информацию, но используем номера
+-- сотрудников как ссылку на таблицу «employees», чтобы получить имя и фамилию
+-- каждого сотрудника. Выводим только 10 строк.
+SELECT employees.first_name, employees.last_name,
+ titles.title, titles.from_date, titles.to_date
+FROM titles INNER JOIN employees ON
+ employees.emp_no = titles.emp_no LIMIT 10;
+
+-- Список всех таблиц во всех базах. Реализации обычно предоставляют
+-- собственные сокращения, чтобы показать все таблицы текущей базы.
+SELECT * FROM INFORMATION_SCHEMA.TABLES
+WHERE TABLE_TYPE='BASE TABLE';
+
+-- Создать таблицу с именем tablename1 и двумя колонками в текущей базе.
+-- Для колонок имеется множество параметров, таких как тип данных.
+CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20));
+
+-- Вставляем строку данных в таблицу «tablename1». Предполагаем, что таблица
+-- настроена таким образом, чтобы принимать эти значения.
+INSERT INTO tablename1 VALUES('Richard','Mutt');
+
+-- В таблице «tablename1» изменить значение fname на «John»
+-- для каждой строки, где колонка lname равна «Mutt».
+UPDATE tablename1 SET fname='John' WHERE lname='Mutt';
+
+-- Удалить из таблицы «tablename1» строки,
+-- где значение колонки lname начинается с «M».
+DELETE FROM tablename1 WHERE lname like 'M%';
+
+-- Удалить все строки из таблицы «tablename1». В итоге получим пустую таблицу.
+DELETE FROM tablename1;
+
+-- Удалить таблицу «tablename1» полностью.
+DROP TABLE tablename1;
+```
diff --git a/ru-ru/swift-ru.html.markdown b/ru-ru/swift-ru.html.markdown
index 7ff660e1..f2b1fd36 100644
--- a/ru-ru/swift-ru.html.markdown
+++ b/ru-ru/swift-ru.html.markdown
@@ -376,14 +376,14 @@ print("Имя :\(name)") // Имя: Яков
// Протокол `Error` используется для перехвата выбрасываемых ошибок
enum MyError: Error {
- case BadValue(msg: String)
- case ReallyBadValue(msg: String)
+ case badValue(msg: String)
+ case reallyBadValue(msg: String)
}
// фунции помеченные словом `throws` должны вызываться с помощью `try`
func fakeFetch(value: Int) throws -> String {
guard 7 == value else {
- throw MyError.ReallyBadValue(msg: "Действительно плохое значение")
+ throw MyError.reallyBadValue(msg: "Действительно плохое значение")
}
return "тест"
@@ -401,7 +401,7 @@ func testTryStuff() {
do {
// обычно try оператор, позволяющий обработать ошибку в `catch` блоке
try fakeFetch(value: 1)
- } catch MyError.BadValue(let msg) {
+ } catch MyError.badValue(let msg) {
print("Ошибка: \(msg)")
} catch {
// все остальное
@@ -535,49 +535,49 @@ if let circle = myEmptyCircle {
// Они могут содержать методы подобно классам.
enum Suit {
- case Spades, Hearts, Diamonds, Clubs
+ case spades, hearts, diamonds, clubs
func getIcon() -> String {
switch self {
- case .Spades: return "♤"
- case .Hearts: return "♡"
- case .Diamonds: return "♢"
- case .Clubs: return "♧"
+ case .spades: return "♤"
+ case .hearts: return "♡"
+ case .diamonds: return "♢"
+ case .clubs: return "♧"
}
}
}
// Значения перечислений допускают сокращенный синтаксис, нет необходимости
// указывать тип перечисления, когда переменная объявляется явно
-var suitValue: Suit = .Hearts
+var suitValue: Suit = .hearts
// Значения нецелочисленных перечислений должны быть указаны явно
// или могут выводится с помощью функции `rawValue` из имени
enum BookName: String {
- case John
- case Luke = "Лука"
+ case john
+ case luke = "Лука"
}
-print("Имя: \(BookName.John.rawValue)")
+print("Имя: \(BookName.john.rawValue)")
// Перечисление (enum) со связанными значениями
enum Furniture {
// Связать с типом Int
- case Desk(height: Int)
+ case desk(height: Int)
// Связать с типами String и Int
- case Chair(String, Int)
+ case chair(String, Int)
func description() -> String {
switch self {
- case .Desk(let height):
+ case .desk(let height):
return "Письменный стол высотой \(height) см."
- case .Chair(let brand, let height):
+ case .chair(let brand, let height):
return "Стул марки \(brand) высотой \(height) см."
}
}
}
-var desk: Furniture = .Desk(height: 80)
+var desk: Furniture = .desk(height: 80)
print(desk.description()) // "Письменный стол высотой 80 см."
-var chair = Furniture.Chair("Foo", 40)
+var chair = Furniture.chair("Foo", 40)
print(chair.description()) // "Стул марки Foo высотой 40 см."
diff --git a/ru-ru/vim-ru.html.markdown b/ru-ru/vim-ru.html.markdown
index 6f62fd49..f43f99eb 100644
--- a/ru-ru/vim-ru.html.markdown
+++ b/ru-ru/vim-ru.html.markdown
@@ -9,7 +9,7 @@ filename: LearnVim-ru.txt
lang: ru-ru
---
-[Vim](www.vim.org)
+[Vim](http://www.vim.org)
(Vi IMproved) это клон полулярного текстового редактора для Unix. Он разработан
с целью повышения скорости и продуктивности и повсеместно используется в
большинство Юникс-подобных систем. В нем имеется множество клавиатурных
diff --git a/ru-ru/yaml-ru.html.markdown b/ru-ru/yaml-ru.html.markdown
new file mode 100644
index 00000000..ddaed2b6
--- /dev/null
+++ b/ru-ru/yaml-ru.html.markdown
@@ -0,0 +1,189 @@
+---
+language: yaml
+filename: learnyaml-ru.yaml
+contributors:
+- [Leigh Brenecki, 'https://github.com/adambrenecki']
+- [Suhas SG, 'https://github.com/jargnar']
+translators:
+- [Sergei Babin, 'https://github.com/serzn1']
+lang: ru-ru
+---
+
+YAML как язык сериализации данных предназначен прежде всего для использования людьми.
+
+Это строгое надмножество JSON с добавлением синтаксически значимых переносов строк и
+отступов как в Python. Тем не менее, в отличие от Python, YAML запрещает
+использование табов для отступов.
+
+```yaml
+--- # начало документа
+
+# Комментарий в YAML выглядит как-то так.
+
+######################
+# Скалярные величины #
+######################
+
+# Наш корневой объект (который продолжается до конца документа) будет соответствовать
+# типу map, который в свою очередь соответствует словарю, хешу или объекту в других языках.
+key: value
+another_key: Другое значение ключа.
+a_number_value: 100
+scientific_notation: 1e+12
+# Число 1 будет интерпретировано как число, а не как логический тип. Если необходимо чтобы
+# значение было интерпретировано как логическое, необходимо использовать true
+boolean: true
+null_value: null
+key with spaces: value
+
+# Обратите внимание что строки используются без кавычек, но могут и с кавычками.
+however: 'Строка заключенная в кавычки.'
+'Ключ заключенный в кавычки.': "Полезно если нужно использовать ':' в вашем ключе."
+single quotes: 'Содержит ''одну'' экранированную строку'
+double quotes: "Содержит несколько: \", \0, \t, \u263A, \x0d\x0a == \r\n, экранированных строк."
+
+# Многострочные строковые значения могут быть записаны как 'строковый блок' (используя |),
+# или как 'сложенный блок' (используя '>').
+literal_block: |
+ Значение всего текста в этом блоке будет присвоено ключу 'literal_block',
+ с сохранением переноса строк.
+
+ Объявление продолжается до удаления отступа и выравнивания с ведущим отступом.
+
+ Любые строки с большим отступом сохраняют остатки своего отступа -
+ эта строка будет содержать дополнительно 4 пробела.
+folded_style: >
+ Весь блок этого тектса будет значением 'folded_style', но в данном случае
+ все символы новой строки будут заменены пробелами.
+
+ Пустые строки будут преобразованы в перенос строки.
+
+ Строки с дополнительными отступами сохраняют их переносы строк -
+ этот текст появится через 2 строки.
+
+##################
+# Типы коллекций #
+##################
+
+# Вложения используют отступы. Отступ в 2 пробела предпочтителен (но не обязателен).
+a_nested_map:
+ key: value
+ another_key: Another Value
+ another_nested_map:
+ hello: hello
+
+# В словарях (maps) используются не только строковые значения ключей.
+0.25: a float key
+
+# Ключи также могут быть сложными, например многострочными.
+# Мы используем ? с последующим пробелом чтобы обозначить начало сложного ключа.
+? |
+ Этот ключ
+ который содержит несколько строк
+: и это его значение
+
+# YAML также разрешает соответствия между последовательностями со сложными ключами
+# Некоторые парсеры могут выдать предупреждения или ошибку
+# Пример
+? - Manchester United
+ - Real Madrid
+: [2001-01-01, 2002-02-02]
+
+# Последовательности (эквивалент списка или массива) выглядят как-то так
+# (обратите внимание что знак '-' считается отступом):
+a_sequence:
+ - Item 1
+ - Item 2
+ - 0.5 # последовательности могут содержать различные типы.
+ - Item 4
+ - key: value
+ another_key: another_value
+ -
+ - Это последовательность
+ - внутри другой последовательности
+ - - - Объявления вложенных последовательностей
+ - могут быть сжаты
+
+# Поскольку YAML это надмножество JSON, вы можете использовать JSON-подобный
+# синтаксис для словарей и последовательностей:
+json_map: {"key": "value"}
+json_seq: [3, 2, 1, "takeoff"]
+в данном случае кавычки не обязательны: {key: [3, 2, 1, takeoff]}
+
+##########################
+# Дополнительные функции #
+##########################
+
+# В YAML есть удобная система так называемых 'якорей' (anchors), которые позволяют легко
+# дублировать содержимое внутри документа. Оба ключа в примере будут иметь одинаковые значения:
+anchored_content: &anchor_name Эта строка будет являться значением обоих ключей.
+other_anchor: *anchor_name
+
+# Якоря могут использоваться для дублирования/наследования свойств
+base: &base
+ name: Каждый будет иметь одинаковое имя
+
+# Регулярное выражение << называется ключом объединения независимо от типа языка.
+# Он используется чтобы показать что все ключи одного или более словарей должны быть
+# добавлены в текущий словарь.
+
+foo: &foo
+ <<: *base
+ age: 10
+
+bar: &bar
+ <<: *base
+ age: 20
+
+# foo и bar могли бы иметь имена: Каждый из них имеет аналогичное имя
+
+# В YAML есть теги (tags), которые используются для явного объявления типов.
+explicit_string: !!str 0.5
+# В некоторых парсерах реализованы теги для конкретного языка, пример для Python
+# пример сложного числового типа.
+python_complex_number: !!python/complex 1+2j
+
+# Мы можем использовать сложные ключи с включенными в них тегами из определенного языка
+? !!python/tuple [5, 7]
+: Fifty Seven
+# Могло бы быть {(5, 7): 'Fifty Seven'} в Python
+
+#######################
+# Дополнительные типы #
+#######################
+
+# Строки и числа не единственные величины которые может понять YAML.
+# YAML также поддерживает даты и время в формате ISO.
+datetime: 2001-12-15T02:59:43.1Z
+datetime_with_spaces: 2001-12-14 21:59:43.10 -5
+date: 2002-12-14
+
+# Тег !!binary показывает что эта строка является base64-закодированным
+# представлением двоичного объекта.
+gif_file: !!binary |
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
+
+# YAML может использовать объекты типа ассоциативных массивов (set), как представлено ниже:
+set:
+ ? item1
+ ? item2
+ ? item3
+or: {item1, item2, item3}
+
+# Сеты (set) являются простыми эквивалентами словарей со значениями
+# типа null; запись выше эквивалентна следующей:
+set2:
+ item1: null
+ item2: null
+ item3: null
+
+... # конец документа
+```
+
+### Больше информации
+
++ [YAML оффициальный вебсайт](http://yaml.org/)
++ [YAML онлайн валидатор](http://www.yamllint.com/)
diff --git a/ruby-ecosystem.html.markdown b/ruby-ecosystem.html.markdown
index 1fbcc752..3c80075b 100644
--- a/ruby-ecosystem.html.markdown
+++ b/ruby-ecosystem.html.markdown
@@ -10,6 +10,16 @@ contributors:
People using Ruby generally have a way to install different Ruby versions,
manage their packages (or gems), and manage their gem dependencies.
+## Ruby Versions
+
+Ruby was created by Yukihiro "Matz" Matsumoto, who remains somewhat of a
+[BDFL](https://en.wikipedia.org/wiki/Benevolent_Dictator_for_Life), although
+that is changing recently. As a result, the reference implementation of Ruby is
+called MRI (Matz' Reference Implementation), and when you hear a Ruby version,
+it is referring to the release version of MRI.
+
+New major versions of Ruby are traditionally released on Christmas Day. The current major version (25 December 2017) is 2.5. The most popular stable versions are 2.4.4 and 2.3.7 (both released 28 March 2018).
+
## Ruby Managers
Some platforms have Ruby pre-installed or available as a package. Most rubyists
@@ -29,28 +39,6 @@ The following are the popular Ruby environment managers:
* [chruby](https://github.com/postmodern/chruby) - Only switches between rubies.
Similar in spirit to rbenv. Unopinionated about how rubies are installed.
-## Ruby Versions
-
-Ruby was created by Yukihiro "Matz" Matsumoto, who remains somewhat of a
-[BDFL](https://en.wikipedia.org/wiki/Benevolent_Dictator_for_Life), although
-that is changing recently. As a result, the reference implementation of Ruby is
-called MRI (Matz' Reference Implementation), and when you hear a Ruby version,
-it is referring to the release version of MRI.
-
-The three major version of Ruby in use are:
-
-* 2.0.0 - Released in February 2013. Most major libraries and frameworks support
- 2.0.0.
-* 1.9.3 - Released in October 2011. This is the version most rubyists use
- currently. Also [retired](https://www.ruby-lang.org/en/news/2015/02/23/support-for-ruby-1-9-3-has-ended/)
-* 1.8.7 - Ruby 1.8.7 has been
- [retired](http://www.ruby-lang.org/en/news/2013/06/30/we-retire-1-8-7/).
-
-The change between 1.8.7 to 1.9.x is a much larger change than 1.9.3 to 2.0.0.
-For instance, the 1.9 series introduced encodings and a bytecode VM. There
-are projects still on 1.8.7, but they are becoming a small minority, as most of
-the community has moved to at least 1.9.2 or 1.9.3.
-
## Ruby Implementations
The Ruby ecosystem enjoys many different implementations of Ruby, each with
@@ -88,7 +76,7 @@ implementation.
to have stopped since Microsoft pulled their support.
Ruby implementations may have their own release version numbers, but they always
-target a specific version of MRI for compatability. Many implementations have
+target a specific version of MRI for compatibility. Many implementations have
the ability to enter different modes (for example, 1.8 or 1.9 mode) to specify
which MRI version to target.
diff --git a/ruby.html.markdown b/ruby.html.markdown
index a1532855..4b96b71c 100644
--- a/ruby.html.markdown
+++ b/ruby.html.markdown
@@ -15,32 +15,39 @@ contributors:
- ["Gabriel Halley", "https://github.com/ghalley"]
- ["Persa Zula", "http://persazula.com"]
- ["Jake Faris", "https://github.com/farisj"]
+ - ["Corey Ward", "https://github.com/coreyward"]
+ - ["Jannik Siebert", "https://github.com/janniks"]
+ - ["Keith Miyake", "https://github.com/kaymmm"]
---
```ruby
# This is a comment
=begin
-This is a multiline comment
-No-one uses them
-You shouldn't either
-=end
-
-# First and foremost: Everything is an object.
+This is a multi-line comment.
+The beginning line must start with "=begin"
+and the ending line must start with "=end".
-# Numbers are objects
+You can do this, or start each line in
+a multi-line comment with the # character.
+=end
-3.class #=> Fixnum
+# In Ruby, (almost) everything is an object.
+# This includes numbers...
+3.class #=> Integer
-3.to_s #=> "3"
+# ...and strings...
+"Hello".class #=> String
+# ...and even methods!
+"Hello".method(:class).class #=> Method
# Some basic arithmetic
1 + 1 #=> 2
8 - 1 #=> 7
10 * 2 #=> 20
35 / 5 #=> 7
-2**5 #=> 32
+2 ** 5 #=> 32
5 % 3 #=> 2
# Bitwise operators
@@ -52,6 +59,7 @@ You shouldn't either
# for calling a method on an object
1.+(3) #=> 4
10.* 5 #=> 50
+100.methods.include?(:/) #=> true
# Special values are objects
nil # equivalent to null in other languages
@@ -70,11 +78,12 @@ false.class #=> FalseClass
1 != 1 #=> false
2 != 1 #=> true
-# apart from false itself, nil is the only other 'falsey' value
+# Apart from false itself, nil is the only other 'falsey' value
-!nil #=> true
-!false #=> true
-!0 #=> false
+!!nil #=> false
+!!false #=> false
+!!0 #=> true
+!!"" #=> true
# More comparisons
1 < 10 #=> true
@@ -82,15 +91,15 @@ false.class #=> FalseClass
2 <= 2 #=> true
2 >= 2 #=> true
-# Combined comparison operator
-1 <=> 10 #=> -1
-10 <=> 1 #=> 1
-1 <=> 1 #=> 0
+# Combined comparison operator (returns `1` when the first argument is greater,
+# `-1` when the second argument is greater, and `0` otherwise)
+1 <=> 10 #=> -1 (1 < 10)
+10 <=> 1 #=> 1 (10 > 1)
+1 <=> 1 #=> 0 (1 == 1)
# Logical operators
true && false #=> false
true || false #=> true
-!true #=> false
# There are alternate versions of the logical operators with much lower
# precedence. These are meant to be used as flow-control constructs to chain
@@ -101,61 +110,54 @@ do_something() and do_something_else()
# `log_error` only called if `do_something` fails.
do_something() or log_error()
-
-# Strings are objects
-
-'I am a string'.class #=> String
-"I am a string too".class #=> String
+# String interpolation
placeholder = 'use string interpolation'
"I can #{placeholder} when using double quoted strings"
#=> "I can use string interpolation when using double quoted strings"
-# Prefer single quoted strings to double quoted ones where possible
-# Double quoted strings perform additional inner calculations
-
-# Combine strings, but not with numbers
+# You can combine strings using `+`, but not with other types
'hello ' + 'world' #=> "hello world"
'hello ' + 3 #=> TypeError: can't convert Fixnum into String
'hello ' + 3.to_s #=> "hello 3"
+"hello #{3}" #=> "hello 3"
-# Combine strings and operators
+# ...or combine strings and operators
'hello ' * 3 #=> "hello hello hello "
-# Append to string
+# ...or append to string
'hello' << ' world' #=> "hello world"
-# print to the output with a newline at the end
+# You can print to the output with a newline at the end
puts "I'm printing!"
#=> I'm printing!
#=> nil
-# print to the output without a newline
+# ...or print to the output without a newline
print "I'm printing!"
-#=> I'm printing! => nil
+#=> "I'm printing!" => nil
# Variables
x = 25 #=> 25
x #=> 25
-# Note that assignment returns the value assigned
-# This means you can do multiple assignment:
+# Note that assignment returns the value assigned.
+# This means you can do multiple assignment.
x = y = 10 #=> 10
x #=> 10
y #=> 10
-# By convention, use snake_case for variable names
+# By convention, use snake_case for variable names.
snake_case = true
# Use descriptive variable names
path_to_project_root = '/good/name/'
-path = '/bad/name/'
+m = '/bad/name/'
-# Symbols (are objects)
# Symbols are immutable, reusable constants represented internally by an
# integer value. They're often used instead of strings to efficiently convey
-# specific, meaningful values
+# specific, meaningful values.
:pending.class #=> Symbol
@@ -167,77 +169,88 @@ status == 'pending' #=> false
status == :approved #=> false
+# Strings can be converted into symbols and vice versa.
+status.to_s #=> "pending"
+"argon".to_sym #=> :argon
+
# Arrays
-# This is an array
+# This is an array.
array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
-# Arrays can contain different types of items
-
+# Arrays can contain different types of items.
[1, 'hello', false] #=> [1, "hello", false]
-# Arrays can be indexed
-# From the front
+# You might prefer %w instead of quotes
+%w[foo bar baz] #=> ["foo", "bar", "baz"]
+
+# Arrays can be indexed.
+# From the front...
array[0] #=> 1
array.first #=> 1
array[12] #=> nil
-# Like arithmetic, [var] access
-# is just syntactic sugar
-# for calling a method [] on an object
-array.[] 0 #=> 1
-array.[] 12 #=> nil
-
-# From the end
+# ...or from the back...
array[-1] #=> 5
array.last #=> 5
-# With a start index and length
+# ...or with a start index and length...
array[2, 3] #=> [3, 4, 5]
-# Reverse an Array
-a=[1,2,3]
-a.reverse! #=> [3,2,1]
-
-# Or with a range
+# ...or with a range...
array[1..3] #=> [2, 3, 4]
-# Add to an array like this
+# You can reverse an Array.
+# Return a new array with reversed values
+[1,2,3].reverse #=> [3,2,1]
+# Reverse an array in place to update variable with reversed values
+a = [1,2,3]
+a.reverse! #=> a==[3,2,1] because of the bang ('!') call to reverse
+
+# Like arithmetic, [var] access is just syntactic sugar
+# for calling a method '[]' on an object.
+array.[] 0 #=> 1
+array.[] 12 #=> nil
+
+# You can add to an array...
array << 6 #=> [1, 2, 3, 4, 5, 6]
# Or like this
array.push(6) #=> [1, 2, 3, 4, 5, 6]
-# Check if an item exists in an array
+# ...and check if an item exists in an array
array.include?(1) #=> true
# Hashes are Ruby's primary dictionary with key/value pairs.
-# Hashes are denoted with curly braces:
+# Hashes are denoted with curly braces.
hash = { 'color' => 'green', 'number' => 5 }
hash.keys #=> ['color', 'number']
-# Hashes can be quickly looked up by key:
-hash['color'] #=> 'green'
+# Hashes can be quickly looked up by key.
+hash['color'] #=> "green"
hash['number'] #=> 5
-# Asking a hash for a key that doesn't exist returns nil:
+# Asking a hash for a key that doesn't exist returns nil.
hash['nothing here'] #=> nil
-# Since Ruby 1.9, there's a special syntax when using symbols as keys:
+# When using symbols for keys in a hash, you can use an alternate syntax.
-new_hash = { defcon: 3, action: true }
+hash = { :defcon => 3, :action => true }
+hash.keys #=> [:defcon, :action]
-new_hash.keys #=> [:defcon, :action]
+hash = { defcon: 3, action: true }
+hash.keys #=> [:defcon, :action]
# Check existence of keys and values in hash
-new_hash.key?(:defcon) #=> true
-new_hash.value?(3) #=> true
+hash.key?(:defcon) #=> true
+hash.value?(3) #=> true
-# Tip: Both Arrays and Hashes are Enumerable
-# They share a lot of useful methods such as each, map, count, and more
+# Tip: Both Arrays and Hashes are Enumerable!
+# They share a lot of useful methods such as each, map, count, and more.
# Control structures
+# Conditionals
if true
'if statement'
elsif false
@@ -246,35 +259,34 @@ else
'else, also optional'
end
+# If a condition controls invocation of a single statement rather than a block of code
+# you can use postfix-if notation
+warnings = ['Patronimic is missing', 'Address too short']
+puts("Some warnings occurred:\n" + warnings.join("\n")) if !warnings.empty?
+
+# Rephrase condition if `unless` sounds better than `if`
+puts("Some warnings occurred:\n" + warnings.join("\n")) unless warnings.empty?
+
+# Loops
+# In Ruby, traditional `for` loops aren't very common. Instead, these
+# basic loops are implemented using enumerable, which hinges on `each`.
+(1..5).each do |counter|
+ puts "iteration #{counter}"
+end
+
+# Which is roughly equivalent to the following, which is unusual to see in Ruby.
for counter in 1..5
puts "iteration #{counter}"
end
-#=> iteration 1
-#=> iteration 2
-#=> iteration 3
-#=> iteration 4
-#=> iteration 5
-# HOWEVER, No-one uses for loops.
-# Instead you should use the "each" method and pass it a block.
-# A block is a bunch of code that you can pass to a method like "each".
-# It is analogous to lambdas, anonymous functions or closures in other
-# programming languages.
+# The `do |variable| ... end` construct above is called a 'block'. Blocks are similar
+# to lambdas, anonymous functions or closures in other programming languages. They can
+# be passed around as objects, called, or attached as methods.
#
-# The "each" method of a range runs the block once for each element of the range.
+# The 'each' method of a range runs the block once for each element of the range.
# The block is passed a counter as a parameter.
-# Calling the "each" method with a block looks like this:
-(1..5).each do |counter|
- puts "iteration #{counter}"
-end
-#=> iteration 1
-#=> iteration 2
-#=> iteration 3
-#=> iteration 4
-#=> iteration 5
-
-# You can also surround blocks in curly brackets:
+# You can also surround blocks in curly brackets.
(1..5).each { |counter| puts "iteration #{counter}" }
# The contents of data structures can also be iterated using each.
@@ -285,8 +297,8 @@ hash.each do |key, value|
puts "#{key} is #{value}"
end
-# If you still need an index you can use "each_with_index" and define an index
-# variable
+# If you still need an index you can use 'each_with_index' and define an index
+# variable.
array.each_with_index do |element, index|
puts "#{element} is number #{index} in the array"
end
@@ -302,9 +314,9 @@ end
#=> iteration 4
#=> iteration 5
-# There are a bunch of other helpful looping functions in Ruby,
-# for example "map", "reduce", "inject", the list goes on. Map,
-# for instance, takes the array it's looping over, does something
+# There are a bunch of other helpful looping functions in Ruby.
+# For example: 'map', 'reduce', 'inject', the list goes on.
+# Map, for instance, takes the array it's looping over, does something
# to it as defined in your block, and returns an entirely new array.
array = [1,2,3,4,5]
doubled = array.map do |element|
@@ -315,6 +327,12 @@ puts doubled
puts array
#=> [1,2,3,4,5]
+# another useful syntax is .map(&:method)
+a = ["FOO", "BAR", "BAZ"]
+a.map { |s| s.downcase } #=> ["foo", "bar", "baz"]
+a.map(&:downcase) #=> ["foo", "bar", "baz"]
+
+# Case construct
grade = 'B'
case grade
@@ -333,7 +351,7 @@ else
end
#=> "Better luck next time"
-# cases can also use ranges
+# Cases can also use ranges
grade = 82
case grade
when 90..100
@@ -345,9 +363,9 @@ else
end
#=> "OK job"
-# exception handling:
+# Exception handling
begin
- # code here that might raise an exception
+ # Code here that might raise an exception
raise NoMemoryError, 'You ran out of memory.'
rescue NoMemoryError => exception_variable
puts 'NoMemoryError was raised', exception_variable
@@ -359,16 +377,16 @@ ensure
puts 'This code always runs no matter what'
end
-# Functions
+# Methods
def double(x)
x * 2
end
-# Functions (and all blocks) implicitly return the value of the last statement
+# Methods (and blocks) implicitly return the value of the last statement.
double(2) #=> 4
-# Parentheses are optional where the result is unambiguous
+# Parentheses are optional where the interpretation is unambiguous.
double 3 #=> 6
double double 3 #=> 12
@@ -377,15 +395,14 @@ def sum(x, y)
x + y
end
-# Method arguments are separated by a comma
+# 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
-
+# All methods have an implicit, optional block parameter.
+# It can be called with the 'yield' keyword.
def surround
puts '{'
yield
@@ -394,46 +411,88 @@ end
surround { puts 'hello world' }
-# {
-# hello world
-# }
+#=> {
+#=> hello world
+#=> }
-
-# You can pass a block to a function
-# "&" marks a reference to a passed block
+# Blocks can be converted into a 'proc' object, which wraps the block
+# and allows it to be passed to another method, bound to a different scope,
+# or manipulated otherwise. This is most common in method parameter lists,
+# where you frequently see a trailing '&block' parameter that will accept
+# the block, if one is given, and convert it to a 'Proc'. The naming here is
+# convention; it would work just as well with '&pineapple'.
def guests(&block)
- block.call 'some_argument'
+ block.class #=> Proc
+ block.call(4)
end
-# You can pass a list of arguments, which will be converted into an array
-# That's what splat operator ("*") is for
+# The 'call' method on the Proc is similar to calling 'yield' when a block is
+# present. The arguments passed to 'call' will be forwarded to the block as arguments.
+
+guests { |n| "You have #{n} guests." }
+# => "You have 4 guests."
+
+# 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']
+# There is also the shorthand block syntax. It's most useful when you need
+# to call a simple method on all array items.
+upcased = ['Watch', 'these', 'words', 'get', 'upcased'].map(&:upcase)
+puts upcased
+#=> ["WATCH", "THESE", "WORDS", "GET", "UPCASED"]
+
+sum = [1, 2, 3, 4, 5].reduce(&:+)
+puts sum
+#=> 15
+
+# Destructuring
+
+# Ruby will automatically destructure arrays on assignment to multiple variables.
+a, b, c = [1, 2, 3]
+a #=> 1
+b #=> 2
+c #=> 3
+
+# In some cases, you will want to use the splat operator: `*` to prompt destructuring
+# of an array into a list.
+ranked_competitors = ["John", "Sally", "Dingus", "Moe", "Marcy"]
+
+def best(first, second, third)
+ puts "Winners are #{first}, #{second}, and #{third}."
+end
+
+best *ranked_competitors.first(3) #=> Winners are John, Sally, and Dingus.
+
+# The splat operator can also be used in parameters.
+def best(first, second, third, *others)
+ puts "Winners are #{first}, #{second}, and #{third}."
+ puts "There were #{others.count} other participants."
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
+best *ranked_competitors
+#=> Winners are John, Sally, and Dingus.
+#=> There were 2 other participants.
-# And if a method ends with an exclamation mark, it does something destructive
+# By convention, all methods that return booleans end with a question mark.
+5.even? #=> false
+5.odd? #=> true
+
+# By convention, if a method name ends with an exclamation mark, it does something destructive
# like mutate the receiver. Many methods have a ! version to make a change, and
-# a non-! version to just return a new changed version
+# a non-! version to just return a new changed version.
company_name = "Dunder Mifflin"
company_name.upcase #=> "DUNDER MIFFLIN"
company_name #=> "Dunder Mifflin"
-company_name.upcase! # we're mutating company_name this time!
+# We're mutating company_name this time.
+company_name.upcase! #=> "DUNDER MIFFLIN"
company_name #=> "DUNDER MIFFLIN"
+# Classes
-# Define a class with the class keyword
+# You can define a class with the 'class' keyword.
class Human
# A class variable. It is shared by all instances of this class.
@@ -441,7 +500,7 @@ class Human
# Basic initializer
def initialize(name, age = 0)
- # Assign the argument to the "name" instance variable for the instance
+ # Assign the argument to the 'name' instance variable for the instance.
@name = name
# If no age given, we will fall back to the default in the arguments list.
@age = age
@@ -457,10 +516,10 @@ class Human
@name
end
- # The above functionality can be encapsulated using the attr_accessor method as follows
+ # The above functionality can be encapsulated using the attr_accessor method as follows.
attr_accessor :name
- # Getter/setter methods can also be created individually like this
+ # Getter/setter methods can also be created individually like this.
attr_reader :name
attr_writer :name
@@ -475,13 +534,11 @@ class Human
end
end
-
-# Instantiate a class
+# Instantiating of a class
jim = Human.new('Jim Halpert')
-
dwight = Human.new('Dwight K. Schrute')
-# Let's call a couple of methods
+# You can call the methods of the generated object.
jim.species #=> "H. sapiens"
jim.name #=> "Jim Halpert"
jim.name = "Jim Halpert II" #=> "Jim Halpert II"
@@ -489,30 +546,30 @@ jim.name #=> "Jim Halpert II"
dwight.species #=> "H. sapiens"
dwight.name #=> "Dwight K. Schrute"
-# Call the class method
+# Calling of a class method
Human.say('Hi') #=> "Hi"
# Variable's scopes are defined by the way we name them.
-# Variables that start with $ have global scope
+# Variables that start with $ have global scope.
$var = "I'm a global var"
defined? $var #=> "global-variable"
-# Variables that start with @ have instance scope
+# Variables that start with @ have instance scope.
@var = "I'm an instance var"
defined? @var #=> "instance-variable"
-# Variables that start with @@ have class scope
+# Variables that start with @@ have class scope.
@@var = "I'm a class var"
defined? @@var #=> "class variable"
-# Variables that start with a capital letter are constants
+# Variables that start with a capital letter are constants.
Var = "I'm a constant"
defined? Var #=> "constant"
-# Class is also an object in ruby. So class can have instance variables.
-# Class variable is shared among the class and all of its descendants.
+# Class is also an object in ruby. So a class can have instance variables.
+# A class variable is shared among the class and all of its descendants.
-# base class
+# Base class
class Human
@@foo = 0
@@ -525,18 +582,17 @@ class Human
end
end
-# derived class
+# Derived class
class Worker < Human
end
-Human.foo # 0
-Worker.foo # 0
+Human.foo #=> 0
+Worker.foo #=> 0
-Human.foo = 2 # 2
-Worker.foo # 2
-
-# Class instance variable is not shared by the class's descendants.
+Human.foo = 2
+Worker.foo #=> 2
+# A class instance variable is not shared by the class's descendants.
class Human
@bar = 0
@@ -552,8 +608,8 @@ end
class Doctor < Human
end
-Human.bar # 0
-Doctor.bar # nil
+Human.bar #=> 0
+Doctor.bar #=> nil
module ModuleExample
def foo
@@ -561,9 +617,8 @@ module ModuleExample
end
end
-# Including modules binds their methods to the class instances
-# Extending modules binds their methods to the class itself
-
+# Including modules binds their methods to the class instances.
+# Extending modules binds their methods to the class itself.
class Person
include ModuleExample
end
@@ -572,13 +627,12 @@ class Book
extend ModuleExample
end
-Person.foo # => NoMethodError: undefined method `foo' for Person:Class
-Person.new.foo # => 'foo'
-Book.foo # => 'foo'
-Book.new.foo # => NoMethodError: undefined method `foo'
+Person.foo #=> NoMethodError: undefined method `foo' for Person:Class
+Person.new.foo #=> "foo"
+Book.foo #=> "foo"
+Book.new.foo #=> NoMethodError: undefined method `foo'
# Callbacks are executed when including and extending a module
-
module ConcernExample
def self.included(base)
base.extend(ClassMethods)
@@ -602,10 +656,10 @@ class Something
include ConcernExample
end
-Something.bar # => 'bar'
-Something.qux # => NoMethodError: undefined method `qux'
-Something.new.bar # => NoMethodError: undefined method `bar'
-Something.new.qux # => 'qux'
+Something.bar #=> "bar"
+Something.qux #=> NoMethodError: undefined method `qux'
+Something.new.bar #=> NoMethodError: undefined method `bar'
+Something.new.qux #=> "qux"
```
## Additional resources
diff --git a/rust.html.markdown b/rust.html.markdown
index 6b75fa87..e835de12 100644
--- a/rust.html.markdown
+++ b/rust.html.markdown
@@ -1,5 +1,5 @@
---
-language: rust
+language: Rust
contributors:
- ["P1start", "http://p1start.github.io/"]
filename: learnrust.rs
@@ -22,7 +22,7 @@ currently available in the nightly builds. Rust has adopted a train-based releas
model with regular releases every six weeks. Rust 1.1 beta was made available at
the same time of the release of Rust 1.0.
-Although Rust is a relatively low-level language, Rust has some functional
+Although Rust is a relatively low-level language, it has some functional
concepts that are generally found in higher-level languages. This makes
Rust not only fast, but also easy and efficient to code in.
@@ -41,6 +41,7 @@ Rust not only fast, but also easy and efficient to code in.
// 1. Basics //
///////////////
+#[allow(dead_code)]
// Functions
// `i32` is the type for 32-bit signed integers
fn add2(x: i32, y: i32) -> i32 {
@@ -48,6 +49,9 @@ fn add2(x: i32, y: i32) -> i32 {
x + y
}
+#[allow(unused_variables)]
+#[allow(unused_assignments)]
+#[allow(dead_code)]
// Main function
fn main() {
// Numbers //
@@ -88,10 +92,8 @@ fn main() {
let s: String = "hello world".to_string();
// A string slice – an immutable view into another string
- // This is basically an immutable pair of pointers to a string – it doesn’t
- // actually contain the contents of a string, just a pointer to
- // the begin and a pointer to the end of a string buffer,
- // statically allocated or contained in another object (in this case, `s`)
+ // The string buffer can be statically allocated like in a string literal
+ // or contained in another object (in this case, `s`)
let s_slice: &str = &s;
println!("{} {}", s, s_slice); // hello world hello world
@@ -174,13 +176,19 @@ fn main() {
impl<T> Foo<T> {
// Methods take an explicit `self` parameter
- fn get_bar(self) -> T {
+ fn bar(&self) -> &T { // self is borrowed
+ &self.bar
+ }
+ fn bar_mut(&mut self) -> &mut T { // self is mutably borrowed
+ &mut self.bar
+ }
+ fn into_bar(self) -> T { // here self is consumed
self.bar
}
}
let a_foo = Foo { bar: 1 };
- println!("{}", a_foo.get_bar()); // 1
+ println!("{}", a_foo.bar()); // 1
// Traits (known as interfaces or typeclasses in other languages) //
@@ -256,11 +264,16 @@ fn main() {
// `while` loop
while 1 == 1 {
println!("The universe is operating normally.");
+ // break statement gets out of the while loop.
+ // It avoids useless iterations.
+ break
}
// Infinite loop
loop {
println!("Hello!");
+ // break statement gets out of the loop
+ break
}
/////////////////////////////////
@@ -281,7 +294,7 @@ fn main() {
// Reference – an immutable pointer that refers to other data
// When a reference is taken to a value, we say that the value has been ‘borrowed’.
// While a value is borrowed immutably, it cannot be mutated or moved.
- // A borrow lasts until the end of the scope it was created in.
+ // A borrow is active until the last use of the borrowing variable.
let mut var = 4;
var = 3;
let ref_var: &i32 = &var;
@@ -290,6 +303,8 @@ fn main() {
println!("{}", *ref_var);
// var = 5; // this would not compile because `var` is borrowed
// *ref_var = 6; // this would not either, because `ref_var` is an immutable reference
+ ref_var; // no-op, but counts as a use and keeps the borrow active
+ var = 2; // ref_var is no longer used after the line above, so the borrow has ended
// Mutable reference
// While a value is mutably borrowed, it cannot be accessed at all.
@@ -300,6 +315,7 @@ fn main() {
println!("{}", *ref_var2); // 6 , // var2 would not compile.
// ref_var2 is of type &mut i32, so stores a reference to an i32, not the value.
// var2 = 2; // this would not compile because `var2` is borrowed.
+ ref_var2; // no-op, but counts as a use and keeps the borrow active until here
}
```
diff --git a/scala.html.markdown b/scala.html.markdown
index d33b6234..08fd37e4 100644
--- a/scala.html.markdown
+++ b/scala.html.markdown
@@ -25,7 +25,7 @@ Scala - the scalable language
/*
Try the REPL
- Scala has a tool called the REPL (Read-Eval-Print Loop) that is anologus to
+ Scala has a tool called the REPL (Read-Eval-Print Loop) that is analogous to
commandline interpreters in many other languages. You may type any Scala
expression, and the result will be evaluated and printed.
@@ -252,7 +252,7 @@ weirdSum(2, 4) // => 16
// The return keyword exists in Scala, but it only returns from the inner-most
// def that surrounds it.
// WARNING: Using return in Scala is error-prone and should be avoided.
-// It has no effect on anonymous functions. For example:
+// It has no effect on anonymous functions. For example here you may expect foo(7) should return 17 but it returns 7:
def foo(x: Int): Int = {
val anonFunc: Int => Int = { z =>
if (z > 5)
@@ -260,9 +260,10 @@ def foo(x: Int): Int = {
else
z + 2 // This line is the return value of anonFunc
}
- anonFunc(x) // This line is the return value of foo
+ anonFunc(x) + 10 // This line is the return value of foo
}
+foo(7) // => 7
/////////////////////////////////////////////////
// 3. Flow Control
@@ -276,6 +277,8 @@ r foreach println
// NB: Scala is quite lenient when it comes to dots and brackets - study the
// rules separately. This helps write DSLs and APIs that read like English
+// Why doesn't `println` need any parameters here?
+// Stay tuned for first-class functions in the Functional Programming section below!
(5 to 1 by -1) foreach (println)
// A while loop
@@ -299,7 +302,7 @@ do {
// Recursion is the idiomatic way of repeating an action in Scala (as in most
// other functional languages).
// Recursive functions need an explicit return type, the compiler can't infer it.
-// Here it's Unit.
+// Here it's Unit, which is analagous to a `void` return type in Java
def showNumbersInRange(a: Int, b: Int): Unit = {
print(a)
if (a < b)
@@ -343,7 +346,7 @@ s(0) // Boolean = false
s(1) // Boolean = true
/* Look up the documentation of map here -
- * http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
+ * https://www.scala-lang.org/api/current/scala/collection/immutable/Map.html
* and make sure you can read it
*/
@@ -412,8 +415,8 @@ class Dog(br: String) {
private def sleep(hours: Int) =
println(s"I'm sleeping for $hours hours")
- // Abstract methods are simply methods with no body. If we uncomment the next
- // line, class Dog would need to be declared abstract
+ // Abstract methods are simply methods with no body. If we uncomment the
+ // def line below, class Dog would need to be declared abstract like so:
// abstract class Dog(...) { ... }
// def chaseAfter(what: String): String
}
@@ -455,13 +458,57 @@ george.phoneNumber // => "1234"
Person("George", "1234") == Person("Kate", "1236") // => false
// Easy way to copy
-// otherGeorge == Person("george", "9876")
+// otherGeorge == Person("George", "9876")
val otherGeorge = george.copy(phoneNumber = "9876")
// And many others. Case classes also get pattern matching for free, see below.
+// Traits
+// Similar to Java interfaces, traits define an object type and method
+// signatures. Scala allows partial implementation of those methods.
+// Constructor parameters are not allowed. Traits can inherit from other
+// traits or classes without parameters.
+
+trait Dog {
+ def breed: String
+ def color: String
+ def bark: Boolean = true
+ def bite: Boolean
+}
+class SaintBernard extends Dog {
+ val breed = "Saint Bernard"
+ val color = "brown"
+ def bite = false
+}
+
+scala> b
+res0: SaintBernard = SaintBernard@3e57cd70
+scala> b.breed
+res1: String = Saint Bernard
+scala> b.bark
+res2: Boolean = true
+scala> b.bite
+res3: Boolean = false
+
+// A trait can also be used as Mixin. The class "extends" the first trait,
+// but the keyword "with" can add additional traits.
+
+trait Bark {
+ def bark: String = "Woof"
+}
+trait Dog {
+ def breed: String
+ def color: String
+}
+class SaintBernard extends Dog with Bark {
+ val breed = "Saint Bernard"
+ val color = "brown"
+}
-// Traits coming soon!
+scala> val b = new SaintBernard
+b: SaintBernard = SaintBernard@7b69c6ba
+scala> b.bark
+res0: String = Woof
/////////////////////////////////////////////////
@@ -479,7 +526,9 @@ def matchPerson(person: Person): String = person match {
case Person(name, number) => "We matched someone : " + name + ", phone : " + number
}
-val email = "(.*)@(.*)".r // Define a regex for the next example.
+// Regular expressions are also built in.
+// Create a regex with the `r` method on a string:
+val email = "(.*)@(.*)".r
// Pattern matching might look familiar to the switch statements in the C family
// of languages, but this is much more powerful. In Scala, you can match much
@@ -545,6 +594,8 @@ List("Dom", "Bob", "Natalia") foreach println
// Combinators
+// Using `s` from above:
+// val s = Set(1, 3, 7)
s.map(sq)
@@ -564,8 +615,8 @@ List(
).filter(_.age > 25) // List(Person("Bob", 30))
-// Scala a foreach method defined on certain collections that takes a type
-// returning Unit (a void method)
+// Certain collections (such as List) in Scala have a `foreach` method,
+// which takes as an argument a type returning Unit - that is, a void method
val aListOfNumbers = List(1, 2, 3, 4, 10, 20, 100)
aListOfNumbers foreach (x => println(x))
aListOfNumbers foreach println
@@ -666,7 +717,7 @@ import scala.collection.immutable.{Map => _, Set => _, _}
// Java classes can also be imported. Scala syntax can be used
import java.swing.{JFrame, JWindow}
-// Your programs entry point is defined in an scala file using an object, with a
+// Your programs entry point is defined in a scala file using an object, with a
// single method, main:
object Application {
def main(args: Array[String]): Unit = {
diff --git a/set-theory.html.markdown b/set-theory.html.markdown
new file mode 100644
index 00000000..6be7aa00
--- /dev/null
+++ b/set-theory.html.markdown
@@ -0,0 +1,132 @@
+---
+category: Algorithms & Data Structures
+name: Set theory
+contributors:
+---
+Set theory is a branch of mathematics that studies sets, their operations, and their properties.
+
+* A set is a collection of disjoint items.
+
+## Basic symbols
+
+### Operators
+* the union operator, `∪`, pronounced "cup", means "or";
+* the intersection operator, `∩`, pronounced "cap", means "and";
+* the exclusion operator, `\`, means "without";
+* the compliment operator, `'`, means "the inverse of";
+* the cross operator, `×`, means "the Cartesian product of".
+
+### Qualifiers
+* the colon qualifier, `:`, means "such that";
+* the membership qualifier, `∈`, means "belongs to";
+* the subset qualifier, `⊆`, means "is a subset of";
+* the proper subset qualifier, `⊂`, means "is a subset of but is not equal to".
+
+### Canonical sets
+* `∅`, the empty set, i.e. the set containing no items;
+* `ℕ`, the set of all natural numbers;
+* `ℤ`, the set of all integers;
+* `ℚ`, the set of all rational numbers;
+* `ℝ`, the set of all real numbers.
+
+There are a few caveats to mention regarding the canonical sets:
+1. Even though the empty set contains no items, the empty set is a subset of itself (and indeed every other set);
+2. Mathematicians generally do not universally agree on whether zero is a natural number, and textbooks will typically explicitly state whether or not the author considers zero to be a natural number.
+
+
+### Cardinality
+
+The cardinality, or size, of a set is determined by the number of items in the set. The cardinality operator is given by a double pipe, `|...|`.
+
+For example, if `S = { 1, 2, 4 }`, then `|S| = 3`.
+
+### The Empty Set
+* The empty set can be constructed in set builder notation using impossible conditions, e.g. `∅ = { x : x =/= x }`, or `∅ = { x : x ∈ N, x < 0 }`;
+* the empty set is always unique (i.e. there is one and only one empty set);
+* the empty set is a subset of all sets;
+* the cardinality of the empty set is 0, i.e. `|∅| = 0`.
+
+## Representing sets
+
+### Literal Sets
+
+A set can be constructed literally by supplying a complete list of objects contained in the set. For example, `S = { a, b, c, d }`.
+
+Long lists may be shortened with ellipses as long as the context is clear. For example, `E = { 2, 4, 6, 8, ... }` is clearly the set of all even numbers, containing an infinite number of objects, even though we've only explicitly written four of them.
+
+### Set Builder
+
+Set builder notation is a more descriptive way of constructing a set. It relies on a _subject_ and a _predicate_ such that `S = { subject : predicate }`. For example,
+
+```
+A = { x : x is a vowel } = { a, e, i, o, u, y}
+B = { x : x ∈ N, x < 10 } = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }
+C = { x : x = 2k, k ∈ N } = { 0, 2, 4, 6, 8, ... }
+```
+
+Sometimes the predicate may "leak" into the subject, e.g.
+
+```
+D = { 2x : x ∈ N } = { 0, 2, 4, 6, 8, ... }
+```
+
+## Relations
+
+### Membership
+
+* If the value `a` is contained in the set `A`, then we say `a` belongs to `A` and represent this symbolically as `a ∈ A`.
+* If the value `a` is not contained in the set `A`, then we say `a` does not belong to `A` and represent this symbolically as `a ∉ A`.
+
+### Equality
+
+* If two sets contain the same items then we say the sets are equal, e.g. `A = B`.
+* Order does not matter when determining set equality, e.g. `{ 1, 2, 3, 4 } = { 2, 3, 1, 4 }`.
+* Sets are disjoint, meaning elements cannot be repeated, e.g. `{ 1, 2, 2, 3, 4, 3, 4, 2 } = { 1, 2, 3, 4 }`.
+* Two sets `A` and `B` are equal if and only if `A ⊆ B` and `B ⊆ A`.
+
+## Special Sets
+
+### The Power Set
+* Let `A` be any set. The set that contains all possible subsets of `A` is called a "power set" and is written as `P(A)`. If the set `A` contains `n` elements, then `P(A)` contains `2^N` elements.
+
+```
+P(A) = { x : x ⊆ A }
+```
+
+## Set operations among two sets
+### Union
+Given two sets `A` and `B`, the union of the two sets are the items that appear in either `A` or `B`, written as `A ∪ B`.
+
+```
+A ∪ B = { x : x ∈ A ∪ x ∈ B }
+```
+
+### Intersection
+Given two sets `A` and `B`, the intersection of the two sets are the items that appear in both `A` and `B`, written as `A ∩ B`.
+
+```
+A ∩ B = { x : x ∈ A, x ∈ B }
+```
+
+### Difference
+Given two sets `A` and `B`, the set difference of `A` with `B` is every item in `A` that does not belong to `B`.
+
+```
+A \ B = { x : x ∈ A, x ∉ B }
+```
+
+### Symmetrical difference
+Given two sets `A` and `B`, the symmetrical difference is all items among `A` and `B` that doesn't appear in their intersections.
+
+```
+A △ B = { x : ((x ∈ A) ∩ (x ∉ B)) ∪ ((x ∈ B) ∩ (x ∉ A)) }
+
+A △ B = (A \ B) ∪ (B \ A)
+```
+
+### Cartesian product
+Given two sets `A` and `B`, the cartesian product between `A` and `B` consists of a set containing all combinations of items of `A` and `B`.
+
+```
+A × B = { (x, y) | x ∈ A, y ∈ B }
+```
diff --git a/shutit.html.markdown b/shutit.html.markdown
new file mode 100644
index 00000000..67d7a4b5
--- /dev/null
+++ b/shutit.html.markdown
@@ -0,0 +1,318 @@
+---
+category: tool
+tool: ShutIt
+contributors:
+ - ["Ian Miell", "http://ian.meirionconsulting.tk"]
+filename: learnshutit.html
+---
+
+## ShutIt
+
+ShutIt is an shell automation framework designed to be easy to use.
+
+It is a wrapper around a Python-based expect clone (pexpect).
+
+You can look at it as 'expect without the pain'.
+
+It is available as a pip install.
+
+## Hello World
+
+Starting with the simplest example. Create a file called example.py:
+
+```python
+
+import shutit
+session = shutit.create_session('bash')
+session.send('echo Hello World', echo=True)
+```
+
+Running this with:
+
+```bash
+python example.py
+```
+
+outputs:
+
+```bash
+$ python example.py
+echo "Hello World"
+echo "Hello World"
+Hello World
+Ians-MacBook-Air.local:ORIGIN_ENV:RhuebR2T#
+```
+
+The first argument to 'send' is the command you want to run. The 'echo'
+argument outputs the terminal interactions. By default ShutIt is silent.
+
+'send' takes care of all the messing around with prompts and 'expects' that
+you might be familiar with from expect.
+
+
+## Log Into a Server
+
+Let's say you want to log into a server and run a command. Change example.py
+to:
+
+```python
+import shutit
+session = shutit.create_session('bash')
+session.login('ssh you@example.com', user='you', password='mypassword')
+session.send('hostname', echo=True)
+session.logout()
+```
+
+which will log you into your server (if you replace with your details) and
+output the hostname.
+
+```
+$ python example.py
+hostname
+hostname
+example.com
+example.com:cgoIsdVv:heDa77HB#
+```
+
+Obviously that's insecure! Instead you can run:
+
+```python
+import shutit
+session = shutit.create_session('bash')
+password = session.get_input('', ispass=True)
+session.login('ssh you@example.com', user='you', password=password)
+session.send('hostname', echo=True)
+session.logout()
+```
+
+which forces you to input the password:
+
+```
+$ python example.py
+Input Secret:
+hostname
+hostname
+example.com
+example.com:cgoIsdVv:heDa77HB#
+```
+
+Again, the 'login' method handles the changing prompt from a login. You give
+ShutIt the login command, the user you expect to log in as, and a password
+(if needed), and ShutIt takes care of the rest.
+
+'logout' handles the ending of a 'login', handling any changes to the prompt
+for you.
+
+## Log Into Multiple Servers
+
+Let's say you have a server farm of two servers, and want to log onto both.
+Just create two sessions and run similar login and send commands:
+
+```python
+import shutit
+session1 = shutit.create_session('bash')
+session2 = shutit.create_session('bash')
+password1 = session1.get_input('Password for server1', ispass=True)
+password2 = session2.get_input('Password for server2', ispass=True)
+session1.login('ssh you@one.example.com', user='you', password=password1)
+session2.login('ssh you@two.example.com', user='you', password=password2)
+session1.send('hostname', echo=True)
+session2.send('hostname', echo=True)
+session1.logout()
+session2.logout()
+```
+
+would output:
+
+```bash
+$ python example.py
+Password for server1
+Input Secret:
+
+Password for server2
+Input Secret:
+hostname
+hostname
+one.example.com
+one.example.com:Fnh2pyFj:qkrsmUNs# hostname
+hostname
+two.example.com
+two.example.com:Gl2lldEo:D3FavQjA#
+```
+
+## Example: Monitor Multiple Servers
+
+We can turn the above into a simple monitoring tool by adding some logic to
+examine the output of a command:
+
+```python
+import shutit
+capacity_command="""df / | awk '{print $5}' | tail -1 | sed s/[^0-9]//"""
+session1 = shutit.create_session('bash')
+session2 = shutit.create_session('bash')
+password1 = session.get_input('Password for server1', ispass=True)
+password2 = session.get_input('Password for server2', ispass=True)
+session1.login('ssh you@one.example.com', user='you', password=password1)
+session2.login('ssh you@two.example.com', user='you', password=password2)
+capacity = session1.send_and_get_output(capacity_command)
+if int(capacity) < 10:
+ print('RUNNING OUT OF SPACE ON server1!')
+capacity = session2.send_and_get_output(capacity_command)
+if int(capacity) < 10:
+ print('RUNNING OUT OF SPACE ON server2!')
+session1.logout()
+session2.logout()
+```
+
+Here you use the 'send\_and\_get\_output' method to retrieve the output of the
+capacity command (df).
+
+There are much more elegant ways to do the above (e.g. have a dictionary of the
+servers to iterate over), but it's up to you how clever you need the Python to
+be.
+
+
+## More Intricate IO - Expecting
+
+Let's say you have an interaction with an interactive command line application
+you want to automate. Here we will use telnet as a trivial example:
+
+```python
+import shutit
+session = shutit.create_session('bash')
+session.send('telnet', expect='elnet>', echo=True)
+session.send('open google.com 80', expect='scape character', echo=True)
+session.send('GET /', echo=True, check_exit=False)
+session.logout()
+```
+
+Note the 'expect' argument. You only need to give a subset of telnet's
+prompt to match and continue.
+
+Note also the 'check\_exit' argument in the above, which is new. We'll come back
+to that. The output of the above is:
+
+```bash
+$ python example.py
+telnet
+telnet> open google.com 80
+Trying 216.58.214.14...
+Connected to google.com.
+Escape character is '^]'.
+GET /
+HTTP/1.0 302 Found
+Cache-Control: private
+Content-Type: text/html; charset=UTF-8
+Referrer-Policy: no-referrer
+Location: http://www.google.co.uk/?gfe_rd=cr&ei=huczWcj3GfTW8gfq0paQDA
+Content-Length: 261
+Date: Sun, 04 Jun 2017 10:57:10 GMT
+
+<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
+<TITLE>302 Moved</TITLE></HEAD><BODY>
+<H1>302 Moved</H1>
+The document has moved
+<A HREF="http://www.google.co.uk/?gfe_rd=cr&amp;ei=huczWcj3GfTW8gfq0paQDA">
+here
+</A>.
+</BODY></HTML>
+Connection closed by foreign host.
+```
+
+Now back to 'check\_exit=False'. Since the telnet command returns a failure exit
+code (1) and we don't want the script to fail, you set 'check\_exit=False' to
+let ShutIt know you don't care about the exit code.
+
+If you didn't pass that argument in, ShutIt gives you an interactive terminal
+if there is a terminal to communicate with. This is called a 'pause point'.
+
+
+## Pause Points
+
+You can trigger a 'pause point' at any point by calling
+
+```python
+[...]
+session.pause_point('This is a pause point')
+[...]
+```
+
+within your script, and then continue with the script by hitting CTRL and ']'
+at the same time. This is great for debugging: add a pause point, have a look
+around, then continue. Try this:
+
+```python
+import shutit
+session = shutit.create_session('bash')
+session.pause_point('Have a look around!')
+session.send('echo "Did you enjoy your pause point?"', echo=True)
+```
+
+with output like this:
+
+```bash
+$ python example.py
+Have a look around!
+
+Ians-Air.home:ORIGIN_ENV:I00LA1Mq# bash
+imiell@Ians-Air:/space/git/shutit ⑂ master + 
+CTRL-] caught, continuing with run...
+2017-06-05 15:12:33,577 INFO: Sending: exit
+2017-06-05 15:12:33,633 INFO: Output (squashed): exitexitIans-Air.home:ORIGIN_ENV:I00LA1Mq# [...]
+echo "Did you enjoy your pause point?"
+echo "Did you enjoy your pause point?"
+Did you enjoy your pause point?
+Ians-Air.home:ORIGIN_ENV:I00LA1Mq#
+```
+
+
+## More Intricate IO - Backgrounding
+
+Returning to our 'monitoring multiple servers' example, let's imagine we
+have a long-running task that we want to run on each server. By default, ShutIt
+works serially which would take a long time. But we can run tasks in the
+background to speed things up.
+
+Here you can try an example with the trivial command: 'sleep 60'.
+
+
+```python
+import shutit
+import time
+long_command="""sleep 60"""
+session1 = shutit.create_session('bash')
+session2 = shutit.create_session('bash')
+password1 = session1.get_input('Password for server1', ispass=True)
+password2 = session2.get_input('Password for server2', ispass=True)
+session1.login('ssh you@one.example.com', user='you', password=password1)
+session2.login('ssh you@two.example.com', user='you', password=password2)
+start = time.time()
+session1.send(long_command, background=True)
+session2.send(long_command, background=True)
+print('That took: ' + str(time.time() - start) + ' seconds to fire')
+session1.wait()
+session2.wait()
+print('That took: ' + str(time.time() - start) + ' seconds to complete')
+```
+
+My laptop says it took 0.5 seconds to run fire those two commands, and then just
+over a minute to complete (using the 'wait' method).
+
+Again, this is trivial, but imagine you have hundreds of servers to manage like
+this and you can see the power it can bring in a few lines of code and one
+Python import.
+
+
+## Learn More
+
+There's a lot more that can be done with ShutIt.
+
+To learn more, see:
+
+[ShutIt](https://ianmiell.github.io/shutit/)
+[GitHub](https://github.com/ianmiell/shutit/blob/master/README.md)
+
+It's a broader automation framework, and the above is its 'standalone mode'.
+
+Feedback, feature requests, 'how do I?'s highly appreciated! Reach me at
+[@ianmiell](https://twitter.com/ianmiell)
diff --git a/sk-sk/bash.html.markdown b/sk-sk/bash-sk.html.markdown
index e9d1490c..e9d1490c 100644
--- a/sk-sk/bash.html.markdown
+++ b/sk-sk/bash-sk.html.markdown
diff --git a/sk-sk/coffeescript.html.markdown b/sk-sk/coffeescript-sk.html.markdown
index 30bbceec..30bbceec 100644
--- a/sk-sk/coffeescript.html.markdown
+++ b/sk-sk/coffeescript-sk.html.markdown
diff --git a/sk-sk/elixir.html.markdown b/sk-sk/elixir-sk.html.markdown
index 2401f92e..2401f92e 100644
--- a/sk-sk/elixir.html.markdown
+++ b/sk-sk/elixir-sk.html.markdown
diff --git a/sk-sk/git.html.markdown b/sk-sk/git-sk.html.markdown
index 21741406..21741406 100644
--- a/sk-sk/git.html.markdown
+++ b/sk-sk/git-sk.html.markdown
diff --git a/sk-sk/json.html.markdown b/sk-sk/json-sk.html.markdown
index 2b1fbb58..2b1fbb58 100644
--- a/sk-sk/json.html.markdown
+++ b/sk-sk/json-sk.html.markdown
diff --git a/sk-sk/latex.html.markdown.tex b/sk-sk/latex-sk.html.markdown.tex
index 5e2f9c7f..5e2f9c7f 100644
--- a/sk-sk/latex.html.markdown.tex
+++ b/sk-sk/latex-sk.html.markdown.tex
diff --git a/sk-sk/ruby.html.markdown b/sk-sk/ruby-sk.html.markdown
index 799865b0..799865b0 100644
--- a/sk-sk/ruby.html.markdown
+++ b/sk-sk/ruby-sk.html.markdown
diff --git a/sl-si/asciidoc-sl.html.markdown b/sl-si/asciidoc-sl.html.markdown
new file mode 100644
index 00000000..52f30fbd
--- /dev/null
+++ b/sl-si/asciidoc-sl.html.markdown
@@ -0,0 +1,136 @@
+---
+language: asciidoc
+contributors:
+ - ["Ryan Mavilia", "http://unoriginality.rocks/"]
+ - ["Abel Salgado Romero", "https://twitter.com/abelsromero"]
+translators:
+ - ["Filip Štamcar", "https://github.com/filips123"]
+lang: sl-si
+filename: asciidoc-sl.md
+---
+
+AsciiDoc je označevalni jezik, ki je podoben Markdownu in ga je mogoče uporabiti za vse od knjig do spletnih dnevnikov. Jezik, ki ga je leta 2002 ustvaril Stuart Rackham, je preprost, vendar omogoča veliko prilagoditev.
+
+## Glava dokumenta
+
+Glave so neobvezne in ne smejo vsebovati praznih vrstic. Od vsebine jih mora ločiti vsaj ena prazna vrstica.
+
+### Naslov
+
+```
+= Naslov dokumenta
+
+Prvi stavek dokumenta.
+```
+
+### Naslov in avtor
+
+```
+= Naslov dokumenta
+Ime Priimek <ime.priimek@learnxinyminutes.com>
+
+Prvi stavek dokumenta.
+```
+
+### Naslov in več avtorjev
+
+```
+
+= Naslov dokumenta
+Ime Priimek <ime.priimek@learnxinyminutes.com>; Janez Novak <janez.novak@pirate.com>
+
+Prvi stavek dokumenta.
+```
+
+Vrstica za revizijo
+
+```
+= Naslov dokumenta V1
+Janez Novak <janez.novak@pirate.com>
+v1.0, 2016-01-13
+
+Prvi stavek dokumenta.
+```
+
+## Odstavki
+
+```
+Za odstavke ne potrebujete nič posebnega.
+
+Da jih ločite, dodajte prazno črto med odstavki.
+
+Če želite ustvariti prazno vrstico, dodajte +
+in ustvarili boste prelom vrstice!
+```
+
+## Oblikovanje besedila
+
+```
+_podčrtaj za pošvno_
+*zvezdice za krepko*
+*_kombinacije za zabavo_*
+`krativec za monospace`
+`*krepki monospace*`
+```
+
+## Naslovi razdelkov
+
+```
+= Stopnja 0 (samo za naslov dokumenta)
+
+== Stopnja 1 <h2>
+
+=== Stopnja 2 <h3>
+
+==== Stopnja 3 <h4>
+
+===== Stopnja 4 <h5>
+
+```
+
+## Seznami
+
+Če želite ustvariti neoštevilčen seznam, uporabite zvezdice.
+
+```
+* foo
+* bar
+* baz
+```
+
+Če želite ustvaril oštevilčen seznam, uporabite pike.
+
+```
+. predmet 1
+. predmet 2
+. predmet 3
+```
+
+Seznami lahko do petkrat gnezdite tako, da dodate dodatne zvezdice ali pike.
+
+```
+* foo 1
+** foo 2
+*** foo 3
+**** foo 4
+***** foo 5
+
+. foo 1
+.. foo 2
+... foo 3
+.... foo 4
+..... foo 5
+```
+
+## Nadaljnje branje
+
+Obstajata dve orodji za obdelavo AsciiDoc dokumentov:
+
+1. [AsciiDoc](http://asciidoc.org/): izvirna implementacija v Pythonu je na voljo v glavnih distribucijah Linuxa. Stabilen in trenutno v vzdrževalnem načinu.
+2. [Asciidoctor](http://asciidoctor.org/): alternativna Ruby implementacija, uporabno tudi iz Java in JavaScript. Z aktivnim razvojem si prizadeva razširiti sintakso AsciiDoc z novimi funkcijami in izhodnimi formati.
+
+Naslednje povezave so povezane `Asciidoctor` implementacijo:
+
+* [Markdown - AsciiDoc syntax comparison](http://asciidoctor.org/docs/user-manual/#comparison-by-example): primerjava skupnih elementov Markdowna in AsciiDoca.
+* [Getting started](http://asciidoctor.org/docs/#get-started-with-asciidoctor): namestitev in navodila, ki omogočajo enostavne dokumente.
+* [Asciidoctor User Manual](http://asciidoctor.org/docs/user-manual/): popolni priročnik z enim dokumentom s sklicevanjem na sintakso, primeri in oridji za upodabljanje.
diff --git a/smalltalk.html.markdown b/smalltalk.html.markdown
index cc7ab84c..aaa592dc 100644
--- a/smalltalk.html.markdown
+++ b/smalltalk.html.markdown
@@ -1,229 +1,271 @@
---
-language: smalltalk
+language: Smalltalk
+filename: smalltalk.st
contributors:
- - ["Jigyasa Grover", "https://github.com/jig08"]
+ - ["Jigyasa Grover", "https://github.com/jigyasa-grover"]
+ - ["tim Rowledge", "tim@rowledge.org"]
---
-- Smalltalk is an object-oriented, dynamically typed, reflective programming language.
+- Smalltalk is a fully object-oriented, dynamically typed, reflective programming language with no 'non-object' types.
- Smalltalk was created as the language to underpin the "new world" of computing exemplified by "human–computer symbiosis."
- It was designed and created in part for educational use, more so for constructionist learning, at the Learning Research Group (LRG) of Xerox PARC by Alan Kay, Dan Ingalls, Adele Goldberg, Ted Kaehler, Scott Wallace, and others during the 1970s.
-Feedback highly appreciated! Reach me at [@jigyasa_grover](https://twitter.com/jigyasa_grover) or send me an e-mail at `grover.jigyasa1@gmail.com`.
+`Feedback highly appreciated! Reach me at [@jigyasa_grover](https://twitter.com/jigyasa_grover) or send me an e-mail at grover.jigyasa1@gmail.com.`
+## The Basics
-##Allowable characters:
+### Everything is an object
+Yes, everything. Integers are instances of one of the numeric classes. Classes are instances of the class Metaclass and are just as manipulable as any other object. All classes are part of a single class tree; no disjoint class trees. Stack frames are objects and can be manipulated, which is how the debugger works. There are no pointers into memory locations that you can dereference and mess with.
+
+### Functions are not called; messages are sent to objects
+- Work is done by sending messages to objects, which decide how to respond to that message and run a method as a result, which eventually returns some object to the original message sending code.
+- The system knows the class of the object receiving a message and looks up the message in that class's list of methods. If it is not found, the lookup continues in the super class until either it is found or the root of the classes is reached and there is still no relevant method.
+- If a suitable method is found the code is run, and the same process keeps on going with all the methods sent by that method and so on forever.
+- If no suitable method is found an exception is raised, which typically results in a user interface notifier to tell the user that the message was not understood. It is entirely possible to catch the exception and do something to fix the problem, which might range from 'ignore it' to 'load some new packages for this class and try again'.
+- A method (more strictly an instance of the class CompiledMethod) is a chunk of Smalltalk code that has been compiled into bytecodes. Executing methods start at the beginning and return to the sender when a return is encountered (we use ^ to signify 'return the following object') or the end of the code is reached, in which case the current object running the code is returned.
+
+### Simple syntax
+Smalltalk has a simple syntax with very few rules.
+The most basic operation is to send a message to an object
+`anObject aMessage`
+
+There are three sorts of messages
+
+- unary - a single symbol that may be several words conjoined in what we call camelcase form, with no arguments. For example 'size', 'reverseBytes', 'convertToLargerFormatPixels'
+- binary - a small set of symbols of the sort often used for arithmetic operations in most languages, requiring a single argument. For example '+', '//', '@'. We do not use traditional arithmetic precedence, something to keep an eye on.
+- keyword - the general form where multiple arguments can be passed. As with the unary form we use camelcase to join words together but arguments are inserted in the midst of the message with colons used to separate them lexically. For example 'setTemperature:', 'at:put:', 'drawFrom:to:lineWidth:fillColor:'
+
+#### An example
+`result := myObject doSomethingWith: thatObject`
+We are sending the message 'doSomethingWith:' to myObject. This happens to be a message that has a single argument but that's not important yet.
+'myObject' is a 'MyExampleClass' instance so the system looks at the list of messages understood by MyExampleClass
+
+- beClever
+- doWeirdThing:
+- doSomethingWith
+
+In searching we see what initially looks like a match - but no, it lacks the final colon. So we find the super class of MyExampleClass - BigExampleClass. Which has a list of known messages of its own
+
+- beClever
+- doSomethingWith:
+- buildCastleInAir
+- annoyUserByDoing:
+
+We find a proper exact match and start to execute the code:
+
+```smalltalk
+doSomethingWith: argumentObject
+ self size > 4 ifTrue: [^argumentObject sizeRelatingTo: self].
+```
+
+Everything here except the `^` involves sending more messages. Event the `ifTrue:` that you might think is a language control structure is just Smalltalk code.
+
+We start by sending `size` to `self`. `self` is the object currently running the code - so in this case it is the myObject we started with. `size` is a very common message that we might anticipate tells us something about how big an object is; you could look it up with the Smalltalk tools very simply. The result we get is then sent the message `>` with the plain old integer 4 (which is an object too; no strange primitive types to pollute the system here) and nobody should be surprised the `>` is a comparison that answers true or false. That boolean (which is actually a Boolean object in Smalltalk) is sent the message `ifTrue:` with the block of code between the `[]` as its argument; obvioulsy a true boolean might be expected to run that block of code and a false to ignore it.
+
+If the block is run then we do some more message sending to the argument object and noting the `^` we return the answer back to our starting point and it gets assigned to `result`. If the block is ignored we seem to run out of code and so `self` is returned and assigned to `result`.
+
+## Smalltalk quick reference cheat-sheet
+Taken from [Smalltalk Cheatsheet](http://www.angelfire.com/tx4/cus/notes/smalltalk.html)
+
+#### Allowable characters:
- a-z
- A-Z
- 0-9
- .+/\*~<>@%|&?
- blank, tab, cr, ff, lf
-##Variables:
-- variables must be declared before use
-- shared vars must begin with uppercase
-- local vars must begin with lowercase
-- reserved names: `nil`, `true`, `false`, `self`, `super`, and `Smalltalk`
+#### Variables:
+- variable names must be declared before use but are untyped
+- shared vars (globals, class vars) conventionally begin with uppercase (except the reserved names shown below)
+- local vars (instance vars, temporaries, method & block arguments) conventionally begin with lowercase
+- reserved names: `nil`, `true`, `false`, `self`, `super`, and `thisContext`
-##Variable scope:
-- Global: defined in Dictionary Smalltalk and accessible by all objects in system - Special: (reserved) `Smalltalk`, `super`, `self`, `true`, `false`, & `nil`
+#### Variable scope:
+- Global: defined in a Dictionary named 'Smalltalk' and accessible by all objects in system
+- Special: (reserved) `Smalltalk`, `super`, `self`, `true`, `false`, & `nil`
- Method Temporary: local to a method
- Block Temporary: local to a block
-- Pool: variables in a Dictionary object
-- Method Parameters: automatic local vars created as a result of message call with params
-- Block Parameters: automatic local vars created as a result of value: message call
-- Class: shared with all instances of one class & its subclasses
-- Class Instance: unique to each instance of a class
-- Instance Variables: unique to each instance
+- Pool: variables in a Dictionary object, possibly shared with classes not directly related by inheritance
+- Method Parameters: automatic method temp vars that name the incoming parameters. Cannot be assigned to
+- Block Parameters: automatic block temp vars that name the incoming parameters. Cannot be assigned to
+- Class: shared with all instances of a class & its subclasses
+- Class Instance: unique to each instance of a class. Too commonly confused with class variables
+- Instance Variables: unique to each instance of a class
-`"Comments are enclosed in quotes"`
+`"Comments are enclosed in quotes and may be arbitrary length"`
-`"Period (.) is the statement separator"`
+`"Period (.) is the statement separator. Not required on last line of a method"`
-## Transcript:
-```
-Transcript clear. "clear to transcript window"
-Transcript show: 'Hello World'. "output string in transcript window"
-Transcript nextPutAll: 'Hello World'. "output string in transcript window"
-Transcript nextPut: $A. "output character in transcript window"
-Transcript space. "output space character in transcript window"
-Transcript tab. "output tab character in transcript window"
-Transcript cr. "carriage return / linefeed"
-'Hello' printOn: Transcript. "append print string into the window"
-'Hello' storeOn: Transcript. "append store string into the window"
-Transcript endEntry. "flush the output buffer"
+#### Transcript:
+```smalltalk
+Transcript clear. "clear to transcript window"
+Transcript show: 'Hello World'. "output string in transcript window"
+Transcript nextPutAll: 'Hello World'. "output string in transcript window"
+Transcript nextPut: $A. "output character in transcript window"
+Transcript space. "output space character in transcript window"
+Transcript tab. "output tab character in transcript window"
+Transcript cr. "carriage return / linefeed"
+'Hello' printOn: Transcript. "append print string into the window"
+'Hello' storeOn: Transcript. "append store string into the window"
+Transcript endEntry. "flush the output buffer"
```
-##Assignment:
-```
+#### Assignment:
+```smalltalk
| x y |
-x _ 4. "assignment (Squeak) <-"
-x := 5. "assignment"
-x := y := z := 6. "compound assignment"
+x _ 4. "assignment (Squeak) <-"
+x := 5. "assignment"
+x := y := z := 6. "compound assignment"
x := (y := 6) + 1.
-x := Object new. "bind to allocated instance of a class"
-x := 123 class. "discover the object class"
-x := Integer superclass. "discover the superclass of a class"
-x := Object allInstances. "get an array of all instances of a class"
-x := Integer allSuperclasses. "get all superclasses of a class"
-x := 1.2 hash. "hash value for object"
-y := x copy. "copy object"
-y := x shallowCopy. "copy object (not overridden)"
-y := x deepCopy. "copy object and instance vars"
-y := x veryDeepCopy. "complete tree copy using a dictionary"
+x := Object new. "bind to allocated instance of a class"
```
-##Constants:
-```
+#### Constants:
+```smalltalk
| b |
-b := true. "true constant"
-b := false. "false constant"
-x := nil. "nil object constant"
-x := 1. "integer constants"
-x := 3.14. "float constants"
-x := 2e-2. "fractional constants"
-x := 16r0F. "hex constant".
-x := -1. "negative constants"
-x := 'Hello'. "string constant"
-x := 'I''m here'. "single quote escape"
-x := $A. "character constant"
-x := $ . "character constant (space)"
-x := #aSymbol. "symbol constants"
-x := #(3 2 1). "array constants"
-x := #('abc' 2 $a). "mixing of types allowed"
-
-```
-
-## Booleans:
+b := true. "true constant"
+b := false. "false constant"
+x := nil. "nil object constant"
+x := 1. "integer constants"
+x := 3.14. "float constants"
+x := 2e-2. "fractional constants"
+x := 16r0F. "hex constant".
+x := -1. "negative constants"
+x := 'Hello'. "string constant"
+x := 'I''m here'. "single quote escape"
+x := $A. "character constant"
+x := $ . "character constant (space)"
+x := #aSymbol. "symbol constants"
+x := #(3 2 1). "array constants"
+x := #('abc' 2 $a). "mixing of types allowed"
```
+
+#### Booleans:
+```smalltalk
| b x y |
x := 1. y := 2.
-b := (x = y). "equals"
-b := (x ~= y). "not equals"
-b := (x == y). "identical"
-b := (x ~~ y). "not identical"
-b := (x > y). "greater than"
-b := (x < y). "less than"
-b := (x >= y). "greater than or equal"
-b := (x <= y). "less than or equal"
-b := b not. "boolean not"
-b := (x < 5) & (y > 1). "boolean and"
-b := (x < 5) | (y > 1). "boolean or"
-b := (x < 5) and: [y > 1]. "boolean and (short-circuit)"
-b := (x < 5) or: [y > 1]. "boolean or (short-circuit)"
-b := (x < 5) eqv: (y > 1). "test if both true or both false"
-b := (x < 5) xor: (y > 1). "test if one true and other false"
-b := 5 between: 3 and: 12. "between (inclusive)"
-b := 123 isKindOf: Number. "test if object is class or subclass of"
-b := 123 isMemberOf: SmallInteger. "test if object is type of class"
-b := 123 respondsTo: sqrt. "test if object responds to message"
-b := x isNil. "test if object is nil"
-b := x isZero. "test if number is zero"
-b := x positive. "test if number is positive"
-b := x strictlyPositive. "test if number is greater than zero"
-b := x negative. "test if number is negative"
-b := x even. "test if number is even"
-b := x odd. "test if number is odd"
-b := x isLiteral. "test if literal constant"
-b := x isInteger. "test if object is integer"
-b := x isFloat. "test if object is float"
-b := x isNumber. "test if object is number"
-b := $A isUppercase. "test if upper case character"
-b := $A isLowercase. "test if lower case character"
-
-```
-
-## Arithmetic expressions:
+b := (x = y). "equals"
+b := (x ~= y). "not equals"
+b := (x == y). "identical"
+b := (x ~~ y). "not identical"
+b := (x > y). "greater than"
+b := (x < y). "less than"
+b := (x >= y). "greater than or equal"
+b := (x <= y). "less than or equal"
+b := b not. "boolean not"
+b := (x < 5) & (y > 1). "boolean and"
+b := (x < 5) | (y > 1). "boolean or"
+b := (x < 5) and: [y > 1]. "boolean and (short-circuit)"
+b := (x < 5) or: [y > 1]. "boolean or (short-circuit)"
+b := (x < 5) eqv: (y > 1). "test if both true or both false"
+b := (x < 5) xor: (y > 1). "test if one true and other false"
+b := 5 between: 3 and: 12. "between (inclusive)"
+b := 123 isKindOf: Number. "test if object is class or subclass of"
+b := 123 isMemberOf: SmallInteger. "test if object is type of class"
+b := 123 respondsTo: sqrt. "test if object responds to message"
+b := x isNil. "test if object is nil"
+b := x isZero. "test if number is zero"
+b := x positive. "test if number is positive"
+b := x strictlyPositive. "test if number is greater than zero"
+b := x negative. "test if number is negative"
+b := x even. "test if number is even"
+b := x odd. "test if number is odd"
+b := x isLiteral. "test if literal constant"
+b := x isInteger. "test if object is integer"
+b := x isFloat. "test if object is float"
+b := x isNumber. "test if object is number"
+b := $A isUppercase. "test if upper case character"
+b := $A isLowercase. "test if lower case character"
```
+
+#### Arithmetic expressions:
+```smalltalk
| x |
-x := 6 + 3. "addition"
-x := 6 - 3. "subtraction"
-x := 6 * 3. "multiplication"
-x := 1 + 2 * 3. "evaluation always left to right (1 + 2) * 3"
-x := 5 / 3. "division with fractional result"
-x := 5.0 / 3.0. "division with float result"
-x := 5.0 // 3.0. "integer divide"
-x := 5.0 \\ 3.0. "integer remainder"
-x := -5. "unary minus"
-x := 5 sign. "numeric sign (1, -1 or 0)"
-x := 5 negated. "negate receiver"
-x := 1.2 integerPart. "integer part of number (1.0)"
-x := 1.2 fractionPart. "fractional part of number (0.2)"
-x := 5 reciprocal. "reciprocal function"
-x := 6 * 3.1. "auto convert to float"
-x := 5 squared. "square function"
-x := 25 sqrt. "square root"
-x := 5 raisedTo: 2. "power function"
-x := 5 raisedToInteger: 2. "power function with integer"
-x := 5 exp. "exponential"
-x := -5 abs. "absolute value"
-x := 3.99 rounded. "round"
-x := 3.99 truncated. "truncate"
-x := 3.99 roundTo: 1. "round to specified decimal places"
-x := 3.99 truncateTo: 1. "truncate to specified decimal places"
-x := 3.99 floor. "truncate"
-x := 3.99 ceiling. "round up"
-x := 5 factorial. "factorial"
-x := -5 quo: 3. "integer divide rounded toward zero"
-x := -5 rem: 3. "integer remainder rounded toward zero"
-x := 28 gcd: 12. "greatest common denominator"
-x := 28 lcm: 12. "least common multiple"
-x := 100 ln. "natural logarithm"
-x := 100 log. "base 10 logarithm"
-x := 100 log: 10. "logarithm with specified base"
-x := 100 floorLog: 10. "floor of the log"
-x := 180 degreesToRadians. "convert degrees to radians"
-x := 3.14 radiansToDegrees. "convert radians to degrees"
-x := 0.7 sin. "sine"
-x := 0.7 cos. "cosine"
-x := 0.7 tan. "tangent"
-x := 0.7 arcSin. "arcsine"
-x := 0.7 arcCos. "arccosine"
-x := 0.7 arcTan. "arctangent"
-x := 10 max: 20. "get maximum of two numbers"
-x := 10 min: 20. "get minimum of two numbers"
-x := Float pi. "pi"
-x := Float e. "exp constant"
-x := Float infinity. "infinity"
-x := Float nan. "not-a-number"
-x := Random new next; yourself. x next. "random number stream (0.0 to 1.0)
-x := 100 atRandom. "quick random number"
-
-```
-
-##Bitwise Manipulation:
+x := 6 + 3. "addition"
+x := 6 - 3. "subtraction"
+x := 6 * 3. "multiplication"
+x := 1 + 2 * 3. "evaluation always left to right (1 + 2) * 3"
+x := 5 / 3. "division with fractional result"
+x := 5.0 / 3.0. "division with float result"
+x := 5.0 // 3.0. "integer divide"
+x := 5.0 \\ 3.0. "integer remainder"
+x := -5. "unary minus"
+x := 5 sign. "numeric sign (1, -1 or 0)"
+x := 5 negated. "negate receiver"
+x := 1.2 integerPart. "integer part of number (1.0)"
+x := 1.2 fractionPart. "fractional part of number (0.2)"
+x := 5 reciprocal. "reciprocal function"
+x := 6 * 3.1. "auto convert to float"
+x := 5 squared. "square function"
+x := 25 sqrt. "square root"
+x := 5 raisedTo: 2. "power function"
+x := 5 raisedToInteger: 2. "power function with integer"
+x := 5 exp. "exponential"
+x := -5 abs. "absolute value"
+x := 3.99 rounded. "round"
+x := 3.99 truncated. "truncate"
+x := 3.99 roundTo: 1. "round to specified decimal places"
+x := 3.99 truncateTo: 1. "truncate to specified decimal places"
+x := 3.99 floor. "truncate"
+x := 3.99 ceiling. "round up"
+x := 5 factorial. "factorial"
+x := -5 quo: 3. "integer divide rounded toward zero"
+x := -5 rem: 3. "integer remainder rounded toward zero"
+x := 28 gcd: 12. "greatest common denominator"
+x := 28 lcm: 12. "least common multiple"
+x := 100 ln. "natural logarithm"
+x := 100 log. "base 10 logarithm"
+x := 100 log: 10. "floor of the log"
+x := 180 degreesToRadians. "convert degrees to radians"
+x := 3.14 radiansToDegrees. "convert radians to degrees"
+x := 0.7 sin. "sine"
+x := 0.7 cos. "cosine"
+x := 0.7 tan. "tangent"
+x := 0.7 arcSin. "arcsine"
+x := 0.7 arcCos. "arccosine"
+x := 0.7 arcTan. "arctangent"
+x := 10 max: 20. "get maximum of two numbers"
+x := 10 min: 20. "get minimum of two numbers"
+x := Float pi. "pi"
+x := Float e. "exp constant"
+x := Float infinity. "infinity"
+x := Float nan. "not-a-number"
+x := Random new next; yourself. x next. "random number stream (0.0 to 1.0)"
+x := 100 atRandom. "quick random number"
```
-| b x |
-x := 16rFF bitAnd: 16r0F. "and bits"
-x := 16rF0 bitOr: 16r0F. "or bits"
-x := 16rFF bitXor: 16r0F. "xor bits"
-x := 16rFF bitInvert. "invert bits"
-x := 16r0F bitShift: 4. "left shift"
-x := 16rF0 bitShift: -4. "right shift"
-"x := 16r80 bitAt: 7." "bit at position (0|1) [!Squeak]"
-x := 16r80 highbit. "position of highest bit set"
-b := 16rFF allMask: 16r0F. "test if all bits set in mask set in receiver"
-b := 16rFF anyMask: 16r0F. "test if any bits set in mask set in receiver"
-b := 16rFF noMask: 16r0F. "test if all bits set in mask clear in receiver"
+#### Bitwise Manipulation:
+```smalltalk
+| b x |
+x := 16rFF bitAnd: 16r0F. "and bits"
+x := 16rF0 bitOr: 16r0F. "or bits"
+x := 16rFF bitXor: 16r0F. "xor bits"
+x := 16rFF bitInvert. "invert bits"
+x := 16r0F bitShift: 4. "left shift"
+x := 16rF0 bitShift: -4. "right shift"
+"x := 16r80 bitAt: 7." "bit at position (0|1) [!Squeak]"
+x := 16r80 highbit. "position of highest bit set"
+b := 16rFF allMask: 16r0F. "test if all bits set in mask set in receiver"
+b := 16rFF anyMask: 16r0F. "test if any bits set in mask set in receiver"
+b := 16rFF noMask: 16r0F. "test if all bits set in mask clear in receiver"
```
-## Conversion:
-```
+#### Conversion:
+```smalltalk
| x |
-x := 3.99 asInteger. "convert number to integer (truncates in Squeak)"
-x := 3.99 asFraction. "convert number to fraction"
-x := 3 asFloat. "convert number to float"
-x := 65 asCharacter. "convert integer to character"
-x := $A asciiValue. "convert character to integer"
-x := 3.99 printString. "convert object to string via printOn:"
-x := 3.99 storeString. "convert object to string via storeOn:"
-x := 15 radix: 16. "convert to string in given base"
+x := 3.99 asInteger. "convert number to integer (truncates in Squeak)"
+x := 3.99 asFraction. "convert number to fraction"
+x := 3 asFloat. "convert number to float"
+x := 65 asCharacter. "convert integer to character"
+x := $A asciiValue. "convert character to integer"
+x := 3.99 printString. "convert object to string via printOn:"
+x := 3.99 storeString. "convert object to string via storeOn:"
+x := 15 radix: 16. "convert to string in given base"
x := 15 printStringBase: 16.
x := 15 storeStringBase: 16.
-
```
-## Blocks:
+#### Blocks:
- blocks are objects and may be assigned to a variable
- value is last expression evaluated unless explicit return
- blocks may be nested
@@ -233,18 +275,20 @@ x := 15 storeStringBase: 16.
- `^`expression terminates block & method (exits all nested blocks)
- blocks intended for long term storage should not contain `^`
-```
+```smalltalk
| x y z |
x := [ y := 1. z := 2. ]. x value. "simple block usage"
x := [ :argOne :argTwo | argOne, ' and ' , argTwo.]. "set up block with argument passing"
Transcript show: (x value: 'First' value: 'Second'); cr. "use block with argument passing"
+
"x := [ | z | z := 1.]. *** localvars not available in squeak blocks"
```
-## Method calls:
+#### Method calls:
- unary methods are messages with no arguments
- binary methods
-- keyword methods are messages with selectors including colons standard categories/protocols: - initialize-release (methods called for new instance)
+- keyword methods are messages with selectors including colons standard categories/protocols:
+- initialize-release (methods called for new instance)
- accessing (get/set methods)
- testing (boolean tests - is)
- comparing (boolean tests with parameter
@@ -253,29 +297,34 @@ Transcript show: (x value: 'First' value: 'Second'); cr. "use block with argu
- updating (receive notification of changes)
- private (methods private to class)
- instance-creation (class methods for creating instance)
-```
+
+```smalltalk
| x |
-x := 2 sqrt. "unary message"
-x := 2 raisedTo: 10. "keyword message"
-x := 194 * 9. "binary message"
-Transcript show: (194 * 9) printString; cr. "combination (chaining)"
-x := 2 perform: #sqrt. "indirect method invocation"
-Transcript "Cascading - send multiple messages to receiver"
+x := 2 sqrt. "unary message"
+x := 2 raisedTo: 10. "keyword message"
+x := 194 * 9. "binary message"
+Transcript show: (194 * 9) printString; cr. "combination (chaining)"
+x := 2 perform: #sqrt. "indirect method invocation"
+Transcript "Cascading - send multiple messages to receiver"
show: 'hello ';
show: 'world';
cr.
-x := 3 + 2; * 100. "result=300. Sends message to same receiver (3)"
+x := 3 + 2; * 100. "result=300. Sends message to same receiver (3)"
```
-##Conditional Statements:
-```
+#### Conditional Statements:
+```smalltalk
| x |
-x > 10 ifTrue: [Transcript show: 'ifTrue'; cr]. "if then"
-x > 10 ifFalse: [Transcript show: 'ifFalse'; cr]. "if else"
-x > 10 "if then else"
+x > 10 ifTrue: [Transcript show: 'ifTrue'; cr]. "if then"
+x > 10 ifFalse: [Transcript show: 'ifFalse'; cr]. "if else"
+
+"if then else"
+x > 10
ifTrue: [Transcript show: 'ifTrue'; cr]
ifFalse: [Transcript show: 'ifFalse'; cr].
-x > 10 "if else then"
+
+"if else then"
+x > 10
ifFalse: [Transcript show: 'ifFalse'; cr]
ifTrue: [Transcript show: 'ifTrue'; cr].
Transcript
@@ -284,7 +333,9 @@ Transcript
ifTrue: ['ifTrue']
ifFalse: ['ifFalse']);
cr.
-Transcript "nested if then else"
+
+"nested if then else"
+Transcript
show:
(x > 10
ifTrue: [x > 5
@@ -292,397 +343,419 @@ Transcript "nested if then else
ifFalse: ['B']]
ifFalse: ['C']);
cr.
-switch := Dictionary new. "switch functionality"
+
+"switch functionality"
+switch := Dictionary new.
switch at: $A put: [Transcript show: 'Case A'; cr].
switch at: $B put: [Transcript show: 'Case B'; cr].
switch at: $C put: [Transcript show: 'Case C'; cr].
result := (switch at: $B) value.
```
-## Iteration statements:
-```
+#### Iteration statements:
+```smalltalk
| x y |
x := 4. y := 1.
-[x > 0] whileTrue: [x := x - 1. y := y * 2]. "while true loop"
-[x >= 4] whileFalse: [x := x + 1. y := y * 2]. "while false loop"
-x timesRepeat: [y := y * 2]. "times repeat loop (i := 1 to x)"
-1 to: x do: [:a | y := y * 2]. "for loop"
-1 to: x by: 2 do: [:a | y := y / 2]. "for loop with specified increment"
-#(5 4 3) do: [:a | x := x + a]. "iterate over array elements"
+[x > 0] whileTrue: [x := x - 1. y := y * 2]. "while true loop"
+[x >= 4] whileFalse: [x := x + 1. y := y * 2]. "while false loop"
+x timesRepeat: [y := y * 2]. "times repeat loop (i := 1 to x)"
+1 to: x do: [:a | y := y * 2]. "for loop"
+1 to: x by: 2 do: [:a | y := y / 2]. "for loop with specified increment"
+#(5 4 3) do: [:a | x := x + a]. "iterate over array elements"
```
-## Character:
-```
+#### Character:
+```smalltalk
| x y |
-x := $A. "character assignment"
-y := x isLowercase. "test if lower case"
-y := x isUppercase. "test if upper case"
-y := x isLetter. "test if letter"
-y := x isDigit. "test if digit"
-y := x isAlphaNumeric. "test if alphanumeric"
-y := x isSeparator. "test if separator char"
-y := x isVowel. "test if vowel"
-y := x digitValue. "convert to numeric digit value"
-y := x asLowercase. "convert to lower case"
-y := x asUppercase. "convert to upper case"
-y := x asciiValue. "convert to numeric ascii value"
-y := x asString. "convert to string"
-b := $A <= $B. "comparison"
+x := $A. "character assignment"
+y := x isLowercase. "test if lower case"
+y := x isUppercase. "test if upper case"
+y := x isLetter. "test if letter"
+y := x isDigit. "test if digit"
+y := x isAlphaNumeric. "test if alphanumeric"
+y := x isSeparator. "test if separator char"
+y := x isVowel. "test if vowel"
+y := x digitValue. "convert to numeric digit value"
+y := x asLowercase. "convert to lower case"
+y := x asUppercase. "convert to upper case"
+y := x asciiValue. "convert to numeric ascii value"
+y := x asString. "convert to string"
+b := $A <= $B. "comparison"
y := $A max: $B.
-
```
-## Symbol:
-```
+#### Symbol:
+```smalltalk
| b x y |
-x := #Hello. "symbol assignment"
-y := 'String', 'Concatenation'. "symbol concatenation (result is string)"
-b := x isEmpty. "test if symbol is empty"
-y := x size. "string size"
-y := x at: 2. "char at location"
-y := x copyFrom: 2 to: 4. "substring"
-y := x indexOf: $e ifAbsent: [0]. "first position of character within string"
-x do: [:a | Transcript show: a printString; cr]. "iterate over the string"
-b := x conform: [:a | (a >= $a) & (a <= $z)]. "test if all elements meet condition"
-y := x select: [:a | a > $a]. "return all elements that meet condition"
-y := x asString. "convert symbol to string"
-y := x asText. "convert symbol to text"
-y := x asArray. "convert symbol to array"
-y := x asOrderedCollection. "convert symbol to ordered collection"
-y := x asSortedCollection. "convert symbol to sorted collection"
-y := x asBag. "convert symbol to bag collection"
-y := x asSet. "convert symbol to set collection"
-```
-
-## String:
+x := #Hello. "symbol assignment"
+y := #Symbol, #Concatenation. "symbol concatenation (result is string)"
+b := x isEmpty. "test if symbol is empty"
+y := x size. "string size"
+y := x at: 2. "char at location"
+y := x copyFrom: 2 to: 4. "substring"
+y := x indexOf: $e ifAbsent: [0]. "first position of character within string"
+x do: [:a | Transcript show: a printString; cr]. "iterate over the string"
+b := x conform: [:a | (a >= $a) & (a <= $z)]. "test if all elements meet condition"
+y := x select: [:a | a > $a]. "return all elements that meet condition"
+y := x asString. "convert symbol to string"
+y := x asText. "convert symbol to text"
+y := x asArray. "convert symbol to array"
+y := x asOrderedCollection. "convert symbol to ordered collection"
+y := x asSortedCollection. "convert symbol to sorted collection"
+y := x asBag. "convert symbol to bag collection"
+y := x asSet. "convert symbol to set collection"
```
+
+#### String:
+```smalltalk
| b x y |
-x := 'This is a string'. "string assignment"
-x := 'String', 'Concatenation'. "string concatenation"
-b := x isEmpty. "test if string is empty"
-y := x size. "string size"
-y := x at: 2. "char at location"
-y := x copyFrom: 2 to: 4. "substring"
-y := x indexOf: $a ifAbsent: [0]. "first position of character within string"
-x := String new: 4. "allocate string object"
-x "set string elements"
+x := 'This is a string'. "string assignment"
+x := 'String', 'Concatenation'. "string concatenation"
+b := x isEmpty. "test if string is empty"
+y := x size. "string size"
+y := x at: 2. "char at location"
+y := x copyFrom: 2 to: 4. "substring"
+y := x indexOf: $a ifAbsent: [0]. "first position of character within string"
+x := String new: 4. "allocate string object"
+x "set string elements"
at: 1 put: $a;
at: 2 put: $b;
at: 3 put: $c;
at: 4 put: $e.
-x := String with: $a with: $b with: $c with: $d. "set up to 4 elements at a time"
-x do: [:a | Transcript show: a printString; cr]. "iterate over the string"
-b := x conform: [:a | (a >= $a) & (a <= $z)]. "test if all elements meet condition"
-y := x select: [:a | a > $a]. "return all elements that meet condition"
-y := x asSymbol. "convert string to symbol"
-y := x asArray. "convert string to array"
-x := 'ABCD' asByteArray. "convert string to byte array"
-y := x asOrderedCollection. "convert string to ordered collection"
-y := x asSortedCollection. "convert string to sorted collection"
-y := x asBag. "convert string to bag collection"
-y := x asSet. "convert string to set collection"
-y := x shuffled. "randomly shuffle string"
-```
-
-## Array: Fixed length collection
+x := String with: $a with: $b with: $c with: $d. "set up to 4 elements at a time"
+x do: [:a | Transcript show: a printString; cr]. "iterate over the string"
+b := x conform: [:a | (a >= $a) & (a <= $z)]. "test if all elements meet condition"
+y := x select: [:a | a > $a]. "return all elements that meet condition"
+y := x asSymbol. "convert string to symbol"
+y := x asArray. "convert string to array"
+x := 'ABCD' asByteArray. "convert string to byte array"
+y := x asOrderedCollection. "convert string to ordered collection"
+y := x asSortedCollection. "convert string to sorted collection"
+y := x asBag. "convert string to bag collection"
+y := x asSet. "convert string to set collection"
+y := x shuffled. "randomly shuffle string"
+```
+
+#### Array:
+Fixed length collection
- ByteArray: Array limited to byte elements (0-255)
- WordArray: Array limited to word elements (0-2^32)
-```
+```smalltalk
| b x y sum max |
-x := #(4 3 2 1). "constant array"
-x := Array with: 5 with: 4 with: 3 with: 2. "create array with up to 4 elements"
-x := Array new: 4. "allocate an array with specified size"
-x "set array elements"
+x := #(4 3 2 1). "constant array"
+x := Array with: 5 with: 4 with: 3 with: 2. "create array with up to 4 elements"
+x := Array new: 4. "allocate an array with specified size"
+x "set array elements"
at: 1 put: 5;
at: 2 put: 4;
at: 3 put: 3;
at: 4 put: 2.
-b := x isEmpty. "test if array is empty"
-y := x size. "array size"
-y := x at: 4. "get array element at index"
-b := x includes: 3. "test if element is in array"
-y := x copyFrom: 2 to: 4. "subarray"
-y := x indexOf: 3 ifAbsent: [0]. "first position of element within array"
-y := x occurrencesOf: 3. "number of times object in collection"
-x do: [:a | Transcript show: a printString; cr]. "iterate over the array"
-b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
-y := x select: [:a | a > 2]. "return collection of elements that pass test"
-y := x reject: [:a | a < 2]. "return collection of elements that fail test"
-y := x collect: [:a | a + a]. "transform each element for new collection"
-y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
-sum := 0. x do: [:a | sum := sum + a]. sum. "sum array elements"
-sum := 0. 1 to: (x size) do: [:a | sum := sum + (x at: a)]. "sum array elements"
-sum := x inject: 0 into: [:a :c | a + c]. "sum array elements"
-max := x inject: 0 into: [:a :c | (a > c) "find max element in array"
+b := x isEmpty. "test if array is empty"
+y := x size. "array size"
+y := x at: 4. "get array element at index"
+b := x includes: 3. "test if element is in array"
+y := x copyFrom: 2 to: 4. "subarray"
+y := x indexOf: 3 ifAbsent: [0]. "first position of element within array"
+y := x occurrencesOf: 3. "number of times object in collection"
+x do: [:a | Transcript show: a printString; cr]. "iterate over the array"
+b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
+y := x select: [:a | a > 2]. "return collection of elements that pass test"
+y := x reject: [:a | a < 2]. "return collection of elements that fail test"
+y := x collect: [:a | a + a]. "transform each element for new collection"
+y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
+sum := 0. x do: [:a | sum := sum + a]. sum. "sum array elements"
+sum := 0. 1 to: (x size)
+ do: [:a | sum := sum + (x at: a)]. "sum array elements"
+sum := x inject: 0 into: [:a :c | a + c]. "sum array elements"
+max := x inject: 0 into: [:a :c | (a > c) "find max element in array"
ifTrue: [a]
ifFalse: [c]].
-y := x shuffled. "randomly shuffle collection"
-y := x asArray. "convert to array"
-"y := x asByteArray." "note: this instruction not available on Squeak"
-y := x asWordArray. "convert to word array"
-y := x asOrderedCollection. "convert to ordered collection"
-y := x asSortedCollection. "convert to sorted collection"
-y := x asBag. "convert to bag collection"
-y := x asSet. "convert to set collection"
+y := x shuffled. "randomly shuffle collection"
+y := x asArray. "convert to array"
+"y := x asByteArray." "note: this instruction not available on Squeak"
+y := x asWordArray. "convert to word array"
+y := x asOrderedCollection. "convert to ordered collection"
+y := x asSortedCollection. "convert to sorted collection"
+y := x asBag. "convert to bag collection"
+y := x asSet. "convert to set collection"
```
-##OrderedCollection: acts like an expandable array
-```
+#### OrderedCollection:
+acts like an expandable array
+
+```smalltalk
| b x y sum max |
-x := OrderedCollection with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
-x := OrderedCollection new. "allocate collection"
-x add: 3; add: 2; add: 1; add: 4; yourself. "add element to collection"
-y := x addFirst: 5. "add element at beginning of collection"
-y := x removeFirst. "remove first element in collection"
-y := x addLast: 6. "add element at end of collection"
-y := x removeLast. "remove last element in collection"
-y := x addAll: #(7 8 9). "add multiple elements to collection"
-y := x removeAll: #(7 8 9). "remove multiple elements from collection"
-x at: 2 put: 3. "set element at index"
-y := x remove: 5 ifAbsent: []. "remove element from collection"
-b := x isEmpty. "test if empty"
-y := x size. "number of elements"
-y := x at: 2. "retrieve element at index"
-y := x first. "retrieve first element in collection"
-y := x last. "retrieve last element in collection"
-b := x includes: 5. "test if element is in collection"
-y := x copyFrom: 2 to: 3. "subcollection"
-y := x indexOf: 3 ifAbsent: [0]. "first position of element within collection"
-y := x occurrencesOf: 3. "number of times object in collection"
-x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
-b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
-y := x select: [:a | a > 2]. "return collection of elements that pass test"
-y := x reject: [:a | a < 2]. "return collection of elements that fail test"
-y := x collect: [:a | a + a]. "transform each element for new collection"
-y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
-sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
-sum := 0. 1 to: (x size) do: [:a | sum := sum + (x at: a)]. "sum elements"
-sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
-max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
+x := OrderedCollection
+ with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
+x := OrderedCollection new. "allocate collection"
+x add: 3; add: 2; add: 1; add: 4; yourself. "add element to collection"
+y := x addFirst: 5. "add element at beginning of collection"
+y := x removeFirst. "remove first element in collection"
+y := x addLast: 6. "add element at end of collection"
+y := x removeLast. "remove last element in collection"
+y := x addAll: #(7 8 9). "add multiple elements to collection"
+y := x removeAll: #(7 8 9). "remove multiple elements from collection"
+x at: 2 put: 3. "set element at index"
+y := x remove: 5 ifAbsent: []. "remove element from collection"
+b := x isEmpty. "test if empty"
+y := x size. "number of elements"
+y := x at: 2. "retrieve element at index"
+y := x first. "retrieve first element in collection"
+y := x last. "retrieve last element in collection"
+b := x includes: 5. "test if element is in collection"
+y := x copyFrom: 2 to: 3. "subcollection"
+y := x indexOf: 3 ifAbsent: [0]. "first position of element within collection"
+y := x occurrencesOf: 3. "number of times object in collection"
+x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
+b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
+y := x select: [:a | a > 2]. "return collection of elements that pass test"
+y := x reject: [:a | a < 2]. "return collection of elements that fail test"
+y := x collect: [:a | a + a]. "transform each element for new collection"
+y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
+sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
+sum := 0. 1 to: (x size)
+ do: [:a | sum := sum + (x at: a)]. "sum elements"
+sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
+max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
ifTrue: [a]
ifFalse: [c]].
-y := x shuffled. "randomly shuffle collection"
-y := x asArray. "convert to array"
-y := x asOrderedCollection. "convert to ordered collection"
-y := x asSortedCollection. "convert to sorted collection"
-y := x asBag. "convert to bag collection"
-y := x asSet. "convert to set collection"
+y := x shuffled. "randomly shuffle collection"
+y := x asArray. "convert to array"
+y := x asOrderedCollection. "convert to ordered collection"
+y := x asSortedCollection. "convert to sorted collection"
+y := x asBag. "convert to bag collection"
+y := x asSet. "convert to set collection"
```
-## SortedCollection: like OrderedCollection except order of elements determined by sorting criteria
-```
+#### SortedCollection:
+like OrderedCollection except order of elements determined by sorting criteria
+
+```smalltalk
| b x y sum max |
-x := SortedCollection with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
-x := SortedCollection new. "allocate collection"
-x := SortedCollection sortBlock: [:a :c | a > c]. "set sort criteria"
-x add: 3; add: 2; add: 1; add: 4; yourself. "add element to collection"
-y := x addFirst: 5. "add element at beginning of collection"
-y := x removeFirst. "remove first element in collection"
-y := x addLast: 6. "add element at end of collection"
-y := x removeLast. "remove last element in collection"
-y := x addAll: #(7 8 9). "add multiple elements to collection"
-y := x removeAll: #(7 8 9). "remove multiple elements from collection"
-y := x remove: 5 ifAbsent: []. "remove element from collection"
-b := x isEmpty. "test if empty"
-y := x size. "number of elements"
-y := x at: 2. "retrieve element at index"
-y := x first. "retrieve first element in collection"
-y := x last. "retrieve last element in collection"
-b := x includes: 4. "test if element is in collection"
-y := x copyFrom: 2 to: 3. "subcollection"
-y := x indexOf: 3 ifAbsent: [0]. "first position of element within collection"
-y := x occurrencesOf: 3. "number of times object in collection"
-x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
-b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
-y := x select: [:a | a > 2]. "return collection of elements that pass test"
-y := x reject: [:a | a < 2]. "return collection of elements that fail test"
-y := x collect: [:a | a + a]. "transform each element for new collection"
-y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
-sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
-sum := 0. 1 to: (x size) do: [:a | sum := sum + (x at: a)]. "sum elements"
-sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
-max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
+x := SortedCollection
+ with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
+x := SortedCollection new. "allocate collection"
+x := SortedCollection sortBlock: [:a :c | a > c]. "set sort criteria"
+x add: 3; add: 2; add: 1; add: 4; yourself. "add element to collection"
+y := x addFirst: 5. "add element at beginning of collection"
+y := x removeFirst. "remove first element in collection"
+y := x addLast: 6. "add element at end of collection"
+y := x removeLast. "remove last element in collection"
+y := x addAll: #(7 8 9). "add multiple elements to collection"
+y := x removeAll: #(7 8 9). "remove multiple elements from collection"
+y := x remove: 5 ifAbsent: []. "remove element from collection"
+b := x isEmpty. "test if empty"
+y := x size. "number of elements"
+y := x at: 2. "retrieve element at index"
+y := x first. "retrieve first element in collection"
+y := x last. "retrieve last element in collection"
+b := x includes: 4. "test if element is in collection"
+y := x copyFrom: 2 to: 3. "subcollection"
+y := x indexOf: 3 ifAbsent: [0]. "first position of element within collection"
+y := x occurrencesOf: 3. "number of times object in collection"
+x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
+b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
+y := x select: [:a | a > 2]. "return collection of elements that pass test"
+y := x reject: [:a | a < 2]. "return collection of elements that fail test"
+y := x collect: [:a | a + a]. "transform each element for new collection"
+y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
+sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
+sum := 0. 1 to: (x size)
+ do: [:a | sum := sum + (x at: a)]. "sum elements"
+sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
+max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
ifTrue: [a]
ifFalse: [c]].
-y := x asArray. "convert to array"
-y := x asOrderedCollection. "convert to ordered collection"
-y := x asSortedCollection. "convert to sorted collection"
-y := x asBag. "convert to bag collection"
-y := x asSet. "convert to set collection"
+y := x asArray. "convert to array"
+y := x asOrderedCollection. "convert to ordered collection"
+y := x asSortedCollection. "convert to sorted collection"
+y := x asBag. "convert to bag collection"
+y := x asSet. "convert to set collection"
```
-## Bag: like OrderedCollection except elements are in no particular order
-```
+#### Bag:
+like OrderedCollection except elements are in no particular order
+
+```smalltalk
| b x y sum max |
-x := Bag with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
-x := Bag new. "allocate collection"
-x add: 4; add: 3; add: 1; add: 2; yourself. "add element to collection"
-x add: 3 withOccurrences: 2. "add multiple copies to collection"
-y := x addAll: #(7 8 9). "add multiple elements to collection"
-y := x removeAll: #(7 8 9). "remove multiple elements from collection"
-y := x remove: 4 ifAbsent: []. "remove element from collection"
-b := x isEmpty. "test if empty"
-y := x size. "number of elements"
-b := x includes: 3. "test if element is in collection"
-y := x occurrencesOf: 3. "number of times object in collection"
-x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
-b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
-y := x select: [:a | a > 2]. "return collection of elements that pass test"
-y := x reject: [:a | a < 2]. "return collection of elements that fail test"
-y := x collect: [:a | a + a]. "transform each element for new collection"
-y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
-sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
-sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
-max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
+x := Bag with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
+x := Bag new. "allocate collection"
+x add: 4; add: 3; add: 1; add: 2; yourself. "add element to collection"
+x add: 3 withOccurrences: 2. "add multiple copies to collection"
+y := x addAll: #(7 8 9). "add multiple elements to collection"
+y := x removeAll: #(7 8 9). "remove multiple elements from collection"
+y := x remove: 4 ifAbsent: []. "remove element from collection"
+b := x isEmpty. "test if empty"
+y := x size. "number of elements"
+b := x includes: 3. "test if element is in collection"
+y := x occurrencesOf: 3. "number of times object in collection"
+x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
+b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
+y := x select: [:a | a > 2]. "return collection of elements that pass test"
+y := x reject: [:a | a < 2]. "return collection of elements that fail test"
+y := x collect: [:a | a + a]. "transform each element for new collection"
+y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
+sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
+sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
+max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
ifTrue: [a]
ifFalse: [c]].
-y := x asOrderedCollection. "convert to ordered collection"
-y := x asSortedCollection. "convert to sorted collection"
-y := x asBag. "convert to bag collection"
-y := x asSet. "convert to set collection"
+y := x asOrderedCollection. "convert to ordered collection"
+y := x asSortedCollection. "convert to sorted collection"
+y := x asBag. "convert to bag collection"
+y := x asSet. "convert to set collection"
```
-## Set: like Bag except duplicates not allowed
-## IdentitySet: uses identity test (== rather than =)
-```
+#### Set:
+like Bag except duplicates not allowed
+
+#### IdentitySet:
+uses identity test (== rather than =)
+
+```smalltalk
| b x y sum max |
-x := Set with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
-x := Set new. "allocate collection"
-x add: 4; add: 3; add: 1; add: 2; yourself. "add element to collection"
-y := x addAll: #(7 8 9). "add multiple elements to collection"
-y := x removeAll: #(7 8 9). "remove multiple elements from collection"
-y := x remove: 4 ifAbsent: []. "remove element from collection"
-b := x isEmpty. "test if empty"
-y := x size. "number of elements"
-x includes: 4. "test if element is in collection"
-x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
-b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
-y := x select: [:a | a > 2]. "return collection of elements that pass test"
-y := x reject: [:a | a < 2]. "return collection of elements that fail test"
-y := x collect: [:a | a + a]. "transform each element for new collection"
-y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
-sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
-sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
-max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
+x := Set with: 4 with: 3 with: 2 with: 1. "create collection with up to 4 elements"
+x := Set new. "allocate collection"
+x add: 4; add: 3; add: 1; add: 2; yourself. "add element to collection"
+y := x addAll: #(7 8 9). "add multiple elements to collection"
+y := x removeAll: #(7 8 9). "remove multiple elements from collection"
+y := x remove: 4 ifAbsent: []. "remove element from collection"
+b := x isEmpty. "test if empty"
+y := x size. "number of elements"
+x includes: 4. "test if element is in collection"
+x do: [:a | Transcript show: a printString; cr]. "iterate over the collection"
+b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
+y := x select: [:a | a > 2]. "return collection of elements that pass test"
+y := x reject: [:a | a < 2]. "return collection of elements that fail test"
+y := x collect: [:a | a + a]. "transform each element for new collection"
+y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
+sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
+sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
+max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
ifTrue: [a]
ifFalse: [c]].
-y := x asArray. "convert to array"
-y := x asOrderedCollection. "convert to ordered collection"
-y := x asSortedCollection. "convert to sorted collection"
-y := x asBag. "convert to bag collection"
-y := x asSet. "convert to set collection"
+y := x asArray. "convert to array"
+y := x asOrderedCollection. "convert to ordered collection"
+y := x asSortedCollection. "convert to sorted collection"
+y := x asBag. "convert to bag collection"
+y := x asSet. "convert to set collection"
```
-## Interval:
-```
+#### Interval:
+```smalltalk
| b x y sum max |
-x := Interval from: 5 to: 10. "create interval object"
+x := Interval from: 5 to: 10. "create interval object"
x := 5 to: 10.
-x := Interval from: 5 to: 10 by: 2. "create interval object with specified increment"
+x := Interval from: 5 to: 10 by: 2. "create interval object with specified increment"
x := 5 to: 10 by: 2.
-b := x isEmpty. "test if empty"
-y := x size. "number of elements"
-x includes: 9. "test if element is in collection"
-x do: [:k | Transcript show: k printString; cr]. "iterate over interval"
-b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
-y := x select: [:a | a > 7]. "return collection of elements that pass test"
-y := x reject: [:a | a < 2]. "return collection of elements that fail test"
-y := x collect: [:a | a + a]. "transform each element for new collection"
-y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
-sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
-sum := 0. 1 to: (x size) do: [:a | sum := sum + (x at: a)]. "sum elements"
-sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
-max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
+b := x isEmpty. "test if empty"
+y := x size. "number of elements"
+x includes: 9. "test if element is in collection"
+x do: [:k | Transcript show: k printString; cr]. "iterate over interval"
+b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
+y := x select: [:a | a > 7]. "return collection of elements that pass test"
+y := x reject: [:a | a < 2]. "return collection of elements that fail test"
+y := x collect: [:a | a + a]. "transform each element for new collection"
+y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
+sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
+sum := 0. 1 to: (x size)
+ do: [:a | sum := sum + (x at: a)]. "sum elements"
+sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
+max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
ifTrue: [a]
ifFalse: [c]].
-y := x asArray. "convert to array"
-y := x asOrderedCollection. "convert to ordered collection"
-y := x asSortedCollection. "convert to sorted collection"
-y := x asBag. "convert to bag collection"
-y := x asSet. "convert to set collection"
+y := x asArray. "convert to array"
+y := x asOrderedCollection. "convert to ordered collection"
+y := x asSortedCollection. "convert to sorted collection"
+y := x asBag. "convert to bag collection"
+y := x asSet. "convert to set collection"
```
-##Associations:
-```
+#### Associations:
+```smalltalk
| x y |
x := #myVar->'hello'.
y := x key.
y := x value.
```
-## Dictionary:
-## IdentityDictionary: uses identity test (== rather than =)
-```
+#### Dictionary:
+#### IdentityDictionary:
+uses identity test (== rather than =)
+
+```smalltalk
| b x y |
-x := Dictionary new. "allocate collection"
-x add: #a->4; add: #b->3; add: #c->1; add: #d->2; yourself. "add element to collection"
-x at: #e put: 3. "set element at index"
-b := x isEmpty. "test if empty"
-y := x size. "number of elements"
-y := x at: #a ifAbsent: []. "retrieve element at index"
-y := x keyAtValue: 3 ifAbsent: []. "retrieve key for given value with error block"
-y := x removeKey: #e ifAbsent: []. "remove element from collection"
-b := x includes: 3. "test if element is in values collection"
-b := x includesKey: #a. "test if element is in keys collection"
-y := x occurrencesOf: 3. "number of times object in collection"
-y := x keys. "set of keys"
-y := x values. "bag of values"
+x := Dictionary new. "allocate collection"
+x add: #a->4;
+ add: #b->3;
+ add: #c->1;
+ add: #d->2; yourself. "add element to collection"
+x at: #e put: 3. "set element at index"
+b := x isEmpty. "test if empty"
+y := x size. "number of elements"
+y := x at: #a ifAbsent: []. "retrieve element at index"
+y := x keyAtValue: 3 ifAbsent: []. "retrieve key for given value with error block"
+y := x removeKey: #e ifAbsent: []. "remove element from collection"
+b := x includes: 3. "test if element is in values collection"
+b := x includesKey: #a. "test if element is in keys collection"
+y := x occurrencesOf: 3. "number of times object in collection"
+y := x keys. "set of keys"
+y := x values. "bag of values"
x do: [:a | Transcript show: a printString; cr]. "iterate over the values collection"
x keysDo: [:a | Transcript show: a printString; cr]. "iterate over the keys collection"
x associationsDo: [:a | Transcript show: a printString; cr]."iterate over the associations"
x keysAndValuesDo: [:aKey :aValue | Transcript "iterate over keys and values"
show: aKey printString; space;
show: aValue printString; cr].
-b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
-y := x select: [:a | a > 2]. "return collection of elements that pass test"
-y := x reject: [:a | a < 2]. "return collection of elements that fail test"
-y := x collect: [:a | a + a]. "transform each element for new collection"
-y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
-sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
-sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
-max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
+b := x conform: [:a | (a >= 1) & (a <= 4)]. "test if all elements meet condition"
+y := x select: [:a | a > 2]. "return collection of elements that pass test"
+y := x reject: [:a | a < 2]. "return collection of elements that fail test"
+y := x collect: [:a | a + a]. "transform each element for new collection"
+y := x detect: [:a | a > 3] ifNone: []. "find position of first element that passes test"
+sum := 0. x do: [:a | sum := sum + a]. sum. "sum elements"
+sum := x inject: 0 into: [:a :c | a + c]. "sum elements"
+max := x inject: 0 into: [:a :c | (a > c) "find max element in collection"
ifTrue: [a]
ifFalse: [c]].
-y := x asArray. "convert to array"
-y := x asOrderedCollection. "convert to ordered collection"
-y := x asSortedCollection. "convert to sorted collection"
-y := x asBag. "convert to bag collection"
-y := x asSet. "convert to set collection"
-
-Smalltalk at: #CMRGlobal put: 'CMR entry'. "put global in Smalltalk Dictionary"
-x := Smalltalk at: #CMRGlobal. "read global from Smalltalk Dictionary"
-Transcript show: (CMRGlobal printString). "entries are directly accessible by name"
-Smalltalk keys do: [ :k | "print out all classes"
+y := x asArray. "convert to array"
+y := x asOrderedCollection. "convert to ordered collection"
+y := x asSortedCollection. "convert to sorted collection"
+y := x asBag. "convert to bag collection"
+y := x asSet. "convert to set collection"
+
+Smalltalk at: #CMRGlobal put: 'CMR entry'. "put global in Smalltalk Dictionary"
+x := Smalltalk at: #CMRGlobal. "read global from Smalltalk Dictionary"
+Transcript show: (CMRGlobal printString). "entries are directly accessible by name"
+Smalltalk keys do: [ :k | "print out all classes"
((Smalltalk at: k) isKindOf: Class)
ifFalse: [Transcript show: k printString; cr]].
-Smalltalk at: #CMRDictionary put: (Dictionary new). "set up user defined dictionary"
-CMRDictionary at: #MyVar1 put: 'hello1'. "put entry in dictionary"
-CMRDictionary add: #MyVar2->'hello2'. "add entry to dictionary use key->value combo"
-CMRDictionary size. "dictionary size"
-CMRDictionary keys do: [ :k | "print out keys in dictionary"
+Smalltalk at: #CMRDictionary put: (Dictionary new). "set up user defined dictionary"
+CMRDictionary at: #MyVar1 put: 'hello1'. "put entry in dictionary"
+CMRDictionary add: #MyVar2->'hello2'. "add entry to dictionary use key->value combo"
+CMRDictionary size. "dictionary size"
+CMRDictionary keys do: [ :k | "print out keys in dictionary"
Transcript show: k printString; cr].
-CMRDictionary values do: [ :k | "print out values in dictionary"
+CMRDictionary values do: [ :k | "print out values in dictionary"
Transcript show: k printString; cr].
-CMRDictionary keysAndValuesDo: [:aKey :aValue | "print out keys and values"
+CMRDictionary keysAndValuesDo: [:aKey :aValue | "print out keys and values"
Transcript
show: aKey printString;
space;
show: aValue printString;
cr].
-CMRDictionary associationsDo: [:aKeyValue | "another iterator for printing key values"
+CMRDictionary associationsDo: [:aKeyValue | "another iterator for printing key values"
Transcript show: aKeyValue printString; cr].
-Smalltalk removeKey: #CMRGlobal ifAbsent: []. "remove entry from Smalltalk dictionary"
-Smalltalk removeKey: #CMRDictionary ifAbsent: []. "remove user dictionary from Smalltalk dictionary"
+Smalltalk removeKey: #CMRGlobal ifAbsent: []. "remove entry from Smalltalk dictionary"
+Smalltalk removeKey: #CMRDictionary ifAbsent: []. "remove user dictionary from Smalltalk dictionary"
```
-## Internal Stream:
-```
+#### Internal Stream:
+```smalltalk
| b x ios |
ios := ReadStream on: 'Hello read stream'.
ios := ReadStream on: 'Hello read stream' from: 1 to: 5.
-[(x := ios nextLine) notNil]
- whileTrue: [Transcript show: x; cr].
+[(x := ios nextLine) notNil] whileTrue: [Transcript show: x; cr].
ios position: 3.
ios position.
x := ios next.
@@ -695,8 +768,7 @@ ios := ReadWriteStream on: 'Hello read stream' from: 1 to: 5.
ios := ReadWriteStream with: 'Hello read stream'.
ios := ReadWriteStream with: 'Hello read stream' from: 1 to: 10.
ios position: 0.
-[(x := ios nextLine) notNil]
- whileTrue: [Transcript show: x; cr].
+[(x := ios nextLine) notNil] whileTrue: [Transcript show: x; cr].
ios position: 6.
ios position.
ios nextPutAll: 'Chris'.
@@ -706,8 +778,8 @@ x := ios contents.
b := ios atEnd.
```
-## FileStream:
-```
+#### FileStream:
+```smalltalk
| b x ios |
ios := FileStream newFileNamed: 'ios.txt'.
ios nextPut: $H; cr.
@@ -717,8 +789,7 @@ ios nextPutAll: 'Hello File'; cr.
ios close.
ios := FileStream oldFileNamed: 'ios.txt'.
-[(x := ios nextLine) notNil]
- whileTrue: [Transcript show: x; cr].
+[(x := ios nextLine) notNil] whileTrue: [Transcript show: x; cr].
ios position: 3.
x := ios position.
x := ios next.
@@ -727,120 +798,122 @@ b := ios atEnd.
ios close.
```
-## Date:
-```
+#### Date:
+```smalltalk
| x y |
-x := Date today. "create date for today"
-x := Date dateAndTimeNow. "create date from current time/date"
-x := Date readFromString: '01/02/1999'. "create date from formatted string"
-x := Date newDay: 12 month: #July year: 1999 "create date from parts"
-x := Date fromDays: 36000. "create date from elapsed days since 1/1/1901"
-y := Date dayOfWeek: #Monday. "day of week as int (1-7)"
-y := Date indexOfMonth: #January. "month of year as int (1-12)"
-y := Date daysInMonth: 2 forYear: 1996. "day of month as int (1-31)"
-y := Date daysInYear: 1996. "days in year (365|366)"
-y := Date nameOfDay: 1 "weekday name (#Monday,...)"
-y := Date nameOfMonth: 1. "month name (#January,...)"
-y := Date leapYear: 1996. "1 if leap year; 0 if not leap year"
-y := x weekday. "day of week (#Monday,...)"
-y := x previous: #Monday. "date for previous day of week"
-y := x dayOfMonth. "day of month (1-31)"
-y := x day. "day of year (1-366)"
-y := x firstDayOfMonth. "day of year for first day of month"
-y := x monthName. "month of year (#January,...)"
-y := x monthIndex. "month of year (1-12)"
-y := x daysInMonth. "days in month (1-31)"
-y := x year. "year (19xx)"
-y := x daysInYear. "days in year (365|366)"
-y := x daysLeftInYear. "days left in year (364|365)"
-y := x asSeconds. "seconds elapsed since 1/1/1901"
-y := x addDays: 10. "add days to date object"
-y := x subtractDays: 10. "subtract days to date object"
-y := x subtractDate: (Date today). "subtract date (result in days)"
-y := x printFormat: #(2 1 3 $/ 1 1). "print formatted date"
-b := (x <= Date today). "comparison"
-```
-
-## Time:
+x := Date today. "create date for today"
+x := Date dateAndTimeNow. "create date from current time/date"
+x := Date readFromString: '01/02/1999'. "create date from formatted string"
+x := Date newDay: 12 month: #July year: 1999 "create date from parts"
+x := Date fromDays: 36000. "create date from elapsed days since 1/1/1901"
+y := Date dayOfWeek: #Monday. "day of week as int (1-7)"
+y := Date indexOfMonth: #January. "month of year as int (1-12)"
+y := Date daysInMonth: 2 forYear: 1996. "day of month as int (1-31)"
+y := Date daysInYear: 1996. "days in year (365|366)"
+y := Date nameOfDay: 1 "weekday name (#Monday,...)"
+y := Date nameOfMonth: 1. "month name (#January,...)"
+y := Date leapYear: 1996. "1 if leap year; 0 if not leap year"
+y := x weekday. "day of week (#Monday,...)"
+y := x previous: #Monday. "date for previous day of week"
+y := x dayOfMonth. "day of month (1-31)"
+y := x day. "day of year (1-366)"
+y := x firstDayOfMonth. "day of year for first day of month"
+y := x monthName. "month of year (#January,...)"
+y := x monthIndex. "month of year (1-12)"
+y := x daysInMonth. "days in month (1-31)"
+y := x year. "year (19xx)"
+y := x daysInYear. "days in year (365|366)"
+y := x daysLeftInYear. "days left in year (364|365)"
+y := x asSeconds. "seconds elapsed since 1/1/1901"
+y := x addDays: 10. "add days to date object"
+y := x subtractDays: 10. "subtract days to date object"
+y := x subtractDate: (Date today). "subtract date (result in days)"
+y := x printFormat: #(2 1 3 $/ 1 1). "print formatted date"
+b := (x <= Date today). "comparison"
```
+
+#### Time:
+```smalltalk
| x y |
-x := Time now. "create time from current time"
-x := Time dateAndTimeNow. "create time from current time/date"
-x := Time readFromString: '3:47:26 pm'. "create time from formatted string"
-x := Time fromSeconds: (60 * 60 * 4). "create time from elapsed time from midnight"
-y := Time millisecondClockValue. "milliseconds since midnight"
-y := Time totalSeconds. "total seconds since 1/1/1901"
-y := x seconds. "seconds past minute (0-59)"
-y := x minutes. "minutes past hour (0-59)"
-y := x hours. "hours past midnight (0-23)"
-y := x addTime: (Time now). "add time to time object"
-y := x subtractTime: (Time now). "subtract time to time object"
-y := x asSeconds. "convert time to seconds"
-x := Time millisecondsToRun: [ "timing facility"
+x := Time now. "create time from current time"
+x := Time dateAndTimeNow. "create time from current time/date"
+x := Time readFromString: '3:47:26 pm'. "create time from formatted string"
+x := Time fromSeconds: (60 * 60 * 4). "create time from elapsed time from midnight"
+y := Time millisecondClockValue. "milliseconds since midnight"
+y := Time totalSeconds. "total seconds since 1/1/1901"
+y := x seconds. "seconds past minute (0-59)"
+y := x minutes. "minutes past hour (0-59)"
+y := x hours. "hours past midnight (0-23)"
+y := x addTime: (Time now). "add time to time object"
+y := x subtractTime: (Time now). "subtract time to time object"
+y := x asSeconds. "convert time to seconds"
+x := Time millisecondsToRun: [ "timing facility"
1 to: 1000 do: [:index | y := 3.14 * index]].
-b := (x <= Time now). "comparison"
+b := (x <= Time now). "comparison"
```
-## Point:
-```
+#### Point:
+```smalltalk
| x y |
-x := 200@100. "obtain a new point"
-y := x x. "x coordinate"
-y := x y. "y coordinate"
-x := 200@100 negated. "negates x and y"
-x := (-200@-100) abs. "absolute value of x and y"
-x := (200.5@100.5) rounded. "round x and y"
-x := (200.5@100.5) truncated. "truncate x and y"
-x := 200@100 + 100. "add scale to both x and y"
-x := 200@100 - 100. "subtract scale from both x and y"
-x := 200@100 * 2. "multiply x and y by scale"
-x := 200@100 / 2. "divide x and y by scale"
-x := 200@100 // 2. "divide x and y by scale"
-x := 200@100 \\ 3. "remainder of x and y by scale"
-x := 200@100 + 50@25. "add points"
-x := 200@100 - 50@25. "subtract points"
-x := 200@100 * 3@4. "multiply points"
-x := 200@100 // 3@4. "divide points"
-x := 200@100 max: 50@200. "max x and y"
-x := 200@100 min: 50@200. "min x and y"
-x := 20@5 dotProduct: 10@2. "sum of product (x1*x2 + y1*y2)"
-```
-
-## Rectangle:
+x := 200@100. "obtain a new point"
+y := x x. "x coordinate"
+y := x y. "y coordinate"
+x := 200@100 negated. "negates x and y"
+x := (-200@-100) abs. "absolute value of x and y"
+x := (200.5@100.5) rounded. "round x and y"
+x := (200.5@100.5) truncated. "truncate x and y"
+x := 200@100 + 100. "add scale to both x and y"
+x := 200@100 - 100. "subtract scale from both x and y"
+x := 200@100 * 2. "multiply x and y by scale"
+x := 200@100 / 2. "divide x and y by scale"
+x := 200@100 // 2. "divide x and y by scale"
+x := 200@100 \\ 3. "remainder of x and y by scale"
+x := 200@100 + 50@25. "add points"
+x := 200@100 - 50@25. "subtract points"
+x := 200@100 * 3@4. "multiply points"
+x := 200@100 // 3@4. "divide points"
+x := 200@100 max: 50@200. "max x and y"
+x := 200@100 min: 50@200. "min x and y"
+x := 20@5 dotProduct: 10@2. "sum of product (x1*x2 + y1*y2)"
```
+
+#### Rectangle:
+```smalltalk
Rectangle fromUser.
```
-## Pen:
-```
+#### Pen:
+```smalltalk
| myPen |
Display restoreAfter: [
Display fillWhite.
-myPen := Pen new. "get graphic pen"
+myPen := Pen new. "get graphic pen"
myPen squareNib: 1.
-myPen color: (Color blue). "set pen color"
-myPen home. "position pen at center of display"
-myPen up. "makes nib unable to draw"
-myPen down. "enable the nib to draw"
-myPen north. "points direction towards top"
-myPen turn: -180. "add specified degrees to direction"
-myPen direction. "get current angle of pen"
-myPen go: 50. "move pen specified number of pixels"
-myPen location. "get the pen position"
-myPen goto: 200@200. "move to specified point"
-myPen place: 250@250. "move to specified point without drawing"
-myPen print: 'Hello World' withFont: (TextStyle default fontAt: 1).
-Display extent. "get display width@height"
-Display width. "get display width"
-Display height. "get display height"
+myPen color: (Color blue). "set pen color"
+myPen home. "position pen at center of display"
+myPen up. "makes nib unable to draw"
+myPen down. "enable the nib to draw"
+myPen north. "points direction towards top"
+myPen turn: -180. "add specified degrees to direction"
+myPen direction. "get current angle of pen"
+myPen go: 50. "move pen specified number of pixels"
+myPen location. "get the pen position"
+myPen goto: 200@200. "move to specified point"
+myPen place: 250@250. "move to specified point without drawing"
+myPen print: 'Hello World'
+ withFont: (TextStyle default fontAt: 1).
+Display extent. "get display width@height"
+Display width. "get display width"
+Display height. "get display height"
].
```
-## Dynamic Message Calling/Compiling:
-```
+#### Dynamic Message Calling/Compiling:
+```smalltalk
| receiver message result argument keyword1 keyword2 argument1 argument2 |
+
"unary message"
receiver := 5.
message := 'factorial' asSymbol.
@@ -862,11 +935,14 @@ keyword1 := 'between:' asSymbol.
keyword2 := 'and:' asSymbol.
argument1 := 10.
argument2 := 20.
+
result := receiver
perform: (keyword1, keyword2) asSymbol
withArguments: (Array with: argument1 with: argument2).
+
result := Compiler evaluate:
((receiver storeString), ' ', keyword1, (argument1 storeString) , ' ', keyword2, (argument2 storeString)).
+
result := (Message
new
setSelector: (keyword1, keyword2) asSymbol
@@ -874,83 +950,94 @@ result := (Message
sentTo: receiver.
```
-## Class/Meta-class:
-```
+#### Class/Meta-Class:
+```smalltalk
| b x |
-x := String name. "class name"
-x := String category. "organization category"
-x := String comment. "class comment"
-x := String kindOfSubclass. "subclass type - subclass: variableSubclass, etc"
-x := String definition. "class definition"
-x := String instVarNames. "immediate instance variable names"
-x := String allInstVarNames. "accumulated instance variable names"
-x := String classVarNames. "immediate class variable names"
-x := String allClassVarNames. "accumulated class variable names"
-x := String sharedPools. "immediate dictionaries used as shared pools"
-x := String allSharedPools. "accumulated dictionaries used as shared pools"
-x := String selectors. "message selectors for class"
-x := String sourceCodeAt: #size. "source code for specified method"
-x := String allInstances. "collection of all instances of class"
-x := String superclass. "immediate superclass"
-x := String allSuperclasses. "accumulated superclasses"
-x := String withAllSuperclasses. "receiver class and accumulated superclasses"
-x := String subclasses. "immediate subclasses"
-x := String allSubclasses. "accumulated subclasses"
-x := String withAllSubclasses. "receiver class and accumulated subclasses"
-b := String instSize. "number of named instance variables"
-b := String isFixed. "true if no indexed instance variables"
-b := String isVariable. "true if has indexed instance variables"
-b := String isPointers. "true if index instance vars contain objects"
-b := String isBits. "true if index instance vars contain bytes/words"
-b := String isBytes. "true if index instance vars contain bytes"
-b := String isWords. true if index instance vars contain words"
-Object withAllSubclasses size. "get total number of class entries"
-```
-
-## Debuging:
+x := String name. "class name"
+x := String category. "organization category"
+x := String comment. "class comment"
+x := String kindOfSubclass. "subclass type - subclass: variableSubclass, etc"
+x := String definition. "class definition"
+x := String instVarNames. "immediate instance variable names"
+x := String allInstVarNames. "accumulated instance variable names"
+x := String classVarNames. "immediate class variable names"
+x := String allClassVarNames. "accumulated class variable names"
+x := String sharedPools. "immediate dictionaries used as shared pools"
+x := String allSharedPools. "accumulated dictionaries used as shared pools"
+x := String selectors. "message selectors for class"
+x := String sourceCodeAt: #size. "source code for specified method"
+x := String allInstances. "collection of all instances of class"
+x := String superclass. "immediate superclass"
+x := String allSuperclasses. "accumulated superclasses"
+x := String withAllSuperclasses. "receiver class and accumulated superclasses"
+x := String subclasses. "immediate subclasses"
+x := String allSubclasses. "accumulated subclasses"
+x := String withAllSubclasses. "receiver class and accumulated subclasses"
+b := String instSize. "number of named instance variables"
+b := String isFixed. "true if no indexed instance variables"
+b := String isVariable. "true if has indexed instance variables"
+b := String isPointers. "true if index instance vars contain objects"
+b := String isBits. "true if index instance vars contain bytes/words"
+b := String isBytes. "true if index instance vars contain bytes"
+b := String isWords. "true if index instance vars contain words"
+Object withAllSubclasses size. "get total number of class entries"
```
+
+#### Debugging:
+```smalltalk
| a b x |
-x yourself. "returns receiver"
-String browse. "browse specified class"
-x inspect. "open object inspector window"
+x yourself. "returns receiver"
+String browse. "browse specified class"
+x inspect. "open object inspector window"
x confirm: 'Is this correct?'.
-x halt. "breakpoint to open debugger window"
+x halt. "breakpoint to open debugger window"
x halt: 'Halt message'.
x notify: 'Notify text'.
-x error: 'Error string'. "open up error window with title"
-x doesNotUnderstand: #cmrMessage. "flag message is not handled"
-x shouldNotImplement. "flag message should not be implemented"
-x subclassResponsibility. "flag message as abstract"
-x errorImproperStore. "flag an improper store into indexable object"
-x errorNonIntegerIndex. "flag only integers should be used as index"
-x errorSubscriptBounds. "flag subscript out of bounds"
-x primitiveFailed. "system primitive failed"
-
-a := 'A1'. b := 'B2'. a become: b. "switch two objects"
+x error: 'Error string'. "open up error window with title"
+x doesNotUnderstand: #cmrMessage. "flag message is not handled"
+x shouldNotImplement. "flag message should not be implemented"
+x subclassResponsibility. "flag message as abstract"
+x errorImproperStore. "flag an improper store into indexable object"
+x errorNonIntegerIndex. "flag only integers should be used as index"
+x errorSubscriptBounds. "flag subscript out of bounds"
+x primitiveFailed. "system primitive failed"
+
+a := 'A1'. b := 'B2'. a become: b. "switch two objects"
Transcript show: a, b; cr.
```
-## Misc
-```
+#### Miscellaneous
+```smalltalk
| x |
-"Smalltalk condenseChanges." "compress the change file"
-x := FillInTheBlank request: 'Prompt Me'. "prompt user for input"
+x := 1.2 hash. "hash value for object"
+y := x copy. "copy object"
+y := x shallowCopy. "copy object (not overridden)"
+y := x deepCopy. "copy object and instance vars"
+y := x veryDeepCopy. "complete tree copy using a dictionary"
+"Smalltalk condenseChanges." "compress the change file"
+x := FillInTheBlank request: 'Prompt Me'. "prompt user for input"
Utilities openCommandKeyHelp
```
-
-
-
## Ready For More?
-### Free Online
+### Online Smalltalk systems
+Most Smalltalks are either free as in OSS or have a free downloadable version with some payment required for commercial usage.
+* [Squeak](https://www.squeak.org)
+* [Pharo](http://pharo.org)
+* [Smalltalk/X](https://www.exept.de/en/smalltalk-x.html)
+* [Gemstone](http://gemtalksystems.com/)
+* [VA Smalltalk](http://www.instantiations.com/products/vasmalltalk/)
+* [VisualWorks Smalltalk](http://www.cincomsmalltalk.com/)
-* [GNU Smalltalk User's Guide](https://www.gnu.org/software/smalltalk/manual/html_node/Tutorial.html)
-* [smalltalk dot org](http://www.smalltalk.org/)
-* [Computer Programming using GNU Smalltalk](http://www.canol.info/books/computer_programming_using_gnu_smalltalk/)
+### Online Smalltalk books and articles
+* [Smalltalk Programming Resources](http://www.whoishostingthis.com/resources/smalltalk/)
* [Smalltalk Cheatsheet](http://www.angelfire.com/tx4/cus/notes/smalltalk.html)
* [Smalltalk-72 Manual](http://www.bitsavers.org/pdf/xerox/parc/techReports/Smalltalk-72_Instruction_Manual_Mar76.pdf)
+* [GNU Smalltalk User's Guide](https://www.gnu.org/software/smalltalk/manual/html_node/Tutorial.html)
+
+#### Historical Documentation(s)
* [BYTE: A Special issue on Smalltalk](https://archive.org/details/byte-magazine-1981-08)
+* [Smalltalk-72 Manual](http://www.bitsavers.org/pdf/xerox/parc/techReports/Smalltalk-72_Instruction_Manual_Mar76.pdf)
* [Smalltalk, Objects, and Design](https://books.google.co.in/books?id=W8_Une9cbbgC&printsec=frontcover&dq=smalltalk&hl=en&sa=X&ved=0CCIQ6AEwAWoVChMIw63Vo6CpyAIV0HGOCh3S2Alf#v=onepage&q=smalltalk&f=false)
* [Smalltalk: An Introduction to Application Development Using VisualWorks](https://books.google.co.in/books?id=zalQAAAAMAAJ&q=smalltalk&dq=smalltalk&hl=en&sa=X&ved=0CCgQ6AEwAmoVChMIw63Vo6CpyAIV0HGOCh3S2Alf/)
-* [Smalltalk Programming Resources](http://www.whoishostingthis.com/resources/smalltalk/)
diff --git a/solidity.html.markdown b/solidity.html.markdown
index 0ad8af32..cc719ec7 100644
--- a/solidity.html.markdown
+++ b/solidity.html.markdown
@@ -4,6 +4,8 @@ filename: learnSolidity.sol
contributors:
- ["Nemil Dalal", "https://www.nemil.com"]
- ["Joseph Chow", ""]
+ - ["Bhoomtawath Plinsut", "https://github.com/varshard"]
+ - ["Shooter", "https://github.com/liushooter"]
---
Solidity lets you program on [Ethereum](https://www.ethereum.org/), a
@@ -37,6 +39,9 @@ features are typically marked, and subject to change. Pull requests welcome.
// simple_bank.sol (note .sol extension)
/* **** START EXAMPLE **** */
+// Declare the source file compiler version
+pragma solidity ^0.4.19;
+
// Start with Natspec comment (the three slashes)
// used for documentation - and as descriptive data for UI elements/actions
@@ -45,7 +50,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
@@ -62,7 +67,7 @@ contract SimpleBank { // CamelCase
event LogDepositMade(address accountAddress, uint amount);
// Constructor, can receive one or many variables here; only one allowed
- function AcmeBank() {
+ function SimpleBank() public {
// msg provides details about the message that's sent to the contract
// msg.sender is contract caller (address of contract creator)
owner = msg.sender;
@@ -70,7 +75,11 @@ contract SimpleBank { // CamelCase
/// @notice Deposit ether into bank
/// @return The balance of the user after the deposit is made
- function deposit() public returns (uint) {
+ function deposit() public payable returns (uint) {
+ // Use 'require' to test user inputs, 'assert' for internal invariants
+ // Here we are making sure that there isn't an overflow issue
+ require((balances[msg.sender] + msg.value) >= balances[msg.sender]);
+
balances[msg.sender] += msg.value;
// no "this." or "self." required with state variable
// all values set to data type's initial value by default
@@ -85,38 +94,28 @@ contract SimpleBank { // CamelCase
/// @param withdrawAmount amount you want to withdraw
/// @return The balance remaining for the user
function withdraw(uint withdrawAmount) public returns (uint remainingBal) {
- if(balances[msg.sender] >= withdrawAmount) {
- // Note the way we deduct the balance right away, before sending - due to
- // the risk of a recursive call that allows the caller to request an amount greater
- // than their balance
- balances[msg.sender] -= withdrawAmount;
-
- if (!msg.sender.send(withdrawAmount)) {
- // increment back only on fail, as may be sending to contract that
- // has overridden 'send' on the receipt end
- balances[msg.sender] += withdrawAmount;
- }
- }
+ require(withdrawAmount <= balances[msg.sender]);
+
+ // Note the way we deduct the balance right away, before sending
+ // Every .transfer/.send from this contract can call an external function
+ // This may allow the caller to request an amount greater
+ // than their balance using a recursive call
+ // Aim to commit state before calling external functions, including .transfer/.send
+ balances[msg.sender] -= withdrawAmount;
+
+ // this automatically throws on a failure, which means the updated balance is reverted
+ msg.sender.transfer(withdrawAmount);
return balances[msg.sender];
}
/// @notice Get balance
/// @return The balance of the user
- // 'constant' prevents function from editing state variables;
+ // 'view' (ex: constant) prevents function from editing state variables;
// allows function to run locally/off blockchain
- function balance() constant returns (uint) {
+ function balance() view public returns (uint) {
return balances[msg.sender];
}
-
- // Fallback function - Called if other functions don't match call or
- // sent ether without data
- // Typically, called when invalid data is sent
- // Added so ether sent to this contract is reverted if the contract fails
- // otherwise, the sender's money is transferred to contract
- function () {
- throw; // throw reverts state to before call
- }
}
// ** END EXAMPLE **
@@ -134,6 +133,11 @@ int256 constant a = 8; // same effect as line above, here the 256 is explicit
uint constant VERSION_ID = 0x123A1; // A hex constant
// with 'constant', compiler replaces each occurrence with actual value
+// All state variables (those outside a function)
+// are by default 'internal' and accessible inside contract
+// and in all contracts that inherit ONLY
+// Need to explicitly set to 'public' to allow external contracts to access
+int256 public a = 8;
// For int and uint, can explicitly set space in steps of 8 up to 256
// e.g., int8, int16, int24
@@ -142,6 +146,12 @@ int64 c;
uint248 e;
// Be careful that you don't overflow, and protect against attacks that do
+// For example, for an addition, you'd do:
+uint256 c = a + b;
+assert(c >= a); // assert tests for internal invariants; require is used for user inputs
+// For more examples of common arithmetic issues, see Zeppelin's SafeMath library
+// https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol
+
// No random functions built in, use other contracts for randomness
@@ -162,14 +172,14 @@ address public owner;
// a getter is automatically created, but NOT a setter
// All addresses can be sent ether
-owner.send(SOME_BALANCE); // returns false on failure
-if (owner.send) {} // REMEMBER: wrap in 'if', as contract addresses have
+owner.transfer(SOME_BALANCE); // fails and reverts on failure
+
+// Can also do a lower level .send call, which returns a false if it failed
+if (owner.send) {} // REMEMBER: wrap send in 'if', as contract addresses have
// functions executed on send and these can fail
// Also, make sure to deduct balances BEFORE attempting a send, as there is a risk of a recursive
// call that can drain the contract
-// can override send by defining your own
-
// Can check balance
owner.balance; // the balance of the owner (user or contract)
@@ -188,7 +198,7 @@ string n = "hello"; // stored in UTF8, note double quotes, not single
// string utility functions to be added in future
// prefer bytes32/bytes, as UTF8 uses more storage
-// Type inferrence
+// Type inference
// var does inferred typing based on first assignment,
// can't be used in functions parameters
var a = true;
@@ -210,7 +220,7 @@ uint x = 5;
// Destructuring/Tuples
-(x, y) = (2, 7); // assign/swap multiple value
+(x, y) = (2, 7); // assign/swap multiple values
// 2. DATA STRUCTURES
@@ -228,7 +238,7 @@ uint x[][5]; // arr with 5 dynamic array elements (opp order of most languages)
// Dictionaries (any type to any other type)
mapping (string => uint) public balances;
balances["charles"] = 1;
-console.log(balances["ada"]); // is 0, all non-set key values return zeroes
+// balances["ada"] result is 0, all non-set key values return zeroes
// 'public' allows following from another contract
contractName.balances("charles"); // returns 1
// 'public' created a getter (but not setter) like the following:
@@ -247,7 +257,7 @@ delete balances; // sets all elements to 0
// mapping, without knowing source keys - can build data structure
// on top to do this
-// Structs and enums
+// Structs
struct Bank {
address owner;
uint balance;
@@ -259,7 +269,7 @@ Bank b = Bank({
// or
Bank c = Bank(msg.sender, 5);
-c.amount = 5; // set to new value
+c.balance = 5; // set to new value
delete b;
// sets to initial value, set all variables in struct to 0, except mappings
@@ -270,7 +280,7 @@ state = State.Created;
// enums can be explicitly converted to ints
uint createdState = uint(State.Created); // 0
-// Data locations: Memory vs. storage vs. stack - all complex types (arrays,
+// Data locations: Memory vs. storage vs. calldata - all complex types (arrays,
// structs) have a data location
// 'memory' does not persist, 'storage' does
// Default is 'storage' for local and state variables; 'memory' for func params
@@ -289,13 +299,13 @@ uint createdState = uint(State.Created); // 0
// 4. Global Variables of note
// ** this **
this; // address of contract
-// often used at end of contract life to send remaining balance to party
+// often used at end of contract life to transfer remaining balance to party
this.balance;
this.someFunction(); // calls func externally via call, not via internal jump
// ** msg - Current message received by the contract ** **
msg.sender; // address of sender
-msg.value; // amount of ether provided to this contract in wei
+msg.value; // amount of ether provided to this contract in wei, the function should be marked "payable"
msg.data; // bytes, complete call data
msg.gas; // remaining gas
@@ -305,6 +315,8 @@ tx.gasprice; // gas price of the transaction
// ** block - Information about current block **
now; // current time (approximately), alias for block.timestamp (uses Unix time)
+// Note that this can be manipulated by miners, so use carefully
+
block.number; // current block number
block.difficulty; // current block difficulty
block.blockhash(1); // returns bytes32, only works for most recent 256 blocks
@@ -331,23 +343,33 @@ function increment(uint x, uint y) returns (uint x, uint y) {
// Call previous functon
uint (a,b) = increment(1,1);
-// 'constant' indicates that function does not/cannot change persistent vars
-// Constant function execute locally, not on blockchain
-uint y;
+// 'view' (alias for 'constant')
+// indicates that function does not/cannot change persistent vars
+// View function execute locally, not on blockchain
+// Noted: constant keyword will soon be deprecated.
+uint y = 1;
-function increment(uint x) constant returns (uint x) {
+function increment(uint x) view returns (uint x) {
x += 1;
y += 1; // this line would fail
- // y is a state variable, and can't be changed in a constant function
+ // y is a state variable, and can't be changed in a view function
}
+// 'pure' is more strict than 'view' or 'constant', and does not
+// even allow reading of state vars
+// The exact rules are more complicated, so see more about
+// view/pure:
+// http://solidity.readthedocs.io/en/develop/contracts.html#view-functions
+
// 'Function Visibility specifiers'
-// These can be placed where 'constant' is, including:
-// public - visible externally and internally (default)
-// external
+// These can be placed where 'view' is, including:
+// public - visible externally and internally (default for function)
+// external - only visible externally (including a call made with this.)
// private - only visible in the current contract
// internal - only visible in current contract, and those deriving from it
+// Generally, a good idea to mark each function explicitly
+
// Functions hoisted - and can assign a function to a variable
function a() {
var z = b;
@@ -358,8 +380,15 @@ function b() {
}
+// All functions that receive ether must be marked 'payable'
+function depositEther() public payable {
+ balances[msg.sender] += msg.value;
+}
+
// Prefer loops to recursion (max call stack depth is 1024)
+// Also, don't setup loops that you haven't bounded,
+// as this can hit the gas limit
// B. Events
// Events are notify external parties; easy to search and
@@ -373,10 +402,15 @@ function b() {
event LogSent(address indexed from, address indexed to, uint amount); // note capital first letter
// Call
-Sent(from, to, amount);
+LogSent(from, to, amount);
-// For an external party (a contract or external entity), to watch:
-Coin.Sent().watch({}, '', function(error, result) {
+/**
+
+For an external party (a contract or external entity), to watch using
+the Web3 Javascript library:
+
+// The following is Javascript code, not Solidity code
+Coin.LogSent().watch({}, '', function(error, result) {
if (!error) {
console.log("Coin transfer: " + result.args.amount +
" coins were sent from " + result.args.from +
@@ -386,6 +420,8 @@ Coin.Sent().watch({}, '', function(error, result) {
"Receiver: " + Coin.balances.call(result.args.to));
}
}
+**/
+
// Common paradigm for one contract to depend on another (e.g., a
// contract that depends on current exchange rate provided by another)
@@ -395,10 +431,10 @@ Coin.Sent().watch({}, '', function(error, result) {
// '_' (underscore) often included as last line in body, and indicates
// function being called should be placed there
-modifier onlyAfter(uint _time) { if (now <= _time) throw; _ }
-modifier onlyOwner { if (msg.sender == owner) _ }
+modifier onlyAfter(uint _time) { require (now >= _time); _; }
+modifier onlyOwner { require(msg.sender == owner) _; }
// commonly used with state machines
-modifier onlyIfState (State currState) { if (currState != State.A) _ }
+modifier onlyIfStateA (State currState) { require(currState == State.A) _; }
// Append right after function declaration
function changeOwner(newOwner)
@@ -412,12 +448,10 @@ onlyIfState(State.A)
// underscore can be included before end of body,
// but explicitly returning will skip, so use carefully
modifier checkValue(uint amount) {
- _
+ _;
if (msg.value > amount) {
uint amountToRefund = amount - msg.value;
- if (!msg.sender.send(amountToRefund)) {
- throw;
- }
+ msg.sender.transfer(amountToRefund);
}
}
@@ -434,23 +468,22 @@ modifier checkValue(uint amount) {
// amount of gas for a block of code - and will fail if that is exceeded
// For example:
for(uint x = 0; x < refundAddressList.length; x++) {
- if (!refundAddressList[x].send(SOME_AMOUNT)) {
- throw;
- }
+ refundAddressList[x].transfer(SOME_AMOUNT);
}
// Two errors above:
-// 1. A failure on send stops the loop from completing, tying up money
+// 1. A failure on transfer stops the loop from completing, tying up money
// 2. This loop could be arbitrarily long (based on the amount of users who need refunds), and
// therefore may always fail as it exceeds the max gas for a block
// Instead, you should let people withdraw individually from their subaccount, and mark withdrawn
+// e.g., favor pull payments over push payments
// 7. OBJECTS/CONTRACTS
// A. Calling external contract
-contract infoFeed {
- function info() returns (uint ret) { return 42; }
+contract InfoFeed {
+ function info() payable returns (uint ret) { return 42; }
}
contract Consumer {
@@ -484,7 +517,7 @@ contract MyContract is abc, def("a custom argument to def") {
function z() {
if (msg.sender == owner) {
def.z(); // call overridden function from def
- super.z(); // call immediate parent overriden function
+ super.z(); // call immediate parent overridden function
}
}
}
@@ -499,23 +532,10 @@ function someAbstractFunction(uint x);
import "filename";
import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol";
-// Importing under active development
-// Cannot currently be done at command line
-
// 8. OTHER KEYWORDS
-// A. Throwing
-// Throwing
-throw; // reverts unused money to sender, state is reverted
-// Can't currently catch
-
-// Common design pattern is:
-if (!addr.send(123)) {
- throw;
-}
-
-// B. Selfdestruct
+// A. Selfdestruct
// selfdestruct current contract, sending funds to address (often creator)
selfdestruct(SOME_ADDRESS);
@@ -540,7 +560,7 @@ function remove() {
// that is private needs to be obfuscated (e.g., hashed w/secret)
// Steps: 1. Commit to something, 2. Reveal commitment
-sha3("some_bid_amount", "some secret"); // commit
+keccak256("some_bid_amount", "some secret"); // commit
// call contract's reveal function in the future
// showing bid plus secret that hashes to SHA3
@@ -614,6 +634,7 @@ contract SomeOracle {
// ** START EXAMPLE **
// CrowdFunder.sol
+pragma solidity ^0.4.19;
/// @title CrowdFunder
/// @author nemild
@@ -647,22 +668,20 @@ contract CrowdFunder {
event LogWinnerPaid(address winnerAddress);
modifier inState(State _state) {
- if (state != _state) throw;
- _
+ require(state == _state);
+ _;
}
modifier isCreator() {
- if (msg.sender != creator) throw;
- _
+ require(msg.sender == creator);
+ _;
}
- // Wait 6 months after final contract state before allowing contract destruction
+ // Wait 24 weeks after final contract state before allowing contract destruction
modifier atEndOfLifecycle() {
- if(!((state == State.ExpiredRefund || state == State.Successful) &&
- completeAt + 6 months < now)) {
- throw;
- }
- _
+ require(((state == State.ExpiredRefund || state == State.Successful) &&
+ completeAt + 24 weeks < now));
+ _;
}
function CrowdFunder(
@@ -670,6 +689,7 @@ contract CrowdFunder {
string _campaignUrl,
address _fundRecipient,
uint _minimumToRaise)
+ public
{
creator = msg.sender;
fundRecipient = _fundRecipient;
@@ -680,7 +700,9 @@ contract CrowdFunder {
function contribute()
public
+ payable
inState(State.Fundraising)
+ returns(uint256 id)
{
contributions.push(
Contribution({
@@ -696,7 +718,9 @@ contract CrowdFunder {
return contributions.length - 1; // return id
}
- function checkIfFundingCompleteOrExpired() {
+ function checkIfFundingCompleteOrExpired()
+ public
+ {
if (totalRaised > minimumToRaise) {
state = State.Successful;
payOut();
@@ -712,31 +736,23 @@ contract CrowdFunder {
public
inState(State.Successful)
{
- if(!fundRecipient.send(this.balance)) {
- throw;
- }
-
-
+ fundRecipient.transfer(this.balance);
LogWinnerPaid(fundRecipient);
}
- function getRefund(id)
- public
+ function getRefund(uint256 id)
inState(State.ExpiredRefund)
+ public
+ returns(bool)
{
- if (contributions.length <= id || id < 0 || contributions[id].amount == 0 ) {
- throw;
- }
+ require(contributions.length > id && id >= 0 && contributions[id].amount != 0 );
- uint amountToRefund = contributions[id].amount;
+ uint256 amountToRefund = contributions[id].amount;
contributions[id].amount = 0;
- if(!contributions[id].contributor.send(amountToSend)) {
- contributions[id].amount = amountToSend;
- return false;
- }
+ contributions[id].contributor.transfer(amountToRefund);
- return true;
+ return true;
}
function removeContract()
@@ -747,8 +763,6 @@ contract CrowdFunder {
selfdestruct(msg.sender);
// creator gets all money that hasn't be claimed
}
-
- function () { throw; }
}
// ** END EXAMPLE **
@@ -795,6 +809,7 @@ someContractAddress.callcode('function_name');
// 13. STYLE NOTES
// Based on Python's PEP8 style guide
+// Full Style guide: http://solidity.readthedocs.io/en/develop/style-guide.html
// Quick summary:
// 4 spaces for indentation
@@ -804,7 +819,7 @@ someContractAddress.callcode('function_name');
// else should be placed on own line
-// 14. NATSPEC COMENTS
+// 14. NATSPEC COMMENTS
// used for documentation, commenting, and external UIs
// Contract natspec - always above contract definition
@@ -822,11 +837,16 @@ someContractAddress.callcode('function_name');
## Additional resources
- [Solidity Docs](https://solidity.readthedocs.org/en/latest/)
-- [Solidity Style Guide](https://ethereum.github.io/solidity//docs/style-guide/): Ethereum's style guide is heavily derived from Python's [pep8](https://www.python.org/dev/peps/pep-0008/) style guide.
-- [Browser-based Solidity Editor](http://chriseth.github.io/browser-solidity/)
+- [Smart Contract Best Practices](https://github.com/ConsenSys/smart-contract-best-practices)
+- [Superblocks Lab - Browser based IDE for Solidity](https://lab.superblocks.com/)
+- [EthFiddle - The JsFiddle for Solidity](https://ethfiddle.com/)
+- [Browser-based Solidity Editor](https://remix.ethereum.org/)
- [Gitter Solidity Chat room](https://gitter.im/ethereum/solidity)
- [Modular design strategies for Ethereum Contracts](https://docs.erisindustries.com/tutorials/solidity/)
+## Important libraries
+- [Zeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/): Libraries that provide common contract patterns (crowdfuding, safemath, etc)
+
## Sample contracts
- [Dapp Bin](https://github.com/ethereum/dapp-bin)
- [Solidity Baby Step Contracts](https://github.com/fivedogit/solidity-baby-steps/tree/master/contracts)
@@ -838,13 +858,11 @@ someContractAddress.callcode('function_name');
- [Smart Contract Security](https://blog.ethereum.org/2016/06/10/smart-contract-security/)
- [Hacking Distributed Blog](http://hackingdistributed.com/)
-## Information purposefully excluded
-- Libraries
-
## Style
-- Python's [PEP8](https://www.python.org/dev/peps/pep-0008/) is used as the baseline style guide, including its general philosophy
+- [Solidity Style Guide](http://solidity.readthedocs.io/en/latest/style-guide.html): Ethereum's style guide is heavily derived from Python's [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide.
## Editors
+- [Emacs Solidity Mode](https://github.com/ethereum/emacs-solidity)
- [Vim Solidity](https://github.com/tomlion/vim-solidity)
- Editor Snippets ([Ultisnips format](https://gist.github.com/nemild/98343ce6b16b747788bc))
diff --git a/sql.html.markdown b/sql.html.markdown
new file mode 100644
index 00000000..685e522d
--- /dev/null
+++ b/sql.html.markdown
@@ -0,0 +1,110 @@
+---
+language: SQL
+filename: learnsql.sql
+contributors:
+ - ["Bob DuCharme", "http://bobdc.com/"]
+---
+
+Structured Query Language (SQL) is an [ISO/IEC 9075](https://www.iso.org/standard/63555.html) standard language for creating and working with databases stored in a set of tables. Implementations usually add their own extensions to the language; [Comparison of different SQL implementations](http://troels.arvin.dk/db/rdbms/) is a good reference on product differences.
+
+Implementations typically provide a command line prompt where you can enter the commands shown here interactively, and they also offer a way to execute a series of these commands stored in a script file. (Showing that you’re done with the interactive prompt is a good example of something that isn’t standardized--most SQL implementations support the keywords QUIT, EXIT, or both.)
+
+Several of these sample commands assume that the [MySQL employee sample database](https://dev.mysql.com/doc/employee/en/) available on [github](https://github.com/datacharmer/test_db) has already been loaded. The github files are scripts of commands, similar to the relevant commands below, that create and populate tables of data about a fictional company’s employees. The syntax for running these scripts will depend on the SQL implementation you are using. A utility that you run from the operating system prompt is typical.
+
+
+```sql
+-- Comments start with two hyphens. End each command with a semicolon.
+
+-- SQL is not case-sensitive about keywords. The sample commands here
+-- follow the convention of spelling them in upper-case because it makes
+-- it easier to distinguish them from database, table, and column names.
+
+-- Create and delete a database. Database and table names are case-sensitive.
+CREATE DATABASE someDatabase;
+DROP DATABASE someDatabase;
+
+-- List available databases.
+SHOW DATABASES;
+
+-- Use a particular existing database.
+USE employees;
+
+-- Select all rows and columns from the current database's departments table.
+-- Default activity is for the interpreter to scroll the results on your screen.
+SELECT * FROM departments;
+
+-- Retrieve all rows from the departments table,
+-- but only the dept_no and dept_name columns.
+-- Splitting up commands across lines is OK.
+SELECT dept_no,
+ dept_name FROM departments;
+
+-- Retrieve all departments columns, but just 5 rows.
+SELECT * FROM departments LIMIT 5;
+
+-- Retrieve dept_name column values from the departments
+-- table where the dept_name value has the substring 'en'.
+SELECT dept_name FROM departments WHERE dept_name LIKE '%en%';
+
+-- Retrieve all columns from the departments table where the dept_name
+-- column starts with an 'S' and has exactly 4 characters after it.
+SELECT * FROM departments WHERE dept_name LIKE 'S____';
+
+-- Select title values from the titles table but don't show duplicates.
+SELECT DISTINCT title FROM titles;
+
+-- Same as above, but sorted (case-sensitive) by the title values.
+SELECT DISTINCT title FROM titles ORDER BY title;
+
+-- Show the number of rows in the departments table.
+SELECT COUNT(*) FROM departments;
+
+-- Show the number of rows in the departments table that
+-- have 'en' as a substring of the dept_name value.
+SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%';
+
+-- A JOIN of information from multiple tables: the titles table shows
+-- who had what job titles, by their employee numbers, from what
+-- date to what date. Retrieve this information, but instead of the
+-- employee number, use the employee number as a cross-reference to
+-- the employees table to get each employee's first and last name
+-- instead. (And only get 10 rows.)
+
+SELECT employees.first_name, employees.last_name,
+ titles.title, titles.from_date, titles.to_date
+FROM titles INNER JOIN employees ON
+ employees.emp_no = titles.emp_no LIMIT 10;
+
+-- List all the tables in all the databases. Implementations typically provide
+-- their own shortcut command to do this with the database currently in use.
+SELECT * FROM INFORMATION_SCHEMA.TABLES
+WHERE TABLE_TYPE='BASE TABLE';
+
+-- Create a table called tablename1, with the two columns shown, for
+-- the database currently in use. Lots of other options are available
+-- for how you specify the columns, such as their datatypes.
+CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20));
+
+-- Insert a row of data into the table tablename1. This assumes that the
+-- table has been defined to accept these values as appropriate for it.
+INSERT INTO tablename1 VALUES('Richard','Mutt');
+
+-- In tablename1, change the fname value to 'John'
+-- for all rows that have an lname value of 'Mutt'.
+UPDATE tablename1 SET fname='John' WHERE lname='Mutt';
+
+-- Delete rows from the tablename1 table
+-- where the lname value begins with 'M'.
+DELETE FROM tablename1 WHERE lname like 'M%';
+
+-- Delete all rows from the tablename1 table, leaving the empty table.
+DELETE FROM tablename1;
+
+-- Remove the entire tablename1 table.
+DROP TABLE tablename1;
+```
+
+## Further Reading
+
+* [Codecademy - SQL](https://www.codecademy.com/learn/learn-sql) A good introduction to SQL in a "learn by doing it" format.
+* [Database System Concepts](https://www.db-book.com) book's Chapter 3 - Introduction to SQL has an in depth explanation of SQL concepts.
diff --git a/standard-ml.html.markdown b/standard-ml.html.markdown
index 133e4f54..9d6b104d 100644
--- a/standard-ml.html.markdown
+++ b/standard-ml.html.markdown
@@ -1,10 +1,12 @@
---
language: "Standard ML"
+filename: standardml.sml
contributors:
- - ["Simon Shine", "http://shine.eu.org/"]
- - ["David Pedersen", "http://lonelyproton.com/"]
+ - ["Simon Shine", "https://simonshine.dk/"]
+ - ["David Pedersen", "https://github.com/davidpdrsn"]
- ["James Baker", "http://www.jbaker.io/"]
- ["Leo Zovic", "http://langnostic.inaimathi.ca/"]
+ - ["Chris Wilson", "http://sencjw.com/"]
---
Standard ML is a functional programming language with type inference and some
@@ -235,17 +237,18 @@ val hmm = answer "What is the meaning of life, the universe and everything?"
(* Functions can take several arguments by taking one tuples as argument: *)
fun solve2 (a : real, b : real, c : real) =
- ( (~b + Math.sqrt(b * b - 4.0*a*c)) / (2.0 * a),
- (~b - Math.sqrt(b * b - 4.0*a*c)) / (2.0 * a) )
+ ((~b + Math.sqrt(b * b - 4.0 * a * c)) / (2.0 * a),
+ (~b - Math.sqrt(b * b - 4.0 * a * c)) / (2.0 * a))
(* Sometimes, the same computation is carried out several times. It makes sense
to save and re-use the result the first time. We can use "let-bindings": *)
fun solve2 (a : real, b : real, c : real) =
- let val discr = b * b - 4.0*a*c
+ let val discr = b * b - 4.0 * a * c
val sqr = Math.sqrt discr
val denom = 2.0 * a
in ((~b + sqr) / denom,
- (~b - sqr) / denom) end
+ (~b - sqr) / denom)
+ end
(* Pattern matching is a funky part of functional programming. It is an
@@ -264,6 +267,19 @@ fun second_elem (x::y::xs) = y
fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs
| evenly_positioned_elems [odd] = [] (* Base case: throw away *)
| evenly_positioned_elems [] = [] (* Base case *)
+
+(* The case expression can also be used to pattern match and return a value *)
+datatype temp =
+ C of real
+ | F of real
+
+(* Declaring a new C temp value...
+ val t: temp = C 45.0 *)
+
+fun temp_to_f t =
+ case t of
+ C x => x * (9.0 / 5.0) + 32.0
+ | F x => x
(* When matching on records, you must use their slot names, and you must bind
every slot in a record. The order of the slots doesn't matter though. *)
@@ -292,6 +308,9 @@ val thermometer =
val some_result = (fn x => thermometer (x - 5) ^ thermometer (x + 5)) 37
(* Here is a higher-order function that works on lists (a list combinator) *)
+(* map f l
+ applies f to each element of l from left to right,
+ returning the list of results. *)
val readings = [ 34, 39, 37, 38, 35, 36, 37, 37, 37 ] (* first an int list *)
val opinions = List.map thermometer readings (* gives [ "Cold", "Warm", ... ] *)
@@ -324,7 +343,11 @@ val n = op + (5, 5) (* n is now 10 *)
(* 'op' is useful when combined with high order functions because they expect
functions and not operators as arguments. Most operators are really just
infix functions. *)
-val sum_of_numbers = foldl op+ 0 [1,2,3,4,5]
+(* foldl f init [x1, x2, ..., xn]
+ returns
+ f(xn, ...f(x2, f(x1, init))...)
+ or init if the list is empty. *)
+val sum_of_numbers = foldl op+ 0 [1, 2, 3, 4, 5]
(* Datatypes are useful for creating both simple and complex structures *)
@@ -343,7 +366,10 @@ val _ = print (say(Red) ^ "\n")
fun say Red = "You are red!"
| say Green = "You are green!"
| say Blue = "You are blue!"
- | say _ = raise Fail "Unknown color"
+
+(* We did not include the match arm `say _ = raise Fail "Unknown color"`
+because after specifying all three colors, the pattern is exhaustive
+and redundancy is not permitted in pattern matching *)
(* Here is a binary tree datatype *)
@@ -377,7 +403,7 @@ fun calculate_interest(n) = if n < 0.0
(* Exceptions can be caught using "handle" *)
val balance = calculate_interest ~180.0
- handle Domain => ~180.0 (* x now has the value ~180.0 *)
+ handle Domain => ~180.0 (* balance now has the value ~180.0 *)
(* Some exceptions carry extra information with them *)
(* Here are some examples of built-in exceptions *)
@@ -387,7 +413,7 @@ fun failing_function [] = raise Empty (* used for empty lists *)
| failing_function xs = raise Fail "This list is too long!"
(* We can pattern match in 'handle' to make sure
- a specfic exception was raised, or grab the message *)
+ a specific exception was raised, or grab the message *)
val err_msg = failing_function [1,2] handle Fail _ => "Fail was raised"
| Domain => "Domain was raised"
| Empty => "Empty was raised"
@@ -407,7 +433,8 @@ fun writePoem(filename) =
let val file = TextIO.openOut(filename)
val _ = TextIO.output(file, "Roses are red,\nViolets are blue.\n")
val _ = TextIO.output(file, "I have a gun.\nGet in the van.\n")
- in TextIO.closeOut(file) end
+ in TextIO.closeOut(file)
+ end
(* Read a nice poem from a file into a list of strings *)
fun readPoem(filename) =
@@ -450,5 +477,6 @@ fun decrement_ret x y = (x := !x - 1; y)
[Moscow ML](http://mosml.org),
[SML/NJ](http://smlnj.org/).
* Follow the Coursera course [Programming Languages](https://www.coursera.org/course/proglang).
-* Get the book *ML for the Working Programmer* by Larry C. Paulson.
+* Read *[ML for the Working Programmer](https://www.cl.cam.ac.uk/~lp15/MLbook/pub-details.html)* by Larry C. Paulson.
* Use [StackOverflow's sml tag](http://stackoverflow.com/questions/tagged/sml).
+* Solve exercises on [Exercism.io's Standard ML track](https://exercism.io/tracks/sml).
diff --git a/stylus.html.markdown b/stylus.html.markdown
new file mode 100644
index 00000000..1c5ddd32
--- /dev/null
+++ b/stylus.html.markdown
@@ -0,0 +1,228 @@
+---
+language: stylus
+filename: learnStylus.styl
+contributors:
+ - ["Salomão Neto", "https://github.com/salomaosnff"]
+ - ["Isaac Henrique", "https://github.com/Isaachi1"]
+translators:
+ - ["Divay Prakash", "https://github.com/divayprakash"]
+---
+
+Stylus is a dynamic stylesheet preprocessor language that is compiled into CSS. It aims to add functionality to CSS without breaking compatibility across web browsers.
+It does this using variables, nesting, mixins, functions and more.
+
+Stylus syntax is very flexible. You can use standard CSS syntax and leave the semicolon (;), colon (:) and even the ({) and (}) optional, making your code even more readable.
+
+Stylus does not provide new style options, but gives functionality that lets you make your CSS much more dynamic.
+
+```scss
+
+/* Code style
+==============================*/
+
+/* Keys, semicolon, and colon are optional in Stylus. */
+
+body {
+ background: #000;
+}
+
+body {
+ background: #000
+}
+
+body {
+ background #000
+}
+
+body
+ background #000
+
+body
+ background: #000;
+
+body
+ background: #000
+
+// Single-line comments are removed when Stylus is compiled into CSS.
+
+/* Multi-line comments are preserved. */
+
+
+/* Selectors
+==============================*/
+
+/* Selecting elements within another element */
+body {
+ background: #000000;
+ h1 {
+ color: #FF0000;
+ }
+}
+
+/* Or if you prefer... */
+body
+ background #000000
+ h1
+ color #FF0000
+
+
+/* Getting parent element reference
+==============================*/
+a {
+ color: #0088dd;
+ &:hover {
+ color: #DD8800;
+ }
+}
+
+
+/* Variables
+==============================*/
+
+
+/*
+ You can store a CSS value (such as the color) of a variable.
+  Although it is optional, it is recommended to add $ before a variable name
+  so you can distinguish a variable from another CSS value.
+*/
+
+$primary-color = #A3A4FF
+$secondary-color = #51527F
+$body-font = 'Roboto', sans-serif
+
+/* You can use variables throughout your style sheet.
+Now, if you want to change the color, you only have to make the change once. */
+
+body
+ background-color $primary-color
+ color $secondary-color
+ font-family $body-font
+
+/* After compilation: */
+body {
+ background-color: #A3A4FF;
+ color: #51527F;
+ font-family: 'Roboto', sans-serif;
+}
+
+/ *
+This is much easier to maintain than having to change color
+each time it appears throughout your style sheet.
+* /
+
+
+/* Mixins
+==============================*/
+
+/* If you find that you are writing the same code for more than one
+element, you may want to store that code in a mixin.
+
+center()
+ display block
+ margin-left auto
+ margin-right auto
+ left 0
+ right 0
+
+/* Using the mixin */
+body {
+ center()
+ background-color: $primary-color
+}
+
+/* After compilation: */
+div {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+ background-color: #A3A4FF;
+}
+
+/* You can use mixins to create a shorthand property. */
+
+size($width, $height)
+ width $width
+ height $height
+
+.rectangle
+ size(100px, 60px)
+
+.square
+ size(40px, 40px)
+
+/* You can use a mixin as a CSS property. */
+circle($ratio)
+ width $ratio * 2
+ height $ratio * 2
+ border-radius $ratio
+
+.ball
+ circle 25px
+
+
+/* Interpolation
+==============================*/
+
+vendor(prop, args)
+ -webkit-{prop} args
+ -moz-{prop} args
+ {prop} args
+
+border-radius()
+ vendor('border-radius', arguments)
+
+box-shadow()
+ vendor('box-shadow', arguments)
+
+button
+ border-radius 1px 2px / 3px 4px
+
+
+/* Functions
+==============================*/
+
+/* Functions in Stylus allow you to perform a variety of tasks, such as recalling some data. */
+
+body {
+ background darken(#0088DD, 50%) // Dim color #0088DD by 50%
+}
+
+/* Creating your own function */
+add(a, b)
+ a + b
+
+body
+ padding add(10px, 5)
+
+
+/* Conditions
+==============================*/
+compare(a, b)
+ if a > b
+ bigger
+ else if a < b
+ smaller
+ else
+ equal
+
+compare(5, 2) // => bigger
+compare(1, 5) // => smaller
+compare(10, 10) // => equal
+
+
+/* Iterations
+==============================*/
+
+/*
+Repeat loop syntax for:
+for <val-name> [, <key-name>] in <expression>
+*/
+
+for $item in (1..2) /* Repeat block 12 times */
+ .col-{$item}
+ width ($item / 12) * 100% /* Calculate row by column number */
+```
+
+Now that you know a little about this powerful CSS preprocessor, you're ready to create more dynamic style sheets. To learn more, visit the official stylus documentation at http://stylus-lang.com.
diff --git a/sv-se/brainfuck-sv.html.markdown b/sv-se/brainfuck-sv.html.markdown
index e9fbc436..57520955 100644
--- a/sv-se/brainfuck-sv.html.markdown
+++ b/sv-se/brainfuck-sv.html.markdown
@@ -1,5 +1,6 @@
---
language: brainfuck
+filename: brainfuck-sv.bf
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
diff --git a/sv-se/haskell-sv.html.markdown b/sv-se/haskell-sv.html.markdown
new file mode 100644
index 00000000..da2d6ab0
--- /dev/null
+++ b/sv-se/haskell-sv.html.markdown
@@ -0,0 +1,461 @@
+---
+language: Haskell
+filename: learnhaskell-sv.hs
+contributors:
+ - ["Adit Bhargava", "http://adit.io"]
+translators:
+ - ["Edward Tjörnhammar", "http://edwtjo.me"]
+lang: sv-se
+---
+
+Haskell skapades för att vara ett praktiskt, rent, funktionellt
+programmeringsspråk. Det är känt för sin använding av monader och dess
+härledande typsystem men anledningen till att jag ständigt återbesöker språket
+är på grund av dess elegans. Haskell gör programmering till ett rent nöje.
+
+```haskell
+-- Radkommenterar börjar med två bindestreck.
+{- Flerradskommentarer innesluts av vänster/höger måsvinge bindestreck
+block på detta vis.
+-}
+
+----------------------------------------------------
+-- 1. Fördefinierade datatyper och operatorer
+----------------------------------------------------
+
+-- Du har siffror
+3 -- 3
+
+-- Matte fungerar som förväntat
+1 + 1 -- 2
+8 - 1 -- 7
+10 * 2 -- 20
+35 / 5 -- 7.0
+
+-- Division är normalt inte heltalsdivision
+35 / 4 -- 8.75
+
+-- Heltalsdivision, här infix div
+35 `div` 4 -- 8
+
+-- Boolar (Sant och Falskt) är fördefinierade
+True
+False
+
+-- Samt dess operationer
+not True -- False
+not False -- True
+1 == 1 -- True
+1 /= 1 -- False
+1 < 10 -- True
+
+-- I ovanstående exempel är `not` en funktion vilken bara tar ett argument.
+-- Haskell behöver inte paranteser för sina funktionsanrop... alla argument
+-- ges mellanslagsseparerade direkt efter funktionen. Det övergripande mönstret
+-- är:
+-- func arg1 arg2 arg3...
+-- Se sektionen om funktioner för information om hur du skriver dina egna.
+
+-- Strängar och bokstäver
+"Detta är en sträng"
+'a' -- bokstav
+'Du kan inte använda enkelfnutt för strängar.' -- fel!
+
+-- Strängar kan konkateneras
+"Hej " ++ "världen!" -- "Hej världen!"
+
+-- En sträng är en lista av bokstäver
+['H', 'e', 'j', 's', 'a', 'n'] -- "Hejsan"
+"Detta är en sträng" !! 0 -- 'D'
+
+
+----------------------------------------------------
+-- 2. Listor och Tupler
+----------------------------------------------------
+
+-- Varje element i en lista måste ha samma typ.
+-- Dessa listor är ekvivalenta:
+[1, 2, 3, 4, 5]
+[1..5]
+
+-- Intervall är mångsidiga.
+['A'..'F'] -- "ABCDEF"
+
+-- Man kan stega intervall.
+[0,2..10] -- [0, 2, 4, 6, 8, 10]
+[5..1] -- [] (Haskell förutsätter normalt inkrement)
+[5,4..1] -- [5, 4, 3, 2, 1]
+
+-- Indexering in i en lista
+[1..10] !! 3 -- 4 (nollindexerat)
+
+-- Man kan ha oändliga listor i Haskell!
+[1..] -- listan över alla naturliga tal
+
+-- Oändliga listor fungerar enbart för att Haskell har "lat evaluering".
+-- Det betyder att Haskell bara evaluerar de uttryck den måste. Du kan alltså
+-- fråga efter det 1000:e elementet i en oändlig lista och Haskell kommer då ge
+-- dig det:
+
+[1..] !! 999 -- 1000
+
+-- Nu har Haskell evaluerat element 1 till 1000 i denna lista... men resten
+-- av medlemmarna i denna oändliga lista existerar inte ännu! Haskell kommer
+-- faktiskt inte utvärdera element den inte måste.
+
+-- Sammanslagning av två listor
+[1..5] ++ [6..10]
+
+-- Lägg till 0 vid listhuvudet
+0:[1..5] -- [0, 1, 2, 3, 4, 5]
+
+-- fler listoperationer som huvud, svans, initiella samt sista
+head [1..5] -- 1
+tail [1..5] -- [2, 3, 4, 5]
+init [1..5] -- [1, 2, 3, 4]
+last [1..5] -- 5
+
+-- listomfattningar
+[x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10]
+
+-- med bivilkor
+[x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10]
+
+-- Varje element i en tupel kan ha olika typ men en tupel kan bara ha en
+-- fixerad, eller statisk, längd.
+-- En tupel:
+("haskell", 1)
+
+-- För att komma åt element i ett par, alltså en 2-tupel, finns
+-- de fördefinierade funktionerna:
+fst ("haskell", 1) -- "haskell"
+snd ("haskell", 1) -- 1
+
+----------------------------------------------------
+-- 3. Funktioner
+----------------------------------------------------
+-- En enkel funktion med två parametrar
+add a b = a + b
+
+-- Notera även att om du använder ghci (Haskellinterpretatorn) kommer du behöva
+-- använda `let` namnbindning för att synliggöra din funktionsdeklaration,
+-- alltså
+let add a b = a + b
+
+-- För att använda funktionen
+add 1 2 -- 3
+
+-- Man kan även göra funktionsanropet infix, alltså mellan parametersättningen,
+-- med hjälp av bakåtfnuttar:
+1 `add` 2 -- 3
+
+-- Du kan även definiera funktioner vars funktionsnamn avsaknar bokstäver!
+-- Med hjälp av parenteser kan du därmed definiera operatorer (normalt infix)!
+-- Följande är en operator för heltalsdivision, vilken förlitar sig på div:
+(//) a b = a `div` b
+35 // 4 -- 8
+
+-- Funktionsvakter: ett enkelt sätt att grena ut dina funktioner
+fib x
+ | x < 2 = 1
+ | otherwise = fib (x - 1) + fib (x - 2)
+
+-- Mönstermatchning fungerar på liknande vis. Här ger vi tre olika
+-- parametermatchningar för vårat fib-resulat. Haskell kommer automatiskt följa
+-- första bästa träff, uppifrån ned, vars vänstra sida om likhetstecknet matchar
+-- anroparens parametervärde.
+fib 1 = 1
+fib 2 = 2
+fib x = fib (x - 1) + fib (x - 2)
+
+-- Mönstermatchning på tupler:
+foo (x, y) = (x + 1, y + 2)
+
+-- Mönstermatchning på listor. Här är `x` det första elementet i listan och `xs`
+-- är resten av listan. Nu kan vi skriva våran egen map-funktion
+minMap func [] = []
+minMap func (x:xs) = func x:(minMap func xs)
+
+-- Anonyma funktioner, eller lambdauttryck, skapas med hjälp av omvänt
+-- snedstreck, följt av parametrarna
+minMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7]
+
+-- Användning av fold (även kallad `inject`, `reduce`, osv.) tillsammans med en
+-- anonym funktion. `fold1` är en vänstervikande funktion och använder första
+-- värdet i listan som det initiella värdet för ackumulatorn.
+foldl1 (\acc x -> acc + x) [1..5] -- 15
+
+----------------------------------------------------
+-- 4. Mer funktioner
+----------------------------------------------------
+
+-- Partiell applikation:
+-- Om du inte anropar funktionen med alla sina argument
+-- blir den partiellt applicerad. Det betyder att du erhåller en funktion där en
+-- delmängd av parametrarna blivit värdesatta men några är fortfarande fria.
+add a b = a + b
+foo = add 10 -- foo är nu en funktion som tar ett nummer och lägger till 10 till
+ -- det
+foo 5 -- 15
+
+-- Ett annat sätt att skriva samma sak
+foo = (10+)
+foo 5 -- 15
+
+-- Funktionskomposition:
+-- Operatorn `.` kedjar ihop funktioner
+-- Till exempel, nedan är `foo` en funktion som tar ett värde, den adderar 10
+-- till det, multiplicerar det resultatet med 4 och sen ersätts med det värdet.
+foo = (4*) . (10+)
+
+-- 4*(10+5) = 60
+foo 5 -- 60
+
+-- Precedensordning:
+-- Haskell har en operator `$`. Denna operator applicerar en funktion till en
+-- given parameter med dess precedens. I kontrast mot vanlig
+-- funktionsapplikation, vilket har den högsta utvärderingsprioriteten 10 och
+-- associerar till vänster, har denna prioritetsordning 0 och är
+-- högerassociativ. Denna låga prioritet medför att parameteruttrycket till
+-- höger om operatorn får det reducerat innan det appliceras till sin vänster.
+
+-- före
+even (fib 7) -- falskt
+
+-- ekvivalent
+even $ fib 7 -- falskt
+
+-- med funktionskomposition
+even . fib $ 7 -- falskt
+
+
+----------------------------------------------------
+-- 5. Typsignaturer
+----------------------------------------------------
+
+-- Haskell har ett väldigt starkt typsystem, alla giltiga uttryck har en typ.
+
+-- Några grundläggande typer:
+5 :: Integer
+"hello" :: String
+True :: Bool
+
+-- Funktioner har också typer,
+-- `not` tar en bool och returnerar en bool:
+-- not :: Bool -> Bool
+
+-- Här är ett exempel på en funktionssignatur vilken beskriver en funktion som
+-- reducerar två heltal till ett:
+-- add :: Integer -> Integer -> Integer
+
+-- Trots att Haskell härleder typen på icke typsatta uttryck är det bra form att
+-- explicit ange dessa för ens deklarerade funktioner:
+double :: Integer -> Integer
+double x = x * 2
+
+----------------------------------------------------
+-- 6. Kontrollflöde och Ifsatser
+----------------------------------------------------
+
+-- if-sats
+haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
+
+-- if-statser kan spridas över rader men indentering har betydelse
+haskell = if 1 == 1
+ then "awesome"
+ else "awful"
+
+-- case uttryck: följande är ett exempel på kommandoradsparsning
+case args of
+ "help" -> printHelp
+ "start" -> startProgram
+ _ -> putStrLn "bad args"
+
+-- Haskell har inte loopar istället används recursion.
+-- map applicerar en funktion över varje element i en lista
+
+map (*2) [1..5] -- [2, 4, 6, 8, 10]
+
+-- man kan deklarera en for funktion genom att använda map
+for array func = map func array
+
+-- och därefter använda den tillsammans med en anonym funktion för att
+-- efterlikna en loop
+for [0..5] $ \i -> show i
+
+-- men vi kunde även ha skrivit på följande vis:
+for [0..5] show
+
+-- Du kan använda foldl eller foldr för att reducera en lista
+-- foldl <fn> <initial value> <list>
+foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
+
+-- Vilket är samma sak som
+(2 * (2 * (2 * 4 + 1) + 2) + 3)
+
+-- foldl viker från vänster, foldr från höger
+foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
+
+-- Vilket alltså är samma sak som
+(2 * 1 + (2 * 2 + (2 * 3 + 4)))
+
+----------------------------------------------------
+-- 7. Datatyper
+----------------------------------------------------
+
+-- Såhär definierar du din egen datatyp i Haskell
+data Color = Red | Blue | Green
+
+-- När du gjort det kan du använda den i funktionssignaturer och uttryck
+say :: Color -> String
+say Red = "Du är Rö!"
+say Blue = "Du är Blå!"
+say Green = "Du är Grön!"
+
+-- Dina datatyper kan även ta parametrar
+data Maybe a = Nothing | Just a
+
+-- Följande uttryck är alla specialiseringar av typen Maybe
+Just "hello" -- har typen `Maybe String`
+Just 1 -- har typen `Maybe Int`
+Nothing -- har typen `Maybe a` för alla `a`
+
+----------------------------------------------------
+-- 8. Haskell IO
+----------------------------------------------------
+
+-- Även om IO inte kan förstås fullt ut utan att först förklara monader är det
+-- inte svårt att lära sig tillräckligt för att komma igång
+
+-- När ett Haskellprogram körs är det topnivåns main som körs. Main måste
+-- returnerna ett värde av typen `IO a`, för någon typ `a`. Till exempel:
+
+main :: IO ()
+main = putStrLn $ "Hej, himmelen! " ++ (say Blue)
+-- putStrLn har typen type String -> IO ()
+
+-- Det är enkelt att göra IO om du kan implementera ditt program som en funktion
+-- från String till String. Funktionen
+-- interact :: (String -> String) -> IO ()
+-- tar denna funktion och matar den med strängdata från stdin och skriver ut
+-- resultatet som en sträng på stdout
+
+countLines :: String -> String
+countLines = show . length . lines
+
+main' = interact countLines
+
+-- Du kan tänka på värden av typen `IO ()` som att representera
+-- händelsesekvenser du vill att din dator skall utföra, likt imperativa språk.
+-- För att kedja ihop händelsesekvenser använder man ett syntaktiskt socker
+-- kallat do-notation. Som exempel:
+
+sägHej :: IO ()
+sägHej = do
+ putStrLn "Vad heter du?"
+ namn <- getLine -- denna raden läser en rad från stdin och vi binder den till
+ -- funktionsnamnet `namn`
+ putStrLn $ "Hejsan, " ++ namn
+
+-- Övning: Skriv din egen version av interageringsfunktionen `interact` som bara
+-- läser en rad från stdin, vanliga `interact` läser till EOF.
+
+-- Koden i sägHej kommer dock aldrig exekveras. Den enda handlingen som blir det
+-- är som bekant utvärderingen av `main`.
+-- För att köra `sägHej` kommentera ut definition av `main` ovan och
+-- avkommentera nedanstående version:
+-- main = sayHello
+
+-- Låt oss bättre förstå hur funktionen `getLine` vi just använde fungerar. Dess
+-- typsignatur är:
+-- getLine :: IO String
+-- Du kan tänka på typen `IO a` som att representeras av ett datorprogram vilken
+-- kommer generera ett värde av typen `a` när det exekveras (utöver allt annat
+-- det kan tänkas göra). Vi kan därtill binda detta värde till ett namn för
+-- återanvändning genom att använda `<-`. Vi kan även skapa våran egen handling
+-- av typen `IO String`:
+
+handling :: IO String
+handling = do
+ putStrLn "Detta är en rad, tihi"
+ input1 <- getLine
+ input2 <- getLine
+ -- Typen av hela `do` blocket är vad som står på sista raden. Här är även
+ -- `return` inte ett nyckelord i språket utan en funktion med en typsignatur
+ return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
+
+-- Vi kan använda `return` på samma sätt som vi använde `getLine`:
+
+main'' = do
+ putStrLn "Jag kommer eka två rader!"
+ result <- handling
+ putStrLn result
+ putStrLn "Tack och hej leverpastej!"
+
+-- Typen `IO` är ett exempel på en monad. Sättet Haskell utnyttjar monader på är
+-- anledningen till hur språket kan bibehålla sin renhet. En funktion vilken
+-- interagerar med omvärlden (alltså gör IO) blir markerad med `IO` i sin
+-- typsignatur. Detta låter oss enkelt upptäcka vilka funktioner som är "rena"
+-- (inte interagerar med omvärlden eller är tillståndsoberoende) and vilka
+-- funktioner som inte är det.
+
+-- Detta är ett mäktigt särdrag eftersom det är enkelt att köra rena funktioner
+-- sammanlöpande; Samtidig programmering är enkel att göra i Haskell.
+
+----------------------------------------------------
+-- 9. Haskell REPL (kodtolk)
+----------------------------------------------------
+
+-- Efter installation av GHC kan vi starta tolken genom att skriva `ghci`.
+-- Nu kan du mata in Haskellkod direkt i den. Nya värden måste introduceras med
+-- `let` bindning:
+
+let foo = 5
+
+-- Du kan även se typen av namnbindningen med `:t`
+
+> :t foo
+foo :: Integer
+
+-- Operatorer, som `+`, `:` och `$` är funktioner. Deras typ kan inspekteras
+-- genom att skriva operatorn mellan parenteser:
+
+> :t (:)
+(:) :: a -> [a] -> [a]
+
+-- Du kan få ytterliggare information om något namn genom att använda `:i`
+
+> :i (+)
+class Num a where
+ (+) :: a -> a -> a
+ ...
+ -- Defined in ‘GHC.Num’
+infixl 6 +
+
+-- Du kan även köra alla handlingar av typen `IO ()` direkt i tolken
+
+> sägHej
+Vad är ditt namn?
+Kompis!
+Hello, Kompis!
+
+```
+
+Det finns mycket mer att upptäcka med Haskell, inklusive typklasser och monader.
+Vilka är de stora idéerna som gör Haskell till det roliga programmeringsspråket
+det är. Jag lämar dig med ett sista exempel; En implementation av quicksort:
+
+```haskell
+qsort [] = []
+qsort (p:xs) = qsort mindre ++ [p] ++ qsort större
+ where mindre = filter (< p) xs
+ större = filter (>= p) xs
+```
+
+Det finns två populära sätt att installera Haskell på: Den traditionella [Cabal sättet](http://www.haskell.org/platform/), eller det nyare [Stack sättet](https://www.stackage.org/install).
+
+Du kan finna vänligare och/eller djupare introduktioner till Haskell på engelska
+från:
+[Learn you a Haskell](http://learnyouahaskell.com/),
+[Happy Learn Haskell Tutorial](http://www.happylearnhaskelltutorial.com/) eller
+[Real World Haskell](http://book.realworldhaskell.org/).
diff --git a/sv-se/nix-sv.html.markdown b/sv-se/nix-sv.html.markdown
new file mode 100644
index 00000000..15d9456b
--- /dev/null
+++ b/sv-se/nix-sv.html.markdown
@@ -0,0 +1,368 @@
+---
+language: nix
+filename: learn-sv.nix
+contributors:
+ - ["Chris Martin", "http://chris-martin.org/"]
+translators:
+ - ["Edward Tjörnhammar", "http://edwtjo.me"]
+lang: sv-se
+---
+
+Nix är ett enkelt funktionelt språk utvecklat för
+[Nix pakethanteraren](https://nixos.org/nix/) och
+[NixOS](https://nixos.org/) linuxdistributionen.
+
+Du kan utvärdera Nix uttryck genom att använda
+[nix-instantiate](https://nixos.org/nix/manual/#sec-nix-instantiate)
+eller [`nix-repl`](https://github.com/edolstra/nix-repl).
+
+```
+with builtins; [
+
+ # Kommentarer
+ #=========================================
+
+ # Inlinekommentarer ser ut såhär.
+
+ /* Flerradskommentarer ser ut
+ såhär. */
+
+
+ # Booleaner
+ #=========================================
+
+ (true && false) # Och
+ #=> false
+
+ (true || false) # Eller
+ #=> true
+
+ (if 3 < 4 then "a" else "b") # Villkorlig
+ #=> "a"
+
+
+ # Heltal
+ #=========================================
+
+ # Heltal är den enda numeriska typen.
+
+ 1 0 42 (-3) # Några heltal
+
+ (4 + 6 + 12 - 2) # Addition
+ #=> 20
+
+ (7 / 2) # Division
+ #=> 3
+
+
+ # Strängar
+ #=========================================
+
+ "Stränglitteraler omgärdas av raka citationstecken."
+
+ "
+ Stränglitteraler kan sträcka sig
+ över flera rader.
+ "
+
+ ''
+ Detta kallas för en indenterad strängliteral, omgärdad av dubbla apostrofer
+ Den plockar intelligent bort ledande blanktecken.
+ ''
+
+ ''
+ a
+ b
+ ''
+ #=> "a\n b"
+
+ ("ab" + "cd") # Strängkonkatenering
+ #=> "abcd"
+
+ # Antikvotering låter dig bädda in språkvärden i strängar.
+ ("Din hemkatalog är ${getEnv "HOME"}")
+ #=> "Din hemkatalog är /home/alice"
+
+
+ # Sökvägar
+ #=========================================
+
+ # Nix har en primitiv, inbyggd, typ för sökvägar.
+ /tmp/tutorials/learn.nix
+
+ # Relativa sökvägar förenas med sökvägen till dess definerande fils sökväg
+ # vid tolkningstillfället för att skapa dess absoluta sökväg.
+
+ tutorials/learn.nix
+ #=> /the-base-path/tutorials/learn.nix
+
+ # En sökväg måste innehålla åtminstonde ett snedstreck, så en relativ sökväg
+ # till en fil i samma katalog måste ges ett "./" prefix
+
+ ./learn.nix
+ #=> /the-base-path/learn.nix
+
+ # Divisionsoperatorn / måste omges av blanksteg om man vill att det skall
+ # tolkas som heltalsdivision
+
+ 7/2 # Detta är en sökväg
+ (7 / 2) # Detta är heltalsdivision
+
+
+ # Importer
+ #=========================================
+
+ # En nix fil innehåller ett enstaka topnivåuttryck utan fria variabler.
+ # Ett importuttryck evalueras till värdet på filen som den importerar.
+ (import /tmp/foo.nix)
+
+ # Importer kan också specificeras med hjälp av strängar.
+ (import "/tmp/foo.nix")
+
+ # Importsökvägar måste vara absoluta. Sökvägslitteraler härleds vid
+ # tolkningstillfället så följande är ok.
+ (import ./foo.nix)
+
+ # Men detta är inte något som sker med strängar.
+ (import "./foo.nix")
+ #=> error: string ‘foo.nix’ doesn't represent an absolute path
+
+
+ # Let
+ #=========================================
+
+ # `let` block tillåter oss att binda värden till namn.
+ (let x = "a"; in
+ x + x + x)
+ #=> "aaa"
+
+ # Bindingar kan referera till varandra och deras ordning sinsemellan spelar
+ # ingen roll.
+ (let y = x + "b";
+ x = "a"; in
+ y + "c")
+ #=> "abc"
+
+ # Innre bindningar skuggar utanpåliggande bindingar.
+ (let a = 1; in
+ let a = 2; in
+ a)
+ #=> 2
+
+
+ # Funktioner
+ #=========================================
+
+ (n: n + 1) # En lambdafunktion som lägger till 1
+
+ ((n: n + 1) 5) # Samma funktion applicerad på 5
+ #=> 6
+
+ # Det finns ingen syntax för direkt namngivna funktioner, istället binder man
+ # dessa med `let` block som andra värden.
+ (let succ = (n: n + 1); in succ 5)
+ #=> 6
+
+ # En funktion är en lambda med en parameter. Flera parameterar kan ges med
+ # hjälp av currying.
+ ((x: y: x + "-" + y) "a" "b")
+ #=> "a-b"
+
+ # Vi kan också ha namngivna funktionsparametrar, vilket vi kommer komma till
+ # senare, efter att vi introducerat attributset.
+
+ # Listor
+ #=========================================
+
+ # Listor noteras med hakparenteser.
+
+ (length [1 2 3 "x"])
+ #=> 4
+
+ ([1 2 3] ++ [4 5])
+ #=> [1 2 3 4 5]
+
+ (concatLists [[1 2] [3 4] [5]])
+ #=> [1 2 3 4 5]
+
+ (head [1 2 3])
+ #=> 1
+ (tail [1 2 3])
+ #=> [2 3]
+
+ (elemAt ["a" "b" "c" "d"] 2)
+ #=> "c"
+
+ (elem 2 [1 2 3])
+ #=> true
+ (elem 5 [1 2 3])
+ #=> false
+
+ (filter (n: n < 3) [1 2 3 4])
+ #=> [ 1 2 ]
+
+
+ # Mängder
+ #=========================================
+
+ # Ett attributset är en oordnad mappning av strängnycklar och värden.
+ { foo = [1 2]; bar = "x"; }
+
+ # Punktoperatorn . väljer ett värde från attributset:et
+ { a = 1; b = 2; }.a
+ #=> 1
+
+ # Frågeoperatorn ? testar om en nyckel är närvarande i ett attributset
+ ({ a = 1; b = 2; } ? a)
+ #=> true
+ ({ a = 1; b = 2; } ? c)
+ #=> false
+
+ # Snedstrecksoperatorn // slår ihop två attributset:ar.
+ ({ a = 1; } // { b = 2; })
+ #=> { a = 1; b = 2; }
+
+ # Värden på höger skriver över värden till vänster.
+ ({ a = 1; b = 2; } // { a = 3; c = 4; })
+ #=> { a = 3; b = 2; c = 4; }
+
+ # Recursionsnyckelordet rec noterar ett rekursivt attributset (en fixpunkt)
+ # i vilket attributen kan referera till varandra.
+ (let a = 1; in { a = 2; b = a; }.b)
+ #=> 1
+ (let a = 1; in rec { a = 2; b = a; }.b)
+ #=> 2
+
+ # Nästlade attributset:ar kan definieras bit för bit.
+ {
+ a.b = 1;
+ a.c.d = 2;
+ a.c.e = 3;
+ }.a.c
+ #=> { d = 2; e = 3; }
+
+ # Ett attributsets barn kan inte tilldelas på detta vis om attributsetet
+ # självt blivit direkt tilldelat.
+ {
+ a = { b = 1; };
+ a.c = 2;
+ }
+ #=> error: attribute ‘a’ already defined
+
+
+ # Bindningsintroduktion, `with`
+ #=========================================
+
+ # Det attributset vilket återfinns i ett `with` uttryck kommer få sina
+ # värdebindningar introducerade i efterkommande uttryck.
+ (with { a = 1; b = 2; };
+ a + b)
+ # => 3
+
+ # Innre bindningar skuggar yttre bindningar.
+ (with { a = 1; b = 2; };
+ (with { a = 5; };
+ a + b))
+ #=> 7
+
+ # Första raden av detta exempel börjar med "with builtins;" eftersom builtins
+ # är ett attributset innehållande alla inbyggda hjälpfunktioner såsom
+ # (length, head, tail, filter, etc.). Detta sparar oss från att hela tiden
+ # referera in i det attributset:et , alltså du kan använda bara "length"
+ # istället för "builtins.length".
+
+
+ # Attributsetmönster
+ #=========================================
+
+ # Attributset är användbara när vi skall skicka med flera värden till en
+ # funktion.
+ (args: args.x + "-" + args.y) { x = "a"; y = "b"; }
+ #=> "a-b"
+
+ # Man kan använda attributsetmönster för ökad tydlighet.
+ ({x, y}: x + "-" + y) { x = "a"; y = "b"; }
+ #=> "a-b"
+
+ # Attributmönster misslyckas dock om det medskickade attributmönstret
+ # innehåller extra nycklar.
+ ({x, y}: x + "-" + y) { x = "a"; y = "b"; z = "c"; }
+ #=> error: anonymous function called with unexpected argument ‘z’
+
+ # Genom att lägga till ", ..." kan vi ignorera ytterliggare nycklar.
+ ({x, y, ...}: x + "-" + y) { x = "a"; y = "b"; z = "c"; }
+ #=> "a-b"
+
+
+ # Felmeddelanden
+ #=========================================
+
+ # `throw` gör att programtolken gör abort med dess tillhörande felmeddelande
+ causes evaluation to abort with an error message.
+ (2 + (throw "foo"))
+ #=> error: foo
+
+ # `tryEval` fångar kastade fel `throw`.
+ (tryEval 42)
+ #=> { success = true; value = 42; }
+ (tryEval (2 + (throw "foo")))
+ #=> { success = false; value = false; }
+
+ # `abort` fungerar som `throw`, men är kritiskt och kan inte fångas.
+ (tryEval (abort "foo"))
+ #=> error: evaluation aborted with the following error message: ‘foo’
+
+ # `assert` utvärderas till det givna värdet om dess predikat är sant.
+ # annars skickar den ett fångbart fel.
+ (assert 1 < 2; 42)
+ #=> 42
+ (assert 1 > 2; 42)
+ #=> error: assertion failed at (string):1:1
+ (tryEval (assert 1 > 2; 42))
+ #=> { success = false; value = false; }
+
+
+ # Orenhet
+ #=========================================
+
+ # Eftersom repeterbarhet för byggen är en kritisk egenskap för
+ # Nix-pakethanteraren betonas funktionell renhet i Nix-programmeringsspråket.
+ # Men med det sagt existerar det källor till orenhet
+
+ # Man kan referera till miljövariabler.
+ (getEnv "HOME")
+ #=> "/home/alice"
+
+ # `trace` funktionen används för att debugga. Den skriver ut första argumentet
+ # till stderr och reduceras samtidigt till det andra argumentet.
+ (trace 1 2)
+ #=> trace: 1
+ #=> 2
+
+ # Man kan skriva filer till Nix-store, lagringsplatsen för alla Nix-uttryck.
+ # Även om detta är orent beteende är det hyfsat säkert eftersom filens
+ # lagringsplats är härledd från dess innehåll och beroenden. Man kan läsa
+ # filer från precis överallt. I nedanstående exempel skriver vi en fil till
+ # Nix-store och sedan läser tillbaka den.
+
+ (let filename = toFile "foo.txt" "hello!"; in
+ [filename (builtins.readFile filename)])
+ #=> [ "/nix/store/ayh05aay2anx135prqp0cy34h891247x-foo.txt" "hello!" ]
+
+ # Vi kan också ladda ned filer till Nix-store.
+ (fetchurl "https://example.com/package-1.2.3.tgz")
+ #=> "/nix/store/2drvlh8r57f19s9il42zg89rdr33m2rm-package-1.2.3.tgz"
+
+]
+```
+
+### Vidare Läsning (eng)
+
+* [Nix Manual - Nix expression language]
+ (https://nixos.org/nix/manual/#ch-expression-language)
+
+* [James Fisher - Nix by example - Part 1: The Nix expression language]
+ (https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55)
+
+* [Susan Potter - Nix Cookbook - Nix By Example]
+ (http://funops.co/nix-cookbook/nix-by-example/)
diff --git a/swift.html.markdown b/swift.html.markdown
index b6554dc6..3981a4ce 100644
--- a/swift.html.markdown
+++ b/swift.html.markdown
@@ -8,22 +8,26 @@ contributors:
- ["Clayton Walker", "https://github.com/cwalk"]
- ["Fernando Valverde", "http://visualcosita.xyz"]
- ["Alexey Nazaroff", "https://github.com/rogaven"]
+ - ["@Samasaur1", "https://github.com/Samasaur1"]
filename: learnswift.swift
---
Swift is a programming language for iOS and OS X development created by Apple. Designed to coexist with Objective-C and to be more resilient against erroneous code, Swift was introduced in 2014 at Apple's developer conference WWDC. It is built with the LLVM compiler included in Xcode 6+.
-The official [Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329) book from Apple is now available via iBooks.
+The official _[Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329)_ book from Apple is now available via iBooks. It goes into much more detail than this guide, and if you have the time and patience to read it, it's recommended. Some of these examples are from that book.
-See also Apple's [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/), which has a complete tutorial on Swift.
+Another great reference is _About Swift_ on Swift's [website](https://docs.swift.org/swift-book/).
```swift
// import a module
-import UIKit
+import Foundation
-//
-// MARK: Basics
-//
+// Single-line comments are prefixed with //
+// Multi-line comments start with /* and end with */
+/* Nested multiline comments
+ /* ARE */
+ allowed
+ */
// Xcode supports landmarks to annotate your code and lists them in the jump bar
// MARK: Section mark
@@ -31,215 +35,383 @@ import UIKit
// TODO: Do something soon
// FIXME: Fix this code
-// In Swift 2, println and print were combined into one print method. Print automatically appends a new line.
-print("Hello, world") // println is now print
-print("Hello, world", terminator: "") // printing without appending a newline
+//MARK: Hello, World
+// From Swift 3 on, to print, just use the `print` method.
+// It automatically appends a new line.
+print("Hello, world")
+
+//
+// MARK: - Variables
+//
+
+
+//Use `let` to declare a constant and `var` to declare a variable.
+let theAnswer = 42
+var theQuestion = "What is the Answer?"
+theQuestion = "How many roads must a man walk down?"
+theQuestion = "What is six by nine?"
+// Atttempting to reassign a constant throws a compile-time error
+//theAnswer = 54
+
+// Both variables and constants can be declared before they are given a value,
+// but must be given a value before they are used
+let someConstant: Int
+var someVariable: String
+// These lines will throw errors:
+//print(someConstant)
+//print(someVariable)
+someConstant = 0
+someVariable = "0"
+// These lines are now valid:
+print(someConstant)
+print(someVariable)
+
+// As you can see above, variable types are automatically inferred.
+// To explicitly declare the type, write it after the variable name,
+// separated by a colon.
+let aString: String = "A string"
+let aDouble: Double = 0
+
+// Values are never implicitly converted to another type.
+// Explicitly make instances of the desired type.
+let stringWithDouble = aString + String(aDouble)
+let intFromDouble = Int(aDouble)
+
+// For strings, use string interpolation
+let descriptionString = "The value of aDouble is \(aDouble)"
+// You can put any expression inside string interpolation.
+let equation = "Six by nine is \(6 * 9), not 42!"
+// To avoid escaping double quotes and backslashes, change the string delimiter
+let explanationString = #"The string I used was "The value of aDouble is \(aDouble)" and the result was \#(descriptionString)"#
+// You can put as many number signs as you want before the opening quote,
+// just match them at the ending quote. They also change the escape character
+// to a backslash followed by the same number of number signs.
+
+let multiLineString = """
+ This is a multi-line string.
+ It's called that because it takes up multiple lines (wow!)
+ Any indentation beyond the closing quotation marks is kept, the rest is discarded.
+ You can include " or "" in multi-line strings because the delimiter is three "s.
+ """
+
+// Arrays
+let shoppingList = ["catfish", "water", "tulips",] //commas are allowed after the last element
+let secondElement = shoppingList[1] // Arrays are 0-indexed
+
+// Arrays declared with let are immutable; the following line throws a compile-time error
+//shoppingList[2] = "mango"
+
+// Arrays are structs (more on that later), so this creates a copy instead of referencing the same object
+var mutableShoppingList = shoppingList
+mutableShoppingList[2] = "mango"
+
+// == is equality
+shoppingList == mutableShoppingList // false
+
+// Dictionaries declared with let are also immutable
+var occupations = [
+ "Malcolm": "Captain",
+ "Kaylee": "Mechanic"
+]
+occupations["Jayne"] = "Public Relations"
+// Dictionaries are also structs, so this also creates a copy
+let immutableOccupations = occupations
-// variables (var) value can change after being set
-// constants (let) value can NOT be changed after being set
+immutableOccupations == occupations // true
-var myVariable = 42
+// Arrays and dictionaries both automatically grow as you add elements
+mutableShoppingList.append("blue paint")
+occupations["Tim"] = "CEO"
+
+// They can both be set to empty
+mutableShoppingList = []
+occupations = [:]
+
+let emptyArray = [String]()
+let emptyArray2 = Array<String>() // same as above
+// [T] is shorthand for Array<T>
+let emptyArray3: [String] = [] // Declaring the type explicitly allows you to set it to an empty array
+let emptyArray4: Array<String> = [] // same as above
+
+// [Key: Value] is shorthand for Dictionary<Key, Value>
+let emptyDictionary = [String: Double]()
+let emptyDictionary2 = Dictionary<String, Double>() // same as above
+var emptyMutableDictionary: [String: Double] = [:]
+var explicitEmptyMutableDictionary: Dictionary<String, Double> = [:] // same as above
+
+// MARK: Other variables
let øπΩ = "value" // unicode variable names
-let π = 3.1415926
-let convenience = "keyword" // contextual variable name
-let weak = "keyword"; let override = "another keyword" // statements can be separated by a semi-colon
-let `class` = "keyword" // backticks allow keywords to be used as variable names
-let explicitDouble: Double = 70
-let intValue = 0007 // 7
-let largeIntValue = 77_000 // 77000
-let label = "some text " + String(myVariable) // String construction
-let piText = "Pi = \(π), Pi 2 = \(π * 2)" // String interpolation
-
-// Build Specific values
-// uses -D build configuration
-#if false
- print("Not printed")
- let buildValue = 3
-#else
- let buildValue = 7
-#endif
-print("Build value: \(buildValue)") // Build value: 7
+let 🤯 = "wow" // emoji variable names
+
+// Keywords can be used as variable names
+// These are contextual keywords that wouldn't be used now, so are allowed
+let convenience = "keyword"
+let weak = "another keyword"
+let override = "another keyword"
+
+// Using backticks allows keywords to be used as variable names even if they wouldn't be allowed normally
+let `class` = "keyword"
+
+// MARK: - Optionals
/*
-Optionals are a Swift language feature that either contains a value,
-or contains nil (no value) to indicate that a value is missing.
-A question mark (?) after the type marks the value as optional.
+ Optionals are a Swift language feature that either contains a value,
+ or contains nil (no value) to indicate that a value is missing.
+ Nil is roughly equivalent to `null` in other languages.
+ A question mark (?) after the type marks the value as optional of that type.
+
+ If a type is not optional, it is guaranteed to have a value.
+
+ Because Swift requires every property to have a type, even nil must be
+ explicitly stored as an Optional value.
-Because Swift requires every property to have a value, even nil must be
-explicitly stored as an Optional value.
+ Optional<T> is an enum, with the cases .none (nil) and .some(T) (the value)
+ */
-Optional<T> is an enum.
-*/
var someOptionalString: String? = "optional" // Can be nil
-// same as above, but ? is a postfix operator (syntax candy)
-var someOptionalString2: Optional<String> = "optional"
+// T? is shorthand for Optional<T> — ? is a postfix operator (syntax candy)
+let someOptionalString2: Optional<String> = nil
+let someOptionalString3 = String?.some("optional") // same as the first one
+let someOptionalString4 = String?.none //nil
+
+/*
+ To access the value of an optional that has a value, use the postfix
+ operator !, which force-unwraps it. Force-unwrapping is like saying, "I
+ know that this optional definitely has a value, please give it to me."
+
+ Trying to use ! to access a non-existent optional value triggers a
+ runtime error. Always make sure that an optional contains a non-nil
+ value before using ! to force-unwrap its value.
+ */
if someOptionalString != nil {
// I am not nil
if someOptionalString!.hasPrefix("opt") {
print("has the prefix")
}
-
- let empty = someOptionalString?.isEmpty
}
-someOptionalString = nil
-/*
-Trying to use ! to access a non-existent optional value triggers a runtime
-error. Always make sure that an optional contains a non-nil value before
-using ! to force-unwrap its value.
-*/
-
-// implicitly unwrapped optional
-var unwrappedString: String! = "Value is expected."
-// same as above, but ! is a postfix operator (more syntax candy)
-var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Value is expected."
-
-// If let structure -
-// If let is a special structure in Swift that allows you to check if an Optional rhs holds a value, and in case it does - unwraps and assigns it to the lhs.
-if let someOptionalStringConstant = someOptionalString {
+// Swift supports "optional chaining," which means that you can call functions
+// or get properties of optional values and they are optionals of the appropriate type.
+// You can even do this multiple times, hence the name "chaining."
+
+let empty = someOptionalString?.isEmpty // Bool?
+
+// if-let structure -
+// if-let is a special structure in Swift that allows you to check
+// if an Optional rhs holds a value, and if it does unwrap
+// and assign it to the lhs.
+if let someNonOptionalStringConstant = someOptionalString {
// has `Some` value, non-nil
- if !someOptionalStringConstant.hasPrefix("ok") {
+ // someOptionalStringConstant is of type String, not type String?
+ if !someNonOptionalStringConstant.hasPrefix("ok") {
// does not have the prefix
}
}
-// Swift has support for storing a value of any type.
-// For that purposes there is two keywords: `Any` and `AnyObject`
-// `AnyObject` == `id` from Objective-C
-// `Any` – also works with any scalar values (Class, Int, struct, etc.)
-var anyVar: Any = 7
-anyVar = "Changed value to a string, not good practice, but possible."
-let anyObjectVar: AnyObject = Int(1) as NSNumber
-
-/*
- Comment here
-
- /*
- Nested comments are also supported
- */
-*/
+//if-var is allowed too!
+if var someNonOptionalString = someOptionalString {
+ someNonOptionalString = "Non optional AND mutable"
+ print(someNonOptionalString)
+}
-//
-// MARK: Collections
-//
+// You can bind multiple optional values in one if-let statement.
+// If any of the bound values are nil, the if statement does not execute.
+if let first = someOptionalString, let second = someOptionalString2,
+ let third = someOptionalString3, let fourth = someOptionalString4 {
+ print("\(first), \(second), \(third), and \(fourth) are all not nil")
+}
-/*
-Array and Dictionary types are structs. So `let` and `var` also indicate
-that they are mutable (var) or immutable (let) when declaring these types.
-*/
-
-// Array
-var shoppingList = ["catfish", "water", "lemons"]
-shoppingList[1] = "bottle of water"
-let emptyArray = [String]() // let == immutable
-let emptyArray2 = Array<String>() // same as above
-var emptyMutableArray = [String]() // var == mutable
-var explicitEmptyMutableStringArray: [String] = [] // same as above
+//if-let supports "," (comma) clauses, which can be used to
+// enforce conditions on newly-bound optional values.
+// Both the assignment and the "," clause must pass.
+let someNumber: Int? = 7
+if let num = someNumber, num > 3 {
+ print("num is not nil and is greater than 3")
+}
+// Implicitly unwrapped optional — An optional value that doesn't need to be unwrapped
+let unwrappedString: String! = "Value is expected."
-// Dictionary
-var occupations = [
- "Malcolm": "Captain",
- "kaylee": "Mechanic"
-]
-occupations["Jayne"] = "Public Relations"
-let emptyDictionary = [String: Float]() // let == immutable
-let emptyDictionary2 = Dictionary<String, Float>() // same as above
-var emptyMutableDictionary = [String: Float]() // var == mutable
-var explicitEmptyMutableDictionary: [String: Float] = [:] // same as above
+// Here's the difference:
+let forcedString = someOptionalString! // requires an exclamation mark
+let implicitString = unwrappedString // doesn't require an exclamation mark
+/*
+ You can think of an implicitly unwrapped optional as giving permission
+ for the optional to be unwrapped automatically whenever it's used.
+ Rather than placing an exclamation mark after the optional's name each time you use it,
+ you place an exclamation mark after the optional's type when you declare it.
+ */
-//
-// MARK: Control Flow
-//
+// Otherwise, you can treat an implicitly unwrapped optional the same way the you treat a normal optional
+// (i.e., if-let, != nil, etc.)
-// Condition statements support "," (comma) clauses, which can be used
-// to help provide conditions on optional values.
-// Both the assignment and the "," clause must pass.
-let someNumber = Optional<Int>(7)
-if let num = someNumber, num > 3 {
- print("num is greater than 3")
-}
+// Pre-Swift 5, T! was shorthand for ImplicitlyUnwrappedOptional<T>
+// Swift 5 and later, using ImplicitlyUnwrappedOptional throws a compile-time error.
+//var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Value is expected." //error
-// for loop (array)
-let myArray = [1, 1, 2, 3, 5]
-for value in myArray {
- if value == 1 {
- print("One!")
- } else {
- print("Not one!")
- }
-}
+// The nil-coalescing operator ?? unwraps an optional if it contains a non-nil value, or returns a default value.
+someOptionalString = nil
+let someString = someOptionalString ?? "abc"
+print(someString) // abc
+// a ?? b is shorthand for a != nil ? a! : b
-// for loop (dictionary)
-var dict = ["one": 1, "two": 2]
-for (key, value) in dict {
- print("\(key): \(value)")
-}
+// MARK: - Control Flow
-// for loop (range)
-for i in -1...shoppingList.count {
- print(i)
-}
-shoppingList[1...2] = ["steak", "peacons"]
-// use ..< to exclude the last number
+let condition = true
+if condition { print("condition is true") } // can't omit the braces
-// while loop
-var i = 1
-while i < 1000 {
- i *= 2
+if theAnswer > 50 {
+ print("theAnswer > 50")
+} else if condition {
+ print("condition is true")
+} else {
+ print("Neither are true")
}
-// repeat-while loop
-repeat {
- print("hello")
-} while 1 == 2
+// The condition in an `if` statement must be a `Bool`, so the following code is an error, not an implicit comparison to zero
+//if 5 {
+// print("5 is not zero")
+//}
// Switch
+// Must be exhaustive
+// Does not implicitly fall through, use the fallthrough keyword
// Very powerful, think `if` statements with syntax candy
// They support String, object instances, and primitives (Int, Double, etc)
let vegetable = "red pepper"
+let vegetableComment: String
switch vegetable {
case "celery":
- let vegetableComment = "Add some raisins and make ants on a log."
-case "cucumber", "watercress":
- let vegetableComment = "That would make a good tea sandwich."
+ vegetableComment = "Add some raisins and make ants on a log."
+case "cucumber", "watercress": // match multiple values
+ vegetableComment = "That would make a good tea sandwich."
case let localScopeValue where localScopeValue.hasSuffix("pepper"):
- let vegetableComment = "Is it a spicy \(localScopeValue)?"
+ vegetableComment = "Is it a spicy \(localScopeValue)?"
default: // required (in order to cover all possible input)
- let vegetableComment = "Everything tastes good in soup."
+ vegetableComment = "Everything tastes good in soup."
+}
+print(vegetableComment)
+
+// You use the `for-in` loop to iterate over a sequence, such as an array, dictionary, range, etc.
+for element in shoppingList {
+ print(element) // shoppingList is of type `[String]`, so element is of type `String`
+}
+//Iterating through a dictionary does not guarantee any specific order
+for (person, job) in immutableOccupations {
+ print("\(person)'s job is \(job)")
+}
+for i in 1...5 {
+ print(i, terminator: " ") // Prints "1 2 3 4 5"
+}
+for i in 0..<5 {
+ print(i, terminator: " ") // Prints "0 1 2 3 4"
+}
+//for index in range can replace a C-style for loop:
+// for (int i = 0; i < 10; i++) {
+// //code
+// }
+//becomes:
+// for i in 0..<10 {
+// //code
+// }
+//To step by more than one, use the stride(from:to:by:) or stride(from:through:by) functions
+//`for i in stride(from: 0, to: 10, by: 2)` is the same as `for (int i = 0; i < 10; i += 2)`
+//`for i in stride(from: 0, through: 10, by: 2)` is the same as `for (int i = 0; i <= 10; i += 2)
+
+// while loops are just like most languages
+var i = 0
+while i < 5 {
+ i += Bool.random() ? 1 : 0
+ print(i)
}
-//
-// MARK: Functions
-//
+// This is like a do-while loop in other languages — the body of the loop executes a minimum of once
+repeat {
+ i -= 1
+ i += Int.random(in: 0...3)
+} while i < 5
-// Functions are a first-class type, meaning they can be nested
-// in functions and can be passed around
+// The continue statement continues executing a loop at the next iteration
+// The break statement ends a swift or loop immediately
-// Function with Swift header docs (format as Swift-modified Markdown syntax)
+// MARK: - Functions
-/**
-A greet operation
+// Functions are a first-class type, meaning they can be nested in functions and can be passed around.
-- A bullet in docs
-- Another bullet in the docs
+// Function with Swift header docs (format as Swift-modified Markdown syntax)
-- Parameter name : A name
-- Parameter day : A day
-- Returns : A string containing the name and day value.
-*/
+/// A greet operation.
+///
+/// - Parameters:
+/// - name: A name.
+/// - day: A day.
+/// - Returns: A string containing the name and day value.
func greet(name: String, day: String) -> String {
return "Hello \(name), today is \(day)."
}
greet(name: "Bob", day: "Tuesday")
-// similar to above except for the function parameter behaviors
-func greet2(name: String, externalParamName localParamName: String) -> String {
- return "Hello \(name), the day is \(localParamName)"
+// Ideally, function names and parameter labels combine to make function calls similar to sentences.
+func sayHello(to name: String, onDay day: String) -> String {
+ return "Hello \(name), the day is \(day)"
+}
+sayHello(to: "John", onDay: "Sunday")
+
+//Functions that don't return anything can omit the return arrow; they don't need to say that they return Void (although they can).
+func helloWorld() {
+ print("Hello, World!")
+}
+
+// Argument labels can be blank
+func say(_ message: String) {
+ print(#"I say "\#(message)""#)
+}
+say("Hello")
+
+// Default parameters can be omitted when calling the function.
+func printParameters(requiredParameter r: Int, optionalParameter o: Int = 10) {
+ print("The required parameter was \(r) and the optional parameter was \(o)")
+}
+printParameters(requiredParameter: 3)
+printParameters(requiredParameter: 3, optionalParameter: 6)
+
+// Variadic args — only one set per function.
+func setup(numbers: Int...) {
+ // it's an array
+ let _ = numbers[0]
+ let _ = numbers.count
+}
+
+// pass by ref
+func swapTwoInts(a: inout Int, b: inout Int) {
+ let tempA = a
+ a = b
+ b = tempA
+}
+var someIntA = 7
+var someIntB = 3
+swapTwoInts(a: &someIntA, b: &someIntB) //must be called with an & before the variable name.
+print(someIntB) // 7
+
+type(of: greet) // (String, String) -> String
+type(of: helloWorld) // () -> Void
+
+// Passing and returning functions
+func makeIncrementer() -> ((Int) -> Int) {
+ func addOne(number: Int) -> Int {
+ return 1 + number
+ }
+ return addOne
+}
+var increment = makeIncrementer()
+increment(7)
+
+func performFunction(_ function: (String, String) -> String, on string1: String, and string2: String) {
+ let result = function(string1, string2)
+ print("The result of calling the function on \(string1) and \(string2) was \(result)")
}
-greet2(name: "John", externalParamName: "Sunday")
// Function that returns multiple items in a tuple
func getGasPrices() -> (Double, Double, Double) {
@@ -266,46 +438,24 @@ print("Highest gas price: \(pricesTuple2.highestPrice)")
func testGuard() {
// guards provide early exits or breaks, placing the error handler code near the conditions.
// it places variables it declares in the same scope as the guard statement.
+ // They make it easier to avoid the "pyramid of doom"
guard let aNumber = Optional<Int>(7) else {
- return
+ return // guard statements MUST exit the scope that they are in.
+ // They generally use `return` or `throw`.
}
print("number is \(aNumber)")
}
testGuard()
-// Variadic Args
-func setup(numbers: Int...) {
- // its an array
- let _ = numbers[0]
- let _ = numbers.count
-}
+// Note that the print function is declared like so:
+// func print(_ input: Any..., separator: String = " ", terminator: String = "\n")
+// To print without a newline:
+print("No newline", terminator: "")
+print("!")
-// Passing and returning functions
-func makeIncrementer() -> ((Int) -> Int) {
- func addOne(number: Int) -> Int {
- return 1 + number
- }
- return addOne
-}
-var increment = makeIncrementer()
-increment(7)
+// MARK: - Closures
-// pass by ref
-func swapTwoInts(a: inout Int, b: inout Int) {
- let tempA = a
- a = b
- b = tempA
-}
-var someIntA = 7
-var someIntB = 3
-swapTwoInts(a: &someIntA, b: &someIntB)
-print(someIntB) // 7
-
-
-//
-// MARK: Closures
-//
var numbers = [1, 2, 6]
// Functions are special case closures ({})
@@ -331,85 +481,157 @@ numbers = numbers.sorted { $0 > $1 }
print(numbers) // [18, 6, 3]
-//
-// MARK: Structures
-//
+// MARK: - Enums
-// Structures and classes have very similar capabilities
-struct NamesTable {
- let names: [String]
+// Enums can optionally be of a specific type or on their own.
+// They can contain methods like classes.
- // Custom subscript
- subscript(index: Int) -> String {
- return names[index]
+enum Suit {
+ case spades, hearts, diamonds, clubs
+ var icon: Character {
+ switch self {
+ case .spades:
+ return "♤"
+ case .hearts:
+ return "♡"
+ case .diamonds:
+ return "♢"
+ case .clubs:
+ return "♧"
+ }
}
}
-// Structures have an auto-generated (implicit) designated initializer
-let namesTable = NamesTable(names: ["Me", "Them"])
-let name = namesTable[1]
-print("Name is \(name)") // Name is Them
+// Enum values allow short hand syntax, no need to type the enum type
+// when the variable is explicitly declared
+var suitValue: Suit = .hearts
+
+// Conforming to the CaseIterable protocol automatically synthesizes the allCases property,
+// which contains all the values. It works on enums without associated values or @available attributes.
+enum Rank: CaseIterable {
+ case ace
+ case two, three, four, five, six, seven, eight, nine, ten
+ case jack, queen, king
+ var icon: String {
+ switch self {
+ case .ace:
+ return "A"
+ case .two:
+ return "2"
+ case .three:
+ return "3"
+ case .four:
+ return "4"
+ case .five:
+ return "5"
+ case .six:
+ return "6"
+ case .seven:
+ return "7"
+ case .eight:
+ return "8"
+ case .nine:
+ return "9"
+ case .ten:
+ return "10"
+ case .jack:
+ return "J"
+ case .queen:
+ return "Q"
+ case .king:
+ return "K"
+ }
+ }
+}
-//
-// MARK: Error Handling
-//
+for suit in [Suit.clubs, .diamonds, .hearts, .spades] {
+ for rank in Rank.allCases {
+ print("\(rank.icon)\(suit.icon)")
+ }
+}
-// The `Error` protocol is used when throwing errors to catch
-enum MyError: Error {
- case BadValue(msg: String)
- case ReallyBadValue(msg: String)
+// String enums can have direct raw value assignments
+// or their raw values will be derived from the Enum field
+enum BookName: String {
+ case john
+ case luke = "Luke"
}
+print("Name: \(BookName.john.rawValue)")
-// functions marked with `throws` must be called using `try`
-func fakeFetch(value: Int) throws -> String {
- guard 7 == value else {
- throw MyError.ReallyBadValue(msg: "Some really bad value")
- }
+// Enum with associated Values
+enum Furniture {
+ // Associate with Int
+ case desk(height: Int)
+ // Associate with String and Int
+ case chair(String, Int)
- return "test"
+ func description() -> String {
+ //either placement of let is acceptable
+ switch self {
+ case .desk(let height):
+ return "Desk with \(height) cm"
+ case let .chair(brand, height):
+ return "Chair of \(brand) with \(height) cm"
+ }
+ }
}
-func testTryStuff() {
- // assumes there will be no error thrown, otherwise a runtime exception is raised
- let _ = try! fakeFetch(value: 7)
+var desk: Furniture = .desk(height: 80)
+print(desk.description()) // "Desk with 80 cm"
+var chair = Furniture.chair("Foo", 40)
+print(chair.description()) // "Chair of Foo with 40 cm"
- // if an error is thrown, then it proceeds, but if the value is nil
- // it also wraps every return value in an optional, even if its already optional
- let _ = try? fakeFetch(value: 7)
+// MARK: - Structures & Classes
- do {
- // normal try operation that provides error handling via `catch` block
- try fakeFetch(value: 1)
- } catch MyError.BadValue(let msg) {
- print("Error message: \(msg)")
- } catch {
- // must be exhaustive
+/*
+ Structures and classes in Swift have many things in common. Both can:
+ - Define properties to store values
+ - Define methods to provide functionality
+ - Define subscripts to provide access to their values using subscript syntax
+ - Define initializers to set up their initial state
+ - Be extended to expand their functionality beyond a default implementation
+ - Conform to protocols to provide standard functionality of a certain kind
+
+ Classes have additional capabilities that structures don't have:
+ - Inheritance enables one class to inherit the characteristics of another.
+ - Type casting enables you to check and interpret the type of a class instance at runtime.
+ - Deinitializers enable an instance of a class to free up any resources it has assigned.
+ - Reference counting allows more than one reference to a class instance.
+
+ Unless you need to use a class for one of these reasons, use a struct.
+
+ Structures are value types, while classes are reference types.
+ */
+
+// MARK: Structures
+
+struct NamesTable {
+ let names: [String]
+
+ // Custom subscript
+ subscript(index: Int) -> String {
+ return names[index]
}
}
-testTryStuff()
-//
-// MARK: Classes
-//
+// Structures have an auto-generated (implicit) designated "memberwise" initializer
+let namesTable = NamesTable(names: ["Me", "Them"])
+let name = namesTable[1]
+print("Name is \(name)") // Name is Them
-// Classes, structures and its members have three levels of access control
-// They are: internal (default), public, private
+// MARK: Classes
-public class Shape {
- public func getArea() -> Int {
+class Shape {
+ func getArea() -> Int {
return 0
}
}
-// All methods and properties of a class are public.
-// If you just need to store data in a
-// structured object, you should use a `struct`
-
-internal class Rect: Shape {
+class Rect: Shape {
var sideLength: Int = 1
// Custom getter and setter property
- private var perimeter: Int {
+ var perimeter: Int {
get {
return 4 * sideLength
}
@@ -470,6 +692,11 @@ print(mySquare.sideLength) // 4
// cast instance
let aShape = mySquare as Shape
+// downcast instance:
+// Because downcasting can fail, the result can be an optional (as?) or an implicitly unwrpped optional (as!).
+let anOptionalSquare = aShape as? Square // This will return nil if aShape is not a Square
+let aSquare = aShape as! Square // This will throw a runtime error if aShape is not a Square
+
// compare instances, not the same as == which compares objects (equal to)
if mySquare === mySquare {
print("Yep, it's mySquare")
@@ -504,104 +731,154 @@ if let circle = myEmptyCircle {
print("circle is not nil")
}
+// MARK: - Protocols
-//
-// MARK: Enums
-//
+// protocols are also known as interfaces in some other languages
-// Enums can optionally be of a specific type or on their own.
-// They can contain methods like classes.
+// `protocol`s can require that conforming types have specific
+// instance properties, instance methods, type methods,
+// operators, and subscripts.
-enum Suit {
- case Spades, Hearts, Diamonds, Clubs
- func getIcon() -> String {
- switch self {
- case .Spades: return "♤"
- case .Hearts: return "♡"
- case .Diamonds: return "♢"
- case .Clubs: return "♧"
- }
- }
+protocol ShapeGenerator {
+ var enabled: Bool { get set }
+ func buildShape() -> Shape
}
-// Enum values allow short hand syntax, no need to type the enum type
-// when the variable is explicitly declared
-var suitValue: Suit = .Hearts
+// MARK: - Other
-// String enums can have direct raw value assignments
-// or their raw values will be derived from the Enum field
-enum BookName: String {
- case John
- case Luke = "Luke"
+// MARK: Typealiases
+
+// Typealiases allow one type (or composition of types) to be referred to by another name
+typealias Integer = Int
+let myInteger: Integer = 0
+
+// MARK: = Operator
+
+// Assignment does not return a value. This means it can't be used in conditional statements,
+// and the following statement is also illegal
+// let multipleAssignment = theQuestion = "No questions asked"
+//But you can do this:
+let multipleAssignment = "No questions asked", secondConstant = "No answers given"
+
+// MARK: Ranges
+
+// The ..< and ... operators create ranges.
+
+// ... is inclusive on both ends (a "closed range") — mathematically, [0, 10]
+let _0to10 = 0...10
+// ..< is inclusive on the left, exclusive on the right (a "range") — mathematically, [0, 10)
+let singleDigitNumbers = 0..<10
+// You can omit one end (a "PartialRangeFrom") — mathematically, [0, ∞)
+let toInfinityAndBeyond = 0...
+// Or the other end (a "PartialRangeTo") — mathematically, (-∞, 0)
+let negativeInfinityToZero = ..<0
+// (a "PartialRangeThrough") — mathematically, (-∞, 0]
+let negativeInfinityThroughZero = ...0
+
+// MARK: Wildcard operator
+
+// In Swift, _ (underscore) is the wildcard operator, which allows values to be ignored
+
+// It allows functions to be declared without argument labels:
+func function(_ labelLessParameter: Int, label labeledParameter: Int, labelAndParameterName: Int) {
+ print(labelLessParameter, labeledParameter, labelAndParameterName)
}
-print("Name: \(BookName.John.rawValue)")
+function(0, label: 0, labelAndParameterName: 0)
-// Enum with associated Values
-enum Furniture {
- // Associate with Int
- case Desk(height: Int)
- // Associate with String and Int
- case Chair(String, Int)
+// You can ignore the return values of functions
+func printAndReturn(_ str: String) -> String {
+ print(str)
+ return str
+}
+let _ = printAndReturn("Some String")
- func description() -> String {
- switch self {
- case .Desk(let height):
- return "Desk with \(height) cm"
- case .Chair(let brand, let height):
- return "Chair of \(brand) with \(height) cm"
- }
- }
+// You can ignore part of a tuple and keep part of it
+func returnsTuple() -> (Int, Int) {
+ return (1, 2)
}
+let (_, two) = returnsTuple()
-var desk: Furniture = .Desk(height: 80)
-print(desk.description()) // "Desk with 80 cm"
-var chair = Furniture.Chair("Foo", 40)
-print(chair.description()) // "Chair of Foo with 40 cm"
+// You can ignore closure parameters
+let closure: (Int, Int) -> String = { someInt, _ in
+ return "\(someInt)"
+}
+closure(1, 2) // returns 1
+// You can ignore the value in a for loop
+for _ in 0..<10 {
+ // Code to execute 10 times
+}
-//
-// MARK: Protocols
-//
+// MARK: Access Control
-// `protocol`s can require that conforming types have specific
-// instance properties, instance methods, type methods,
-// operators, and subscripts.
+/*
+ Swift has five levels of access control:
+ - Open: Accessible *and subclassible* in any module that imports it.
+ - Public: Accessible in any module that imports it, subclassible in the module it is declared in.
+ - Internal: Accessible and subclassible in the module it is declared in.
+ - Fileprivate: Accessible and subclassible in the file it is declared in.
+ - Private: Accessible and subclassible in the enclosing declaration (think inner classes/structs/enums)
-protocol ShapeGenerator {
- var enabled: Bool { get set }
- func buildShape() -> Shape
+ See more here: https://docs.swift.org/swift-book/LanguageGuide/AccessControl.html
+ */
+
+// MARK: Preventing Overrides
+
+// You can add keyword `final` before a class or instance method, or a property to prevent it from being overridden
+class Shape {
+ final var finalInteger = 10
}
-// Protocols declared with @objc allow optional functions,
-// which allow you to check for conformance. These functions must be
-// marked with @objc also.
-@objc protocol TransformShape {
- @objc optional func reshape()
- @objc optional func canReshape() -> Bool
+// Prevent a class from being subclassed
+final class ViewManager {
}
-class MyShape: Rect {
- var delegate: TransformShape?
+// MARK: Conditional Compilation, Compile-Time Diagnostics, & Availability Conditions
+
+// Conditional Compilation
+#if false
+print("This code will not be compiled")
+#else
+print("This code will be compiled")
+#endif
+/*
+ Options are:
+ os() macOS, iOS, watchOS, tvOS, Linux
+ arch() i386, x86_64, arm, arm64
+ swift() >= or < followed by a version number
+ compiler() >= or < followed by a version number
+ canImport() A module name
+ targetEnvironment() simulator
+ */
+#if swift(<3)
+println()
+#endif
- func grow() {
- sideLength += 2
+// Compile-Time Diagnostics
+// You can use #warning(message) and #error(message) to have the compiler emit warnings and/or errors
+#warning("This will be a compile-time warning")
+// #error("This would be a compile-time error")
- // Place a question mark after an optional property, method, or
- // subscript to gracefully ignore a nil value and return nil
- // instead of throwing a runtime error ("optional chaining").
- if let reshape = self.delegate?.canReshape?(), reshape {
- // test for delegate then for method
- self.delegate?.reshape?()
- }
- }
+//Availability Conditions
+if #available(iOSMac 10.15, *) {
+ // macOS 10.15 is available, you can use it here
+} else {
+ // macOS 10.15 is not available, use alternate APIs
}
+// MARK: Any and AnyObject
-//
-// MARK: Other
-//
+// Swift has support for storing a value of any type.
+// For that purpose there are two keywords: `Any` and `AnyObject`
+// `AnyObject` == `id` from Objective-C
+// `Any` works with any values (class, Int, struct, etc.)
+var anyVar: Any = 7
+anyVar = "Changed value to a string, not good practice, but possible."
+let anyObjectVar: AnyObject = Int(1) as NSNumber
-// `extension`s: Add extra functionality to an already existing type
+// MARK: Extensions
+
+// Extensions allow you to add extra functionality to an already-declared type, even one that you don't have the source code for.
// Square now "conforms" to the `CustomStringConvertible` protocol
extension Square: CustomStringConvertible {
@@ -614,17 +891,23 @@ print("Square: \(mySquare)")
// You can also extend built-in types
extension Int {
- var customProperty: String {
- return "This is \(self)"
+ var doubled: Int {
+ return self * 2
}
- func multiplyBy(num: Int) -> Int {
+ func multipliedBy(num: Int) -> Int {
return num * self
}
+
+ mutating func multiplyBy(num: Int) {
+ self *= num
+ }
}
-print(7.customProperty) // "This is 7"
-print(14.multiplyBy(num: 3)) // 42
+print(7.doubled) // 14
+print(7.doubled.multipliedBy(num: 3)) // 42
+
+// MARK: Generics
// Generics: Similar to Java and C#. Use the `where` keyword to specify the
// requirements of the generics.
@@ -637,10 +920,21 @@ func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? {
}
return nil
}
-let foundAtIndex = findIndex(array: [1, 2, 3, 4], valueToFind: 3)
-print(foundAtIndex == 2) // true
+findIndex(array: [1, 2, 3, 4], valueToFind: 3) // Optional(2)
+
+// You can extend types with generics as well
+extension Array where Array.Element == Int {
+ var sum: Int {
+ var total = 0
+ for el in self {
+ total += el
+ }
+ return total
+ }
+}
+
+// MARK: Operators
-// Operators:
// Custom operators can start with the characters:
// / = - + * % < > ! & | ^ . ~
// or
@@ -673,4 +967,40 @@ var bar: Float = 20
foo <-> bar
print("foo is \(foo), bar is \(bar)") // "foo is 20.0, bar is 10.0"
+
+// MARK: - Error Handling
+
+// The `Error` protocol is used when throwing errors to catch
+enum MyError: Error {
+ case badValue(msg: String)
+ case reallyBadValue(msg: String)
+}
+
+// functions marked with `throws` must be called using `try`
+func fakeFetch(value: Int) throws -> String {
+ guard 7 == value else {
+ throw MyError.reallyBadValue(msg: "Some really bad value")
+ }
+
+ return "test"
+}
+
+func testTryStuff() {
+ // assumes there will be no error thrown, otherwise a runtime exception is raised
+ let _ = try! fakeFetch(value: 7)
+
+ // if an error is thrown, then it proceeds, but if the value is nil
+ // it also wraps every return value in an optional, even if its already optional
+ let _ = try? fakeFetch(value: 7)
+
+ do {
+ // normal try operation that provides error handling via `catch` block
+ try fakeFetch(value: 1)
+ } catch MyError.badValue(let msg) {
+ print("Error message: \(msg)")
+ } catch {
+ // must be exhaustive
+ }
+}
+testTryStuff()
```
diff --git a/ta_in/css-ta.html.markdown b/ta_in/css-ta.html.markdown
index cbe88f1e..4ea7f959 100644
--- a/ta_in/css-ta.html.markdown
+++ b/ta_in/css-ta.html.markdown
@@ -233,6 +233,48 @@ css முன்னுரிமை பின்வருமாறு
* `B` இது அடுத்தது.
* `D` இதுவே கடைசி .
+## Media Queries [மீடியா குரிஸ்]
+
+CSS மீடியா குரிஸ் CSS 3 அம்சங்கள். பயன்படுத்தும் கணினி, கைபேசி அல்லது சாதனத்தின் பிஸேல் டென்சிட்டிக்கு ஏற்றவாறு மீடியா குரிஸ் விதிகளை பயன்படுத்தலாம்.
+
+```css
+/* அனைத்து டேவிஸ்களுக்கும் பொதுவான விதி */
+h1 {
+ font-size: 2em;
+ color: white;
+ background-color: black;
+}
+
+/* பிரிண்ட் செய்யும்போது h1 கலர் மாற்ற */
+@media print {
+ h1 {
+ color: black;
+ background-color: white;
+ }
+}
+
+/* 480 பிஸேல்ளுக்கு மேல் சிகிரீன் அளவு உள்ள சாதனத்தில் எழுத்து அளவு மிகை படுத்த */
+@media screen and (min-width: 480px) {
+ h1 {
+ font-size: 3em;
+ font-weight: normal;
+ }
+}
+```
+
+மீடியா குரிஸ் வழங்கும் அம்சங்கள் :
+`width`, `height`, `device-width`, `device-height`, `orientation`, `aspect-ratio`, `device-aspect-ratio`, `color`, `color-index`, `monochrome`, `resolution`, `scan`, `grid`. இவையுள் பெரும்பான்மை `min-` அல்லது `max-` வுடன் பயன்படுத்தலாம் .
+
+`resolution` பழைய சாதனங்களில் பயன்படாது, எனவே `device-pixel-ratio` பயன்படுத்தவும்.
+
+பல கைபேசி மற்றும் கணினிகள், வீடு கணினி திரை அளவு காட்ட முற்படும். எனவே `viewport` மெட்டா டேக் பயன்படுத்தவும்.
+
+```html
+<head>
+ <meta name="viewport" content="width=device-width; initial-scale=1.0">
+</head>
+```
+
## css அம்சங்களின் பொருந்தகூடிய தன்மை
பெரும்பாலான css 2 வின் அம்சங்கள் எல்லா உலாவிகளிலும் , கருவிகளிலும் உள்ளன. ஆனால் முன்கூட்டியே அந்த அம்சங்களை பரிசோதிப்பது நல்லது.
diff --git a/ta_in/javascript-ta.html.markdown b/ta_in/javascript-ta.html.markdown
index d3fe5a85..b328765f 100644
--- a/ta_in/javascript-ta.html.markdown
+++ b/ta_in/javascript-ta.html.markdown
@@ -1,7 +1,7 @@
---
language: javascript
contributors:
- - ['Adam Brenecki', 'http://adam.brenecki.id.au']
+ - ['Leigh Brenecki', 'https://leigh.net.au']
- ['Ariel Krakowski', 'http://www.learneroo.com']
translators:
- ["Rasendran Kirushan", "https://github.com/kirushanr"]
@@ -22,8 +22,8 @@ javascript 1995 ஆம் ஆண்டு Netscape இல் பணிபுர
V8 JavaScript engine Node .js உதவியுடன் இயங்குகிறது .
உங்கள் கருத்துக்கள் மிகவும் வரவேற்கபடுகின்றன , என்னுடன் தொடர்புகொள்ள
-[@adambrenecki](https://twitter.com/adambrenecki), or
-[adam@brenecki.id.au](mailto:adam@brenecki.id.au).
+[@ExcitedLeigh](https://twitter.com/ExcitedLeigh), or
+[l@leigh.net.au](mailto:l@leigh.net.au).
```js
// குறிப்புக்கள் C நிரலாக்கத்தை ஒத்தது .ஒரு வரி குறிப்புக்கள் "//" குறியீடுடன் ஆரம்பமாகும்
diff --git a/ta_in/json-ta.html.markdown b/ta_in/json-ta.html.markdown
index d85e0d82..7f6559fa 100644
--- a/ta_in/json-ta.html.markdown
+++ b/ta_in/json-ta.html.markdown
@@ -1,6 +1,6 @@
---
language: json
-filename: learnjson.json
+filename: learnjson-ta.json
contributors:
- ["Anna Harren", "https://github.com/iirelu"]
- ["Marco Scannadinari", "https://github.com/marcoms"]
diff --git a/ta_in/xml-ta.html.markdown b/ta_in/xml-ta.html.markdown
index d782399d..13aa9255 100644
--- a/ta_in/xml-ta.html.markdown
+++ b/ta_in/xml-ta.html.markdown
@@ -5,6 +5,7 @@ contributors:
- ["João Farias", "https://github.com/JoaoGFarias"]
translators:
- ["Rasendran Kirushan", "https://github.com/kirushanr"]
+ - ["Sridhar Easwaran", "https://github.com/sridhareaswaran"]
lang: in-ta
---
@@ -14,6 +15,57 @@ XML ஆனது ஒரு கட்டமைப்பு மொழி ஆகு
HTML போல் அன்றி , XML ஆனது தகவலை மட்டும் கொண்டு செல்ல்கிறது
+
+## சில வரையறை மற்றும் முன்னுரை
+
+பல கூறுகளால் அமைக்கப்பட்டது. ஒவொரு கூறுகளிலும் அட்ட்ரிபூட்க்கள் இருக்கும், அவை அந்தந்த கூறுகளை வரையறுக்க பயன்படும். மேலும் அந்த கூறுகளை தகவல் அல்லது கிளை கூறுகள் இருக்கலாம். அணைத்து கோப்புகளிலும் ரூட்/ஆரம்ப கூறு இருக்கும், அது தனக்குள் கிளை கூறுகளை கொண்டுருக்கும்.
+
+XML பாகுபடுத்தி மிகவும் கண்டிப்பான வீதிகளைக்கொண்டது. [XML தொடரியல் விதிகளை அறிய] (http://www.w3schools.com/xml/xml_syntax.asp).
+
+
+```xml
+<!-- இது ஒரு XML குறிப்ப -->
+<!-- குறிப்புக்கள்
+பலவரி இருக்கலாம் -->
+
+<!-- கூறுகள்/Elements -->
+<!-- Element எனப்படுவது அடிப்படை கூறு. அவை இருவகைப்பாடு. காலியான கூறு: -->
+<element1 attribute="value" /> <!-- காலியான கூறு - உள்ளடக்கம் இல்லாதது -->
+<!-- மற்றும் காலி-இல்லாத கூறு : -->
+<element2 attribute="value">Content</element2>
+<!-- கூற்றின் பெயர் எழுத்துக்கள் மற்றும் எண் கொண்டு மட்டுமே இருக்கவேண்டும்.. -->
+
+<empty /> <!-- காலியான கூறு - உள்ளடக்கம் இல்லாதது -->
+
+<notempty> <!-- காலி-இல்லாத கூற - துவக்கம் -->
+ <!-- உள்ளடக்கம் -->
+</notempty> <!-- முடிவு -->
+
+<!-- கூற்றின் பெயர்கள் எழுத்து வடிவுணர்வு கொண்டது-->
+<element />
+<!-- ஓட்றது அல்ல -->
+<eLEMENT />
+
+<!-- Attributes/பண்புகளை -->
+<!-- Attribute ஒரு மதிப்பு இணை -->
+<element attribute="value" another="anotherValue" many="space-separated list" />
+<!-- ஒரு கூற்றில் Attribute ஒருமுறைதான் தோன்றும். அது ஒரேயொரு பணப்பை கொண்டிருக்கும் -->
+
+<!-- கீழை கூறுகள் -->
+<!-- ஒரு கூரானது பல கீழை கூறுகளை கொண்டிருக்கலாம் : -->
+<parent>
+ <child>Text</child>
+ <emptysibling />
+</parent>
+
+<!-- XML இடைவெளி கான்கெடுக்கப்படும். -->
+<child>
+ Text
+</child>
+<!-- ஓட்றது அல்ல -->
+<child>Text</child>
+```
+
* XML வாக்கிய அமைப்பு
diff --git a/tcl.html.markdown b/tcl.html.markdown
index 9118081d..1b577b49 100644
--- a/tcl.html.markdown
+++ b/tcl.html.markdown
@@ -1,21 +1,21 @@
---
language: Tcl
contributors:
- - ["Poor Yorick", "http://pooryorick.com/"]
+ - ["Poor Yorick", "https://pooryorick.com/"]
filename: learntcl.tcl
---
-Tcl was created by [John Ousterhout](http://wiki.tcl.tk/John Ousterout) as a
-reusable scripting language for chip design tools he was creating. In 1997 he
+Tcl was created by [John Ousterhout](https://wiki.tcl-lang.org/page/John+Ousterhout) as a
+reusable scripting language for circuit design tools that he authored. In 1997 he
was awarded the [ACM Software System
-Award](http://en.wikipedia.org/wiki/ACM_Software_System_Award) for Tcl. Tcl
+Award](https://en.wikipedia.org/wiki/ACM_Software_System_Award) for Tcl. Tcl
can be used both as an embeddable scripting language and as a general
programming language. It can also be used as a portable C library, even in
cases where no scripting capability is needed, as it provides data structures
such as dynamic strings, lists, and hash tables. The C library also provides
portable functionality for loading dynamic libraries, string formatting and
-code conversion, filesystem operations, network operations, and more.
-Various features of Tcl stand out:
+code conversion, filesystem operations, network operations, and more. Various
+features of Tcl stand out:
* Convenient cross-platform networking API
@@ -30,101 +30,105 @@ Various features of Tcl stand out:
* A threading model recognized as robust and easy to use
-If Lisp is a list processor, then Tcl is a string processor. All values are
-strings. A list is a string format. A procedure definition is a string
-format. To achieve performance, Tcl internally caches structured
-representations of these values. The list commands, for example, operate on
+Tcl has much in common with Lisp, but instead of lists, Tcl uses strings as the
+currency of the language. All values are strings. A list is a string with a
+defined format, and the body of a procedure (a script) is also a string rather
+than a block. To achieve performance, Tcl internally caches structured
+representations of these values. list routines, for example, operate on
the internal cached representation, and Tcl takes care of updating the string
representation if it is ever actually needed in the script. The copy-on-write
-design of Tcl allows script authors can pass around large data values without
+design of Tcl allows script authors to pass around large data values without
actually incurring additional memory overhead. Procedures are automatically
-byte-compiled unless they use the more dynamic commands such as "uplevel",
+byte-compiled unless they use the more dynamic routines such as "uplevel",
"upvar", and "trace".
Tcl is a pleasure to program in. It will appeal to hacker types who find Lisp,
Forth, or Smalltalk interesting, as well as to engineers and scientists who
just want to get down to business with a tool that bends to their will. Its
-discipline of exposing all programmatic functionality as commands, including
-things like loops and mathematical operations that are usually baked into the
+discipline of exposing all programmatic functionality as routines, including
+things like looping and mathematical operations that are usually baked into the
syntax of other languages, allows it to fade into the background of whatever
-domain-specific functionality a project needs. It's syntax, which is even
-lighter that that of Lisp, just gets out of the way.
-
-
+domain-specific functionality a project needs. Its syntax, which is even
+lighter than 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
+# Tcl is not Sh 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
# to get by with syntax they know from another language. It works at first,
-# but soon leads to frustration with more complex scripts.
+# but soon leads to frustration when scripts become more complex.
-# Braces are just a quoting mechanism, not a code block constructor or a list
-# constructor. Tcl doesn't have either of those things. Braces are used,
-# though, to escape special characters in procedure bodies and in strings that
-# are formatted as lists.
+# Braces are a quoting mechanism, not syntax for the construction of code
+# blocks or lists. Tcl doesn't have either of those things. Braces are used to
+# escape special characters, which makes them well-suited for quoting procedure
+# bodies and strings that should be interpreted 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
-# whitespace. Since every word is a string, in the simple case no special
-# markup such as quotes, braces, or backslash, is necessary. Even when quotes
-# are used, they are not a string constructor, but just another escaping
-# character.
+###############################################################################
-set greeting1 Sal
-set greeting2 ut
-set greeting3 ations
+# A script is made up of commands delimited by newlines or semicolons. Each
+# command is a call to a routine. The first word is the name of a routine to
+# call, and subsequent words are arguments to the routine. Words are delimited
+# by whitespace. Since each argument is a word in the command it is already a
+# string, and may be unquoted:
+set part1 Sal
+set part2 ut; set part3 ations
-#semicolon also delimits commands
-set greeting1 Sal; set greeting2 ut; set greeting3 ations
+# a dollar sign introduces variable substitution:
+set greeting $part1$part2$part3
-# Dollar sign introduces variable substitution
-set greeting $greeting1$greeting2$greeting3
+# When "set" is given only the name of a variable, it returns the
+# value of that variable:
+set part3 ;# Returns the value of the variable.
-# Bracket introduces command substitution. The result of the command is
-# substituted in place of the bracketed script. When the "set" command is
-# given only the name of a variable, it returns the value of that variable.
-set greeting $greeting1$greeting2[set greeting3]
+# Left and right brackets embed a script to be evaluated for a result to
+# substitute into the word:
+set greeting $part1$part2[set part3]
-# Command substitution should really be called script substitution, because an
-# entire script, not just a command, can be placed between the brackets. The
-# "incr" command increments the value of a variable and returns its value.
-
-set i 0
+# An embedded script may be composed of multiple commands, the last of which provides
+# the result for the substitution:
set greeting $greeting[
- incr i
- incr i
- incr i
+ incr i
+ incr i
+ incr i
]
-# i is now 3
+puts $greeting ;# The output is "Salutations3"
-# backslash suppresses the special meaning of characters
+# Every word in a command is a string, including the name of the routine, so
+# substitutions can be used on it as well. Given this variable
+# assignment,
+set action pu
+
+# , the following three commands are equivalent:
+puts $greeting
+${action}ts $greeting
+[set action]ts $greeting
+
+
+# backslash suppresses the special meaning of characters:
set amount \$16.42
-# backslash adds special meaning to certain characters
+# backslash adds special meaning to certain characters:
puts lots\nof\n\n\n\n\n\nnewlines
# A word enclosed in braces is not subject to any special interpretation or
# substitutions, except that a backslash before a brace is not counted when
-# looking for the closing brace
+# looking for the closing brace:
set somevar {
This is a literal $ sign, and this \} escaped
brace remains uninterpreted
@@ -132,38 +136,44 @@ set somevar {
# In a word enclosed in double quotes, whitespace characters lose their special
-# meaning
+# meaning:
set name Neo
set greeting "Hello, $name"
-#variable names can be any string
+# A variable name can be any string:
set {first name} New
-# The brace form of variable substitution handles more complex variable names
+# The braced form of variable substitution handles more complex variable names:
set greeting "Hello, ${first name}"
-# The "set" command can always be used instead of variable substitution
+# "set" can always be used instead of variable substitution, and can handle all
+# variable names:
set greeting "Hello, [set {first name}]"
-# To promote the words within a word to individual words of the current
-# command, use the expansion operator, "{*}".
-set {*}{name Neo}
-
-# is equivalent to
+# To unpack a list into the command, use the expansion operator, "{*}". These
+# two commands are equivalent:
set name Neo
+set {*}{name Neo}
# An array is a special variable that is a container for other variables.
set person(name) Neo
-set person(gender) male
+set person(destiny) {The One}
set greeting "Hello, $person(name)"
-# A namespace holds commands and variables
+# "variable" can be used to declare or set variables. In contrast with "set",
+# which uses both the global namespace and the current namespace to resolve a
+# variable name, "variable" uses only the current namespace:
+variable name New
+
+
+# "namespace eval" creates a new namespace if it doesn't exist. A namespace
+# can contain both routines and variables:
namespace eval people {
namespace eval person1 {
variable name Neo
@@ -171,105 +181,169 @@ namespace eval people {
}
-#The full name of a variable includes its enclosing namespace(s), delimited by two colons:
-set greeting "Hello $people::person1::name"
+# Use two or more colons to delimit namespace components in variable names:
+namespace eval people {
+ set greeting "Hello $person1::name"
+}
+
+# Two or more colons also delimit namespace components in routine names:
+proc people::person1::speak {} {
+ puts {I am The One.}
+}
+
+# Fully-qualified names begin with two colons:
+set greeting "Hello $::people::person1::name"
+
+
+###############################################################################
+## 3. No More Syntax
+###############################################################################
+# All other functionality is implemented via routines. From this point on,
+# there is no new syntax. Everything else there is to learn about
+# Tcl is about the behaviour of individual routines and what meaning they
+# assign to their arguments.
-################################################################################
-## 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
-# the behaviour of individual commands, and what meaning they assign to their
-# arguments.
+###############################################################################
+## 4. Variables and Namespaces
+###############################################################################
+
+# Each variable and routine is associated with some namespace.
# To end up with an interpreter that can do nothing, delete the global
# namespace. It's not very useful to do such a thing, but it illustrates the
-# nature of Tcl.
-namespace delete ::
-
+# nature of Tcl. The name of the global namespace is actually the empty
+# string, but the only way to represent it is as a fully-qualified name. To
+# try it out call this routine:
+proc delete_global_namespace {} {
+ 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 "set" always keeps its eye on both the global namespace and the
+# current namespace, it's safer to use "variable" to declare a variable or
+# assign a value to a variable. If a variable called "name" already exists in
+# the global namespace, using "set" here will assign a value to the global
+# variable instead of to a variable in the current namespace, whereas
+# "variable" operates only on the current namespace.
namespace eval people {
namespace eval person1 {
variable name Neo
}
}
+# Once a variable is declared in a namespace, [set] sees it instead of seeing
+# an identically-named variable in the global namespace:
+namespace eval people {
+ namespace eval person1 {
+ variable name
+ set name Neo
+ }
+}
+
+# But if "set" has to create a new variable, it always does it relative to the
+# current namespace:
+unset name
+namespace eval people {
+ namespace eval person1 {
+ set name neo
+ }
-# The full name of a variable can always be used, if desired.
-set people::person1::name Neo
+}
+set people::person1::name
+# An absolute name always begins with the name of the global namespace (the
+# empty string), followed by two colons:
+set ::people::person1::name Neo
-################################################################################
-## 4. Commands
-################################################################################
-# Math can be done with the "expr" command.
+# Within a procedure, the "variable" links a variable in the current namespace
+# into the local scope:
+namespace eval people::person1 {
+ proc fly {} {
+ variable name
+ puts "$name is flying!"
+ }
+}
+
+
+
+
+###############################################################################
+## 5. Built-in Routines
+###############################################################################
+
+# Math can be done with the "expr":
set a 3
set b 4
set c [expr {$a + $b}]
# Since "expr" performs variable substitution on its own, brace the expression
# to prevent Tcl from performing variable substitution first. See
-# "http://wiki.tcl.tk/Brace%20your%20#%20expr-essions" for details.
+# "https://wiki.tcl-lang.org/page/Brace+your+expr-essions" for details.
-# The "expr" command understands variable and command substitution
+# "expr" understands variable and script substitution:
set c [expr {$a + [set b]}]
-# The "expr" command provides a set of mathematical functions
+# "expr" provides a set of mathematical functions:
set c [expr {pow($a,$b)}]
-# Mathematical operators are available as commands in the ::tcl::mathop
-# namespace
+# Mathematical operators are available as routines in the ::tcl::mathop
+# namespace:
::tcl::mathop::+ 5 3
-# Commands can be imported from other namespaces
+# Routines can be imported from other namespaces:
namespace import ::tcl::mathop::+
set result [+ 5 3]
-# New commands can be created via the "proc" command.
+# Non-numeric values must be quoted, and operators like "eq" can be used to
+# constrain the operation to string comparison:
+set name Neo
+expr {{Bob} eq $name}
+
+# The general operators fall back to string string comparison if numeric
+# operation isn't feasible:
+expr {{Bob} == $name}
+
+
+# "proc" creates new routines:
proc greet name {
return "Hello, $name!"
}
-#multiple parameters can be specified
+#multiple parameters can be specified:
proc greet {greeting name} {
return "$greeting, $name!"
}
# As noted earlier, braces do not construct a code block. Every value, even
-# the third argument of the "proc" command, is a string. The previous command
-# rewritten to not use braces at all:
+# the third argument to "proc", is a string. The previous command
+# can be rewritten using no braces:
proc greet greeting\ name return\ \"\$greeting,\ \$name!\"
+# "
-# When the last parameter is the literal value, "args", it collects all extra
-# arguments when the command is invoked
-proc fold {cmd args} {
- set res 1
+# When the last parameter is the literal value "args", all extra arguments
+# passed to the routine are collected into a list and assigned to "args":
+proc fold {cmd first args} {
foreach arg $args {
- set res [$cmd $res $arg]
+ set first [$cmd $first $arg]
}
- return res
+ return $first
}
fold ::tcl::mathop::* 5 3 3 ;# -> 45
-# Conditional execution is implemented as a command
+# Conditional execution is implemented as a routine:
if {3 > 4} {
puts {This will never happen}
} elseif {4 > 4} {
@@ -279,30 +353,40 @@ if {3 > 4} {
}
-# Loops are implemented as commands. The first, second, and third
-# arguments of the "for" command are treated as mathematical expressions
+# Loops are implemented as routines. The first and third arguments to
+# "for" are treated as scripts, while the second argument is treated as
+# an expression:
+set res 0
for {set i 0} {$i < 10} {incr i} {
set res [expr {$res + $i}]
}
+unset res
-# The first argument of the "while" command is also treated as a mathematical
-# expression
+# The first argument to "while" is also treated as an expression:
set i 0
while {$i < 10} {
incr i 2
}
-# A list is a specially-formatted string. In the simple case, whitespace is sufficient to delimit values
+# A list is a string, and items in the list are delimited by whitespace:
set amounts 10\ 33\ 18
set amount [lindex $amounts 1]
+# Whitespace in a list item must be quoted:
+set inventory {"item 1" item\ 2 {item 3}}
+
+
+# It's generally a better idea to use list routines when modifying lists:
+lappend inventory {item 1} {item 2} {item 3}
+
# Braces and backslash can be used to format more complex values in a list. A
# list looks exactly like a script, except that the newline character and the
-# semicolon character lose their special meanings. This feature makes Tcl
-# homoiconic. There are three items in the following list.
+# semicolon character lose their special meanings, and there is no script or
+# variable substitution. This feature makes Tcl homoiconic. There are three
+# items in the following list:
set values {
one\ two
@@ -314,19 +398,19 @@ set values {
}
-# Since a list is a string, string operations could be performed on it, at the
-# risk of corrupting the formatting of the list.
+# Since, like all values, a list is a string, string operations could be
+# performed on it, at the risk of corrupting the formatting of the list:
set values {one two three four}
set values [string map {two \{} $values] ;# $values is no-longer a \
- properly-formatted listwell-formed list
+ properly-formatted list
-# The sure-fire way to get a properly-formmated list is to use "list" commands
+# The sure-fire way to get a properly-formatted list is to use "list" routines:
set values [list one \{ three four]
lappend values { } ;# add a single space as an item in the list
-# Use "eval" to evaluate a value as a script
+# Use "eval" to evaluate a value as a script:
eval {
set name Neo
set greeting "Hello, $name"
@@ -334,84 +418,93 @@ eval {
# A list can always be passed to "eval" as a script composed of a single
-# command.
+# command:
eval {set name Neo}
eval [list set greeting "Hello, $name"]
-# Therefore, when using "eval", use [list] to build up a desired command
+# Therefore, when using "eval", use "list" to build up the desired command:
set command {set name}
lappend command {Archibald Sorbisol}
eval $command
-# A common mistake is not to use list functions when building up a command
+# A common mistake is not to use list functions when building up a command:
set command {set name}
append command { Archibald Sorbisol}
-eval $command ;# There is an error here, because there are too many arguments \
- to "set" in {set name Archibald Sorbisol}
+try {
+ eval $command ;# The error here is that there are too many arguments \
+ to "set" in {set name Archibald Sorbisol}
+} on error {result eoptions} {
+ puts [list {received an error} $result]
+}
+# This mistake can easily occur with "subst":
-# This mistake can easily occur with the "subst" command.
set replacement {Archibald Sorbisol}
set command {set name $replacement}
-set command [subst $command]
-eval $command ;# The same error as before: too many arguments to "set" in \
- {set name Archibald Sorbisol}
+set command [subst $command]
+try {
+ eval $command ;# The same error as before: too many arguments to "set" in \
+ {set name Archibald Sorbisol}
+} trap {TCL WRONGARGS} {result options} {
+ puts [list {received another error} $result]
+}
-# The proper way is to format the substituted value using use the "list"
-# command.
+# "list" correctly formats a value for substitution:
set replacement [list {Archibald Sorbisol}]
set command {set name $replacement}
set command [subst $command]
eval $command
-# It is extremely common to see the "list" command being used to properly
-# format values that are substituted into Tcl script templates. There are
-# several examples of this, below.
+# "list" is commonly used to format values for substitution into scripts: There
+# are several examples of this, below.
-# The "apply" command evaluates a string as a command.
+# "apply" evaluates a two-item list as a routine:
set cmd {{greeting name} {
return "$greeting, $name!"
}}
apply $cmd Whaddup Neo
+# A third item can be used to specify the namespace to apply the routine in:
+set cmd [list {greeting name} {
+ return "$greeting, $name!"
+} [namespace current]]
+apply $cmd Whaddup Neo
-# The "uplevel" command evaluates a script in some enclosing scope.
+
+# "uplevel" evaluates a script at some higher level in the call stack:
proc greet {} {
- uplevel {puts "$greeting, $name"}
+ uplevel {puts "$greeting, $name"}
}
proc set_double {varname value} {
- if {[string is double $value]} {
- uplevel [list variable $varname $value]
- } else {
- error [list {not a double} $value]
- }
+ if {[string is double $value]} {
+ uplevel [list variable $varname $value]
+ } else {
+ error [list {not a double} $value]
+ }
}
-# The "upvar" command links a variable in the current scope to a variable in
-# some enclosing scope
+# "upvar" links a variable at the current level in the call stack to a variable
+# at some higher level:
proc set_double {varname value} {
- if {[string is double $value]} {
- upvar 1 $varname var
- set var $value
- } else {
- error [list {not a double} $value]
- }
+ if {[string is double $value]} {
+ upvar 1 $varname var
+ set var $value
+ } else {
+ error [list {not a double} $value]
+ }
}
-#get rid of the built-in "while" command.
+# Get rid of the built-in "while" routine, and use "proc" to define a new one:
rename ::while {}
-
-
-# Define a new while command with the "proc" command. More sophisticated error
-# handling is left as an exercise.
+# handling is left as an exercise:
proc while {condition script} {
if {[uplevel 1 [list expr $condition]]} {
uplevel 1 $script
@@ -420,35 +513,76 @@ proc while {condition script} {
}
-# The "coroutine" command creates a separate call stack, along with a command
-# to enter that call stack. The "yield" command suspends execution in that
-# stack.
-proc countdown {} {
- #send something back to the initial "coroutine" command
- yield
+# "coroutine" creates a new call stack, a new routine to enter that call stack,
+# and then calls that routine. "yield" suspends evaluation in that stack and
+# returns control to the calling stack:
+proc countdown count {
+ # send something back to the creator of the coroutine, effectively pausing
+ # this call stack for the time being.
+ yield [info coroutine]
- set count 3
- while {$count > 1} {
- yield [incr count -1]
- }
- return 0
+ while {$count > 1} {
+ yield [incr count -1]
+ }
+ return 0
}
-coroutine countdown1 countdown
-coroutine countdown2 countdown
-puts [countdown 1] ;# -> 2
-puts [countdown 2] ;# -> 2
-puts [countdown 1] ;# -> 1
-puts [countdown 1] ;# -> 0
-puts [coundown 1] ;# -> invalid command name "countdown1"
-puts [countdown 2] ;# -> 1
+coroutine countdown1 countdown 3
+coroutine countdown2 countdown 5
+puts [countdown1] ;# -> 2
+puts [countdown2] ;# -> 4
+puts [countdown1] ;# -> 1
+puts [countdown1] ;# -> 0
+catch {
+ puts [coundown1] ;# -> invalid command name "countdown1"
+} cres copts
+puts $cres
+puts [countdown2] ;# -> 3
+
+
+# Coroutine stacks can yield control to each other:
+
+proc pass {whom args} {
+ return [yieldto $whom {*}$args]
+}
+
+coroutine a apply {{} {
+ yield
+ set result [pass b {please pass the salt}]
+ puts [list got the $result]
+ set result [pass b {please pass the pepper}]
+ puts [list got the $result]
+}}
+
+coroutine b apply {{} {
+ set request [yield]
+ while 1 {
+ set response [pass c $request]
+ puts [list [info coroutine] is now yielding]
+ set request [pass a $response]
+ }
+}}
+
+coroutine c apply {{} {
+ set request [yield]
+ while 1 {
+ if {[string match *salt* $request]} {
+ set request [pass b salt]
+ } else {
+ set request [pass b huh?]
+ }
+ }
+}}
+
+# get things moving
+a
```
## Reference
-[Official Tcl Documentation](http://www.tcl.tk/man/tcl/)
+[Official Tcl Documentation](https://www.tcl-lang.org)
-[Tcl Wiki](http://wiki.tcl.tk)
+[Tcl Wiki](https://wiki.tcl-lang.org)
[Tcl Subreddit](http://www.reddit.com/r/Tcl)
diff --git a/tcsh.html.markdown b/tcsh.html.markdown
new file mode 100644
index 00000000..e38b7a27
--- /dev/null
+++ b/tcsh.html.markdown
@@ -0,0 +1,791 @@
+---
+category: tool
+tool: tcsh
+filename: LearnTCSH.csh
+contributors:
+ - ["Nicholas Christopoulos", "https://github.com/nereusx"]
+
+---
+tcsh ("tee-see-shell") is a Unix shell based on and compatible with the C shell (csh).
+It is essentially the C shell with programmable command-line completion, command-line editing,
+and a few other features.
+It is the native root shell for BSD-based systems such as FreeBSD.
+
+Almost all Linux distros and BSD today use tcsh instead of the original csh. In
+most cases csh is a symbolic link that points to tcsh.
+This is because tcsh is backward compatible with csh, and the last
+is not maintained anymore.
+
+- [TCSH Home](http://www.tcsh.org/)
+- [TCSH Wikipedia](https://en.wikipedia.org/wiki/Tcsh)
+- [TCSH manual page](http://www.tcsh.org/tcsh.html/top.html)
+- [“An Introduction to the C shell”, William Joy](https://docs.freebsd.org/44doc/usd/04.csh/paper.html)
+- [TCSH Bug reports and/or features requests](https://bugs.gw.com/)
+
+Some more files:
+[tcsh help command (for 132x35 terminal size)](https://github.com/nereusx/dotfiles/blob/master/csh-help),
+[my ~/.tcshrc](https://github.com/nereusx/dotfiles/blob/master/.tcshrc)
+
+```tcsh
+#!/bin/tcsh
+# First line of the script is shebang which tells the system how to execute the
+# script: http://en.wikipedia.org/wiki/Shebang_(Unix)
+# TCSH emulates the shebang on systems which don't understand it.
+
+# In most cases you'll use `#!/bin/tcsh -f', because `-f' option does not load
+# any resource or start-up files, or perform any command hashing, and thus
+# starts faster.
+
+# --- the echo command --------------------------------------------------------
+# The `echo' writes each word to the shell's standard output, separated by
+# spaces and terminated with a newline. The echo_style shell variable may be
+# set to emulate (or not) the flags and escape sequences.
+
+# Display the value of echo_style
+echo $echo_style
+
+# Enable `echo' to support backslashed characters and `-n' option (no new line)
+# This is the default for tcsh, but your distro may change it. Slackware has
+# done so.
+set echo_style = both
+
+# Prints "Hello world"
+echo Hello world
+echo "Hello world"
+echo 'Hello world'
+echo `echo Hello world`
+
+# This prints "twonlines" in one line
+echo two\nlines
+
+# Prints the two lines
+echo "two\nlines"
+echo 'two\nlines'
+
+# --- Basic Syntax ------------------------------------------------------------
+
+# A special character (including a blank or tab) may be prevented from having
+# its special meaning by preceding it with a backslash `\'.
+# this will display the last history commands
+echo !!
+# this will not
+echo \!\!
+
+# Single quotes prevents expanding special characters too, but some
+# characters like `!' and backslash have higher priority
+# `$' (variable value) will not expands
+echo '$1 tip'
+# `!' (history) will expands
+echo '!!'
+
+# Strings enclosed by back-quotes will be executed and replaced by the result.
+echo `ls`
+
+# Semi-colon separate commands
+echo 'first line'; echo 'second line'
+
+# There is also conditional execution
+echo "Always executed" || echo "Only executed if first command fails"
+echo "Always executed" && echo "Only executed if first command does NOT fail"
+
+# Parenthesised commands are always executed in a subshell,
+
+# example: create a project and then informs you that it finished while
+# it does the installation.
+make && ( espeak "BOSS, compilation finished"; make install )
+
+# prints the home directory but leaving you where you were
+(cd; pwd); pwd
+
+# Read tcsh man-page documentation
+man tcsh
+
+# --- Variables ---------------------------------------------------------------
+# The shell maintains a list of variables, each of which has as value a list of
+# zero or more words. The values of shell variables can be displayed and
+# changed with the `set' and `unset' commands.
+# The system maintains its own list of ``environment'' variables.
+# These can be displayed and changed with `printenv', `setenv' and `unsetenv'.
+# The syntax of setenv is similar to POSIX sh.
+
+# Assign a value or nothing will create a variable
+# Assign nothing
+set var
+# Assign a numeric value
+# the '@' denotes the expression is arithmetic; it works similar to 'set' but
+# the right value can be a numeric expression.
+@ var = 1 + 2
+# Assign a string value
+set var = "Hello, I am the contents of 'var' variable"
+# Assign the output of a program
+set var = `ls`
+
+# Remove a variable
+unset var
+# Prints 1 (true) if the variable `var' exists otherwise prints 0 (false)
+echo $?var
+# Print all variables and their values
+set
+
+# Prints the contents of 'var'
+echo $var;
+echo "$var";
+# Prints the string `$var'
+echo \$var
+echo '$var'
+# braces can be used to separate variable from the rest when its needed
+set num = 12; echo "There ${num}th element"
+
+# Prints the number of characters of the value: 6
+set var = '123456'; echo $%var
+
+### LISTs
+# Assign a list of values
+set var = ( one two three four five )
+# Print all the elements: one two three four five
+echo $var
+echo $var[*]
+# Print the count of elements: 5
+echo $#var
+# Print indexed element; prints the second element: two
+echo $var[2]
+# Print range of elements; prints 2nd up to 3rd: two, three
+echo $var[2-3]
+# Prints all elements starting from the 3rd: three four five
+echo $var[3-]
+# Prints print all up to 3rd element: one two three
+echo $var[-3]
+
+### Special Variables
+# $argv list of command-line arguments
+# $argv[0] this file-name (the file of the script file)
+# $# $0, $n, $* are the same as $#argv, $argv[0], $argv[n], $argv[*]
+# $status, $? the exit code of the last command that executed
+# $_ the previous command line
+# $! the PID of the last background process started by this shell
+# $$ script's PID
+
+# $path, $PATH the list of directories that will search for executable to run
+# $home, $HOME user's home directory, also the `~' can be used instead
+# $uid user's login ID
+# $user user's login name
+# $gid the user's group ID
+# $group the user's group-name
+# $cwd, $PWD the Current/Print Working Directory
+# $owd the previous working directory
+# $tcsh tcsh version
+# $tty the current tty; ttyN for linux console, pts/N for terminal
+# emulators under X
+# $term the terminal type
+# $verbose if set, causes the words of each command to be printed.
+# can be set by the `-v' command line option too.
+# $loginsh if set, it is a login shell
+
+# TIP: $?0 is always false in interactive shells
+# TIP: $?prompt is always false in non-interactive shells
+# TIP: if `$?tcsh' is unset; you run the original `csh' or something else;
+# try `echo $shell'
+# TIP: $verbose this is useful to debugging scripts
+# NOTE: $PWD and $PATH are synchronised with $cwd and $pwd automatically.
+
+# --- Variable modifiers ------------------------------------------------------
+# Syntax: ${var}:m[:mN]
+# Where <m> is:
+# h : the directory t : the filenane r : remove extension e : the extension
+# u : uppercase the first lowercase letter
+# l : lowercase the first uppercase letter
+# p : print but do not execute it (hist)
+# q : quote the substituted words, preventing further substitutions
+# x : like q, but break into words at white spaces
+# g : apply the following modifier once to each word
+# a : apply the following modifier as many times as possible to single word
+# s/l/r/ : search for `l' and replace with `r', not regex; the `&' in the r is
+# replaced by l
+# & : Repeat the previous substitution
+
+# start with this file
+set f = ~/Documents/Alpha/beta.txt
+# prints ~/Documents/Alpha/beta
+echo $f:r
+# prints ~/Documents/Alpha
+echo $f:h
+# prints beta.txt
+echo $f:t
+# prints txt
+echo $f:e
+# prints beta
+echo $f:t:r
+# prints Beta
+echo $f:t:r:u
+# prints Biota
+echo $f:t:r:u:s/eta/iota/
+
+# --- Redirection -------------------------------------------------------------
+
+# Create file.txt and write the standard output to it
+echo 'this string' > file.txt
+# Create file.txt and write the standard output and standard error to it
+echo 'this string' >& file.txt
+# Append the standard output to file.txt
+echo 'this string' >> file.txt
+# Append the standard output and standard error to file.txt
+echo 'this string' >>& file.txt
+# Redirect the standard input from file.txt
+cat < file.txt
+# Input from keyboard; this stores the input line to variable `x'
+set x = $<
+# Document here;
+cat << LABEL
+...text here...
+LABEL
+
+# TIP: this is how to get standard error separated:
+(grep 'AGP' /usr/src/linux/Documentation/* > output-file.txt) >& error-file.txt
+
+# example: read a name from standard input and display a greetings message
+echo -n "Enter your name? "
+set name = $<
+echo "Greetings $name"
+
+# --- Expressions ------------------------------------------------------------
+
+# Operators:
+# == equal != not equal ! not
+# > greater than < less than >= greater or equal <= less or equal
+# && logical AND || logical OR
+
+if ( $name != $user ) then
+ echo "Your name isn't your username"
+else
+ echo "Your name is your username"
+endif
+
+# single-line form
+if ( $name != $user ) echo "Your name isn't your username"
+
+# NOTE: if $name is empty, tcsh sees the above condition as:
+# if ( != $user ) ...
+# which is invalid syntax
+# so the "safe" way to use potentially empty variables in tcsh is:
+# if ( "$name" != $user ) ...
+# which, when $name is empty, is seen by tcsh as:
+# if ( "" != $user ) ...
+# which works as expected
+
+# There is also conditional execution
+echo "Always executed" || echo "Only executed if first command fails"
+echo "Always executed" && echo "Only executed if first command does NOT fail"
+
+# To use && and || with if statements, you don't need multiple pairs of
+# square brackets:
+if ( "$name" == "Steve" && "$age" == 15 ) then
+ echo "This will run if $name is Steve AND $age is 15."
+endif
+
+if ( "$name" == "Daniya" || "$name" == "Zach" ) then
+ echo "This will run if $name is Daniya OR Zach."
+endif
+
+# String matching operators ( `=~' and `!~' )
+# The ‘==’ ‘!=’ ‘=~’ and ‘!~’ operators compare their arguments as strings;
+# all others operate on numbers. The operators ‘=~’ and ‘!~’ are like ‘!=’
+# and ‘==’ except that the right hand side is a glob-pattern against which
+# the left hand operand is matched.
+
+if ( $user =~ ni[ck]* ) echo "Greetings Mr. Nicholas."
+if ( $user !~ ni[ck]* ) echo "Hey, get out of Nicholas PC."
+
+# Arithmetic expressions are denoted with the following format:
+@ result = 10 + 5
+echo $result
+
+# Arithmetic Operators
+# +, -, *, /, %
+#
+# Arithmetic Operators which must be parenthesised
+# !, ~, |, &, ^, ~, <<, >>,
+# Compare and logical operators
+#
+# All operators are same as in C.
+
+# It is non so well documented that numeric expressions require spaces
+# in-between; Also, `@' has its own parser, it seems that work well when the
+# expression is parenthesised otherwise the primary parser seems it is active.
+# Parenthesis require spaces around, this is documented.
+
+# wrong
+@ x = $y+1
+@ x = 0644 & 022; echo $x
+@ x = (0644 & 022) +1; echo $x
+@ x = (0644 & 022)+ 1; echo $x
+@ x = ( ~077 ); echo $x
+
+# correct
+@ x = $y + 1
+@ x = ( 0644 & 022 ) + 1; echo $x
+@ x = ( ~ 077 ); echo $x
+@ x = ( ~ 077 | 022 ); echo $x
+@ x = ( ! 0 ); echo $x
+
+# C's operators ++ and -- are supported if there is not assignment
+@ result ++
+
+# None shell created to do mathematics;
+# Except for the basic operations, use an external command with backslashes.
+#
+# I suggest the calc as the best option.
+# (http://www.isthe.com/chongo/tech/comp/calc/)
+#
+# The standard Unix's bc as second option
+# (https://www.gnu.org/software/bc/manual/html_mono/bc.html)
+#
+# The standard Unix's AWK as third option
+# (https://www.gnu.org/software/gawk/manual/gawk.html)
+
+# You can also use `perl', `php' or even several BASICs, but prefer the
+# above utilities for faster load-and-run results.
+
+# real example: (that I answer in StackExchange)
+# REQ: x := 1001b OR 0110b
+
+# in `tcsh' expression (by using octal)
+@ x = ( 011 | 06 ); echo $x
+
+# the same by using `calc' (and using binary as the original req)
+set x = `calc '0b1001 | 0b110'`; echo $x
+
+# --- File Inquiry Operators --------------------------------------------------
+# NOTE: The builtin `filetest' command do the same thing.
+
+#### Boolean operators
+# -r read access -w write access -x execute access -e existence
+# -f plain file -d directory -l symbolic link -p named pipe
+# -S socket file
+# -o ownership -z zero size -s non-zero size
+# -u SUID is set -g SGID is set -k sticky is set
+# -b block device -c char device
+# -t file (digit) is an open file descriptor for a terminal device
+
+# if the file `README' exists, displays a message
+if ( -e README ) echo "I have already README file"
+
+# if the `less' program is installed, use this instead of `more'
+if ( -e `where less` ) then
+ alias more 'less'
+endif
+
+#### Non-boolean operators
+# -Z returns the file size in bytes
+# -M returns the modification time (mtime) -M: returns mtime string
+# -A returns the lass access time (atime) -A: returns atime string
+# -U returns the owners user ID -U: returns the owners user-name
+# -G returns the group ID -G: returns the group-name
+# -P returns the permissions as octal number -Pmode returns perm. AND mode
+
+# this will display the date as Unix-time integer: 1498511486
+filetest -M README.md
+
+# This will display "Tue Jun 27 00:11:26 2017"
+filetest -M: README.md
+
+# --- Basic Commands ----------------------------------------------------------
+
+# Navigate though file system with `chdir' (cd)
+cd path # change working directory
+cd # change to home directory
+cd - # change to previous directory
+cd .. # go up one directory
+
+# Examples:
+cd ~/Downloads # go to my `Downloads' directory
+
+# Use `mkdir` to create new directories.
+mkdir newdir
+# The `-p` flag causes new intermediate directories to be created as necessary.
+mkdir -p ~/.backup/saves
+
+# which & where
+# find if csh points to tcsh
+ls -lha `which csh`
+# find if csh is installed on more than one directory
+where csh
+
+# --- Pipe-lines --------------------------------------------------------------
+# A pipeline is a sequence of processes chained together by their standard
+# streams, so that the output of each process (stdout) feeds directly as input
+# (stdin) to the next one. This `pipes' are created with the `|' special
+# character and it is one of the most powerful characteristics of Unix.
+
+# example:
+ls -l | grep key | less
+# "ls -l" produces a process, the output (stdout) of which is piped to the
+# input (stdin) of the process for "grep key"; and likewise for the process
+# for "less".
+
+# the `ls', the `grep' and the `less' are programs of Unix and they have their
+# own man-page. The `pipe' mechanism is part of the kernel but the syntax
+# and the control is job of the shell, the tcsh in our case.
+
+# NOTE: `pipe' mechanism has Windows too, but it is buggy and I sign it for all
+# versions until Windows XP SP3 API32 which was the last one that I worked on.
+# Microsoft still denied it but is well known bug since it is a common method
+# for inter-process communication. For small I/O it will work well.
+# tcsh, along with grep, gcc and perl is one of the first Unix programs that
+# ported to DOS (with EMX DOS extender) and later to Windows (1998).
+
+# example: this will convert tcsh to PostScript and will show it with okular
+zcat /usr/man/man1/tcsh.1.gz | groff -Tps -man | okular -
+
+# a better version
+zcat `locate -b -n 1 '\tcsh.1.gz'` | groff -Tps -man | okular -
+
+# even better
+set page = tcsh; set loc = (locate -b -n 1 "\\\\"${page}".1.gz");
+ zcat `eval $loc` | groff -Tps -man | okular -
+
+# the same, modified to create man page pdf
+set page = tcsh; set loc = (locate -b -n 1 "\\\\"${page}".1.gz");
+ zcat `eval $loc` | groff -Tps -man | ps2pdf - ${page}.pdf
+
+# the same, but now shows the ${page}.pdf too
+set page = tcsh; set loc = (locate -b -n 1 "\\\\"${page}".1.gz");
+ zcat `eval $loc` | groff -Tps -man | ps2pdf - ${page}.pdf && okular tcsh.pdf
+
+# NOTE: `okular' is the default application of KDE environment and it shows
+# postcript and pdf files. You can replace it with your lovely pdf viewer.
+# zcat, locate, groff, are common programs in all Unices. `ps2pdf' program
+# is part of `ghostscript' package that is widely used.
+
+# --- Control Flow ------------------------------------------------------------
+
+#### IF-THEN-ELSE-ENDIF
+# Syntax:
+# if ( expr ) then
+# ...
+# [else if ( expr2 ) then
+# ...]
+# [else
+# ...]
+# endif
+#
+# If the specified expr is true then the commands to the first else are
+# executed; otherwise if expr2 is true then the commands to the second else
+# are executed, etc.
+# Any number of else-if pairs are possible; only one endif is needed.
+#
+# Single-line form:
+#
+# if ( expr ) command
+#
+# If `expr' evaluates true, then command is executed.
+# `command' must be a simple command, not an alias, a pipeline, a command list
+# or a parenthesized command list. With few words, avoid to use it.
+#
+# BUG: Input/output redirection occurs even if expr is false and command is
+# thus not executed.
+#
+
+# check if we are in non-interactive shell and quit if true
+if ( $?USER == 0 || $?prompt == 0 ) exit
+
+# check if we are a login shell
+if ( $?loginsh ) then
+ # check if you are on linux console (not X's terminal)
+ if ( $tty =~ tty* ) then
+ # enable keypad application keys (man console_codes)
+ echo '\033='
+ endif
+endif
+
+#### SWITCH-ENDSW
+# Syntax:
+# switch ( expr )
+# case pattern:
+# ...
+# [breaksw]
+# [default:
+# ...]
+# endsw
+#
+# tcsh uses a case statement that works similarly to switch in C.
+# Each case label is successively matched, against the specified string which
+# is first command and filename expanded. The file metacharacters `*', `?'
+# and `[...]' may be used in the case labels. If none of the labels match the
+# execution begins after the default label if its defined.
+# The command `breaksw' causes execution to continue after the endsw. Otherwise
+# control may fall through case labels and default labels as in C.
+
+switch ( $var )
+case *.[1-9]:
+case *.[1-9].gz:
+ echo "$var is a man-page."
+ breaksw
+case *gz:
+ echo "$var is gzipped"
+ breaksw
+default:
+ file $var
+endsw
+
+#### FOREACH-END
+# Syntax:
+# foreach name ( wordlist )
+# ...
+# [break | continue]
+# end
+#
+# Successively sets the variable `name' to each member of `wordlist' and
+# executes the sequence of commands between this command and the matching
+# `end' keyword. The `continue' keyword jump to the next element back to
+# top; and the `break' keyword terminates the loop.
+#
+# BUG: `foreach' doesn't ignore here documents when looking for its end.
+
+# example: counting 1 to 10
+foreach i ( `seq 1 10` )
+ echo $i
+end
+
+# example: type all files in the list
+foreach f ( a.txt b.txt c.txt )
+ cat $f
+end
+
+# example: convert wma to ogg
+foreach f ( *.wma )
+ ffmpeg -i "$f" "$f:r".ogg
+end
+
+#### WHILE-END
+# while ( expr )
+# ...
+# [break | continue]
+# end
+#
+# Executes the commands between the `while' and the matching `end' while `expr'
+# evaluates non-zero. `break' and `continue' may be used to terminate or
+# continue the loop prematurely.
+
+# count from 1 to 10
+set num = 1
+while ( $num <= 10 )
+ echo $num
+ @ num ++
+end
+
+# print all directories of CWD
+set lst = ( * )
+while ( $#lst )
+ if ( -d $lst[1] ) echo $lst[1] is directory
+ shift lst
+end
+
+# separate command-line arguments to options or parameters
+set options
+set params
+set lst = ( $* )
+while ( $#lst )
+ if ( "$lst[1]" =~ '-*' ) then
+ set options = ( $options $lst[1] )
+ else
+ set params = ( $params $lst[1] )
+ endif
+ shift lst
+end
+echo 'options =' $options
+echo 'parameters =' $params
+
+#### REPEAT
+# Syntax: repeat count command
+#
+# The specified command, which is subject to the same restrictions as the
+# command in the one line if statement above, is executed count times.
+# I/O redirections occur exactly once, even if count is 0.
+#
+# TIP: in most cases prefer `while'
+
+repeat 3 echo "ding dong"
+
+# --- Functions ---------------------------------------------------------------
+# tcsh has no functions but its expression syntax is advanced enough to use
+# `alias' as functions. Another method is recursion
+
+# Alias argument selectors; the ability to define an alias to take arguments
+# supplied to it and apply them to the commands that it refers to.
+# Tcsh is the only shell that provides this feature.
+#
+# \!# argument selector for all arguments, including the alias/command
+# itself; arguments need not be supplied.
+# \!* argument selector for all arguments, excluding the alias/command;
+# arguments need not be supplied.
+# \!$ argument selector for the last argument; argument need not be supplied,
+# but if none is supplied, the alias name is considered to be the
+# last argument.
+# \!^ argument selector for first argument; argument MUST be supplied.
+# \!:n argument selector for the nth argument; argument MUST be supplied;
+# n=0 refers to the alias/command name.
+# \!:m-n argument selector for the arguments from the mth to the nth;
+# arguments MUST be supplied.
+# \!:n-$ argument selector for the arguments from the nth to the last;
+# at least argument n MUST be supplied.
+
+# Alias the cd command so that when you change directories, the contents
+# are immediately displayed.
+alias cd 'cd \!* && ls'
+
+# --- Recursion method --- begin ---
+#!/bin/tcsh -f
+set todo = option1
+if ( $#argv > 0 ) then
+ set todo = $argv[1]
+endif
+
+switch ( $todo )
+case option1:
+# ...
+ $0 results
+ breaksw
+case option2:
+# ...
+ $0 results
+ breaksw
+case results:
+ echo "print the results here"
+# ...
+ breaksw
+default:
+ echo "Unknown option: $todo"
+# exit 0
+endsw
+# --- Recursion method --- end ---
+
+# --- examples ----------------------------------------------------------------
+
+# this script prints available power-states if no argument is set;
+# otherwise it set the state of the $argv[1]
+# --- power-state script --- begin --------------------------------------------
+#!/bin/tcsh -f
+# get parameter ("help" for none)
+set todo = help
+if ( $#argv > 0 ) then
+ set todo = $argv[1]
+endif
+# available options
+set opts = `cat /sys/power/state`
+# is known?
+foreach o ( $opts )
+ if ( $todo == $o ) then
+ # found; execute it
+ echo -n $todo > /sys/power/state
+ break
+ endif
+end
+# print help and exit
+echo "usage: $0 [option]"
+echo "available options on kernel: $opts"
+# --- power-state script --- end ----------------------------------------------
+
+# Guess the secret number game
+# --- secretnum.csh --- begin -------------------------------------------------
+#!/bin/tcsh -f
+set secret=`shuf -i1-100 -n1`
+echo "I have a secret number from 1 up to 100"
+while ( 1 )
+ echo -n "Guess: "
+ set guess = $<
+ if ( $secret == $guess ) then
+ echo "You found it"
+ exit 1
+ else
+ if ( $secret > $guess ) then
+ echo "its greater"
+ else if ( $secret < $guess ) then
+ echo "its lesser"
+ endif
+ endif
+ endif
+end
+# --- secretnum.csh --- end ---------------------------------------------------
+
+# -----------------------------------------------------------------------------
+# Appendices
+
+#### About [T]CSH:
+# * CSH is notorious about its bugs;
+# * It was also famous about its advanced interactive mode.
+# * TCSH is famous that have the most advanced completition subsystem.
+# * TCSH is famous that have the most advanced aliases subsystem; aliases
+# can take parameters and often used as functions!
+# * TCSH is well known that preferred by people (me too) because of better
+# syntax. All shells are using Thomson's syntax with exception of [t]csh,
+# fish and plan9's shells (rc, ex).
+# * It is smaller and consume far less memory than bash, zsh even mksh!
+# (memusage reports)
+# * TCSH still has bugs; less but have; if you write readable clean code you'll
+# find none; well almost none... This has to do with the implementation of
+# csh; that no means the other shells has good implementation.
+# * no one well known shell is capable for regular programming; if your script
+# getting big, use a programming language, or at least PHP or Perl (good
+# script languages).
+#
+# Advises:
+# 1. Do not use redirection in single-line if (it is well documented bug)
+# In most cases avoid to use single-line IFs.
+# 2. Do not mess up with other shells code, c-shell is not compatible with
+# other shells and has different abilities and priorities.
+# 3. Use spaces as you'll use them to write readable code in any language.
+# A bug of csh was `set x=1' worked, `set x = 1' worked, `set x =1' did not!
+# 4. It is well documented that numeric expressions require spaces in-between;
+# also parenthesise all bit-wise and unary operators.
+# 5. Do not write a huge weird expression with several quotes, backslashes etc
+# It is bad practice for generic programming, it is dangerous in any shell.
+# 6. Help tcsh, report the bug here <https://bugs.gw.com/>
+# 7. Read the man page, `tcsh' has huge number of options, and variables.
+#
+# I suggest the following options enabled by default
+# --------------------------------------------------
+# Even in non-interactive shells
+# set echo_style=both
+# set backslash_quote
+# set parseoctal
+# unset noclobber
+#
+# Whatever...
+# set inputmode=insert
+# set autolist
+# set listjobs
+# set padhour
+# set color
+# set colorcat
+# set nobeep
+# set cdtohome
+#
+# set histdup
+# set histlit
+# set nohistclop
+#
+# unset compat_expr
+# unset noglob
+# unset autologout
+# unset time
+# unset tperiod
+#
+# NOTE: If the `backslash_quote' is set, it may create compatibility issues
+# with other tcsh scripts which was written without it.
+#
+# NOTE: The same for `parseoctal', but it is better to fix the problematic
+# scripts.
+#
+# NOTE: **for beginners only**
+# This enable automatically rescan `path' directories if need to. (like bash)
+# set autorehash
+
+#### common aliases
+# alias hist 'history 20'
+# alias ll 'ls --color -lha'
+# alias today "date '+%d%h%y'
+# alias ff 'find . -name '
+
+#### a nice prompt
+# set prompt = "%B%{\033[35m%}%t %{\033[32m%}%n@%m%b %C4 %# "
+```
diff --git a/textile.html.markdown b/textile.html.markdown
new file mode 100644
index 00000000..2b81674a
--- /dev/null
+++ b/textile.html.markdown
@@ -0,0 +1,505 @@
+---
+language: textile
+contributors:
+ - ["Keith Miyake", "https://github.com/kaymmm"]
+filename: learn-textile.textile
+---
+
+
+Textile is a lightweight markup language that uses a text formatting syntax to
+convert plain text into structured HTML markup. The syntax is a shorthand
+version of HTML that is designed to be easy to read and write. Textile is used
+for writing articles, forum posts, readme documentation, and any other type of
+written content published online.
+
+- [Comments](#comments)
+- [Paragraphs](#paragraphs)
+- [Headings](#headings)
+- [Simple Text Styles](#simple-text-styles)
+- [Lists](#lists)
+- [Code blocks](#code-blocks)
+- [Horizontal rule](#horizontal-rule)
+- [Links](#links)
+- [Images](#images)
+- [Footnotes and Endnotes](#footnotes-and-endnotes)
+- [Tables](#tables)
+- [Character Conversions](#character-conversions)
+- [CSS](#css)
+- [Spans and Divs](#spans-and-divs)
+- [Additional Info](#additional-info)
+
+## Comments
+
+```
+###. Comments begin with three (3) '#' signs followed by a full-stop period '.'.
+Comments can span multiple lines until a blank line is reached.
+
+###..
+Multi-line comments (including blank lines) are indicated by three (3) '#'
+signs followed by two (2) full-stop periods '..'.
+
+This line is also part of the above comment.
+
+The comment continues until the next block element is reached
+
+p. This line is not commented
+
+<!-- HTML comments are also…
+
+respected -->
+
+```
+
+## Paragraphs
+
+```
+###. Paragraphs are a one or multiple adjacent lines of text separated by one or
+multiple blank lines. They can also be indicated explicitly with a 'p. '
+
+This is a paragraph. I'm typing in a paragraph isn't this fun?
+
+Now I'm in paragraph 2.
+I'm still in paragraph 2 too!
+Line breaks without blank spaces are equivalent to a <br /> in XHTML.
+
+p. I'm an explicitly defined paragraph
+
+ Lines starting with a blank space are not wrapped in <p>..</p> tags.
+
+###. Paragraphs (and all block elements) can be aligned using shorthand:
+
+p<. Left aligned paragraph (default).
+
+p>. Right aligned paragraph.
+
+p=. Centered paragraph.
+
+p<>. Justified paragraph.
+
+h3>. Right aligned <h3>
+
+
+###. Paragraphs can be indented using a parentheses for each em
+Indentation utilizes padding-[left/right] css styles.
+
+p(. Left indent 1em.
+
+p((. Left indent 2em.
+
+p))). Right indent 3em.
+
+h2). This is equivalent to <h2 style="padding-right: 1em;">..</h2>
+
+
+###. Block quotes use the tag 'bq.'
+
+bq. This is a block quote.
+
+bq.:http://someurl.com You can include a citation URL immediately after the '.'
+
+bq.. Multi-line blockquotes containing
+
+blank lines are indicated using two periods
+
+p. Multi-line blockquotes continue until a new block element is reached.
+
+bq. You can add a footer to a blockquote using html:
+<footer>citation text</footer>
+
+
+###. Preformatted text blocks:
+
+pre. This text is preformatted. <= those two spaces will carry through.
+
+pre.. This is a multi-line preformatted…
+
+…text block that includes blank lines
+
+p. End a multi-line preformatted text block with a new block element.
+
+```
+
+## Headings
+
+You can create HTML elements `<h1>` through `<h6>` easily by prepending the
+text you want to be in that element by 'h#.' where # is the level 1-6.
+A blank line is required after headings.
+
+
+```
+h1. This is an <h1>
+
+h2. This is an <h2>
+
+h3. This is an <h3>
+
+h4. This is an <h4>
+
+h5. This is an <h5>
+
+h6. This is an <h6>
+
+```
+
+
+## Simple text styles
+
+```
+###. Bold and strong text are indicated using asterisks:
+
+*This is strong text*
+**This is bold text**
+This is [*B*]old text within a word.
+
+*Strong* and **Bold** usually display the same in browsers
+but they use different HTML markup, thus the distinction.
+
+###. Italics and emphasized text are indicated using underscores.
+
+_This is Emphasized text_
+__This is Italics text__
+This is It[_al_]ics within a word.
+
+_Emphasized_ and __Italics__ text typically display the same in browsers,
+but again, they use different HTML markup and thus the distinction.
+
+###. Superscripts and Subscripts use carats and tildes:
+
+Superscripts are 2 ^nd^ to none, but subscripts are CO ~2~ L too.
+Note the spaces around the superscripts and subscripts.
+
+To avoid the spaces, add square brackets around them:
+2[^nd^] and CO[~2~]L
+
+###. Insertions and deletions are indicated using -/+ symbols:
+This is -deleted- text and this is +inserted+ text.
+
+###. Citations are indicated using double '?':
+
+??This is a cool citation??
+
+```
+
+## Lists
+
+```
+###. Unordered lists can be made using asterisks '*' to indicate levels:
+
+* Item
+** Sub-Item
+* Another item
+** Another sub-item
+** Yet another sub-item
+*** Three levels deep
+
+###. Ordered lists are done with a pound sign '#':
+
+# Item one
+# Item two
+## Item two-a
+## Item two-b
+# Item three
+** Mixed unordered list within ordered list
+
+###. Ordered lists can start above 1 and can continue after another block:
+
+#5 Item 5
+# Item 6
+
+additional paragraph
+
+#_ Item 7 continued from above
+# Item 8
+
+###. Definition lists are indicated with a dash and assignment:
+
+- First item := first item definition
+- Second := second def.
+- Multi-line :=
+Multi-line
+definition =:
+```
+
+## Code blocks
+
+```
+Code blocks use the 'bc.' shorthand:
+
+bc. This is code
+ So is this
+
+This is outside of the code block
+
+bc.. This is a multi-line code block
+
+Blank lines are included in the multi-line code block
+
+p. End a multi-line code block with any block element
+
+p. Indicate @inline code@ using the '@' symbol.
+
+```
+
+## Horizontal rule
+
+Horizontal rules (`<hr/>`) are easily added with two hyphens
+
+```
+--
+```
+
+## Links
+
+```
+###. Link text is in quotes, followed by a colon and the URL:
+
+"Link text":http://linkurl.com/ plain text.
+
+"Titles go in parentheses at the end of the link text"(mytitle):http://url.com
+###. produces <a href... title="mytitle">...</a>
+
+###. Use square brackets when the link text or URL might be ambiguous:
+["Textile on Wikipedia":http://en.wikipedia.org/wiki/Textile_(markup_language)]
+
+###. Named links are useful if the same URL is referenced multiple times.
+Multiple "references":txstyle to the "txstyle":txstyle website.
+
+[txstyle]https://txstyle.org/
+
+```
+
+## Images
+
+```
+###. Images can be included by surrounding its URL with exclamation marks (!)
+Alt text is included in parenthesis after the URL, and they can be linked too:
+
+!http://imageurl.com!
+
+!http://imageurl.com(image alt-text)!
+
+!http://imageurl.com(alt-text)!:http://image-link-url.com
+
+```
+
+## Footnotes and Endnotes
+
+```
+A footnote is indicated with the reference id in square brackets.[1]
+
+fn1. Footnote text with a "link":http://link.com.
+
+A footnote without a link.[2!]
+
+fn2. The corresponding unlinked footnote.
+
+A footnote with a backlink from the footnote back to the text.[3]
+
+fn3^. This footnote links back to the in-text citation.
+
+
+Endnotes are automatically numbered[#first] and are indicated using square[#second]
+brackets and a key value[#first]. They can also be unlinked[#unlinkednote!]
+
+###. Give the endnotes text:
+
+note#first. This is the first endnote text.
+
+note#second. This is the second text.
+
+note#unlinkednote. This one isn't linked from the text.
+
+### Use the notelist block to place the list of notes in the text:
+This list will start with #1. Can also use alpha or Greeks.
+notelist:1. ###. start at 1 (then 2, 3, 4...)
+notelist:c. ###. start at c (then d, e, f...)
+notelist:α. ###. start at α (then β, γ, δ...)
+
+###. The notelist syntax is as follows:
+
+notelist. Notes with backlinks to every citation made to them.
+notelist+. Notes with backlinks to every citation made to them,
+ followed by the unreferenced notes.
+notelist^. Notes with one backlink to the first citation made to each note.
+notelist^+. Notes with one backlink to the first citation made to each note,
+ followed by unreferenced notes.
+notelist!. Notes with no backlinks to the citations.
+notelist!+. Notes with no backlinks to the citations, followed by
+ unreferenced notes.
+```
+
+## Tables
+
+
+```
+###. Tables are simple to define using the pipe '|' symbol
+
+| A | simple | table | row |
+| And | another | table | row |
+| With an | | empty | cell |
+
+###. Headers are preceded by '|_.'
+|_. First Header |_. Second Header |
+| Content Cell | Content Cell |
+
+###. The <thead> tag is added when |^. above and |-. below the heading are used.
+
+|^.
+|_. First Header |_. Second Header |
+|-.
+| Content Cell | Content Cell |
+| Content Cell | Content Cell |
+
+###. The <tfoot> tag is added when |~. above and |-. below the footer are used.
+
+|~.
+|\2=. A footer, centered & across two columns |
+|-.
+| Content Cell | Content Cell |
+| Content Cell | Content Cell |
+
+###. Attributes are be applied either to individual cells, rows, or to
+the entire table. Cell attributes are placed within each cell:
+
+|a|{color:red}. styled|cell|
+
+###. Row attributes are placed at the beginning of a row,
+followed by a dot and a space:
+
+(rowclass). |a|classy|row|
+
+###. Table attributes are specified by placing the special 'table.' block
+modifier immediately before the table:
+
+table(tableclass).
+|a|classy|table|
+|a|classy|table|
+
+###. Spanning rows and colums:
+A backslash \ is used for a column span:
+
+|\2. spans two cols |
+| col 1 | col 2 |
+
+###. A forward slash / is used for a row span:
+
+|/3. spans 3 rows | row a |
+| row b |
+| row c |
+
+###. Vertical alignments within a table cell:
+
+|^. top alignment|
+|-. middle alignment|
+|~. bottom alignment|
+
+###. Horizontal alignments within a table cell
+
+|:\1. |400|
+|=. center alignment |
+| no alignment |
+|>. right alignment |
+
+```
+or, for the same results
+
+```
+Col 1 | Col2 | Col3
+:-- | :-: | --:
+Ugh this is so ugly | make it | stop
+```
+
+
+## Character Conversions
+
+### Registered, Trademark, Copyright Symbols
+
+```
+RegisteredTrademark(r), Trademark(tm), Copyright (c)
+```
+
+### Acronyms
+
+```
+###. Acronym definitions can be provided in parentheses:
+
+EPA(Environmental Protection Agency) and CDC(Center for Disease Control)
+```
+
+### Angle Brackets and Ampersand
+
+```
+### Angled brackets < and > and ampersands & are automatically escaped:
+< => &lt;
+> => &gt;
+& => &amp;
+```
+
+### Ellipses
+
+```
+p. Three consecutive periods are translated into ellipses...automatically
+```
+
+### Em and En dashes
+
+```
+###. En dashes (short) is a hyphen surrounded by spaces:
+
+This line uses an en dash to separate Oct - Nov 2018.
+
+###. Em dashes (long) are two hyphens with or without spaces:
+
+This is an em dash--used to separate clauses.
+But we can also use it with spaces -- which is a less-used convention.
+That last hyphen between 'less' and 'used' is not converted between words.
+```
+
+## Fractions and other Math Symbols
+
+```
+One quarter: (1/4) => ¼
+One half: (1/2) => ½
+Three quarters: (3/4) => ¾
+Degree: (o) => °
+Plus/minus: (+/-) => ±
+```
+### Multiplication/Dimension
+
+```
+p. Numbers separated by the letter 'x' translate to the multiplication
+or dimension symbol '×':
+3 x 5 => 3 × 5
+```
+
+### Quotes and Apostrophes
+
+```
+###. Straight quotes and apostrophes are automatically converted to
+their curly equivalents:
+
+"these", 'these', and this'n are converted to their HTML entity equivalents.
+Leave them straight using '==' around the text: =="straight quotes"==.
+```
+
+## CSS
+
+```
+p{color:blue}. CSS Styles are enclosed in curly braces '{}'
+p(my-class). Classes are enclosed in parenthesis
+p(#my-id). IDs are enclosed in parentheses and prefaced with a pound '#'.
+```
+
+## Spans and Divs
+
+```
+%spans% are enclosed in percent symbols
+div. Divs are indicated by the 'div.' shorthand
+```
+---
+
+## For More Info
+
+* TxStyle Textile Documentation: [https://txstyle.org/](https://txstyle.org/)
+* promptworks Textile Reference Manual: [https://www.promptworks.com/textile](https://www.promptworks.com/textile)
+* Redmine Textile Formatting: [http://www.redmine.org/projects/redmine/wiki/RedmineTextFormattingTextile](http://www.redmine.org/projects/redmine/wiki/RedmineTextFormattingTextile)
diff --git a/th-th/pascal.th.html.markdown b/th-th/pascal.th.html.markdown
new file mode 100644
index 00000000..bf1da958
--- /dev/null
+++ b/th-th/pascal.th.html.markdown
@@ -0,0 +1,236 @@
+---
+language: Pascal
+filename: learnpascal.pas
+contributors:
+ - ["Ganesha Danu", "http://github.com/blinfoldking"]
+ - ["Keith Miyake", "https://github.com/kaymmm"]
+translators:
+ - ["Worajedt Sitthidumrong", "https://bitbucket.org/wrj"]
+lang: th-th
+---
+
+> Pascal (ปาสกาล) เป็นภาษาโปรแกรมมิ่งทั้งแบบ imperative และ procedural ที่ออกแบบโดย Niklaus Wirth (นิเคล้า เวิร์ท) เมื่อปี 1968-69 และเผยแพร่ตอน 1970 โดยเน้นให้เป็นภาษาที่เล็ก มีประสิทธิภาพ เพื่อเสริมการเขียนโปรแกรมที่มีแนวปฏิบัติที่ดีด้วยการใช้โครงสร้างของตัวภาษา และโครงสร้างข้อมูลมากำกับ ชื่อของภาษานี้ตั้งเป็นเกียรติให้กับนักคณิตศาสตร์ชาวฝรั่งเศส, นักปรัชญา และนักฟิสิกส์ ชื่อ Blaise Pascal (เบลส ปาสกาล) ข้อมูลจาก : [วิกิพีเดีย][1]
+
+การคอมไพล์และรันโค้ดภาษาปาสกาลนี้ สามารถใช้ปาสกาลคอมไพลเลอร์ฟรีชื่อ Free Pascal ได้ โดย [ดาวน์โหลดที่นี่][2]
+
+ด้านล่างจะเป็นโครงสร้างภาษาหลัก ๆ ที่ต้องเข้าใจก่อน ปาสกาลจะเป็นภาษาที่เข้มงวดกับโครงสร้างโค้ดมาก
+
+```pascal
+//โปรแกรมปาสกาล
+//คอมเม้นต์เขียนแบบนี้ ใช้สแลชสองครั้ง
+{
+ แต่ถ้าต้องการคอมเม้นหลาย ๆ บรรทัด
+ ให้ใช้ วงเล็บปีกกา (curly brackets)
+ เนื้อหาอยู่บรรทัดเดียวกันกับปีกกาได้
+}
+
+//อย่างแรก ต้องประกาศ ชื่อโปรแกรม
+program learn_pascal; //<-- ห้ามลืม semicolon
+
+const
+ {
+ ประกาศค่าคงที่ (constant) ในบล็อคนี้
+ }
+type
+ {
+ ประกาศชนิดข้อมูลของเราเองที่นี่ ไม่ว่าจะเป็น ชนิดข้อมูลทั่วไป
+ หรือจะเป็นคลาส
+ }
+var
+ {
+ ตัวแปร ในภาษาปาสกาล ไม่เหมือนกับภาษาอื่น ๆ
+ เพราะต้องประกาศในบล็อค var ก่อนใช้งานเสมอ
+ }
+
+//มาถึงส่วนโปรแกรมหลัก หรือ main fucntion นั่นเอง
+begin
+ {
+ โค้ดเราทำงานอะไร อย่างไร ก็เริ่มรันจากตรงนี้
+ }
+end. // จบการทำงานของ _โปรแกรม_ เราจะจบด้วย จุลภาค "."
+```
+
+โค้ดต่อจากนี้ จะเป็นการอธิบายประกาศตัวแปรของปาสกาล
+
+```pascal
+//การประกาศตัวแปร ทำได้แบบนี้
+//var ชื่อตัวแปร : ชนิด ;
+var a:integer;
+var b:integer;
+
+//หรือแบบที่นิยมมากกว่า คือเอามาเก็บในบล็อค var ทั้งหมด
+var
+ a : integer;
+ b : integer;
+
+//ถ้าจะเอาแบบสั้น ๆ บรรทัดเดียว ก็ทำได้ ทำได้พร้อมกันหลาย ๆ ตัวแปรด้วย
+var a,b : integer;
+```
+
+โค้ดตัวอย่างนี้เป็นโปรแกรม Learn\_More ที่เป็นโครงสร้างโปรแกรมง่าย ๆ ที่จบสมบูรณ์หนึ่งโปรแกรม มีบล็อค program, const, type, main (Begin..End.)
+
+```pascal
+program Learn_More;
+// มาต่อเรื่อง ชนิดของข้อมูล (data types) และ ตัวดำเนินการ (operators)
+
+const
+ PI = 3.141592654;
+ GNU = 'GNU''s Not Unix';
+ // ค่าคงที่ ให้ตั้งชื่อเป็น ตัวพิมพ์ใหญ่ ทั้งหมด ใช้กับชนิดข้อมูลใดๆ ก็ได้
+ // ค่าคงที่ ก็ตามชื่อเลย กำหนดค่าแล้ว ไม่สามารถเปลี่ยนแปลงได้ขณะรัน
+
+// การประกาศชนิดข้อมูลของเราเอง
+// "ชนิด" ของตัวแปรสองแบบนี้ จะนำไปใช้ด้านล่าง
+type
+ ch_array : array [0..255] of char;
+ // อะเรย์ เป็นชนิดข้อมูลที่มี ความยาว/ช่องเก็บข้อมูล และ ชนิดข้อมูล
+ // โค้ดด้านบน เป็นการประกาศอะเรย์ของตัวอักษา 255 ตัวอักษา
+ // ซึ่งได้ ความยาว/ช่องเก็บข้อมูลในตัวแปรตัวนี้ 256 ช่องที่เป็นข้อความ
+ md_array : array of array of integer;
+ // ด้านบนนี้ เป็นตัวอย่าง อะเรย์สองมิติของเลขจำนวนเต็ม
+ // อะเรย์ ยังซ้อนกับอะเรย์ได้อีกด้วย ทำให้สร้าง อะเรย์หลายมิติได้
+ // เรายังสามารถสร้าง อะเรย์ที่มีความยาวช่องเท่ากับศูนย์ (0) ได้อีกด้วย
+ // ซึ่งทำให้เกิด อะเรย์ที่จำนวนช่องยืดหยุ่นได้ (dymaically sized array)
+
+// การประกาศตัวแปร : ชื่อตัวแปรเหล่านี้จะนำไปใช้ด้านล่างต่อไป
+var
+ int, c, d : integer;
+ // ประกาศในบล็อค var มีตัวแปรสามตัวเป็นอินทีเจอร์
+ // ชนิดจำนวนเต็ม แบบ 16 bit มีช่วงข้อมูล [-32,768.. 32,767]
+ // »int« ในที่นี้เป็น "ชื่อตัวแปร" ที่ต้นฉบับตั้งให้สอดคล้องกับชนิดข้อมูล
+ // อย่าสับสนกับบางภาษาที่มีชนิด int ประกาศหน้าชื่อตัวแปร
+ r : real;
+ // ตัวแปร r เป็นชนิดเรียล (real) หรือเลขทศนิยม
+ // real มีช่วงข้อมูล [3.4E-38..3.4E38]
+ bool : boolean;
+ // ข้อมูลชนิดบูเลียน (boolean) มีค่าได้สองแบบ คือ True/False
+ ch : char;
+ // ตัวแปร ch เป็นชนิดตัวอักษร (ชาร์? คาร์?) หรือคาแรกเตอร์
+ // ตัวอักษรเป็นแบบ ASCII 8 bit ดังนั้นจะไม่ใช่ UTF, Unicode
+ str : string;
+ // ตัวแปรสตริงจะเก็บข้อความ หรือ char หลาย ๆ ตัว
+ // ชนิดข้อมูลนี้ไม่เป็นมาตรฐานภาษาแต่คอมไพเลอร์ปาสกาลก็มักจะมีให้
+ // ทั่ว ๆ ไปแล้ว จะเป็นอะเรย์ของ char ความยาวตั้งต้น 255
+ s : string[50];
+ // แบบนี้คือ กำหนดความยาว string เอง ให้เก็บ char 50 ตัว
+ // แบบนี้ก็ทำให้ประหยัดหน่วยความจำมากขึ้นนั่นเอง
+ my_str: ch_array;
+ // ชนิดตัวแปร ใช้เป็นชนิดที่เรากำหนดเองก็ได้ อย่างตอนนี้
+ // ch_array เป็น "ชนิดข้อมูล" ที่เราสร้างขึ้นมาในบล็อค type
+ my_2d : md_array;
+ // ตัวแปรแบบอะเรย์ที่ไม่ประกาศขนาด (dynamically sized array)
+ // ก่อนเอาไปใช้จริงต้องระบุขนาดก่อนใช้เสมอ
+
+ // ชนิดข้อมูลแบบ integer เพิ่มเติม
+ b : byte; // มีช่วงข้อมูล [0..255]
+ shi : shortint; // มีช่วงข้อมูล [-128..127]
+ smi : smallint; // มีช่วงข้อมูล [-32,768..32,767] (standard Integer)
+ w : word; // มีช่วงข้อมูล [0..65,535]
+ li : longint; // มีช่วงข้อมูล [-2,147,483,648..2,147,483,647]
+ lw : longword; // มีช่วงข้อมูล [0..4,294,967,295]
+ c : cardinal; // ก็คือ longword
+ i64 : int64; // มีช่วงข้อมูล
+ // [-9223372036854775808..9223372036854775807]
+ qw : qword; // มีช่วงข้อมูล [0..18,446,744,073,709,551,615]
+
+ // ชนิดข้อมูลแบบ real เพิ่มเติม
+ rr : real; // มีช่วงข้อมูลที่ขึ้นกับระบบปฏิบัติการ
+ // (เช่นเป็นแบบ 8-bit, 16-bit, ฯลฯ)
+ rs : single; // มีช่วงข้อมูล [1.5E-45..3.4E38]
+ rd : double; // มีช่วงข้อมูล [5.0E-324 .. 1.7E308]
+ re : extended; // มีช่วงข้อมูล [1.9E-4932..1.1E4932]
+ rc : comp; // มีช่วงข้อมูล [-2E64+1 .. 2E63-1]
+
+Begin
+ // การกำหนดค่าตัวแปรให้ขณะประกาศ
+ int := 1;
+ r := 3.14;
+ ch := 'a'; // ใช้ single quote เหมือนกันทั้ง char และ string
+ str := 'apple';
+ bool := true;
+ // ภาษาปาสกาล มอง "ชื่อเฉพาะ" แบบไม่สนพิมพ์ใหญ่พิมพ์เล็ก
+ // (case-insensitive language)
+ // ตัวดำเนินการแบบคณิตศาสตร์ (arithmethic operation)
+ int := 1 + 1; // int = 2 ซึ่งจะกำหนดทับค่าเดิมด้านบนที่เคยประกาศ
+ int := int + 1; // int = 2 + 1 = 3 นำค่าตอนนี้ (2) มา +1 ได้ 3
+ int := 4 div 2; // int = 2 หารด้วย div จะได้ผลเป็น integer เสมอ
+ int := 3 div 2; // int = 1
+ int := 1 div 2; // int = 0
+
+ bool := true or false; // bool = true
+ bool := false and true; // bool = false
+ bool := true xor true; // bool = false
+
+ r := 3 / 2; // หารด้วย / จะได้ผลเป็น real เสมอ
+ r := int; // เรากำหนดค่า integer ให้ตัวแปร real ได้
+ // แต่ทำกลับกัน โดยกำหนด real ให้ integer ไม่ได้
+
+ c := str[1]; // กำหนดค่าแรกใน array str ให้ตัวแปร c ที่เป็น char
+ str := 'hello' + 'world'; // เรารวม string เข้าด้วยกันด้วย +
+
+ my_str[0] := 'a'; // กำหนดค่าให้ string เฉพาะตำแหน่งแบบอะเรย์ทั่วไป
+
+ setlength(my_2d,10,10); // ปรับขนาดอะเรย์ 2 มิติให้เป็นขนาด 10x10
+ // โดยตัวแปร my_2d นี้สร้างแล้วด้านบน
+ for c := 0 to 9 do // อะเรย์เริ่มจาก 0 และจบที่ ความยาว-1
+ for d := 0 to 9 do // ตัวนับ (counter) จำเป็นต้องประกาศก่อนใช้
+ my_2d[c,d] := c * d;
+ // กำหนดอะเรย์หลายมิติ ด้วยการใช้วงเล็บก้ามปู (square brackets)
+
+End.
+// จบโปรแกรมบริบูรณ์ ด้วย "."
+```
+
+ด้านล่าง เป็นตัวอย่างการเขียนโปรแกรมปาสกาลชื่อ Functional\_Programming
+
+```pascal
+program Functional_Programming;
+
+Var
+ i, dummy : integer;
+
+function factorial_recursion(const a: integer) : integer;
+{ ทำการคำนวณแฟคทอเรียลซ้ำ ๆ ของเลขจำนวนเต็ม โดยผ่านพารามิเตอร์ a
+ ถ้าจะประกาศตัวแปรโลคอลในฟังก์ชั่น ก็ทำได้ โดยการใช้บล็อค var ภายในฟังก์ชั่น
+ เช่น :
+ var
+ local_a : integer;
+}
+Begin
+ If a >= 1 Then
+ { ฟังก์ชั่นนี้คืนค่ากลับ โดยการกำหนดค่าที่ผ่านทางพารามิเตอร์ a
+ นำมาคูณกับฟังก์ชั่นที่ผ่าน a-1 สุดท้ายก็กำหนดค่าลงไปให้กับฟังก์ชั่นตรงๆ }
+ factorial_recursion := a * factorial_recursion(a-1)
+ Else
+ factorial_recursion := 1;
+End; // จบ ฟังก์ชั่น ด้วย ";" หลัง End ไม่เหมือนกับจบ โปรแกรม ที่จะใช้ "."
+
+procedure get_integer(var i : integer; dummy : integer);
+{ เรารับ input จากผู้ใช้มาเก็บใน parameter i ที่เป็น integer ที่ตั้งขึ้นใน
+ พารามิเตอร์ โดยใช้ var ประกาศ ทำให้ค่าที่รับเข้ามาจะเปลี่ยนปรับได้จาก
+ ภายนอกการประกาศพารามิเตอร์นี้ ส่วน dummy เป็นตัวแปรที่ปรับเปลี่ยนได้
+ "เฉพาะจากภายในฟังก์ชั่น,โพรซีเยอร์นั้น ๆ }
+Begin
+ write('Enter an integer: ');
+ readln(i);
+ dummy := 4; // dummy จะไม่ทำให้ค่าที่ได้รับมาครั้งแรกใน main block เปลี่ยน
+End;
+
+//--------------------//
+// main program block
+//--------------------//
+Begin
+ dummy := 3;
+ get_integer(i, dummy);
+ writeln(i, '! = ', factorial_recursion(i));
+ // พิมพ์ค่า i!
+ writeln('dummy = ', dummy); // จะให้ค่าเป็น '3' เสมอ
+ // เพราะจะไม่เปลี่ยนเนื่องด้วย
+ // การประกาศพารามิเตอร์ใน
+ // โพรซีเยอร์ get_integer ด้านบน
+End.
+
+```
+
+[1]: https://en.wikipedia.org/wiki/Pascal_(programming_language)
+[2]: https://www.freepascal.org/
diff --git a/th-th/typescript.th.html.markdown b/th-th/typescript.th.html.markdown
new file mode 100644
index 00000000..5395c2a7
--- /dev/null
+++ b/th-th/typescript.th.html.markdown
@@ -0,0 +1,259 @@
+---
+language: TypeScript
+contributors:
+ - ["Philippe Vlérick", "https://github.com/pvlerick"]
+ - ["Worajedt Sitthidumrong", "https://bitbucket.org/wrj"]
+filename: learntypescript-th.ts
+lang: th-th
+---
+
+TypeScript เป็นภาษาที่มีเป้าหมายเพื่อทำให้การพัฒนาซอฟต์แวร์ขนาดใหญ่ด้วย JavaScript ทำได้ง่ายขึ้น โดยที่ TypeScript ได้เพิ่มแนวคิดที่พบทั่วไป อาทิ classes, modules, interfaces, generics และ static typing (ไม่บังคับ) เข้าไปในภาษา JavaScript ดังนั้น TypeScript ก็เลยเป็น Super Set ของ JavaScript อีกที โค้ด JavaScript ทุกส่วน ก็คือโค้ดที่ทำงานได้ถูกต้องใน TypeScript ทำให้เราเพิ่ม TypeScript เข้าไปใช้ในโปรเจคการพัฒนาของเราได้ไม่ยากเลย เพราะ TypeScript คอมไพล์ผลลัพธ์ออกมาเป็น JavaScript ในท้ายสุดอยู่ดี
+
+บทความนี้จะเน้นเฉพาะ syntax ส่วนขยายของ TypeScript ซึ่งจะไม่รวมกับที่มีใน [JavaScript](/docs/javascript)
+
+การทดสอบเขียน TypeScript เริ่มได้ง่าย ๆ โดยเข้าไปที่
+[Playground](http://www.typescriptlang.org/Playground) ซึ่งคุณจะเขียนโค้ดพร้อม autocomplete และเห็นเลยว่ามันจะแปลงมาเป็นผลลัพธ์แบบ JavaScript อย่างไร
+
+```ts
+// TypeScript มี data type พื้นฐาน 3 แบบ
+let isDone: boolean = false;
+let lines: number = 42;
+let name: string = "Anders";
+
+// แต่เราก็สามารถละการบอกชนิดได้ โดยชนิดตัวแปรก็จะปรับชนิดของเขาจากข้อมูลที่กำหนดให้โดยตรง
+let isDone = false;
+let lines = 42;
+let name = "Anders";
+
+// ถ้าไม่รู้ ก็กำหนดเป็นชนิด "Any" ได้
+let notSure: any = 4;
+notSure = "maybe a string instead";
+notSure = false; // โอเค ตอนนี้เป็น Boolean แน่ ๆ
+
+// ใช้ const สำหรับสร้าง ค่าคงที่
+const numLivesForCat = 9;
+numLivesForCat = 1; // Error
+
+// สำหรับ collections มี typed arrays และ generic arrays
+// ก็คือ อะเรย์บอกชนิด และ อะเรย์เจเนอริก ตามลำดับ
+let list: number[] = [1, 2, 3];
+// ในอีกทางหนึ่ง สร้างเป็นอะเรย์ชนิด generic array
+let list: Array<number> = [1, 2, 3];
+
+// และสำหรับ enumerations:
+enum Color { Red, Green, Blue };
+let c: Color = Color.Green;
+
+// สุดท้าย, "void" ใช้เมื่อเป็นกรณีพิเศษที่ฟังก์ชันไม่ส่งค่ากลับ
+function bigHorribleAlert(): void {
+ alert("I'm a little annoying box!");
+}
+
+// ฟังก์ชั่น (Functions) เป็นสิ่งที่มีความสำคัญมาเป็นอันดับหนึ่ง รองรับการใช้ "fat arrow" ในการสร้าง lambda function และ type inference
+
+// สไตล์ต่อไปนี้มีค่าเท่ากันกับบรรทัดที่ยกตัวอย่างด้านล่าง เพราะคอมไพเลอร์จะมองเหมือนกัน และได้ JavaScript แบบเดียวกัน
+let f1 = function (i: number): number { return i * i; }
+// อนุมานชนิดที่ส่งกลับ หรือ type inferred
+let f2 = function (i: number) { return i * i; }
+// เขียนแบบ "Fat arrow" แต่บอกชนิดส่งกลับ
+let f3 = (i: number): number => { return i * i; }
+// เขียนแบบ "Fat arrow" แต่อนุมานชนิดส่งกลับ
+let f4 = (i: number) => { return i * i; }
+// เขียนแบบ "Fat arrow" อนุมานชนิดส่งกลับ พร้อมกับไม่มีวงเล็บ แปลว่าไม่ต้องมี return keyword ด้วย
+let f5 = (i: number) => i * i;
+
+// Interfaces นั้นเป็นเหมือนเราออกแบบโครงสร้าง คุณสมบัติต่าง ๆ ตอนเอาไปใช้ จะต้องเป็นไปตาม interface นั้น ๆ เหมือนกับเป็นการกำหนดสเป็คของ "ชนิดข้อมูล"
+interface Person {
+ name: string;
+ // Optional properties กำหนดด้วย "?"
+ age?: number;
+ // และมี function พร้อมชนิดได้ใน interface
+ move(): void;
+}
+
+// Object นี้ implements "Person" interface ทำให้มันเป็นชนิด Person และมันก็มี property name และ function move()
+let p: Person = { name: "Bobby", move: () => { } };
+// Objects นี้เป็นชนิด Person ด้วย และมี optional property หรือ age?: นั่นเอง
+let validPerson: Person = { name: "Bobby", age: 42, move: () => { } };
+// ไม่ใช่ Person เพราะ age: ต้องเป็น number เท่านั้น ตามข้อกำหนดใน interface Person
+let invalidPerson: Person = { name: "Bobby", age: true };
+
+// Interfaces ยังนำมาใช้ในลักษณะของ function ได้อีกด้วย
+interface SearchFunc {
+ (source: string, subString: string): boolean;
+}
+// เฉพาะชนิด parameters เท่านั้นที่สำคัญ ชื่อของมันไม่จำเป็นต้องเหมือน
+let mySearch: SearchFunc;
+mySearch = function (src: string, sub: string) {
+ return src.search(sub) != -1;
+}
+
+// สมาชิกใน class จะเข้าถึงได้แบบ public เป็นค่าปริยาย
+class Point {
+ // Properties
+ // ตั้งค่า Properties ของ class นี้
+ x: number;
+
+ // Constructor
+ // เราใส่ public/private keywords ตรงนี้ได้ มีผลเหมือนกันกับกำหนด x ด้านบน
+ // ในตัวอย่าง y มีการกำหนดเช่นเดียวกับ x แต่พิมพ์สั้นกว่า
+ // สังเกตว่า มีการกำหนดค่าปริยายให้ parameters ได้ด้วย
+
+ constructor(x: number, public y: number = 0) {
+ this.x = x;
+ }
+
+ // Functions
+ dist() { return Math.sqrt(this.x*this.x + this.y*this.y); }
+
+ // Static members
+ static origin = new Point(0, 0);
+}
+
+// Classes สามารถระบุชนิด interface ที่ต้องการได้ตรง ๆ ด้วยเช่นโค้ดด้านล่าง
+// แต่อะไรที่จะ implement มานั้น ถ้าไม่ได้กำหนดไว้ใน constructor ก็จะเกิดข้อผิดพลาดตอนคอมไพล์
+class PointPerson implements Person {
+ name: string // ตรงนี้จะผิด แก้ไขโดยการไปสร้างตัวรับค่าเข้ามาผ่านทาง constructor
+ move() {}
+}
+
+let p1 = new Point(10, 20);
+let p2 = new Point(25); //y เป็น 0 เพราะกำหนดค่าปริยายไว้ให้แล้ว
+
+// Inheritance การสืบทอดคุณสมบัติ
+class Point3D extends Point {
+ constructor(x: number, y: number, public z: number = 0) {
+ super(x, y); // เราจะต้องเรียกใช้ super class constructor โดยตรง
+ }
+
+ // Overwrite ฟังก์ชั่นที่มีอยู่เดิมใน Point
+ dist() {
+ let d = super.dist();
+ return Math.sqrt(d * d + this.z * this.z);
+ }
+}
+
+// Modules ใช้เป็นกลุ่มของ class เราใช้ "." เป็นตัวแบ่ง sub modules
+// อย่างกรณีนี้จะเป็น Module.Class เช่น Geometry.Square
+module Geometry {
+ export class Square {
+ constructor(public sideLength: number = 0) {
+ }
+ area() {
+ return Math.pow(this.sideLength, 2);
+ }
+ }
+}
+
+let s1 = new Geometry.Square(5);
+
+// เราทำให้เรียกใช้ง่ายขึ้นโดยการใช้ alias มาอ้างชื่อ module แบบเดียวกับบางภาษา เช่น Python
+import G = Geometry;
+
+let s2 = new G.Square(10);
+
+// Generics
+// Classes
+class Tuple<T1, T2> {
+ constructor(public item1: T1, public item2: T2) {
+ }
+}
+
+// Interfaces
+interface Pair<T> {
+ item1: T;
+ item2: T;
+}
+
+// และ functions
+let pairToTuple = function <T>(p: Pair<T>) {
+ return new Tuple(p.item1, p.item2);
+};
+
+let tuple = pairToTuple({ item1: "hello", item2: "world" });
+
+// เราเรียกใช้ไฟล์ definition แบบนี้:
+/// <reference path="jquery.d.ts" />
+
+// Template Strings ( คือ strings ที่ใช้ backticks ครอบ — "`" ปุ่มบนซ้ายคีย์บอร์ด )
+// แทรกข้อความใน String ด้วย Template Strings
+let name = 'Tyrone';
+let greeting = `Hi ${name}, how are you?`
+// Strings หลายบรรทัดก็ทำได้ใน Template Strings
+let multiline = `This is an example
+of a multiline string`;
+
+// READONLY: ความสามารถใหม่ใน TypeScript 3.1
+interface Person {
+ readonly name: string;
+ readonly age: number;
+}
+
+var p1: Person = { name: "Tyrone", age: 42 };
+p1.age = 25; // Error แน่นอน เพราะ p1.age ถูกกำหนดเป็น read-only
+
+var p2 = { name: "John", age: 60 }; // สังเกตว่า p2 ไม่ได้กำหนดเป็น Person
+var p3: Person = p2; // ทำได้ เป็น read-only alias ของ p2 และกำหนดเป็น Person
+p3.x = 35; // Error p3.x ก็เป็น read-only
+p2.x = 45; // Ok ทำได้แต่ก็จะเปลี่ยนค่า p3.x ด้วย เพราะ p3 เป็น alias ของ p2
+
+class Car {
+ readonly make: string;
+ readonly model: string;
+ readonly year = 2018;
+
+ constructor() {
+ this.make = "Unknown Make"; // อนุญาตให้กำหนดค่าได้ใน constructor แม้ว่าจะ read-only
+ this.model = "Unknown Model"; // อนุญาตให้กำหนดค่าได้ใน constructor แม้ว่าจะ read-only
+ }
+}
+
+let numbers: Array<number> = [0, 1, 2, 3, 4];
+let moreNumbers: ReadonlyArray<number> = numbers;
+moreNumbers[5] = 5; // Error, สมาชิกอะเรย์เป็น read-only แปลว่า ห้ามแก้ไข
+moreNumbers.push(5); // Error, push method ใช้ไม่ได้ เพราะมันจะไปแก้ไข read-only array
+moreNumbers.length = 3; // Error, เพราะ length ก็ต้อง read-only
+numbers = moreNumbers; // Error, method ที่ทำให้อะเรย์เปลี่ยนได้จะไม่อนุญาต
+
+// Tagged Union Types สำหรับโมเดลสเตท ที่อาจจะมีได้หลายๆ สเตท
+type State =
+ | { type: "loading" }
+ | { type: "success", value: number }
+ | { type: "error", message: string };
+
+ประกาศ const state: State;
+if (state.type === "success") {
+ console.log(state.value);
+} else if (state.type === "error") {
+ console.error(state.message);
+}
+
+// Iterators และ Generators
+
+// ประโยคแบบ for..of
+// การทำซ้ำกับ ลิสต์ของค่าในออปเจ็คต์
+let arrayOfAnyType = [1, "string", false];
+for (const val of arrayOfAnyType) {
+ console.log(val); // 1, "string", false
+}
+
+let list = [4, 5, 6];
+for (const i of list) {
+ console.log(i); // 4, 5, 6
+}
+
+// ประโยคแบบ for..in
+// การทำซ้ำกับ ลิสต์ของคีย์ในออปเจ็คต์
+for (const i in list) {
+ console.log(i); // 0, 1, 2
+}
+
+
+```
+
+## อ่านเพิ่มเติมที่
+ * [TypeScript Official website] (http://www.typescriptlang.org/)
+ * [TypeScript language specifications] (https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)
+ * [Anders Hejlsberg - Introducing TypeScript on Channel 9] (http://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript)
+ * [Source Code on GitHub] (https://github.com/Microsoft/TypeScript)
+ * [Definitely Typed - repository for type definitions] (http://definitelytyped.org/)
diff --git a/tmux.html.markdown b/tmux.html.markdown
index 1214a5ba..1c2c2da3 100644
--- a/tmux.html.markdown
+++ b/tmux.html.markdown
@@ -78,6 +78,7 @@ combinations called 'Prefix' keys.
p # Change to the previous window
{ # Swap the current pane with the previous pane
} # Swap the current pane with the next pane
+ [ # Enter Copy Mode to copy text or view history.
s # Select a new session for the attached client
interactively
diff --git a/toml.html.markdown b/toml.html.markdown
index 980563f9..2b234965 100755
--- a/toml.html.markdown
+++ b/toml.html.markdown
@@ -32,7 +32,7 @@ boolean = true
dateTime = 1979-05-27T07:32:00-08:00
scientificNotation = 1e+12
"key can be quoted" = true # Both " and ' are fine
-"key may contains" = "letters, numbers, underscores, and dashes"
+"key may contain" = "letters, numbers, underscores, and dashes"
# A bare key must be non-empty, but an empty quoted key is allowed
"" = "blank" # VALID but discouraged
@@ -102,9 +102,10 @@ boolMustBeLowercase = true
# Datetime #
############
-date1 = 1979-05-27T07:32:00Z # follows the RFC 3339 spec
-date2 = 1979-05-27T07:32:00 # without offset
-date3 = 1979-05-27 # without offset nor time
+date1 = 1979-05-27T07:32:00Z # UTC time, following RFC 3339/ISO 8601 spec
+date2 = 1979-05-26T15:32:00+08:00 # with RFC 3339/ISO 8601 offset
+date3 = 1979-05-27T07:32:00 # without offset
+date4 = 1979-05-27 # without offset or time
####################
# COLLECTION TYPES #
@@ -116,7 +117,7 @@ date3 = 1979-05-27 # without offset nor time
array1 = [ 1, 2, 3 ]
array2 = [ "Commas", "are", "delimiters" ]
-array3 = [ "Don't mixed", "different", "types" ]
+array3 = [ "Don't mix", "different", "types" ]
array4 = [ [ 1.2, 2.4 ], ["all", 'strings', """are the same""", '''type'''] ]
array5 = [
"Whitespace", "is", "ignored"
@@ -170,6 +171,9 @@ c = 1
[a]
d = 2
+# Will generate the following in JSON:
+# { "a": {"b": {"c": 1}, "d": 2 } }
+
# You cannot define any key or table more than once. Doing so is invalid.
# DO NOT DO THIS
@@ -219,36 +223,56 @@ emptyTableAreAllowed = true
name = "Nail"
sku = 284758393
color = "gray"
+```
+The equivalent in JSON would be:
+```json
+{
+ "products": [
+ {
+ "name": "array of table",
+ "sku": 7385594937,
+ "emptyTableAreAllowed": true
+ },
+ {},
+ {
+ "name": "Nail",
+ "sku": 284758393,
+ "color": "gray"
+ }
+ ]
+}
+```
+```toml
# You can create nested arrays of tables as well. Each double-bracketed
# sub-table will belong to the nearest table element above it.
[[fruit]]
- name = "apple"
+ name = "apple" # I am a property in fruit table/map
- [fruit.Geometry]
+ [fruit.geometry]
shape = "round"
- note = "I am an fruit's property"
+ note = "I am a property in geometry table/map"
[[fruit.color]]
name = "red"
- note = "I am an array's item in apple"
+ note = "I am an array item in apple fruit's table/map"
[[fruit.color]]
name = "green"
- note = "I am in the same array than red"
+ note = "I am in the same array as red"
[[fruit]]
name = "banana"
[[fruit.color]]
name = "yellow"
- note = "I am an array's item too but banana's one"
-```
-
-In JSON land, this code will be:
+ note = "I am an array item in banana fruit's table/map"
+```
+The equivalent in JSON would be:
```json
+
{
"fruit": [
{
diff --git a/tr-tr/c++-tr.html.markdown b/tr-tr/c++-tr.html.markdown
new file mode 100644
index 00000000..9d65cf9c
--- /dev/null
+++ b/tr-tr/c++-tr.html.markdown
@@ -0,0 +1,1076 @@
+---
+language: c++
+lang: tr-tr
+filename: learncpp-tr.cpp
+contributors:
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Matt Kline", "https://github.com/mrkline"]
+ - ["Geoff Liu", "http://geoffliu.me"]
+ - ["Connor Waters", "http://github.com/connorwaters"]
+ - ["Ankush Goyal", "http://github.com/ankushg07"]
+ - ["Jatin Dhankhar", "https://github.com/jatindhankhar"]
+ - ["Adem Budak", "https://github.com/p1v0t"]
+---
+
+C++
+[yaratıcısı Bjarne Stroustrup'a göre](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
+
+- "daha iyi bir C" yapmak
+- veri soyutlamayı desteklemek
+- nesneye yönelik programlamayı deskteklemek
+- tipten bağımsız programlamayı desteklemek
+
+için tasarlanmış bir sistem programlama dilir.
+
+Sözdizimi daha yeni dillerden daha zor veya karmaşık olsa da işlemcinin doğrudan çalıştırabileceği
+native komutlara derlenerek, donanım üzerinde (C gibi) sıkı bir kontrol sağlar, bunu yaparken
+tipten bağımsızlık, exception'lar ve sınıflar gibi yüksek-seviyeli özellikleri destekler.
+Bu hız ve kullanışlılık C++'ı en çok kullanılan dillerden biri yapar.
+
+```c++
+//////////////////////
+// C ile karşılaştırma
+//////////////////////
+
+// C++ _neredeyse_ C'nin bir üstkümesidir, değişken tanımı, basit tipleri
+// ve fonksiyonları için temelde aynı sözdizimini paylaşır.
+
+// Aynı C gibi, programın başlangıç noktası bir integer döndüren
+// main fonksiyonudur.
+// Bu değer programın bitiş statüsünü belli eder.
+// Daha fazla bilgi için bknz http://en.wikipedia.org/wiki/Exit_status .
+
+int main(int argc, char** argv)
+{
+ // Komut satırı argümanları C'de olduğu gibi argv ve argc ile geçilir
+ // argc, argüman sayısını belli eder,
+ // argv, argümanları belli eden, C-stili string'lerin (char*) dizisidir.
+ // İlk argüman çağrılan programın adıdır.
+ // Eğer argümanları umursamıyorsan, argv ve argc kullanılmayabilir
+ // int main() gibi
+
+ // 0 çıkış durumu başarıyı belirtir.
+ return 0;
+}
+
+// Bunlara rağmen C++ aşağıdaki noktalarda farklılaşır:
+
+// C++'ta, karakterler char türündendir
+sizeof('c') == sizeof(char) == 1
+
+// C'de, karakterler int türündendir
+sizeof('c') == sizeof(int)
+
+
+// C++ katı bir prototip kuralına sahiptir
+void func(); // fonksiyon argüman kabul etmez
+
+// C'de
+void func(); // fonksiyon herhangi bir sayıda argüman kabul edebilir
+
+// C++'da NULL yerine nullptr kullanılır
+int* ip = nullptr;
+
+// C standard başlıkları başına "c" eklenip, sondaki .h
+// kullanılmadan C++'ta kullanılabilir
+#include <cstdio>
+
+int main()
+{
+ printf("Hello, world!\n");
+ return 0;
+}
+
+//////////////////////////////////
+// Fonksiyonun fazladan yüklenmesi
+//////////////////////////////////
+
+// C++ herbir fonksiyonun farklı parametereler
+// aldığı fonksiyon fazladan yüklenmesini desktekler
+
+void print(char const* myString)
+{
+ printf("String %s\n", myString);
+}
+
+void print(int myInt)
+{
+ printf("My int is %d", myInt);
+}
+
+int main()
+{
+ print("Hello"); // void print(const char*) fonksiyonunu çağırır.
+ print(15); // void print(int) fonksiyonunu çağırır.
+}
+
+////////////////////////////////
+// Default fonksiyon argümanları
+////////////////////////////////
+
+// Eğer çağırıcı tarafından fonksiyona argüman sağlanmamışsa,
+// fonksiyona default argüman verebilirsin
+
+void doSomethingWithInts(int a = 1, int b = 4)
+{
+ // Burada int'lerle birşeyler yap
+}
+
+int main()
+{
+ doSomethingWithInts(); // a = 1, b = 4
+ doSomethingWithInts(20); // a = 20, b = 4
+ doSomethingWithInts(20, 5); // a = 20, b = 5
+}
+
+// Default argümanlar, argüman listesinin sonunda yer almalı.
+
+void invalidDeclaration(int a = 1, int b) // Hata!
+{
+}
+
+
+/////////////////////////
+// Namespace(İsim uzayı)
+/////////////////////////
+
+// Namespace'ler değişken, fonksiyon ve diğer bildirimlerin
+// kapsama alanını ayırır.
+// Namespace'ler içiçe geçebilir.
+
+namespace First {
+ namespace Nested {
+ void foo()
+ {
+ printf("This is First::Nested::foo\n");
+ }
+ } // Nested namespace'inin sonu
+} // First namespace'inin sonu
+
+namespace Second {
+ void foo()
+ {
+ printf("This is Second::foo\n");
+ }
+}
+
+void foo()
+{
+ printf("This is global foo\n");
+}
+
+int main()
+{
+ // Second namespace'i içinideki tüm sembolleri mevcut kapsama alanına dahil eder.
+ // Dikkat edersen artık yalnızca foo() çağrısı çalışmayacaktır çünkü hangi
+ // namespace'ten çağrıldığı açık değildir.
+ using namespace Second;
+
+ Second::foo(); // "This is Second::foo" yazdırıır
+ First::Nested::foo(); // "This is First::Nested::foo" yazdırır
+ ::foo(); // "This is global foo" yazdırır.
+}
+
+///////////////
+// Input/Output
+///////////////
+
+// C++'ta input ve output stream'leri kullanır.
+// cin, cout ve cerr,sırasıyla, stdin, stdout, ve stderr'i temsil eder.
+// << araya ekleme ve >> aradan çıkarma operatörüdür.
+
+#include <iostream> // I/O stream'lerini dahil etmek için
+
+using namespace std; // Streamler std namespace'i içindedir(standard kütüphane)
+
+int main()
+{
+ int myInt;
+
+ // stdout (veya terminal/screen)'ta çıktı verir
+ cout << "Enter your favorite number:\n";
+ // Girdiyi alır
+ cin >> myInt;
+
+ // cout ayrıca formatlanabilir
+ cout << "Your favorite number is " << myInt << "\n";
+ // prints "Your favorite number is <myInt>"
+
+ cerr << "Used for error messages";
+}
+
+//////////////
+// String'ler
+/////////////
+
+// String'ler C++'ta nesnedir ve pek çok üye fonksiyonu vardır
+#include <string>
+
+using namespace std; // String'ler de std namespace'i içindedir. (standard kütüphane)
+
+string myString = "Hello";
+string myOtherString = " World";
+
+// + eklemek için kullanıldır
+cout << myString + myOtherString; // "Hello World"
+
+cout << myString + " You"; // "Hello You"
+
+// C++'ta stringler are mutable'dır (değişebilir).
+myString.append(" Dog");
+cout << myString; // "Hello Dog"
+
+
+///////////////////////
+// Reference (Referans)
+///////////////////////
+
+// C'deki pointer'lara ek olarak
+// C++ _reference_'lara sahiptir.
+// Bunlar bir kere atandınğında tekrardan atanamayan pointer'dır
+// ve null olamaz.
+// Değişkenin kendisiyle aynı sözdizimine sahiptir:
+// Değerine ulaşmak için * ihtiyaç yoktur ve
+// atama için & (address of) kullanılmaz.
+
+using namespace std;
+
+string foo = "I am foo";
+string bar = "I am bar";
+
+
+string& fooRef = foo; // Bu foo'nun reference'ını oluşturur.
+fooRef += ". Hi!"; // foo'yu reference'ı üzerinden değiştirir.
+cout << fooRef; // "I am foo. Hi!" yazdırır.
+
+// "fooRef"e yeniden atama yapmaz. Bu "foo = bar" denktir ve bu satırdan sonra
+// foo == "I am bar" olur
+cout << &fooRef << endl; // foo'un adresini yazdırır
+fooRef = bar;
+cout << &fooRef << endl; //Hala foo'nun adresini yazdırır
+cout << fooRef; //"I am bar" yazdırır
+
+// fooRef'in adresi aynı kalır yani hala foo'nun adresidir.
+
+const string& barRef = bar; // bar'a const reference oluşturur
+// C'de olduğu gibi, const değerler (pointer'lar ve reference'ler) değiştirilemez.
+barRef += ". Hi!"; // Hata, const reference'ler değiştirilemez.
+
+// Kısa bir ekleme: reference'lere devam etmeden önce, geçici nesne konseptinden
+// bahsetmeliyiz. Mesela aşadaki gibi bir kod var:
+string tempObjectFun() { ... }
+string retVal = tempObjectFun();
+
+// Bu iki satırda aslında ne oluyor:
+// - tempObjectFun fonksiyonundan bir string nesnesi dönüyor
+// - dönmüş olan nesneyle yeni bir string oluşturuyor
+// - dönmüş olan nesne yok ediliyor
+// İşte bu dönen nesneye geçici nesne denir. Geçici nesneler fonksiyon nesne
+// döndürdüğünde oluşturulur ve ifade işini bitirdiğinde yok edilir (Aslında,
+// standard'ın söylediği şey bu ama derleyiciler bu davranışı değiştirmemize
+// izin veriyor. Daha fazla detay için "return value optimization" diye
+// aratabilirsin. Sonuç olarak aşağıdaki kodda:
+foo(bar(tempObjectFun()))
+
+// foo ve bar'ın varolduğunu kabul ediyoruz, tempObjectFun'dan dönen nesne
+// bar'a geçti ve foo çağrılmadan önce yokedildir.
+
+// Şimdi reference'lara dönelim. "ifadenin sonunda" kuralının bir istisnası
+// eğer geçici nesne const reference'a geçildiyse oratya çıkar, bu durumda
+// nesnenin ömrü mevcut kapsama alanına kadar uzar:
+
+void constReferenceTempObjectFun() {
+ // constRef geçici nesneyi alır ve bu durum fonksiyonun sonuna kadar geçerlidir.
+ const string& constRef = tempObjectFun();
+ ...
+}
+
+// C++11 ile gelen diğer bir reference geçici nesnelere özeldir. Bu türden birden
+// bir tip tanımlayamazsın ama aşırı yüklenme sırasında bu tipler öncelik alır:
+void someFun(string& s) { ... } // Regular reference
+void someFun(string&& s) { ... } // Geçici nesneye reference
+
+string foo;
+someFun(foo); // regular reference'ı çağırır
+someFun(tempObjectFun()); // geçici reference'ı çağırır
+
+/////////////////////
+// Enum
+/////////////////////
+
+// Enum'lar sabit değerler yapmak için kullanılır ve çoğunlukla kodun daha okunaklı
+// olması için kullanılır
+
+enum ECarTypes
+{
+ Sedan,
+ Hatchback,
+ SUV,
+ Wagon
+};
+
+ECarTypes GetPreferredCarType()
+{
+ return ECarTypes::Hatchback;
+}
+
+// C++11 ile beraber bir tipi enum'a atamanın kolay bir yolu var, bu enum'un istenen
+// tipe dönüştürmek için kullanışlı bir yöntem
+enum ECarTypes : uint8_t
+{
+ Sedan, // 0
+ Hatchback, // 1
+ SUV = 254, // 254
+ Hybrid // 255
+};
+
+void WriteByteToFile(uint8_t InputValue)
+{
+ // Serialize the InputValue to a file
+}
+
+void WritePreferredCarTypeToFile(ECarTypes InputCarType)
+{
+ // enum uint8_t tipine dönüştürüldü
+ WriteByteToFile(InputCarType);
+}
+
+// Diğer yandan enum'ların yanlışlıkla integer tipini veya diğer enumlara dönüşmesini
+// istemiyorsan enum class olarak tanımlayabilirsin
+enum class ECarTypes : uint8_t
+{
+ Sedan, // 0
+ Hatchback, // 1
+ SUV = 254, // 254
+ Hybrid // 255
+};
+
+void WriteByteToFile(uint8_t InputValue)
+{
+ // Serialize the InputValue to a file
+}
+
+void WritePreferredCarTypeToFile(ECarTypes InputCarType)
+{
+ // ECarTypes, uint8_t tipinde olmasına rağmen, "enum class" olarak
+ // tanımlandığından derlenmeyecektir!
+ WriteByteToFile(InputCarType);
+}
+
+///////////////////////////////////////////
+// Sınıflar ve nesneye yönelik proglamalama
+///////////////////////////////////////////
+
+// Sınıflara(class) ilk örnek
+#include <iostream>
+
+// Sınıfı tanımla.
+// Sınıflar genelde header (.h veya .hpp) dosyalarında tanımlanır.
+class Dog {
+ // Üye değişkenler ve fonksiyonlar default olarak private'dir.
+ std::string name;
+ int weight;
+
+// Aşağıda, "private:" veya "protected:" bulunana kadar
+// bütün üyeler public'tir.
+public:
+
+ // Default constructor
+ Dog();
+
+ // Üye fonksiyon bildirimi (gerçeklenimi aşağıda)
+ // Dikkat ederseniz using namespace std; yerine
+ // std::string kullandık.
+ // Hiçbir zaman header dosyasında "using namespace std;" kullanma.
+ void setName(const std::string& dogsName);
+
+ void setWeight(int dogsWeight);
+
+ // Nesnenin durumunu değiştirmeyen fonksiyonlar const ile işaretlenmelidir
+
+ // Türetilen sınıflarda fonksiyonu override edebilmek için başına
+ // _virtual_ eklenmelidir.
+ // Fonksiyonlar, performanslar ilgili nedenlerden ötürü default olarak virtual değildir
+ virtual void print() const;
+
+ // Fonksiyonlar class içinde de tanımlanabilir.
+ // Bu şekille tanımlanan fonksiyonlar otomatik olarak inline olur.
+ void bark() const { std::cout << name << " barks!\n"; }
+
+ // C++ constructor'ların yanında destructor'da sağlar.
+ // Bunlar nesne silindiğinde veya scope'un dışına çıktığında çağrılır.
+ // Bu RAII gibi güçlü paradigmaları etkin kılar.
+ // (aşağıda açıklandı)
+ // Eğer sınıf kendisinden türetiliyorsa, destructor virtual olmalıdır,
+ // eğer virtual değilse, türetilmiş sınıfın destructor'ı nesne, ana sınıf
+ // referans'ı veya pointer'ı üzerinden yok edildiğinde, çağrılmayacaktır.
+ virtual ~Dog();
+
+}; // class tanımının sonuda noktalı virgül(;) olmalıdır.
+
+// Sınıfın üye fonksiyonları genelde .cpp dosyaları içinde gerçeklenir.
+Dog::Dog()
+{
+ std::cout << "A dog has been constructed\n";
+}
+
+// Objects (such as strings) should be passed by reference
+// Nesneler (string gibi) reference ile fonksiyonlara geçilmelidir
+// Eğer nesneleri değiştirilecekse reference ile fonksiyonlara geçilmelidir,
+// değiştirilmeyecekse const reference ile geçilmelidir.
+void Dog::setName(const std::string& dogsName)
+{
+ name = dogsName;
+}
+
+void Dog::setWeight(int dogsWeight)
+{
+ weight = dogsWeight;
+}
+
+// Dikkat edersen "virtual" yalnızca bildirimde gerekli, tanımlamada değil.
+void Dog::print() const
+{
+ std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
+}
+
+Dog::~Dog()
+{
+ std::cout << "Goodbye " << name << "\n";
+}
+
+int main() {
+ Dog myDog; // "A dog has been constructed" yazdırır
+ myDog.setName("Barkley");
+ myDog.setWeight(10);
+ myDog.print(); // "Dog is Barkley and weighs 10 kg" yazdırır.
+ return 0;
+} // "Goodbye Barkley" yazdırır.
+
+// Inheritance(Miras)
+
+// Bu sınıf, Dog sınıfında public ve protected olan herşeyi miras alır,
+// private olanları da miras alır ama, public ve protected sınıflar aracılıyla
+// yapılmıyorsa, doğrudan erişemez.
+class OwnedDog : public Dog {
+
+public:
+ void setOwner(const std::string& dogsOwner);
+
+ // print fonksiyonunun davranışını bütün OwnedDogs sınıfı için override eder
+ // (üstünden geçer, kendine uyarlar).
+ // bknz http://en.wikipedia.org/wiki/Polymorphism_(computer_science)
+ // override anahtar sözcüpü kullanılma da olur ama kullanılması aslında bir temel
+ // temel sınıf fonksiyonunun üzerinden geçtiğimizi gösterir.
+ void print() const override;
+
+private:
+ std::string owner;
+};
+
+// Bu arada takip eden .cpp dosyasında:
+
+void OwnedDog::setOwner(const std::string& dogsOwner)
+{
+ owner = dogsOwner;
+}
+
+void OwnedDog::print() const
+{
+ Dog::print(); // Ana dog sınıfındaki print fonksiyonunu çağırır
+ std::cout << "Dog is owned by " << owner << "\n";
+ // "Dog is <name> and weights <weight>"
+ // "Dog is owned by <owner>"
+ // yazdırır
+}
+
+/////////////////////////////////////////////////////
+// ilk değer atama ve Operatörün fazladan yüklenmesi
+/////////////////////////////////////////////////////
+
+// C++ dilinde +, -, *, /, gibi operatörlerin davranışını fazladan yükleyebilirsiniz.
+// Bu, operator her kullandınıldığında çağrılan bir fonksiyon tanımlamasıyla yapılır.
+
+#include <iostream>
+using namespace std;
+
+class Point {
+public:
+ // Üye değişkenkenlere default değer atanabilir.
+ double x = 0;
+ double y = 0;
+
+ // Default constructor
+ Point() { };
+
+ Point (double a, double b) :
+ x(a),
+ y(b)
+ { /* İlk değer atama dışında birşey yapma */ }
+
+ // + operatorünün fazladan yükle.
+ Point operator+(const Point& rhs) const;
+
+ // += operatorünü fazladan yükle
+ Point& operator+=(const Point& rhs);
+
+ // - ve -= operatorleri fazladan yüklemek de mantıklı olurdu
+ // ama kısa tutmak için burda değinmedik.
+};
+
+Point Point::operator+(const Point& rhs) const
+{
+ // yeni bir nokta oluştur ve bunu rhs ile topla
+ return Point(x + rhs.x, y + rhs.y);
+}
+
+Point& Point::operator+=(const Point& rhs)
+{
+ x += rhs.x;
+ y += rhs.y;
+ return *this;
+}
+
+int main () {
+ Point up (0,1);
+ Point right (1,0);
+ // Bu Point + operatorünü çağırır
+ Point result = up + right;
+ // "Result is upright (1,1)" yazdırır.
+ cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
+ return 0;
+}
+
+////////////////////////
+// Şablonlar (Templates)
+////////////////////////
+
+// Şablonlar C++ dilinde tipten bağımsız programlama için kullanılır.
+
+// Zaten aşina olduğun tipten bağımsız programlamayla başladık. Bir tip parametresi
+// alan fonksiyon veya sınıf tanımlamaık için:
+template<class T>
+class Box {
+public:
+ // Bu sınıfta T, herhangi bir tip için kullanılabilir.
+ void insert(const T&) { ... }
+};
+
+// Derleme esnasında derleyici aslında, parametreleri yerine konmuş şekilde herbir şablonu üretir,
+// bu yüzden sınıfın tam tanımı her çağrılma sırasında var olmak zorundadır. Bu nedenle şablon sınıflarını
+// tamamen header dosyalarında görürsün.
+
+// Stack'ta şablon sınıfın bir örneğini oluşturmak için:
+Box<int> intBox;
+
+// ve, anladığın gibi, kullanabilirsin:
+intBox.insert(123);
+
+// Tabi, şablonları içiçe geçirebilirsin:
+Box<Box<int> > boxOfBox;
+boxOfBox.insert(intBox);
+
+// C++11'den önce iki '>' arasına boşluk koymak zorundaydık yoksa sağa kaydırma
+// operatörü olarak algılanabilirdi.
+
+// Bazen şunu da görebilirsin
+// template<typename T>
+// 'class' ve 'typename' anahtar sözcükleri çoğunlukla
+// birbirlerinin yerine kullanılabilir. Tam açıklama için, bknz.
+// http://en.wikipedia.org/wiki/Typename
+// (evet, bu anahtar sözcüğün kendi Wikipedia sayfası var).
+
+// Benzer şekilde, bir şablon fonksiyon:
+template<class T>
+void barkThreeTimes(const T& input)
+{
+ input.bark();
+ input.bark();
+ input.bark();
+}
+
+// Dikkat edersen tip parametresi hakkında birşey belirtilmedi. Derleyici bunları üretecek
+// ve her parametre geçişinde tip-kontrolü yapacaktır, bu nedenle de fonksiyon herhangi bir T
+// tipi için çalışacaktır!
+
+Dog fluffy;
+fluffy.setName("Fluffy")
+barkThreeTimes(fluffy); // Üç kere "Fluffy barks" yazdırır.
+
+// Şablonun parametresi sınıf olmak zorunda değildir:
+template<int Y>
+void printMessage() {
+ cout << "Learn C++ in " << Y << " minutes!" << endl;
+}
+
+// Ve template'i daha etkili kod için dışarıdan özelleştirebilirsin.
+// Tabiki gerçek-dünya kullanımlarında özelleştirme bunun kadar kolay değildir.
+// Dikkat edersen, bütün parametreleri dıştan özelleştirmiş olsak bile
+// hala fonksiyonu (veya sınıfı( template olarak tanımlamamız gerekli.
+template<>
+void printMessage<10>() {
+ cout << "Learn C++ faster in only 10 minutes!" << endl;
+}
+
+printMessage<20>(); // "Learn C++ in 20 minutes!" yazdırır
+printMessage<10>(); // "Learn C++ faster in only 10 minutes!" yazdırır
+
+
+///////////////////////////////////////////////
+// İstisnai Durum Yönetimi (Exception Handling)
+///////////////////////////////////////////////
+
+// Standard kütüphane bazı istisnai tipler sağlar
+// (bknz http://en.cppreference.com/w/cpp/error/exception)
+// ama herhangi bir tip de istisnai durum fırlatabilir
+
+#include <exception>
+#include <stdexcept>
+
+// _try_ bloğu içinde fırlatılan bütün istisnai durumlar, takip eden, _catch_ ile
+// yakalanabilir.
+try {
+ // _new_ kullanarak heap'ten istisnai durumlar için yer ayırma
+ throw std::runtime_error("A problem occurred");
+}
+
+// istisnai durumlar nesne ise const reference ile yakala
+catch (const std::exception& ex)
+{
+ std::cout << ex.what();
+}
+
+// Bir önceki _catch_ bloğundan kaçan istisnai durum burda yakala
+catch (...)
+{
+ std::cout << "Unknown exception caught";
+ throw; // Tekrardan istisnai durum fırlatır
+}
+
+///////
+// RAII
+///////
+
+// RAII, "Resource Acquisition Is Initialization" kelimelerinin kısaltmasıdır.
+// Bu Türkçe, "Kaynak alımı aynı zamanda ilk değer atamasıdır." olarak çevrilebilir.
+// Bunu basitçe constructor ile ayrılan hafızanın destructor ile iade edilmesi olarak
+// düşünebiliriz.
+
+// Bunun ne şekilde kullanışlı olduğunu görmek için
+// bir C dosyasının, dosya işleme biçimine bakabiliriz:
+void doSomethingWithAFile(const char* filename)
+{
+ // Başlangıçta herşeyin yolunda gittiğini düşünelim
+
+ FILE* fh = fopen(filename, "r"); // Dosyayı okuma modunda aç
+
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+
+ fclose(fh); // Dosyayı kapat
+}
+
+// Malesef hatalarla başa çıkmaya çalışırken işler hızlıca karmaşıklaşır.
+// Mesela fopen'ın başarısız olduğunu varsayalım, ve doSoomethingWithTheFile ve
+// doSomethingWithIt hata kodları gönderdi.
+// (İstisnai durumlar yonetimi, hata koduna tercih ediler bir yöntemdir, ama bazı
+// programcılar, özellikle C arkaplanı olanlar, aynı fikirde değildir.
+// Bu durumda her bir fonksiyon çağrısını kontrol etmeli ve bir problem oluştuysa
+// dosyayı kapatmalıyız.
+
+bool doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r"); // Dosyayı okuma modunda aç
+ if (fh == nullptr) // Başarısız olma durumunda dönen değer null olur
+ return false; // Başarısız olma durumunu çağırıcıya bildir
+
+ // Başarısız olma durumunda her iki fonksiyonun da false döndürdüğünü kabul edelim
+ if (!doSomethingWithTheFile(fh)) {
+ fclose(fh); // Dosyayı kapatalım, akıntı olmasın.
+ return false; // Hatayı bildir
+ }
+ if (!doSomethingElseWithIt(fh)) {
+ fclose(fh); // Dosyayı kapatalım, akıntı olmasın.
+ return false; // Hatayı bildir
+ }
+
+ fclose(fh); // Dosyayı kapat
+ return true; // Başarı durumunu ifade eder
+}
+
+// C programcıları biraz goto kullanarak bu durumu temizler
+bool doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r");
+ if (fh == nullptr)
+ return false;
+
+ if (!doSomethingWithTheFile(fh))
+ goto failure;
+
+ if (!doSomethingElseWithIt(fh))
+ goto failure;
+
+ fclose(fh); // Dosyayı kapat
+ return true; // Başarı durumunu ifade eder
+
+failure:
+ fclose(fh);
+ return false; // Hatayı bildir
+}
+
+// Eğer fonksiyon istisnai durum yönetimi araçlarını kullanırsa
+// işler daha temiz olur ama hala en iyi durumun altında kalır.
+void doSomethingWithAFile(const char* filename)
+{
+ FILE* fh = fopen(filename, "r");
+ if (fh == nullptr)
+ throw std::runtime_error("Could not open the file.");
+
+ try {
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+ }
+ catch (...) {
+ fclose(fh); // Hata durumunda dosyayı kapattığından emin ol
+ throw; // Sonra, tekrardan istisnai durum fırlat
+ }
+
+ fclose(fh); // Dosyayı kapat
+ // Herşey başarılı
+}
+
+// Şimdi aynı şeyi C++'ın dosya stream sınıfıyla (fstream) karşılaştıralım
+// fstream, dosyayı kapatmak için kendi destructor'ını kullanır.
+// Destructor'ın, nesne scope dışına çıktığında otomatik olarak çağrıldığını
+// hatırlayın.
+void doSomethingWithAFile(const std::string& filename)
+{
+ std::ifstream fh(filename); // Dosyayı aç
+
+ // Dosyayla birşeyler yap
+ doSomethingWithTheFile(fh);
+ doSomethingElseWithIt(fh);
+
+} // Dosya, destructor tarafından otomatik olarak kapatıldı
+
+// Bunun _çok büyük_ avantajları var:
+// 1. Ne olursa olursun,
+// kaynak (bu örnekte dosya tutucusu) temizlenecektir.
+// Destructor doğru yazıldığında,
+// Tutucuyu kapatmayı unutma ve kaynak akıntısı _imkansız_dır.
+// 2. Kodun çok daha temiz olduğuna dikkat edin.
+// Destructor, dosyayı kapatma işini, endilenmemize gerek kalmadan
+// arka planda halleder.
+// 3. Kod, istisnai durumlara karşı korunaklıdır.
+// İstisnai durum fonksiyonun herhangi bir yerinde fırlatılabilir ve
+// temizleme işi gene de yapılır.
+
+// Bütün C++ kodu deyimleri RAII prensibini tüm kaynakları için kullanır.
+// Ek örnekler şunlardır:
+// - unique_ptr ve shared_ptr ile hafıza kullanımı
+// - Tutucular - standard kütüphane linked list,
+// vector (yani kendiliğinden boyu ayarlanan dizi), hash map vs.
+// scope'un dışına çıktığında içerini otomatik olarak yok eden tüm yapılar.
+// - lock_guard ve unique_lock kullanan mutex'ler
+
+///////////////////////////////////////
+// Lambda İfadeleri (C++11 ve yukarısı)
+///////////////////////////////////////
+
+// lambda'lar, tam olarak çağrıldığı yerde bir anonim fonksiyon tanımlamak
+// veya fonksiyona argüman geçmek için uygun bir yoldur.
+
+// Mesela, pair'lardan oluşan bir vector'u, pair'ın ikinci değerine
+// göre sıralamak isteyelim
+
+vector<pair<int, int> > tester;
+tester.push_back(make_pair(3, 6));
+tester.push_back(make_pair(1, 9));
+tester.push_back(make_pair(5, 0));
+
+// sort fonksiyonuna üçüncü argüman olarak lambda ifadesini geç
+// sort, <algorithm> başlığında tanımlı
+
+sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs) {
+ return lhs.second < rhs.second;
+ });
+
+// Lambda ifadesinin söz dizimine dikkat edin,
+// lambda'daki [], değişkenleri "tutmak" için kullanılır
+// "Tutma listesi", fonksiyon gövdesinde nelerin, ne şekilde erişilebilir olduğunu tanımlar
+// Şunlardan biri olabilir:
+// 1. bir değer : [x]
+// 2. bir referans : [&x]
+// 3. mevcut scope içindeki herhangi bir değişkene referans ile [&]
+// 4. 3 ile aynı, ama değer ile [=]
+// Mesela:
+vector<int> dog_ids;
+// number_of_dogs = 3;
+for(int i = 0; i < 3; i++) {
+ dog_ids.push_back(i);
+}
+
+int weight[3] = {30, 50, 10};
+
+// Mesela dog_ids vector'unu dog'ların ağırlıklarına göre sıralamak isteyelim
+// Yani en sonunda şöyle olmalı: [2, 0, 1]
+
+// Burada lambda ifadesi oldukça kullanışlıdır
+
+sort(dog_ids.begin(), dog_ids.end(), [&weight](const int &lhs, const int &rhs) {
+ return weight[lhs] < weight[rhs];
+ });
+// Dikkat edersen "weight" dizisini referans ile aldık.
+// C++'da lambdalar hakkında daha fazla bilgi için : http://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11
+
+//////////////////////////////////
+// Akıllı For (C++11 ve yukarısı)
+//////////////////////////////////
+
+// Akıllı for döngüsünü bir tutucuyu dolaşmak için kullanabilirsin
+int arr[] = {1, 10, 3};
+
+for(int elem: arr){
+ cout << elem << endl;
+}
+
+// Tutucunun elemanlarının tipi için endişe etmeden "auto" kullanabilirsin
+// Mesela:
+
+for(auto elem: arr) {
+ // arr dizisinin elemanlarıyla ilgili bir şeyler yap
+}
+
+////////////////
+// Güzel Şeyler
+////////////////
+
+// C++ dilinin bakış açısı yeni başlayanlar için (hatta dili iyi bilenler için bile)
+// şaşırtıcı olabilir.
+// Bu bölüm, ne yazık ki, büyük ölçüde tam değil; C++ kendi ayağına ateş edilebilecek kolay
+// dillerden biridir.
+
+// private metodları override edebilirsin!
+class Foo {
+ virtual void bar();
+};
+class FooSub : public Foo {
+ virtual void bar(); // Foo::bar fonksiyonu override edilir!
+};
+
+
+// 0 == false == NULL (çoğu zaman)!
+bool* pt = new bool;
+*pt = 0; // 'pt'nin gösterdiği değere false atar.
+pt = 0; // 'pt'ye null pointer atar. Her iki satır uyarısız derlenir.
+
+// nullptr'ın bu meselenin bazılarını çözmesi beklenmiştir:
+int* pt2 = new int;
+*pt2 = nullptr; // Derlenmez.
+pt2 = nullptr; // pt2'ye null atar.
+
+// bool tipleri için bir istisna vardır.
+// Bu null pointer'ları if(!ptr) ile test etmek içindir.
+// ama sonuç olarak bir bool değerine nullptr atayabilirsin!
+*pt = nullptr; // '*pt' değeri bir boll olmasına rağmen, hala derlenir!
+
+
+// '=' != '=' != '='!
+// Calls Foo::Foo(const Foo&) or some variant (see move semantics) copy
+// Foo::Foo(const Foo&) çağrısını veya kopyalama constructor'ının bir çeşidinin çağrısınıyapar(taşıma semantiklerine bknz.)
+Foo f2;
+Foo f1 = f2;
+
+// Foo::operator=(Foo&) çağrısını yapar.
+Foo f1;
+f1 = f2;
+
+
+///////////////////////////////////////
+// Tuple (C++11 ve yukarısı)
+///////////////////////////////////////
+
+#include<tuple>
+
+// Ana fikir olarak, Tuple, eski veri yapılarına (C'deki struct'lar) benzer ama isimli veri üyeleri yerine
+// elemanlarına tuple içindeki sırasına göre erişilir.
+
+// Tuple'ı inşa ederek başlayalım
+// değişkenleri tuple içinde paketliyoruz
+auto first = make_tuple(10, 'A');
+const int maxN = 1e9;
+const int maxL = 15;
+auto second = make_tuple(maxN, maxL);
+
+// 'first' tuple'ının değerlerini yazdırma
+cout << get<0>(first) << " " << get<1>(first) << "\n"; // 10 A yazdırır
+
+// 'second' tuple'ının değerlerini yazdırma
+cout << get<0>(second) << " " << get<1>(second) << "\n"; // 1000000000 15 yazdırır
+
+// Değişkenleri tuple'dan çıkarma
+
+int first_int;
+char first_char;
+tie(first_int, first_char) = first;
+cout << first_int << " " << first_char << "\n"; // 10 A yazdırır
+
+// Ayrıca şu şekide de tuple oluşturabiliriz.
+
+tuple<int, char, double> third(11, 'A', 3.14141);
+// tuple_size, tuple'daki eleman sayısını (constexpr olarak) döndürür
+
+cout << tuple_size<decltype(third)>::value << "\n"; // 3 yazdırır
+
+// tuple_cat, tuple'daki tüm elemanları aynı sırada birleştirir.
+
+auto concatenated_tuple = tuple_cat(first, second, third);
+// concatenated_tuple = (10, 'A', 1e9, 15, 11, 'A', 3.14141) olur
+
+cout << get<0>(concatenated_tuple) << "\n"; // 10 yazdırır
+cout << get<3>(concatenated_tuple) << "\n"; // 15 yazdırır
+cout << get<5>(concatenated_tuple) << "\n"; // 'A' yazdırır
+
+
+/////////////////////
+// Tutucular
+/////////////////////
+
+// Tutucular veya Standard Şablon Kütüphanesi(STL) önceden tanımlanmış şablonlar sunar.
+// Bunlar elemanları için ayrılan hafıza alanını yönetir
+// ve onlara erişim ve değiştirmek için üye fonksiyonlar sağlar
+
+// Bazı tutucular şunlardır:
+
+// Vector (Dinamik Dizi)
+// koşma anında nesne dizisi veya list oluşturmamızı sağlar
+#include <vector>
+string val;
+vector<string> my_vector; // vector'ü tanımla
+cin >> val;
+my_vector.push_back(val); // val değerini my_vector vectörüne push edecektir
+my_vector.push_back(val); // val değerini yeniden push edecektir (şu an iki elemanı var)
+
+// vector içinde dolaşmak için iki seçenek var:
+// ya klasik döngüyle (0. index'ten son index'e kadar iterasyon yaparak)
+for (int i = 0; i < my_vector.size(); i++) {
+ cout << my_vector[i] << endl; // vector'ün elemanlarına uşamak için [] operatörünü kullanabiliriz
+}
+
+// ya da iteratör kulllanarak:
+vector<string>::iterator it; // vector için iterator tanımla
+for (it = my_vector.begin(); it != my_vector.end(); ++it) {
+ cout << *it << endl;
+}
+
+// Set(Küme)
+// Set'ler benzersiz(unique) elemanları belirli bir sırada saklayan tutuculardır.
+// Set, benzersiz değerleri, herhangi bir fonksiyon veya kod gerektirmeksizin, sıralı olarak
+
+#include<set>
+set<int> ST; // int tipi için set tanımlar
+ST.insert(30); // ST kümesini 30 değerini dahil eder
+ST.insert(10); // ST kümesini 10 değerini dahil eder
+ST.insert(20); // ST kümesini 20 değerini dahil eder
+ST.insert(30); // ST kümesini 30 değerini dahil eder
+// Şimdi kümedeki elemanlar aşağıdaki gibidir
+// 10 20 30
+
+// Bir eleman silmek için:
+ST.erase(20); // 20 değerine sahip elemanı siler
+// Set ST: 10 30
+// Iterator kullanarak Set içinde iterasyon yapmak için:
+set<int>::iterator it;
+for(it=ST.begin();it<ST.end();it++) {
+ cout << *it << endl;
+}
+// Output:
+// 10
+// 30
+
+// Tutucuyu tamamen silmek için Tutucu_Adi.clear() kullanırız
+ST.clear();
+cout << ST.size(); // ST kümesinin eleman sayısı(size)nı yazdırır.
+// Output: 0
+
+// NOTE: Aynı elemanlari içerebilen kümle için multiset kullanırız
+
+// Map(Harita)
+// Map, elemanları anahtar değer, haritalanmış değer şeklinde özel bir sırada saklar.
+// anahtar_değer -> haritalanmış_değer
+
+#include<map>
+map<char, int> mymap; // Anahtar char ve değer int olacak şekilde map tanımlar
+
+mymap.insert(pair<char,int>('A',1));
+// 1 değeri için A anahtar değerini ekler
+mymap.insert(pair<char,int>('Z',26));
+// 26 değeri için Z anahtar değerini ekler
+
+// Map'te dolaşma
+map<char,int>::iterator it;
+for (it=mymap.begin(); it!=mymap.end(); ++it)
+ std::cout << it->first << "->" << it->second << '\n';
+// Output:
+// A->1
+// Z->26
+
+// Anahtar'a atanmış değeri bulmak için
+it = mymap.find('Z');
+cout << it->second;
+
+// Output: 26
+
+
+/////////////////////////////////////////////
+// Mantıksal ve Bit seviyesindeki operatörler
+/////////////////////////////////////////////
+
+// Pek çok C++ operatörleri diğer dillerdekiyle aynıdır
+
+// Mantıksal operatörler
+
+// C++, bool ifadelerinde Kısa-devre değerlendirmesini kullanır yani ikinci argüman yalnızca ilk argüman
+// ifadenin değerine karar vermek için yeterli değilse çalıştırılır
+
+true && false // **mantıksal ve** işlemi yapılır ve yanlış sonucu üretilir
+true || false // **mantıksal veya** işlemi yapılır ve true sonucu üretilir
+! true // **mantıksal değil** işlemi yapılır ve yalnış sonucu üretilir
+
+// Sembolleri kullanmak yerine onlara karşılık gelen anahtar kelimeler kullanılabilir
+true and false // **mantıksal ve** işlemi yapılır ve yanlış sonucu üretilir
+true or false // **mantıksal veya** işlemi yapılır ve true sonucu üretilir
+not true // **mantıksal değil** işlemi yapılır ve yalnış sonucu üretilir
+
+// Bit seviyesindeki operatörler
+
+// **<<** Sola kaydırma operatörü
+// << bitleri sola kaydırır
+4 << 1 // 4'ün bitlerini 1 sola kaydırır ve 8 sonucunu verir
+// x << n, x * 2^n olarak düşünülebilir
+
+
+// **>>** Sağa kaydırma operatörü
+// >> bitleri sağa kaydırır
+4 >> 1 // 4'ün bitlerini 1 sağa kaydırır ve 2 sonucunu verir
+// x >> n, x / 2^n olarak düşünülebilir
+
+~4 // Bit seviyesinde değil işlemini gerçekleştirir
+4 | 3 // Bit seviyesinde veya işlemini gerçekleştirir
+4 & 3 // Bit seviyesinde ve işlemini gerçekleştirir
+4 ^ 3 // Bit seviyesinde xor işlemini gerçekleştirir
+
+// Eşdeğer anahtar kelimeler
+compl 4 // Bit seviyesinde değil işlemini gerçekleştirir
+4 bitor 3 // Bit seviyesinde veya işlemini gerçekleştiri
+4 bitand 3 // Bit seviyesinde ve işlemini gerçekleştirir
+4 xor 3 // Bit seviyesinde xor işlemini gerçekleştirir
+
+
+```
+İleri okuma:
+
+* Güncel bir referans [CPP Reference](http://cppreference.com/w/cpp) adresinde bulunabilir.
+* Ek kaynaklar [CPlusPlus](http://cplusplus.com) adresinde bulunabilir.
+* Dilin temellerini ve kodlama ortamını belirleyen bir öğretici [TheChernoProject - C ++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb) adresinde bulunabilir.
diff --git a/tr-tr/c-tr.html.markdown b/tr-tr/c-tr.html.markdown
index 33544765..4ef12527 100644
--- a/tr-tr/c-tr.html.markdown
+++ b/tr-tr/c-tr.html.markdown
@@ -477,11 +477,11 @@ typedef void (*my_fnp_type)(char *);
[K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language)'in bir kopyasını bulundurmak mükemmel olabilir
-Diğer bir iyi kaynak ise [Learn C the hard way](http://c.learncodethehardway.org/book/)
+Diğer bir iyi kaynak ise [Learn C the hard way](http://learncodethehardway.org/c/)
It's very important to use proper spacing, indentation and to be consistent with your coding style in general.
Readable code is better than clever code and fast code. For a good, sane coding style to adopt, see the
-[Linux kernel coding stlye](https://www.kernel.org/doc/Documentation/CodingStyle).
+[Linux kernel coding style](https://www.kernel.org/doc/Documentation/CodingStyle).
Diğer taraftan google sizin için bir arkadaş olabilir.
diff --git a/tr-tr/clojure-tr.html.markdown b/tr-tr/clojure-tr.html.markdown
new file mode 100644
index 00000000..5ebe5ce6
--- /dev/null
+++ b/tr-tr/clojure-tr.html.markdown
@@ -0,0 +1,491 @@
+---
+language: clojure
+lang: tr-tr
+filename: learnclojure-tr.clj
+contributors:
+ - ["Adam Bard", "http://adambard.com/"]
+ - ["Seçkin KÜKRER", "https://leavenha.github.io"]
+translators:
+ - ["Seçkin KÜKRER", "https://leavenha.github.io"]
+---
+
+[JVM]: https://tr.wikipedia.org/wiki/Java_sanal_makinesi
+[STM]: https://en.wikipedia.org/wiki/Software_transactional_memory
+
+Clojure, Lisp dialekti, barınan bir dildir. [JVM][JVM] üzerinde barınıyor. Clojure, Lisp'in tüm gücü ve kendi mantalitesi ile mükemmel bir genel-amaçlı programlama dilidir. Clojure, Eş-zamanlı programlama, Makrolar, Fonksiyonel Programlama, Tembel yapılar ve daha fazlasını vaadediyor.
+
+(Bu örnekleri çalıştırmak için Clojure 1.2 versionu veya daha yenisine sahip olmalısınız.)
+
+
+```clojure
+; Noktalı Virgül, satırı yorumlamak için kullanılır.
+
+; Clojure programları formlardan meydana gelir,
+; Parantezlerle çevirili değerler, boşluk ile ayrılır. --Virgül ile değil--
+;
+; Clojure okuyucusu*, listedeki ilk elemanı çağırılacak bir fonksiyon
+; Veya makro, geri kalan ifadeleri o çağırıma argüman olarak kabul eder.
+;
+
+; Bir dosyadaki ilk çağırım isim-uzayı tanımlamak için `ns` olmalı.
+(ns clojure-öğren)
+
+;
+; Bir diğer yorumlama seçeneği de, ifade-içi. Bu diyez (`#`), ve alt çizgi
+; İle başlar ve herhangi bir s-ifade'ye uygulanabilir.
+;
+#_(bu çağırım değerlendirilmeyecektir)
+
+; Öncelikle fonksiyon çağırımları ve temel işlemler:
+
+; Örnek bir fonksiyon çağırımı:
+; (örnek-bir-fonksiyon ilk-argüman ikinci-argüman)
+
+; `str` aldığı argümanları bir karakter katarı olarak geri verir.
+(str "Merhaba" " " "dünya!") ; => "Merhaba dünya!"
+
+; Matematik, oldukça sezgisel ve basit
+(+ 1 1) ; => 2
+(- 2 1) ; => 1
+(* 1 2) ; => 2
+(/ 2 1) ; => 2
+
+; Eşitlik için `=`
+(= 1 1) ; => true
+(= 2 1) ; => false
+
+; `not` beklediğiniz gibi, mantıksal ifadeleri tersine çevirir.
+(not true) ; => false
+
+; Clojure formları, iç-içe çağırılabilir
+; Değerlendirilen çağırımlar bir üst form'a argüman
+; Olarak verilir.
+(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
+
+; Tipler
+;;;;;;;;;;;;;
+
+; Clojure, Java'nın temel tipleri olan mantıksal (boolean),
+; Tam sayılar (int) ve karakter katarlarını (string) kullanır.
+; Değerleri denetlemek için `class` fonksiyonunu kullanın.
+(class 1) ; Tam sayı sabitleri ön-tanımlı olarak `java.lang.Long` ile tanımlanır.
+(class 1.); Kayan noktalı sayı sabitleri
+; Ön-tanımlı olarak `java.lang.Double` ile tanımlanır.
+(class ""); Karakter katarı sabitleri her zaman, --sadece-- çift tırnak
+; ile tanımlanır ve ön-tanımlı olarak `java.lang.String` tipindedir.
+(class false) ; Mantıksal değer sabitleri, `java.lang.Boolean`.
+(class nil); "Null", (tanımsız) değerler `nil` ile tanımlanır.
+
+; Clojure okuyucusu her paranter ifadesini bir çağırım olarak
+; değerlendirdiğinden bir liste tanımlamak için çağırımı durdurmalıyız.
+'(+ 1 2) ; => (+ 1 2)
+; ((quote (+ 1 2)) için bir kısa yoldur)
+
+; Alıntılanmış listeleri çağırabilirsiniz.
+(eval '(+ 1 2)) ; => 3
+
+; Koleksiyonlar ve Ardışıklar
+;;;;;;;;;;;;;;;;;;;
+
+; Listeler bağlı-liste veri yapısı,
+; Vektörler dizi altyapısı kullanır.
+(class '(1 2 3)); => clojure.lang.PersistentList
+(class [1 2 3]); => clojure.lang.PersistentVector
+
+; Bir liste `(1 2 3)` şeklinde gösterilebilir, yazılabilir.
+; Fakat bu listeyi, Alıntılamalıyız --Quote--.
+; Bu, onu bir fonksiyon çağırımı olarak değil,
+; bir liste olarak değerlendirilmesini sağlayacaktır.
+; Ayrıca, `(list 1 2 3)` tamamen `'(1 2 3)` ifadesi ile
+; eşdeğerdir.
+
+; 'Koleksiyonlar' sadece bir veri grubudur.
+; Vektörler ve Listeler, koleksiyondur:
+(coll? '(1 2 3)) ; => true
+(coll? [1 2 3]) ; => true
+
+; 'Ardışıklar' (seqs), bir veri listesinin soyut tanımlamasıdır.
+; Sadece listeler ardışıktır.
+(seq? '(1 2 3)) ; => true
+(seq? [1 2 3]) ; => false
+
+; Bir ardışık, ulaşıldığında sadece giriş verisi vermelidir.
+; Yani, ardışıklar tembel olabilir. | Sonsuz ardışıklar tanımlanabilir.
+(range 4) ; => (0 1 2 3)
+(range) ; => (0 1 2 3 4 ...) (sonsuz bir ardışık)
+(take 4 (range)) ; (0 1 2 3)
+
+; Bu yapılarda ekleme işlemi için `cons` kullanılır.
+(cons 4 [1 2 3]) ; => (4 1 2 3)
+(cons 4 '(1 2 3)) ; => (4 1 2 3)
+
+; `conj` bir koleksiyona en verimli şekilde veri ekler.
+; Bu, listeler için liste başına, vektörler için ise vektör sonuna demektir.
+(conj [1 2 3] 4) ; => [1 2 3 4]
+(conj '(1 2 3) 4) ; => (4 1 2 3)
+
+; `concat` koleksiyonları birleştirmek için kullanılır.
+(concat [1 2] '(3 4)) ; => (1 2 3 4)
+
+; `filter` ve `map` koleksiyonlarla işlem yapmak için
+; ön-tanımlı yüksek-seviyeli fonksiyonlardır.
+;
+; ps: `inc` argümanını bir arttıran bir fonksiyon.
+(map inc [1 2 3]) ; => (2 3 4)
+(filter even? [1 2 3]) ; => (2)
+
+; Koleksiyonları indirgemek için `reduce` kullanılır.
+(reduce + [1 2 3 4])
+; = (+ (+ (+ 1 2) 3) 4)
+; => 10
+
+; Reduce, bir ilk-tanım değeri alabilir.
+(reduce conj [] '(3 2 1))
+; = (conj (conj (conj [] 3) 2) 1)
+; => [3 2 1]
+
+; Fonksiyonlar
+;;;;;;;;;;;;;;;;;;;;;
+
+; Yeni bir fonksiyon oluşturmak için `fn` kullanın.
+; Bir fonksiyon her zaman son ifadesini döndürür.
+(fn [] "Merhaba Dünya!") ; => fn
+
+; Fonksiyonu çağırmak için bir çift paranteze daha ihtiyaç var.
+((fn [] "Merhaba Dünya!")) ; => "Merhaba Dünya!"
+
+; İsim uzayında bir değişken tanımlamak için `def`
+; kullanılır.
+(def x 1)
+x ; => 1
+
+; Bir değişkene fonksiyon değeri atamak için,
+(def merhaba-dünya (fn [] "Merhaba Dünya!"))
+(merhaba-dünya) ; => "Merhaba Dünya!"
+
+; Bu süreci, `defn` ile kısaltabiliriz.
+(defn hello-world [] "Merhaba Dünya!")
+
+; `defn` fonksiyon çağırımındaki üçüncü eleman
+; --vektör-- bir argüman listesidir. Fonksiyonun alacağı
+; argümanları tanımlar.
+(defn merhaba [isim]
+ (str "Merhaba " isim))
+(merhaba "Dünya!") ; => "Merhaba Dünya!"
+
+; Ayrıca, `#()` kısa yolunu, fonksiyon deklare etmek için
+; kullanabiliriz.
+(def merhaba2 #(str "Merhaba " %1))
+(merhaba2 "Dünya!") ; => "Merhaba Dünya!"
+
+; Çok düzeyli fonksiyonlar da tanımlanabilir,
+(defn merhaba3
+ ([] "Merhaba Dünya!")
+ ([isim] (str "Merhaba " isim)))
+(merhaba3) ; => "Merhaba Dünya!"
+(merhaba3 "A. NESİN!") ; => "Hello A. NESİN!"
+
+; Fonksiyonlar, belirsiz-sayıda argüman alabilir,
+; ve bunları sizin için bir ardışıkta depolayabilir.
+(defn argüman-sayısı [& argümanlarım]
+ (str "Verilen argüman sayısı:" (count argümanlarım) ", argümanlar: " argümanlarım))
+(argüman-sayısı "Öğün" "Çalış" "Güven")
+; => "Verilen argüman sayısı:3, argümanlar: ("Öğün" "Çalış" "Güven")"
+
+; Elbette, sıradan ve belirsiz-sayılı fonksiyon argümanlarını
+; harmanlayabilirsiniz.
+(defn merhabalar [ev-sahibi & misafirler]
+ (str "Merhabalar, " misafirler ". Benim adım " ev-sahibi "."))
+(merhabalar "İklim" "Ayşe" "Fatma" "Nurdan")
+; => "Merhabalar, (\"Ayşe\" \"Fatma\" \"Nurdan\"). Benim adım İklim."
+
+
+; Eşlemeler
+;;;;;;;;;;
+
+; Hash-Maps, Array-Maps
+; Hash-Eşlemeleri ve Dizi-Eşlemeleri bir arayüzü paylaşırlar.
+; Hash-Eşlemeleri daha hızlıdır, fakat anahtar sıralaması tutmazlar.
+(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
+(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
+
+; Dizi-Eşlemeleri bir çok işlem sırasında otomatik olarak Hash-Eşlemelerine
+; dönüşürler. Eğer yeterince büyürlerse, endişelenmenize gerek yoktur.
+
+; Eşlemeler anahtar değeri olarak herhangi hash-ifadesi (hashable)
+; alabilirler. Ama çoğunlukla, bu iş için anahtar-kelimeler `keyword`
+; kullanılır.
+; Anahtar-kelimeler, karakter katarları gibidirler, fakat
+; bir kaç artıları vardır.
+(class :a) ; => clojure.lang.Keyword
+
+(def karakterkatarı-eşlemesi {"a" 1, "b" 2, "c" 3})
+karakterkatarı-eşlemesi ; => {"a" 1, "b" 2, "c" 3}
+
+(def anahtar-eşlemesi {:a 1, :b 2, :c 3})
+anahtar-eşlemesi ; => {:a 1, :c 3, :b 2}
+
+; Bu arada, virgüller her zaman boşluk olarak değerlendirilir
+; ve etkisizdirler.
+
+; Bir eşlemeleden fonksiyon notasyonu ile değer çağırmak,
+(karakterkatarı-eşlemesi "a") ; => 1
+(anahtar-eşlemesi :a) ; => 1
+
+; Keyword tipleri kendi değerlerini argüman olarak aldıkları bir
+; eşlemeden değer notasyonu ile çağırabilirler.
+(:b anahtar-eşlemesi) ; => 2
+
+; Bu notasyonu, bir karakter katarı ile denemeyiniz.
+;("a" karakterkatarı-eşlemesi)
+; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
+
+; Verilmemiş bir değeri çağırmak, `nil` döndürecektir.
+(karakterkatarı-eşlemesi "d") ; => nil
+
+; Eşlemelere yeni değerler eklemek için `assoc` kullanırız.
+(def yeni-anahtar-eşlemesi (assoc anahtar-eşlemesi :d 4))
+yeni-anahtar-eşlemesi ; => {:a 1, :b 2, :c 3, :d 4}
+
+; Ama unutmayın, Clojure veri yapıları değişmezdir!
+anahtar-eşlemesi ; => {:a 1, :b 2, :c 3}
+
+; Değer silmek için ise `dissoc` kullanılır.
+(dissoc anahtar-eşlemesi :a :b) ; => {:c 3}
+
+; Kümeler
+;;;;;;
+
+(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
+(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
+
+; `conj` ile bir değer eklenir.
+(conj #{1 2 3} 4) ; => #{1 2 3 4}
+
+; `disj` ile değer çıkarılır.
+(disj #{1 2 3} 1) ; => #{2 3}
+
+; Fonksiyon notasyonu kümelerde de tanımlıdır.
+; Kendi içlerinde değer arayan bir fonksiyon olarak
+; kullanılabilirler.
+(#{1 2 3} 1) ; => 1
+(#{1 2 3} 4) ; => nil
+
+; `clojure.sets` isim-uzayında daha fazla fonksiyon vardır.
+
+; Kullanışlı Formlar
+;;;;;;;;;;;;;;;;;
+
+; Clojure için mantıksal yapılar bir özel-form'dur.
+; Ve diğer fonksiyonlar gibi kullanılabilir.
+; `if` fonksiyonunun ilk argümanı bir test ifadesidir.
+(if true "ya şundadır" "ya bunda") ; => "ya şundadır"
+; İkinci ifade doğru, üçüncü ifade ise yanlışsa ifadeleridir.
+; Eğer test terimi doğru olarak değerlendirilirse,
+; doğru ifadesi, yanlışsa yanlış ifadesi değerlendirilir ve döndürülür.
+;
+; Bir yanlışsa ifadesi yoksa `nil` döndürülür.
+(if false "a") ; => nil
+
+; Yerel geçici-değişken tanımlamak için `let` kullanılır.
+; İfadelerin varlığı `let` çağırımı ile sınırlıdır.
+(let [a 1 b 2]
+ (> a b)) ; => false
+
+; İfade ve çağırımları `do` ile gruplayabilirsiniz.
+; Çağırımların sonuncusu `do` ifadesinin değeri olarak
+; döndürülecektir.
+(do
+ (print "Selamlar!")
+ "Dünya!") ; => "Dünya!" (prints "Selamlar!")
+
+; Fonksiyonlar kapalı bir `do` ifadesi ile çevrelenmiştir.
+(defn yazdır-ve-selamla! [isim]
+ (println "Merhaba, " isim "!")
+ (str "Merhaba, " isim "!"))
+(yazdır-ve-selamla! "Zübeyde") ;=> "Merhaba, Zübeyde!" ("Merhaba, Zübeyde!" yazdırır.)
+
+; `let` ifadesi de kapalı bir `do` ile gelmektedir.
+(let [isim "Ayten"]
+ (print "Merhabalar, " isim)
+ (str "Merhabalar, " isim)) ; => "Merhabalar, " ("Merhabalar, Ayten" yazdırır)
+
+; Sıralama-makroları (-> ve ->>) ile veri dönüşümünü daha temiz ifade
+; edebilirsiniz.
+; Bu makrolar ilk argümanı sonraki her çağırımın içine yerleştirir.
+;
+; `->` makrosu, ifadeyi çağırımların ilk argümanı olacak şekilde yerleştirir.
+(->
+ {:a 1 :b 2}
+ (assoc :c 3) ;=> (assoc {:a 1 :b 2} :c 3)
+ (dissoc :b))
+
+; Bu ifade aşağıdaki şekilde yazılabilir:
+; (dissoc (assoc {:a 1 :b 2} :c 3) :b)
+; ve `{:a 1 :c 3}` olarak değer bulur.
+
+; Sondan-Sıralama-Makrosu (->>) ise aynı şeyi yapar,
+; tek fark ise, ifadeyi, çağırımların son argümanı olarak yerleştirir.
+;
+(->>
+ (range 10) ;=> '(0 1 2 3 4 5 6 7 8 9)
+ (map inc) ;=> (map inc (range 10))
+ (filter odd?) ;=> (filter odd? (map inc (range 10)))
+ (into [])) ;=> (into [] (filter odd? (map inc (range 10))))
+ ; Sonuç: [1 3 5 7 9]
+
+; Bir ifadedeki önceki veri dönüşümlerinin sonucunu nereye
+; koyacağınız konusunda daha fazla özgürlük istediğiniz bir durumda,
+; Sıralama-Makrolarından daha özgür bi' şey kullanmak istersiniz;
+; `as->` makrosu ile dönüşümlerin çıktısına bir isim atayabilir
+; ve ardışık çağırımlarda yer tutucu olarak kullanabilirsiniz.
+
+(as-> [1 2 3] girdi
+ (map inc girdi);=> ifadeyi isterseniz çağırımın son argümanı olarak,
+ (nth girdi 2) ;=> veya çağırımın ilk argümanı olarak,
+ (conj [4 5 6] girdi [8 9 10])) ;=> ya da istediğiniz sırada kullanabilirsiniz.
+;=> [4 5 6 4 [8 9 10]]
+
+
+
+; Modüller
+;;;;;;;;;;;;;;;
+
+; `use` çağırdığınız modüldeki tüm tanımlara erişmenize olanak verir.
+(use 'clojure.set)
+
+; Şu anda, küme fonksiyonlarını kullanabiliriz.
+(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
+(difference #{1 2 3} #{2 3 4}) ; => #{1}
+
+; Ayrıca eklenecek fonksiyonları seçebilirsiniz de:
+(use '[clojure.set :only [intersection]])
+
+; Bir modülü eklemek için `require` kullanılır.
+(require 'clojure.string)
+
+; İsim-uzayı kapsamlı çağırımlar aşağıdaki şekildedir:
+; isim-uzayı/fonksiyon-ismi --isim uzayı ismi ve fonksiyon ismi
+; arasına eğik çizgi koymanız yeterli.
+; Burada, modül `clojure.string` ve fonksiyon ismi `blank?`
+(clojure.string/blank? "") ; => true
+
+; Ekleme sırasında, bir modüle takma-ad verilebilir.
+(require '[clojure.string :as str])
+(str/replace "Bu bir özet metindir, test için kullanılabilir!"
+ #"[aeıioöuü]" str/upper-case)
+; => "BU bIr ÖzEt mEtIndIr, tEst IçIn kUllAnIlAbIlIr!"
+; (#"", burada düzenli ifadeler için bir sözdizimsel-şekerlemeyi ifade eder)
+
+; Bir isim-uzayı tanımlamasında `require` kullanılabilir.
+; `ns` bir makrodur ve `require` (ve `use`, ama lütfen kullanmayın)
+; dahil olmak üzere bir çok çağırım için işlevsellik sağlamaktadır.
+; Bu notasyonu kullanırsanız, modüllerinizi alıntılamak zorunda kalmazsınız.
+(ns test
+ (:require
+ [clojure.string :as str]
+ [clojure.set :as set]))
+
+
+; Java
+;;;;;;;;;;;;;;;;;
+
+; Java, kocaman ve kullanışlı bir standart kütüphaneye sahip,
+; Clojure, Java etkileşimi ile, bundan yararlanabilirsiniz.
+
+; `import` diğer modüller gibi, bir java modülü de ele alabilir.
+; Date, bir Java modülü.
+(import java.util.Date)
+
+; `ns` çağırımında da kullanabilirsiniz.
+(ns test
+ (:import java.util.Date
+ java.util.Calendar))
+
+; Bir Java nesnesinden oluşturmak için `new` çağırımını kullanabilirsiniz.
+(new Date)
+
+; Ayrıca Clojure Okuyucusu, size bunun daha farklı bir yolunu sunar:
+; Sınıf isminin sonuna koyulacak bir nokta `.` ile
+; bu yapılabilir.
+(Date.) ; <bir tarih nesnesi>
+
+; `.` --nokta-- çağırımı, size nesnelerdeki metotlara erişme imkanı verir.
+(. (new Date) getTime) ; <bir zaman-damgası>
+(.getTime (Date.)) ; Üstteki ifade ile tamamen aynı sonucu verir.
+
+; Sınıf içindeki statik metotlara erişmek için `/` ayracını
+; sınıf ile metot ismi birleştirmek için kullanabilirsiniz.
+; (örnekSınıf/statikMetot)
+(System/currentTimeMillis) ; <bir zaman-damgası> (`system` her zaman sunulur)
+
+; Sınıflarla işlem yaparken, `doto` bu süreci kolaylaştırabilir.
+; İlk argüman sınıf nesnesi, sonraki her çağırım, nesne üzerinde yapılır.
+(import java.util.Calendar)
+(doto (Calendar/getInstance)
+ (.set 2000 1 1 0 0 0) ; => `set` metodu, `doto` ifadesine verilen
+ ; sınıf nesnesi üzerinde çağırılır.
+ .getTime) ; => Bir tarih nesnesi. set to 2000-01-01 00:00:00
+
+
+; STM
+;;;;;;;;;;;;;;;;;
+
+; 'Software Transactional Memory' Clojure'un değişmez veri yapılarını
+; ele alırken kullandığı bir mekanizmadır. Clojure içinde bunu kullanan
+; birkaç yapı vardır.
+
+; Bir `atom` en basitidir. Bir ilkleme-değeri verin.
+(def benim-atomum (atom {}))
+
+; Bir atomu güncellemek için `swap!` kullanılır.
+; `swap!` fonksiyonu, ilk argüman olarak aldığı atomu, ikinci argüman
+; olarak aldığı fonksiyona uygular. Bu fonksiyona ek argümanlar ise
+; fonksiyondan sonra gelirler.
+(swap! benim-atomum assoc :a 1)
+; benim-atomum'un değerini (assoc {} :a 1) ifadesinin sonucu ile değiştirir.
+(swap! benim-atomum assoc :b 2)
+; benim-atomum'un değerini (assoc {:a 1} :b 2) ifadesinin sonucu ile değiştirir.
+
+; `deref` ile, atomun değerini çözümleyebilirsiniz.
+benim-atomum ;=> Atom<#...> (Atom ifadesi döndürür)
+@benim-atomum ; => {:a 1 :b 2}
+
+; İşte, `atom` kullanan basit bir sayaç.
+(def sayaç (atom 0)) ;=> Şu anki isim uzayına, `sayaç` ile, 0 başlangıç
+; değeri ile bir atom tanımladık.
+(defn sayaç-arttır [benim-atomum]
+ (swap! sayaç inc)) ;=> Atom'un değerini bir arttır.
+
+(sayaç-arttır sayaç)
+(sayaç-arttır sayaç)
+(sayaç-arttır sayaç)
+(sayaç-arttır sayaç)
+(sayaç-arttır sayaç)
+(sayaç-arttır sayaç)
+
+@sayaç ; => 6
+
+; Diğer STM yapıları `ref`'ler ve `agent`'lar.
+; Ref'ler: http://clojure.org/refs
+; Agent'lar: http://clojure.org/agents
+```
+
+### Çevirim-içi içerikler
+
+Bu içerik, Rich Hickey'nin derin yazılım geliştirme anlayışına ve John McCarthy'nin vizyonu olan Lisp'in, Clojure'a miras verdiklerini anlamak için elbette yeterli değildir. Fakat fonksiyonel paradigma ve bu paradigmanın modern bir Lisp lehçesinde kullanımına göz kırpmış oldunuz.
+
+Clojure.org, bir çok içerik ve makale var. (İngilizce içerik):
+[http://clojure.org/](http://clojure.org/)
+
+Clojuredocs.org, örneklerle bezenmiş Clojure dökümantasyonu:
+[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
+
+4Clojure, interaktif bir şekilde FP ve Clojure yeteneklerinizi geliştirmenize olanak veriyor:
+[http://www.4clojure.com/](http://www.4clojure.com/)
+
+Clojure-doc.org, Başlangıç için bir içeriklere sahip:
+[http://clojure-doc.org/](http://clojure-doc.org/)
+
+BraveClojure, bir başka clojure öğreten web sitesi:
+[https://www.braveclojure.com/](https://www.braveclojure.com/)
diff --git a/tr-tr/css-tr.html.markdown b/tr-tr/css-tr.html.markdown
new file mode 100644
index 00000000..d13dadcc
--- /dev/null
+++ b/tr-tr/css-tr.html.markdown
@@ -0,0 +1,304 @@
+---
+language: css
+contributors:
+ - ["Mohammad Valipour", "https://github.com/mvalipour"]
+ - ["Marco Scannadinari", "https://github.com/marcoms"]
+ - ["Geoffrey Liu", "https://github.com/g-liu"]
+ - ["Connor Shea", "https://github.com/connorshea"]
+ - ["Deepanshu Utkarsh", "https://github.com/duci9y"]
+ - ["Brett Taylor", "https://github.com/glutnix"]
+ - ["Tyler Mumford", "https://tylermumford.com"]
+filename: learncss-tr.css
+translators:
+ - ["Fatih Turan", "http://fatihturan.com"]
+lang: tr-tr
+---
+
+Web sayfaları bir sayfanın içeriğini belirleyen HTML ile inşa edilirler. CSS (Basamaklı Biçim Sayfaları) ise bir sayfanın **görünümünü** belirleyen ayrı bir dildir.
+
+CSS kodu statik *kurallardan* oluşur. Her kural bir ya da daha fazla *seçici* alır ve görsel *özelliklere* belirli *değerleri* verir. Sonrasında bu özellikler seçiciler tarafından belirlenen sayfa unsurlarına uygulanır.
+
+Bu rehber, CSS 3'ün yeni özellikleri ile genişletilen CSS 2 ile dikkate alınarak yazılmıştır.
+
+**NOT:** CSS görsel sonuçlar ürettiğinden dolayı, öğrenmek için herşeyi bir CSS oyun alanı içinde ([dabblet](http://dabblet.com) gibi) denemeniz gerekmektedir. Bu makale sözdizimi kuralları ve genel ipuçları üzerine odaklanmaktadır.
+
+## Sözdizimi
+
+```css
+/* yorumlar bu satırdaki gibi taksim-yıldız içinde görünür
+CSS'te "tek satırlık yorumlar" bulunmamaktadır; bu sadece tek bir yorum yazma stilidir */
+
+/* ####################
+ ## SEÇİCİLER
+ #################### */
+
+/* seçici bir sayfadaki unsuru hedeflemek için kullanılır. */
+seçici { özellik: değer; /* daha fazla özellikler...*/ }
+
+/*
+İşte bir örnek:
+
+<div class='class1 class2' id='anID' attr='value' otherAttr='en-us foo bar' />
+*/
+
+/* */
+
+/* CSS sınıflarının birini kullanarak hedefleyebilirsiniz */
+.class1 { }
+
+/* veya her iki sınıfı birden!*/
+.class1.class2 { }
+
+/* veya sadece ögenin adını yazarak */
+div { }
+
+/* veya onun ID adını */
+#anID { }
+
+/* veya onun aldığı bir özelliği kullanarak! */
+[attr] { font-size:smaller; }
+
+/* veya onun aldığı özelliğin belirli bir değeri varsa */
+[attr='value'] { font-size:smaller; }
+
+/* bir değer ile başlıyorsa (CSS 3) */
+[attr^='val'] { font-size:smaller; }
+
+/* veya bir değer ile bitiyorsa (CSS 3)*/
+[attr$='ue'] { font-size:smaller; }
+
+/* veya boşlukla ayrılmış liste içinde bir değer içeriyorsa */
+[otherAttr~='foo'] { }
+[otherAttr~='bar'] { }
+
+/* veya tire ile ayrılmış bir liste içinde bir değer içeriyorsa, örneğin: "-" (U+002D) */
+[otherAttr|='en'] { font-size:smaller; }
+
+/* Farklı seçicileri birleştirerek daha fazla odaklanmış bir seçici oluşturabilirsiniz. Seçiciler arasında boşluk bırakmayın. */
+div.some-class[attr$='ue'] { }
+
+/* Başka bir ögenin alt ögesi olan bir ögeyi seçebilirsiniz. */
+div.some-parent > .class-name { }
+
+/* veya bir başka ögeden türeyeni seçebilirsiniz. Alt ögeler onların ebeveynlerinin direkt türünden gelir, sadece ağacın bir alt ögeleridirler. Soyundan gelenler ağacın herhangi bir alt seviyesinde olabilir. */
+
+div.some-parent .class-name { }
+
+/* Uyarı: Seçiciler arasında bir boşluk bırakmazsanız aynı seçicinin başka bir anlamı olur.
+Ne olduğunu tahmin edebilir misiniz? */
+
+div.some-parent.class-name { }
+
+/* Ayrıca bir ögenin bitişik kardeşini temel alarak bir ögeyi seçebilirsiniz. */
+.i-am-just-before + .this-element { }
+
+/* veya kendisinden önce gelen herhangi bir kardeş ögeyi */
+.i-am-any-element-before ~ .this-element { }
+
+/* Yalnızca belli bir durumda bir öge seçmek için kullanılan sahte sınıflar adı verilen bazı seçiciler vardır. */
+
+/* Örneğin, imleç bir ögenin üzerine geldiğinde */
+selector:hover { }
+
+/* veya bir bağlantı ziyaret edildiğinde */
+selector:visited { }
+
+/* veya ziyaret edilmediğinde */
+selected:link { }
+
+/* veya bir ögeye odaklanıldığında */
+selected:focus { }
+
+/* Ebeveyninin ilk alt ögesi olan herhangi bir öge */
+selector:first-child {}
+
+/* Ebeveyninin son alt ögesi olan herhangi bir öge */
+selector:last-child {}
+
+/* Sahte sınıflar gibi sahte elementler de bir dokümanın belirli bir parçasına stil vermenize izin verir. */
+
+/* Seçilen ögenin sanal ilk alt ögesiyle eşleşir. */
+selector::before {}
+
+/* Seçilen ögenin sanal son alt ögesiyle eşleşir. */
+selector::after {}
+
+/* Uygun yerlerde yıldız karakteri ile bütün ögeleri seçmek için joker olarak kullanılabilir. */
+
+* { } /* Bütün ögeler */
+.parent * { } /* Tüm alt ögeler */
+.parent > * { } /* Tüm çocuk ögeler */
+
+/* ####################
+ ## ÖZELLİKLER
+ #################### */
+
+selector {
+
+ /* Ölçü birimleri kesin veya göreceli olabilir.*/
+
+ /* Göreceli birimler */
+ width: 50%; /* Ebeveyn elementin yüzdesel olarak genişliği */
+ font-size: 2em; /* Öğenin özgün yazı tipi boyutunda katları */
+ font-size: 2rem; /* veya kök ögenin yazı tipi boyutu */
+ font-size: 2vw; /* Görüntüleme çerçevesinin genişliğinin %1 olarak katları (CSS 3) */
+ font-size: 2vh; /* veya onun yüksekliğinin */
+ font-size: 2vmin; /* Bir vh veya vw'nin hangisi küçükse */
+ font-size: 2vmax; /* veya daha büyük... */
+
+ /* Kesin birimler */
+ width: 200px; /* Piksel */
+ font-size: 20pt; /* Nokta */
+ width: 5cm; /* Santimetre */
+ min-width: 50mm; /* Milimetre */
+ max-width: 5in; /* İnç */
+
+ /* Renkler */
+ color: #F6E; /* Kısa onaltılık (HEX) biçimi */
+ color: #FF66EE; /* Uzun onaltılık (HEX) biçimi */
+ color: tomato; /* Bir isim verilen renk */
+ color: rgb(255, 255, 255); /* RGB değerleri verilen türde */
+ color: rgb(10%, 20%, 50%); /* RGB yüzdeleri verilen türde */
+ color: rgba(255, 0, 0, 0.3); /* RGBA değerleri verilen türde (CSS 3) Not: 0 <= a <= 1 */
+ color: transparent; /* Şeffaflık değerinin sıfır olması ile eşdeğer */
+ color: hsl(0, 100%, 50%); /* HSL yüzdeleri verilen türde (CSS 3) */
+ color: hsla(0, 100%, 50%, 0.3); /* HSL ile beraber şeffaflık değeri verilen türde */
+
+ /* Kenarlıklar */
+ border-width:5px;
+ border-style:solid;
+ border-color:red; /* background-color'ın ayarlanışına benzer şekilde */
+ border: 5px solid red; /* Bu aynı şeyin kısayol ile yazılışıdır */
+ border-radius:20px; /* Bu bir CSS3 özelliğidir */
+
+ /* Görseller ve Ögelerin Arkaplanları */
+ background-image: url(/img-path/img.jpg); /* url() içindeki tırnak işaretleri isteğe bağlı */
+
+ /* Yazı tipleri */
+ font-family: Arial;
+ /* Eğer yazı tipi ailesi isminde bir boşluk var ise tırnak işareti içine alınmalıdır. */
+ font-family: "Courier New";
+ /* Eğer ilk sıradaki bulunamazsa, tarayıcı bir sonrakini kullanır */
+ font-family: "Courier New", Trebuchet, Arial, sans-serif;
+}
+```
+
+## Kullanım
+
+CSS dosyasınızı `.css`uzantısı ile kaydedin.
+
+```html
+<!-- CSS dosyanızı sayfanın içindeki <head> alanına dahil etmeniz gerekiyor. Bu önerilen yöntemdir. Bakın: http://stackoverflow.com/questions/8284365 -->
+<link rel='stylesheet' type='text/css' href='path/to/style.css'>
+
+<!-- Bazı CSS kodları satır içi olarak yazabilirsiniz. -->
+<style>
+ a { color: purple; }
+</style>
+
+<!-- Veya ögenin üzerinde CSS özelliklerini direkt ayarlayabilirsiniz. -->
+<div style="border: 1px solid red;">
+</div>
+```
+
+## Öncelik veya Basamak
+
+Bir öge birden çok seçici tarafından hedef alınabilir ve bir özellik kümesine birden fazla kez sahip olabilir. Bunun gibi durumlarda, kurallardan biri diğerlerine göre önceliklidir. Daha spesifik bir seçiciye sahip kurallar, daha az spesifik bir seçicinin önceliğini alır ve kural daha sonra stil sayfasında bir önceki kuralın üzerine yazar.
+
+Bu işleme geçiş denir ve olayısıyla Geçişli/Basamaklı Stil Sayfaları adı da buradan gelmiştir.
+
+Aşağıdaki CSS göz önüne alındığında:
+
+```css
+/* A */
+p.class1[attr='değer']
+
+/* B */
+p.class1 { }
+
+/* C */
+p.class2 { }
+
+/* D */
+p { }
+
+/* E */
+p { özellik: değer !important; }
+```
+
+ve aşağıdaki biçimlendirmeyi:
+
+```html
+<p style='/*F*/ özellik:değer;' class='class1 class2' attr='değer'>
+```
+
+Stilin önceliği ise aşağıdaki gibidir. Unutmayın, öncelik **her bir özellik için ayrı ayrı geçerlidir**, tüm blok için geçerli değildir.
+
+* `E` `!important` kelimesi yüzünden en yüksek önceliğe sahiptir. Kullanımından kaçınmanız önerilir.
+* `F` satıriçi stil olduğu için bir sonraki önceliğe sahiptir.
+* `A` bir sonraki önceliğe sahiptir. Çünkü her şeyden daha "özgüdür". 3 belirteci vardır: `p` ögesinin adı, sınıf` class1`, bir öznitelik `attr = 'değer'.
+* `C`, `B` ile aynı özdeşliğe sahip olsa da, bundan sonra geldiğinden dolayı öncelik hakkına sahiptir.
+* `B` bir sonraki önceliğe sahiptir.
+* Sonuncu önceliğe sahip olan`D`'dir.
+
+## Medya Sorguları
+
+CSS Medya Sorguları, CSS 3'te belirli CSS kurallarının ne zaman uygulanması gerektiğini (örneğin basılan zaman veya belirli boyutlar veya piksel yoğunluğu olan bir ekranda olduğunda) belirlemenize izin veren bir özelliktir. Medya Sorguları, seçicilere önceliğk eklemez.
+
+```css
+/* Tüm cihazlarda kullanılacak olan bir kural */
+h1 {
+ font-size: 2em;
+ color: white;
+ background-color: black;
+}
+
+/* h1 ögesini değiştirip bir yazıcıda daha az mürekkep kullanın*/
+@media print {
+ h1 {
+ color: black;
+ background-color: white;
+ }
+}
+
+/* En az 480 piksel genişliğinde bir ekran gösterildiğinde font yüksekliğini daha büyük yap */
+@media screen and (min-width: 480px) {
+ h1 {
+ font-size: 3em;
+ font-weight: normal;
+ }
+}
+```
+
+Medya sorguları aşağıdaki bu özellikleri içerebilir:
+`width`, `height`, `device-width`, `device-height`, `orientation`, `aspect-ratio`, `device-aspect-ratio`, `color`, `color-index`, `monochrome`, `resolution`, `scan`, `grid`. Bu özelliklerin birçoğunu `min-` veya `max-` öneki ile kullanabilirsiniz.
+
+`resolution` özelliği eski cihazlarda desteklenmediğinden ötürü `device-pixel-ratio` kullanın.
+
+Eğer `viewport` meta etiketi sağlanmadıkça birçok akıllı telefon ve tabletler, sayfayı masaüstü bilgisayardaymış gibi göstermeye çalışacaktır.
+
+```html
+<head>
+ <meta name="viewport" content="width=device-width; initial-scale=1.0">
+</head>
+```
+
+## Uyumluluk
+
+CSS 2'deki çoğu özellik (ve CSS 3'deki birçoğu) bütün tarayıcılar ve cihazlar için bulunmaktadır. Ancak yeni bir özelliği kullanmadan önce kontrol etmek her zaman iyi bir uygulamadır.
+
+## Kaynaklar
+
+* [CanIUse](http://caniuse.com) (Detaylı uyumluluk bilgileri)
+* [Dabblet](http://dabblet.com/) (CSS oyun alanı)
+* [Mozilla Geliştirici Ağının CSS belgelendirmesi](https://developer.mozilla.org/en-US/docs/Web/CSS) (Eğitseller ve referanslar)
+* [Codrops' CSS Referansı](http://tympanus.net/codrops/css_reference/) (Referans)
+
+## Daha Fazla Okuma
+
+* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/)
+* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/)
+* [QuirksMode CSS](http://www.quirksmode.org/css/)
+* [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context)
+* [SASS](http://sass-lang.com/) and [LESS](http://lesscss.org/) for CSS pre-processing
+* [CSS-Tricks](https://css-tricks.com)
diff --git a/tr-tr/dynamic-programming-tr.html.markdown b/tr-tr/dynamic-programming-tr.html.markdown
new file mode 100644
index 00000000..e6a734a7
--- /dev/null
+++ b/tr-tr/dynamic-programming-tr.html.markdown
@@ -0,0 +1,55 @@
+---
+language: Dynamic Programming
+filename: dynamic-tr.txt
+contributors:
+ - ["Akashdeep Goel", "https://github.com/akashdeepgoel"]
+translators:
+ - ["Mehmet Cem Yaraş", "https://www.linkedin.com/in/yarascem/"]
+lang: tr-tr
+---
+
+# Dinamik Programlama
+
+## Giriş
+
+Dinamik Programlama, göreceğimiz gibi belirli bir problem sınıfını çözmek için kullanılan güçlü bir tekniktir. Fikir çok basittir, verilen girdiyle ilgili bir sorunu çözdüyseniz, aynı sorunun tekrar çözülmesini önlemek için sonucunu gelecekte referans olarak kaydedilmesine dayanır.
+
+Her zaman hatırla! "Geçmiş hatırlayamayanlar, aynı şeyleri tekrar yaşamaya mahkumlardır!"
+
+## Bu tür sorunların çözüm yolları
+
+1. Yukarıdan aşağıya:
+Verilen problemi çözerek çözmeye başlayın. Sorunun zaten çözüldüğünü görürseniz, kaydedilen cevabı döndürmeniz yeterlidir. Çözülmemişse, çözünüz ve cevabı saklayınız. Bu genellikle düşünmek kolaydır ve çok sezgiseldir. Buna Ezberleştirme denir.
+
+2. Aşağıdan yukarıya:
+Sorunu analiz edin ve alt problemlerin çözülme sırasını görün ve önemsiz alt sorundan verilen soruna doğru başlayın. Bu süreçte, problemi çözmeden önce alt problemlerin çözülmesi gerekmektedir. Buna Dinamik Programlama denir.
+
+## Örnek
+
+En Uzun Artan Subsequence problemi belirli bir dizinin en uzun artan alt dizini bulmaktır. `S = {a1, a2, a3, a4, ............., an-1}` dizisi göz önüne alındığında, en uzun bir alt kümeyi bulmak zorundayız, böylece tüm j ve i, `j<I` için , `aj<ai` alt kümesinde. Her şeyden önce, en son alt dizgenin (LSi) değerini dizinin son elemanı olan ai'nin her indeksinde bulmalıyız. Daha sonra en büyük LSi, verilen dizideki en uzun alt dizin olacaktır. Başlamak için, ai, dizinin elemanı olduğundan (Son öğe) LSi atanır. Sonra tüm j için `j<i` ve `aj<ai` gibi, En Büyük LSj'yi buluruz ve LSi'ye ekleriz. Sonra algoritma `O(n2)` zaman alır.
+
+En uzun artan alt dizinin uzunluğunu bulmak için sözde kod:
+Bu algoritmaların karmaşıklığı dizi yerine daha iyi veri yapısı kullanılarak azaltılabilir. Büyük dizin ve dizin gibi selefi dizi ve değişkeni saklama çok zaman kazandıracaktır.
+
+Yönlendirilmiş asiklik grafiğinde en uzun yolu bulmak için benzer bir kavram uygulanabilir.
+
+```python
+for i=0 to n-1
+ LS[i]=1
+ for j=0 to i-1
+ if (a[i] > a[j] and LS[i]<LS[j])
+ LS[i] = LS[j]+1
+for i=0 to n-1
+ if (largest < LS[i])
+
+```
+
+### Bazı Ünlü Dinamik Programlama Problemleri
+
+- Floyd Warshall Algorithm - Tutorial and C Program source code: [http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code]()
+- Integer Knapsack Problem - Tutorial and C Program source code: [http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem]()
+- Longest Common Subsequence - Tutorial and C Program source code : [http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence]()
+
+## Online Kaynaklar
+
+- [codechef](https://www.codechef.com/wiki/tutorial-dynamic-programming)
diff --git a/tr-tr/edn-tr.html.markdown b/tr-tr/edn-tr.html.markdown
new file mode 100644
index 00000000..9a2ac1ff
--- /dev/null
+++ b/tr-tr/edn-tr.html.markdown
@@ -0,0 +1,157 @@
+---
+language: edn
+filename: learnedn-tr.edn
+lang: tr-tr
+contributors:
+ - ["Seçkin KÜKRER", "https://github.com/LeaveNhA"]
+---
+
+# Y = 20 Dakika.
+
+### Genişletilebilir Veri Notasyonu (EDN, Extensible Data Notation).
+
+### Okunuşu: (Türkçe: ey-di-en), (English: eed-n)
+
+### Kodlama Türü: UTF-8
+
+EDN Clojure sözdiziminin bir alt kümesidir. Bu alt küme, amacı gereği kod barındırmaz. Ve kendisi bir tip sistemi değildir. Bir şeması da yoktur. En basit tabirle; Genişletilebilir Veri Notasyonu kabul edilebilir elemanların bir kümesidir.
+
+EDN elementleri, akışları ve dosyaları UTF-8 kullanılarak kodlanmalıdır. Üstelik, dökümanı çevreleyen işaretçiler de olmadığı için akış, dağıtık programlama mesaj arayüzü ve diğer dinamik sistemler için idealdir.
+
+
+```clojure
+; Yorumlar, yorumlarımız, noktalı virgül ile başlıyor.
+;; Genellikle ikili olarak kullanılıyorlar.
+
+;; |--------------------------------|
+; |--------- Genel Yapısı ---------|
+;; |--------------------------------|
+
+;; Boşluklar --whitespaces--, elementler için en yaygın ayıraçtır.
+"Mustafa" "Kemal" "ATATÜRK"
+;; Fakat okunuşu arttırdığı gerekçesiyle "," (virgüller --commas--) EDN yorumlayıcısı tarafından görmezden gelinir ve boşluk olarak nitelendirilir.
+"Mustafa","Kemal","PAŞA"
+;; Üstelik bu yenilikçi sözdizimsel kurala rağmen, {}, [] () gibi koleksiyon karakterlerini ayırmak için boşluğa ya da boşluğa çözümlenen virgüle ihtiyacınız yoktur.
+[["MUSTAFA"] ["KEMAL"] [[{"ATA" "ATATÜRK"}]]]
+;; Üst düzey vektör elemanlarını birbirinden ayıran boşlukları da kaldırabilirsiniz.
+;; Fakat bu size, okunması zor bir vektör dışında hiç bir şey vermeyecektir.
+
+;; |--------------------------------|
+; |-------- Atomik Yapılar --------|
+;; |--------------------------------|
+
+; Mantıksal Değerler
+;; Mantıksal Doğru, çoğu teknolojide aynı gösterimi var.
+true
+;; Mantıksal Yanlış.
+false
+
+; Karakter Katarları
+;; Karakter katarları, --SADECE-- çift tırnak ile belirtilebilir.
+"İzmirin dağlarında çiçekler açar!"
+;; C, C++, Java v.b. gibi dillerin desteklediği kaçış sekanslarını da destekler.
+"Altın güneş orda sırmalar saçar.\nBozulmuş düşmanlar yel gibi kaçar."
+;; Kaçış sekansları için bknz: $!$
+
+; Karakter Sabitleri
+;; Karakter sabitleri önlerinde bir ters eğik çizgi ile temsil edilirler.
+\T \Ü \R \K
+;; Üstelik, belirli kaçıl sekanslarının da karşılığı Karakter Sabiti olarak var.
+\newline \return
+
+; Anahtar Kelimeler
+;; Anahtar Kelimeler, önlerinde bir ":" iki nokta --colon--
+:yımırta
+:kaşar
+:bıngıl
+
+; Semboller
+;; Semboller tanımlayıcıları temsil etmek için kullanılır.
+;; "/" karakteri, Sembol Sabitlerinde isim-uzayı ayıracı olarak kullanılıyor.
+izmir/kızları
+;; "mutfak" isim uzayındaki "ekmek-bıçağı" isimli sembole çözümlenir.
+
+banyo/fayans
+parke
+laminat
+
+; Sayısal Değerler
+;; Tam Sayı sabiti.
+1991
+;; Kayan Noktalı Sabiti.
+19.67
+
+; Listeler
+;; Listeler, yukarıdaki temel tiplerin ardışıklanmasıdır.
+(bomba :bomba nokta \c \o \m)
+
+; Vektörler
+;; Vektörler bir bakıma Listelere benzeseler de, bir çok açıdan farklıdırlar.
+;; Mesela Listenin aksine Vektörler, Rastgele Erişime imkan verir.
+[[] "şimdi" "asker"]
+
+; Eşlemeler
+;; Sıfır veya daha fazla Anahtar-Değer çifti kabul eder.
+;; Not: Clojure Veri Yapıları Soyutlaması ile Eşlemeler de, teknik olarak ardışık olarak işlenebilir.
+{:canı :neler-ister?
+ :uykuda "mevlam"}
+;; Bu ve diğer tüm Veri Yapıları Homojendir, birbirilerini barındırabilir, kapsayabilir, içerebilirler.
+;; Ayrıca okunurluk gibi farklı sebeplerle virgül kullanımında özgürsünüz.
+{{:id_ "129u391824981237981237" :kim "BEN"}, göster!}
+
+; Kümeler
+;; Kümeler eşsiz eleman barındıran bir yapıdır.
+;; Matematikteki karşılığını veriyor dersek yanlış olmaz.
+#{:sen 3 milyar 750 milyon}
+
+;; |--------------------------------|
+; |------ Etiketli Elemanlar ------|
+;; |--------------------------------|
+
+;; EDN (Genişletilebilir Veri Notasyonu), # sembolü ile genişletilebilir.
+
+#benimuygulamam/bağlantı {:içerik "Y dakikada EDN Öğren" :url "https://learnxinyminutes.com/docs/tr-tr/edn-tr" :tıhlama-aksiyonu yırrttılll!}
+
+;; Ve bu yapıyı yorumlayacak bir de yapı gerekiyor.
+(defn ->bağlantı [props]
+ (str "<a href='" (:url props) "'" ">"
+ (:içerik props)
+ "</a>"))
+
+;; Bu örnekte yorumlayıcıya, basit bir fonksiyon veriyoruz.
+;; `clojure.edn/read-string` aslında bir ayarlar Eşlemesi kabul ediyor.
+;; (Bu tür fonksiyon genişlemeleri, Clojure ekosisteminde yaygındır.)
+
+(clojure.edn/read-string
+ {:readers {'benimuygulamam/bağlantı ->bağlantı}}
+ "#benimuygulamam/bağlantı {:içerik \"Y dakikada EDN Öğren\" :url \"https://learnxinyminutes.com/docs/tr-tr/edn-tr\" :tıhlama-aksiyonu yırrttılll!}")
+;=> "<a href='https://learnxinyminutes.com/docs/tr-tr/edn-tr'>Y dakikada EDN Öğren</a>"
+
+;; |--------------------------------|
+; |--- Ön Tanımlı Genişletmeler ---|
+;; |--------------------------------|
+
+; Tarih Etiketi
+;; Bu etiket `inst` ön-ekinden sonra bir RFC-3339 formatında bir karakter katarı beklemektedir.
+#inst "2013-10-21T14:50:00+00:00" ; => Formatlanmış bir şekilde: 21/10/2013 14:50:00
+
+; UUID Etiketi
+;; Bu etiket `uuid` ön-ekinden sonra bir UUID karşılığını karakter katarı olarak kabul eder.
+#uuid "11k12fae-7d3c-11k0-a765-0010ckke6hgk"
+
+```
+
+# Son Ek
+Bu içerik, EDN'i tanıtmakta kısıtlı bir açıyla, özet bilgiler sunmaktadır.
+Fakat, Clojure ve diğer Veri Odaklı dillerde, Verinin yolculuğunu anlamak için önemli bir rol oynamaktadır.
+EDN'in var olan probleme çözümü ve artı/eksilerinin doğru şekilde kavranması mühimdir.
+Ben bu dökümanı hazırlarken, EDN ve gerçek dünya kullanımını anlatan yoktu. Fakat ümidim, Clojure ve diğer teknolojiler üzerinde kullanımının artmasından sonra birinin bu ihtiyacı giderecek özgün kaynak çıkarmasıdır.
+
+Başarılar!
+
+# Referanslar
+
+- [EDN Formatı Standardı](https://github.com/edn-format/edn)
+- [Gerçeklemeler](https://github.com/edn-format/edn/wiki/Implementations)
+- [Etiketlenmiş Elementler](http://www.compoundtheory.com/clojure-edn-walkthrough/)
+- [Clojure.Docs EDN İçeriği](https://clojuredocs.org/clojure.edn)
diff --git a/tr-tr/git-tr.html.markdown b/tr-tr/git-tr.html.markdown
new file mode 100644
index 00000000..87c1820c
--- /dev/null
+++ b/tr-tr/git-tr.html.markdown
@@ -0,0 +1,596 @@
+---
+category: tool
+lang: tr-tr
+tool: git
+contributors:
+ - ["Jake Prather", "http://github.com/JakeHP"]
+ - ["Leo Rudberg" , "http://github.com/LOZORD"]
+ - ["Betsy Lorton" , "http://github.com/schbetsy"]
+ - ["Bruno Volcov", "http://github.com/volcov"]
+ - ["Andrew Taylor", "http://github.com/andrewjt71"]
+ - ["Jason Stathopulos", "http://github.com/SpiritBreaker226"]
+ - ["Milo Gilad", "http://github.com/Myl0g"]
+ - ["Adem Budak", "https://github.com/p1v0t"]
+
+filename: LearnGit-tr.txt
+---
+
+Git dağınık versiyon kontrol ve kaynak kod yönetim sistemidir.
+
+Bunu projenin bir seri anlık durumunu kaydederek yapar ve bu anlık durumları
+kullanarak versiyon ve kaynak kodu yönetmeni sağlar.
+
+## Versiyonlama Konseptleri
+
+### Versiyon kontrol nedir?
+
+Versiyon kontrol, zaman içerisinde dosya(lar)daki değişikliği kaydeden sistemdir.
+
+### Merkezi Versiyonlama vs. Dağınık Versiyonlama
+
+* Merkezi versiyon kontrolü dosyaların eşitlenmesine, takibine ve yedeklenmesine odaklanır.
+* Dağınık versiyon kontrolü değişimin paylaşılmasına odaklanır. Her değişiminin benzersiz bir adı vardır.
+* Dağınık sistemlerin belirlenmiş bir yapısı yoktur. Git ile kolayca SVN'deki gibi merkezi bir sistem elde edebilirsin.
+
+[Daha fazla bilgi](http://git-scm.com/book/en/Getting-Started-About-Version-Control)
+
+### Neden Git?
+
+* Çevrimdışı çalışabilir
+* Diğerleriyle beraber çalışmak kolaydır!
+* Dallanma kolaydır!
+* Dallanma hızlıdır!
+* Git hızlıdır
+* Git esnektir
+
+## Git Mimarisi
+
+### Repository
+
+Bir grup dosya, dizin, geriye dönük kayıt, commit, head. Bunları kaynak kodun veri
+yapısı gibi düşünebilirsin, herbir kaynak kod "elemanı" seni kendi revizyon geçmişine
+eriştirir.
+
+Bir git repo'su .git dizini ve çalışma ağacından oluşur.
+
+### .git Dizini (repository bileşeni)
+
+.git dizini bütün konfigrasyon, log, dallanma, HEAD ve daha fazlasını tutar.
+[detaylı liste](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html)
+
+### Çalışma Ağacı (repository bileşeni)
+
+Temelde repo'daki dizinlerin ve dosyalarındır. Sıkça çalışma ağacın olarak anılır.
+
+### Index (.git dizininin birleşeni)
+
+Index git'in evreleme alanıdır (staging area). Temelde çalışma ağacını Git repo'sundan
+ayıran bir katmandır. Bu geliştiricilere neyin Git repo'suna gönderileceği hakkında daha
+fazla güç verir.
+
+### Commit
+
+Bir git commit'i Çalışma Ağacındaki bir takım değişiklerdir. Mesela 5 tane dosya
+eklemişsindir ve diğer 2 tanesini silmişindir, bu değişikler commit'te (anlık kayıtta)
+tutulacaktır. Bu commit daha sonra diğer repo'lara bastırılabilir (pushed) ve bastırılmaz!
+
+### Branch
+
+Bir branch esasen yaptığın son commit'e göstericidir(pointer). Commit'lemeye devam ettiğinde,
+bu gösterici otomatik olarak son commit'e güncellenir.
+
+### Tag
+
+Bir tag, tarihteki belirli bir noktanın işaretidir. İnsanlar bunu genelde
+sürüm notları için kullanır (v1.0 vs.)
+
+### HEAD ve head (.git dizininin birleşenleri)
+
+HEAD mevcut branch'a bir göstericidir. Bir repository yalnızca 1 *aktif*
+HEAD'e sahiptir.
+head, commit'e bir göstericidir. Bir repository herhangi bir sayıda head'e sahip olabilir.
+
+### Git'in Stage'leri
+* Modified - Dosyada değişikler yapıldı ama henüz Git Veritabanına commit yapılmadı.
+* Staged - Modified edilmiş bir dosyayı, sonraki commit'e gitmek üzere işaretler.
+* Committed - Dosyalar Git Veritabanına commit'lendi.
+
+### Kavramsal Kaynaklar
+
+* [Bilgisayar Bilimciler için Git](http://eagain.net/articles/git-for-computer-scientists/)
+* [Tasarımcılar için Git](http://hoth.entp.com/output/git_for_designers.html)
+
+## Komutlar
+
+### init
+
+Boş bir Git repository'si oluştur. Git repository'sinin ayarları, depolanmış
+bilgileri ve daha fazlası ".git" adlı dizinde (bir klasör) tutulur.
+
+```bash
+$ git init
+```
+
+### config
+
+Ayarları yapılandırmak için. Repository, sistemin kendisi veya global yapılandırmalar
+için olarabilir. (global yapılandırma dosyası `~/.gitconfig`).
+
+```bash
+# Print & Set Some Basic Config Variables (Global)
+$ git config --global user.email "MyEmail@Zoho.com"
+$ git config --global user.name "My Name"
+```
+
+[git config hakkında daha fazla bilgi için.](http://git-scm.com/docs/git-config)
+
+### help
+
+Her bir komutun detaylı kılavuzuna hızlı bir erişim için. Ya da sadece bazı şeylerin
+anlamı için hızlı bir hatırlatıcı için.
+
+```bash
+# Quickly check available commands
+$ git help
+
+# Check all available commands
+$ git help -a
+
+# Command specific help - user manual
+# git help <command_here>
+$ git help add
+$ git help commit
+$ git help init
+# or git <command_here> --help
+$ git add --help
+$ git commit --help
+$ git init --help
+```
+
+### dosyaları ignore etme
+
+git'in bazı dosya(ları) ve klasör(leri) kasıtlı olarak takip etmemesi için. Genel
+olarak,repository'de ne de olsa paylaşılacak, private ve temp dosyaları için.
+
+```bash
+$ echo "temp/" >> .gitignore
+$ echo "private_key" >> .gitignore
+```
+
+### status
+
+index dosyası(temelde çalıştığın repo) ve mevcut HEAD commit arasındaki farkı göstermek için.
+
+```bash
+# Will display the branch, untracked files, changes and other differences
+$ git status
+
+# To learn other "tid bits" about git status
+$ git help status
+```
+
+### add
+
+Dosyaları staging area'ya eklemek için. Eğer yeni dosyaları staging area'ya `git add`
+yapmazsanız, commit'lere eklenmez!
+
+```bash
+# add a file in your current working directory
+$ git add HelloWorld.java
+
+# add a file in a nested dir
+$ git add /path/to/file/HelloWorld.c
+
+# Regular Expression support!
+$ git add ./*.java
+
+# You can also add everything in your working directory to the staging area.
+$ git add -A
+```
+Bu yalnızca dosyayı staging area'a/index'e ekler, çalışılan dizine/repo'ya commit etmez.
+
+### branch
+
+Branch'ları yönetir. Bu komutu kullanarak, branch'ları görebilir, düzenleyebilir, oluşturabilir, silebilirsin.
+
+```bash
+# list existing branches & remotes
+$ git branch -a
+
+# create a new branch
+$ git branch myNewBranch
+
+# delete a branch
+$ git branch -d myBranch
+
+# rename a branch
+# git branch -m <oldname> <newname>
+$ git branch -m myBranchName myNewBranchName
+
+# edit a branch's description
+$ git branch myBranchName --edit-description
+```
+
+### tag
+
+tag'leri yönetir
+
+```bash
+# List tags
+$ git tag
+
+# Create a annotated tag
+# The -m specifies a tagging message, which is stored with the tag.
+# If you don’t specify a message for an annotated tag,
+# Git launches your editor so you can type it in.
+$ git tag -a v2.0 -m 'my version 2.0'
+
+# Show info about tag
+# That shows the tagger information, the date the commit was tagged,
+# and the annotation message before showing the commit information.
+$ git show v2.0
+
+# Push a single tag to remote
+$ git push origin v2.0
+
+# Push a lot of tags to remote
+$ git push origin --tags
+```
+
+### checkout
+
+index'in versiyonun eşlemek için çalışma ağacındaki,veya belirtilen ağactaki, tüm dosyaları günceller.
+
+```bash
+# Checkout a repo - defaults to master branch
+$ git checkout
+
+# Checkout a specified branch
+$ git checkout branchName
+
+# Create a new branch & switch to it
+# equivalent to "git branch <name>; git checkout <name>"
+
+$ git checkout -b newBranch
+```
+
+### clone
+
+Varolan bir repository'i yeni bir dizine clone'lar veya kopyalar.
+Ayrıca clone'lanmış repodaki her bir branch için, uzak branch'a bastırmana izin veren,
+uzak takip branch'ları ekler.
+
+```bash
+# Clone learnxinyminutes-docs
+$ git clone https://github.com/adambard/learnxinyminutes-docs.git
+
+# shallow clone - faster cloning that pulls only latest snapshot
+$ git clone --depth 1 https://github.com/adambard/learnxinyminutes-docs.git
+
+# clone only a specific branch
+$ git clone -b master-cn https://github.com/adambard/learnxinyminutes-docs.git --single-branch
+```
+
+### commit
+
+index'in mevcut içeriğini yeni bir "commit"te saklar. Bu commit, kullanıcının oluşturduğu
+bir mesajı ve yapılan değişiklikleri saklar.
+
+```bash
+# commit with a message
+$ git commit -m "Added multiplyNumbers() function to HelloWorld.c"
+
+# signed commit with a message (user.signingkey must have been set
+# with your GPG key e.g. git config --global user.signingkey 5173AAD5)
+$ git commit -S -m "signed commit message"
+
+# automatically stage modified or deleted files, except new files, and then commit
+$ git commit -a -m "Modified foo.php and removed bar.php"
+
+# change last commit (this deletes previous commit with a fresh commit)
+$ git commit --amend -m "Correct message"
+```
+
+### diff
+
+Shows differences between a file in the working directory, index and commits.
+Bir dosyanın, çalışma ağacı, index ve commit'ler arasındaki farklarını göster.
+
+```bash
+# Show difference between your working dir and the index
+$ git diff
+
+# Show differences between the index and the most recent commit.
+$ git diff --cached
+
+# Show differences between your working dir and the most recent commit
+$ git diff HEAD
+```
+
+### grep
+
+Bir repository'de hızlıca arama yapmana izin verir.
+
+İsteğe Bağlı Yapılandırmalar:
+
+```bash
+# Thanks to Travis Jeffery for these
+# Set line numbers to be shown in grep search results
+$ git config --global grep.lineNumber true
+
+# Make search results more readable, including grouping
+$ git config --global alias.g "grep --break --heading --line-number"
+```
+
+```bash
+# Search for "variableName" in all java files
+$ git grep 'variableName' -- '*.java'
+
+# Search for a line that contains "arrayListName" and, "add" or "remove"
+$ git grep -e 'arrayListName' --and \( -e add -e remove \)
+```
+
+Daha fazla örnek için
+[Git Grep Ninja](http://travisjeffery.com/b/2012/02/search-a-git-repo-like-a-ninja)
+
+### log
+
+Repository'deki commitleri gösterir.
+
+```bash
+# Show all commits
+$ git log
+
+# Show only commit message & ref
+$ git log --oneline
+
+# Show merge commits only
+$ git log --merges
+
+# Show all commits represented by an ASCII graph
+$ git log --graph
+```
+
+### merge
+
+Dış commit'lerdeki değişiklikleri mevcut branch'a "merge" et (birleştir).
+
+```bash
+# Merge the specified branch into the current.
+$ git merge branchName
+
+# Always generate a merge commit when merging
+$ git merge --no-ff branchName
+```
+
+### mv
+
+Bir dosyayı yeniden taşı veya yeniden adlandır
+
+```bash
+# Renaming a file
+$ git mv HelloWorld.c HelloNewWorld.c
+
+# Moving a file
+$ git mv HelloWorld.c ./new/path/HelloWorld.c
+
+# Force rename or move
+# "existingFile" already exists in the directory, will be overwritten
+$ git mv -f myFile existingFile
+```
+
+### pull
+
+Bir repository'den çeker ve diğer branch'a merge eder.
+
+```bash
+# Update your local repo, by merging in new changes
+# from the remote "origin" and "master" branch.
+# git pull <remote> <branch>
+$ git pull origin master
+
+# By default, git pull will update your current branch
+# by merging in new changes from its remote-tracking branch
+$ git pull
+
+# Merge in changes from remote branch and rebase
+# branch commits onto your local repo, like: "git fetch <remote> <branch>, git
+# rebase <remote>/<branch>"
+$ git pull origin master --rebase
+```
+
+### push
+
+Bir branch'taki değişikleri, uzak branch'a bastır ve birleştir.
+
+```bash
+# Push and merge changes from a local repo to a
+# remote named "origin" and "master" branch.
+# git push <remote> <branch>
+$ git push origin master
+
+# By default, git push will push and merge changes from
+# the current branch to its remote-tracking branch
+$ git push
+
+# To link up current local branch with a remote branch, add -u flag:
+$ git push -u origin master
+# Now, anytime you want to push from that same local branch, use shortcut:
+$ git push
+```
+
+### stash
+
+Stash'leme çalışma dizinindeki kirli durumu alır ve bitmemiş değişiklikler
+yığınına kaydeder. Bu değişikleri istediğin zaman tekrar uygulayabilirsin.
+
+Mesela git repo'nda bazı işler yaptın ama remote'dan pull yapmak istiyorsun.
+Bazı dosyalarında kirli (commit'lenmemiş) değişiklikler olduğundan `git pull`
+yapamazsın. Onun yerine önce `git stash` ile değişikliklerini yığına kaydet!
+
+(stash, sözlük anlamı: bir şeyi, özel bir yere güvenli biçimde saklamak)
+
+```bash
+$ git stash
+Saved working directory and index state \
+ "WIP on master: 049d078 added the index file"
+ HEAD is now at 049d078 added the index file
+ (To restore them type "git stash apply")
+```
+
+Şimdi pull yapabilirsin!
+
+```bash
+git pull
+```
+`...changes apply...`
+
+Herşeyin tamam olduğunu kontrol et
+
+```bash
+$ git status
+# On branch master
+nothing to commit, working directory clean
+```
+Şu ana kadar neleri stash'lediğini `git stash list` kullanarak görebilirsin.
+Stash'lenen şeyler Son-Giren-İlk-Çıkar şeklinde tutulduğundan en son değişim
+en üste olacaktır.
+
+```bash
+$ git stash list
+stash@{0}: WIP on master: 049d078 added the index file
+stash@{1}: WIP on master: c264051 Revert "added file_size"
+stash@{2}: WIP on master: 21d80a5 added number to log
+```
+Şimdi de kirli değişiklileri yığından çıkarıp uygulayalım.
+
+```bash
+$ git stash pop
+# On branch master
+# Changes not staged for commit:
+# (use "git add <file>..." to update what will be committed)
+#
+# modified: index.html
+# modified: lib/simplegit.rb
+#
+```
+
+`git stash apply` da aynı şeyi yapar
+
+Şimdi kendi işine dönmeye hazırsın!
+
+[Ek Okuma.](http://git-scm.com/book/en/v1/Git-Tools-Stashing)
+
+### rebase (dikkat)
+
+Branch'ta commit'lenen tüm değişimleri al ve onları başka bir branch'ta tekrar oynat
+*Public repo'ya push edilmiş commit'leri rebase etme*
+
+```bash
+# Rebase experimentBranch onto master
+# git rebase <basebranch> <topicbranch>
+$ git rebase master experimentBranch
+```
+
+[Ek Okuma.](http://git-scm.com/book/en/Git-Branching-Rebasing)
+
+### reset (dikkat)
+
+Reset the current HEAD to the specified state. This allows you to undo merges,
+pulls, commits, adds, and more. It's a great command but also dangerous if you
+don't know what you are doing.
+
+HEAD'i belirtilen duruma resetle. Bu merge'leri, pull'ları, commit'leri, add'leri
+ve daha fazlasını geriye almanı sağlar. Muhteşem bir komuttur ama aynı zamanda, ne
+yaptığını bilmiyorsan, tehlikelidir.
+
+```bash
+# Reset the staging area, to match the latest commit (leaves dir unchanged)
+$ git reset
+
+# Reset the staging area, to match the latest commit, and overwrite working dir
+$ git reset --hard
+
+# Moves the current branch tip to the specified commit (leaves dir unchanged)
+# all changes still exist in the directory.
+$ git reset 31f2bb1
+
+# Moves the current branch tip backward to the specified commit
+# and makes the working dir match (deletes uncommitted changes and all commits
+# after the specified commit).
+$ git reset --hard 31f2bb1
+```
+
+### reflog (dikkat)
+
+Reflog, verilen zaman içinde,default olarak 90 gündür, yaptığın git komutlarını listeler.
+
+Bu sana beklemediğin şekilde yanlış giden komutları geriye çevirme şansı verir.
+(mesela, eğer bir rebase uygulamanı kırdıysa)
+
+Şu şekilde yapıbilirsin:
+
+1. `git reflog` rebase için tüm git komutlarını listele
+
+```
+38b323f HEAD@{0}: rebase -i (finish): returning to refs/heads/feature/add_git_reflog
+38b323f HEAD@{1}: rebase -i (pick): Clarify inc/dec operators
+4fff859 HEAD@{2}: rebase -i (pick): Update java.html.markdown
+34ed963 HEAD@{3}: rebase -i (pick): [yaml/en] Add more resources (#1666)
+ed8ddf2 HEAD@{4}: rebase -i (pick): pythonstatcomp spanish translation (#1748)
+2e6c386 HEAD@{5}: rebase -i (start): checkout 02fb96d
+```
+2. Nereye reset'leyeceğini seç, şu durumda `2e6c386` veya `HEAD@{5}`
+3. 'git reset --hard HEAD@{5}' bu repo'nu seçilen head'e eşitler
+4. Rebase'e yeniden başlayabilir veya onu yalnız bırakabilirsin.
+
+[Ek Okuma.](https://git-scm.com/docs/git-reflog)
+
+### revert
+
+Revert commit'leri geri almada kullanılır. Projenin durumunu önceki bir noktaya
+alan reset ile karıştırılmamalıdır. Revert, belirtilen commit'in tersine yeni bir
+commit ekleyecektir.
+
+```bash
+# Revert a specified commit
+$ git revert <commit>
+```
+
+### rm
+
+git add'in tersine, git rm çalışma ağacından dosyaları kaldırır.
+
+```bash
+# remove HelloWorld.c
+$ git rm HelloWorld.c
+
+# Remove a file from a nested dir
+$ git rm /pather/to/the/file/HelloWorld.c
+```
+
+## Daha Fazla Bilgi
+
+* [tryGit - Git'i öğrenmek için eğlenceli interaktif bir yol](http://try.github.io/levels/1/challenges/1)
+
+* [Git Dallanmayı Öğren - Git'i web üzerinde öğrenmek için en görsel ve interaktif yol](http://learngitbranching.js.org/)
+
+* [Udemy Git Tutorial: Kapsayıcı bir kılavuz](https://blog.udemy.com/git-tutorial-a-comprehensive-guide/)
+
+* [Git Immersion - Git'in temelinden başlayan bir tur](http://gitimmersion.com/)
+
+* [git-scm - Video Tutorial](http://git-scm.com/videos)
+
+* [git-scm - Dökümantasyon](http://git-scm.com/docs)
+
+* [Atlassian Git - Tutorial & Workflow](https://www.atlassian.com/git/)
+
+* [SalesForce Kopya Kağıdı](http://res.cloudinary.com/hy4kyit2a/image/upload/SF_git_cheatsheet.pdf)
+
+* [GitGuys](http://www.gitguys.com/)
+
+* [Git - Basit bir kılavuz](http://rogerdudler.github.io/git-guide/index.html)
+
+* [Pro Git](http://www.git-scm.com/book/en/v2)
+
+* [Yeni başlayanlar için Git ve Github](http://product.hubspot.com/blog/git-and-github-tutorial-for-beginners)
diff --git a/tr-tr/html-tr.html.markdown b/tr-tr/html-tr.html.markdown
new file mode 100644
index 00000000..b4afe7df
--- /dev/null
+++ b/tr-tr/html-tr.html.markdown
@@ -0,0 +1,157 @@
+---
+language: html
+filename: learnhtml-tr.txt
+contributors:
+ - ["Christophe THOMAS", "https://github.com/WinChris"]
+translators:
+ - ["Kemal MUTLU", "https://github.com/kemtake"]
+ - ["Nuri Akman", "https://github.com/vedia"]
+lang: tr-tr
+---
+
+HTML, HyperText Markup Language (Hiper Metin İşaretleme Dili) anlamına gelir.
+
+Web sayfaları yazmamızı sağlayan bir dildir. Bu işaretleme dili, metin ve verilerin nasıl gösterilmesi gerektiği kodlanarak web sayfaları yazmamızı sağlar. Aslında, html dosyaları basit metin dosyalarıdır.
+
+Bu işaretleme nedir? Sayfanın verilerini, açılış etiketleri ve kapanış etiketleri ile çevreleyerek düzenleme yöntemidir. Bu işaretleme, içerdiği metne anlam vermeyi sağlar. Diğer bilgisayar dillerinde olduğu gibi, HTML’nin birçok sürümü vardır. Burada HTML5 hakkında konuşacağız.
+
+**NOT :** Etkilerin nasıl çalıştıklarını anlamak, çıktılarını görebilmek için [codepen](https://codepen.io/) gibi bir siteden de faydalanabilirsiniz. Bu makale temel olarak HTML sözdizimi ve bazı yararlı ipuçlarıyla ilgilidir.
+
+```html
+<!-- Yorumlar bu satır gibi eklenir! -->
+
+<!--
+ Yorumlar
+ birden
+ fazla
+ satıra
+ yayılabilir!
+-->
+
+<!-- #################### Başlık #################### -->
+
+<!-- İşte, analiz edeceğimiz örnek bir HTML dosyası. -->
+
+
+<!doctype html>
+ <html>
+ <head>
+ <title>Benim Sitem</title>
+ </head>
+ <body>
+ <h1>Merhaba dünya!</h1>
+ <a href="http://codepen.io/anon/pen/xwjLbZ">
+ Bunun ne olduğuna bir bak.
+ </a>
+ <p>Bu bir paragraftır.</p>
+ <p>Bu başka bir paragraf.</p>
+ <ul>
+ <li>Bu, numaralandırılmamış bir listede bulunan bir öğe/maddedir (madde imi)</li>
+ <li>Bu başka bir öğe</li>
+ <li>Ve bu listedeki son öğe </li>
+ </ul>
+ </body>
+ </html>
+
+<!--
+Bir HTML dosyası, tarayıcıya her zaman sayfanın HTML olduğunu belirterek başlar.
+-->
+<!doctype html>
+
+<!-- Bundan sonra, bir <html> etiketi açılarak başlar. -->
+<html>
+
+<!-- dosyanın sonu </html> etiketi ile kapatılır. -->
+</html>
+
+<!-- Sayfada, bu son etiketten sonra hiçbir şey bulunmamalıdır. -->
+
+<!-- Açılış ve kapanış etiketleri arasında (<html> </html>) şunları bulunur: -->
+
+<!-- <head> ile tanımlanan bir sayfa başlığu (bu, </head> ile kapatılmalıdır). -->
+<!-- Baslik, gösterilmeyen bazi aciklamalar ve ek bilgiler icerir; buna üstveri denir. -->
+
+<head>
+ <!-- <title> etiketi, tarayıcıda gösterilecek başlığı gösterir. Pencerenin başlık çubuğu ve sekme adı.-->
+ <title>Benim Sitem</title>
+</head>
+
+<!-- <head> bölümünden sonra, <body> etiketi gelir. -->
+<!-- Bu noktaya kadar, tarif edilen hiçbir şey tarayıcı penceresinde görünmez. -->
+<!-- <body> etiketinden sonra görüntülenecek içeriğe yer verilir. -->
+
+<body>
+ <!-- h1 etiketi bir başlık oluşturur. -->
+ <h1>Merhaba Dünya!</h1>
+ <!--
+ Ayrıca başlıklar <h1> etiketinden <h6> etiketine kadar gidebilir.
+ <h1> etiketi en önemli, <h6> etiketi en düşük öncelikli başlığı yazmamızı sağlar.
+ -->
+
+ <!-- href="" özniteliğine verilen URL'ye bir köprü oluşturur. -->
+ <a href="http://codepen.io/anon/pen/xwjLbZ">
+ Bunun ne olduğuna bir bak.
+ </a>
+
+ <!-- <p> etiketi, html sayfasına metin eklememize izin verir. -->
+ <p>Bu bir paragraftır.</p>
+ <p>Bu başka bir paragraf.</p>
+
+ <!-- <ul> etiketi bir madde imi listesi oluşturur. -->
+ <!--
+ Numaralandırılmış bir listeye sahip olmak için <ol> etiketi de kullanılabilir. Bu durumda 1. madde 2. madde vb. şekilde gider.
+ -->
+ <ul>
+ <li>Bu, numaralandırılmamış bir bir liste kalemidir (madde imi)</li>
+ <li>Bu başka bir öğe</li>
+ <li>Ve bu listedeki son öğe</li>
+ </ul>
+</body>
+
+<!-- İşte bir html dosyası oluşturmak bu kadar basit. -->
+
+<!-- Ancak birçok farklı HTML etiketi türü de eklenebilir. -->
+
+<!-- <img /> etiketi bir resim eklemek için kullanılır. -->
+<!--
+Resmin kaynağı, src = "" özniteliği kullanılarak belirtilir.
+Kaynak, bir URL veya bilgisayarınızdaki bir dosyanın yolu olabilir.
+-->
+<img src="http://i.imgur.com/XWG0O.gif"/>
+
+<!-- HTML'de bir Tablo oluşturmak da mümkündür. -->
+
+<!-- Bir <table> elemanı açarız. -->
+<table>
+
+ <!-- <tr> bir satır oluşturmamızı sağlar. -->
+ <tr>
+ <!-- <th> tablo sütununa bir başlık vermemize izin verir. -->
+ <th>Birinci Başlık</th>
+ <th>İkinci Başlık</th>
+ </tr>
+
+ <tr>
+ <!-- <td> bir tablo hücresi oluşturmamızı sağlar. -->
+ <td>ilk satırın, ilk hücresi (sutunu)</td>
+ <td>ilk satırın, ikinci hücresi (sutunu)</td>
+ </tr>
+
+ <tr>
+ <td>ikinci satırın, ilk hücresi (sutunu) </td>
+ <td>ikinci satırın, ikinci hücresi (sutunu)</td>
+ </tr>
+</table>
+
+```
+
+## Kullanım
+
+HTML içeriği, .html veya .htm ile biten dosyalara yazılır. Mim türü text/html .
+HTML olarak yazılmış dosyalar, `.html` veya `.htm` dosya uzantısına sahiptirler. mime type'ı ise `text/html` dir.
+
+## Daha fazla bilgi için
+
+* [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/tr-tr/jquery-tr.html.markdown b/tr-tr/jquery-tr.html.markdown
new file mode 100644
index 00000000..4a4ebeae
--- /dev/null
+++ b/tr-tr/jquery-tr.html.markdown
@@ -0,0 +1,338 @@
+---
+category: tool
+tool: jquery
+contributors:
+ - ["Seçkin KÜKRER", "https://github.com/leavenha"]
+filename: jquery-tr-tr.js
+lang: tr-tr
+---
+
+# Tanım
+
+jQuery, (IPA: ˈd͡ʒeɪˌkwɪəɹiː).
+j + Query, olarak isimlendirilmiş, çünkü çoğunlukla HTML elementlerini sorgulamak ve onları manipüle etmek için kullanılır.
+
+jQuery, 2006 yılında geliştirilmiş ve günümüzde halen kullanımı yaygın, görece en popüler çapraz-platform JavaScript kütüphanelerinden birisidir. Şimdilerde jQuery ekibi tarafından gelişimi devam etmektedir. Dünyanın bir çok yerinden büyük şirketler ve bağımsız yazılım ekipleri tarafından kullanılmaktadır.
+
+Genel kullanım amacı animasyonlardır; Galeri, ek menü, sayfa geçişleri, ve diğer tüm gerçeklemelere sağladığı kolaylıkla birlikte Flash'ın alternatifi olarak yorumlanabilir. [Ajax][ajax-wikipedia-page] işlemleri de dahil olmak üzere olay-yönetimi, döküman manipülasyonu ve bir çok programlama görevini kolaylaştırır.
+
+Resmi sitesinden ([jQuery][jquery-official-website]) indirip web sitenize yükleyebilirsiniz. jQuery günümüz JavaScript kütüphaneleri gibi, küçültülmüş boyutlarda bulut tabanlı İçerik Dağıtım Ağı sistemleri sayesinde bağımsız olarak da sitenize eklenebilir.
+
+Kütüphanenin kullanımı ile, jQueryUI gibi ek paketlerle gelişmiş ve modern arayüzler gerçekleyebilirsiniz.
+
+Fakat, jQuery'ye giriş yapmadan önce elbetteki bu kütüphanenin üzerine kurulduğu teknoloji olan [JavaScript'i öğrenmelisiniz][javascript-learnxinyminutes-page].
+
+```js
+
+// Bu belgedeki değişken isimleri Türkçe,
+// ve [Lower Camel Case] notasyonu uygulamaktadır.
+// Bu belgedeki kod parçalarının çıktıları,
+// onları uyguladığınız dökümanın içeriğine bağlı olarak değişmektedir.
+
+// Döküman boyunca, aşağıdaki gösterimde
+// Kod - Çıktı ikilisi ile içeriğin anlamlandırılması
+// kolaylaştırılmaya çalışmıştır.
+// ornek_kod_parcasi();
+// => "ÖRNEK ÇIKTI"
+
+// *. Konsept
+// jQuery DOM nesnelerini seçmek için inovatif bir yol sunar.
+// `$` değişkeni, `jQuery` kütüphanesine işaret eder.
+// Fonksiyon notasyonu ile DOM nesnelerini elde eder
+// ve üzerinde işlemler gerçekleştirirsiniz.
+$(window)
+// => jQuery [Window] (1)
+// Bize tarayıcının belirlediği window nesnesini verir.
+
+// 1. Seçiciler
+// Tüm nesneleri seçmek için `*` çağırımı yapılır.
+const hepsi = $('*');
+// => jQuery [<html>, <head>, <meta>,
+// .... <meta>, <title>, <meta>, <meta>,
+// .... <meta>, <link>, <link>, …] (1134) = $1
+
+// Seçiciler, jQuery'de bir nesne seçmek için kullanılırlar,
+const sayfa = $(window);
+// => jQuery [window] (1)
+// Sayfa, açık döküman nesnesini seçer.
+
+// Elementler, kendileri için seçicidirler.
+const tumParagraflar = $('p');
+// => jQuery [<p>, <p>, <p>] (3)
+
+// Seçiciler aynı zamanda CSS seçicileri olabilir.
+const mavi = $('.mavi');
+// => jQuery [<p class='mavi'] (1)
+
+// Aynı zamanda element ile birlikte kullanılabilirler.
+const maviParagraf = $('p.mavi');
+// => jQuery [<p class='mavi'>] (1)
+
+// Özellik seçicileri de mevcuttur,
+// Elementin özelliği için seçim yaparlar.
+const isimSecicisi = $('input[name*="kayit.form"]');
+// => jQuery [<input name='kayit.form.sifre'>,
+// <input name='kayit.form.dogumtarihi'> ...] (10)
+
+// Diğer özellik seçiciler;
+/*
+- Özelliğin içinde arayan; *=
+- Özelliğin içinde verilen kelimeleri arayan; ~=
+ |-(kelimeler boşlukla ayrılmalı, *='den farkına dikkat ediniz.)
+- Özelliğin başlangıç verisini arayan; ^=
+- Özelliğin bitiş verisini arayan; $=
+- Özelliği tamamen karşılaştıran; =
+- Özelliğin eşitsizlik durumunu karşılaştıran; !=
+
+Diğer tüm seçiciler için resmi siteyi kontrol ediniz.
+*/
+
+// 2. Olaylar ve Efektler
+// - Olaylar
+// jQuery kullanıcı ile tarayıcı arasındaki etkileşimi olaylar ile ele alır.
+
+// En yaygın kullanımı tartışmasız ki Dökümanın Yüklenmesi olayıdır.
+
+// $.ready fonksiyonu, argüman olarak aldığı fonksiyonu,
+// seçilen eleman tamamen yüklendiğinde çağıracaktır.
+$(document).ready(function(){
+ // Dökümanın tamamı yüklendiğine göre, iş mantığımı çağırabiliriz.
+ console.info('Döküman yüklendi!');
+})
+// => jQuery [#document] (1)
+
+// Bir dökümanın tamamının yüklenmeden,
+// herhangi bir iş mantığı çalıştırmanın
+// neden kötü bir fikir olduğunu merak ediyorsanız,
+// ileri okuma kısmına danışabilirsiniz.
+
+// Önce Olay tanımlayalım.
+
+// Tıklama olayı için `$.click` olay tetikleyicisi kullanılıyor.
+$('.mavi').click(function(){
+ // Unutmayın ki, önceden tanımlanmış
+ // bir fonksiyonu da argüman olarak verebilirsiniz.
+ console.info('Mavi butona tıkladın!');
+})
+// => jQuery [<button>, <button>, <button>, <button>, <button>, …] (365)
+
+// Çift Tıklama olayı için `$.dblclick` olay tetikleyicisi kullanılıyor.
+$('.mavi').dblclick(function(){
+ console.info('Mavi butona çift tıkladın!');
+})
+// => jQuery [<button>, <button>, <button>, <button>, <button>, …] (365)
+
+// Seçilen Elemente birden fazla tetiklenecek fonksiyon tanımalamak
+// istersek, Olayları ve Fonksiyonları Anahtar-Değer yapısı sağlayan
+// Objeleri kullanarak da çağırabiliriz.
+
+// => tetiklenecekFonksiyon
+$('.mor').on({
+ click: () => console.info('Tek tıklama ile tetiklendim!'),
+ dblclick: () => console.info('Çift tıklama ile tetiklendim!'),
+ // ...
+});
+// => jQuery [<button>, <button>, <button>, <button>, <button>, …] (365)
+
+// Diğer olay tetikleyicileri;
+/*
+Elemente,
+- Fokus/Odaklanma; $.focus
+- Fokus/Odaklanmanın kaybedilmesi; $.blur
+- Farenin alanına girmesi; $.mouseenter
+- Farenin alanından çıkması; $.mouseleave
+
+Diğer tüm olay tetikleyicileri için resmi siteyi kontrol ediniz.
+*/
+
+// Tanımlanan olayları tetiklemek için,
+// Kullanıcı-Tarayıcı etkileşimi yerine elle çağrı yapmak da mümkün.
+// Tanımlama ile çağırım arasındaki fark sadece sağlanan argümanlardır.
+// Argümansız çağırım, olayı tetikler.
+
+// Tıklama olayını tetiklemek için.
+$('.mavi').click();
+// => Mavi butona tıkladın!
+// => jQuery [<button>] (1)
+
+// Çift Tıklama olayını tetiklemek için.
+$('.mavi').dblclick();
+// => Mavi butona çift tıkladın!
+// => jQuery [<button>] (1)
+
+// - Efektler
+// jQuery bir çok ön-tanımlı efekt sunmakta.
+// Bu efektler, belirli parametlerle, farklı iş mantıklarını
+// gerçeklemenize izin verebilir.
+// Önce parametresiz işlevlere göz atalım.
+
+// Elementleri saklayabilir,
+$('#slaytresmi').hide();
+// => jQuery [<img id='slaytresmi'>] (1)
+
+// Gizlenen elementleri tekrar görünür yapabilir,
+$('#slaytresmi').show();
+// => jQuery [<img id='slaytresmi'>] (1)
+
+// Yada dilediğiniz CSS niteliğini anime edebilirsiniz,
+
+// Bu parametre, anime etmek istediğiniz CSS özelliklerini
+// belirleyen Obje bilgisidir.
+// Yükseklik ve Genişlik bilgileri için değerler belirliyoruz.
+const animeEdilecekCSSOzellikleri =
+ {
+ weight: "300px",
+ height: "300px"
+ };
+
+// Diğer anime edilebilir CSS özellikleri;
+/*
+Elementin,
+- Opaklık; opacity
+- Dış çevre mesafesi; margin
+- Çerçeve yüksekliği; borderWidth
+- Satır yüksekliği; lineHeight
+
+Diğer tüm özellikler için resmi siteyi kontrol ediniz.
+*/
+
+// Bu parametre animasyonun süresini belirler.
+const milisaniyeCinsindenAnimasyonSuresi =
+ 1200;
+
+// Bu parametre, 'linear' yada 'swing' metin
+// bilgilerinden birini alır ve animasyonun
+// akıcılığını belirler.
+// x ∈ {'linear', 'swing'}
+const animasyonAkiciligi = 'linear';
+
+// Bu parametre, bir fonksiyondur ve
+// animasyondan sonra çağırılır.
+// Bir geri-çağırım (callback*) olarak değerlendirilebilir.
+const animasyonGeriCagirimFonksiyonu = function(){
+ console.info('Animasyon bitti!');
+};
+
+// Şimdi tanımlanan bilgilerimizle animasyonu çağırıyoruz.
+$('#slaytresmi').animate(animeEdilecekCSSOzellikleri,
+ milisaniyeCinsindenAnimasyonSuresi,
+ animasyonAkiciligi,
+ animasyonGeriCagirimFonksiyonu);
+// => jQuery [<img id='slaytresmi'>] (1)
+
+// Kütüphane `$.animate` fonksiyonu için, anime edeceğiniz
+// CSS özellikleri dışındaki tüm argümanlar için
+// ön tanımlı değerler sağlamaktadır.
+// Bu değerler için resmi siteyi kontrol ediniz.
+
+// Diğer ön tanımlı efektler;
+/*
+Elementi,
+- Yukarı kaydırır; $.slideUp
+- Verilen saydamlık değerine anime eder; $.fadeTo
+- Görünür yada görünmez yapar (geçerli durumuna bağlı); $.toggle
+
+Diğer tüm efektler için resmi siteyi kontrol ediniz.
+*/
+
+// 3. Manipülasyon
+
+// jQuery'de, HTML elementlerinin isteğiniz doğrultusunda
+// değiştirilmesi için araçlar sunulmakta.
+
+// Bir ön-tanımlı CSS sınıfımız olduğunu hayal edebilirsiniz.
+// Bu sınıfı istediğimiz elemente uygulamak için,
+$('#slaytresmi').addClass('inanilmaz-bir-cerceve-sinifi');
+// => jQuery [<img id='slaytresmi' class='inanilmaz-bir-cerceve-sinifi'>] (1)
+
+// Bu CSS sınıfını istediğimiz zaman silebiliriz,
+$('#slaytresmi').removeClass('inanilmaz-bir-cerceve-sinifi');
+// => jQuery [<img id='slaytresmi'>] (1)
+
+// Bu HTML elementini, istediğimiz başka bir element ile çevreleyebiliriz,
+$('#slaytresmi').wrap('<div class="farkli-bir-cerceve"></div>');
+// => jQuery [<img id='slaytresmi'>] (1)
+// Sonucun gözlemlenebilmesi için, elementin çevreleme işlemi sonrası
+// döküman üzerindeki yapısını temel bir seçici ile gözlemleyebiliriz;
+$('.farli-bir-cerceve')
+// => jQuery [<div class='farkli-bir-cerceve>] (1)
+// => <div class="farkli-bir-cerceve">
+// <img id='slaytresmi'>
+// </div>
+
+// Elemente içerik ekleyebiliriz,
+// Eklemeler döküman içeriğinin sonuna yapılacaktır.
+// Bu süreci daha iyi gözlemleyebilmek için içeriğine bakmamız yeterli,
+// Ekleme öncesinde;
+$('.farkli-bir-cerceve');
+// => jQuery [<div class='farkli-bir-cerceve>] (1)
+// => <div class="farkli-bir-cerceve">
+// <img id='slaytresmi'>
+// </div>
+
+// `$.append` fonksiyonu ile ekleme işlemini yapıyoruz.
+$('.farkli-bir-cerceve').append('<h1>Bu çerçeve farklı!</h1>');
+// => jQuery [<div class='farkli-bir-cerceve>] (1)
+// => <div class="farkli-bir-cerceve">
+// <img id='slaytresmi'>
+// <h1>Bu çerçeve farklı!</h1>
+// </div>
+
+// Dökümandan element silebiliriz,
+$('.farkli-bir-cerceve > h1').remove();
+// => jQuery [<h1>] (1)
+
+// Dökümanın güncel halini görmek için seçiciyi çağırıyoruz,
+$('.farkli-bir-cerceve');
+// => jQuery [<div class='farkli-bir-cerceve>] (1**
+// => <div class="farkli-bir-cerceve">
+// <img id='slaytresmi'>
+// </div>
+
+// Elementlerin özniteliklerini değiştirebilir yada
+// silebiliriz.
+// Öznitelik erişici ve değiştiricisi,
+// Bir fonksiyon notasyonuyla yapılanmış durumda.
+// Eğer bir öznitelik bilgisini almak istiyorsak, ilgili öznitelik
+// ismini;
+
+$('.farkli-bir-cerceve > img').attr('id');
+// => 'slaytresmi'
+
+// Eğer bir öznitelik bilgisini güncellemek istiyorsak,
+// ilgili öznitelik ismi ve sonrasında yeni değerini argüman
+// olarak $.attr fonksiyonuna iletiyoruz;
+
+$('.farkli-bir-cerceve > img').attr('id', 'cercevelislaytresmi');
+// => jQuery [<img id='cercevelislaytresmi'>] (1)
+
+// Diğer ön fonksiyonlar;
+/*
+Elementin,
+- Yükseklik değeri, $.height
+- HTML döküman içeriği, $.html
+- Girdi içeriği, $.val
+- Verilen CSS sınıfına sahipliği, $.hasClass
+
+Diğer tüm manipülasyon fonksiyonları için resmi siteyi kontrol ediniz.
+*/
+
+```
+
+## Notlar
+
+- Yaygın bir yanlış bilineni düzeltmek adına; jQuery bir çalışma-çatısı değil, bir *kütüphanedir*.
+- [Lower Camel Case][lower-camel-case-notasyonu] notasyonu için Wikipedia sayfası.
+
+## İleri Okuma
+
+### İngilizce
+
+- [jQuery][jquery-official-website] resmi sitesi.
+
+- [Jakob Jenkov | $(document).ready article](http://tutorials.jenkov.com/jquery/document-ready.html)
+
+[jquery-official-website]: https://jquery.com
+[ajax-wikipedia-page]: https://en.wikipedia.org/wiki/Ajax_(programming)
+[javascript-learnxinyminutes-page]: https://learnxinyminutes.com/docs/javascript/
+[lower-camel-case-notasyonu]: https://en.wikipedia.org/wiki/Camel_case#Programming_and_coding
diff --git a/tr-tr/kotlin-tr.html.markdown b/tr-tr/kotlin-tr.html.markdown
new file mode 100644
index 00000000..4d2dd291
--- /dev/null
+++ b/tr-tr/kotlin-tr.html.markdown
@@ -0,0 +1,474 @@
+---
+language: kotlin
+filename: kotlin-tr.kt
+contributors:
+ - ["Baha Can Aydın", "https://github.com/bahacan19"]
+lang: tr-tr
+---
+Kotlin, JVM, Android ve tarayıcı için statik olarak yazılmış bir programlama dilidir.
+Java %100 birlikte çalışabilir.
+[Daha:](https://kotlinlang.org/)
+
+```kotlin
+
+// Tek satır yoruma almak için : //
+/*
+ Birkaç satırı yoruma almak için
+*/
+
+// "package" anahtar kelimesi tıpkı Java'da olduğu gibidir.
+package com.learnxinyminutes.kotlin
+
+/*
+Bir Kotlin programının başlama noktası (Java'da olduğu gibi) "com.learnxinyminutes.kotlin.main" metodudur.
+Bu metoda komut satırından bir 'Array' gönderilebilir.
+*/
+fun main(args: Array<String>) {
+ /*
+ Bir değer tanımlamak için "var" ya da "val" anahtar kelimeleri kullanılıyor.
+ "val" tanımlananlar tekrar atanamazken "var" tanımlananlar atanabilir.
+ */
+ val fooVal = 10 // fooVal değerini daha sonra tekrar atayamıyoruz
+ var fooVar = 10
+ fooVar = 20 // fooVar tekrar atanabilir.
+
+ /*
+ Çoğu zaman, Kotlin bir değişkenin tipini anlayabilir,
+ bu yüzden her zaman belirtmeye gerek yoktur.
+ Bir değişkenin tipini şöyle belirtebiliriz:
+ */
+ val foo: Int = 7
+
+ /*
+ String değerler Java'da olduğu gibi tanımlanır.
+ */
+ val fooString = "İşte String bu!"
+ val barString = "Yeni satıra geçiyorum...?\nGeçtim!"
+ val bazString = "Tab mı istedin?\tAl bakalım!"
+ println(fooString)
+ println(barString)
+ println(bazString)
+
+ /*
+ Raw string, üçlü çift-tırnak sınırlandırılan String bloklarıdır.
+ Tıpkı bir text editör gibi String tanımlamaya izin verir.
+ */
+ val fooRawString = """
+fun helloWorld(val name : String) {
+ println("Merhaba, dünya!")
+}
+"""
+ println(fooRawString)
+
+ /*
+ String değerler, ($) işareti ile birtakım deyimler ve değerler içererbilir
+ */
+ val fooTemplateString = "$fooString değerinin ${fooString.length} adet karakteri vardır."
+ println(fooTemplateString)
+
+ /*
+ Null atanabilen bir değişken nullable olarak tanımlanmalıdır.
+ Bu, deişken tipinin sonuna ? eklenerek yapılabilir.
+ Erişim ise '?.' operatörü ile yapılır.
+ Bir değişken null ise, yerine kullaılacak alternatif bir değer belirtmek için
+ '?:' operatörünü kullanırız.
+ */
+ var fooNullable: String? = "abc"
+ println(fooNullable?.length) // => 3
+ println(fooNullable?.length ?: -1) // => 3
+ fooNullable = null
+ println(fooNullable?.length) // => null
+ println(fooNullable?.length ?: -1) // => -1
+
+ /*
+ Metodlar "fun" anahtar kelimesi ile tanımlanır.
+ Metod argümanları, Metod adından sonra parantez içinde belirtilir.
+ Metod argümanlarının opsiyonel olarak default (varsayılan) değerleri olabilir.
+ Metodun dönüş tipi, gerekirse, metod parentezinden sonra ':' operatörü ile belirtilir.
+ */
+ fun hello(name: String = "dünya"): String {
+ return "Merhaba, $name!"
+ }
+ println(hello("foo")) // => Merhaba, foo!
+ println(hello(name = "bar")) // => Merhaba, bar!
+ println(hello()) // => Merhaba, dünya!
+
+ /*
+ Bir metoda çokca argüman göndermek için 'vararg' anahtar kelimesi
+ kullanılır.
+ */
+ fun varargExample(vararg names: Int) {
+ println("${names.size} adet arguman paslanmıştır")
+ }
+ varargExample() // => 0 adet arguman paslanmıştır
+ varargExample(1) // => 1 adet arguman paslanmıştır
+ varargExample(1, 2, 3) // => 3 adet arguman paslanmıştır
+
+ /*
+ Bir metod tek bir ifadeden oluşuyorsa
+ süslü parantezler yerine '=' kullanılabilir.
+ */
+ fun odd(x: Int): Boolean = x % 2 == 1
+ println(odd(6)) // => false
+ println(odd(7)) // => true
+
+ // Eğer dönüş tipi anlaşılabiliyorsa ayrıca belirtmemize gerek yoktur.
+ fun even(x: Int) = x % 2 == 0
+ println(even(6)) // => true
+ println(even(7)) // => false
+
+ // Metodlar, metodları arguman ve dönüş tipi olarak alabilir
+ fun not(f: (Int) -> Boolean): (Int) -> Boolean {
+ return {n -> !f.invoke(n)} // bu satırdaki !f.invoke(n) metodu !f(n) şeklinde sadeleştirilebilir.
+ }
+
+
+ // Bir metodu sadece '::' ön eki ile de arguman olarak çağırabiliriz
+ println(not(::odd)(4)) // ==> true
+
+ // Metodlar değişken gibi atanabilir.
+ val notOdd = not(::odd)
+ val notEven = not(::even)
+
+ // Lambda ifadeleri arguman olarak paslanabilir.
+ val notZero = not {n -> n == 0}
+ /*
+ Eğer bir lambda fonksiyonu sadece bir arguman alıyorsa,
+ '->' ifadesi atlanabilir, 'it' ifadesi ile belirtilebilir.
+ */
+ val notPositive = not { it > 0} // not(n -> n > 0) ifadesi ile aynı
+
+ for (i in 0..4) {
+ println("${notOdd(i)} ${notEven(i)} ${notZero(i)} ${notPositive(i)}")
+ }
+
+ /*
+ * Diğer for döngüleri
+ * */
+ val myInt = 3
+ for (i in 1..100) { } // kapalı aralık. 100 dahil.
+ for (i in 1 until 100) { } // 100 dahil değil
+ for (x in 2..10 step 2) { } // ikişer adımlı
+ for (x in 10 downTo 1) { } // Ondan geriye doğru. 1 dahil.
+ if (myInt in 1..10) { }
+
+
+
+ /*
+ Bir sınıf tanımlamak için 'class' anahtar kelimesi kullanılır.
+ Kotlin'de bütün sınıflar varsayılan olarak 'final' tanımlanırlar.
+ * */
+ class ExampleClass(val x: Int) {
+
+ fun memberFunction(y: Int): Int {
+ return x + y
+ }
+
+ infix fun yTimes(y: Int): Int {
+ return x * y
+ }
+ }
+ /*
+ * Bir sınıfı türetilebilir yapmak için 'open' anahtar kelimesi kullanılır.
+ * */
+ open class A
+
+ class B : A()
+
+
+ /*
+ Yeni bir instance oluşturmak için doğrudan constructor çağırılır.
+ Kotlinde 'new' anahtar kelimesi yoktur.
+ */
+ val fooExampleClass = ExampleClass(7)
+ // Bir sınıfa üye metodları . (nokta) ile çağırabiliriz.
+ println(fooExampleClass.memberFunction(4)) // => 11
+ /*
+ 'infix' ön eki ile tanımlanan metodlar
+ alışılan metod çağrısını daha kolay bir söz dizimine dönüştürür.
+ */
+ println(fooExampleClass yTimes 4) // => 28
+
+ /*
+ Data class lar sadece veri tutan sınıflar için uygun bir çözümdür.
+ Bu şekilde tanımlanan sınıfların "hashCode"/"equals" ve "toString" metodları
+ otomatik olarak oluşur.
+ */
+ 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)
+
+ // Data class ların copy metodları olur.
+ val fooCopy = fooData.copy(y = 100)
+ println(fooCopy) // => DataClassExample(x=1, y=100, z=4)
+
+ // Destructuring Declarations, bir objeyi çoklu değişkenler ile ifade etme yöntemidir.
+ val (a, b, c) = fooCopy
+ println("$a $b $c") // => 1 100 4
+
+ // bir 'for' döngüsü içinde 'Destructuring' :
+ 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 de destructurable gösterilebilir.
+ for ((key, value) in mapData) {
+ println("$key -> $value")
+ }
+
+ // 'with' metodu ile bir objeye bir lamda metodu uygulayabiliriz.
+ data class MutableDataClassExample (var x: Int, var y: Int, var z: Int)
+ val fooMutableData = MutableDataClassExample(7, 4, 9)
+ with (fooMutableData) {
+ x -= 2
+ y += 2
+ z--
+ }
+
+ println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8)
+
+ /*
+ 'listOf' metodu ile bir liste oluşturulabilir.
+ Oluşan liste immutable olacaktır, yani elaman eklenemez ve çıkarılamaz.
+ */
+ val fooList = listOf("a", "b", "c")
+ println(fooList.size) // => 3
+ println(fooList.first()) // => a
+ println(fooList.last()) // => c
+ // Elemanlara indexleri ile erişilebilir.
+ println(fooList[1]) // => b
+
+ // Mutable bir liste ise 'mutableListOf' metodu ile oluşturabilir.
+ val fooMutableList = mutableListOf("a", "b", "c")
+ fooMutableList.add("d")
+ println(fooMutableList.last()) // => d
+ println(fooMutableList.size) // => 4
+
+ // Bir 'set' oluşturmak için 'setOf' metodunu kullanabiliriz.
+ val fooSet = setOf("a", "b", "c")
+ println(fooSet.contains("a")) // => true
+ println(fooSet.contains("z")) // => false
+
+ // 'mapOf' metodu ile 'map' oluşturabiliriz.
+ val fooMap = mapOf("a" to 8, "b" to 7, "c" to 9)
+ // Map değerlerine ulaşmak için :
+ println(fooMap["a"]) // => 8
+
+ /*
+ Sequence, Kotlin dilinde lazy-hesaplanan collection ları temsil eder.
+ Bunun için 'generateSequence' metodunu kullanabiliriz. Bu metod bir önceki değerden
+ bir sonraki değeri hesaplamak için gerekli bir lamda metodunu arguman olarak alır.
+ */
+ val fooSequence = generateSequence(1, { it + 1 })
+
+ val x = fooSequence.take(10).toList()
+ println(x) // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+
+ // Örneğin fibonacci serisi oluşturabilen bir 'Sequence' oluşturmak için:
+ 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 Collection lar ile çalışmak için higher-order metodlar sağlar.
+ val z = (1..9)
+ .map {it * 3} // her bir elamanı 3 ile çarp
+ .filter {it < 20} // 20 den küçük değerleri ele
+ .groupBy {it % 2 == 0} // ikiye tam bölünen ve bölünmeyen şeklinde grupla (Map)
+ .mapKeys {if (it.key) "even" else "odd"} // oluşan map in boolen 'key' lerini String bir değere dönüştür.
+ println(z) // => {odd=[3, 9, 15], even=[6, 12, 18]}
+
+ // Bir 'for' döngüsü 'itearator' sağlayan her objeye uygulanabilir.
+ for (c in "merhaba") {
+ println(c)
+ }
+
+ // 'while' döngüsü diğer dillere benzer şekilde çalışır.
+ var ctr = 0
+ while (ctr < 5) {
+ println(ctr)
+ ctr++
+ }
+ do {
+ println(ctr)
+ ctr++
+ } while (ctr < 10)
+
+ /*
+ 'if' bir dönüş değeri olan deyim gibi de kullanılabilir.
+ Bu sebepten Kotlin, Java'da bulunan '?:' ifadesi içermez.
+ */
+ val num = 5
+ val message = if (num % 2 == 0) "even" else "odd"
+ println("$num is $message") // => 5 is odd
+
+ // 'if-else if' yapıları için 'when' kullanılabilir.
+ val i = 10
+ when {
+ i < 7 -> println("first block")
+ fooString.startsWith("hello") -> println("second block")
+ else -> println("else block")
+ }
+
+ // 'when' bir parametre ile de kullanılabilir.
+ 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' dönüş değeri olan bir metod gibi de davranabilir.
+ 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)
+
+
+ /*
+ Bir objenin tipini 'is' operatörü ile tayin edebiliriz.
+ Eğer obje tip kontrolünü geçerse, cast etmeden doğrudan
+ o tipteymiş gibi kullanılabilir.
+ */
+ fun smartCastExample(x: Any) : Boolean {
+ if (x is Boolean) {
+ // x otomatik olarak Boolean'a cast edilir.
+ return x
+ } else if (x is Int) {
+ // x otomatik olarak Int tipine cast edilir.
+ return x > 0
+ } else if (x is String) {
+ // x otomatik olarak String tipine cast edilir.
+ return x.isNotEmpty()
+ } else {
+ return false
+ }
+ }
+ println(smartCastExample("Merhaba, dünya!")) // => true
+ println(smartCastExample("")) // => false
+ println(smartCastExample(5)) // => true
+ println(smartCastExample(0)) // => false
+ println(smartCastExample(true)) // => true
+
+ // Smartcast 'when' bloğu ile de çalışır.
+ fun smartCastWhenExample(x: Any) = when (x) {
+ is Boolean -> x
+ is Int -> x > 0
+ is String -> x.isNotEmpty()
+ else -> false
+ }
+
+ /*
+ Extension lar, bir sınıfa fonksinolalite eklemenin bir yoludur.
+ */
+ fun String.remove(c: Char): String {
+ return this.filter {it != c}
+ }
+ println("Merhaba, dünya!".remove('a')) // => Merhb, düny!
+
+
+
+ //Biraz detaylı Kotlin
+
+
+ /*
+ * Delegated Properties, bir değişken tanımlarken kullanılan birkaç standart yöntemler içerir.
+ * https://kotlinlang.org/docs/reference/delegated-properties.html
+ * En bilinen delegate property metodları: lazy(), observable()
+ * */
+
+ /*
+ * Lazy, bir değişkeni ilk erişimde çalıştırılacak olan bir lambda ile tanımlama metodudur.
+ * Sonraki erişimlerde değişkene atanan değer hatırlanır.
+ * Lazy, synchronized bir delegation yöntemidir; değer sadece bir thread içinde hesaplanır,
+ * tüm thread ler aynı değere erişir. Eğer senkronizasyon gerekli değilse, lazy metodu içine
+ * LazyThreadSafetyMode.PUBLICATION paslanabilir.
+ * */
+
+ val lazyValue: String by lazy( {
+ println("bi sn... hesaplıyorum....")
+ "Selam!"
+ })
+
+ println(lazyValue)// bi sn... hesaplıyorum.... Selam!
+ println(lazyValue) // Selam!
+ /*
+ * Observable, bir değişkende olabilecek yeniden atama değişikliklerini dinleme yöntemidir.
+ * İki arguman alır; değişkenin ilk değeri, değiştiğinde çağrılan bir handler metodu. Handler
+ * metodu değişken her değiştiğinde çağırılır.
+ * */
+ var myObservableName: String by Delegates.observable("<isim yok>") {
+ prop, old, new ->
+ println("$old -> $new")
+ }
+ myObservableName = "Baha" //<isim yok> -> Baha
+ myObservableName = "Can" //Baha -> Can
+
+
+ /*
+ * Eğer değişkenin yeniden atanmasını denetlemek isterek vetoable()
+ * metodunu kullanabiliriz.
+ * */
+
+ var myVetoableName : String by Delegates.vetoable("<isim yok>"){
+ property, oldValue, newValue ->
+ if (newValue.length < 2) {
+ println("Tek harfli isim kabul etmiyoruz!")
+ false
+ } else {
+ println("$oldValue -> $newValue")
+ true
+ }
+ }
+
+ myVetoableName = "Baha" //<isim yok> -> Baha
+ myVetoableName = "C" //Tek harfli isim kabul etmiyoruz!
+ println(myVetoableName) //Baha
+
+
+ //singleton değişkene ulaşmak:
+ println(ObjectExample.hello()) // => Merhaba
+}
+
+// Enum class lar Java'daki enum lara benzerdir.
+enum class EnumExample {
+ A, B, C
+}
+
+/*
+'object' anahtar kelimesi ile singleton nesneler oluşturulabilir.
+Bu şekilde tanımlanan sınıflardan yeni nesneler oluşturulamaz, sadece adı ile refere edilebilir.
+*/
+object ObjectExample {
+ fun hello(): String {
+ return "Merhaba"
+ }
+}
+
+fun useObject() {
+ ObjectExample.hello()
+ val someRef: Any = ObjectExample
+}
+
+```
+
+### İlerisi için:
+
+* [Kotlin tutorials](https://kotlinlang.org/docs/tutorials/)
+* [Try Kotlin in your browser](http://try.kotlinlang.org/)
+* [A list of Kotlin resources](http://kotlin.link/)
+* [Kotlin Koans in your IDE](https://kotlinlang.org/docs/tutorials/koans.html/)
diff --git a/tr-tr/markdown-tr.html.markdown b/tr-tr/markdown-tr.html.markdown
index b8f11e39..6caba1da 100644
--- a/tr-tr/markdown-tr.html.markdown
+++ b/tr-tr/markdown-tr.html.markdown
@@ -11,7 +11,7 @@ filename: markdown-tr.md
Markdown, 2004 yılında John Gruber tarafından oluşturuldu. Asıl amacı kolay okuma ve yazmayı sağlamakla beraber kolayca HTML (artık bir çok diğer formatlara) dönüşüm sağlamaktır.
-```markdown
+```md
<!-- Markdown, HTML'i kapsar, yani her HTML dosyası geçerli bir Markdown dosyasıdır, bu demektir
ki Markdown içerisinde HTML etiketleri kullanabiliriz, örneğin bu yorum elementi, ve
markdown işleyicisinde etki etmezler. Fakat, markdown dosyası içerisinde HTML elementi oluşturursanız,
diff --git a/tr-tr/python-tr.html.markdown b/tr-tr/python-tr.html.markdown
index 01285080..6d9cdcbe 100644
--- a/tr-tr/python-tr.html.markdown
+++ b/tr-tr/python-tr.html.markdown
@@ -1,316 +1,344 @@
---
-language: python
-filename: learnpython-tr.py
+language: Python
contributors:
- - ["Louie Dinh", "http://ldinh.ca"]
+ - ["Louie Dinh", "http://pythonpracticeprojects.com"]
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+ - ["Batuhan Osman T.", "https://github.com/BTaskaya"]
translators:
- - ["Haydar KULEKCI", "http://scanf.info/"]
+ - ["Eray AYDIN", "http://erayaydin.me/"]
lang: tr-tr
+filename: learnpython-tr.py
---
-Python Guido Van Rossum tarafından 90'ların başında yaratılmıştır. Şu anda
-varolanlar arasında en iyi dillerden birisidir. Ben (Louie Dinh) Python
-dilinin syntax'ının belirginliğine aşığım. O basit olarak çalıştırılabilir
-pseudocode'dur.
-Geri bildirimlerden son derece mutluluk duyarım! Bana [@louiedinh](http://twitter.com/louiedinh)
-adresinden ya da louiedinh [at] [google's email service] adresinden ulaşabilirsiniz.
+Python,90ların başlarında Guido Van Rossum tarafından oluşturulmuştur. En popüler olan dillerden biridir. Beni Python'a aşık eden sebep onun syntax beraklığı. Çok basit bir çalıştırılabilir söz koddur.
-Çeviri için geri bildirimleri de [@kulekci](http://twitter.com/kulekci)
-adresine yapabilirsiniz.
+Not: Bu makale Python 3 içindir. Eğer Python 2.7 öğrenmek istiyorsanız [burayı](http://learnxinyminutes.com/docs/pythonlegacy/) kontrol edebilirsiniz.
-Not: Bu yazıdaki özellikler Python 2.7 için geçerlidir, ama Python 2.x için de
-uygulanabilir. Python 3 için başka bir zaman tekrar bakınız.
+```python
+# Tek satırlık yorum satırı kare(#) işareti ile başlamaktadır.
-```python
-# Tek satır yorum hash işareti ile başlar.
-""" Çoklu satır diziler üç tane çift tırnak
- arasında yazılır. Ve yorum olarak da
- kullanılabilir
+""" Çok satırlı olmasını istediğiniz yorumlar
+ üç adet tırnak(") işareti ile
+ yapılmaktadır
"""
-
####################################################
-## 1. İlkel Veri Tipleri ve Operatörler
+## 1. Temel Veri Türleri ve Operatörler
####################################################
# Sayılar
-3 #=> 3
+3 # => 3
+
+# Tahmin edebileceğiniz gibi matematik
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+
+# Bölme işlemi varsayılan olarak onluk döndürür
+35 / 5 # => 7.0
+
+# Tam sayı bölmeleri, pozitif ve negatif sayılar için aşağıya yuvarlar
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # onluklar için de bu böyledir
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
-# Matematik beklediğiniz gibi
-1 + 1 #=> 2
-8 - 1 #=> 7
-10 * 2 #=> 20
-35 / 5 #=> 7
+# Onluk kullanırsanız, sonuç da onluk olur
+3 * 2.0 # => 6.0
-# Bölünme biraz ilginç. EĞer tam sayılar üzerinde bölünme işlemi yapıyorsanız
-# sonuç otomatik olarak kırpılır.
-5 / 2 #=> 2
+# Kalan operatörü
+7 % 3 # => 1
-# Bölünme işlemini düzenlemek için kayan noktalı sayıları bilmeniz gerekir.
-2.0 # Bu bir kayan noktalı sayı
-11.0 / 4.0 #=> 2.75 ahhh...daha iyi
+# Üs (2 üzeri 4)
+2**4 # => 16
-# İşlem önceliğini parantezler ile sağlayabilirsiniz.
-(1 + 3) * 2 #=> 8
+# Parantez ile önceliği değiştirebilirsiniz
+(1 + 3) * 2 # => 8
-# Boolean değerleri bilindiği gibi
+# Boolean(Doğru-Yanlış) değerleri standart
True
False
-# not ile nagatif(mantıksal) değerini alma
-not True #=> False
-not False #=> True
+# 'değil' ile terse çevirme
+not True # => False
+not False # => True
-# Eşitlik ==
-1 == 1 #=> True
-2 == 1 #=> False
+# Boolean Operatörleri
+# "and" ve "or" büyük küçük harf duyarlıdır
+True and False #=> False
+False or True #=> True
-# Eşitsizlik !=
-1 != 1 #=> False
-2 != 1 #=> True
+# Bool operatörleri ile sayı kullanımı
+0 and 2 #=> 0
+-5 or 0 #=> -5
+0 == False #=> True
+2 == True #=> False
+1 == True #=> True
-# Daha fazla karşılaştırma
-1 < 10 #=> True
-1 > 10 #=> False
-2 <= 2 #=> True
-2 >= 2 #=> True
+# Eşitlik kontrolü ==
+1 == 1 # => True
+2 == 1 # => False
-# Karşılaştırma zincirleme yapılabilir!
-1 < 2 < 3 #=> True
-2 < 3 < 2 #=> False
+# Eşitsizlik Kontrolü !=
+1 != 1 # => False
+2 != 1 # => True
-# Karakter dizisi " veya ' ile oluşturulabilir
-"This is a string."
-'This is also a string.'
+# Diğer karşılaştırmalar
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
-# Karakter dizileri birbirleri ile eklenebilir
-"Hello " + "world!" #=> "Hello world!"
+# Zincirleme şeklinde karşılaştırma da yapabilirsiniz!
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
-# A string can be treated like a list of characters
-# Bir string'e karakter listesi gibi davranabilirsiniz.
-"This is a string"[0] #=> 'T'
+# Yazı(Strings) " veya ' işaretleri ile oluşturulabilir
+"Bu bir yazı."
+'Bu da bir yazı.'
-# % karakter dizisini(string) formatlamak için kullanılır, bunun gibi:
-"%s can be %s" % ("strings", "interpolated")
+# Yazılar da eklenebilir! Fakat bunu yapmanızı önermem.
+"Merhaba " + "dünya!" # => "Merhaba dünya!"
-# String'leri formatlamanın yeni bir yöntem ise format metodudur.
-# Bu metod tercih edilen yöntemdir.
-"{0} can be {1}".format("strings", "formatted")
-# Eğer saymak istemiyorsanız anahtar kelime kullanabilirsiniz.
-"{name} wants to eat {food}".format(name="Bob", food="lasagna")
+# Bir yazı(string) karakter listesi gibi işlenebilir
+"Bu bir yazı"[0] # => 'B'
-# None bir objedir
-None #=> None
+# .format ile yazıyı biçimlendirebilirsiniz, şu şekilde:
+"{} da ayrıca {}".format("yazılar", "işlenebilir")
-# "==" eşitliğini non objesi ile karşılaştırmak için kullanmayın.
-# Onun yerine "is" kullanın.
-"etc" is None #=> False
-None is None #=> True
+# Biçimlendirme işleminde aynı argümanı da birden fazla kullanabilirsiniz.
+"{0} çeviktir, {0} hızlıdır, {0} , {1} üzerinden atlayabilir".format("Ahmet", "şeker çubuğu")
+#=> "Ahmet çeviktir, Ahmet hızlıdır, Ahmet , şeker çubuğu üzerinden atlayabilir"
-# 'is' operatörü obje kimliği için test etmektedir. Bu ilkel değerler
-# için kullanışlı değildir, ama objeleri karşılaştırmak için kullanışlıdır.
+# Argümanın sırasını saymak istemiyorsanız, anahtar kelime kullanabilirsiniz.
+"{isim} yemek olarak {yemek} istiyor".format(isim="Ahmet", yemek="patates") #=> "Ahmet yemek olarak patates istiyor"
-# None, 0 ve boş string/list'ler False olarak değerlendirilir.
-# Tüm eşitlikler True döner
-0 == False #=> True
-"" == False #=> True
+# Eğer Python 3 kodunuz ayrıca Python 2.5 ve üstünde çalışmasını istiyorsanız,
+# eski stil formatlamayı kullanabilirsiniz:
+"%s bu %s yolla da %s" % ("yazılar", "eski", "biçimlendirilebilir")
-####################################################
-## 2. Değişkenler ve Kolleksiyonlar
-####################################################
+# Hiçbir şey(none) da bir objedir
+None # => None
-# Ekrana yazdırma oldukça kolaydır.
-print "I'm Python. Nice to meet you!"
+# Bir değerin none ile eşitlik kontrolü için "==" sembolünü kullanmayın
+# Bunun yerine "is" kullanın. Obje türünün eşitliğini kontrol edecektir.
+"vb" is None # => False
+None is None # => True
+# None, 0, ve boş yazılar/listeler/sözlükler hepsi False değeri döndürü.
+# Diğer veriler ise True değeri döndürür
+bool(0) # => False
+bool("") # => False
+bool([]) #=> False
+bool({}) #=> False
-# Değişkenlere bir değer atamadan önce tanımlamaya gerek yoktur.
-some_var = 5 # Değişken isimlerinde gelenek küçük karakter ve alt çizgi
- # kullanmaktır.
-some_var #=> 5
-# Daha önceden tanımlanmamış ya da assign edilmemeiş bir değişkene erişmeye
-# çalıştığınızda bir hata fırlatılacaktır. Hata ayıklama hakkında daha fazla
-# bilgi için kontrol akışı kısmına göz atınız.
-some_other_var # isim hatası fırlatılır
+####################################################
+## 2. Değişkenler ve Koleksiyonlar
+####################################################
-# isterseniz "if"i bir ifade gibi kullanabilirsiniz.
-"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+# Python bir yazdırma fonksiyonuna sahip
+print("Ben Python. Tanıştığıma memnun oldum!")
-# Listeler
+# Değişkenlere veri atamak için önce değişkeni oluşturmanıza gerek yok.
+# Düzenli bir değişken için hepsi_kucuk_ve_alt_cizgi_ile_ayirin
+bir_degisken = 5
+bir_degisken # => 5
+
+# Önceden tanımlanmamış değişkene erişmek hata oluşturacaktır.
+# Kontrol akışları başlığından hata kontrolünü öğrenebilirsiniz.
+bir_bilinmeyen_degisken # NameError hatası oluşturur
+
+# Listeler ile sıralamaları tutabilirsiniz
li = []
-# Önceden değerleri tanımlanmış listeler
-other_li = [4, 5, 6]
-
-# Bir listenin sonuna birşeyler eklemek
-li.append(1) #li şu anda [1]
-li.append(2) #li şu anda [1, 2]
-li.append(4) #li şu anda [1, 2, 4]
-li.append(3) #li şu anda [1, 2, 4, 3]
-# pop ile sondan birşeyler silmek
-li.pop() #=> 3 and li is now [1, 2, 4]
-# Tekrar sonuna eklemek
-li.append(3) # li is now [1, 2, 4, 3] again.
-
-# Dizi gibi listenin elemanlarına erişmek
-li[0] #=> 1
-# Son elemanın değerine ulaşmak
-li[-1] #=> 3
-
-# Listede bulunmayan bir index'teki elemana erişirken "IndexError" hatası
-# fırlatılır
-li[4] # IndexError fırlatılır
-
-# slice syntax'ı ile belli aralıktakı değerlere bakabilirsiniz.
-# (Açık ve kapalı aralıklıdır.)
-li[1:3] #=> [2, 4]
-# Başlangıcı ihmal etme
-li[2:] #=> [4, 3]
-# Sonu ihmal etme
-li[:3] #=> [1, 2, 4]
-
-# "del" ile istenilen bir elemanı listeden silmek
-del li[2] # li is now [1, 2, 3]
-
-# Listeleri birbiri ile birleştirebilirsiniz.
-li + other_li #=> [1, 2, 3, 4, 5, 6] - Not: li ve other_li yanlız bırakılır
-
-# extend ile listeleri birleştirmek
-li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
-
-# bir değerin liste içerisinde varlığını "in" ile kontrol etmek
-1 in li #=> True
-
-# "len" ile listenin uzunluğunu bulmak
-len(li) #=> 6
-
-# Tüpler listeler gibidir sadece değişmezler(immutable)
+# Önceden doldurulmuş listeler ile başlayabilirsiniz
+diger_li = [4, 5, 6]
+
+# 'append' ile listenin sonuna ekleme yapabilirsiniz
+li.append(1) # li artık [1] oldu
+li.append(2) # li artık [1, 2] oldu
+li.append(4) # li artık [1, 2, 4] oldu
+li.append(3) # li artık [1, 2, 4, 3] oldu
+# 'pop' ile listenin son elementini kaldırabilirsiniz
+li.pop() # => 3 ve li artık [1, 2, 4]
+# Çıkarttığımız tekrardan ekleyelim
+li.append(3) # li yeniden [1, 2, 4, 3] oldu.
+
+# Dizi gibi listeye erişim sağlayın
+li[0] # => 1
+# Son elemente bakın
+li[-1] # => 3
+
+# Listede olmayan bir elemente erişim sağlamaya çalışmak IndexError hatası oluşturur
+li[4] # IndexError hatası oluşturur
+
+# Bir kısmını almak isterseniz.
+li[1:3] # => [2, 4]
+# Başlangıç belirtmezseniz
+li[2:] # => [4, 3]
+# Sonu belirtmesseniz
+li[:3] # => [1, 2, 4]
+# Her ikişer objeyi seçme
+li[::2] # =>[1, 4]
+# Listeyi tersten almak
+li[::-1] # => [3, 4, 2, 1]
+# Kombinasyonları kullanarak gelişmiş bir şekilde listenin bir kısmını alabilirsiniz
+# li[baslangic:son:adim]
+
+# "del" ile isteğe bağlı, elementleri listeden kaldırabilirsiniz
+del li[2] # li artık [1, 2, 3] oldu
+
+# Listelerde de ekleme yapabilirsiniz
+# Not: değerler üzerinde değişiklik yapılmaz.
+li + diger_li # => [1, 2, 3, 4, 5, 6]
+
+# Listeleri birbirine bağlamak için "extend()" kullanılabilir
+li.extend(diger_li) # li artık [1, 2, 3, 4, 5, 6] oldu
+
+# Listedeki bir elementin olup olmadığı kontrolü "in" ile yapılabilir
+1 in li # => True
+
+# Uzunluğu öğrenmek için "len()" kullanılabilir
+len(li) # => 6
+
+
+# Tüpler listeler gibidir fakat değiştirilemez.
tup = (1, 2, 3)
-tup[0] #=> 1
-tup[0] = 3 # TypeError fırlatılır.
-
-# Litelerde yapılanların hepsini tüplerde de yapılabilir
-len(tup) #=> 3
-tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
-tup[:2] #=> (1, 2)
-2 in tup #=> True
-
-# Tüplerin(veya listelerin) içerisindeki değerleri değişkenelere
-# atanabilir
-a, b, c = (1, 2, 3) # a şu anda 1, b şu anda 2 ve c şu anda 3
-# Eğer parantez kullanmaz iseniz tüpler varsayılan olarak oluşturulur
+tup[0] # => 1
+tup[0] = 3 # TypeError hatası oluşturur
+
+# Diğer liste işlemlerini tüplerde de uygulayabilirsiniz
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# Tüpleri(veya listeleri) değişkenlere açabilirsiniz
+a, b, c = (1, 2, 3) # 'a' artık 1, 'b' artık 2 ve 'c' artık 3
+# Eğer parantez kullanmazsanız varsayılan oalrak tüpler oluşturulur
d, e, f = 4, 5, 6
-# şimdi iki değeri değiş tokuş etmek çok kolaydır.
-e, d = d, e # d şimdi 5 ve e şimdi 4
+# 2 değeri birbirine değiştirmek bu kadar kolay
+e, d = d, e # 'd' artık 5 ve 'e' artık 4
+
+# Sözlükler anahtar kodlarla verileri tutar
+bos_sozl = {}
+# Önceden doldurulmuş sözlük oluşturma
+dolu_sozl = {"bir": 1, "iki": 2, "uc": 3}
-# Sözlükler (Dictionaries) key-value saklanır.
-empty_dict = {}
-# Sözlüklere önceden değer atama örneği
-filled_dict = {"one": 1, "two": 2, "three": 3}
+# Değere bakmak için [] kullanalım
+dolu_sozl["bir"] # => 1
-# Değere ulaşmak için [] kullanılır
-filled_dict["one"] #=> 1
+# Bütün anahtarları almak için "keys()" kullanılabilir.
+# Listelemek için list() kullanacağınız çünkü dönen değerin işlenmesi gerekiyor. Bu konuya daha sonra değineceğiz.
+# Not - Sözlük anahtarlarının sıralaması kesin değildir.
+# Beklediğiniz çıktı sizinkiyle tam uyuşmuyor olabilir.
+list(dolu_sozl.keys()) # => ["uc", "iki", "bir"]
-# Tüm anahtarlara(key) "keys()" metodu ile ulaşılır
-filled_dict.keys() #=> ["three", "two", "one"]
-# Not - Sözlüklerin anahtarlarının sıralı geleceği garanti değildir
-# Sonuçlarınız değer listesini aldığınızda tamamen eşleşmeyebilir
-# Tüm değerleri almak için "values()" kullanabilirsiniz.
-filled_dict.values() #=> [3, 2, 1]
-# Not - Sıralama ile ilgili anahtarlar ile aynı durum geçerlidir.
+# Tüm değerleri almak için "values()" kullanacağız. Dönen değeri biçimlendirmek için de list() kullanmamız gerekiyor
+# Not - Sıralama değişebilir.
+list(dolu_sozl.values()) # => [3, 2, 1]
-# Bir anahtarın sözlükte oluş olmadığını "in" ile kontrol edilebilir
-"one" in filled_dict #=> True
-1 in filled_dict #=> False
-# Olmayan bir anahtar çağrıldığında KeyError fırlatılır.
-filled_dict["four"] # KeyError
+# Bir anahtarın sözlükte olup olmadığını "in" ile kontrol edebilirsiniz
+"bir" in dolu_sozl # => True
+1 in dolu_sozl # => False
-# "get()" metodu KeyError fırlatılmasını önler
-filled_dict.get("one") #=> 1
-filled_dict.get("four") #=> None
-# get() metodu eğer anahtar mevcut değilse varsayılan bir değer atama
-# imknaı sağlar.
-filled_dict.get("one", 4) #=> 1
-filled_dict.get("four", 4) #=> 4
+# Olmayan bir anahtardan değer elde etmek isterseniz KeyError sorunu oluşacaktır.
+dolu_sozl["dort"] # KeyError hatası oluşturur
-# "setdefault()" metodu sözlüğe yeni bir key-value eşleşmesi eklemenin
-# güvenli bir yoludur.
-filled_dict.setdefault("five", 5) #filled_dict["five"] is set to 5
-filled_dict.setdefault("five", 6) #filled_dict["five"] is still 5
+# "get()" metodu ile değeri almaya çalışırsanız KeyError sorunundan kurtulursunuz
+dolu_sozl.get("bir") # => 1
+dolu_sozl.get("dort") # => None
+# "get" metoduna parametre belirterek değerin olmaması durumunda varsayılan bir değer döndürebilirsiniz.
+dolu_sozl.get("bir", 4) # => 1
+dolu_sozl.get("dort", 4) # => 4
+# "setdefault()" metodu sözlükte, belirttiğiniz anahtarın [olmaması] durumunda varsayılan bir değer atayacaktır
+dolu_sozl.setdefault("bes", 5) # dolu_sozl["bes"] artık 5 değerine sahip
+dolu_sozl.setdefault("bes", 6) # dolu_sozl["bes"] değişmedi, hala 5 değerine sahip
-# Sets store ... well sets
-empty_set = set()
-# Bir demek değer ile bir "set" oluşturmak
-some_set = set([1,2,2,3,4]) # some_set is now set([1, 2, 3, 4])
+# Sözlüğe ekleme
+dolu_sozl.update({"dort":4}) #=> {"bir": 1, "iki": 2, "uc": 3, "dort": 4}
+#dolu_sozl["dort"] = 4 #sözlüğe eklemenin bir diğer yolu
-# Python 2.7'den beri {}'ler bir "set" tanımlaman için kullanılabilir
-filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+# Sözlükten anahtar silmek için 'del' kullanılabilir
+del dolu_sozl["bir"] # "bir" anahtarını dolu sözlükten silecektir
-# Bir set'e daha fazla eleman eklemek
-filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
-# "&" işareti ile iki set'in kesişimlerini alınabilir
-other_set = {3, 4, 5, 6}
-filled_set & other_set #=> {3, 4, 5}
+# Setler ... set işte :D
+bos_set = set()
+# Seti bir veri listesi ile de oluşturabilirsiniz. Evet, biraz sözlük gibi duruyor. Üzgünüm.
+bir_set = {1, 1, 2, 2, 3, 4} # bir_set artık {1, 2, 3, 4}
-# | işareti ile
-filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+# Sete yeni setler ekleyebilirsiniz
+dolu_set = bir_set
-# "-" işareti ile iki set'in farkları alınabilir
-{1,2,3,4} - {2,3,5} #=> {1, 4}
+# Sete bir diğer öğe ekleme
+dolu_set.add(5) # dolu_set artık {1, 2, 3, 4, 5} oldu
-# "in" ile değerin set içerisinde olup olmadığını kontrol edebilirsiniz
-2 in filled_set #=> True
-10 in filled_set #=> False
+# Setlerin çakışan kısımlarını almak için '&' kullanabilirsiniz
+diger_set = {3, 4, 5, 6}
+dolu_set & diger_set # => {3, 4, 5}
+
+# '|' ile aynı olan elementleri almayacak şekilde setleri birleştirebilirsiniz
+dolu_set | diger_set # => {1, 2, 3, 4, 5, 6}
+
+# Farklılıkları almak için "-" kullanabilirsiniz
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+
+# Bir değerin olup olmadığının kontrolü için "in" kullanılabilir
+2 in dolu_set # => True
+10 in dolu_set # => False
####################################################
-## 3. Akış Denetimi
+## 3. Kontrol Akışları ve Temel Soyutlandırma
####################################################
-# Bir değişken oluşturmak
-some_var = 5
+# Bir değişken oluşturalım
+bir_degisken = 5
-# Buradaki bir if ifadesi. Girintiler(Intentation) Python'da önemlidir!
-# "some_var is smaller than 10" yazdırılır.
-if some_var > 10:
- print "some_var is totally bigger than 10."
-elif some_var < 10: # elif ifadesi isteğe bağlıdır
- print "some_var is smaller than 10."
-else: # Bu da isteğe bağlıdır.
- print "some_var is indeed 10."
+# Burada bir "if" ifadesi var. Girinti(boşluk,tab) python için önemlidir!
+# çıktı olarak "bir_degisken 10 dan küçük" yazar
+if bir_degisken > 10:
+ print("bir_degisken 10 dan büyük")
+elif bir_degisken < 10: # Bu 'elif' ifadesi zorunlu değildir.
+ print("bir_degisken 10 dan küçük")
+else: # Bu ifade de zorunlu değil.
+ print("bir_degisken değeri 10")
"""
-For döngüleri listeler üzerinde iterasyon yapar
-Ekrana yazdırılan:
- dog is a mammal
- cat is a mammal
- mouse is a mammal
+Döngülerle lsiteleri döngüye alabilirsiniz
+çıktı:
+ köpek bir memeli hayvandır
+ kedi bir memeli hayvandır
+ fare bir memeli hayvandır
"""
-for animal in ["dog", "cat", "mouse"]:
- # Biçimlendirmeleri string'e katmak için % kullanabilirsiniz
- print "%s is a mammal" % animal
-
+for hayvan in ["köpek", "kedi, "fare"]:
+ # format ile kolayca yazıyı biçimlendirelim
+ print("{} bir memeli hayvandır".format(hayvan))
+
"""
-"range(number)" ifadesi sıfırdan verilen sayıya kadar bir sayı listesi döner
-Ekrana yazdırılan:
+"range(sayi)" bir sayı listesi döndür
+0'dan belirttiğiniz sayıyıa kadar
+çıktı:
0
1
2
3
"""
for i in range(4):
- print i
+ print(i)
"""
-While döngüsü koşul sağlanmayana kadar devam eder
-Ekrana yazdırılan:
+'While' döngüleri koşul çalıştıkça işlemleri gerçekleştirir.
+çıktı:
0
1
2
@@ -318,185 +346,295 @@ Ekrana yazdırılan:
"""
x = 0
while x < 4:
- print x
- x += 1 # Shorthand for x = x + 1
-
-# try/except bloğu ile hatalar ayıklanabilir
+ print(x)
+ x += 1 # Uzun hali x = x + 1
-# Python 2.6 ve üstü için çalışacaktır:
+# Hataları kontrol altına almak için try/except bloklarını kullanabilirsiniz
try:
- # "raise" bir hata fırlatmak için kullanılabilir
- raise IndexError("This is an index error")
+ # Bir hata oluşturmak için "raise" kullanabilirsiniz
+ raise IndexError("Bu bir index hatası")
except IndexError as e:
- pass # Pass is just a no-op. Usually you would do recovery here.
+ pass # Önemsiz, devam et.
+except (TypeError, NameError):
+ pass # Çoklu bir şekilde hataları kontrol edebilirsiniz, tabi gerekirse.
+else: # İsteğe bağlı bir kısım. Eğer hiçbir hata kontrol mekanizması desteklemiyorsa bu blok çalışacaktır
+ print("Her şey iyi!") # IndexError, TypeError ve NameError harici bir hatada bu blok çalıştı
+
+# Temel Soyutlandırma, bir objenin işlenmiş halidir.
+# Aşağıdaki örnekte; Obje, range fonksiyonuna temel soyutlandırma gönderdi.
+
+dolu_sozl = {"bir": 1, "iki": 2, "uc": 3}
+temel_soyut = dolu_sozl.keys()
+print(temel_soyut) #=> range(1,10). Bu obje temel soyutlandırma arayüzü ile oluşturuldu
+
+# Temel Soyutlandırılmış objeyi döngüye sokabiliriz.
+for i in temel_soyut:
+ print(i) # Çıktısı: bir, iki, uc
+
+# Fakat, elementin anahtarına değerine.
+temel_soyut[1] # TypeError hatası!
+
+# 'iterable' bir objenin nasıl temel soyutlandırıldığıdır.
+iterator = iter(temel_soyut)
+
+# 'iterator' o obje üzerinde yaptığımız değişiklikleri hatırlayacaktır
+# Bir sonraki objeyi almak için __next__ fonksiyonunu kullanabilirsiniz.
+iterator.__next__() #=> "bir"
+
+# Bir önceki __next__ fonksiyonumuzu hatırlayıp bir sonraki kullanımda bu sefer ondan bir sonraki objeyi döndürecektir
+iterator.__next__() #=> "iki"
+iterator.__next__() #=> "uc"
+
+# Bütün nesneleri aldıktan sonra bir daha __next__ kullanımınızda, StopIterator hatası oluşturacaktır.
+iterator.__next__() # StopIteration hatası
+
+# iterator'deki tüm nesneleri almak için list() kullanabilirsiniz.
+list(dolu_sozl.keys()) #=> Returns ["bir", "iki", "uc"]
####################################################
## 4. Fonksiyonlar
####################################################
+# "def" ile yeni fonksiyonlar oluşturabilirsiniz
+def topla(x, y):
+ print("x = {} ve y = {}".format(x, y))
+ return x + y # Değer döndürmek için 'return' kullanmalısınız
-# Yeni bir fonksiyon oluşturmak için "def" kullanılır
-def add(x, y):
- print "x is %s and y is %s" % (x, y)
- return x + y # Return values with a return statement
+# Fonksiyonu parametleri ile çağırıyoruz
+topla(5, 6) # => çıktı "x = 5 ve y = 6" ve değer olarak 11 döndürür
-# Fonksiyonu parametre ile çağırmak
-add(5, 6) #=> prints out "x is 5 and y is 6" and returns 11
+# Bir diğer fonksiyon çağırma yöntemi de anahtar değerleri ile belirtmek
+topla(y=6, x=5) # Anahtar değeri belirttiğiniz için parametre sıralaması önemsiz.
-# Diğer bir yol fonksiyonları anahtar argümanları ile çağırmak
-add(y=6, x=5) # Anahtar argümanlarının sırası farklı da olabilir
+# Sınırsız sayıda argüman da alabilirsiniz
+def argumanlar(*argumanlar):
+ return argumanlar
-# Değişken sayıda parametresi olan bir fonksiyon tanımlayabilirsiniz
-def varargs(*args):
- return args
+argumanlar(1, 2, 3) # => (1, 2, 3)
-varargs(1, 2, 3) #=> (1,2,3)
+# Parametrelerin anahtar değerlerini almak isterseniz
+def anahtar_par(**anahtarlar):
+ return anahtar
-# Değişken sayıda anahtar argümanlı parametre alan fonksiyonlar da
-# tanımlayabilirsiniz.
-def keyword_args(**kwargs):
- return kwargs
+# Çalıştırdığımızda
+anahtar_par(anah1="deg1", anah2="deg2") # => {"anah1": "deg1", "anah2": "deg2"}
-# Şu şekilde kullanılacaktır
-keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
-# Eğer isterseniz ikisini aynı anda da yapabilirsiniz
-def all_the_args(*args, **kwargs):
- print args
- print kwargs
+# İsterseniz, bu ikisini birden kullanabilirsiniz
+def tum_argumanlar(*argumanlar, **anahtarla):
+ print(argumanlar)
+ print(anahtarla)
"""
-all_the_args(1, 2, a=3, b=4) prints:
+tum_argumanlar(1, 2, a=3, b=4) çıktı:
(1, 2)
{"a": 3, "b": 4}
"""
-# Fonksiyonu çağırırken, args/kwargs'ın tam tersini de yapabilirsiniz!
-# Tüpü yaymak için * ve kwargs'ı yaymak için ** kullanın.
-args = (1, 2, 3, 4)
-kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # foo(1, 2, 3, 4) ile eşit
-all_the_args(**kwargs) # foo(a=3, b=4) ile eşit
-all_the_args(*args, **kwargs) # foo(1, 2, 3, 4, a=3, b=4) ile eşit
-
-# Python first-class fonksiyonlara sahiptir
-def create_adder(x):
- def adder(y):
- return x + y
- return adder
+# Fonksiyonu çağırırken de aynısını kullanabilirsiniz
+argumanlar = (1, 2, 3, 4)
+anahtarla = {"a": 3, "b": 4}
+tum_argumanlar(*argumanlar) # = foo(1, 2, 3, 4)
+tum_argumanlar(**anahtarla) # = foo(a=3, b=4)
+tum_argumanlar(*argumanlar, **anahtarla) # = foo(1, 2, 3, 4, a=3, b=4)
+
+
+# Fonksiyonlarda kullanacağımız bir değişken oluşturalım
+x = 5
+
+def belirleX(sayi):
+ # Fonksiyon içerisindeki x ile global tanımladığımız x aynı değil
+ x = sayi # => 43
+ print (x) # => 43
+
+def globalBelirleX(sayi):
+ global x
+ print (x) # => 5
+ x = sayi # global olan x değişkeni artık 6
+ print (x) # => 6
+
+belirleX(43)
+globalBelirleX(6)
-add_10 = create_adder(10)
-add_10(3) #=> 13
-# Anonymous fonksiyonlar da vardır
-(lambda x: x > 2)(3) #=> True
+# Sınıf fonksiyonları oluşturma
+def toplama_olustur(x):
+ def topla(y):
+ return x + y
+ return topla
+
+ekle_10 = toplama_olustur(10)
+ekle_10(3) # => 13
-# Dahili yüksek seviye fonksiyonlar vardır
-map(add_10, [1,2,3]) #=> [11, 12, 13]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+# Bilinmeyen fonksiyon
+(lambda x: x > 2)(3) # => True
-# Map etme(maps) ve filtreleme(filtres) için liste kullanabiliriz.
-[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]
+# TODO - Fix for iterables
+# Belirli sayıdan yükseğini alma fonksiyonu
+map(ekle_10, [1, 2, 3]) # => [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+# Filtreleme işlemi için liste comprehensions da kullanabiliriz
+[ekle_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
####################################################
## 5. Sınıflar
####################################################
-# We subclass from object to get a class.
-class Human(object):
-
- # Bir sınıf özelliği. Bu sınıfın tüm "instance"larına paylaşılmıştır.
- species = "H. sapiens"
-
- # Basic initializer
- def __init__(self, name):
- # Metoda gelen argümanın değerini sınıfın elemanı olan "name"
- # değişkenine atama
- self.name = name
-
- # Bir instance metodu. Tüm metodlar ilk argüman olarak "self"
- # parametresini alır
- def say(self, msg):
- return "%s: %s" % (self.name, msg)
-
- # Bir sınıf metodu tüm "instance"lar arasında paylaşılır
- # İlk argüman olarak sınıfı çağırarak çağrılırlar
+
+# Sınıf oluşturmak için objeden alt sınıf oluşturacağız.
+class Insan(object):
+
+ # Sınıf değeri. Sınıfın tüm nesneleri tarafından kullanılabilir
+ tur = "H. sapiens"
+
+ # Basit başlatıcı, Sınıf çağrıldığında tetiklenecektir.
+ # Dikkat edin, iki adet alt çizgi(_) bulunmakta. Bunlar
+ # python tarafından tanımlanan isimlerdir.
+ # Kendinize ait bir fonksiyon oluştururken __fonksiyon__ kullanmayınız!
+ def __init__(self, isim):
+ # Parametreyi sınıfın değerine atayalım
+ self.isim = isim
+
+ # Bir metot. Bütün metotlar ilk parametre olarak "self "alır.
+ def soyle(self, mesaj):
+ return "{isim}: {mesaj}".format(isim=self.isim, mesaj=mesaj)
+
+ # Bir sınıf metotu bütün nesnelere paylaştırılır
+ # İlk parametre olarak sınıf alırlar
@classmethod
- def get_species(cls):
- return cls.species
+ def getir_tur(snf):
+ return snf.tur
- # Bir statik metod bir sınıf ya da instance referansı olmadan çağrılır
+ # Bir statik metot, sınıf ve nesnesiz çağrılır
@staticmethod
def grunt():
return "*grunt*"
-# Bir sınıf örneği oluşturmak
-i = Human(name="Ian")
-print i.say("hi") # "Ian: hi" çıktısı verir
+# Sınıfı çağıralım
+i = Insan(isim="Ahmet")
+print(i.soyle("merhaba")) # çıktı "Ahmet: merhaba"
-j = Human("Joel")
-print j.say("hello") # "Joel: hello" çıktısı verir
+j = Insan("Ali")
+print(j.soyle("selam")) # çıktı "Ali: selam"
-# Sınıf metodunu çağıralım
-i.get_species() #=> "H. sapiens"
+# Sınıf metodumuzu çağıraim
+i.getir_tur() # => "H. sapiens"
-# Paylaşılan sınıf özellik değiştirelim.
-Human.species = "H. neanderthalensis"
-i.get_species() #=> "H. neanderthalensis"
-j.get_species() #=> "H. neanderthalensis"
+# Paylaşılan değeri değiştirelim
+Insan.tur = "H. neanderthalensis"
+i.getir_tur() # => "H. neanderthalensis"
+j.getir_tur() # => "H. neanderthalensis"
-# Statik metodu çağırma
-Human.grunt() #=> "*grunt*"
+# Statik metodumuzu çağıralım
+Insan.grunt() # => "*grunt*"
####################################################
-## 6. Modüller
+## 6. Moduller
####################################################
-# Modülleri sayfaya dahil edebilirsiniz
+# Modülleri içe aktarabilirsiniz
import math
-print math.sqrt(16) #=> 4
+print(math.sqrt(16)) # => 4.0
-# Modül içerisinden spesifik bir fonksiyonu getirebilirsiniz
+# Modülden belirli bir fonksiyonları alabilirsiniz
from math import ceil, floor
-print ceil(3.7) #=> 4.0
-print floor(3.7) #=> 3.0
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
-# Modüldeki tüm fonksiyonları dahil edebilirsiniz
-# Uyarı: bu önerilmez
+# Modüldeki tüm fonksiyonları içe aktarabilirsiniz
+# Dikkat: bunu yapmanızı önermem.
from math import *
-# Modülün adını kısaltabilirsiniz
+# Modül isimlerini değiştirebilirsiniz.
+# Not: Modül ismini kısaltmanız çok daha iyi olacaktır
import math as m
-math.sqrt(16) == m.sqrt(16) #=> True
+math.sqrt(16) == m.sqrt(16) # => True
-# Python modülleri sıradan python dosyalarıdır. Kendinize bir modül
-# yazabilirsiniz, ve dahil edebilirsiniz. Modülün adı ile dosya adı
-# aynı olmalıdır.
+# Python modulleri aslında birer python dosyalarıdır.
+# İsterseniz siz de yazabilir ve içe aktarabilirsiniz Modulün
+# ismi ile dosyanın ismi aynı olacaktır.
-# Modüllerde tanımlanmış fonksiyon ve metodları öğrenebilirsiniz.
+# Moduldeki fonksiyon ve değerleri öğrenebilirsiniz.
import math
dir(math)
+####################################################
+## 7. Gelişmiş
+####################################################
+
+# Oluşturucular uzun uzun kod yazmamanızı sağlayacak ve yardımcı olacaktır
+def kare_sayilar(nesne):
+ for i in nesne:
+ yield i + i
+
+# Bir oluşturucu(generator) değerleri anında oluşturur.
+# Bir seferde tüm değerleri oluşturup göndermek yerine teker teker her oluşumdan
+# sonra geri döndürür. Bu demektir ki, kare_sayilar fonksiyonumuzda 15'ten büyük
+# değerler işlenmeyecektir.
+# Not: range() da bir oluşturucu(generator)dur. 1-900000000 arası bir liste yapmaya çalıştığınızda
+# çok fazla vakit alacaktır.
+# Python tarafından belirlenen anahtar kelimelerden kaçınmak için basitçe alt çizgi(_) kullanılabilir.
+range_ = range(1, 900000000)
+# kare_sayilar'dan dönen değer 30'a ulaştığında durduralım
+for i in kare_sayilar(range_):
+ print(i)
+ if i >= 30:
+ break
+
+
+# Dekoratörler
+# Bu örnekte,
+# Eğer lutfen_soyle True ise dönen değer değişecektir.
+from functools import wraps
+
+def yalvar(hedef_fonksiyon):
+ @wraps(hedef_fonksiyon)
+ def metot(*args, **kwargs):
+ msj, lutfen_soyle = hedef_fonksiyon(*args, **kwargs)
+ if lutfen_soyle:
+ return "{} {}".format(msj, "Lütfen! Artık dayanamıyorum :(")
+ return msj
+
+ return metot
+
+
+@yalvar
+def soyle(lutfen_soyle=False):
+ msj = "Bana soda alır mısın?"
+ return msj, lutfen_soyle
+
+
+print(soyle()) # Bana soda alır mısın?
+print(soyle(lutfen_soyle=True)) # Ban soda alır mısın? Lutfen! Artık dayanamıyorum :(
```
-## Daha fazlası için hazır mısınız?
+## Daha Fazlasına Hazır Mısınız?
-### Ücretsiz Dökümanlar
+### Ücretsiz Online
+* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
* [Dive Into Python](http://www.diveintopython.net/)
-* [The Official Docs](http://docs.python.org/2.6/)
+* [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 Module of the Week](http://pymotw.com/2/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+* [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/)
-### Dead Tree
+### Kitaplar
* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+
diff --git a/tr-tr/python3-tr.html.markdown b/tr-tr/python3-tr.html.markdown
deleted file mode 100644
index e53d5568..00000000
--- a/tr-tr/python3-tr.html.markdown
+++ /dev/null
@@ -1,640 +0,0 @@
----
-language: python3
-contributors:
- - ["Louie Dinh", "http://pythonpracticeprojects.com"]
- - ["Steven Basart", "http://github.com/xksteven"]
- - ["Andre Polykanine", "https://github.com/Oire"]
- - ["Andre Polykanine", "https://github.com/Oire"]
-translators:
- - ["Eray AYDIN", "http://erayaydin.me/"]
-lang: tr-tr
-filename: learnpython3-tr.py
----
-
-Python,90ların başlarında Guido Van Rossum tarafından oluşturulmuştur. En popüler olan dillerden biridir. Beni Python'a aşık eden sebep onun syntax beraklığı. Çok basit bir çalıştırılabilir söz koddur.
-
-Not: Bu makale Python 3 içindir. Eğer Python 2.7 öğrenmek istiyorsanız [burayı](http://learnxinyminutes.com/docs/python/) kontrol edebilirsiniz.
-
-```python
-
-# Tek satırlık yorum satırı kare(#) işareti ile başlamaktadır.
-
-""" Çok satırlı olmasını istediğiniz yorumlar
- üç adet tırnak(") işareti ile
- yapılmaktadır
-"""
-
-####################################################
-## 1. Temel Veri Türleri ve Operatörler
-####################################################
-
-# Sayılar
-3 # => 3
-
-# Tahmin edebileceğiniz gibi matematik
-1 + 1 # => 2
-8 - 1 # => 7
-10 * 2 # => 20
-
-# Bölme işlemi varsayılan olarak onluk döndürür
-35 / 5 # => 7.0
-
-# Tam sayı bölmeleri, pozitif ve negatif sayılar için aşağıya yuvarlar
-5 // 3 # => 1
-5.0 // 3.0 # => 1.0 # onluklar için de bu böyledir
--5 // 3 # => -2
--5.0 // 3.0 # => -2.0
-
-# Onluk kullanırsanız, sonuç da onluk olur
-3 * 2.0 # => 6.0
-
-# Kalan operatörü
-7 % 3 # => 1
-
-# Üs (2 üzeri 4)
-2**4 # => 16
-
-# Parantez ile önceliği değiştirebilirsiniz
-(1 + 3) * 2 # => 8
-
-# Boolean(Doğru-Yanlış) değerleri standart
-True
-False
-
-# 'değil' ile terse çevirme
-not True # => False
-not False # => True
-
-# Boolean Operatörleri
-# "and" ve "or" büyük küçük harf duyarlıdır
-True and False #=> False
-False or True #=> True
-
-# Bool operatörleri ile sayı kullanımı
-0 and 2 #=> 0
--5 or 0 #=> -5
-0 == False #=> True
-2 == True #=> False
-1 == True #=> True
-
-# Eşitlik kontrolü ==
-1 == 1 # => True
-2 == 1 # => False
-
-# Eşitsizlik Kontrolü !=
-1 != 1 # => False
-2 != 1 # => True
-
-# Diğer karşılaştırmalar
-1 < 10 # => True
-1 > 10 # => False
-2 <= 2 # => True
-2 >= 2 # => True
-
-# Zincirleme şeklinde karşılaştırma da yapabilirsiniz!
-1 < 2 < 3 # => True
-2 < 3 < 2 # => False
-
-# Yazı(Strings) " veya ' işaretleri ile oluşturulabilir
-"Bu bir yazı."
-'Bu da bir yazı.'
-
-# Yazılar da eklenebilir! Fakat bunu yapmanızı önermem.
-"Merhaba " + "dünya!" # => "Merhaba dünya!"
-
-# Bir yazı(string) karakter listesi gibi işlenebilir
-"Bu bir yazı"[0] # => 'B'
-
-# .format ile yazıyı biçimlendirebilirsiniz, şu şekilde:
-"{} da ayrıca {}".format("yazılar", "işlenebilir")
-
-# Biçimlendirme işleminde aynı argümanı da birden fazla kullanabilirsiniz.
-"{0} çeviktir, {0} hızlıdır, {0} , {1} üzerinden atlayabilir".format("Ahmet", "şeker çubuğu")
-#=> "Ahmet çeviktir, Ahmet hızlıdır, Ahmet , şeker çubuğu üzerinden atlayabilir"
-
-# Argümanın sırasını saymak istemiyorsanız, anahtar kelime kullanabilirsiniz.
-"{isim} yemek olarak {yemek} istiyor".format(isim="Ahmet", yemek="patates") #=> "Ahmet yemek olarak patates istiyor"
-
-# Eğer Python 3 kodunuz ayrıca Python 2.5 ve üstünde çalışmasını istiyorsanız,
-# eski stil formatlamayı kullanabilirsiniz:
-"%s bu %s yolla da %s" % ("yazılar", "eski", "biçimlendirilebilir")
-
-
-# Hiçbir şey(none) da bir objedir
-None # => None
-
-# Bir değerin none ile eşitlik kontrolü için "==" sembolünü kullanmayın
-# Bunun yerine "is" kullanın. Obje türünün eşitliğini kontrol edecektir.
-"vb" is None # => False
-None is None # => True
-
-# None, 0, ve boş yazılar/listeler/sözlükler hepsi False değeri döndürü.
-# Diğer veriler ise True değeri döndürür
-bool(0) # => False
-bool("") # => False
-bool([]) #=> False
-bool({}) #=> False
-
-
-####################################################
-## 2. Değişkenler ve Koleksiyonlar
-####################################################
-
-# Python bir yazdırma fonksiyonuna sahip
-print("Ben Python. Tanıştığıma memnun oldum!")
-
-# Değişkenlere veri atamak için önce değişkeni oluşturmanıza gerek yok.
-# Düzenli bir değişken için hepsi_kucuk_ve_alt_cizgi_ile_ayirin
-bir_degisken = 5
-bir_degisken # => 5
-
-# Önceden tanımlanmamış değişkene erişmek hata oluşturacaktır.
-# Kontrol akışları başlığından hata kontrolünü öğrenebilirsiniz.
-bir_bilinmeyen_degisken # NameError hatası oluşturur
-
-# Listeler ile sıralamaları tutabilirsiniz
-li = []
-# Önceden doldurulmuş listeler ile başlayabilirsiniz
-diger_li = [4, 5, 6]
-
-# 'append' ile listenin sonuna ekleme yapabilirsiniz
-li.append(1) # li artık [1] oldu
-li.append(2) # li artık [1, 2] oldu
-li.append(4) # li artık [1, 2, 4] oldu
-li.append(3) # li artık [1, 2, 4, 3] oldu
-# 'pop' ile listenin son elementini kaldırabilirsiniz
-li.pop() # => 3 ve li artık [1, 2, 4]
-# Çıkarttığımız tekrardan ekleyelim
-li.append(3) # li yeniden [1, 2, 4, 3] oldu.
-
-# Dizi gibi listeye erişim sağlayın
-li[0] # => 1
-# Son elemente bakın
-li[-1] # => 3
-
-# Listede olmayan bir elemente erişim sağlamaya çalışmak IndexError hatası oluşturur
-li[4] # IndexError hatası oluşturur
-
-# Bir kısmını almak isterseniz.
-li[1:3] # => [2, 4]
-# Başlangıç belirtmezseniz
-li[2:] # => [4, 3]
-# Sonu belirtmesseniz
-li[:3] # => [1, 2, 4]
-# Her ikişer objeyi seçme
-li[::2] # =>[1, 4]
-# Listeyi tersten almak
-li[::-1] # => [3, 4, 2, 1]
-# Kombinasyonları kullanarak gelişmiş bir şekilde listenin bir kısmını alabilirsiniz
-# li[baslangic:son:adim]
-
-# "del" ile isteğe bağlı, elementleri listeden kaldırabilirsiniz
-del li[2] # li artık [1, 2, 3] oldu
-
-# Listelerde de ekleme yapabilirsiniz
-# Not: değerler üzerinde değişiklik yapılmaz.
-li + diger_li # => [1, 2, 3, 4, 5, 6]
-
-# Listeleri birbirine bağlamak için "extend()" kullanılabilir
-li.extend(diger_li) # li artık [1, 2, 3, 4, 5, 6] oldu
-
-# Listedeki bir elementin olup olmadığı kontrolü "in" ile yapılabilir
-1 in li # => True
-
-# Uzunluğu öğrenmek için "len()" kullanılabilir
-len(li) # => 6
-
-
-# Tüpler listeler gibidir fakat değiştirilemez.
-tup = (1, 2, 3)
-tup[0] # => 1
-tup[0] = 3 # TypeError hatası oluşturur
-
-# Diğer liste işlemlerini tüplerde de uygulayabilirsiniz
-len(tup) # => 3
-tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
-tup[:2] # => (1, 2)
-2 in tup # => True
-
-# Tüpleri(veya listeleri) değişkenlere açabilirsiniz
-a, b, c = (1, 2, 3) # 'a' artık 1, 'b' artık 2 ve 'c' artık 3
-# Eğer parantez kullanmazsanız varsayılan oalrak tüpler oluşturulur
-d, e, f = 4, 5, 6
-# 2 değeri birbirine değiştirmek bu kadar kolay
-e, d = d, e # 'd' artık 5 ve 'e' artık 4
-
-
-# Sözlükler anahtar kodlarla verileri tutar
-bos_sozl = {}
-# Önceden doldurulmuş sözlük oluşturma
-dolu_sozl = {"bir": 1, "iki": 2, "uc": 3}
-
-# Değere bakmak için [] kullanalım
-dolu_sozl["bir"] # => 1
-
-# Bütün anahtarları almak için "keys()" kullanılabilir.
-# Listelemek için list() kullanacağınız çünkü dönen değerin işlenmesi gerekiyor. Bu konuya daha sonra değineceğiz.
-# Not - Sözlük anahtarlarının sıralaması kesin değildir.
-# Beklediğiniz çıktı sizinkiyle tam uyuşmuyor olabilir.
-list(dolu_sozl.keys()) # => ["uc", "iki", "bir"]
-
-
-# Tüm değerleri almak için "values()" kullanacağız. Dönen değeri biçimlendirmek için de list() kullanmamız gerekiyor
-# Not - Sıralama değişebilir.
-list(dolu_sozl.values()) # => [3, 2, 1]
-
-
-# Bir anahtarın sözlükte olup olmadığını "in" ile kontrol edebilirsiniz
-"bir" in dolu_sozl # => True
-1 in dolu_sozl # => False
-
-# Olmayan bir anahtardan değer elde etmek isterseniz KeyError sorunu oluşacaktır.
-dolu_sozl["dort"] # KeyError hatası oluşturur
-
-# "get()" metodu ile değeri almaya çalışırsanız KeyError sorunundan kurtulursunuz
-dolu_sozl.get("bir") # => 1
-dolu_sozl.get("dort") # => None
-# "get" metoduna parametre belirterek değerin olmaması durumunda varsayılan bir değer döndürebilirsiniz.
-dolu_sozl.get("bir", 4) # => 1
-dolu_sozl.get("dort", 4) # => 4
-
-# "setdefault()" metodu sözlükte, belirttiğiniz anahtarın [olmaması] durumunda varsayılan bir değer atayacaktır
-dolu_sozl.setdefault("bes", 5) # dolu_sozl["bes"] artık 5 değerine sahip
-dolu_sozl.setdefault("bes", 6) # dolu_sozl["bes"] değişmedi, hala 5 değerine sahip
-
-# Sözlüğe ekleme
-dolu_sozl.update({"dort":4}) #=> {"bir": 1, "iki": 2, "uc": 3, "dort": 4}
-#dolu_sozl["dort"] = 4 #sözlüğe eklemenin bir diğer yolu
-
-# Sözlükten anahtar silmek için 'del' kullanılabilir
-del dolu_sozl["bir"] # "bir" anahtarını dolu sözlükten silecektir
-
-
-# Setler ... set işte :D
-bos_set = set()
-# Seti bir veri listesi ile de oluşturabilirsiniz. Evet, biraz sözlük gibi duruyor. Üzgünüm.
-bir_set = {1, 1, 2, 2, 3, 4} # bir_set artık {1, 2, 3, 4}
-
-# Sete yeni setler ekleyebilirsiniz
-dolu_set = bir_set
-
-# Sete bir diğer öğe ekleme
-dolu_set.add(5) # dolu_set artık {1, 2, 3, 4, 5} oldu
-
-# Setlerin çakışan kısımlarını almak için '&' kullanabilirsiniz
-diger_set = {3, 4, 5, 6}
-dolu_set & diger_set # => {3, 4, 5}
-
-# '|' ile aynı olan elementleri almayacak şekilde setleri birleştirebilirsiniz
-dolu_set | diger_set # => {1, 2, 3, 4, 5, 6}
-
-# Farklılıkları almak için "-" kullanabilirsiniz
-{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
-
-# Bir değerin olup olmadığının kontrolü için "in" kullanılabilir
-2 in dolu_set # => True
-10 in dolu_set # => False
-
-
-####################################################
-## 3. Kontrol Akışları ve Temel Soyutlandırma
-####################################################
-
-# Bir değişken oluşturalım
-bir_degisken = 5
-
-# Burada bir "if" ifadesi var. Girinti(boşluk,tab) python için önemlidir!
-# çıktı olarak "bir_degisken 10 dan küçük" yazar
-if bir_degisken > 10:
- print("bir_degisken 10 dan büyük")
-elif bir_degisken < 10: # Bu 'elif' ifadesi zorunlu değildir.
- print("bir_degisken 10 dan küçük")
-else: # Bu ifade de zorunlu değil.
- print("bir_degisken değeri 10")
-
-
-"""
-Döngülerle lsiteleri döngüye alabilirsiniz
-çıktı:
- köpek bir memeli hayvandır
- kedi bir memeli hayvandır
- fare bir memeli hayvandır
-"""
-for hayvan in ["köpek", "kedi, "fare"]:
- # format ile kolayca yazıyı biçimlendirelim
- print("{} bir memeli hayvandır".format(hayvan))
-
-"""
-"range(sayi)" bir sayı listesi döndür
-0'dan belirttiğiniz sayıyıa kadar
-çıktı:
- 0
- 1
- 2
- 3
-"""
-for i in range(4):
- print(i)
-
-"""
-'While' döngüleri koşul çalıştıkça işlemleri gerçekleştirir.
-çıktı:
- 0
- 1
- 2
- 3
-"""
-x = 0
-while x < 4:
- print(x)
- x += 1 # Uzun hali x = x + 1
-
-# Hataları kontrol altına almak için try/except bloklarını kullanabilirsiniz
-try:
- # Bir hata oluşturmak için "raise" kullanabilirsiniz
- raise IndexError("Bu bir index hatası")
-except IndexError as e:
- pass # Önemsiz, devam et.
-except (TypeError, NameError):
- pass # Çoklu bir şekilde hataları kontrol edebilirsiniz, tabi gerekirse.
-else: # İsteğe bağlı bir kısım. Eğer hiçbir hata kontrol mekanizması desteklemiyorsa bu blok çalışacaktır
- print("Her şey iyi!") # IndexError, TypeError ve NameError harici bir hatada bu blok çalıştı
-
-# Temel Soyutlandırma, bir objenin işlenmiş halidir.
-# Aşağıdaki örnekte; Obje, range fonksiyonuna temel soyutlandırma gönderdi.
-
-dolu_sozl = {"bir": 1, "iki": 2, "uc": 3}
-temel_soyut = dolu_sozl.keys()
-print(temel_soyut) #=> range(1,10). Bu obje temel soyutlandırma arayüzü ile oluşturuldu
-
-# Temel Soyutlandırılmış objeyi döngüye sokabiliriz.
-for i in temel_soyut:
- print(i) # Çıktısı: bir, iki, uc
-
-# Fakat, elementin anahtarına değerine.
-temel_soyut[1] # TypeError hatası!
-
-# 'iterable' bir objenin nasıl temel soyutlandırıldığıdır.
-iterator = iter(temel_soyut)
-
-# 'iterator' o obje üzerinde yaptığımız değişiklikleri hatırlayacaktır
-# Bir sonraki objeyi almak için __next__ fonksiyonunu kullanabilirsiniz.
-iterator.__next__() #=> "bir"
-
-# Bir önceki __next__ fonksiyonumuzu hatırlayıp bir sonraki kullanımda bu sefer ondan bir sonraki objeyi döndürecektir
-iterator.__next__() #=> "iki"
-iterator.__next__() #=> "uc"
-
-# Bütün nesneleri aldıktan sonra bir daha __next__ kullanımınızda, StopIterator hatası oluşturacaktır.
-iterator.__next__() # StopIteration hatası
-
-# iterator'deki tüm nesneleri almak için list() kullanabilirsiniz.
-list(dolu_sozl.keys()) #=> Returns ["bir", "iki", "uc"]
-
-
-####################################################
-## 4. Fonksiyonlar
-####################################################
-
-# "def" ile yeni fonksiyonlar oluşturabilirsiniz
-def topla(x, y):
- print("x = {} ve y = {}".format(x, y))
- return x + y # Değer döndürmek için 'return' kullanmalısınız
-
-# Fonksiyonu parametleri ile çağırıyoruz
-topla(5, 6) # => çıktı "x = 5 ve y = 6" ve değer olarak 11 döndürür
-
-# Bir diğer fonksiyon çağırma yöntemi de anahtar değerleri ile belirtmek
-topla(y=6, x=5) # Anahtar değeri belirttiğiniz için parametre sıralaması önemsiz.
-
-# Sınırsız sayıda argüman da alabilirsiniz
-def argumanlar(*argumanlar):
- return argumanlar
-
-argumanlar(1, 2, 3) # => (1, 2, 3)
-
-# Parametrelerin anahtar değerlerini almak isterseniz
-def anahtar_par(**anahtarlar):
- return anahtar
-
-# Çalıştırdığımızda
-anahtar_par(anah1="deg1", anah2="deg2") # => {"anah1": "deg1", "anah2": "deg2"}
-
-
-# İsterseniz, bu ikisini birden kullanabilirsiniz
-def tum_argumanlar(*argumanlar, **anahtarla):
- print(argumanlar)
- print(anahtarla)
-"""
-tum_argumanlar(1, 2, a=3, b=4) çıktı:
- (1, 2)
- {"a": 3, "b": 4}
-"""
-
-# Fonksiyonu çağırırken de aynısını kullanabilirsiniz
-argumanlar = (1, 2, 3, 4)
-anahtarla = {"a": 3, "b": 4}
-tum_argumanlar(*argumanlar) # = foo(1, 2, 3, 4)
-tum_argumanlar(**anahtarla) # = foo(a=3, b=4)
-tum_argumanlar(*argumanlar, **anahtarla) # = foo(1, 2, 3, 4, a=3, b=4)
-
-
-# Fonksiyonlarda kullanacağımız bir değişken oluşturalım
-x = 5
-
-def belirleX(sayi):
- # Fonksiyon içerisindeki x ile global tanımladığımız x aynı değil
- x = sayi # => 43
- print (x) # => 43
-
-def globalBelirleX(sayi):
- global x
- print (x) # => 5
- x = sayi # global olan x değişkeni artık 6
- print (x) # => 6
-
-belirleX(43)
-globalBelirleX(6)
-
-
-# Sınıf fonksiyonları oluşturma
-def toplama_olustur(x):
- def topla(y):
- return x + y
- return topla
-
-ekle_10 = toplama_olustur(10)
-ekle_10(3) # => 13
-
-# Bilinmeyen fonksiyon
-(lambda x: x > 2)(3) # => True
-
-# TODO - Fix for iterables
-# Belirli sayıdan yükseğini alma fonksiyonu
-map(ekle_10, [1, 2, 3]) # => [11, 12, 13]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
-
-# Filtreleme işlemi için liste comprehensions da kullanabiliriz
-[ekle_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
-[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
-
-####################################################
-## 5. Sınıflar
-####################################################
-
-
-# Sınıf oluşturmak için objeden alt sınıf oluşturacağız.
-class Insan(obje):
-
- # Sınıf değeri. Sınıfın tüm nesneleri tarafından kullanılabilir
- tur = "H. sapiens"
-
- # Basit başlatıcı, Sınıf çağrıldığında tetiklenecektir.
- # Dikkat edin, iki adet alt çizgi(_) bulunmakta. Bunlar
- # python tarafından tanımlanan isimlerdir.
- # Kendinize ait bir fonksiyon oluştururken __fonksiyon__ kullanmayınız!
- def __init__(self, isim):
- # Parametreyi sınıfın değerine atayalım
- self.isim = isim
-
- # Bir metot. Bütün metotlar ilk parametre olarak "self "alır.
- def soyle(self, mesaj):
- return "{isim}: {mesaj}".format(isim=self.name, mesaj=mesaj)
-
- # Bir sınıf metotu bütün nesnelere paylaştırılır
- # İlk parametre olarak sınıf alırlar
- @classmethod
- def getir_tur(snf):
- return snf.tur
-
- # Bir statik metot, sınıf ve nesnesiz çağrılır
- @staticmethod
- def grunt():
- return "*grunt*"
-
-
-# Sınıfı çağıralım
-i = Insan(isim="Ahmet")
-print(i.soyle("merhaba")) # çıktı "Ahmet: merhaba"
-
-j = Insan("Ali")
-print(j.soyle("selam")) # çıktı "Ali: selam"
-
-# Sınıf metodumuzu çağıraim
-i.getir_tur() # => "H. sapiens"
-
-# Paylaşılan değeri değiştirelim
-Insan.tur = "H. neanderthalensis"
-i.getir_tur() # => "H. neanderthalensis"
-j.getir_tur() # => "H. neanderthalensis"
-
-# Statik metodumuzu çağıralım
-Insan.grunt() # => "*grunt*"
-
-
-####################################################
-## 6. Moduller
-####################################################
-
-# Modülleri içe aktarabilirsiniz
-import math
-print(math.sqrt(16)) # => 4.0
-
-# Modülden belirli bir fonksiyonları alabilirsiniz
-from math import ceil, floor
-print(ceil(3.7)) # => 4.0
-print(floor(3.7)) # => 3.0
-
-# Modüldeki tüm fonksiyonları içe aktarabilirsiniz
-# Dikkat: bunu yapmanızı önermem.
-from math import *
-
-# Modül isimlerini değiştirebilirsiniz.
-# Not: Modül ismini kısaltmanız çok daha iyi olacaktır
-import math as m
-math.sqrt(16) == m.sqrt(16) # => True
-
-# Python modulleri aslında birer python dosyalarıdır.
-# İsterseniz siz de yazabilir ve içe aktarabilirsiniz Modulün
-# ismi ile dosyanın ismi aynı olacaktır.
-
-# Moduldeki fonksiyon ve değerleri öğrenebilirsiniz.
-import math
-dir(math)
-
-
-####################################################
-## 7. Gelişmiş
-####################################################
-
-# Oluşturucular uzun uzun kod yazmamanızı sağlayacak ve yardımcı olacaktır
-def kare_sayilar(nesne):
- for i in nesne:
- yield i + i
-
-# Bir oluşturucu(generator) değerleri anında oluşturur.
-# Bir seferde tüm değerleri oluşturup göndermek yerine teker teker her oluşumdan
-# sonra geri döndürür. Bu demektir ki, kare_sayilar fonksiyonumuzda 15'ten büyük
-# değerler işlenmeyecektir.
-# Not: range() da bir oluşturucu(generator)dur. 1-900000000 arası bir liste yapmaya çalıştığınızda
-# çok fazla vakit alacaktır.
-# Python tarafından belirlenen anahtar kelimelerden kaçınmak için basitçe alt çizgi(_) kullanılabilir.
-range_ = range(1, 900000000)
-# kare_sayilar'dan dönen değer 30'a ulaştığında durduralım
-for i in kare_sayilar(range_):
- print(i)
- if i >= 30:
- break
-
-
-# Dekoratörler
-# Bu örnekte,
-# Eğer lutfen_soyle True ise dönen değer değişecektir.
-from functools import wraps
-
-
-def yalvar(hedef_fonksiyon):
- @wraps(hedef_fonksiyon)
- def metot(*args, **kwargs):
- msj, lutfen_soyle = hedef_fonksiyon(*args, **kwargs)
- if lutfen_soyle:
- return "{} {}".format(msj, "Lütfen! Artık dayanamıyorum :(")
- return msj
-
- return metot
-
-
-@yalvar
-def soyle(lutfen_soyle=False):
- msj = "Bana soda alır mısın?"
- return msj, lutfen_soyle
-
-
-print(soyle()) # Bana soda alır mısın?
-print(soyle(lutfen_soyle=True)) # Ban soda alır mısın? Lutfen! Artık dayanamıyorum :(
-```
-
-## Daha Fazlasına Hazır Mısınız?
-
-### Ücretsiz Online
-
-* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)
-* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
-* [Dive Into Python](http://www.diveintopython.net/)
-* [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/)
-* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
-* [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/)
-
-### Kitaplar
-
-* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
-* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
-* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
-
diff --git a/tr-tr/pythonlegacy-tr.html.markdown b/tr-tr/pythonlegacy-tr.html.markdown
new file mode 100644
index 00000000..cd757625
--- /dev/null
+++ b/tr-tr/pythonlegacy-tr.html.markdown
@@ -0,0 +1,502 @@
+---
+language: Python 2 (legacy)
+filename: learnpythonlegacy-tr.py
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+translators:
+ - ["Haydar KULEKCI", "http://scanf.info/"]
+lang: tr-tr
+---
+Python Guido Van Rossum tarafından 90'ların başında yaratılmıştır. Şu anda
+varolanlar arasında en iyi dillerden birisidir. Ben (Louie Dinh) Python
+dilinin syntax'ının belirginliğine aşığım. O basit olarak çalıştırılabilir
+pseudocode'dur.
+
+Geri bildirimlerden son derece mutluluk duyarım! Bana [@louiedinh](http://twitter.com/louiedinh)
+adresinden ya da louiedinh [at] [google's email service] adresinden ulaşabilirsiniz.
+
+Çeviri için geri bildirimleri de [@kulekci](http://twitter.com/kulekci)
+adresine yapabilirsiniz.
+
+Not: Bu yazıdaki özellikler Python 2.7 için geçerlidir, ama Python 2.x için de
+uygulanabilir. Python 3 için başka bir zaman tekrar bakınız.
+
+
+```python
+# Tek satır yorum hash işareti ile başlar.
+""" Çoklu satır diziler üç tane çift tırnak
+ arasında yazılır. Ve yorum olarak da
+ kullanılabilir
+"""
+
+
+####################################################
+## 1. İlkel Veri Tipleri ve Operatörler
+####################################################
+
+# Sayılar
+3 #=> 3
+
+# Matematik beklediğiniz gibi
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+
+# Bölünme biraz ilginç. EĞer tam sayılar üzerinde bölünme işlemi yapıyorsanız
+# sonuç otomatik olarak kırpılır.
+5 / 2 #=> 2
+
+# Bölünme işlemini düzenlemek için kayan noktalı sayıları bilmeniz gerekir.
+2.0 # Bu bir kayan noktalı sayı
+11.0 / 4.0 #=> 2.75 ahhh...daha iyi
+
+# İşlem önceliğini parantezler ile sağlayabilirsiniz.
+(1 + 3) * 2 #=> 8
+
+# Boolean değerleri bilindiği gibi
+True
+False
+
+# not ile nagatif(mantıksal) değerini alma
+not True #=> False
+not False #=> True
+
+# Eşitlik ==
+1 == 1 #=> True
+2 == 1 #=> False
+
+# Eşitsizlik !=
+1 != 1 #=> False
+2 != 1 #=> True
+
+# Daha fazla karşılaştırma
+1 < 10 #=> True
+1 > 10 #=> False
+2 <= 2 #=> True
+2 >= 2 #=> True
+
+# Karşılaştırma zincirleme yapılabilir!
+1 < 2 < 3 #=> True
+2 < 3 < 2 #=> False
+
+# Karakter dizisi " veya ' ile oluşturulabilir
+"This is a string."
+'This is also a string.'
+
+# Karakter dizileri birbirleri ile eklenebilir
+"Hello " + "world!" #=> "Hello world!"
+
+# A string can be treated like a list of characters
+# Bir string'e karakter listesi gibi davranabilirsiniz.
+"This is a string"[0] #=> 'T'
+
+# % karakter dizisini(string) formatlamak için kullanılır, bunun gibi:
+"%s can be %s" % ("strings", "interpolated")
+
+# String'leri formatlamanın yeni bir yöntem ise format metodudur.
+# Bu metod tercih edilen yöntemdir.
+"{0} can be {1}".format("strings", "formatted")
+# Eğer saymak istemiyorsanız anahtar kelime kullanabilirsiniz.
+"{name} wants to eat {food}".format(name="Bob", food="lasagna")
+
+# None bir objedir
+None #=> None
+
+# "==" eşitliğini non objesi ile karşılaştırmak için kullanmayın.
+# Onun yerine "is" kullanın.
+"etc" is None #=> False
+None is None #=> True
+
+# 'is' operatörü obje kimliği için test etmektedir. Bu ilkel değerler
+# için kullanışlı değildir, ama objeleri karşılaştırmak için kullanışlıdır.
+
+# None, 0 ve boş string/list'ler False olarak değerlendirilir.
+# Tüm eşitlikler True döner
+0 == False #=> True
+"" == False #=> True
+
+
+####################################################
+## 2. Değişkenler ve Kolleksiyonlar
+####################################################
+
+# Ekrana yazdırma oldukça kolaydır.
+print "I'm Python. Nice to meet you!"
+
+
+# Değişkenlere bir değer atamadan önce tanımlamaya gerek yoktur.
+some_var = 5 # Değişken isimlerinde gelenek küçük karakter ve alt çizgi
+ # kullanmaktır.
+some_var #=> 5
+
+# Daha önceden tanımlanmamış ya da assign edilmemeiş bir değişkene erişmeye
+# çalıştığınızda bir hata fırlatılacaktır. Hata ayıklama hakkında daha fazla
+# bilgi için kontrol akışı kısmına göz atınız.
+some_other_var # isim hatası fırlatılır
+
+# isterseniz "if"i bir ifade gibi kullanabilirsiniz.
+"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+
+# Listeler
+li = []
+# Önceden değerleri tanımlanmış listeler
+other_li = [4, 5, 6]
+
+# Bir listenin sonuna birşeyler eklemek
+li.append(1) #li şu anda [1]
+li.append(2) #li şu anda [1, 2]
+li.append(4) #li şu anda [1, 2, 4]
+li.append(3) #li şu anda [1, 2, 4, 3]
+# pop ile sondan birşeyler silmek
+li.pop() #=> 3 and li is now [1, 2, 4]
+# Tekrar sonuna eklemek
+li.append(3) # li is now [1, 2, 4, 3] again.
+
+# Dizi gibi listenin elemanlarına erişmek
+li[0] #=> 1
+# Son elemanın değerine ulaşmak
+li[-1] #=> 3
+
+# Listede bulunmayan bir index'teki elemana erişirken "IndexError" hatası
+# fırlatılır
+li[4] # IndexError fırlatılır
+
+# slice syntax'ı ile belli aralıktakı değerlere bakabilirsiniz.
+# (Açık ve kapalı aralıklıdır.)
+li[1:3] #=> [2, 4]
+# Başlangıcı ihmal etme
+li[2:] #=> [4, 3]
+# Sonu ihmal etme
+li[:3] #=> [1, 2, 4]
+
+# "del" ile istenilen bir elemanı listeden silmek
+del li[2] # li is now [1, 2, 3]
+
+# Listeleri birbiri ile birleştirebilirsiniz.
+li + other_li #=> [1, 2, 3, 4, 5, 6] - Not: li ve other_li yanlız bırakılır
+
+# extend ile listeleri birleştirmek
+li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
+
+# bir değerin liste içerisinde varlığını "in" ile kontrol etmek
+1 in li #=> True
+
+# "len" ile listenin uzunluğunu bulmak
+len(li) #=> 6
+
+# Tüpler listeler gibidir sadece değişmezler(immutable)
+tup = (1, 2, 3)
+tup[0] #=> 1
+tup[0] = 3 # TypeError fırlatılır.
+
+# Litelerde yapılanların hepsini tüplerde de yapılabilir
+len(tup) #=> 3
+tup + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6)
+tup[:2] #=> (1, 2)
+2 in tup #=> True
+
+# Tüplerin(veya listelerin) içerisindeki değerleri değişkenelere
+# atanabilir
+a, b, c = (1, 2, 3) # a şu anda 1, b şu anda 2 ve c şu anda 3
+# Eğer parantez kullanmaz iseniz tüpler varsayılan olarak oluşturulur
+d, e, f = 4, 5, 6
+# şimdi iki değeri değiş tokuş etmek çok kolaydır.
+e, d = d, e # d şimdi 5 ve e şimdi 4
+
+
+# Sözlükler (Dictionaries) key-value saklanır.
+empty_dict = {}
+# Sözlüklere önceden değer atama örneği
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Değere ulaşmak için [] kullanılır
+filled_dict["one"] #=> 1
+
+# Tüm anahtarlara(key) "keys()" metodu ile ulaşılır
+filled_dict.keys() #=> ["three", "two", "one"]
+# Not - Sözlüklerin anahtarlarının sıralı geleceği garanti değildir
+# Sonuçlarınız değer listesini aldığınızda tamamen eşleşmeyebilir
+
+# Tüm değerleri almak için "values()" kullanabilirsiniz.
+filled_dict.values() #=> [3, 2, 1]
+# Not - Sıralama ile ilgili anahtarlar ile aynı durum geçerlidir.
+
+# Bir anahtarın sözlükte oluş olmadığını "in" ile kontrol edilebilir
+"one" in filled_dict #=> True
+1 in filled_dict #=> False
+
+# Olmayan bir anahtar çağrıldığında KeyError fırlatılır.
+filled_dict["four"] # KeyError
+
+# "get()" metodu KeyError fırlatılmasını önler
+filled_dict.get("one") #=> 1
+filled_dict.get("four") #=> None
+# get() metodu eğer anahtar mevcut değilse varsayılan bir değer atama
+# imknaı sağlar.
+filled_dict.get("one", 4) #=> 1
+filled_dict.get("four", 4) #=> 4
+
+# "setdefault()" metodu sözlüğe yeni bir key-value eşleşmesi eklemenin
+# güvenli bir yoludur.
+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
+empty_set = set()
+# Bir demek değer ile bir "set" oluşturmak
+some_set = set([1,2,2,3,4]) # some_set is now set([1, 2, 3, 4])
+
+# Python 2.7'den beri {}'ler bir "set" tanımlaman için kullanılabilir
+filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+
+# Bir set'e daha fazla eleman eklemek
+filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
+
+# "&" işareti ile iki set'in kesişimlerini alınabilir
+other_set = {3, 4, 5, 6}
+filled_set & other_set #=> {3, 4, 5}
+
+# | işareti ile
+filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
+
+# "-" işareti ile iki set'in farkları alınabilir
+{1,2,3,4} - {2,3,5} #=> {1, 4}
+
+# "in" ile değerin set içerisinde olup olmadığını kontrol edebilirsiniz
+2 in filled_set #=> True
+10 in filled_set #=> False
+
+
+####################################################
+## 3. Akış Denetimi
+####################################################
+
+# Bir değişken oluşturmak
+some_var = 5
+
+# Buradaki bir if ifadesi. Girintiler(Intentation) Python'da önemlidir!
+# "some_var is smaller than 10" yazdırılır.
+if some_var > 10:
+ print "some_var is totally bigger than 10."
+elif some_var < 10: # elif ifadesi isteğe bağlıdır
+ print "some_var is smaller than 10."
+else: # Bu da isteğe bağlıdır.
+ print "some_var is indeed 10."
+
+
+"""
+For döngüleri listeler üzerinde iterasyon yapar
+Ekrana yazdırılan:
+ dog is a mammal
+ cat is a mammal
+ mouse is a mammal
+"""
+for animal in ["dog", "cat", "mouse"]:
+ # Biçimlendirmeleri string'e katmak için % kullanabilirsiniz
+ print "%s is a mammal" % animal
+
+"""
+"range(number)" ifadesi sıfırdan verilen sayıya kadar bir sayı listesi döner
+Ekrana yazdırılan:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+While döngüsü koşul sağlanmayana kadar devam eder
+Ekrana yazdırılan:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # Shorthand for x = x + 1
+
+# try/except bloğu ile hatalar ayıklanabilir
+
+# Python 2.6 ve üstü için çalışacaktır:
+try:
+ # "raise" bir hata fırlatmak için kullanılabilir
+ raise IndexError("This is an index error")
+except IndexError as e:
+ pass # Pass is just a no-op. Usually you would do recovery here.
+
+
+####################################################
+## 4. Fonksiyonlar
+####################################################
+
+
+# Yeni bir fonksiyon oluşturmak için "def" kullanılır
+def add(x, y):
+ print "x is %s and y is %s" % (x, y)
+ return x + y # Return values with a return statement
+
+# Fonksiyonu parametre ile çağırmak
+add(5, 6) #=> prints out "x is 5 and y is 6" and returns 11
+
+# Diğer bir yol fonksiyonları anahtar argümanları ile çağırmak
+add(y=6, x=5) # Anahtar argümanlarının sırası farklı da olabilir
+
+# Değişken sayıda parametresi olan bir fonksiyon tanımlayabilirsiniz
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) #=> (1,2,3)
+
+# Değişken sayıda anahtar argümanlı parametre alan fonksiyonlar da
+# tanımlayabilirsiniz.
+def keyword_args(**kwargs):
+ return kwargs
+
+# Şu şekilde kullanılacaktır
+keyword_args(big="foot", loch="ness") #=> {"big": "foot", "loch": "ness"}
+
+# Eğer isterseniz ikisini aynı anda da yapabilirsiniz
+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}
+"""
+
+# Fonksiyonu çağırırken, args/kwargs'ın tam tersini de yapabilirsiniz!
+# Tüpü yaymak için * ve kwargs'ı yaymak için ** kullanın.
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # foo(1, 2, 3, 4) ile eşit
+all_the_args(**kwargs) # foo(a=3, b=4) ile eşit
+all_the_args(*args, **kwargs) # foo(1, 2, 3, 4, a=3, b=4) ile eşit
+
+# Python first-class fonksiyonlara sahiptir
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) #=> 13
+
+# Anonymous fonksiyonlar da vardır
+(lambda x: x > 2)(3) #=> True
+
+# Dahili yüksek seviye fonksiyonlar vardır
+map(add_10, [1,2,3]) #=> [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7]
+
+# Map etme(maps) ve filtreleme(filtres) için liste kullanabiliriz.
+[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7]
+
+
+####################################################
+## 5. Sınıflar
+####################################################
+
+# We subclass from object to get a class.
+class Human(object):
+
+ # Bir sınıf özelliği. Bu sınıfın tüm "instance"larına paylaşılmıştır.
+ species = "H. sapiens"
+
+ # Basic initializer
+ def __init__(self, name):
+ # Metoda gelen argümanın değerini sınıfın elemanı olan "name"
+ # değişkenine atama
+ self.name = name
+
+ # Bir instance metodu. Tüm metodlar ilk argüman olarak "self"
+ # parametresini alır
+ def say(self, msg):
+ return "%s: %s" % (self.name, msg)
+
+ # Bir sınıf metodu tüm "instance"lar arasında paylaşılır
+ # İlk argüman olarak sınıfı çağırarak çağrılırlar
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Bir statik metod bir sınıf ya da instance referansı olmadan çağrılır
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+
+# Bir sınıf örneği oluşturmak
+i = Human(name="Ian")
+print i.say("hi") # "Ian: hi" çıktısı verir
+
+j = Human("Joel")
+print j.say("hello") # "Joel: hello" çıktısı verir
+
+# Sınıf metodunu çağıralım
+i.get_species() #=> "H. sapiens"
+
+# Paylaşılan sınıf özellik değiştirelim.
+Human.species = "H. neanderthalensis"
+i.get_species() #=> "H. neanderthalensis"
+j.get_species() #=> "H. neanderthalensis"
+
+# Statik metodu çağırma
+Human.grunt() #=> "*grunt*"
+
+
+####################################################
+## 6. Modüller
+####################################################
+
+# Modülleri sayfaya dahil edebilirsiniz
+import math
+print math.sqrt(16) #=> 4.0
+
+# Modül içerisinden spesifik bir fonksiyonu getirebilirsiniz
+from math import ceil, floor
+print ceil(3.7) #=> 4.0
+print floor(3.7) #=> 3.0
+
+# Modüldeki tüm fonksiyonları dahil edebilirsiniz
+# Uyarı: bu önerilmez
+from math import *
+
+# Modülün adını kısaltabilirsiniz
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
+
+# Python modülleri sıradan python dosyalarıdır. Kendinize bir modül
+# yazabilirsiniz, ve dahil edebilirsiniz. Modülün adı ile dosya adı
+# aynı olmalıdır.
+
+# Modüllerde tanımlanmış fonksiyon ve metodları öğrenebilirsiniz.
+import math
+dir(math)
+
+
+
+```
+
+## Daha fazlası için hazır mısınız?
+
+### Ücretsiz Dökümanlar
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+
+### Dead Tree
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
diff --git a/tr-tr/ruby-tr.html.markdown b/tr-tr/ruby-tr.html.markdown
new file mode 100644
index 00000000..7bc21c83
--- /dev/null
+++ b/tr-tr/ruby-tr.html.markdown
@@ -0,0 +1,1598 @@
+---
+name: ruby
+language: ruby
+filename: learnruby-tr.rb
+contributors:
+ - ["Seçkin KÜKRER", "https://github.com/LeaveNhA"]
+lang: tr-tr
+---
+
+# Dile nazik bir giriş.
+
+## Ruby Nedir ?
+
+Ruby, doğrudan bir Google aramasıyla aklınızdakini bulmanız zor olabilir. İngilizce bu kelime, `Ruby` (IPA: ˈruːbi) "kırmızı taş" anlamına gelen Fransızca kökenli bir kelime olan `rubi`'den gelmektedir.
+
+Yaratıcısı tarafından, yine esinlenilen bir dil olarak ortaya çıkan `Ruby`, Perl, Smalltalk, Eiffel, Ada, Lisp programlama dillerinin en iyi özelliklerini almıştır. ! [İmperativ]() programlama mentalitesi üzerine kurmayı seçtiği bu teknoloji, günümüzde sektöründe öncü.
+
+
+## Tarihçe
+
+Ruby 1995’te halka duyurulduğundan beri, dünya çapında programcıların dikkatini çekmeye başlamıştır. 2006 Ruby’nin altın yılı olmuştur. Dünyanın en büyük şehirlerinde aktif kullanıcı grupları ve Ruby ile ilgili konferanslar gerçekleştirilmiştir.
+
+Daha sonraları `Ruby`, dünya çapında programlama dillerinin büyümesini ve popülaritesini ölçen dizinlerin (TIOBE dizini gibi) çoğunda ilk 10 içinde yer almıştır. Büyümenin çoğu, Ruby ile yazılmış yazılımların popülaritesiyle ilgilidir, özellikle de Ruby on Rails web çatısıyla.
+
+! [kaynak]()
+
+## Sektördeki Konumu ve Geleceği ?
+
+Çoğu uzmana göre, şu anda sadece `Rails` teknolojisi için bir betik dili olarak sıkışmış durumda.
+
+Bazıları ise, dilin kendi geleceğini, 2020 içinde yayınlanması planlanan `Ruby 3` ile sağlamlaştıracağını ve yeni imkanlar ve sektörek kullanım ve tercihler ile popüleritesinin artacağını düşünüyor.
+
+## Her Şey Nesne
+
+Matz'ın incelemiş olduğu diller sonucunda, teknik olarak en iyi sözdizimin kaynağını “Perl’den daha güçlü ama Python’dan daha nesneye yönelik bir betik dili” olarak tanımlamış.
+
+Her şeyin Nesne olarak görüldüğü bir programlama teknolojisi, bütünlük kavramı açısından herkese kucak açan bir pürüzsüzlük sunuyor. `Ruby`'nin neden tartışmasız, saf bir Nesne yönelimli bir programlama dili olduğuna dair örnekleri aşağıda vereceğim.
+
+## Diğer Gerçeklemeler
+
+- [JRuby](http://jruby.org/), JVM’in (Java Virtual Machine) üstünde çalışan Ruby’dir, JVM’in eniyileyen JIT derleyicisi, çöp toplayıcısı, eşzamanlı thread’leri, araç ekosistemi, ve muazzam sayıdaki kütüphanelerinden faydalanır.
+- [Rubinius](http://rubini.us/), ‘Ruby’da yazılmış Ruby’dir’. LLVM’in üstüne inşa edilmiştir ve ayrıca diğer dillerin üstüne inşa edebilecekleri şık bir sanal makine de sunar.
+- [TruffleRuby](https://github.com/oracle/truffleruby), GraalVM’in üstünde çalışan yüksek performanslı bir Ruby gerçeklemesidir.
+- [IronRuby](http://www.ironruby.net/), “.NET Web Çatısı’yla sıkı sıkıya bağlı” bir gerçeklemedir.
+
+Diğer gerçeklemeler için, lütfen ileri okumaya danışınız.
+
+```ruby
+# Bu karakter ile başlayan satırlar, yorum satırı olarak değerlendirilir.
+# Diğer yorum satırı tanımlamaları için tanımlamalar ve ifadeler kısmına danışın.
+
+## Örnek yapısı; bu örnek dosyadaki her Ruby ifadesi, Ruby yorumlayıcısı
+## tarafından yorumlanarak sonucu `=>` ifadesinin sağına yazılır.
+## örnek ifade #=> örnek sonuç
+## formatındadır.
+## Bazen satır aşımını önlemek için
+## örnek ifade
+## #=> örnek sonuç
+## şeklinde yer verilecektir.
+
+# --------------------------------
+# Veriler ve Temsilleri
+# --------------------------------
+
+## --
+## Sayılar:
+## --
+### Ruby, tamsayı veri tipini destekler. Sayısal değerlerin sisteminizdeki temsili
+### bu veri yapısıdır.
+
+# Tam sayı örneği.
+1453 #=> 1453
+
+## Okunabilirlik için, binlik ya da ondalık kısmını `_` ile
+## ayırmak mümkündür ve bu karakter tümüyle görmezden gelinir.
+3_14 #=> 314
+
+## Negatif sayılar `-` ile başlıyor.
+-3750 #=> -3750
+
+## Oktal sayılar
+03603 #=> 1923
+
+## Onaltılık sayılar
+0x23B #=> 571
+
+## İkilik sayılar
+0b11110000011 #=> 1923
+
+## Büyük sayılar temsili
+12345678901234567890 #=> 12345678901234567890
+
+## Kayan noktalı sayılar
+
+## Bir kayan-noktalı/Ondalıklı sayı.
+3.14 #=> 3.14
+
+## Bilimsel notasyon
+1.0e3 #=> 1000.0
+
+## Bir ipucu,
+## üsten önce işaret!
+3e+9 #=> 3000000000.0
+
+## --
+# Mantıksal Değerler
+## --
+
+## Mantıksal doğru ifadesi.
+true #=> true
+
+## Mantıksal yanlış ifadesi.
+false #=> false
+
+## --
+# Metinler
+## --
+
+## Metin sabitleri
+'Bu, bir metin ifadesi.'
+
+## Kaçışlar için
+'Kaçışlar için "\\"' #=> "Kaçışlar için \"\\\""
+
+## Alternatif ise çift tırnaklı ifadeler.
+"Bu da bir metin ifadesi."
+
+## Kaçışlarda farkı ise,
+"Kaçılar için '\\'" #=> "Kaçılar için '\\'"
+## bazı kaçış notasyonlarına gerek kalmaması.
+
+## Bazı notasyon karakterleri
+
+### Yeni Satır (New Line 0x0a)
+"\n" #=> "\n"
+
+### Boşluk (Space 0x20)
+"\s" #=> "\s"
+
+## --
+# Karakterler
+## --
+
+## Basitçe önlerine soru işareti getirilmiş
+## tek karakter sabitleridir.
+?a #=> "a"
+
+
+## --
+# Semboller
+## --
+## Ruby'de semboller, temsilleri bakımından
+## Clojure'daki semboller ile benzerlerdir.
+:sembol #=> :sembol
+
+## Kendileri, birinci sınıf değerdir.
+:türk.class #=> Symbol
+## Ve aynı zamanda Unicode desteği vardır. (1.9 sürümünden beri)
+
+
+## --
+# Diziler
+## --
+## Basitçe, Ruby dizileri birilerinden virgül ile ayrılmış,
+## değer veya değer sahibi referansların köşeli parantezler
+## ile çevrelenmesi ile oluşturulur. ([])
+[1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
+
+## Metinler için de durum aynı.
+["Mustafa", "Kemal", "ATATÜRK"] #=> ["Mustafa", "Kemal", "ATATÜRK"]
+
+## Aynı zamanda, Ruby dizileri tip bağımsız nesne ardışıklarıdır.
+[1881, "Mustafa", "Kemal", "ATATÜRK", 1923, "∞"]
+## Aynı zamanda Unicode destekler (1.9 sürümünden beri)
+
+## --
+# Eşlemeler
+## --
+## Ruby eşlemeleri, süslü parantezler içinde virgül ile ayrılan,
+## anahtar ve değer ikililieridir.
+
+## Bir tane de olabilir,
+{"izmir" => "kızları"} #=> {"izmir" => "kızları"}
+
+## Ya da, birden fazla...
+{"izmir" => "kızları", "paris" => "sokakları"} #=> {"izmir" => "kızları", "paris" => "sokakları"}
+
+## Aslında her değeri anahtar veya değer olarak
+## yerleştirmek mümkün.
+
+## Sembolleri,
+{:zafer => "30 Ağustos!"} #=> {:zafer=>"30 Ağustos!"}
+
+## Rakamları bile.
+{28101923 => "Efendiler, yarın Cumhuriyeti'i ilân edeceğiz!"}
+#=> {28101923=>"Efendiler, yarın Cumhuriyeti'i ilân edeceğiz!"}
+
+## Semboller için ufak bir sözdizimsel şekerleme mevcut ki,
+{istanbul: "beyefendi"} #=> {:istanbul=>"beyefendi"}
+## Bu kullanıma göre, sembol anahtarlar ile değerler arasına
+## `=>` yerine basitçe sembolün başına gelecek `:` sembolü
+## getiriliyor.
+
+
+## --
+# Aralıklar
+## --
+## Ruby aralıkları temeliyle başlangıç ve bitiş
+## değerleri arasındaki aralığın veriye dönüştürülmesi
+## için bir dil olanağıdır.
+
+## (başlangıç..bitiş) notasyonu kullanılabilir.
+(0..10) #=> 0..10
+## REPL'ın bize verdiği ifade sizi yanıltmasın, bu bir aralıktır.
+## Meraklılarıyla, dökümanın devamında içindeki değerleri
+## gezeceğiz.
+
+## Range.new notasyonu ile de ilklenebilirler.
+Range.new(0, 10) #=> 0..10
+
+## --
+# Düzenli İfadeler
+## --
+## İki / operatörünün ortasına tanımlanırlar.
+//.class #=> Regexp
+
+## Örnek bir düzenli ifade, a harfi için.
+/[a]/ #=> /[a]/
+
+# --------------------------------
+# Değelerin Manipüle edilmesi
+# --------------------------------
+
+## --
+## Rakamlar
+## --
+
+## Aritmatik, bildiğimiz şekilde.
+## !! infix notasyon
+
+235 + 1218 #=> 1453
+123 - 35 #=> 88
+2 * 2 #=> 4
+1 / 1 #=> 1
+
+## Bit tabanlı işlemler.
+2 & 5 #=> 0
+3 | 9 #=> 11
+2 ^ 5 #=> 7
+## Aslında C tipi ailesi dillerdeki gibi. Sezgisel bir yaklaşımla, hayatta kalınabilir.
+## Ama yine de dökümantasyona başvurulmasını tavsiye ederim.
+
+
+## --
+## Mantıksal
+## --
+
+## ! operatörü teklidir, ve aldığı değerin mantıksal tersini alır.
+!true #=> false
+!false #=> true
+
+
+## --
+## Metinler
+## --
+
+### Boş mu ?
+"".empty? #=> true
+
+### Bir bölümünü alalım.
+"Ölürüm TÜRKİYEM!".slice(7, 7) #=> "Türkiye"
+## Bir başka şekilde, indis notasyonu ile,
+"Ölürüm Türkiye'm!"[7, 7] #=> "Türkiye"
+
+## Küçük harfe dönüştürelim
+"LAY-LAY-LOM sana göre sevmeler...".downcase
+#=> "lay-lay-lom sana göre sevmeler..."
+
+## Büyük harfa dönüştürelim
+"beşiktaş".upcase #=> "BEŞIKTAŞ"
+
+## Karakterlerine ayıralım
+"BEŞİKTAŞ".chars #=> ["B", "E", "Ş", "İ", "K", "T", "A", "Ş"]
+
+## Çevrelemek için
+"Ahmet Mete IŞIKARA".center(30)
+#=> " Ahmet Mete IŞIKARA "
+
+## İçerik kontrolü için include metodu
+"aşk".include?(?a) #=> true
+## argümanı metin tipinde de verebilirdik, ama
+## yukarıdaki temsillerde gördüğümüz gibi,
+## yorumlayıcı, karakter sabitini metin olarak işliyor zaten.
+
+## Konumunu alalım.
+"Dayı".index("a") #=> 1
+## Elbette, tasarımında sağlıklı kararlar alınmış her
+## dil gibi, Ruby'de 0'dan saymaya başlıyor.
+
+## Metin yerleştirme yapalım
+"Ali Baba'nın x çiftliği var.".sub("x", "bir")
+#=> "Ali Baba'nın bir çiftliği var."
+
+## Birden fazla eşleşme için, değiştirme yapalım
+"Dal sarkar x kalkar, x kalkar dal sarkar.".gsub("x", "kartal")
+#=> "Dal sarkar kartal kalkar, kartal kalkar dal sarkar."
+
+## Düzenli ifadeler ile, cümledeki sesli harfleri değiştirelim.
+"Bir berber bir bere...".gsub(/[ie]/, "*")
+#=> "B*r b*rb*r b*r b*r*..."
+
+## Diğer işlevler için ileri okumadaki kaynağa başvurunuz.
+
+
+## --
+## Eşlemeler
+## --
+
+## basit bir eşleme ile başlayalım.
+{:boy => 1.74} #=> {:boy => 1.74}
+
+## Belirli bir anahtar, eşlememizde barınıyor mu diye
+## kontrol ediyoruz.
+{:boy => 1.74}.has_key? :boy
+#=> true
+## Parantezlerin yokluğu sizi yanıltmasın,
+## bu bir fonksiyon çağırısıdır.
+
+## Eşlemeden veri çekiyoruz
+{:boy => 1.74}.fetch :boy
+#=> 1.74
+
+## Eşlemelere veri ekliyoruz
+{:boy => 1.74}.merge!(kilo: 74)
+#=> {:boy=>1.74, :kilo=>74}
+
+## Anahtarlarımıza bakalım
+{:boy=>1.74, :kilo=>74}.keys
+#=> [:boy, :kilo]
+
+## Değerlerimize bakalım
+{:boy=>1.74, :kilo=>74}.values
+#=> [1.74, 74]
+
+## Dizi olarak almak istersek
+{:boy=>1.74, :kilo=>74}.to_a
+#=> [[:boy, 1.74], [:kilo, 74]]
+## Endişelenmeyin, dönüşümler için koca bir bölüm
+## ayırdım.
+
+
+## --
+## Diziler
+## --
+
+## Örnek bir dizi ile başlayalım.
+["Mustafa", "Kemal", "ATATÜRK"]
+#=> ["Mustafa", "Kemal", "ATATÜRK"]
+
+## İlk değeri alıyoruz
+["Mustafa", "Kemal", "ATATÜRK"].first
+#=> "Mustafa"
+
+## Son Değeri,
+["Mustafa", "Kemal", "ATATÜRK"].last
+#=> "ATATÜRK"
+
+## Indis araması için `fetch` metodu.
+["Mustafa", "Kemal", "ATATÜRK"].fetch 1
+#=> "Kemal"
+
+## Var olamyan bir indis ararsak hata alıyoruz.
+
+## Fakat seçimli ikinci argüman bize indisin
+## bulunamaması halinde döndürülecek değeri
+## belirleme imkanı veriyor.
+["Mustafa", "Kemal", "ATATÜRK"].fetch 20101927, "Nutuk"
+#=> "Nutuk"
+
+## Birden fazla değer almak için, slice metodunu
+## kullanabiliriz
+["Fatih", "Sultan", "Mehmet"].slice 1..2
+#=> ["Sultan", "Mehmet"]
+
+## Ya da, indis notasyonu da kullanılabilir.
+["Fatih", "Sultan", "Mehmet"][1..2]
+#=> ["Sultan", "Mehmet"]
+
+## Baştan n tane eleman almak için take metodunu kullanıyoruz
+["Fatih", "Sultan", "Mehmet"].take 2
+#=> ["Fatih", "Sultan"]
+
+## Rastgele bir dizi elemanı elde etmek için sample metodunu
+## kullanıyoruz
+["Fatih", "Sultan", "Mehmet"].sample
+#=> "Fatih"
+
+## `sample` metodu seçimli bir argüman kabul eder.
+## bu argüman rastgele istenen eleman sayısını temsil eder
+["Fatih", "Sultan", "Mehmet"].sample 2
+#=> ["Fatih", "Sultan"]
+
+## Aradığınız eleman, dizide var mı kontrolü için
+## include? metodu kullanılıyor
+["Fatih", "Sultan", "Mehmet"].include? "Fatih"
+#=> true
+
+## Dizinizdeki elemanları koşul dahilinde seçimlemek için
+## select metodunu kullanıyoruz
+["Fatih", "Sultan", "Mehmet"].select {|s| s.include? ?a}
+#=> ["Fatih", "Sultan"]
+## Süzme işleminin koşulu, a karakteri içeren nesneler için olumlu.
+## Not: filter metodu, select için bir takma addır.
+
+## Ters bir yöntem, süzgeçleme için ise;
+["Fatih", "Sultan", "Mehmet"].reject {|s| s.include? ?a}
+#=> ["Mehmet"]
+## koşulumuz aynıydı, seçimleme metodumuzu değiştirdik.
+
+### Yapısal düzenlemeler için:
+## Dizileri ters çevirmek,
+["Fatih", "Sultan", "Mehmet"].reverse
+#=> ["Mehmet", "Sultan", "Fatih"]
+
+## Sıralamak için sort metodu,
+["İş", "Aşk", "Para"].sort
+#=> ["Aşk", "Para", "İş"]
+
+## Ön koşulla sıralamak için,
+["İş", "Aşk", "Para"].sort {|a,b| b <=> a }
+#=> ["İş", "Para", "Aşk"]
+## Koşulumuz basitçe tersine sıralamak için bir tanımdır.
+## ileride karşılaştırma operatörlerini göreceğiz.
+
+## Tekrarlı elemanların temizlenmesi için
+[1,2,3,4,5,6,7,1,2,4,1,5,6,1,2,5].uniq
+#=> [1, 2, 3, 4, 5, 6, 7]
+
+## Dizilerin birleştirilmesi için
+[1,2] + [3,4]
+#=> [1, 2, 3, 4]
+## infix notasyon sizi yanıltmasın,
+## tasarımı gereği, her şey sınıflar ve metotlarına çağırım
+## olarak yürüyor.
+## Kanıtlayalım;
+[1,2].+([3,4])
+#=> [1, 2, 3, 4]
+
+## Peki ya aynı elemanları içerebilecek dizileri birleştirmek
+## istersek ?
+[1,2] | [2,3,4]
+#=> [1, 2, 3, 4]
+## | operatörü bizi, nihai sonuçtaki tekrarlı veriden koruyor.
+
+## Peki ya bir diziyi, eleman bazında diğeriyle
+## süzmek istersek ?
+[1,2] - [2,3,4]
+#=> [1]
+## Notasyon sizi yanıltmasın, Küme gibi davranan bir dizi işlevi.
+
+### Veri Dönüşümleri için:
+## Dizideki her elemana uygulamak istediğiniz bir
+## dönüşümü, map metodu ile uygulayabilirsiniz,
+["Kontak İsmi",
+ "Kontak Telefon Numarası"].map {|element| "<label>#{element}</label>"}
+#=> ["<label>Kontak İsmi</label>", "<label>Kontak Telefon Numarası</label>"]
+## HTML konusu için yine LearnXinYminutes'e danışabilirsiniz.
+
+## Son elde ettiğimiz veriyi birleştirmek için,
+["<label>Kontak İsmi</label>",
+ "<label>Kontak Telefon Numarası</label>"].join ""
+#=> "<label>Kontak İsmi</label><label>Kontak Telefon Numarası</label>"
+
+## Veriyi indirgemek için ise reduce metodu kullanırız,
+["<label>Kontak İsmi</label>",
+ "<label>Kontak Telefon Numarası</label>"]
+ .reduce("") {|akümülatör, veri| akümülatör + veri}
+#=> "<label>Kontak İsmi</label><label>Kontak Telefon Numarası</label>"
+## Akümülatör, her operasyondan dönen ara-geçici değer.
+## Bu değeri, parantez içinde ilkledik,
+## eğer vermeseydik, dizinin ilk elemanı olacaktı.
+
+## Tabi, daha kolay bir yolu var;
+["<label>Kontak İsmi</label>",
+ "<label>Kontak Telefon Numarası</label>"].reduce(:+)
+#=> "<label>Kontak İsmi</label><label>Kontak Telefon Numarası</label>"
+## reduce metodu, ikili bir operasyonu (akümülatör için metot!)
+## sembol olarak vermenize izin verir ve bu, reduce için
+## indirgeme fonksiyonu olarak kullanılır.
+
+## Nüansları olsa da, son üç Ruby çağırımı aynı sonucu vermektedir.
+
+
+## --
+## Semboller
+## --
+
+## Ruby sembolleri, çalışma zamanında değiştirilemezler.
+## Ama metinsel değerlerden semboller elde etmek mümkündür.
+## Bunu dönüşümler kısmında işlemek daha doğru olacak diye düşündüm.
+
+# --------------------------------
+# Dönüşümler
+# --------------------------------
+
+## --
+# Rakamlar
+## --
+
+## Sayısal değerlerin diğer tiplere dönüşümü;
+
+## Sayısal -> Metinsel
+1923.to_s #=> "1923"
+
+## Sayısal -> Mantıksal
+!1923 #=> false
+## Farkedebileceğiniz gibi,
+## sayısal değerler, mantıksal doğru'ya değerlendiriliyor.
+
+## Sayısal -> Sembol
+## Maalesef, Ruby bile Sayısal değerden Sembol değerlerine
+## doğrudan dönüşüm için metot barındırmıyor.
+## Bunu yine de başarmak istersek, değeri önce
+## Metinsel'e dönüştürerek Sembol dönüşümü için hazırlarız.
+1923.to_s.to_sym
+#=> :"1923"
+
+## Sayısal -> Dizi | bölümlenerek
+## Yine doğrudan bir dönüşüm yoktur.
+## Böyle bir doğrudan dönüşüm teşvik de edilmez.
+## Ama ihtiyaç olabilecek bir dönüşüm.
+1923.to_s.split('')
+#=> ["1", "9", "2", "3"]
+## Öncelikle Metinsel dönüşüm yapılır, sonra
+## her bir karakter için ayrılır.
+## Yine her bir rakamı sayısal bir şekilde elde etmek için
+## her birini Metinsel'den Sayısal değere dönüştürecek
+## ifade aşağıdaki gibidir.
+1923.to_s.split('').map { |i| i.to_i }
+#=> [1, 9, 2, 3]
+
+
+## --
+# Mantıksal
+## --
+
+## Mantıksal -> Metinsel
+true.to_s #=> "true"
+false.to_s #=> "false"
+
+## Mantıksal değeler için gerçeklenmiş başka bir dönüşüm
+## metodu olmadığı için, bu kısmı dilde ufak bir nüansa ayırmak
+## istedim.
+## Kaynak için ileri okumaya başvurunuz.
+
+## Hangi programlama dilinden gelirseniz gelin,
+## dilde doğruluk değerleri diye bir küme vardır.
+## Hangi değerlerin mantıksal doğru değerine dönüşeceği,
+## bu değer yerine geçebileceği
+## fikri üzerine kurulu bir küme.
+## Ve Ruby'de nil değeri, false dışında, mantıksal yanlış değerine çözümlenen tek şey.
+## Bu ön bilgi ile doyduysak, başlayalım.
+
+!!nil #=> false
+!!false #=> false
+!!0 #=> true
+!!"" #=> true
+## Şimdi ne oldu burada ?
+## `!!` ifadesi; değilinin değili, yani kendisi. Tek bir farkla.
+## Verinin türü değiştiriliyor. Mantıksal olarak yorumlanıyor.
+## Yukarıda, nil ve false ifadeleri mantıksal olarak yanlış olarak yorumlanıyor.
+## Diğerleri ise mantıksal doğru.
+
+
+## --
+# Metinsel
+## --
+
+## Metinsel -> Sayısal
+## Öncelikle dilde ufak bir tuzağa dikkat çekmek isterim.
+"".to_i #=> 0
+"asd".to_i #=> 0
+## Sayısal yorumlaması geçersiz ve boş her metinsel değer,
+## 0 rakamına değerlendirilir.
+
+## Başarılı bir dönüşüm,
+"1234".to_i #=> 1234
+
+## Sayı sistemini belirleyebileceğiniz seçimli bir argüman
+## kabul ediyor, to_i metodu.
+"1234".to_i 5 #=> 194
+## 1234 sayısının, beşlik tabandaki karşılığı.
+
+## Tam sayı dışında doğrudan dönüşümler
+## dil olanağı olarak sunulmuş durumda;
+
+## Kompleks sayı olarak,
+"1234".to_c #=> (1234+0i)
+
+## Ondalık (Kayan-noktalı) sayı olarak,
+"1234".to_f #=> 1234.0
+
+## Rasyonel sayı olarak,
+"1234".to_r #=> (1234/1)
+
+## Metinsel -> Mantıksal
+
+## Mantıksal değerin kendisi için tersinin, tersini alırız
+!!"seçkin" #=> true
+
+## Mantıksal tersi için ise tersini,
+!"seçkin" #=> false
+
+## Metinsel -> Sembol
+"cengiz".to_sym #=> :cengiz
+
+## Metinsel -> Dizi
+"Cengiz Han".split #=> ["Cengiz", "Han"]
+
+## split metodu, seçimli argümanının varsayılan değeri
+## boşluk karakteridir.
+
+## Metinsel -> Dizi | bölümlenerek
+"Cengiz Han".split ""
+#=> ["C", "e", "n", "g", "i", "z", " ", "H", "a", "n"]
+
+
+## --
+# Sembol
+## --
+
+## Sembol -> Metinsel
+:metin.to_s #=> "metin"
+## Başka bir dönüşüm için dilin bir teşviki yoktur.
+
+## --
+# Diziler
+## --
+
+## Dizi -> Metinsel
+[1,2,3,4,5].to_s #=> "[1, 2, 3, 4, 5]"
+
+
+## --
+# Eşlemeler
+## --
+
+## Eşleme -> Dizi
+{a: 1, b: 2, c: 3}.to_a
+#=> [[:a, 1], [:b, 2], [:c, 3]]
+## Her bir anahtar-değer çifti bir dizi olarak
+## değerlendirilir ve elemanları sırasıyla
+## anahtar ve değerdir.
+
+## Eşleme -> Metinsel
+{a: 1, b: 2, c: 3}.to_s
+#=> "{:a=>1, :b=>2, :c=>3}"
+## inspect metodu için bir takma addır.
+
+
+# --------------------------------
+# Tanımlamalar, ifadeler, yorumlama.
+# --------------------------------
+
+## --
+## Yorumlama
+## --
+
+## Dökümanın başından beri gördüğümüz bu tek satır yorumlama operatörü
+## (#)
+## kendinden sonra gelen her şeyin, satır boyunca yorumlama olarak
+## değerlendirilmesi gerektiğini Ruby yorumlayıcısına söyler.
+
+## Ruby, farklı yorumlama imkanları da sağlamaktadır.
+## Örneğin;
+=begin
+ Başlangıç ifadesi (=begin), sonlandırma ifadesi (=end)
+ ile arasında kalan her şeyi yorum satırı olarak ele alır.
+=end
+
+## --
+## Global değişkenler.
+## --
+
+## Ruby evrensel değişkenleri, kapsamı en geniş değişken türüdür.
+## Her yerden erişilebilir...
+
+## Basitçe dolar sembolü ( $ ) ile başlarlar.
+$evrensel_bir_değişken = 42 #=> 42
+
+## Bir çok metadoloji ve yöntem ve teknoloji, size
+## evrensel değişkenler kullanmanın projenizi karmaşıklaştıracağı
+## ve bakımını zorlaştıracağını söyler; Haklıdırlar...
+
+## --
+## Varlık değişkenleri.
+## --
+
+## At ( @ ) sembölü ile başlarlar ve isimlerinin de ifade ettiği
+## gibi, kendileri bir Sınıf'ın değeridir.
+
+class Varlık
+ def initialize()
+ @varlık_değişkeni = 101
+ end
+
+ def göster()
+ puts "Varlık değişkeni: #@varlık_değişkeni"
+ end
+end
+
+varlık1 = Varlık.new()
+
+varlık1.göster()
+#=> Varlık değişkeni: 101
+
+## Sınıf tanımı şimdilik kafanızı karıştırmasın.
+## İlgilenmemiz gereken kısım;
+## @varlık_değişkeni = 101
+## ifadesidir. Ve nesne özelinde tanımlama yapar.
+## Kapsamı sadece o nesnedir.
+
+## ! NOT: ilklenmemiş varlık değişkenleri nil ön değeri ile
+## yaşam döngüsüne başlar.
+
+## --
+## Sınıf değişkenleri.
+## --
+
+## Sınıf değişkenleri iki at ( @@ ) sembölü ile başlarlar.
+## Tanımlar, herhangi bir metot içinde
+## kullanılmadan önce ilklenmelidirler.
+## İlklenmemiş bir Sınıf Değişkenine referansta bulunmak,
+## bir hata oluşturur.
+
+class Sınıf
+ @@sınıf_nesne_sayısı = 0
+
+ def initialize()
+ @@sınıf_nesne_sayısı += 1
+ end
+
+ def göster()
+ puts "Sınıf sayısı: #@@sınıf_nesne_sayısı"
+ end
+end
+
+sınıf_varlığı1 = Sınıf.new()
+sınıf_varlığı2 = Sınıf.new()
+sınıf_varlığı3 = Sınıf.new()
+
+sınıf_varlığı1.göster()
+#=> Sınıf sayısı: 3
+
+
+## --
+## Yerel değişkenler.
+## --
+
+## Yerel değişkenlerin isimlendirmesi küçük harf
+## ya da alt çizgi ( _ ) ile başlar ve kapsamı tanımın
+## yapıldığı sınıf, modül, metot yada blok içinde kalır.
+
+## --
+## Sabitler.
+## --
+
+## Ruby sabitleri, büyük harf ile tanımlanırlar ve
+## kapsamları için iki senaryo mevcuttur;
+
+## - Sınıf ya da Modül içinde tanımlanırlarsa
+## Tanımın yapıldığı blok içinden erişilebilir.
+
+## - Sınıf ya da Modül dışında yapılan tanımlar ise
+## Evrensel bir kapsama sahiptir ve her yerden
+## erişilebilirler.
+
+## Örneğin:
+
+class Sabit
+ SABİT = 299_792_458
+
+ def göster
+ puts "Sabit değer: #{SABİT}"
+ end
+end
+
+# Create Objects
+sabit = Sabit.new()
+
+sabit.göster()
+#=> Sabit değer: 299792458
+
+## İfadenin tanımındaki alt çizgiler sizi yanıltmasın
+## binlik ayracı olarak kullandım ve Ruby yorumlayıcısı
+## tamamen görmezden geliyor.
+## Bknz: Veriler ve Temsiller: Sayılar.
+
+## --
+## Sözde Değişkenler.
+## --
+
+## Ruby özel bir dil.
+## Öyle ki, Bazı sözde-değişkenler ile
+## size, ihtiyacınız olabileceği erişimi sağlar.
+## Ama onlara atama yapamazsınız.
+
+## Sözde değişkenler ve kullanımları
+## ile ilgili İleri okumaya başvurunuz.
+
+
+# --------------------------------
+# Konvansiyonlar ve teşvikler.
+# --------------------------------
+
+## Konvansiyonlar:
+
+## --
+## İsimlendirme Konvansiyonları:
+## Döküman boyunca yaptığım gibi,
+## tanımlayıcılar ve erişilebilir tanımlanmış ifadeler
+## için lütfen önerildiği gibi İngilizce kullanın.
+## İsimlendirme, Bilgisayar bilimlerinde yeterince
+## ağır bir zemin ve dilin teşvik ettiği rehber
+## ve önerdiği konvansiyonları takip ederek
+## bakımı, okuması ve geliştirmesi kolay projeler
+## gerçeklemek mümkündür.
+
+## --
+## Semboller, Metotlar ve Değişkenler için
+##-Snake Case ( snake_case ) kullanılması önerilir.
+
+## --
+## Sınıflar için Camel Case (CamelCase):
+## Sınıf isimlendirmeleri için önerildiği gibi,
+## Camel Case isimlendirme notasyonuna sadık kalın.
+
+## --
+## Dosyalar ve Klasörler için Snake Case (snake_case):
+## Dosya ve klasörleri isimlendirmek için lütfen
+## Snake Case isimlendirme konvansiyonuna sadık kalın.
+
+## --
+## Dosya Başına Bir Sınıf:
+## Her dosyada bir sınıf barındırmaya özen gösterin.
+
+## ---
+## Bu kısımdaki teşvik içerikleri
+## rubocop-hq/ruby-style-guide'dan gelmektedir.
+
+## ! Rehbere göre bu dökümanı düzenle!
+
+## --
+## Girintileme:
+## Girintileme için TAB yerine, iki boşluk kullanın.
+
+def bir_metot
+ birşeyler_yap
+end
+## Yerine;
+def bir_metot
+ birşeyler_yap
+end
+
+## --
+## Satır Başına Karakter:
+## Satır başına maksimum 80 karakter olacak şekilde
+## dökümanı yapılandırın.
+
+## --
+## Satır Sonları:
+## Unix-Stili satır sonlarını kulanın.
+## Eğer Git kullanıyorsanız;
+## $ git config --global core.autocrlf true
+## ifadesi sizi bu zahmetten kurtaracaktır.
+
+## --
+## Satır Başına Bir İfade:
+## Satır başına bir ifade kullanın.
+
+puts 'test!'; puts 'test!'
+## Yerine;
+puts 'test!'
+puts 'test!'
+
+## --
+## Boşluklar ve Operatörler:
+## Operatörler, virgüller, ifade ayraçları
+## aralarında boşluk bırakın.
+
+toplam=1+2
+x,z=1,2
+class FooError<StandardError;end
+## Yerine;
+toplam = 1 + 2
+x , z = 1 , 2
+class FooError < StandardError; end
+## Bir kaç istisna hariç
+## - Üs operatörü
+## - Rasyonel sayı gösteriminde kullanılan eğik çizgi.
+## - Güvenli gösterim operatörü.
+
+
+### Daha fazlası için ileri okumadaki
+### bu rehbere danışabilirsiniz...
+
+# --------------------------------
+# Bloklar, Kontrol blokları ve örnekler.
+# --------------------------------
+
+## --
+## Ruby Blokları:
+## Süslü parantezler ya da `do`, `end` ile çevrelenen,
+## değişkenleri ortama bağlı işlevlerdir.
+## Diğer dillerde !{Closure} ( closure ) karşılığı
+## bulur.
+## Ruby'de bloklar, ifadeleri gruplamanın bir şeklidir.
+## Bloklar tanımlandıklarında çalıştırılmazlar,
+## Ruby, bu yönetimi akıllıca yapar.
+
+## Örneğin;
+
+## Tanımlamamız
+def selamla_sonra_çağır
+ puts 'Selamlar!'
+ yield ## tüm sihir burada!
+end
+
+## Şimdi tanımı çağıralım
+selamla_sonra_çağır {puts 'Çağrı, gerçekleşti!'}
+#= Selamlar!
+#= Çağrı, gerçekleşti!
+#=> nil
+## Çağırım, kendini çağıran kaynağa nil döndürmekte.
+## Değerlendirmenin sonucunda, Ruby yorumlayıcısı,
+## ifadenin değerini nil olarak çıktılar.
+## Fakat, puts çağrıları, girdi/çıktı işlevimizi
+## yerine getirir ve metinleri ekrana basar.
+
+## Blokların argüman almaları da mümkündür:
+def selamla_sonra_değer_ile_çağır
+ puts 'Selamlar!'
+ yield('Hain Kostok') ## tüm sihir burada!
+end
+
+selamla_sonra_değer_ile_çağır {|isim| puts "Sana da selam, #{isim}!"}
+#= Selamlar!
+#= Sana da selam, Hain Kostok!
+#=> nil
+
+## Detaylı bilgi için, ileri okumaya başvurunuz.
+
+## --
+## Eğer ( if ) kontrol ifadesi:
+## Algoritmanızda dallanma imkanı sağlar.
+## Şablonu:
+## if koşul_ifadesi [then]
+## yürütülecek_kod
+## [elsif bir_diğer_koşul [then]
+## yürütülecek_diğer_kod]
+## [else
+## yürütülecek_bir_diğer_kod]
+## end
+
+## Bu kalıba sadık kalarak, dallanmalarımızı kodlarız.
+## Köşeli parantezler, sezgisel olarak anlaşılacağı üzere
+## seçimli ifadelerdir.
+
+## Örnek:
+if true
+ puts 'Koşul ifadesi, buradan devam edecek!'
+else
+ puts 'Buradan değil.'
+end
+#= Koşul ifadesi, buradan devam edecek!
+#=> nil
+
+## --
+## Eğer ( if ) düzenleyicisi:
+## Kompak bir dil olanağıdır. Aynı şekilde, çalıştırılacak kod
+## ve bir koşul ifadesi alır. Ve koşul ifadesine bakarak
+## ifadenin yürütüleceğine karar verir.
+## Şablonu:
+## çalıştırılacak_kod if koşul_ifadesi
+
+## Örnek:
+
+puts 'Bu ifade yürütülecek!' if true
+#= Bu ifade yürütülecek!
+#=> nil
+
+
+## --
+## Durum ( case ) kontrol ifadesi:
+## Bir koşul ifadesi ve bir ya da daha fazla karşılaştırma ifadesi
+## alarak, eşleşen bloğu yürütür.
+## Şablonu:
+## case koşullanacak_ifade
+## [when karşılaştırma_ifadesi [, karşılaştırma_ifadeleri ...] [then]
+## yürütülecek_kod ]...
+## [else
+## eşleşme_olmazsa_yürütülecek_kod ]
+## end
+
+yaş = 27
+case yaş
+when 0 .. 2
+ puts "bebek"
+when 3 .. 6
+ puts "küçük çocuk"
+when 7 .. 12
+ puts "çocuk"
+when 13 .. 18
+ puts "genç"
+else
+ puts "yetişkin"
+end
+#= yetişkin
+#=> nil
+
+## --
+## .. Sürece ( while ) kontrol ifadesi:
+## Aldığı koşul ifadesini kontrol eder,
+## kontrol bloğunu çağırır ve tekrar kontrol eder.
+## Koşul ifadesi doğru olduğu sürece, kontrol bloğu
+## çağırılmaya devam eder.
+## Şablonu:
+## while koşul_ifadesi [do]
+## yürütülecek_kod
+## end
+
+## Örnek:
+
+$n = 0
+$sayı = 5
+
+while $n < $sayı do
+ puts("Döngü içinde n = #$n" )
+ $n +=1
+end
+#= Döngü içinde n = 0
+#= Döngü içinde n = 1
+#= Döngü içinde n = 2
+#= Döngü içinde n = 3
+#= Döngü içinde n = 4
+#=> nil
+
+## --
+## .. Sürece ( while ) düzenleyicisi:
+## Eğer düzenleyecisi gibi, kompak bir dil olanağıdur.
+## Kontrol ifadesinin işlevini yerine getirir,
+## ama satır içi kullanıma müsade ederek.
+## Şablonu:
+## çalıştırılacak_kod while koşul_ifadesi
+## Yada:
+## begin
+## çalıştırılacak_kod
+## end while koşul_ifadesi
+
+## --
+## İçin ( for ) kontrol ifadesi:
+## N kere, I kere, X kere gibi ifadelerin dildeki kontrol
+## karşılığıdır. Çoklu veri üzerinde iterasyonlar yapmanızı
+## veri üzerinde operasyonlar yürütmenizi sağlar.
+## Şablonu:
+## for değişken [, başka_değişken ...] in ifade [do]
+## yürütülecek_kod
+## end
+
+## Örnek:
+for i in 1..5
+ puts i
+end
+#= 0
+#= 1
+#= 2
+#= 3
+#= 4
+#= 5
+#=> 0..5
+
+## Ardışıkları itere etmek için tek yol bu değil tabii.
+## İlerleyen kısımda buna yer verilecektir.
+
+## --
+## Sonlandırıcı ( break ) kontrol ifadesi:
+## Bu kontrol ifadesi yürütüldüğünde, çalışma zamanını
+## en iç tekrarlı bloktan çıkarır.
+
+## Örnek:
+for i in 1..5
+ break if i > 2
+ puts i
+end
+#= 0
+#= 1
+#= 2
+#=> nil
+## break kontrol ifadesi, if düzenleyecisi ile çevrelenmiştir.
+## if i > 2
+## break
+## end
+## ifadesi ile eşdeğerdir.
+## ifade yürütüldüğü anda, en yakın tekrarlı blok terkedilir.
+## Yorumlayıcı, sonraki ifadeden yürütmeye devam eder.
+
+## Diğer kontrol ifadeleri ve kullanımları için ileri okumaya başvurunuz...
+
+
+# --------------------------------
+# Özel anahtar kelimeler; kullanımları ve örnekleri.
+# --------------------------------
+
+## --
+## __ENCODING__:
+## Bu anahtar kelime size yorumlayıcı kodlama türünü verecektir.
+
+__ENCODING__
+#=> "#<Encoding:UTF-8>"
+
+## Platform, araç ve çalışma zamanı yürütme
+## yönteminize bağlı olarak alacağınız çıktı
+## değişiklik gösterebilir.
+
+## --
+## __LINE__:
+## Geçerli dosyada, yürütme satır numarasını verir.
+
+__LINE__
+#=> 67
+
+## Platform, araç ve çalışma zamanı yürütme
+## yönteminize bağlı olarak alacağınız çıktı
+## değişiklik gösterebilir.
+
+## --
+## BEGIN ve END:
+## BEGIN:
+## Dosyadaki tüm içerikten önce yürütülür.
+## END:
+## Dosyadaki tüm içeriklerden sonra yürütülür.
+
+## --
+## alias:
+## Herhangi bir tanımlayıcı için takma ad tanımlamanıza
+## olanak sağlar.
+
+$eski = 0
+alias $yeni $eski
+
+$yeni
+#=> 0
+
+## --
+## and:
+## Düşük öncelikli bir Mantıksal VE operatörü.
+
+## --
+## begin / end ve rescue:
+## İstisnalar begin / end blokları
+## arasında ele alınır ve `rescue` anahtar kelimesi ile
+## işlenirler.
+## İstisnalar ve mantalitesine dair ön girişi
+## Teşvik edilen paradigma ve anlatımı kısmında bulabilirsiniz.
+
+## Hata yönetimi, Ruby'de de özenle işlenmiş bir konudur.
+
+## Örnek:
+
+begin
+ yanlış_bir_hesaplama = 2/0
+ puts "Hesaplama sonucu: #{yanlış_bir_hesaplama}"
+ rescue ZeroDivisionError => hata_nesnesi
+ puts "Sıfıra bölümle ilgili bir hata yakalandı: #{hata_nesnesi.message}"
+end
+#= Sıfıra bölümle ilgili bir hata yakalandı: divided by 0
+#=> nil
+
+## Örneğimizde matematiksel sistemimiz için hatalı bir
+## işlem gerçekleştiriyoruz. Sonrasında hatayı ilgili
+## hata durumu için belirlediğimi alanda yönetiyoruz.
+## Örnekte hatayı çıktılayarak yönettik, gerçek dünyada
+## biraz daha kompleks gerçekleşebilir.
+## Gerçek dünya örnekleri için ileri okumaya başvurabilirsiniz.
+
+
+## --
+## defined?:
+## defined?, argümanını metinsel olarak açıklayan bir dil olanağıdır.
+
+## Örnek:
+RUBY_VERSION
+#=> "2.4.0"
+
+defined? RUBY_VERSION
+#=> "constant"
+
+defined? nil
+#=> "nil"
+
+defined? puts
+#=> "method"
+
+
+## --
+## ensure:
+## Hata yönetiminin bir parçası olarak dilde görev atfedilen ensure,
+## blok içinde, hata olsun ya da olmasın yürütüleceği garanti edilen
+## dil ifadeleri için bir imkandır.
+
+## Örnek:
+
+begin
+ yanlış_bir_hesaplama = 2/0
+ puts "Hesaplama sonucu: #{yanlış_bir_hesaplama}"
+ rescue ZeroDivisionError => hata_nesnesi
+ puts "Sıfıra bölümle ilgili bir hata yakalandı: #{hata_nesnesi.message}"
+ ensure
+ puts "Hesaplama bloğu sonlandı!"
+end
+#= Sıfıra bölümle ilgili bir hata yakalandı: divided by 0
+#= Hesaplama bloğu sonlandı!
+#=> nil
+
+
+## --
+## self:
+## Nesnenin kendisine erişim sağlayan bir dil olanağı.
+
+## Örnek:
+
+dünya = "Dünya!"
+#=> "Dünya!"
+
+dünya
+#=> "Dünya!"
+
+dünya.class
+#=> String
+
+def dünya.selamla
+ "Merhaba, " + self
+end
+#=> :selamla
+
+dünya.selamla
+#=> "Merhaba, Dünya!"
+
+## Nesnenin kendisine bir metot tanımladık,
+## bunu yaparken de değerine erişim sağladık.
+
+## --
+## super:
+## Nesne yönelimli programlama (spesifik olarak, obje tabanlı)
+## paradigmasına göre, kalıtım konseptinde, türeyen sınıfın
+## türetildiği sınıfa erişimi (üst sınıfı, atası, hiyerarşik üstü)
+## bu anahtar kelime ile gerçekleşir.
+
+class A
+ def initialize(a)
+ @a = a
+ end
+end
+
+class B < A
+ def initialize(a, b)
+ @b = b
+ super a
+ end
+end
+
+b = B.new 1, 2
+#=> #<B:0x00007f852d04c7e8 @b=2, @a=1>
+## super ile üst sınıfın ilklenmesi gerçekleştirildi,
+## aldığımız çıktıda da @a=1 çıktısıyla gözlemlenebilir.
+
+## Bu konunun, dilin paradigma teşviği ile ilgili
+## olduğunu ve anlamazsanız, Paradigma başlığını bitirdikten
+## sonra tekrar bu örneği değerlendirmeniz gerektiğini hatırlatırım.
+
+## --
+## yield:
+## Ruby blokları kısmında anlattık, ama, burada da bir nüanstan
+## bahsetmeden geçemeyeceğim.
+## Çalıştırılabilir ifadeleri çalıştırmanın birden fazla yolu vardır.
+## Fakat yield, en performanslı dil olanağı olarak dökümanda işlenmiş.
+## Kaynak için ileri okumaya danışın.
+
+
+
+# --------------------------------
+# G/Ç ( I/O )
+# --------------------------------
+
+=begin
+ G/Ç, Girdi/Çıktı ( Input/Output ) kısaltmasıdır.
+ Temelde, sistemden girdi almak ve çıktı yaratmak amacıyla vardır.
+ Girdi örnekleri:
+ - Klavyeden bastığınız herhangi bir tuş.
+ - Fare hareketleriniz ya da tıklamalarınız.
+ - Mikrofonunuzun aldığı sesler.
+
+ Çıktı örnekleri:
+ - Herhangi bir dil ifadesinin sonucu.
+ - Dijital bir ses dosyasının sese dönüşmesi.
+ - Ekranda gördükleriniz.
+
+ Fakat endişelenmeyin, G/Ç derken, şu anda
+ biz sadece Ruby'de,
+ - Dosya okuma/yazma.
+ - Ekrana metin yazdırma / Bilgi okuma.
+ - Ağ soketleri. ( biraz da olsa )
+ işlerinden bahsediyor olacağız.
+=end
+
+defined? IO
+#=> "constant"
+
+IO.class
+#=> Class
+
+## IO sınıfı, File ve Socket gibi pratik kullanımı olan sınıfların atasıdır.
+## Septikler için;
+
+File.superclass
+#=> IO
+## Gözlemlediğiniz üzere, superclass metodu, üst sınıfı veriyor.
+
+## --
+## Dosya Okuma ve Yazma:
+## Ruby'de dosya okuma ve yazma işlemleri için, File
+## sınıfını kullanacağız.
+
+## Dosyaya yazmak için;
+File.write 'test.txt', "a,b,c"
+#=> 5
+## 5, ifadenin ürettiği dönüş değeridir.
+## ve, çıktılanan karakter sayısını verir.
+
+## Dosyadan okuma için;
+## Bu kısım, açıklayıcı olması açısından
+## ifadeleri teker teker işleyeceğiz.
+
+File
+#=> File
+## Sınıfımız.
+
+File.readlines 'test.txt'
+#=> ["a,b,c"]
+## readlines File sınıfının bir metodu ve aldığı argüman dosya yoludur.
+
+File.readlines('test.txt').first
+#=> "a,b,c"
+## Dönüş değeri bir diziydi, her bir satır bir eleman olacak şekilde.
+## Biz, kendi verilerimizi, kendi ayıracımızla kaydetmeyi seçtik.
+## Eğer, `\n` satır ifadesi ile ayırmayı seçseydik, readlines
+## metodu zaten işlevi gereği, bize değerleri ayrı ayrı verecekti.
+
+File.readlines('test.txt').first.split ','
+#=> ["a", "b", "c"]
+## verilerimizi aldık.
+
+## Eğer yeni satır karakterini ayıraç olarak kullansaydık;
+File.write 'ntest.txt', ['a', 'b', 'c'].join("\n")
+#=> 5
+
+File.readlines('ntest.txt').map(&:chomp)
+#=> ["a", "b", "c"]
+## Bu da genel kullanımlı bir yaklaşımdır.
+
+## --
+## Ekrana bilgi yazdırma ve Okuma:
+## Konsol'a bilgi çıktılamak için,
+## önceden tanımlanmış $stdout global nesnesini kullanacağız.
+## Pratik kullanımda, prints işlevinden bir farkı yoktur.
+## Aynı sonuca ikisi ile de ulaşabilirsiniz.
+
+$stdout.print "Bu bir çıktı.\n"
+#= Bu bir çıktı.
+#=> nil
+
+## Şimdi kullanıcıdan bilgi okuyalım:
+$stdin.gets
+#! Bu kısımda hiç bir çıktı verilmez ve aksine
+#! sizden girdi beklenir. Bir metin yazın ve onaylamak için
+#! enter tuşunu kullanın.
+#- Bu bir girdi metni!
+#=> "Bu bir girdi metni!\n"
+
+## Aldığımız veriyi temizlenin yolunu biliyoruz.
+## Dönüş değerine chomp metodunu uygulamak.
+$stdin.gets.chomp
+#- Bu bir girdi metni!
+#=> "Bu bir girdi metni!"
+
+
+## --
+## Ağ girdi/çıktı yönetimi
+## Ruby'de soketler (Socket)
+## haricen çalışma zamanına dahil edilir.
+
+require 'socket'
+#=> true
+
+soket = TCPSocket.new('google.com', 80)
+#=> #<TCPSocket:fd 13, AF_INET, 192.168.0.11, 63989>
+## Alacağınız çıktı değişiklik gösterebilir.
+## Soketi oluşturduk ve bir değişkene atadık.
+## Şimdi bunun üzerinden okuma ve yazma işlemlerini
+## gerçekleştireceğiz.
+
+soket.write "GET / HTTP/1.1"
+#=> 14
+
+soket.write "\r\n\r\n"
+#=> 4
+## İki write metodunun sonucu da, sokete yazılan verinin
+## uzunluğudur.
+
+## Şimdi okuma zamanı, soketi açtık, isteğimizi bildirdik.
+## Şimdi soket üzerinden aldığımız cevabı ekrana yazdıralım.
+
+soket.recv 80
+#=> "HTTP/1.1 200 OK\r\nDate: Thu, 03 Sep 2020 10:48:21 GMT\r\nExpires: -1\r\nCache-Control"
+## Alacağınız çıktı değişiklik gösterebilir.
+## Ancak, başarılı şekilde okuma yaptık.
+
+
+
+# --------------------------------
+# Teşviğinde bulunduğu paradigma ve derinlemesine anlatımı.
+# --------------------------------
+
+## --
+## Nesne Yönelimli Programlama Nedir?
+## Kısaca NYP, en basit anlatımıyla;
+## nesnelerle programlamadır.
+## Nesne paradigması, her programcıya doğal ve sezgisel gelir.
+## Bunun sebebi, zaten gerçekliği algılama şeklimize uygun olmasıdır.
+## Araba, onu bir araya getiren nesnelerden oluşur,
+## tekerlekleri, direksiyonu, kasası, ve diğer parçalarıyla.
+## Ama bu, tam tanım değildir. NYP'de, Nesneler,
+## Bilgilere ( evet, varlık olarak başka nesneler de sayılabilir )
+## ve bu bilgileri yönetecek ( hesaplamalar gerçekleştirecek
+## ya da aksiyonlar alacak -- G/Ç -- gibi ) metotlara sahiptir.
+
+## Bir nesnenin en net tanımı böyle yapılabilirken,
+## NYP, bir gerçek dünya problemi için bir araya getirilmiş
+## -- çoğunlukla birden fazla -- sınıfların yapıları,
+## ilişkileri ve işlevlerini ele alır.
+
+## Bir paradigma olarak NYP, bizlere her varlığı nesne olarak
+## modellemeyi ve problem uzayımızdaki nesnelerle olan ilişkilerini
+## Ruby'de NYP için sağlanan imkanlarla yönetmeyi öğütler.
+
+## Sınıf içerisinde saklanan bilgiye öznitelik ya da özellik,
+## işlevlere ise metot denilir.
+## NYP jargonu için ileri okumaya başvurabilirsiniz.
+
+## --
+## Ruby'de NYP teşviki:
+
+## Nesneler, Sınıfların gerçeklenmiş halleridir.
+## Tam tersi ile, Sınıflar ise, nesnelerin soyut kalıplarıdır.
+
+## Bir sınıf tanımı yapalım ve gerçekleyelim:
+
+class Araba
+end
+#=> nil
+## Evet, evet. Tanımımız hiç bir öznitelik ( attributes ) ya da
+## metot ( method ) içermiyor.
+
+## Şimdi bir özellik ekleyelim
+class Araba
+ def initialize(hız)
+ @hız = hız
+ end
+end
+
+araba = Araba.new 100
+#=> #<Araba:0x00007f7f300e59c8 @hız=100>
+
+## En naif haliyle, hız bilgisi saklayan bir araba sınıfı gerçekledik.
+## initialize metodu, Ruby imkanları ile, nesne yaşam döngünüzün ilk adımıdır.
+## Bu döngüyü aşağıdaki gibi betimlemek mümkündür.
+## İlkleme ( initialize ) -> [İşlevlerin çağırımı] -> Sonlandırma
+## İlkleme, initialize metodu ile ele alınır, alınacak tüm argümanlar,
+## sınıfın iş mantığı doğrultusuyla, bu ilk işlevde yönetilir ve nesne
+## kullanıma hazır hale getirilir.
+
+## Şimdi bir işlev ekleyelim.
+
+class Araba
+ def initialize(hız)
+ @hız = hız
+ end
+
+ def git!
+ puts 'Hınn, hınn!'
+ end
+end
+
+araba = Araba.new 100
+#=> #<Araba:0x00007f7f300e59c8 @hız=100>
+
+## Şimdi metodu çağırıyoruz.
+araba.git!
+#= Hınn, hınn!
+#=> nil
+
+## Başlığın amacı sadece Ruby'nin NYP olanaklarını ve
+## teşviğini işlemek değil. Paradigmaya bir giriş kazandırmak.
+## Bundan dolayı, etkileşim içinde birden fazla sınıf görmeliyiz.
+
+class Tekerlek
+ YERLİ = 5
+ İTHAL = 1
+
+ def initialize (tür)
+ @güç = tür
+ end
+
+ def döndür!
+ @güç -= 1
+ end
+end
+
+class Araba
+ def initialize (hız)
+ @hız = hız
+ @tekerlekler = (1..4).map {|| Tekerlek.new(Tekerlek::YERLİ)}
+ end
+
+ def git!
+ if @tekerlekler.map(&:döndür!).filter {|ömür| ömür < 0}.first then
+ puts 'Paat!'
+ else
+ puts 'Hınnn, hınnn!'
+ end
+ end
+end
+
+## nesnemizi oluşturuyoruz
+araba = Araba.new 100
+
+## altı sefer, araba nesnesinin git! metodunu çağırıyoruz.
+(0..6).map {|| araba.git! }
+#= Hınnn, hınnn!
+#= Hınnn, hınnn!
+#= Hınnn, hınnn!
+#= Hınnn, hınnn!
+#= Hınnn, hınnn!
+#= Paat!
+#= Paat!
+
+## İş mantığımıza göre, arabamızın dört tekeri ve ve Yerli olanlar
+## 5 birim dayanıklılığa sahip. ;)
+## Bu beş birim tükenince, araba gitmek yerine,
+## patlak teker çıktısı alıyoruz.
+
+
+## Şimdiye kadar gördüklerimizi bir analiz edelim;
+## Araba, sınıfın ismi. Her sınıf, tanımlamasak da, temel bir
+## kurucu metot içerecek şekilde dil işleyicisi tarafından
+## ele alınıyor.
+## Bizim bir tanımımız var ama.
+## Hız bilgisi alıyoruz.
+## bu bilgi, sınıf özniteliğidir. Sınıf, bu bilgiye kendi içinden erişebilir.
+## Bir de, binek araçların dört tekerleği olduğu fikriyle,
+## nesne içinde, kurucu metot içinde dört tane Tekerlek nesnesi gerçekliyor
+## ve saklıyoruz.
+## İş mantığımıza göre onlara erişmemiz gerekiyor.
+## git! metodu içinde, erişiyor ve kullanıyoruz.
+## metotların sonundaki ünlem işareti bir konvansiyondur,
+## metotların saf olmayan çağırımlar gerçeklediği anlamına gelmektedir.
+## Kendilerini ( ya da sahip olduğu diğer nesneleri ) değiştirdikleri,
+## bir girdi/çıktı gerçekleştirdikleri yada buna benzer yan etki içeren
+## bir ifade barındırdıkları anlamına gelir.
+
+## Sizi temin ederim ki, NYP, bu dökümanı ( hali hazırda ~1560 satır )
+## genel anlatımı için bile ikiye katlayabilir.
+## Lütfen detaylı bilgi için ileri okumaya başvurunuz.
+```
+
+# İleri okumalar.
+
+Tümüyle İngilizce olan bu ileri okumalara inat, bu detaylı özgün Türkçe içeriği üretmek istedim.
+Dilerim, benden sonra katkıda bulunanlar olur.
+
+- [Ruby Style Guide](https://rubystyle.guide), Ruby stil rehberi.
+- [Ruby-Doc üzerinde Proc](https://ruby-doc.org/core-2.4.0/Proc.html), Ruby Blokları ve Proc kavramı için.
+- [Ruby-Doc üzerinde String](https://ruby-doc.org/core-2.6/String.html) sınıfı, işlevleri, metotları.
+- [Ruby-Doc üzerinde TrueClass](https://ruby-doc.org/core-2.5.1/TrueClass.html#method-i-to_s) Dildeki mantıksal ifadelerin gerçeklemesi olan TrueClass (ve FalseClass için de aynı bağlantı üzerinden içeriğe ulaşılabilir) dönüşüm içeriği kaynağı.
+- [Ruby Gerçeklemeleri Listesi](https://github.com/codicoscepticos/ruby-implementations) Ruby'nin farklı platformlardaki gerçeklemeleri. Opal ve Topaz dikkat çekenleridir.
+- [The Object-Oriented Thought Process](https://www.amazon.com/Object-Oriented-Thought-Process-Developers-Library/dp/0321861272) kitap, bir paradigma olarak NYP ve düşünce yapısından bahsediyor. Bir paradigma olarak, NYP, türetildiği temel paradigmadan ne almış, başka paradigmalara ne kadar imkan sağlıyor ve paralel paradigma uyumu konusunda tüm sorularınıza cevap bulabilirsiniz. Yazar, belli etmese de, pragmatik bir yaklaşımda.
+- [Block Argument](https://docs.ruby-lang.org/en/2.4.0/syntax/methods_rdoc.html#label-Block+Argument) Ruby Blokları ve yield hakkındaki Ruby resmi döküman sayfası ve alt başlığı.
+- [A Theory of Objects]() Class-Based Languages başlığında inceleniyorlar.
diff --git a/tr-tr/sql-tr.html.markdown b/tr-tr/sql-tr.html.markdown
new file mode 100644
index 00000000..54007d32
--- /dev/null
+++ b/tr-tr/sql-tr.html.markdown
@@ -0,0 +1,125 @@
+---
+language: SQL
+contributors:
+ - ["Metin Yalçınkaya", "https://github.com/mtnylnky"]
+lang: tr-tr
+filename: learnsql-tr.sql
+---
+
+
+```sql
+-- Yorumlar iki tire ile başlar
+
+-- KISITLAR
+Not null -- Bir kolon asla boş olamaz
+default -- Boş olan yerlere varsayılan bir değer atar
+unique -- Bir kolondaki tüm değerlerin farklı olması kısıtlaması
+primary key -- Bir tablodaki her veri için kimlik bilgisi niteliğindedir
+check -- Bir kolondaki değerlerin belli bir kısıtlamayı sağlamasını sağlar
+
+-- Tablo oluşturulur
+CREATE TABLE tablo1 ();
+
+-- Tabloyu içerisinde kolonlar ile oluşturma
+CREATE TABLE tablo1(id INTEGER PRIMARY KEY NOT NULL UNIQUE, ad TEXT, soyad TEXT, yas INTEGER);
+
+-- TABLO varlığını kontrol eder
+.table
+
+-- Veri tabanında olan bütün tabloları görüntüler.
+.schema
+
+-- Satır ekle
+INSERT INTO tablo1 ( ad, soyad) VALUES ("Deger1","Deger2");
+
+-- Veritabanında tablo üzerindeki verileri görüntüle
+-- Sadece 'ad' gibi sınırlı bir veri için
+SELECT ad FROM tablo1;
+-- Bütün veriler için
+SELECT * FROM tablo1;
+
+-- Veri güncelleme
+UPDATE tablo1 SET ad = "deger1-2"; WHERE name = "Deger1";
+
+-- Satır sil
+DELETE FROM tablo1 WHERE id = 1;
+DELETE FROM tablo1 WHERE ad = "Deger1" OR ad = "Deger2";
+
+-- Tabloya sonradan kolon ekleme
+ALTER TABLE tablo1 ADD COLUMN email TEXT;
+
+-- Tablodaki kolon adı değiştirme
+EXEC sp_rename ' tablo1.[ad]', Ad, 'COLUMN';
+
+-- Tablo adı değiştirme
+ALTER TABLE table1 RENAME TO Table1;
+
+-- Tabloyu silme
+DROP TABLE Table1;
+
+-- BİR TABLOYU BAŞKA TABLO KULLANARAK DOLDURMAK
+INSERT INTO Tablo2 SELECT id,ad, soyad, email from Tablo1;
+
+-- LIKE KOMUTU
+-- Belirli bir kritere göre arama yaparken kullanılır
+-- Adı 'A' ile başlayan veriler
+SELECT * FROM tablo1 WHERE adi LIKE "A%";
+-- İçinde 'A' olan veriler
+SELECT * FROM tablo1 WHERE adi LIKE "%A%";
+
+-- LIMIT KOMUTU
+-- Gösterilen satır sayısını sınırlamak için
+SELECT * FROM Tablo1 LIMIT 6;
+-- Gösterilen satırları belirli bir noktadan başlamak üzere sınırlamak için
+SELECT * FROM Tablo1 LIMIT 6 OFFSET 3;
+
+-- ORDER BY KOMUTU
+-- Herhangi bir kolona göre gösterilen değerleri azalan veya artan şekilde sıralamak için
+SELECT kolon FROM tablo1 WHERE yas ORDER BY column1, column2, .. columnN] [ASC | DESC];
+SELECT * FROM Tablo1 ORDER BY yas ASC
+SELECT * FROM Tablo1 ORDER BY yas DESC
+
+-- DISTINCT ANAHTAR SÖZCÜĞÜ
+-- Bu anahtar sözcükle sadece farklı değerler gösterilir.
+SELECT DISTINCT yas FROM tablo1;
+
+-- JOIN KOMUTU
+-- CROSS JOIN
+-- Cross join bir tablodaki her satırı ikinci tablodaki bir satır ile eşleştirmek için kulanılır.
+-- Eğer birinci tabloda x satır ikinci tabloda y satır varsa sonuçta x*y satır olur.
+SELECT ... FROM table1 CROSS JOIN table2 …
+SELECT ad, yas FROM Tablo1 CROSS JOIN Tablo2;
+
+-- INNER JOIN
+-- Inner join iki tablodaki ortak kolon değerlerini kullanarak bir sonuç üretir.
+SELECT ... FROM table1 [INNER] JOIN table2 ON conditional_expression …
+SELECT ad, yas FROM Tablo1 INNER JOIN Tablo2 ON Tablo1.ad = Tablo2.soyad;
+
+-- OUTER JOIN
+-- Outer join iki tablodaki ortak kolon değerlerinin dışında kalanları kullanarak bir sonuç üretir.
+SELECT isci_num, isim, dept FROM Tablo1 LEFT OUTER JOIN Tablo2 ON Tablo1.id = Tablo2.isci_num;
+
+-- ÇEKİRDEK FONKSİYONLAR
+COUNT -- Sayma
+AVG -- Ortalama
+ABS -- Mutlak değer
+SUM -- Toplam
+RANDOM -- Rastgele
+ROUND -- Yuvarlama
+MAX -- Maksimim
+MIN -- Minimum
+UPPER -- Büyük Harf
+LOWER -- Küçük Harf
+LENGTH -- Uzunluk
+CURRENT_TIMESTAMP -- Zaman
+
+SELECT max(yas) FROM Table1;
+SELECT min(yas) FROM Table1;
+SELECT avg(yas) FROM Table1;
+SELECT * From Table1 WHERE yas ==18;
+SELECT sum(yas) FROM Table1;
+SELECT random() AS Random;
+SELECT upper(ad) FROM Table1;
+SELECT lower(ad) FROM Table1;
+SELECT ad, length(ad) FROM Table1;
+``` \ No newline at end of file
diff --git a/tr-tr/swift-tr.html.markdown b/tr-tr/swift-tr.html.markdown
index 15056bb8..4c2cf59b 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
---
@@ -443,47 +443,47 @@ if let daire = benimBosDairem {
// Sınıflar gibi metotlar içerebilirler.
enum Kart {
- case Kupa, Maca, Sinek, Karo
+ case kupa, maca, sinek, karo
func getIcon() -> String {
switch self {
- case .Maca: return "♤"
- case .Kupa: return "♡"
- case .Karo: return "♢"
- case .Sinek: return "♧"
+ case .maca: return "♤"
+ case .kupa: return "♡"
+ case .karo: return "♢"
+ case .sinek: return "♧"
}
}
}
// Enum değerleri kısayol syntaxa izin verir. Eğer değişken tipi açık olarak belirtildiyse enum tipini yazmaya gerek kalmaz.
-var kartTipi: Kart = .Kupa
+var kartTipi: Kart = .kupa
// Integer olmayan enumlar direk değer (rawValue) atama gerektirir.
enum KitapAdi: String {
- case John = "John"
- case Luke = "Luke"
+ case john = "John"
+ case luke = "Luke"
}
-print("Name: \(KitapAdi.John.rawValue)")
+print("Name: \(KitapAdi.john.rawValue)")
// Değerlerle ilişkilendirilmiş Enum
enum Mobilya {
// Int ile ilişkilendirilmiş
- case Masa(yukseklik: Int)
+ case masa(yukseklik: Int)
// String ve Int ile ilişkilendirilmiş
- case Sandalye(String, Int)
-
+ case sandalye(String, Int)
+
func aciklama() -> String {
switch self {
- case .Masa(let yukseklik):
+ case .masa(let yukseklik):
return "Masa boyu \(yukseklik) cm"
- case .Sandalye(let marka, let yukseklik):
+ case .sandalye(let marka, let yukseklik):
return "\(brand) marka sandalyenin boyu \(yukseklik) cm"
}
}
}
-var masa: Mobilya = .Masa(yukseklik: 80)
+var masa: Mobilya = .masa(yukseklik: 80)
print(masa.aciklama()) // "Masa boyu 80 cm"
-var sandalye = Mobilya.Sandalye("Foo", 40)
+var sandalye = Mobilya.sandalye("Foo", 40)
print(sandalye.aciklama()) // "Foo marka sandalyenin boyu 40 cm"
diff --git a/typescript.html.markdown b/typescript.html.markdown
index 1d712369..f7a41ce1 100644
--- a/typescript.html.markdown
+++ b/typescript.html.markdown
@@ -5,33 +5,49 @@ contributors:
filename: learntypescript.ts
---
-TypeScript is a language that aims at easing development of large scale applications written in JavaScript.
-TypeScript adds common concepts such as classes, modules, interfaces, generics and (optional) static typing to JavaScript.
-It is a superset of JavaScript: all JavaScript code is valid TypeScript code so it can be added seamlessly to any project. The TypeScript compiler emits JavaScript.
+TypeScript is a language that aims at easing development of large scale
+applications written in JavaScript. TypeScript adds common concepts such as
+classes, modules, interfaces, generics and (optional) static typing to
+JavaScript. It is a superset of JavaScript: all JavaScript code is valid
+TypeScript code so it can be added seamlessly to any project. The TypeScript
+compiler emits JavaScript.
-This article will focus only on TypeScript extra syntax, as opposed to [JavaScript](javascript.html.markdown).
+This article will focus only on TypeScript extra syntax, as opposed to
+[JavaScript](/docs/javascript).
-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.
+To test TypeScript's compiler, head to the
+[Playground](https://www.typescriptlang.org/play) 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;
-var name: string = "Anders";
+let isDone: boolean = false;
+let lines: number = 42;
+let name: string = "Anders";
+
+// But you can omit the type annotation if the variables are derived
+// from explicit literals
+let isDone = false;
+let lines = 42;
+let name = "Anders";
// When it's impossible to know, there is the "Any" type
-var notSure: any = 4;
+let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
+// Use const keyword for constants
+const numLivesForCat = 9;
+numLivesForCat = 1; // Error
+
// For collections, there are typed arrays and generic arrays
-var list: number[] = [1, 2, 3];
+let list: number[] = [1, 2, 3];
// Alternatively, using the generic array type
-var list: Array<number> = [1, 2, 3];
+let list: Array<number> = [1, 2, 3];
// For enumerations:
-enum Color {Red, Green, Blue};
-var c: Color = Color.Green;
+enum Color { Red, Green, Blue };
+let c: Color = Color.Green;
// Lastly, "void" is used in the special case of a function returning nothing
function bigHorribleAlert(): void {
@@ -41,16 +57,18 @@ function bigHorribleAlert(): void {
// Functions are first class citizens, support the lambda "fat arrow" syntax and
// use type inference
-// The following are equivalent, the same signature will be infered by the
+// The following are equivalent, the same signature will be inferred by the
// compiler, and same JavaScript will be emitted
-var f1 = function(i: number): number { return i * i; }
+let f1 = function (i: number): number { return i * i; }
// Return type inferred
-var f2 = function(i: number) { return i * i; }
-var f3 = (i: number): number => { return i * i; }
-// Return type inferred
-var f4 = (i: number) => { return i * i; }
-// Return type inferred, one-liner means no return keyword needed
-var f5 = (i: number) => i * i;
+let f2 = function (i: number) { return i * i; }
+// "Fat arrow" syntax
+let f3 = (i: number): number => { return i * i; }
+// "Fat arrow" syntax with return type inferred
+let f4 = (i: number) => { return i * i; }
+// "Fat arrow" syntax with return type inferred, braceless means no return
+// keyword needed
+let f5 = (i: number) => i * i;
// Interfaces are structural, anything that has the properties is compliant with
// the interface
@@ -64,19 +82,19 @@ interface Person {
// Object that implements the "Person" interface
// Can be treated as a Person since it has the name and move properties
-var p: Person = { name: "Bobby", move: () => {} };
+let p: Person = { name: "Bobby", move: () => { } };
// Objects that have the optional property:
-var validPerson: Person = { name: "Bobby", age: 42, move: () => {} };
+let validPerson: Person = { name: "Bobby", age: 42, move: () => { } };
// Is not a person because age is not a number
-var invalidPerson: Person = { name: "Bobby", age: true };
+let invalidPerson: Person = { name: "Bobby", age: true };
// Interfaces can also describe a function type
interface SearchFunc {
(source: string, subString: string): boolean;
}
// Only the parameters' types are important, names are not important.
-var mySearch: SearchFunc;
-mySearch = function(src: string, sub: string) {
+let mySearch: SearchFunc;
+mySearch = function (src: string, sub: string) {
return src.search(sub) != -1;
}
@@ -96,14 +114,21 @@ class Point {
}
// Functions
- dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
+ dist(): number { return Math.sqrt(this.x * this.x + this.y * this.y); }
// Static members
static origin = new Point(0, 0);
}
-var p1 = new Point(10 ,20);
-var p2 = new Point(25); //y will be 0
+// Classes can be explicitly marked as implementing an interface.
+// Any missing properties will then cause an error at compile-time.
+class PointPerson implements Person {
+ name: string
+ move() {}
+}
+
+let p1 = new Point(10, 20);
+let p2 = new Point(25); //y will be 0
// Inheritance
class Point3D extends Point {
@@ -112,8 +137,8 @@ class Point3D extends Point {
}
// Overwrite
- dist() {
- var d = super.dist();
+ dist(): number {
+ let d = super.dist();
return Math.sqrt(d * d + this.z * this.z);
}
}
@@ -129,12 +154,12 @@ module Geometry {
}
}
-var s1 = new Geometry.Square(5);
+let s1 = new Geometry.Square(5);
// Local alias for referencing a module
import G = Geometry;
-var s2 = new G.Square(10);
+let s2 = new G.Square(10);
// Generics
// Classes
@@ -150,23 +175,107 @@ interface Pair<T> {
}
// And functions
-var pairToTuple = function<T>(p: Pair<T>) {
+let pairToTuple = function <T>(p: Pair<T>) {
return new Tuple(p.item1, p.item2);
};
-var tuple = pairToTuple({ item1:"hello", item2:"world"});
+let tuple = pairToTuple({ item1: "hello", item2: "world" });
// Including references to a definition file:
/// <reference path="jquery.d.ts" />
// Template Strings (strings that use backticks)
// String Interpolation with Template Strings
-var name = 'Tyrone';
-var greeting = `Hi ${name}, how are you?`
+let name = 'Tyrone';
+let greeting = `Hi ${name}, how are you?`
// Multiline Strings with Template Strings
-var multiline = `This is an example
+let multiline = `This is an example
of a multiline string`;
+// READONLY: New Feature in TypeScript 3.1
+interface Person {
+ readonly name: string;
+ readonly age: number;
+}
+
+var p1: Person = { name: "Tyrone", age: 42 };
+p1.age = 25; // Error, p1.age is read-only
+
+var p2 = { name: "John", age: 60 };
+var p3: Person = p2; // Ok, read-only alias for p2
+p3.age = 35; // Error, p3.age is read-only
+p2.age = 45; // Ok, but also changes p3.age because of aliasing
+
+class Car {
+ readonly make: string;
+ readonly model: string;
+ readonly year = 2018;
+
+ constructor() {
+ this.make = "Unknown Make"; // Assignment permitted in constructor
+ this.model = "Unknown Model"; // Assignment permitted in constructor
+ }
+}
+
+let numbers: Array<number> = [0, 1, 2, 3, 4];
+let moreNumbers: ReadonlyArray<number> = numbers;
+moreNumbers[5] = 5; // Error, elements are read-only
+moreNumbers.push(5); // Error, no push method (because it mutates array)
+moreNumbers.length = 3; // Error, length is read-only
+numbers = moreNumbers; // Error, mutating methods are missing
+
+// Tagged Union Types for modelling state that can be in one of many shapes
+type State =
+ | { type: "loading" }
+ | { type: "success", value: number }
+ | { type: "error", message: string };
+
+declare const state: State;
+if (state.type === "success") {
+ console.log(state.value);
+} else if (state.type === "error") {
+ console.error(state.message);
+}
+
+// Iterators and Generators
+
+// for..of statement
+// iterate over the list of values on the object being iterated
+let arrayOfAnyType = [1, "string", false];
+for (const val of arrayOfAnyType) {
+ console.log(val); // 1, "string", false
+}
+
+let list = [4, 5, 6];
+for (const i of list) {
+ console.log(i); // 4, 5, 6
+}
+
+// for..in statement
+// iterate over the list of keys on the object being iterated
+for (const i in list) {
+ console.log(i); // 0, 1, 2
+}
+
+// Type Assertion
+
+let foo = {} // Creating foo as an empty object
+foo.bar = 123 // Error: property 'bar' does not exist on `{}`
+foo.baz = 'hello world' // Error: property 'baz' does not exist on `{}`
+
+// Because the inferred type of foo is `{}` (an object with 0 properties), you
+// are not allowed to add bar and baz to it. However with type assertion,
+// the following will pass:
+
+interface Foo {
+ bar: number;
+ baz: string;
+}
+
+let foo = {} as Foo; // Type assertion here
+foo.bar = 123;
+foo.baz = 'hello world'
+
```
## Further Reading
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/uk-ua/cypher-ua.html.markdown b/uk-ua/cypher-ua.html.markdown
new file mode 100644
index 00000000..0911793b
--- /dev/null
+++ b/uk-ua/cypher-ua.html.markdown
@@ -0,0 +1,254 @@
+---
+language: cypher
+filename: LearnCypher-ua.cql
+contributors:
+ - ["Théo Gauchoux", "https://github.com/TheoGauchoux"]
+translators:
+ - ["AstiaSun", "https://github.com/AstiaSun"]
+lang: uk-ua
+---
+
+Cypher - це мова запитів Neo4j для спрощення роботи з графами. Вона повторює синтаксис SQL та перемішує його з таким собі ascii стилем для відображення структури графа.
+Цей навчальний матеріал передбачає, що ви вже знайомі із концепцією графів, зобрема що таке вершини та зв'язки між ними.
+
+[Деталі тут](https://neo4j.com/developer/cypher-query-language/)
+
+
+Вершини
+---
+
+**Відображує запис у графі.**
+
+`()`
+Таким чином у запиті позначається пуста *вершина*. Використовується зазвичай для того, щоб позначити, що вона є, проте це не так вже й важливо для запиту.
+
+`(n)`
+Це вершина, яка має назву **n**, до неї можна повторно звертатись у запиті. Звернення до вершини **n** починається з нижнього підкреслення та використовує camelCase (верблюжий регіст).
+
+`(p:Person)`
+Можна також додати *ярлик* до вершини, в данному випадку - **Person**. Це як тип / клас / категорія. Назва *ярлика* починається з великої літери та використовує верблюжу нотацію.
+
+`(p:Person:Manager)`
+Вершина може мати кілька *ярликів*.
+
+`(p:Person {name : 'Théo Gauchoux', age : 22})`
+Вершина також може мати різні *властивості*, в данному випадку - **name** та **age**. Також мають починатися з великої літери та використовувати верблюжу нотацію.
+
+Наступні типи дозволяється використовувати у властивостях:
+
+ - Чиселиний
+ - Булевий
+ - Рядок
+ - Списки попередніх примітивних типів
+
+*Увага! В Cypher не існує типу, що відображає час. Замість нього можна використовувати рядок із визначеним шаблоном або чисельне відображення певної дати.*
+
+`p.name`
+За допомогою крапки можна звернутись до властивості вершини.
+
+
+Зв'язки (або ребра)
+---
+
+**Сполучають дві вершини**
+
+`[:KNOWS]`
+Це *зв'язок* з *ярликом* **KNOWS**. Це такий же самий *ярлик* як і у вершини. Починається з великої літери та використовує ВЕРХНІЙ\_РЕГІСТР\_ІЗ\_ЗМІЇНОЮ\_НОТАЦІЄЮ.
+
+`[k:KNOWS]`
+Це той же самий *зв'язок*, до якого можна звертатись через змінну **k**. Можна подалі використовувати у запиті, хоч це і не обов'язково.
+
+`[k:KNOWS {since:2017}]`
+Той же *зв'язок*, але вже із *властивостями* (як у *вершини*), в данному випадку властивість - це **since**.
+
+`[k:KNOWS*..4]`
+Це структурна інформація, яку використовують *шляхи*, які розглянуті нижче. В данному випадку, **\*..4** говорить: "Сумістити шаблон із зв'язком **k**, що повторюватиметься від одного до чотирьох разів."
+
+
+Шляхи
+---
+
+**Спосіб поєднувати вершини та зв'язки.**
+
+`(a:Person)-[:KNOWS]-(b:Person)`
+Шлях описує, що вершини **a** та **b** знають (knows) один одного.
+
+`(a:Person)-[:MANAGES]->(b:Person)`
+Шлях може бути направленим. Цей описує, що **а** є менеджером **b**.
+
+`(a:Person)-[:KNOWS]-(b:Person)-[:KNOWS]-(c:Person)`
+Можна створювати ланцюги зі зв'язків. Цей шлях описує друга друга (**a** знає **b**, який в свою чергу знає **c**).
+
+`(a:Person)-[:MANAGES]->(b:Person)-[:MANAGES]->(c:Person)`
+Ланцюг, аналогічно, також може бути направленим. Шлях описує, що **a** - бос **b** і супер бос для **c**.
+
+Шаблони, які часто використовуються (з документації Neo4j):
+
+```
+// Друг-мого-друга
+(user)-[:KNOWS]-(friend)-[:KNOWS]-(foaf)
+
+// Найкоротший шлях
+path = shortestPath( (user)-[:KNOWS*..5]-(other) )
+
+// Спільна фільтрація
+(user)-[:PURCHASED]->(product)<-[:PURCHASED]-()-[:PURCHASED]->(otherProduct)
+
+// Навігація по дереву
+(root)<-[:PARENT*]-(leaf:Category)-[:ITEM]->(data:Product)
+
+```
+
+
+Запити на створення
+---
+
+Створити нову вершину:
+```
+CREATE (a:Person {name:"Théo Gauchoux"})
+RETURN a
+```
+*`RETURN` дозволяє повернути результат після виконання запиту. Можна повертати кілька значень, наприклад, `RETURN a, b`.*
+
+Створити новий зв'язок (із двома вершинами):
+```
+CREATE (a:Person)-[k:KNOWS]-(b:Person)
+RETURN a,k,b
+```
+
+Запити на знаходження
+---
+
+Знайти всі вершини:
+```
+MATCH (n)
+RETURN n
+```
+
+Знайти вершини за ярликом:
+```
+MATCH (a:Person)
+RETURN a
+```
+
+Знайти вершини за ярликом та властивістю:
+```
+MATCH (a:Person {name:"Théo Gauchoux"})
+RETURN a
+```
+
+Знайти вершини відповідно до зв'язків (ненаправлених):
+```
+MATCH (a)-[:KNOWS]-(b)
+RETURN a,b
+```
+
+Знайти вершини відповідно до зв'язків (направлених):
+```
+MATCH (a)-[:MANAGES]->(b)
+RETURN a,b
+```
+
+Знайти вершини за допомогою `WHERE`:
+```
+MATCH (p:Person {name:"Théo Gauchoux"})-[s:LIVES_IN]->(city:City)
+WHERE s.since = 2015
+RETURN p,state
+```
+
+Можна використовувати вираз `MATCH WHERE` разом із операцією `CREATE`:
+```
+MATCH (a), (b)
+WHERE a.name = "Jacquie" AND b.name = "Michel"
+CREATE (a)-[:KNOWS]-(b)
+```
+
+
+Запити на оновлення
+---
+
+Оновити окрему властивість вершини:
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+SET p.age = 23
+```
+
+Оновити всі властивості вершини:
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+SET p = {name: "Michel", age: 23}
+```
+
+Додати нову властивіcть до вершини:
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+SET p + = {studies: "IT Engineering"}
+```
+
+Повісити ярлик на вершину:
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+SET p:Internship
+```
+
+
+Запити на видалення
+---
+
+Видалити окрему вершину (пов'язані ребра повинні бути видалені перед цим):
+```
+MATCH (p:Person)-[relationship]-()
+WHERE p.name = "Théo Gauchoux"
+DELETE relationship, p
+```
+
+Видалити властивість певної вершини:
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+REMOVE p.age
+```
+
+*Зверніть увагу, що ключове слово `REMOVE` це не те саме, що й `DELETE`!*
+
+Видалити ярлик певної вершини:
+```
+MATCH (p:Person)
+WHERE p.name = "Théo Gauchoux"
+DELETE p:Person
+```
+
+Видалити всю базу даних:
+```
+MATCH (n)
+OPTIONAL MATCH (n)-[r]-()
+DELETE n, r
+```
+
+*Так, це `rm -rf /` на мові Cypher !*
+
+
+Інші корисні запити
+---
+
+`PROFILE`
+Перед виконанням, показати план виконання запитів.
+
+`COUNT(e)`
+Порахувати елементи (вершини та зв'язки), що відповідають **e**.
+
+`LIMIT x`
+Обмежити результат до x перших результатів.
+
+
+Особливі підказки
+---
+
+- У мові Cypher існують лише однорядкові коментарі, що позначаються двійним слешем : // Коментар
+- Можна виконати скрипт Cypher, збережений у файлі **.cql** прямо в Neo4j (прямо як імпорт). Проте, не можна мати мати кілька виразів в цьому файлі (розділених **;**).
+- Використовуйте командний рядок Neo4j для написання запитів Cypher, це легко і швидко.
+- Cypher планує бути стандартною мовою запитів для всіх графових баз даних (більш відома як **OpenCypher**).
diff --git a/uk-ua/go-ua.html.markdown b/uk-ua/go-ua.html.markdown
new file mode 100644
index 00000000..f980f7b1
--- /dev/null
+++ b/uk-ua/go-ua.html.markdown
@@ -0,0 +1,449 @@
+---
+name: Go
+category: language
+language: Go
+filename: learngo-ua.go
+contributors:
+ - ["Sonia Keys", "https://github.com/soniakeys"]
+ - ["Christopher Bess", "https://github.com/cbess"]
+ - ["Jesse Johnson", "https://github.com/holocronweaver"]
+ - ["Quint Guvernator", "https://github.com/qguv"]
+ - ["Jose Donizetti", "https://github.com/josedonizetti"]
+ - ["Alexej Friesen", "https://github.com/heyalexej"]
+ - ["Clayton Walker", "https://github.com/cwalk"]
+ - ["Leonid Shevtsov", "https://github.com/leonid-shevtsov"]
+translators:
+ - ["AstiaSun", "https://github.com/AstiaSun"]
+lang: uk-ua
+---
+
+Go був створений для того, щоб виконати задачу. Це не останній тренд в теорії мов програмування, а спосіб вирішення реальних проблем.
+
+Він увібрав принципи з імперативних мов зі статичною типізацією.
+Go швидко компілюється та виконується, а його багатопоточність легка для
+вивчення, оскільки багатоядерні CPU стали буденністю. Ця мова програмування успішно використовується у кодах великих продуктів (~100 мільйонів в Google, Inc.)
+
+Go має чудову стандартну бібліотеку та чимале ком'юніті.
+
+```go
+// Однорядковий коментар
+/* Багато-
+ рядковий коментар */
+
+// Кожен файл вихідного коду має починатись із ключового слова package.
+// main - це спеціальна назва, що оголошує виконуваний код, а не бібліотеку.
+package main
+
+// import оголошує бібліотеки, що використовуються в даному файлі.
+import (
+ "fmt" // Пакет стандартної бібліотеки Go.
+ "io/ioutil" // Цей пакет реалізує деякі I/O функції утиліт.
+ m "math" // Бібліотека математичних операцій з локальним псевдонімом m.
+ "net/http" // Так, веб сервер!
+ "os" // Функції операційної системи, такі як робота з файловою системою.
+ "strconv" // Перетворення текстових змінних.
+)
+
+// Оголошення функції.
+// Функція main - особлива. Це вхідна точка для виконуваних програм.
+// Ви можете любити це, або ж ненавидіти, але Go використовує фігурні дужки.
+func main() {
+ // Println виводить рядок в stdout.
+ // Ця функція входить у пакет fmt.
+ fmt.Println("Hello world!")
+
+ // Викликати іншу функцію з цього файлу.
+ beyondHello()
+}
+
+// Аргументи функцій описуються у круглих дужках.
+// Навіть якщо ніякі аргументи не передаються, пусті круглі дужки - обов`язкові.
+func beyondHello() {
+ var x int // Оголошення змінної. Перед використанням змінні обов'язково мають бути оголошені.
+ x = 3 // Присвоєння значення.
+ // "Короткі" оголошення використовують := щоб окреслити тип, оголосити та присвоїти значення.
+ y := 4
+ sum, prod := learnMultiple(x, y) // Функція повертає два значення.
+ fmt.Println("sum:", sum, "prod:", prod) // Просто вивід.
+ learnTypes() // < y хвилин, потрібно вивчити більше!
+}
+
+/* <- багаторядковий коментар
+Функції можуть мати параметри та повертати довільну кількість значень.
+В цьому прикладі `x`, `y` - це аргументи, а `sum`, `prod` - це змінні, що повертаються.
+Зверніть увагу, що `x` та `sum` мають тип `int`.
+*/
+func learnMultiple(x, y int) (sum, prod int) {
+ return x + y, x * y // Повернути два значення.
+}
+
+// Кілька вбудованих типів та літералів.
+func learnTypes() {
+ // Короткі оголошення зазвичай виконують все, що необхідно.
+ str := "Вчи Go!" // рядок (string).
+
+ s2 := `"Необроблений" текст
+може містити переноси рядків.` // Також має тип рядок.
+
+ // Не ASCII символи. Go використовує UTF-8.
+ g := 'Σ' // руничний тип, псевдонім для int32, містить позицію юнікод кода.
+
+ f := 3.14195 // float64, IEEE-754 64-бітне число з плаваючою крапкою.
+ c := 3 + 4i // complex128, комплексні числа, що являють собою два float64.
+
+ // Синтаксис ініціалізації з var.
+ var u uint = 7 // Беззнаковий цілочисельний тип, проте розмір залежить від імплементації, так само як і int.
+ var pi float32 = 22. / 7
+
+ // Синтаксис перетворення типів з коротким оголошенням.
+ n := byte('\n') // Байт - це переіменований uint8.
+
+ // Розмір масива фіксований протягом часу виконання.
+ var a4 [4]int // Масив з 4 чисел, всі проініціалізовані 0.
+ a5 := [...]int{3, 1, 5, 10, 100} // Масив проініціалізованих чисел з фіксованим розміром у
+ // п'ять елементів, що мають значення 3, 1, 5, 10, та 100.
+
+ // Зрізи мають динамічний розмір. Переваги є і у масивів, й у зрізів, проте
+ // останні використовуються частіше.
+ s3 := []int{4, 5, 9} // Порівняйте з a5. Тут немає трьокрапки.
+ s4 := make([]int, 4) // Виділяє пам'ять для зрізу з 4 чисел, проініціалізованих 0.
+ var d2 [][]float64 // Декларація, нічого не виділяється.
+ bs := []byte("a slice") // Синтаксис переведення у інший тип.
+
+ // Оскільки зрізи динамічні, до них можна додавати елементи за необхідністю.
+ // Для цієї операції використовується вбудована функція append().
+ // Перший аргумент - це зріз, до якого додається елемент. Зазвичай
+ // змінна масиву оновлюється на місці, як у прикладі нижче.
+ s := []int{1, 2, 3} // В результаті отримуємо зріз із 3 чисел.
+ s = append(s, 4, 5, 6) // додаємо 3 елементи. Зріз тепер довжини 6.
+ fmt.Println(s) // Оновлений зріз тепер має значення [1 2 3 4 5 6]
+
+ // Щоб об'єднати два зрізи, замість того, щоб проходитись по всім елементам,
+ // можна передати посилання на зріз із трьокрапкою, як у прикладі нижче. Таким чином,
+ // зріз розпакується і його елементи додадуться до зріза s.
+ s = append(s, []int{7, 8, 9}...)
+ fmt.Println(s) // Оновлений зріз тепер дорівнює [1 2 3 4 5 6 7 8 9]
+
+ p, q := learnMemory() // Оголошує змінні p, q, що є вказівниками на числа.
+ fmt.Println(*p, *q) // * іде попереду вказівника. Таким чином, виводяться числа.
+
+ // Асоціативний масив (map) - це динамічно розширюваний тип даних, як хеш
+ // або словник в інших мовах програмування
+ m := map[string]int{"three": 3, "four": 4}
+ m["one"] = 1
+
+ // В Go змінні, які не використовуються, вважаються помилкою.
+ // Нижнє підкреслення дозволяє "використати" змінну, але проігнорувати значення.
+ _, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a5, s4, bs
+ // Зазвичай це використовується, щоб проігнорувати значення, що повертає функція.
+ // Наприклад, в скрипті нашвидкоруч можна проігнорувати помилку, яку повертає
+ // функція os.Create, вважаючи, що файл буде створений за будь-яких умов.
+ file, _ := os.Create("output.txt")
+ fmt.Fprint(file, "Приклад, як відбувається запис у файл.")
+ file.Close()
+
+ // Вивід значень змінних.
+ fmt.Println(s, c, a4, s3, d2, m)
+
+ learnFlowControl() // Рухаємось далі.
+}
+
+// Навідміну від більшості інших мов програмування, функції в Go підтримують
+// іменоване значення, що повертається.
+// Змінні, значення яких повертається функцією, вказуються із зазначенням типу при
+// оголошенні функції. Таким чином, можна з легкістю повернути їхні значення в різних
+// точках коду, не перелічуючи їх після ключового слова return.
+func learnNamedReturns(x, y int) (z int) {
+ z = x * y
+ return // z не потрібно вказувати, при оголошенні описано змінну для повернення.
+}
+
+// Go використовує сміттєзбірник. В ньому використовуються вказівники, проте немає
+// операцій з вказівниками. Можлива помилка при використовуванні вказівника nil, але не
+// при збільшенні значення вказівника (перехід по адресам пам'яті).
+func learnMemory() (p, q *int) {
+ // Іменовані змінні, що повертаються, p та q, мають тип вказівника на чисельне значення.
+ p = new(int) // Вбудована функція виділяє нову пам'ять.
+ // Виділена адреса пам'яті чисельного типу int ініціалізовується 0, p більше не nil.
+ s := make([]int, 20) // Виділити пам'ять для 20 чисел у вигляді суцільного блоку в пам'яті.
+ s[3] = 7 // Присвоїти значення одному з них.
+ r := -2 // Оголосити нову локальну змінну.
+ return &s[3], &r // Оператор & повертає адресу в пам'яті об'єкта.
+}
+
+func expensiveComputation() float64 {
+ return m.Exp(10)
+}
+
+func learnFlowControl() {
+ // if твердження вимагає фігурні дужки, але не вимагає округлих.
+ if true {
+ fmt.Println("Кажу ж")
+ }
+ // Форматування стандартизовано командою командного рядка "go fmt".
+ if false {
+ // Pout.
+ } else {
+ // Gloat.
+ }
+ // Використання перемикача (switch) замість ланцюга if-тверджень.
+ x := 42.0
+ switch x {
+ case 0:
+ case 1:
+ case 42:
+ // Кейси не "провалюються". Натомість, є ключове слово `fallthrough`:
+ // https://github.com/golang/go/wiki/Switch#fall-through (англ)
+ case 43:
+ // Недоступний.
+ default:
+ // Кейс за замовчуванням не обов'язковий.
+ }
+ // Як і if, формат оголошення циклу for не вимагає круглих дужок:
+ // Змінні, оголошені всередині if та for - належать цій області видимості.
+ for x := 0; x < 3; x++ { // ++ - це твердження.
+ fmt.Println("iteration", x)
+ }
+ // Тут x == 42.
+
+ // For - це єдиний цикл в Go, проте він має кілька різних форм.
+ for { // Ініціалізація циклу.
+ break // Упс, помилково зайшли.
+ continue // Недоступне твердження.
+ }
+
+ // Можна використовувати діапазони, зрізи, рядки, асоціативні масиви, або ж
+ // канал для ітерації в циклі. Діапазон (range) повертає один (канал) або два
+ // значення (масив, зріз, рядок та асоціативний масив).
+ for key, value := range map[string]int{"one": 1, "two": 2, "three": 3} {
+ // для кожної пари в асоціативному масиві, надрукувати ключ та значення
+ fmt.Printf("key=%s, value=%d\n", key, value)
+ }
+ // якщо потрібне тільки значення, можна застосувати нижнє підкреслення як ключ
+ for _, name := range []string{"Bob", "Bill", "Joe"} {
+ fmt.Printf("Hello, %s\n", name)
+ }
+
+ // так само, як і з циклом for, оператор := в розгалуженні означає оголосити
+ // локальну змінну в області видимості if та присвоїти значення. Далі
+ // значення змінної проходить перевірку y > x.
+ if y := expensiveComputation(); y > x {
+ x = y
+ }
+ // Літерали функцій - це замикання
+ xBig := func() bool {
+ return x > 10000 // Посилання на x, що був оголошений раніше, перед switch.
+ }
+ x = 99999
+ fmt.Println("xBig:", xBig()) // true
+ x = 1.3e3 // Тобто, тепер x == 1300
+ fmt.Println("xBig:", xBig()) // false тепер.
+
+ // Функція може бути оголошена та викликана в одному рядку, поводячи себе
+ // як аргумент функції, але за наступних умов:
+ // 1) літерал функції негайно викликається за допомогою ()
+ // 2) тип значення, що повертається, точно відповідає очікуваному типу аргументу
+ fmt.Println("Add + double two numbers: ",
+ func(a, b int) int {
+ return (a + b) * 2
+ }(10, 2)) // Викликаємо з аргументами 10 та 2
+ // => Додати + подвоїти два числа: 24
+
+ // Коли вам це знадобиться, ви полюбите це
+ goto love
+love:
+
+ learnFunctionFactory() // функція, що повертає функцію - це весело(3)(3)
+ learnDefer() // Швидкий обхід до важливого ключового слова.
+ learnInterfaces() // Тут на вас чекає крута штука!
+}
+
+func learnFunctionFactory() {
+ // Два наступних твердження роблять однакові дії, але другий приклад частіше
+ // застосовується
+ fmt.Println(sentenceFactory("summer")("A beautiful", "day!"))
+
+ d := sentenceFactory("summer")
+ fmt.Println(d("A beautiful", "day!"))
+ fmt.Println(d("A lazy", "afternoon!"))
+}
+
+// Декоратори звична річ для багатьох мов програмування. В Go їх можна реалізувати
+// за допомогою літералів функцій, що приймають аргументи.
+func sentenceFactory(mystring string) func(before, after string) string {
+ return func(before, after string) string {
+ return fmt.Sprintf("%s %s %s", before, mystring, after) // новий рядок
+ }
+}
+
+func learnDefer() (ok bool) {
+ // твердження defer змушує функцію посилатись на список. Список
+ // збережених викликів виконується ПІСЛЯ того, як оточуюча функція закінчує
+ // виконання.
+ defer fmt.Println("відкладені твердження виконуються у зворотньому порядку (LIFO).")
+ defer fmt.Println("\nЦей рядок надрукується першим, тому що")
+ // Відкладення зазвичай використовується для того, щоб закрити файл. Таким чином,
+ // функція, що закриває файл, залишається близькою до функції, що відкриває файл.
+ return true
+}
+
+// Оголошує Stringer як тип інтерфейсу з одним методом, String.
+type Stringer interface {
+ String() string
+}
+
+// Оголошує pair як структуру з двома полями, цілими числами x та y.
+type pair struct {
+ x, y int
+}
+
+// Оголошує метод для типу pair. pair тепер реалізує Stringer, оскільки pair оголосив
+// всі методи в цьому інтерфейсі.
+func (p pair) String() string { // p тепер називається "приймачем"
+ // Sprintf - ще одна функція з пакету fmt.
+ // Крапка використовується, щоб звернутись до полів об'єкту p.
+ return fmt.Sprintf("(%d, %d)", p.x, p.y)
+}
+
+func learnInterfaces() {
+ // Синтаксис з використанням фігурних дужок називається "літералом структури".
+ // Він застосовується до ініціалізованої структури. Оператор := оголошує
+ // та ініціалізує p цією структурою.
+ p := pair{3, 4}
+ fmt.Println(p.String()) // Викликає метод String об'єкта p типу pair.
+ var i Stringer // Оголошує і інтерфейсного типу Stringer.
+ i = p // Допустиме, оскільки pair реалізує Stringer
+ // Викликає метод String об'єкта і, що має тип Stringer. Виводить те ж саме, що й
+ // аналогічний метод вище.
+ fmt.Println(i.String())
+
+ // Функції з бібліотеки fmt викликають метод String, щоб запросити у об'єкта
+ // своє представлення, яке можна надрукувати.
+ fmt.Println(p) // Виводить те ж саме, що й раніше.
+ fmt.Println(i) // Виводить те ж саме, що й раніше.
+
+ learnVariadicParams("great", "learning", "here!")
+}
+
+// Кількість аргументів функції може бути змінною.
+func learnVariadicParams(myStrings ...interface{}) {
+ // Пройтись по значенням всіх аргументів.
+ // _ - це ігнорування порядкового номеру аргумента в масиві.
+ for _, param := range myStrings {
+ fmt.Println("param:", param)
+ }
+
+ // Передати значення аргументів як параметр змінної величини.
+ fmt.Println("params:", fmt.Sprintln(myStrings...))
+
+ learnErrorHandling()
+}
+
+func learnErrorHandling() {
+ // Ідіома ", ok"використовується, щоб перевірити виконання команди без помилок.
+ m := map[int]string{3: "three", 4: "four"}
+ if x, ok := m[1]; !ok { // ok буде мати значення false, тому що 1 не знаходиться
+ // в асоціативному масиві.
+ fmt.Println("немає таких")
+ } else {
+ fmt.Print(x) // x буде мати значення 1, якщо 1 знаходиться в m.
+ }
+ // Значення помилки повідомляє не тільки, що все добре, але й може розповісти
+ // більше про проблему.
+ if _, err := strconv.Atoi("non-int"); err != nil { // _ ігнорує значення
+ // виводить помилку 'strconv.ParseInt: parsing "non-int": invalid syntax'
+ fmt.Println(err)
+ }
+ // Ми розглянемо інтерфейси дещо пізніше. А поки, розглянемо багатопоточність.
+ learnConcurrency()
+}
+
+// Канал с - це потокозохищений об'єкт для спілкування між потоками.
+func inc(i int, c chan int) {
+ c <- i + 1 // Оператор <- виконує операцію "надіслати",якщо змінна каналу
+ // знаходиться зліва від нього.
+}
+
+// inc виконує збільшення значення на 1. Ми використаємо його, щоб збільшувати
+// числа рівночасно.
+func learnConcurrency() {
+ // вже знайома функція make, яка раніше використовувалась для виділення пам'яті,
+ // тут використовується для створення каналу. Make виділяє пам'ять та ініціалізує
+ // зрізи, асоційовані масиви та канали. Новостворений канал буде передавати
+ // цілочисельні значення.
+ c := make(chan int)
+ // Запустити три одночасні ґорутини. Числа будуть збільшуватись рівночасно, імовірно
+ // паралельно якщо пристрій здатний до цього та правильно сконфігурований.
+ // Всі три ґорутини надсилають значення в один канал.
+ go inc(0, c) // Твердження go запускає нову ґорутину.
+ go inc(10, c)
+ go inc(-805, c)
+ // Читаємо три результати з каналу та друкуємо їх.
+ // Порядок результатів - невідомий!
+ fmt.Println(<-c, <-c, <-c) // якщо канал знаходиться справа від оператора <-,
+ // він виконує функцію "приймача".
+
+ cs := make(chan string) // Ще один канал, який примає рядки.
+ ccs := make(chan chan string) // Канал каналів рядків.
+ go func() { c <- 84 }() // Запустимо нову ґорутину, щоб надіслати значення в канал с.
+ go func() { cs <- "wordy" }() // Надсилаємо "wordy" в канал cs.
+ // Ключове слово select має синтаксис, подібний до switch, проте кожен кейс
+ // включає в себе операцію з каналом. Він обирає довільний кейс з наявних, які готові
+ // комунікувати (передавати дані).
+ select {
+ case i := <-c: // Отримане значення може бути присвоєно змінній,
+ fmt.Printf("it's a %T", i)
+ case <-cs: // або значення може бути проігнороване.
+ fmt.Println("it's a string")
+ case <-ccs: // Пустий канал, не готовий комунікувати.
+ fmt.Println("Не відбудеться.")
+ }
+ // На цьому етапі, значення було прочитане або з с або з cs. Одна з двох
+ // ґорутин завершилась, але інша все ще заблокована.
+
+ learnWebProgramming() // Go вміє й у веб. Так, ти хочеш зробити це.
+}
+
+// Лиш одна функція з пакету http запускає веб сервер.
+func learnWebProgramming() {
+
+ // перший аргумент ListenAndServe - це TCP адреса, який сервер буде слухати.
+ // Другий аргумент - це інтерфейс, а точніше http.Handler.
+ go func() {
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // не ігноруйте помилки
+ }()
+
+ requestServer()
+}
+
+// pair матиме тип http.Handler, якщо реалізувати один його метод, ServeHTTP.
+func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ // Відповідати на запити можна методом, що належить http.ResponseWriter.
+ w.Write([]byte("Ти вивчив Go за Y хвилин!"))
+}
+
+func requestServer() {
+ resp, err := http.Get("http://localhost:8080")
+ fmt.Println(err)
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ fmt.Printf("\nWebserver said: `%s`", string(body))
+}
+```
+
+## Подальше вивчення
+
+Основним джерелом всієї інформації про Go залишається [офіційна веб-сторінка](http://golang.org/). Там можна знайти уроки, інтерактивно пограти та багато про що почитати.
+Окрім туру, у [документації](https://golang.org/doc/) міститься інформація як писати чистий та ефективний код на Go, документація пакетів та окремих команд, а також історія релізів.
+
+Надзвичайно рекомендується ознайомитись із визначенням мови. Вона легко читається та на диво коротка (в порівнянні з іншими сучасними мовами).
+
+Можна погратись з кодом вище на [Go playground](https://play.golang.org/p/tnWMjr16Mm). Спробуй змінити його та запустити із свого браузера. Поміть, що можна використовувати [https://play.golang.org](https://play.golang.org) як [REPL](https://uk.wikipedia.org/wiki/REPL) до тестів та коду в твоєму браузері, без встановлення Go.
+
+В списку для прочитання новачкам в Go - [вихідний код стандартної бібліотеки](http://golang.org/src/pkg/). Код всеосяжно задокоментований, тому є найкращим прикладом з боку зручного для прочитання та швидкості розуміння коду на цій мові програмування. Приведений стиль та ідіоми Go.
+Крім того, можна просто натиснути на назву функції в [документації](http://golang.org/pkg/), щоб перейти до її реалізації.
+
+Іншим прекрасним посиланням для вивчення Go є [Go by example](https://gobyexample.com/).
+
+Go Mobile додає підтримку мобільних платформ (Android та iOS). Можна написати нативний код на Go для мобільних застосунків або написати бібліотеку, що міститиме прив'язки (bindings) з пакету Go, які можуть бути викликані з Java (Android) та Objective-C (iOS). Деталі можна дізнатись на [веб-сторінці Go Mobile](https://github.com/golang/go/wiki/Mobile).
diff --git a/uk-ua/java-ua.html.markdown b/uk-ua/java-ua.html.markdown
index 1ea30f3d..40d56988 100644
--- a/uk-ua/java-ua.html.markdown
+++ b/uk-ua/java-ua.html.markdown
@@ -1,5 +1,6 @@
---
language: java
+filename: LearnJava-ua.java
contributors:
- ["Jake Prather", "http://github.com/JakeHP"]
- ["Jakukyo Friel", "http://weakish.github.io"]
@@ -11,8 +12,8 @@ contributors:
translators:
- ["Oleksandr Tatarchuk", "https://github.com/tatarchuk"]
- ["Andre Polykanine", "https://github.com/Oire"]
-filename: LearnJavaUa.java
lang: uk-ua
+
---
Java є об’єктно-орієнтованою мовою програмування загального призначення з підтримкою паралельного програмування, яка базується на класах.
@@ -29,7 +30,7 @@ JavaDoc-коментар виглядає так. Використовуєтьс
// Імпорт класу ArrayList з пакета java.util
import java.util.ArrayList;
-// Імпорт усіх класів з пакета java.security
+// Імпорт усіх класів з пакета java.security
import java.security.*;
// Кожний .java файл містить один зовнішній публічний клас, ім’я якого співпадає
@@ -98,13 +99,13 @@ public class LearnJava {
// Примітка: Java не має беззнакових типів.
- // Float — 32-бітне число з рухомою комою одиничної точності за стандартом IEEE 754
+ // Float — 32-бітне число з рухомою комою одиничної точності за стандартом IEEE 754
// 2^-149 <= float <= (2-2^-23) * 2^127
float fooFloat = 234.5f;
// f або F використовується для позначення того, що змінна має тип float;
// інакше трактується як double.
- // Double — 64-бітне число з рухомою комою подвійної точності за стандартом IEEE 754
+ // Double — 64-бітне число з рухомою комою подвійної точності за стандартом IEEE 754
// 2^-1074 <= x <= (2-2^-52) * 2^1023
double fooDouble = 123.4;
@@ -129,13 +130,13 @@ public class LearnJava {
// байтів, операції над ними виконуються функціями, які мають клас BigInteger
//
// BigInteger можна ініціалізувати, використовуючи масив байтів чи рядок.
-
+
BigInteger fooBigInteger = new BigInteger(fooByteArray);
// BigDecimal — Незмінні знакові дробові числа довільної точності
//
- // BigDecimal складається з двох частин: цілого числа довільної точності
+ // BigDecimal складається з двох частин: цілого числа довільної точності
// з немасштабованим значенням та 32-бітного масштабованого цілого числа
//
// BigDecimal дозволяє розробникам контролювати десяткове округлення.
@@ -146,10 +147,10 @@ public class LearnJava {
// чи немасштабованим значенням (BigInteger) і масштабованим значенням (int).
BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt);
-
+
// Для дотримання заданої точності рекомендується використовувати
- // конструктор, який приймає String
-
+ // конструктор, який приймає String
+
BigDecimal tenCents = new BigDecimal("0.1");
@@ -294,7 +295,7 @@ public class LearnJava {
// Виконається 10 разів, fooFor 0->9
}
System.out.println("Значення fooFor: " + fooFor);
-
+
// Вихід із вкладеного циклу через мітку
outer:
for (int i = 0; i < 10; i++) {
@@ -305,7 +306,7 @@ public class LearnJava {
}
}
}
-
+
// Цикл For Each
// Призначений для перебору масивів та колекцій
int[] fooList = {1, 2, 3, 4, 5, 6, 7, 8, 9};
@@ -317,7 +318,7 @@ public class LearnJava {
// Оператор вибору Switch Case
// Оператор вибору працює з типами даних byte, short, char, int.
- // Також працює з переліками Enum,
+ // Також працює з переліками Enum,
// класом String та класами-обгортками примітивних типів:
// Character, Byte, Short та Integer.
int month = 3;
@@ -333,7 +334,7 @@ public class LearnJava {
break;
}
System.out.println("Результат Switch Case: " + monthString);
-
+
// Починаючи з Java 7 і далі, вибір рядкових змінних здійснюється так:
String myAnswer = "можливо";
switch(myAnswer) {
@@ -397,7 +398,7 @@ public class LearnJava {
// toString повертає рядкове представлення об’єкту.
System.out.println("Інформація про об’єкт trek: " + trek.toString());
-
+
// У Java немає синтаксису для явного створення статичних колекцій.
// Це можна зробити так:
@@ -553,7 +554,7 @@ public interface Digestible {
// Можна створити клас, що реалізує обидва інтерфейси.
public class Fruit implements Edible, Digestible {
-
+
@Override
public void eat() {
// ...
@@ -591,7 +592,7 @@ public class ExampleClass extends ExampleClassParent implements InterfaceOne,
// Позначення класу як абстрактного означає, що оголошені у ньому методи мають
// бути реалізовані у дочірніх класах. Подібно до інтерфейсів, не можна створити екземпляри
// абстракних класів, але їх можна успадковувати. Нащадок зобов’язаний реалізувати всі абстрактні
-// методи. на відміну від інтерфейсів, абстрактні класи можуть мати як визначені,
+// методи. На відміну від інтерфейсів, абстрактні класи можуть мати як визначені,
// так і абстрактні методи. Методи в інтерфейсах не мають тіла,
// за винятком статичних методів, а змінні неявно мають модифікатор final, на відміну від
// абстрактного класу. Абстрактні класи МОЖУТЬ мати метод «main».
@@ -693,41 +694,41 @@ public abstract class Mammal()
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
- THURSDAY, FRIDAY, SATURDAY
+ THURSDAY, FRIDAY, SATURDAY
}
// Перелік Day можна використовувати так:
public class EnumTest {
-
+
// Змінна того же типу, що й перелік
Day day;
-
+
public EnumTest(Day day) {
this.day = day;
}
-
+
public void tellItLikeItIs() {
switch (day) {
case MONDAY:
- System.out.println("Понеділкі важкі.");
+ System.out.println("Понеділки важкі.");
break;
-
+
case FRIDAY:
System.out.println("П’ятниці краще.");
break;
-
- case SATURDAY:
+
+ case SATURDAY:
case SUNDAY:
System.out.println("Вихідні найліпші.");
break;
-
+
default:
System.out.println("Середина тижня так собі.");
break;
}
}
-
+
public static void main(String[] args) {
EnumTest firstDay = new EnumTest(Day.MONDAY);
firstDay.tellItLikeItIs(); // => Понеділки важкі.
@@ -736,7 +737,7 @@ public class EnumTest {
}
}
-// Переліки набагато потужніші, ніж тут показано.
+// Переліки набагато потужніші, ніж тут показано.
// Тіло переліків може містити методи та інші змінні.
// Дивіться більше тут: https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
diff --git a/uk-ua/javascript-ua.html.markdown b/uk-ua/javascript-ua.html.markdown
index ac6a2bde..2f17f586 100644
--- a/uk-ua/javascript-ua.html.markdown
+++ b/uk-ua/javascript-ua.html.markdown
@@ -1,7 +1,7 @@
---
language: javascript
contributors:
- - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Leigh Brenecki", "https://leigh.net.au"]
- ["Ariel Krakowski", "http://www.learneroo.com"]
- ["clearsense", "https://github.com/clearsense"]
filename: javascript-uk.js
@@ -17,7 +17,7 @@ JavaScript було створено в 1995 році Бренданом Айк
вбудована підтримка браузерами призвела до того, що JavaScript став популярніший
за власне Java.
-Зараз JavaScript не обмежується тільки веб-браузеорм. Наприклад, Node.js,
+Зараз JavaScript не обмежується тільки веб-браузером. Наприклад, Node.js,
програмна платформа, що дозволяє виконувати JavaScript код з використанням
рушія V8 від браузера Google Chrome, стає все більш і більш популярною.
@@ -45,7 +45,7 @@ doStuff()
3; // = 3
1.5; // = 1.5
-// Деякі прості арифметичні операції працють так, як ми очікуємо.
+// Деякі прості арифметичні операції працюють так, як ми очікуємо.
1 + 1; // = 2
0.1 + 0.2; // = 0.30000000000000004 (а деякі - ні)
8 - 1; // = 7
@@ -106,7 +106,7 @@ null == undefined; // = true
// ... але приведення не виконується при ===
"5" === 5; // = false
-null === undefined; // = false
+null === undefined; // = false
// ... приведення типів може призвести до дивних результатів
13 + !0; // 14
@@ -171,7 +171,7 @@ myArray[3] = "світ";
// Об’єкти в JavaScript схожі на словники або асоціативні масиви в інших мовах
var myObj = {key1: "Hello", key2: "World"};
-// Ключі - це рядки, але лапки не обов’язкі, якщо ключ задовольняє
+// Ключі - це рядки, але лапки не обов’язкові, якщо ключ задовольняє
// правилам формування назв змінних. Значення можуть бути будь-яких типів.
var myObj = {myKey: "myValue", "my other key": 4};
@@ -258,7 +258,7 @@ function myFunction(thing) {
return thing.toUpperCase();
}
myFunction("foo"); // = "FOO"
-
+
// Зверніть увагу, що значення яке буде повернено, повинно починатися на тому ж
// рядку, що і ключове слово return, інакше завжди буде повертатися значення undefined
// через автоматичну вставку крапки з комою
@@ -332,7 +332,7 @@ var myObj = {
};
myObj.myFunc(); // = "Hello, world!"
-// Функції, що прикріплені до об’єктів мають доступ до поточного об’єкта за
+// Функції, що прикріплені до об’єктів мають доступ до поточного об’єкта за
// допомогою ключового слова this.
myObj = {
myString: "Hello, world!",
@@ -348,7 +348,7 @@ myObj.myFunc(); // = "Hello, world!"
var myFunc = myObj.myFunc;
myFunc(); // = undefined
-// Функція може бути присвоєна іншому об’єкту. Тоді вона матиме доступ до
+// Функція може бути присвоєна іншому об’єкту. Тоді вона матиме доступ до
// цього об’єкта через this
var myOtherFunc = function() {
return this.myString.toUpperCase();
@@ -371,7 +371,7 @@ Math.min(42, 6, 27); // = 6
Math.min([42, 6, 27]); // = NaN (Ой-ой!)
Math.min.apply(Math, [42, 6, 27]); // = 6
-// Але call і apply — тимчасові. Коли ми хочемо зв’язати функцію і об’єкт
+// Але call і apply — тимчасові. Коли ми хочемо зв’язати функцію і об’єкт
// використовують bind
var boundFunc = anotherFunc.bind(myObj);
boundFunc(" Hello!"); // = "Hello world, Hello!"
@@ -475,7 +475,7 @@ if (Object.create === undefined) { // не перезаписуємо метод
// Створюємо правильний конструктор з правильним прототипом
var Constructor = function(){};
Constructor.prototype = proto;
-
+
return new Constructor();
}
}
diff --git a/uk-ua/kotlin-ua.html.markdown b/uk-ua/kotlin-ua.html.markdown
new file mode 100644
index 00000000..5e79cc48
--- /dev/null
+++ b/uk-ua/kotlin-ua.html.markdown
@@ -0,0 +1,464 @@
+---
+language: kotlin
+filename: LearnKotlin-uk.kt
+lang: uk-ua
+contributors:
+ - ["S Webber", "https://github.com/s-webber"]
+translators:
+ - ["AstiaSun", "https://github.com/AstiaSun"]
+---
+
+Kotlin - це мова програмування зі статичною типізацією для JVM, Android та браузера.
+Вона має 100% сумісність із Java.
+
+[Детальніше](https://kotlinlang.org/)
+
+```kotlin
+// Однорядкові коментарі починаються з //
+/*
+Такий вигляд мають багаторядкові коментарі
+*/
+
+// Ключове слово package працює так само, як і в Java.
+package com.learnxinyminutes.kotlin
+
+/*
+Точкою входу для програм на Kotlin є функція під назвою main.
+Вона приймає масив із аргументів, що були передані через командний рядок.
+Починаючи з Kotlin 1.3, функція main може бути оголошена без параметрів взагалі.
+*/
+fun main(args: Array<String>) {
+ /*
+ Оголошення змінних відбувається за допомогою ключових слів var або val.
+ Відмінність між ними полягає в тому, що значення змінних, оголошених через
+ val, не можна змінювати. Водночас, змінній "var" можна переприсвоїти нове
+ значення в подальшому.
+ */
+ 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)
+
+ /*
+ Необроблений рядок розмежовується за допомогою потрійних лапок (""").
+ Необроблені рядки можуть містити переніс рядка (не спеціальний символ \n) та
+ будь-які інші символи.
+ */
+ val fooRawString = """
+fun helloWorld(val name : String) {
+ println("Hello, world!")
+}
+"""
+ println(fooRawString)
+
+ /*
+ Рядки можуть містити шаблонні вирази.
+ Шаблонний вираз починається із символа доллара "$".
+ */
+ val fooTemplateString = "$fooString has ${fooString.length} characters"
+ println(fooTemplateString) // => My String Is Here! has 18 characters
+
+ /*
+ Щоб змінна могла мати значення null, потрібно це додатково вказати.
+ Для цього після оголошеного типу змінної додається спеціальний символ "?".
+ Отримати значення такої змінної можна використавши оператор "?.".
+ Оператор "?:" застосовується, щоб оголосити альтернативне значення змінної
+ у випадку, якщо вона буде рівна 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() // => Argument has 0 elements
+ varargExample(1) // => Argument has 1 elements
+ varargExample(1, 2, 3) // => Argument has 3 elements
+
+ /*
+ Коли функція складається з одного виразу, фігурні дужки не є обов'язковими.
+ Тіло функції вказується після оператора "=".
+ */
+ 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)
+ // Методи класу викликаються через крапку.
+ println(fooExampleClass.memberFunction(4)) // => 11
+ /*
+ Якщо функція була позначена ключовим словом infix, тоді її можна викликати через
+ інфіксну нотацію.
+ */
+ 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.
+ data class MutableDataClassExample (var x: Int, var y: Int, var z: Int)
+ val fooMutableData = MutableDataClassExample(7, 4, 9)
+ with (fooMutableData) {
+ x -= 2
+ y += 2
+ z--
+ }
+ println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8)
+
+ /*
+ Список можна створити використовуючи функцію listOf.
+ Список буде незмінним, тобто елементи не можна буде додавати або видаляти.
+ */
+ val fooList = listOf("a", "b", "c")
+ println(fooList.size) // => 3
+ println(fooList.first()) // => a
+ println(fooList.last()) // => c
+ // доступ до елементів здійснюється через їхні порядковий номер.
+ println(fooList[1]) // => b
+
+ // Змінні списки можна створити використовуючи функцію mutableListOf.
+ val fooMutableList = mutableListOf("a", "b", "c")
+ fooMutableList.add("d")
+ println(fooMutableList.last()) // => d
+ println(fooMutableList.size) // => 4
+
+ // Функція 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)
+ // Доступ до значень в асоціативних масивах здійснюється через їхні ключі.
+ println(fooMap["a"]) // => 8
+
+ /*
+ Послідовності представлені як колекції лінивих обчислень. Функція generateSequence
+ створює послідовність.
+ */
+ 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 має функції вищого порядку для роботи з колекціями.
+ 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. Якщо перевірка проходить
+ успішно, тоді можна використовувати об'єкт як данний тип не приводячи до нього
+ додатково.
+ */
+ fun smartCastExample(x: Any) : Boolean {
+ if (x is Boolean) {
+ // x тепер має тип Boolean
+ return x
+ } else if (x is Int) {
+ // x тепер має тип Int
+ return x > 0
+ } else if (x is String) {
+ // x тепер має тип 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
+
+ // Smartcast (розумне приведення) також працює з блоком when
+ fun smartCastWhenExample(x: Any) = when (x) {
+ is Boolean -> x
+ is Int -> x > 0
+ is String -> x.isNotEmpty()
+ else -> false
+ }
+
+ /*
+ Розширення - це ще один спосіб розширити функціонал класу.
+ Подібні методи розширення реалізовані у С#.
+ */
+ fun String.remove(c: Char): String {
+ return this.filter {it != c}
+ }
+ println("Hello, world!".remove('l')) // => Heo, word!
+}
+
+// Класи перелічення також подібні до тих типів, що і в Java.
+enum class EnumExample {
+ A, B, C // Константи перелічення розділені комами.
+}
+fun printEnum() = println(EnumExample.A) // => A
+
+// Оскільки кожне перелічення - це об'єкт класу enum, воно може бути
+// проініціалізоване наступним чином:
+enum class EnumExample(val value: Int) {
+ A(value = 1),
+ B(value = 2),
+ C(value = 3)
+}
+fun printProperty() = println(EnumExample.A.value) // => 1
+
+// Кожне перелічення має властивості, які дозволяють отримати його ім'я
+// та порядок (позицію) в класі enum:
+fun printName() = println(EnumExample.A.name) // => A
+fun printPosition() = println(EnumExample.A.ordinal) // => 0
+
+/*
+Ключове слово object можна використати для створення об'єкту сінглтону. Об'єкт не
+можна інстанціювати, проте на його унікальний екземпляр можна посилатись за іменем.
+Подібна можливість є в сінглтон об'єктах у Scala.
+*/
+object ObjectExample {
+ fun hello(): String {
+ return "hello"
+ }
+
+ override fun toString(): String {
+ return "Hello, it's me, ${ObjectExample::class.simpleName}"
+ }
+}
+
+
+fun useSingletonObject() {
+ println(ObjectExample.hello()) // => hello
+ // В Kotlin, "Any" - це корінь ієрархії класів, так само, як і "Object" у Java.
+ val someRef: Any = ObjectExample
+ println(someRef) // => Hello, it's me, ObjectExample
+}
+
+
+/*
+Оператор перевірки на те, що об'єкт не рівний null, (!!) перетворює будь-яке значення в ненульовий тип і кидає виняток, якщо значення рівне null.
+*/
+var b: String? = "abc"
+val l = b!!.length
+
+// Далі - приклади перевизначення методів класу Any в класі-насліднику
+data class Counter(var value: Int) {
+ // перевизначити Counter += Int
+ operator fun plusAssign(increment: Int) {
+ this.value += increment
+ }
+
+ // перевизначити Counter++ та ++Counter
+ operator fun inc() = Counter(value + 1)
+
+ // перевизначити Counter + Counter
+ operator fun plus(other: Counter) = Counter(this.value + other.value)
+
+ // перевизначити Counter * Counter
+ operator fun times(other: Counter) = Counter(this.value * other.value)
+
+ // перевизначити Counter * Int
+ operator fun times(value: Int) = Counter(this.value * value)
+
+ // перевизначити Counter in Counter
+ operator fun contains(other: Counter) = other.value == this.value
+
+ // перевизначити Counter[Int] = Int
+ operator fun set(index: Int, value: Int) {
+ this.value = index + value
+ }
+
+ // перевизначити виклик екземпляру Counter
+ operator fun invoke() = println("The value of the counter is $value")
+
+}
+// Можна також перевизначити оператори через методи розширення.
+// перевизначити -Counter
+operator fun Counter.unaryMinus() = Counter(-this.value)
+
+fun operatorOverloadingDemo() {
+ var counter1 = Counter(0)
+ var counter2 = Counter(5)
+ counter1 += 7
+ println(counter1) // => Counter(value=7)
+ println(counter1 + counter2) // => Counter(value=12)
+ println(counter1 * counter2) // => Counter(value=35)
+ println(counter2 * 2) // => Counter(value=10)
+ println(counter1 in Counter(5)) // => false
+ println(counter1 in Counter(7)) // => true
+ counter1[26] = 10
+ println(counter1) // => Counter(value=36)
+ counter1() // => The value of the counter is 36
+ println(-counter2) // => Counter(value=-5)
+}
+```
+
+### Подальше вивчення
+
+* [Уроки Kotlin](https://kotlinlang.org/docs/tutorials/)
+* [Спробувати попрацювати з Kotlin в браузері](https://play.kotlinlang.org/)
+* [Список корисних посилань](http://kotlin.link/)
diff --git a/uk-ua/mips-ua.html.markdown b/uk-ua/mips-ua.html.markdown
new file mode 100644
index 00000000..8d4517fe
--- /dev/null
+++ b/uk-ua/mips-ua.html.markdown
@@ -0,0 +1,366 @@
+---
+language: "MIPS Assembly"
+filename: MIPS.asm
+contributors:
+ - ["Stanley Lim", "https://github.com/Spiderpig86"]
+translators:
+ - ["AstiaSun", "https://github.com/AstiaSun"]
+lang: uk-ua
+---
+
+Мова ассемблера MIPS (англ. Microprocessor without Interlocked Pipeline Stages) була написана для роботи з мікропроцесорами MIPS, парадигма яких була описана в 1981 році [Джоном Геннессі](https://uk.wikipedia.org/wiki/Джон_Лерой_Геннессі). Ці RISC процесори використовуються у таких вбудованих системах, як маршрутизатори та мережеві шлюзи.
+
+[Детальніше](https://en.wikipedia.org/wiki/MIPS_architecture)
+
+```asm
+# Коментарі позначені як'#'
+
+# Всі символи після '#' ігноруються лексичним аналізатором асемблера.
+
+# Зазвичай програми поділяються на .data та .text частини
+
+.data # У цьому розділі дані зберігаються у пам'яті, виділеній в RAM, подібно до змінних
+ # в мовах програмування вищого рівня
+
+ # Змінна оголошується наступним чином: [назва]: .[тип] [значення]
+ # Наприклад:
+ hello_world: .asciiz "Hello World\n" # Оголосити текстову змінну
+ num1: .word 42 # word - це чисельний тип 32-бітного розряду
+
+ arr1: .word 1, 2, 3, 4, 5 # Масив чисел
+ arr2: .byte 'a', 'b' # Масив буквених символів (розмір кожного - 1 байт)
+ buffer: .space 60 # Виділити місце в RAM
+ # (не очищується, тобто не заповнюється 0)
+
+ # Розміри типів даних
+ _byte: .byte 'a' # 1 байт
+ _halfword: .half 53 # 2 байти
+ _word: .word 3 # 4 байти
+ _float: .float 3.14 # 4 байти
+ _double: .double 7.0 # 8 байтів
+
+ .align 2 # Вирівнювання пам'яті даних, де число
+ # показує кількість байтів, вирівнених
+ # у степені 2. (.align 2 означає
+ # чисельне (word) вирівнювання оскільки
+ # 2^2 = 4 байти)
+
+.text # Розділ, що містить інструкції та
+ # логіку програми
+
+.globl _main # Оголошує назву інструкції як
+ # глобальну, тобто, яка є доступною для
+ # всіх інших файлів
+
+ _main: # програми MIPS виконують інструкції
+ # послідовно, тобто першочергово код
+ # буде виконуватись після цієї позначки
+
+ # Виведемо на екран "hello world"
+ la $a0, hello_world # Завантажує адресу тексту у пам'яті
+ li $v0, 4 # Завантажує значення системної
+ # команди (вказуючи тип функціоналу)
+ syscall # Виконує зазначену системну команду
+ # з обраним аргументом ($a0)
+
+ # Регістри (використовуються, щоб тримати дані протягом виконання програми)
+ # $t0 - $t9 # Тимчасові регістри використовуються
+ # для проміжних обчислень всередині
+ # підпрограм (не зберігаються між
+ # викликами функцій)
+
+ # $s0 - $s7 # Збережені регістри, у яких значення
+ # зберігаються між викликами підпрограм.
+ # Зазвичай зберігаються у стеку.
+
+ # $a0 - $a3 # Регістри для передачі аргументів для
+ # підпрограм
+ # $v0 - $v1 # Регістри для значень, що повертаються
+ # від викликаної функції
+
+ # Типи інструкції завантаження / збереження
+ la $t0, label # Скопіювати адресу в пам'яті, де
+ # зберігається значення змінної label
+ # в регістр $t0
+ lw $t0, label # Скопіювати чисельне значення з пам'яті
+ lw $t1, 4($s0) # Скопіювати чисельне значення з адреси
+ # пам'яті регістра зі зміщенням в
+ # 4 байти (адреса + 4)
+ lb $t2, label # Скопіювати буквений символ в частину
+ # нижчого порядку регістра $t2
+ lb $t2, 0($s0) # Скопіювати буквений символ з адреси
+ # в $s0 із зсувом 0
+ # Подібне використання і 'lh' для halfwords
+
+ sw $t0, label # Зберегти чисельне значення в адресу в
+ # пам'яті, що відповідає змінній label
+ sw $t0, 8($s0) # Зберегти чисельне значення в адресу,
+ # що зазначена у $s0, та зі зсувом у 8 байтів
+ # Така ж ідея використання 'sb' та 'sh' для буквених символів та halfwords.
+ # 'sa' не існує
+
+
+### Математичні операції ###
+ _math:
+ # Пам'ятаємо, що попередньо потрібно завантажити дані в пам'ять
+ lw $t0, num # Із розділа з даними
+ li $t0, 5 # Або безпосередньо з константи
+ li $t1, 6
+ add $t2, $t0, $t1 # $t2 = $t0 + $t1
+ sub $t2, $t0, $t1 # $t2 = $t0 - $t1
+ mul $t2, $t0, $t1 # $t2 = $t0 * $t1
+ div $t2, $t0, $t1 # $t2 = $t0 / $t1 (Може не підтримуватись
+ # деякими версіями MARS)
+ div $t0, $t1 # Виконує $t0 / $t1. Отримати частку можна
+ # за допомогою команди 'mflo', остаток - 'mfhi'
+
+ # Бітовий зсув
+ sll $t0, $t0, 2 # Побітовий зсув вліво на 2. Біти вищого порядку
+ # не зберігаються, нищого - заповнюються 0
+ sllv $t0, $t1, $t2 # Зсув вліво зі змінною кількістю у
+ # регістрі
+ srl $t0, $t0, 5 # Побітовий зсув вправо на 5 (не зберігає
+ # біти, біти зліва заповнюються 0)
+ srlv $t0, $t1, $t2 # Зсув вправо зі змінною кількістю у
+ # регістрі
+ sra $t0, $t0, 7 # Побітовий арифметичний зсув вправо
+ # (зберігає біти)
+ srav $t0, $t1, $t2 # Зсув вправо зі змінною кількістю у
+ # регістрі зі збереження значеннь бітів
+
+ # Побітові операції
+ and $t0, $t1, $t2 # Побітове І (AND)
+ andi $t0, $t1, 0xFFF # Побітове І з безпосереднім значенням
+ or $t0, $t1, $t2 # Побітове АБО (OR)
+ ori $t0, $t1, 0xFFF # Побітове АБО з безпосереднім значенням
+ xor $t0, $t1, $t2 # Побітова виключна диз'юнкція (XOR)
+ xori $t0, $t1, 0xFFF # Побітове XOR з безпосереднім значенням
+ nor $t0, $t1, $t2 # Побітова стрілка Пірса (NOR)
+
+## Розгалуження ##
+ _branching:
+ # В основному інструкції розгалуження мають наступну форму:
+ # <instr> <reg1> <reg2> <label>
+ # де label - це назва змінної, в яку ми хочемо перейти, якщо зазначене твердження
+ # правдиве
+
+ beq $t0, $t1, reg_eq # Перейдемо у розгалуження reg_eq
+ # якщо $t0 == $t1, інакше -
+ # виконати наступний рядок
+ bne $t0, $t1, reg_neq # Розгалужується, якщо $t0 != $t1
+ b branch_target # Розгалуження без умови завжди виконується
+ beqz $t0, req_eq_zero # Розгалужується, якщо $t0 == 0
+ bnez $t0, req_neq_zero # Розгалужується, якщо $t0 != 0
+ bgt $t0, $t1, t0_gt_t1 # Розгалужується, якщо $t0 > $t1
+ bge $t0, $t1, t0_gte_t1 # Розгалужується, якщо $t0 >= $t1
+ bgtz $t0, t0_gt0 # Розгалужується, якщо $t0 > 0
+ blt $t0, $t1, t0_gt_t1 # Розгалужується, якщо $t0 < $t1
+ ble $t0, $t1, t0_gte_t1 # Розгалужується, якщо $t0 <= $t1
+ bltz $t0, t0_lt0 # Розгалужується, якщо $t0 < 0
+ slt $s0, $t0, $t1 # Інструкція, що посилає сигнал коли
+ # $t0 < $t1, результат зберігається в $s0
+ # (1 - правдиве твердження)
+
+ # Просте твердження якщо (if)
+ # if (i == j)
+ # f = g + h;
+ # f = f - i;
+
+ # Нехай $s0 = f, $s1 = g, $s2 = h, $s3 = i, $s4 = j
+ bne $s3, $s4, L1 # if (i !=j)
+ add $s0, $s1, $s2 # f = g + h
+
+ L1:
+ sub $s0, $s0, $s3 # f = f - i
+
+ # Нижче наведений приклад знаходження максимального значення з 3 чисел
+ # Пряма трансляція в Java з логіки MIPS:
+ # if (a > b)
+ # if (a > c)
+ # max = a;
+ # else
+ # max = c;
+ # else
+ # max = b;
+ # else
+ # max = c;
+
+ # Нехай $s0 = a, $s1 = b, $s2 = c, $v0 = повернути регістр
+ ble $s0, $s1, a_LTE_b # якщо (a <= b) розгалуження(a_LTE_b)
+ ble $s0, $s2, max_C # якщо (a > b && a <=c) розгалуження(max_C)
+ move $v0, $s1 # інакше [a > b && a > c] max = a
+ j done # Перейти в кінець програми
+
+ a_LTE_b: # Мітка розгалуження, коли a <= b
+ ble $s1, $s2, max_C # якщо (a <= b && b <= c) розгалуження(max_C)
+ move $v0, $s1 # якщо (a <= b && b > c) max = b
+ j done # Перейти в кінець програми
+
+ max_C:
+ move $v0, $s2 # max = c
+
+ done: # Кінець програми
+
+## Цикли ##
+ _loops:
+ # Цикл складається з умови виходу та з інструкції переходу після його завершення
+ li $t0, 0
+ while:
+ bgt $t0, 10, end_while # Коли $t0 менше 10, продовжувати ітерації
+ addi $t0, $t0, 1 # Збільшити значення
+ j while # Перейти на початок циклу
+ end_while:
+
+ # Транспонування 2D матриці
+ # Припустимо, що $a0 зберігає адресу цілочисельної матриці розмірністю 3 x 3
+ li $t0, 0 # Лічильник для i
+ li $t1, 0 # Лічильник для j
+ matrix_row:
+ bgt $t0, 3, matrix_row_end
+
+ matrix_col:
+ bgt $t1, 3, matrix_col_end
+
+ # ...
+
+ addi $t1, $t1, 1 # Збільшити лічильник стовпця (col)
+ matrix_col_end:
+
+ # ...
+
+ addi $t0, $t0, 1
+ matrix_row_end:
+
+## Функції ##
+ _functions:
+ # Функції - це процедури, що викликаються, приймають аргументи та повертають значення
+
+ main: # Програма починається з головної функції
+ jal return_1 # jal збереже поточний ПЦ (програмний центр) в $ra,
+ # а потім перейде до return_1
+
+ # Як передати аргументи?
+ # По-перше, ми маємо передати значення аргументів у регістри аргументів
+ li $a0, 1
+ li $a1, 2
+ jal sum # Тепер ми можемо викликати функцію
+
+ # Як щодо рекурсії?
+ # Тут потрібно дещо більше роботи оскільки ми маємо впевнитись, що ми збережемо
+ # та зчитаємо попередній ПЦ в $ra, оскільки jal автоматично перепише її при виклику
+ li $a0, 3
+ jal fact
+
+ li $v0, 10
+ syscall
+
+ # Ця функція повертає 1
+ return_1:
+ li $v0, 1 # Завантажити val в регіст $v0
+ jr $ra # Повернутись до попереднього ПЦ і продовжити виконання
+
+
+ # Функція з двома аргументами
+ sum:
+ add $v0, $a0, $a1
+ jr $ra # Повернутись
+
+ # Рекурсивна функція, яка знаходить факторіал
+ fact:
+ addi $sp, $sp, -8 # Виділити місце в стеку
+ sw $s0, ($sp) # Зберегти регістр, що містить поточне число
+ sw $ra, 4($sp) # Зберегти попередній ПЦ
+
+ li $v0, 1 # Проініціалізувати значення, що повертатиметься
+ beq $a0, 0, fact_done # Закінчити, якщо параметр 0
+
+ # Інакше, продовжити рекурсію
+ move $s0, $a0 # Скопіювати $a0 в $s0
+ sub $a0, $a0, 1
+ jal fact
+
+ mul $v0, $s0, $v0 # Множення
+
+ fact_done:
+ lw $s0, ($sp)
+ lw $ra, ($sp) # Відновити ПЦ
+ addi $sp, $sp, 8
+
+ jr $ra
+
+## Макроси ##
+ _macros:
+ # Макроси надзвичайно корисні для заміни блоків коду, що повторюються, за допомогою
+ # однієї змінної, для покращення читабельності
+ # Це не заміна функцій.
+ # Вони мають бути оголошені перед використанням
+
+ # Макрос для виведення нових рядків (оскільки операція досить часто виконується)
+ .macro println()
+ la $a0, newline # Значення нового рядка зберігатиметься тут
+ li $v0, 4
+ syscall
+ .end_macro
+
+ println() # Асемблер скопіює цей блок коду сюди
+ # перед тим, як виконувати його
+
+ # Можна передавати параметри у макроси.
+ # Параметри позначаються знаком '%' з довільною назвою
+ .macro print_int(%num)
+ li $v0, 1
+ lw $a0, %num
+ syscall
+ .end_macro
+
+ li $t0, 1
+ print_int($t0)
+
+ # Значення також можна передавати безпосередньо в макроси
+ .macro immediates(%a, %b)
+ add $t0, %a, %b
+ .end_macro
+
+ immediates(3, 5)
+
+ # Одночасно із назвами змінних
+ .macro print(%string)
+ la $a0, %string
+ li $v0, 4
+ syscall
+ .end_macro
+
+ print(hello_world)
+
+## Масиви ##
+.data
+ list: .word 3, 0, 1, 2, 6 # Це масив чисел
+ char_arr: .asciiz "hello" # Це текстовий масив
+ buffer: .space 128 # Виділяє блок пам'яті, що
+ # автоматично не очищується
+ # Ці блоки пам'яті вирівнені
+ # вирівнені поруч один з одним
+
+.text
+ la $s0, list # Завантажити адресу списку
+ li $t0, 0 # Лічильник
+ li $t1, 5 # Довжина списку
+
+ loop:
+ bgt $t0, $t1, end_loop
+
+ lw $a0, ($s0)
+ li $v0, 1
+ syscall # Вивести число
+
+ addi $s0, $s0, 4 # Розмір числа - 4 байти
+ addi $t0, $t0, 1 # Збільшити
+ j loop
+ end_loop:
+
+## Включення ##
+# Потрібно для імпорту сторонніх файлів у програму (насправді, код з цього файлу
+# копіюється та вставляється в місце, де оголошений імпорт)
+.include "somefile.asm"
+
+```
diff --git a/uk-ua/pythonlegacy-ua.html.markdown b/uk-ua/pythonlegacy-ua.html.markdown
new file mode 100644
index 00000000..e2a6d19e
--- /dev/null
+++ b/uk-ua/pythonlegacy-ua.html.markdown
@@ -0,0 +1,818 @@
+---
+language: Python 2 (legacy)
+lang: uk-ua
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+ - ["Amin Bandali", "https://aminb.org"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
+ - ["evuez", "http://github.com/evuez"]
+ - ["asyne", "https://github.com/justblah"]
+ - ["habi", "http://github.com/habi"]
+translators:
+ - ["Oleh Hromiak", "https://github.com/ogroleg"]
+filename: learnpythonlegacy-ua.py
+---
+
+Мову Python створив Гвідо ван Россум на початку 90-х. Наразі це одна з
+найбільш популярних мов. Я закохався у Python завдяки простому і зрозумілому
+синтаксису. Це майже як виконуваний псевдокод.
+
+З вдячністю чекаю ваших відгуків: [@louiedinh](http://twitter.com/louiedinh)
+або louiedinh [at] [поштовий сервіс від Google]
+
+Примітка: Ця стаття стосується Python 2.7, проте має працювати і
+у інших версіях Python 2.x. Python 2.7 підходить до кінця свого терміну,
+його підтримку припинять у 2020, тож наразі краще починати вивчення Python
+з версії 3.x.
+Аби вивчити Python 3.x, звертайтесь до статті по Python 3.
+
+```python
+# Однорядкові коментарі починаються з символу решітки.
+
+""" Текст, що займає декілька рядків,
+ може бути записаний з використанням 3 знаків " і
+ зазвичай використовується у якості
+ вбудованої документації
+"""
+
+####################################################
+## 1. Примітивні типи даних та оператори
+####################################################
+
+# У вас є числа
+3 # => 3
+
+# Математика працює досить передбачувано
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7
+
+# А ось з діленням все трохи складніше. Воно цілочисельне і результат
+# автоматично округлюється у меншу сторону.
+5 / 2 # => 2
+
+# Аби правильно ділити, спершу варто дізнатися про числа
+# з плаваючою комою.
+2.0 # Це число з плаваючою комою
+11.0 / 4.0 # => 2.75 ох... Так набагато краще
+
+# Результат цілочисельного ділення округлюється у меншу сторону
+# як для додатніх, так і для від'ємних чисел.
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # Працює і для чисел з плаваючою комою
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
+
+# Зверніть увагу, що ми також можемо імпортувати модуль для ділення,
+# див. розділ Модулі
+# аби звичне ділення працювало при використанні лише '/'.
+from __future__ import division
+
+11 / 4 # => 2.75 ...звичне ділення
+11 // 4 # => 2 ...цілочисельне ділення
+
+# Залишок від ділення
+7 % 3 # => 1
+
+# Піднесення до степеня
+2 ** 4 # => 16
+
+# Приорітет операцій вказується дужками
+(1 + 3) * 2 # => 8
+
+# Логічні оператори
+# Зверніть увагу: ключові слова «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
+
+# Для заперечення використовується not
+not True # => False
+not False # => True
+
+# Рівність — це ==
+1 == 1 # => True
+2 == 1 # => False
+
+# Нерівність — це !=
+1 != 1 # => False
+2 != 1 # => True
+
+# Ще трохи порівнянь
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# Порівняння можуть бути записані ланцюжком!
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# Рядки позначаються символом " або '
+"Це рядок."
+'Це теж рядок.'
+
+# І рядки також можна додавати!
+"Привіт " + "світ!" # => "Привіт світ!"
+# Рядки можна додавати і без '+'
+"Привіт " "світ!" # => "Привіт світ!"
+
+# ... або множити
+"Привіт" * 3 # => "ПривітПривітПривіт"
+
+# З рядком можна працювати як зі списком символів
+"Це рядок"[0] # => 'Ц'
+
+# Ви можете дізнатися довжину рядка
+len("Це рядок") # => 8
+
+# Символ % використовується для форматування рядків, наприклад:
+"%s можуть бути %s" % ("рядки", "інтерпольовані")
+
+# Новий спосіб форматування рядків — використання методу format.
+# Це бажаний спосіб.
+"{} є {}".format("Це", "заповнювач")
+"{0} можуть бути {1}".format("рядки", "форматовані")
+# Якщо ви не хочете рахувати, то можете скористатися ключовими словами.
+"{name} хоче з'істи {food}".format(name="Боб", food="лазанью")
+
+# None - це об'єкт
+None # => None
+
+# Не використовуйте оператор рівності '=='' для порівняння
+# об'єктів з None. Використовуйте для цього «is»
+"etc" is None # => False
+None is None # => True
+
+# Оператор 'is' перевіряє ідентичність об'єктів. Він не
+# дуже корисний при роботі з примітивними типами, проте
+# незамінний при роботі з об'єктами.
+
+# None, 0 і порожні рядки/списки рівні False.
+# Всі інші значення рівні True
+bool(0) # => False
+bool("") # => False
+
+
+####################################################
+## 2. Змінні та колекції
+####################################################
+
+# В Python є оператор print
+print "Я Python. Приємно познайомитись!" # => Я Python. Приємно познайомитись!
+
+# Отримати дані з консолі просто
+input_string_var = raw_input(
+ "Введіть щось: ") # Повертає дані у вигляді рядка
+input_var = input("Введіть щось: ") # Працює з даними як з кодом на python
+# Застереження: будьте обережні при використанні методу input()
+
+# Оголошувати змінні перед ініціалізацією не потрібно.
+some_var = 5 # За угодою використовується нижній_регістр_з_підкресленнями
+some_var # => 5
+
+# При спробі доступу до неініціалізованої змінної
+# виникне виняткова ситуація.
+# Див. розділ Потік управління, аби дізнатись про винятки більше.
+some_other_var # Помилка в імені
+
+# if може використовуватися як вираз
+# Такий запис еквівалентний тернарному оператору '?:' у мові С
+"yahoo!" if 3 > 2 else 2 # => "yahoo!"
+
+# Списки зберігають послідовності
+li = []
+# Можна одразу створити заповнений список
+other_li = [4, 5, 6]
+
+# Об'єкти додаються у кінець списку за допомогою методу append
+li.append(1) # li тепер дорівнює [1]
+li.append(2) # li тепер дорівнює [1, 2]
+li.append(4) # li тепер дорівнює [1, 2, 4]
+li.append(3) # li тепер дорівнює [1, 2, 4, 3]
+# І видаляються з кінця методом pop
+li.pop() # => повертає 3 і li стає рівним [1, 2, 4]
+# Повернемо елемент назад
+li.append(3) # li тепер знову дорівнює [1, 2, 4, 3]
+
+# Поводьтесь зі списком як зі звичайним масивом
+li[0] # => 1
+# Присвоюйте нові значення вже ініціалізованим індексам за допомогою =
+li[0] = 42
+li[0] # => 42
+li[0] = 1 # Зверніть увагу: повертаємось до попереднього значення
+# Звертаємось до останнього елементу
+li[-1] # => 3
+
+# Спроба вийти за границі масиву призводить до помилки в індексі
+li[4] # помилка в індексі
+
+# Можна звертатися до діапазону, використовуючи так звані зрізи
+# (Для тих, хто любить математику: це називається замкнуто-відкритий інтервал).
+li[1:3] # => [2, 4]
+# Опускаємо початок
+li[2:] # => [4, 3]
+# Опускаємо кінець
+li[:3] # => [1, 2, 4]
+# Вибираємо кожен другий елемент
+li[::2] # => [1, 4]
+# Перевертаємо список
+li[::-1] # => [3, 4, 2, 1]
+# Використовуйте суміш вищеназваного для більш складних зрізів
+# li[початок:кінець:крок]
+
+# Видаляємо довільні елементи зі списку оператором del
+del li[2] # li тепер [1, 2, 3]
+
+# Ви можете додавати списки
+li + other_li # => [1, 2, 3, 4, 5, 6]
+# Зверніть увагу: значення li та other_li при цьому не змінились.
+
+# Поєднувати списки можна за допомогою методу extend
+li.extend(other_li) # Тепер li дорівнює [1, 2, 3, 4, 5, 6]
+
+# Видалити перше входження значення
+li.remove(2) # Тепер li дорівнює [1, 3, 4, 5, 6]
+li.remove(2) # Помилка значення, оскільки у списку li немає 2
+
+# Вставити елемент за вказаним індексом
+li.insert(1, 2) # li знову дорівнює [1, 2, 3, 4, 5, 6]
+
+# Отримати індекс першого знайденого елементу
+li.index(2) # => 1
+li.index(7) # Помилка значення, оскільки у списку li немає 7
+
+# Перевірити елемент на входження у список можна оператором in
+1 in li # => True
+
+# Довжина списку обчислюється за допомогою функції len
+len(li) # => 6
+
+# Кортежі схожі на списки, лише незмінні
+tup = (1, 2, 3)
+tup[0] # => 1
+tup[0] = 3 # Виникає помилка типу
+
+# Все те ж саме можна робити і з кортежами
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# Ви можете розпаковувати кортежі (або списки) у змінні
+a, b, c = (1, 2, 3) # a == 1, b == 2 и c == 3
+d, e, f = 4, 5, 6 # дужки можна опустити
+# Кортежі створюються за замовчуванням, якщо дужки опущено
+g = 4, 5, 6 # => (4, 5, 6)
+# Дивіться, як легко обміняти значення двох змінних
+e, d = d, e # тепер d дорівнює 5, а e дорівнює 4
+
+# Словники містять асоціативні масиви
+empty_dict = {}
+# Ось так описується попередньо заповнений словник
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Значення можна отримати так само, як і зі списку
+filled_dict["one"] # => 1
+
+# Можна отримати всі ключі у виді списку за допомогою методу keys
+filled_dict.keys() # => ["three", "two", "one"]
+# Примітка: збереження порядку ключів у словників не гарантується
+# Ваші результати можуть не співпадати з цими.
+
+# Можна отримати і всі значення у вигляді списку, використовуйте метод values
+filled_dict.values() # => [3, 2, 1]
+# Те ж зауваження щодо порядку ключів діє і тут
+
+# Отримуйте всі пари ключ-значення у вигляді списку кортежів
+# за допомогою "items()"
+filled_dict.items() # => [("one", 1), ("two", 2), ("three", 3)]
+
+# За допомогою оператору in можна перевіряти ключі на входження у словник
+"one" in filled_dict # => True
+1 in filled_dict # => False
+
+# Спроба отримати значення за неіснуючим ключем викине помилку ключа
+filled_dict["four"] # помилка ключа
+
+# Аби уникнути цього, використовуйте метод get()
+filled_dict.get("one") # => 1
+filled_dict.get("four") # => None
+# Метод get також приймає аргумент за замовчуванням, значення якого буде
+# повернуто при відсутності вказаного ключа
+filled_dict.get("one", 4) # => 1
+filled_dict.get("four", 4) # => 4
+# Зверніть увагу, що filled_dict.get("four") все ще => None
+# (get не встановлює значення елементу словника)
+
+# Присвоюйте значення ключам так само, як і в списках
+filled_dict["four"] = 4 # тепер filled_dict["four"] => 4
+
+# Метод setdefault() вставляє пару ключ-значення лише
+# за відсутності такого ключа
+filled_dict.setdefault("five", 5) # filled_dict["five"] повертає 5
+filled_dict.setdefault("five", 6) # filled_dict["five"] все ще повертає 5
+
+
+# Множини містять... ну, загалом, множини
+# (які схожі на списки, проте в них не може бути елементів, які повторюються)
+empty_set = set()
+# Ініціалізація множини набором значень
+some_set = set([1,2,2,3,4]) # some_set тепер дорівнює set([1, 2, 3, 4])
+
+# Порядок не гарантовано, хоча інколи множини виглядають відсортованими
+another_set = set([4, 3, 2, 2, 1]) # another_set тепер set([1, 2, 3, 4])
+
+# Починаючи з Python 2.7, ви можете використовувати {}, аби створити множину
+filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
+
+# Додавання нових елементів у множину
+filled_set.add(5) # filled_set тепер дорівнює {1, 2, 3, 4, 5}
+
+# Перетин множин: &
+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. Потік управління
+####################################################
+
+# Для початку створимо змінну
+some_var = 5
+
+# Так виглядає вираз if. Відступи у python дуже важливі!
+# результат: «some_var менше, ніж 10»
+if some_var > 10:
+ print("some_var набагато більше, ніж 10.")
+elif some_var < 10: # Вираз elif є необов'язковим.
+ print("some_var менше, ніж 10.")
+else: # Це теж необов'язково.
+ print("some_var дорівнює 10.")
+
+
+"""
+Цикли For проходять по спискам
+
+Результат:
+ собака — це ссавець
+ кішка — це ссавець
+ миша — це ссавець
+"""
+for animal in ["собака", "кішка", "миша"]:
+ # Можете використовувати оператор {0} для інтерполяції форматованих рядків
+ print "{0} — це ссавець".format(animal)
+
+"""
+"range(число)" повертає список чисел
+від нуля до заданого числа
+Друкує:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print(i)
+"""
+"range(нижня_границя, верхня_границя)" повертає список чисел
+від нижньої границі до верхньої
+Друкує:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print i
+
+"""
+Цикли while продовжуються до тих пір, поки вказана умова не стане хибною.
+Друкує:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print(x)
+ x += 1 # Короткий запис для x = x + 1
+
+# Обробляйте винятки блоками try/except
+
+# Працює у Python 2.6 і вище:
+try:
+ # Аби створити виняток, використовується raise
+ raise IndexError("Помилка у індексі!")
+except IndexError as e:
+ pass # pass — оператор, який нічого не робить. Зазвичай тут відбувається
+ # відновлення після помилки.
+except (TypeError, NameError):
+ pass # Винятки можна обробляти групами, якщо потрібно.
+else: # Необов'язковий вираз. Має слідувати за останнім блоком except
+ print("Все добре!") # Виконається лише якщо не було ніяких винятків
+finally: # Виконується у будь-якому випадку
+ print "Тут ми можемо звільнити ресурси"
+
+# Замість try/finally для звільнення ресурсів
+# ви можете використовувати вираз with
+with open("myfile.txt") as f:
+ for line in f:
+ print line
+
+
+####################################################
+## 4. Функції
+####################################################
+
+# Використовуйте def для створення нових функцій
+def add(x, y):
+ print "x дорівнює {0}, а y дорівнює {1}".format(x, y)
+ return x + y # Повертайте результат за допомогою ключового слова return
+
+
+# Виклик функції з аргументами
+add(5, 6) # => друкує «x дорівнює 5, а y дорівнює 6» і повертає 11
+
+# Інший спосіб виклику функції — виклик з іменованими аргументами
+add(y=6, x=5) # Іменовані аргументи можна вказувати у будь-якому порядку
+
+
+# Ви можете визначити функцію, яка приймає змінну кількість аргументів,
+# які будуть інтерпретовані як кортеж, за допомогою *
+def varargs(*args):
+ return args
+
+
+varargs(1, 2, 3) # => (1,2,3)
+
+
+# А також можете визначити функцію, яка приймає змінне число
+# іменованих аргументів, котрі будуть інтерпретовані як словник, за допомогою **
+def keyword_args(**kwargs):
+ return kwargs
+
+
+# Давайте подивимось що з цього вийде
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
+
+# Якщо хочете, можете використовувати обидва способи одночасно
+def all_the_args(*args, **kwargs):
+ print(args)
+ print(kwargs)
+
+
+"""
+all_the_args(1, 2, a=3, b=4) друкує:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Коли викликаєте функції, то можете зробити навпаки!
+# Використовуйте символ * аби розпакувати позиційні аргументи і
+# ** для іменованих аргументів
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # еквівалентно foo(1, 2, 3, 4)
+all_the_args(**kwargs) # еквівалентно foo(a=3, b=4)
+all_the_args(*args, **kwargs) # еквівалентно foo(1, 2, 3, 4, a=3, b=4)
+
+# ви можете передавати довільне число позиційних або іменованих аргументів
+# іншим функціям, які їх приймають, розпаковуючи за допомогою
+# * або ** відповідно
+def pass_all_the_args(*args, **kwargs):
+ all_the_args(*args, **kwargs)
+ print varargs(*args)
+ print keyword_args(**kwargs)
+
+
+# Область визначення функцій
+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
+
+# Присутні вбудовані функції вищого порядку
+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]
+
+# Для зручного відображення і фільтрації можна використовувати
+# включення у вигляді списків
+[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 '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. Класи
+####################################################
+
+# Аби отримати клас, ми наслідуємо object.
+class Human(object):
+ # Атрибут класу. Він розділяється всіма екземплярами цього класу.
+ species = "H. sapiens"
+
+ # Звичайний конструктор, буде викликаний при ініціалізації екземпляру класу
+ # Зверніть увагу, що подвійне підкреслення на початку та наприкінці імені
+ # використовується для позначення об'єктів та атрибутів,
+ # які використовуються Python, але знаходяться у просторах імен,
+ # якими керує користувач. Не варто вигадувати для них імена самостійно.
+ def __init__(self, name):
+ # Присвоєння значення аргумента атрибуту класу name
+ self.name = name
+
+ # Ініціалізуємо властивість
+ self.age = 0
+
+ # Метод екземпляру. Всі методи приймають self у якості першого аргументу
+ def say(self, msg):
+ return "%s: %s" % (self.name, msg)
+
+ # Методи класу розділяються між усіма екземплярами
+ # Вони викликаються з вказанням викликаючого класу
+ # у якості першого аргументу
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Статичний метод викликається без посилання на клас або екземпляр
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+ # Властивість.
+ # Перетворює метод 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
+
+
+# Створюємо екземпляр класу
+i = Human(name="Данило")
+print(i.say("привіт")) # Друкує: «Данило: привіт»
+
+j = Human("Меланка")
+print(j.say("Привіт")) # Друкує: «Меланка: привіт»
+
+# Виклик методу класу
+i.get_species() # => "H. sapiens"
+
+# Зміна розділюваного атрибуту
+Human.species = "H. neanderthalensis"
+i.get_species() # => "H. neanderthalensis"
+j.get_species() # => "H. neanderthalensis"
+
+# Виклик статичного методу
+Human.grunt() # => "*grunt*"
+
+# Оновлюємо властивість
+i.age = 42
+
+# Отримуємо значення
+i.age # => 42
+
+# Видаляємо властивість
+del i.age
+i.age # => виникає помилка атрибуту
+
+####################################################
+## 6. Модулі
+####################################################
+
+# Ви можете імпортувати модулі
+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
+
+# Можете імпортувати всі функції модуля.
+# Попередження: краще так не робіть
+from math import *
+
+# Можете скорочувати імена модулів
+import math as m
+
+math.sqrt(16) == m.sqrt(16) # => True
+# Ви також можете переконатися, що функції еквівалентні
+from math import sqrt
+
+math.sqrt == m.sqrt == sqrt # => True
+
+# Модулі в Python — це звичайні Python-файли. Ви
+# можете писати свої модулі та імпортувати їх. Назва
+# модуля співпадає з назвою файлу.
+
+# Ви можете дізнатися, які функції та атрибути визначені
+# в модулі
+import math
+
+dir(math)
+
+
+# Якщо у вас є Python скрипт з назвою math.py у тій же папці, що
+# і ваш поточний скрипт, то файл math.py
+# може бути завантажено замість вбудованого у Python модуля.
+# Так трапляється, оскільки локальна папка має перевагу
+# над вбудованими у Python бібліотеками.
+
+####################################################
+## 7. Додатково
+####################################################
+
+# Генератори
+# Генератор "генерує" значення тоді, коли вони запитуються, замість того,
+# щоб зберігати все одразу
+
+# Метод нижче (*НЕ* генератор) подвоює всі значення і зберігає їх
+# в `double_arr`. При великих розмірах може знадобитися багато ресурсів!
+def double_numbers(iterable):
+ double_arr = []
+ for i in iterable:
+ double_arr.append(i + i)
+ return double_arr
+
+
+# Тут ми спочатку подвоюємо всі значення, потім повертаємо їх,
+# аби перевірити умову
+for value in double_numbers(range(1000000)): # `test_non_generator`
+ print value
+ if value > 5:
+ break
+
+
+# Натомість ми можемо скористатися генератором, аби "згенерувати"
+# подвійне значення, як тільки воно буде запитане
+def double_numbers_generator(iterable):
+ for i in iterable:
+ yield i + i
+
+
+# Той самий код, але вже з генератором, тепер дозволяє нам пройтися по
+# значенням і подвоювати їх одне за одним якраз тоді, коли вони обробляються
+# за нашою логікою, одне за одним. А як тільки ми бачимо, що value > 5, ми
+# виходимо з циклу і більше не подвоюємо більшість значень,
+# які отримали на вхід (НАБАГАТО ШВИДШЕ!)
+for value in double_numbers_generator(xrange(1000000)): # `test_generator`
+ print value
+ if value > 5:
+ break
+
+# Між іншим: ви помітили використання `range` у `test_non_generator` і
+# `xrange` у `test_generator`?
+# Як `double_numbers_generator` є версією-генератором `double_numbers`, так
+# і `xrange` є аналогом `range`, але у вигляді генератора.
+# `range` поверне нам масив з 1000000 значень
+# `xrange`, у свою чергу, згенерує 1000000 значень для нас тоді,
+# коли ми їх запитуємо / будемо проходитись по ним.
+
+# Аналогічно включенням у вигляді списків, ви можете створювати включення
+# у вигляді генераторів.
+values = (-x for x in [1, 2, 3, 4, 5])
+for x in values:
+ print(x) # друкує -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]
+
+# Декоратори
+# Декоратор – це функція вищого порядку, яка приймає та повертає функцію.
+# Простий приклад використання – декоратор add_apples додає елемент 'Apple' в
+# список fruits, який повертає цільова функція get_fruits.
+def add_apples(func):
+ def get_fruits():
+ fruits = func()
+ fruits.append('Apple')
+ return fruits
+ return get_fruits
+
+@add_apples
+def get_fruits():
+ return ['Banana', 'Mango', 'Orange']
+
+# Друкуємо список разом з елементом 'Apple', який знаходиться в ньому:
+# Banana, Mango, Orange, Apple
+print ', '.join(get_fruits())
+
+# У цьому прикладі beg обертає say
+# Beg викличе say. Якщо say_please дорівнюватиме True, то повідомлення,
+# що повертається, буде змінено.
+from functools import wraps
+
+
+def beg(target_function):
+ @wraps(target_function)
+ def wrapper(*args, **kwargs):
+ msg, say_please = target_function(*args, **kwargs)
+ if say_please:
+ return "{} {}".format(msg, "Будь ласка! Я бідний :(")
+ return msg
+
+ return wrapper
+
+
+@beg
+def say(say_please=False):
+ msg = "Ви можете купити мені пива?"
+ return msg, say_please
+
+
+print say() # Ви можете купити мені пива?
+print say(say_please=True) # Ви можете купити мені пива? Будь ласка! Я бідний :(
+```
+
+## Готові до більшого?
+
+### Безкоштовні онлайн-матеріали
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [Официальная документация](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+
+### Платні
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+
diff --git a/uk-ua/rust-ua.html.markdown b/uk-ua/rust-ua.html.markdown
new file mode 100644
index 00000000..4ec2b7c9
--- /dev/null
+++ b/uk-ua/rust-ua.html.markdown
@@ -0,0 +1,331 @@
+---
+language: rust
+contributors:
+ - ["P1start", "http://p1start.github.io/"]
+translators:
+ - ["Volodymyr Korniichuk", "https://github.com/ezhikus"]
+filename: learnrust-uk.rs
+lang: uk-ua
+---
+
+Rust - це мова програмування, що розрабляється спільнотою Mozilla Research
+Rust поєднує в собі низькорівневий контроль швидкодії з високорівневими
+інструментами забезпечення гарантій цілісності та безпеки.
+
+Rust досягає своїх цілей без автоматичного збирання сміття і не вимагає
+наявності певного середовища виконання, що робить можливим пряму заміну
+бібліотек, написаних на мові С на бібліотеки, написані на Rust.
+
+Перший реліз Rust (версія 0.1) вийшла в січні 2012 року і з тих пір оновлення
+виходили так часто, що загальною порадою розробникам було не чекати якоїсь
+стабільної версії, а використовувати нічні збірки компілятора.
+
+15 травня 2015 року вийшла версія Rust 1.0. Для цієї версії була дана гарантія
+зворотної сумісності. Подальші нічні збірки покращили швидкість компіляції та
+деякі інші аспекти. На даний момент оновлення Rust виходять кожні 6 тижнів.
+Бета-версія Rust 1.1 вийшла одночасно з релізом Rust 1.0.
+
+Не зважаючи на те, що Rust є відносно низькорівневою мовою програмування, в
+ній є деякі концепти, притаманні високорівневим мовам. Це робить Rust не лише
+швидким, але й досить зручним та ефективним інструментом розробки.
+
+```rust
+// Це коментар. Він починається в цьому рядку...
+// і продовжується в цьому
+
+/// Цей коментар включає в себе документацію і підтримує markdown.
+/// # Приклади
+///
+/// ```
+/// let five = 5
+/// ```
+
+///////////////
+// 1. Основи //
+///////////////
+
+#[allow(dead_code)]
+// Функції
+// `i32` - це 32-бітний цілочислений знаковий тип даних
+fn add2(x: i32, y: i32) -> i32 {
+ // неявне повернення результату (в кінці рядку немає крапки з комою)
+ x + y
+}
+
+#[allow(unused_variables)]
+#[allow(unused_assignments)]
+#[allow(dead_code)]
+// Головна функція
+fn main() {
+ // Числа //
+
+ // Незмінне число
+ let x: i32 = 1;
+
+ // суфікси для позначення цілого числа та числа з плаваючою змінною
+ let y: i32 = 13i32;
+ let f: f64 = 1.3f64;
+
+ // Вивід типів
+ // Як правило, Rust може самостійно визначити тип змінної, отож
+ // ви можете не прописувати його явно
+ // В даному документі типи явно прописані в багатьох місцях, це зроблено
+ // виключно в навчальних цілях. В реальному коді вивід типів спрацює
+ // в більшості випадків
+ let implicit_x = 1;
+ let implicit_f = 1.3;
+
+ // арифметика
+ let sum = x + y + 13;
+
+ // Змінні
+ let mut mutable = 1;
+ mutable = 4;
+ mutable += 2;
+
+ // Строки //
+
+ // Строкові літерали
+ let x: &str = "Привіт, світ!";
+
+ // Друк на екран
+ println!("{} {}", f, x); // 1.3 Привіт, світ!
+
+ // `String` – строка, що розміщується в "купі"
+ let s: String = "hello world".to_string();
+
+ // Строковий зріз - це незмінне відображення якоїсь строки (або її частини)
+ // Зріз можна розглядати як константну пару покажчиків (на початок та кінець
+ // якоїсь строки)
+ let s_slice: &str = &s;
+
+ println!("{} {}", s, s_slice); // Привіт, світ! Привіт, світ!
+
+ // Вектори/масиви //
+
+ // Масив фіксованого розміру
+ let four_ints: [i32; 4] = [1, 2, 3, 4];
+
+ // Масив змінного розміру (вектор)
+ let mut vector: Vec<i32> = vec![1, 2, 3, 4];
+ vector.push(5);
+
+ // Зріз - незмінне відображення масиву
+ // Це схоже на строковий зріз, але в даному випадку мова йде про вектори
+ let slice: &[i32] = &vector;
+
+ // Використовуйте `{:?}` щоб вивести щось в цілях відлагодження
+ println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
+
+ // Кортеж //
+
+ // Кортеж - це набір фіксованого розміру, що включає значення кількох типів
+ let x: (i32, &str, f64) = (1, "привіт", 3.4);
+
+ // розбираємо кортеж "х" на окремі змінні "a", "b" та "с"
+ let (a, b, c) = x;
+ println!("{} {} {}", a, b, c); // 1 привіт 3.4
+
+ // доступ по індексу
+ println!("{}", x.1); // привіт
+
+ //////////////
+ // 2. Типи //
+ //////////////
+
+ // Структура
+ struct Point {
+ x: i32,
+ y: i32,
+ }
+
+ let origin: Point = Point { x: 0, y: 0 };
+
+ // Структура з безіменними полями, "кортежна структура"
+ struct Point2(i32, i32);
+
+ let origin2 = Point2(0, 0);
+
+ // перелічуваний тип даних
+ enum Direction {
+ Left,
+ Right,
+ Up,
+ Down,
+ }
+
+ let up = Direction::Up;
+
+ // перелічуваний тип даних з полями
+ enum OptionalI32 {
+ AnI32(i32),
+ Nothing,
+ }
+
+ let two: OptionalI32 = OptionalI32::AnI32(2);
+ let nothing = OptionalI32::Nothing;
+
+ // Узагальнене програмування //
+
+ struct Foo<T> { bar: T }
+
+ // Ось так стандартна бібліотека Rust оголошує `Option`
+ enum Optional<T> {
+ SomeVal(T),
+ NoVal,
+ }
+
+ // Методи //
+
+ impl<T> Foo<T> {
+ // Методи приймають неявний параметр `self`
+ fn get_bar(self) -> T {
+ self.bar
+ }
+ }
+
+ let a_foo = Foo { bar: 1 };
+ println!("{}", a_foo.get_bar()); // 1
+
+ // Типажі (в інших мовах програмування схожою сутністю є інтерфейси) //
+
+ trait Frobnicate<T> {
+ fn frobnicate(self) -> Option<T>;
+ }
+
+ impl<T> Frobnicate<T> for Foo<T> {
+ fn frobnicate(self) -> Option<T> {
+ Some(self.bar)
+ }
+ }
+
+ let another_foo = Foo { bar: 1 };
+ println!("{:?}", another_foo.frobnicate()); // Some(1)
+
+ /////////////////////////
+ // 3. Відповідність шаблону //
+ /////////////////////////
+
+ let foo = OptionalI32::AnI32(1);
+ match foo {
+ OptionalI32::AnI32(n) => println!("Це тип i32: {}", n),
+ OptionalI32::Nothing => println!("Це ніщо!"),
+ }
+
+ // Складніший приклад
+ struct FooBar { x: i32, y: OptionalI32 }
+ let bar = FooBar { x: 15, y: OptionalI32::AnI32(32) };
+
+ match bar {
+ FooBar { x: 0, y: OptionalI32::AnI32(0) } =>
+ println!("Числа рівні нулю!"),
+ FooBar { x: n, y: OptionalI32::AnI32(m) } if n == m =>
+ println!("Числа однакові"),
+ FooBar { x: n, y: OptionalI32::AnI32(m) } =>
+ println!("Числа різні: {} {}", n, m),
+ FooBar { x: _, y: OptionalI32::Nothing } =>
+ println!("Друге число - ніщо!"),
+ }
+
+ /////////////////////
+ // 4. Потік керування //
+ /////////////////////
+
+ // Цикл `for`
+ let array = [1, 2, 3];
+ for i in array.iter() {
+ println!("{}", i);
+ }
+
+ // Діапазони
+ for i in 0u32..10 {
+ print!("{} ", i);
+ }
+ println!("");
+ // друкує `0 1 2 3 4 5 6 7 8 9 `
+
+ // `if`
+ if 1 == 1 {
+ println!("Математика працює!");
+ } else {
+ println!("Ой, лишенько...");
+ }
+
+ // `if` як вираз
+ let value = if true {
+ "добре"
+ } else {
+ "погано"
+ };
+
+ // Цикл `while`
+ while 1 == 1 {
+ println!("Всесвіт функціонує стабільно.");
+ // Вираз break перериває цикл
+ break
+ }
+
+ // Нескінченний цикл
+ loop {
+ println!("Привіт!");
+ // Вираз break перериває цикл
+ break
+ }
+
+ /////////////////////////////////
+ // 5. Вказівники і безпека пам'яті //
+ /////////////////////////////////
+
+ // Володіючий вказівник - тільки хтось один може "володіти" вказівником в
+ // будь-який момент. Це означає, що коли "Box" вийде за межі області
+ // видимості - його можна безпечно звільнити
+ let mut mine: Box<i32> = Box::new(3);
+ *mine = 5; // розіменування `mine` з присвоєнням йому нового значення
+ // `now_its_mine` перебирає на себе володіння над `mine`. Іншими словами,
+ // `mine` переміщується.
+ let mut now_its_mine = mine;
+ *now_its_mine += 2;
+
+ println!("{}", now_its_mine); // 7
+ // println!("{}", mine); // цей код не скомпілюється, оскільки тепер
+ // покажчиком на дані володіє `now_its_mine`
+
+ // Посилання – незмінний вказівник на дані
+ // При створенні посилання на якесь значення, ми говоримо, що значення
+ // було "запозичене". Поки значення є запозиченим - воно не може бути
+ // змінене або переміщене. Запозичення пропадає, як тільки стається вихід з
+ // області видимості, де було створене посилання
+ let mut var = 4;
+ var = 3;
+ let ref_var: &i32 = &var;
+
+ println!("{}", var); // На відміну від `mine`, `var` можна використати
+ println!("{}", *ref_var);
+ // var = 5; // цей код не скомпілюється, оскільки `var` зараз є запозиченим
+ // *ref_var = 6; // цей код також не зкомпілюється, оскільки `ref_var`
+ // є незмінним посиланням
+
+ // Змінне посилання
+ // Значення можна запозичити з можливістю зміни. У цьому випадку доступ до
+ // оригінального значення втрачається.
+ let mut var2 = 4;
+ let ref_var2: &mut i32 = &mut var2;
+ *ref_var2 += 2; // '*' використовується для доступу до змінного посилання
+
+ println!("{}", *ref_var2); // 6 , // при заміні на var2 код не зкомпілюється
+ // ref_var2 має тип &mut i32, отож зберігає посилання на i32, а не значення
+ // var2 = 2; // цей рядок не зкомпілюється, оскільки `var2` є запозиченим.
+}
+```
+
+## Матеріали для самовдосконалення
+
+В даному матеріалі ми оглянули лише основи Rust. Більше матеріалу ви можете
+знайти на сайті
+[The Rust Programming Language](http://doc.rust-lang.org/book/index.html)
+Також існує Reddit-розділ [/r/rust](http://reddit.com/r/rust). Люди на каналі
+irc.mozilla.org також завжди раді допомогти новачкам.
+
+Ви можете спробувати можливості Rust за допомогою онлайн-компілятора на сторінці
+[Rust playpen](http://play.rust-lang.org) або
+[Rust website](http://rust-lang.org).
diff --git a/uk-ua/wasm-ua.html.markdown b/uk-ua/wasm-ua.html.markdown
new file mode 100644
index 00000000..34f8cef8
--- /dev/null
+++ b/uk-ua/wasm-ua.html.markdown
@@ -0,0 +1,226 @@
+---
+language: WebAssembly
+lang: uk-ua
+filename: learnwasm-ua.wast
+contributors:
+ - ["Dean Shaff", "http://dean-shaff.github.io"]
+translators:
+ - ["Oleh Hromiak", "https://github.com/ogroleg"]
+---
+
+```
+;; learnwasm-ua.wast
+
+(module
+ ;; У WebAssembly весь код знаходиться в модулях. Будь-яка операція
+ ;; може бути записана за допомогою s-виразу. Також існує синтаксис "стек машини",
+ ;; втім, він не сумісний з проміжним бінарним представленням коду.
+
+ ;; Формат бінарного проміжного представлення майже повністю сумісний
+ ;; з текстовим форматом WebAssembly.
+ ;; Деякі відмінності:
+ ;; local_set -> local.set
+ ;; local_get -> local.get
+
+ ;; Код розміщується у функціях
+
+ ;; Типи даних
+ (func $data_types
+ ;; WebAssembly має чотири типи даних:
+ ;; i32 - ціле число, 32 біти
+ ;; i64 - ціле число, 64 біти (не підтримується у JavaScript)
+ ;; f32 - число з плаваючою комою, 32 біти
+ ;; f64 - число з плаваючою комою, 64 біти
+
+ ;; Створити локальну змінну можна за допомогою ключового слова "local".
+ ;; Змінні потрібно оголошувати на початку функції.
+
+ (local $int_32 i32)
+ (local $int_64 i64)
+ (local $float_32 f32)
+ (local $float_64 f64)
+
+ ;; Змінні, оголошені вище, ще не ініціалізовані, себто, не мають значення.
+ ;; Давайте присвоїмо їм значення за допомогою <тип даних>.const:
+
+ (local.set $int_32 (i32.const 16))
+ (local.set $int_32 (i64.const 128))
+ (local.set $float_32 (f32.const 3.14))
+ (local.set $float_64 (f64.const 1.28))
+ )
+
+ ;; Базові операції
+ (func $basic_operations
+
+ ;; Нагадаємо, у WebAssembly будь-що є s-виразом, включно
+ ;; з математичними виразами або зчитуванням значень змінних
+
+ (local $add_result i32)
+ (local $mult_result f64)
+
+ (local.set $add_result (i32.add (i32.const 2) (i32.const 4)))
+ ;; тепер add_result дорівнює 6!
+
+ ;; Для кожної операції потрібно використовувати правильний тип:
+ ;; (local.set $mult_result (f32.mul (f32.const 2.0) (f32.const 4.0))) ;; Ніт! mult_result має тип f64!
+ (local.set $mult_result (f64.mul (f64.const 2.0) (f64.const 4.0))) ;; Ніт! mult_result має тип f64!
+
+ ;; У WebAssembly є вбудовані функції накшталт математики та побітових операцій.
+ ;; Варто зазначити, що тут відсутні вбудовані тригонометричні функції.
+ ;; Тож нам потрібно:
+ ;; - написати їх самостійно (не найкраща ідея)
+ ;; - звідкись їх імпортувати (як саме - побачимо згодом)
+ )
+
+ ;; Функції
+ ;; Параметри вказуються ключовим словом `param`, значення, що повертається - `result`
+ ;; Поточне значення стеку і є значенням функції, що повертається
+
+ ;; Ми можемо викликати інші функції за допомогою `call`
+
+ (func $get_16 (result i32)
+ (i32.const 16)
+ )
+
+ (func $add (param $param0 i32) (param $param1 i32) (result i32)
+ (i32.add
+ (local.get $param0)
+ (local.get $param1)
+ )
+ )
+
+ (func $double_16 (result i32)
+ (i32.mul
+ (i32.const 2)
+ (call $get_16))
+ )
+
+ ;; Досі ми не могли що-небудь вивести на консоль і не мали доступу
+ ;; до високорівневої математики (степеневі функції, обрахунок експоненти або тригонометрія).
+ ;; Більше того, ми навіть не могли викликати WASM функції у Javascript!
+ ;; Виклик цих функцій у WebAssembly залежить від того,
+ ;; де ми знаходимось - чи це Node.js, чи середовище браузера.
+
+ ;; Якщо ми у Node.js, то потрібно виконати два кроки. По-перше, ми маємо сконвертувати
+ ;; текстове представлення WASM у справжній код webassembly.
+ ;; Наприклад, ось так (Binaryen):
+
+ ;; wasm-as learn-wasm.wast -o learn-wasm.wasm
+
+ ;; Давай також застосуємо оптимізації:
+
+ ;; wasm-opt learn-wasm.wasm -o learn-wasm.opt.wasm -O3 --rse
+
+ ;; Тепер наш скомпільований WebAssembly можна завантажити у Node.js:
+ ;; const fs = require('fs')
+ ;; const instantiate = async function (inFilePath, _importObject) {
+ ;; var importObject = {
+ ;; console: {
+ ;; log: (x) => console.log(x),
+ ;; },
+ ;; math: {
+ ;; cos: (x) => Math.cos(x),
+ ;; }
+ ;; }
+ ;; importObject = Object.assign(importObject, _importObject)
+ ;;
+ ;; var buffer = fs.readFileSync(inFilePath)
+ ;; var module = await WebAssembly.compile(buffer)
+ ;; var instance = await WebAssembly.instantiate(module, importObject)
+ ;; return instance.exports
+ ;; }
+ ;;
+ ;; const main = function () {
+ ;; var wasmExports = await instantiate('learn-wasm.wasm')
+ ;; wasmExports.print_args(1, 0)
+ ;; }
+
+ ;; Цей код зчитує функції з importObject
+ ;; (вказано у асинхронній JavaScript функції instantiate), а потім експортує функцію
+ ;; "print_args", яку ми викликаємо у Node.js
+
+ (import "console" "log" (func $print_i32 (param i32)))
+ (import "math" "cos" (func $cos (param f64) (result f64)))
+
+ (func $print_args (param $arg0 i32) (param $arg1 i32)
+ (call $print_i32 (local.get $arg0))
+ (call $print_i32 (local.get $arg1))
+ )
+ (export "print_args" (func $print_args))
+
+ ;; Завантаження даних з пам'яті WebAssembly.
+ ;; Наприклад, ми хочемо порахувати cos для елементів Javascript масиву.
+ ;; Нам потрібно отримати доступ до масиву і можливість ітерувати по ньому.
+ ;; У прикладі нижче ми змінимо існуючий масив.
+ ;; f64.load і f64.store приймають адресу числа у пам'яті *у байтах*.
+ ;; Для того, щоб отримати доступ до 3-го елементу масиву, ми маємо передати щось
+ ;; накшталт (i32.mul (i32.const 8) (i32.const 2)) у функцію f64.store.
+
+ ;; У JavaScript ми викличемо `apply_cos64` таким чином
+ ;; (використаємо функцію instantiate з попереднього прикладу):
+ ;;
+ ;; const main = function () {
+ ;; var wasm = await instantiate('learn-wasm.wasm')
+ ;; var n = 100
+ ;; const memory = new Float64Array(wasm.memory.buffer, 0, n)
+ ;; for (var i=0; i<n; i++) {
+ ;; memory[i] = i;
+ ;; }
+ ;; wasm.apply_cos64(n)
+ ;; }
+ ;;
+ ;; Ця функція не буде працювати, якщо ми виділимо пам'ять для (створимо) Float32Array у JavaScript.
+
+ (memory (export "memory") 100)
+
+ (func $apply_cos64 (param $array_length i32)
+ ;; визначаємо змінну циклу або лічильник
+ (local $idx i32)
+ ;; визначаємо змінну для доступу до пам'яті
+ (local $idx_bytes i32)
+ ;; константа - кількість байтів у числі типу f64.
+ (local $bytes_per_double i32)
+
+ ;; визначаємо змінну, яка зберігатиме значення з пам'яті
+ (local $temp_f64 f64)
+
+ (local.set $idx (i32.const 0))
+ (local.set $idx_bytes (i32.const 0)) ;; не обов'язково
+ (local.set $bytes_per_double (i32.const 8))
+
+ (block
+ (loop
+ ;; записуємо у idx_bytes необхідне зміщення в пам'яті - для поточного числа.
+ (local.set $idx_bytes (i32.mul (local.get $idx) (local.get $bytes_per_double)))
+
+ ;; отримуємо число з пам'яті (за зміщенням):
+ (local.set $temp_f64 (f64.load (local.get $idx_bytes)))
+
+ ;; рахуємо cos:
+ (local.set $temp_64 (call $cos (local.get $temp_64)))
+
+ ;; тепер зберігаємо результат обчислень у пам'ять:
+ (f64.store
+ (local.get $idx_bytes)
+ (local.get $temp_64))
+
+ ;; або робимо все за один крок (альтернативний код)
+ (f64.store
+ (local.get $idx_bytes)
+ (call $cos
+ (f64.load
+ (local.get $idx_bytes))))
+
+ ;; збільшуємо лічильник на одиницю (інкремент)
+ (local.set $idx (i32.add (local.get $idx) (i32.const 1)))
+
+ ;; якщо лічильник дорівнює довжині масиву, то завершуємо цикл
+ (br_if 1 (i32.eq (local.get $idx) (local.get $array_length)))
+ (br 0)
+ )
+ )
+ )
+ (export "apply_cos64" (func $apply_cos64))
+)
+
+```
diff --git a/vala.html.markdown b/vala.html.markdown
new file mode 100755
index 00000000..393578b0
--- /dev/null
+++ b/vala.html.markdown
@@ -0,0 +1,503 @@
+---
+language: vala
+contributors:
+ - ["Milo Gilad", "https://github.com/Myl0g"]
+filename: LearnVala.vala
+---
+
+In GNOME's own words, "Vala is a programming language that aims to bring modern programming language features to GNOME developers without imposing any additional runtime requirements and without using a different ABI compared to applications and libraries written in C."
+
+Vala has aspects of Java and C#, so it'll be natural to those who know either.
+
+[Read more here.](https://wiki.gnome.org/Projects/Vala)
+
+```vala
+
+// Single line comment
+
+/* Multiline
+Comment */
+
+/**
+* Documentation comment
+*/
+
+/* Data Types */
+
+char character = 'a'
+unichar unicode_character = 'u' // 32-bit unicode character
+
+int i = 2; // ints can also have guaranteed sizes (e.g. int64, uint64)
+uint j = -6; // Won't compile; unsigned ints can only be positive
+
+long k;
+
+short l;
+ushort m;
+
+string text = "Hello,"; // Note that the == operator will check string content
+
+string verbatim = """This is a verbatim (a.k.a. raw) string. Special characters
+(e.g. \n and "") are not interpreted. They may also be multiple lines long.""";
+
+// String Templates allow for easy string formatting
+string string_template = @"$text world"; // "$text" evaluates to "Hello,"
+
+int test = 5;
+int test2 = 10;
+string template2 = @"$(test * test2) is a number."; // Expression evaluation
+
+string template_slice = string_template[7:12]; // => "world"
+
+// Most data types have methods for parsing.
+
+bool parse_bool = bool.parse("false"); // => false
+int parse_int = int.parse("-52"); // => -52
+string parse_string = parse_int.to_string(); // => "-52"
+
+/* Basic I/O */
+
+stdout.printf(parse_string); // Prints to console
+string input = stdin.read_line(); // Gets input from console
+
+stderr.printf("Error message"); // Error printing
+
+/* Arrays */
+
+int[] int_array = new int[10]; // Array of ints with 10 slots
+int better_int_array[10]; // Above expression, shortened
+int_array.length; // => 10;
+
+int[] int_array2 = {5, 10, 15, 20}; // Can be created on-the-fly
+
+int[] array_slice = int_array2[1:3]; // Slice (copy of data)
+unowned int[] array_slice_ref = int_array2[1:3]; // Reference to data
+
+// Multi-dimensional Arrays (defined with a number of commas in the brackets)
+
+int[,] multi_array = new int[6,4]; // 6 is the number of arrays, 4 is their size
+int[,] multi_array2 = {{7, 4, 6, 4},
+ {3, 2, 4, 6},
+ {5, 9, 5, 1}}; // new int[3,4]
+multi_array2[2,3] = 12; // 2 is the array, 3 is the index in the array
+int first_d = multi_array2.length[0] // => 3
+int second_d = multi_array2.length[1] // => 4
+
+// Stacked arrays (e.g. int[][]) where array lengths vary are not supported.
+
+// Multi-dimensional arrays cannot be sliced, nor can they be converted to one-
+// dimensional.
+
+int[] add_to_array = {};
+add_to_array += 12; // Arrays can be dynamically added to
+
+add_to_array.resize(20); // Array now has 20 slots
+
+uint8[] chars = "test message".data;
+chars.move(5, 0, 7);
+stdout.printf((string) chars); // Casts the array to a string and prints it
+
+/* Control Flow */
+
+int a = 1;
+int b = 2;
+int[] foreach_demo = {2, 4, 6, 8};
+
+while (b > a) { // While loop; checks if expression is true before executing
+ b--;
+}
+
+do {
+ b--;
+}
+while (b > a); // Do While loop; executes the code in "do" before while (b > a)
+
+for (a = 0; a < 10; a++) { stdout.printf("%d\n", a); } // for loop
+
+foreach (int foreach_demo_var in foreach_demo) {
+ stdout.printf("%d\n", foreach_demo_var);
+} // foreach works on any iterable collection
+
+if (a == 0) {
+ stdout.printf("%d\n", a);
+} else if (a > 1) {
+ stdout.printf("%d\n", a);
+} else {
+ stdout.printf("A is less than 0");
+} // if-then-else
+
+switch (a) {
+ case 1:
+ stdout.printf("A is 1\n");
+ break;
+ case 5:
+ case 10:
+ stdout.printf("A is 5 or 10\n");
+ break;
+ default:
+ stdout.printf("???\n")
+ break;
+} // switch statement
+
+/* Type Casting and Inference */
+
+int cast_to_float = 10;
+float casted_float = (float) cast_to_float; // static casting; no runtime checks
+
+// For runtime checks, use dynamic casting.
+// Dynamically casted objects must be the following:
+// - Object's class is the same class as the desired type
+// - Object's class is a subclass of the desired type
+// - Desired class is an interface implemented by the object's class
+
+float dyna_casted_float = cast_to_float as float // Won't compile
+
+var inferred_string = "hello"; // Type inference
+
+/* Methods (a.k.a. functions) */
+
+int method_demo(string arg1, Object arg2) { // Returns int and takes args
+ return 1;
+}
+
+// Vala methods cannot be overloaded.
+
+void some_method(string text) { }
+void some_method(int number) { } // Won't compile
+
+// To achieve similar functionality, use default argument values.
+
+void some_better_method(string text, int number = 0) { }
+
+some_better_method("text");
+some_better_method("text", 12);
+
+// varargs (variable-length argument lists) are also supported.
+
+void method_with_varargs(int arg1, ...) {
+ var varargs_list = va_list(); // gets the varargs list
+
+ string arg_string = varargs_list.arg(); // gets arguments, one after another
+ int int_vararg = varargs_list.arg();
+
+ stdout.printf("%s, %d\n", arg_string, int_vararg)
+}
+
+string? ok_to_be_null(int? test_int) { } // "?" denotes possible null value
+
+// Delegates
+
+delegate void DelegateDemo(char char_a);
+
+void delegate_match(char char_a) { // Matches DelegateDemo's signature
+ stdout.printf("%d\n");
+}
+
+void call_delegate(DelegateDemo d, char char_b) { // Takes a delegate arg
+ d(char_b) // calls delegate
+}
+
+void final_delegate_demo() {
+ call_delegate(delegate_match); // Passes matching method as argument
+}
+
+// Lambdas (a.k.a. Anonymous Methods) are defined with "=>"
+
+(a) => { stdout.printf("%d\n", a); } // Prints "a"
+
+/* Namespaces */
+
+namespace NamespaceDemo {
+ // Allows you to organize variable names
+ int namespace_int = 12;
+}
+namespace_int += 5; // Won't compile
+
+using NamespaceDemo;
+namespace_int += 5; // Valid
+
+/* Structs and Enums */
+
+struct Closet {
+ public uint shirts; // Default access modifier is private
+ public uint jackets;
+}
+
+Closet struct_init_1 = Closet(); // or Closet struct_init_1 = {};
+Closet struct_init_2 = {15, 3};
+var struct_init_3 = Closet() { // Type inference also works
+ shirts = 15;
+ jackets = 3;
+}
+
+enum HouseSize { // An example of an enum
+ SMALL,
+ MODERATE,
+ BIG
+}
+
+/* Classes and Object-Oriented Programming */
+
+class Message : GLib.Object { // Class Message extends GLib's Object
+ private string sender; // a private field
+ public string text {get; set;} // a public property (more on that later)
+ protected bool is_digital = true; // protected (this class and subclasses)
+ internal bool sent = false; // internal (classes in same package)
+
+ public void send(string sender) { // public method
+ this.sender = sender;
+ sent = true;
+ }
+
+ public Message() { // Constructor
+ // ...
+ }
+
+}
+
+// Since method overloading isn't possible, you can't overload constructors.
+// However, you can use named constructors to achieve the same functionality.
+
+public class Calculator : GLib.Object {
+
+ public Calculator() {
+ }
+
+ public Calculator.with_name(string name) {
+ }
+
+ public Calculator.model(string model_id, string name = "") {
+ this.with_name(@"$model_id $name"); // Chained constructors with "this"
+ }
+ ~Calculator() { } // Only needed if you're using manual memory management
+}
+
+var calc1 = new Calculator.with_name("Temp");
+var calc2 = new Calculator.model("TI-84");
+
+// Signals (a.k.a. events or event listeners) are a way to execute multiple
+// methods with the same signature at the same time.
+
+public class SignalDemo : GLib.Object {
+ public signal void sig_demo(int sig_demo_int); // Must be public
+
+ public static int main(string[] args) {
+ // main method; program does not compile without it
+
+ var sig_demo_class = new SignalDemo(); // New instance of class
+
+ sig_demo_class.sig_demo.connect((ob, sig_int) => { // Lambda used as handler
+ stdout.printf("%d\n", sig_int); // "ob" is object on which it is emitted
+ });
+
+ sig_demo_class.sig_demo(27); // Signal is emitted
+
+ return 0;
+ }
+}
+
+// You may use the connect() method and attach as many handlers as you'd like.
+// They'll all run at around the same time when the signal is emitted.
+
+// Properties (getters and setters)
+
+class Animal : GLib.Object {
+ private int _legs; // prefixed with underscore to prevent name clashes
+
+ public int legs {
+ get { return _legs; }
+ set { _legs = value; }
+ }
+
+ public int eyes { get; set; default = 5; } // Shorter way
+ public int kingdom { get; private set; default = "Animalia"} // Read-only
+
+ public static void main(string args[]) {
+ rabbit = new Animal();
+
+ // All GLib.Objects have a signal "notify" emitted when a property changes.
+
+ // If you specify a specific property, replace all underscores with dashes
+ // to conform to the GObject naming convention.
+
+ rabbit.notify["eyes"].connect((s, p) => { // Remove the ["eyes"] for all
+ stdout.printf("Property '%s' has changed!\n", p.name);
+ });
+
+ rabbit.legs = 2;
+ rabbit.legs += 2;
+ rabbit.eyes = 2;
+
+ }
+}
+
+// Inheritance: Vala classes may inherit 1 class. Inheritance is not implicit.
+
+class SuperDemo : GLib.Object {
+ public int data1;
+ protected int data2;
+ internal int data3;
+ private int data4;
+
+ public static void test_method { } // Statics can be called w/out an object
+}
+class SubDemo : SuperDemo {
+ public static void main(string args[]) {
+ stdout.printf((string) data1); // Will compile
+ stdout.printf((string) data2); // Protected can be accessed by subclasses
+ stdout.printf((string) data3); // Internal is accessible to package
+ stdout.printf((string) data4); // Won't compile
+ }
+}
+
+// Abstract Classes and Methods
+
+public abstract class OperatingSystem : GLib.Object {
+ public void turn_on() {
+ stdout.printf("Booted successfully.\n");
+ }
+ public abstract void use_computer();
+}
+
+public class Linux : OperatingSystem {
+ public override void use_computer() { // Abstract methods must be overridden
+ stdout.printf("Beep boop\n");
+ }
+}
+
+// Add default behavior to an abstract method by making it "virtual".
+
+public abstract class HardDrive : GLib.Object {
+ public virtual void die() {
+ stdout.printf("CLICK-CLICK-CLICK\n");
+ }
+}
+public class MyHD : HardDrive {
+ public override void die() {
+ return;
+ }
+}
+
+// Interfaces: classes can implement any number of these.
+
+interface Laptop { // May only contain abstracts or virtuals
+ public abstract void turn_on();
+ public abstract void turn_off();
+
+ public abstract int cores; // Won't compile; fields cannot be abstract
+ public abstract int cores {get; set;} // Will compile
+
+ public virtual void keyboard() { // Virtuals are allowed (unlike Java/C#)
+ stdout.printf("Clickity-clack\n");
+ }
+}
+
+// The ability to use virtuals in Vala means that multiple inheritance is
+// possible (albeit somewhat confined)
+
+// Interfaces cannot implement interfaces, but they may specify that certain
+// interfaces or classes must be also implemented (pre-requisites).
+
+public interface CellPhone : Collection, GLib.Object {}
+
+// You can get the type info of a class at runtime dynamically.
+
+bool type_info = object is TypeName; // uses "is" to get a bool
+
+Type type_info2 = object.get_type();
+var type_name = type_info2.name();
+
+Type type_info3 = typeof(Linux);
+Linux type_demo = (Linux) Object.new(type_info3);
+
+// Generics
+
+class Computer<OperatingSystem> : GLib.Object {
+ private OperatingSystem os;
+
+ public void install_os(OperatingSystem os) {
+ this.os = os;
+ }
+ public OperatingSystem retrieve_os() {
+ return this.os;
+ }
+}
+
+var new_computer = new Computer<Linux>();
+
+/* Other Features */
+
+// Assertions: crash if a statement is not true (at runtime)
+
+bool is_true = true;
+assert(is_true);
+
+// Contract Programming
+
+int contract_demo(int arg1, int arg2) {
+ requires(arg1 > 0 && arg1 < 10) // Notice the lack of semicolon
+ requires(arg2 >= 12)
+ ensures(result >= 0)
+}
+
+// Error Handling
+
+void error_demo(int int_ex) throws GError {
+ if (int_ex != 1) {
+ throw new GError("TEST MESSAGE");
+ }
+}
+void error_demo2() {
+ try {
+ error_demo(0);
+ } catch (GError ge) {
+ stdout.printf("%s\n", ge.message);
+ }
+}
+
+// Main Loop
+
+void main() {
+
+ var main_loop = new MainLoop();
+ var time = new TimeoutSource(2000);
+
+ time.set_callback(() => { // Executes the following lambda after 2000ms
+ stdout.printf("2000ms have passed\n");
+ main_loop.quit();
+ return false;
+ });
+
+ time.attach(main_loop.get_context());
+
+ loop.run();
+}
+
+// Pointers (manual memory management)
+
+Object* pointer_obj = new Object(); // Creates Object instance and gives pointer
+
+pointer_obj->some_method(); // Executes some_method
+pointer_obj->some_data; // Returns some_data
+
+delete pointer_obj;
+
+int more = 57;
+int* more_pointer = &i; // & = address-of
+int indirection_demo = more_pointer*; // indirection
+
+// Profiles: affect which Vala features are avaliable and which libraries the
+// C-code will use.
+// - gobject (default)
+// posix
+// dova
+// Use "--profile=whatever" when compiling.
+
+```
+* More Vala documentation can be found [here](https://valadoc.org/).
+* [Alternate construction syntax](https://wiki.gnome.org/Projects/Vala/Tutorial#GObject-Style_Construction) similar to GObject
+* More on contract programming [here](http://en.wikipedia.org/wiki/Contract_programming)
+* Collections library can be found [here](https://wiki.gnome.org/Projects/Vala/Tutorial#Collections)
+* [Multithreading](https://wiki.gnome.org/Projects/Vala/Tutorial#Multi-Threading)
+* Read about building GUIs with GTK+ and Vala [here](http://archive.is/7C7bw).
+* D-Bus [integration](https://wiki.gnome.org/Projects/Vala/Tutorial#D-Bus_Integration)
diff --git a/vi-vn/html-vi.html.markdown b/vi-vn/html-vi.html.markdown
new file mode 100644
index 00000000..ca591174
--- /dev/null
+++ b/vi-vn/html-vi.html.markdown
@@ -0,0 +1,123 @@
+---
+language: html
+filename: learnhtml-vi.html
+contributors:
+ - ["Christophe THOMAS", "https://github.com/WinChris"]
+translators:
+ - ["Robert Steed", "https://github.com/robochat"]
+ - ["Xuan (Sean) Luong", "https://github.com/xuanluong"]
+lang: vi-vn
+---
+
+HTML là viết tắt của HyperText Markup Language (Ngôn ngữ đánh dấu siêu văn bản).
+Nó là một ngôn ngữ cho phép chúng ta viết nên những trang web.
+Nó là một ngôn ngữ đánh dấu, cho phép chúng ta viết trang web bằng code để chỉ định cách thức mà văn bản và dữ liệu nên được trình bày.
+Tập tin html thực chất chỉ là một tập tin văn bản đơn giản.
+Đánh dấu có nghĩa là gì? Nó là một phương pháp tổ chức dữ liệu của một trang web bằng cách bao quanh dữ liệu bởi các thẻ (tags) mở và đóng.
+Việc đánh dấu phục vụ mục đích cung cấp tầm quan trọng của phần văn bản mà nó bao quanh.
+Cũng như các ngôn ngữ máy tính khác, HTML có nhiều phiên bản. Ở đây chúng ta nói về HTML5.
+
+**Lưu ý :** Bạn có thể thử nghiệm những thẻ và phần tử HTML khác nhau trong quá trình đọc bài viết bằng cách truy cập những trang web như [codepen](http://codepen.io/pen/) để có thể thấy được tác dụng của những thẻ hay phần tử HTML đó,
+nhằm hiểu cách chúng hoạt động và làm quen với ngôn ngữ HTML.
+Bài viết này chủ yếu bàn về cú pháp của HTML và một vài mẹo hữu dụng.
+
+
+```html
+<!-- Bình luận được bao quanh bởi các ký tự giống như trong ví dụ này -->
+
+<!-- #################### Các thẻ #################### -->
+
+<!-- Dưới đây là tập tin HTML ví dụ mà chúng ta sẽ phân tích. -->
+
+<!doctype html>
+ <html>
+ <head>
+ <title>Trang web của tôi</title>
+ </head>
+ <body>
+ <h1>Xin chào!</h1>
+ <a href = "http://codepen.io/anon/pen/xwjLbZ">Truy cập để biết cái gì sẽ được hiển thị</a>
+ <p>Đây là một văn bản.</p>
+ <p>Một văn bản khác.</p>
+ <ul>
+ <li>Đây là một danh sách không liệt kê</li>
+ <li>Đây là một danh sách không liệt kê khác</li>
+ <li>Danh sách không liệt kê cuối cùng của danh sách cha</li>
+ </ul>
+ </body>
+ </html>
+
+<!-- Một tập tin HTML luôn bắt đầu bằng việc thể hiện cho trình duyệt rằng nó là một trang HTML -->
+<!doctype html>
+
+<!-- Sau đó nó bắt đầu với một thẻ <html> mở -->
+<html>
+
+<!-- thẻ đó sẽ được đóng vào cuối tập tin bằng một thẻ đóng </html>. -->
+</html>
+
+<!-- Không nên viết gì sau thể đóng cuối cùng này. -->
+
+<!-- Ở bên trong (giữa thẻ đóng và mở <html></html>), ta tìm thấy: -->
+
+<!-- Phần đầu được định nghĩa bằng <head> (và phải được đóng lại bằng </head>). -->
+<!-- Phần đầu chứa một vài định nghĩa và những thông tin khác không được dùng để hiển thị; đây gọi là siêu dữ liệu (metadata) -->
+
+<head>
+ <title>Trang web của tôi</title><!-- Thẻ <title> cho trình duyệt biết dòng chữ để hiển thị trên thanh tựa đề của trình duyệt vả tên tab. -->
+</head>
+
+<!-- Sau phần <head> ta sẽ gặp thẻ <body> -->
+<!-- Cho tới đây, chưa có gì được hiển thị trên cửa sổ trình duyệt. -->
+<!-- Chúng ta phải đưa nội dùng vào phần <body> để hiển thị. -->
+
+<body>
+ <h1>Xin chào!</h1> <!-- Thẻ h1 tạo ra một đề mục. -->
+ <!-- Ngoài <h1> ra ta còn có những đề mục cấp thấp hơn, từ h2 đến h6 -->
+ <a href = "http://codepen.io/anon/pen/xwjLbZ">Truy cập để biết cái gì sẽ được hiển thị</a> <!-- một liên kết đền một url được cung cấp bởi thuộc tính href="" -->
+ <p>Đây là một văn bản.</p> <!-- Thẻ <p> cho phép đưa văn bản vào trang html. -->
+ <p>Một văn bản khác.</p>
+ <ul> <!-- Thẻ <ul> tạo ra danh sách không đánh s. -->
+ <!-- Để có một danh sách có đánh số ta dùng thể <ol> thay vì <ul> từ đó sẽ có số thứ tự 1. cho phần tử đầu tiên, 2. cho phần tử thứ hai, v.v... -->
+ <li>Đây là một danh sách không liệt kê</li>
+ <li>Đây là một danh sách không liệt kê khác</li>
+ <li>Danh sách không liệt kê cuối cùng của danh sách cha</li>
+ </ul>
+</body>
+
+<!-- Và ta đã có một tập tim HTML. Việc tạo ra tập tin HTML có thể được thực hiện một cách đơn giản. -->
+
+<!-- Những ta cũng có thể thêm vào những loại thẻ HTML khác. -->
+
+<!-- Chèn vào một ảnh. -->
+<img src="http://i.imgur.com/XWG0O.gif"/> <!-- Nguồn của ảnh sẽ được khai báo qua thuộc tính src="" -->
+<!-- Nguồn ảnh có thể là một URL hoặc đường dẫn tới một tập tin trong máy. -->
+
+<!-- Ta cũng có thể tạo ra một table. -->
+
+<table> <!-- Tạo bảng với thẻ <table>. -->
+ <tr> <!-- <tr> dùng để tạo ra một hàng. -->
+ <th>Cột một</th> <!-- <th> dùng để khai báo tên cột. -->
+ <th>Cột hai</th>
+ </tr>
+ <tr>
+ <td>hàng một, cột một</td> <!-- <td> dùng để tạo ra một ô trong table. -->
+ <td>hàng một, cột hai</td>
+ </tr>
+ <tr>
+ <td>hàng hai, cột một</td>
+ <td>hàng hai, cột hai</td>
+ </tr>
+</table>
+
+```
+
+## Cách sử dụng
+
+HTML được viết trong tập tin có phần mở rộng `.html`.
+
+## Thông tin mở rộng
+
+* [wikipedia](https://vi.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/vi-vn/less-vi.html.markdown b/vi-vn/less-vi.html.markdown
new file mode 100644
index 00000000..594ccc31
--- /dev/null
+++ b/vi-vn/less-vi.html.markdown
@@ -0,0 +1,395 @@
+---
+language: less
+contributors:
+ - ["Saravanan Ganesh", "http://srrvnn.me"]
+translators:
+ - ["Thanh Duy Phan", "https://github.com/thanhpd"]
+filename: learnless-vi.less
+lang: vi-vn
+---
+
+Less là một CSS pre-processor (bộ tiền xử lí CSS), nó thêm các tính năng như biến (variable), lồng (nesting), mixin và nhiều thứ khác. Less cùng với các CSS pre-processor khác như [Sass](http://sass-lang.com/) giúp lập trình viên viết được các đoạn CSS bảo trì được và không bị lặp lại (DRY - Don't Repeat Yourself).
+
+```css
+
+
+// Comment (chú thích) một dòng sẽ bị xóa khi Less được biên dịch thành CSS
+
+/* Comment trên nhiều dòng sẽ được giữ lại */
+
+
+
+/* Biến
+==============================*/
+
+
+/* Ta có thể lưu giá trị CSS (ví dụ như color) vào một biến.
+ Sử dụng ký hiệu '@' để khai báo một biến. */
+
+@primary-color: #a3a4ff;
+@secondary-color: #51527f;
+@body-font: 'Roboto', sans-serif;
+
+/* Sau khi khai báo biến, ta có thể sử dụng nó ở trong tệp stylesheet.
+ Nhờ sử dụng biến ta chỉ cần thay đổi một lần
+ tại 1 nơi để thay đổi tất cả những đoạn sử dụng biến */
+
+body {
+ background-color: @primary-color;
+ color: @secondary-color;
+ font-family: @body-font;
+}
+
+/* Đoạn code trên sẽ được biên dịch thành: */
+
+body {
+ background-color: #a3a4ff;
+ color: #51527F;
+ font-family: 'Roboto', sans-serif;
+}
+
+
+/* Cách sử dụng này giúp ta dễ dàng bảo trì hơn
+ việc phải đổi giá trị mỗi lần nó xuất hiện
+ trong tệp stylesheet. */
+
+
+
+/* Mixins
+==============================*/
+
+
+/* Nếu đang viết một đoạn code cho nhiều hơn một
+ element, ta có thể sử dụng lại nó dễ dàng. */
+
+.center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+}
+
+/* Ta có thể dùng mixin chỉ bằng việc thêm selector
+ vào trong nội dung style của element khác */
+
+div {
+ .center;
+ background-color: @primary-color;
+}
+
+/* Đoạn code trên sẽ được biên dịch thành: */
+
+.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;
+}
+
+/* Ta có thể ngăn không cho code mixin được biên dịch
+ bằng cách thêm cặp ngoặc tròn đằng sau selector */
+
+.center() {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+}
+
+div {
+ .center;
+ background-color: @primary-color;
+}
+
+/* Đoạn code trên sẽ được biên dịch thành: */
+div {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+ background-color: #a3a4ff;
+}
+
+
+
+/* Nesting - Lồng
+==============================*/
+
+
+/* Less cho phép ta có thể lồng selector bên trong selector */
+
+ul {
+ list-style-type: none;
+ margin-top: 2em;
+
+ li {
+ background-color: #f00;
+ }
+}
+
+/* Selector bắt đầu bằng ký tự '&' sẽ thay thế ký tự '&'
+ với selector cha. */
+/* Ta cũng có thể lồng các pseudo-class với nhau */
+/* Nên lưu ý không nên lồng quá nhiều lần sẽ làm code kém tính bảo trì.
+ Kinh nghiệm cho thấy không nên lồng quá 3 lần.
+ Ví dụ: */
+
+ul {
+ list-style-type: none;
+ margin-top: 2em;
+
+ li {
+ background-color: red;
+
+ &:hover {
+ background-color: blue;
+ }
+
+ a {
+ color: white;
+ }
+ }
+}
+
+/* Biên dịch thành: */
+
+ul {
+ list-style-type: none;
+ margin-top: 2em;
+}
+
+ul li {
+ background-color: red;
+}
+
+ul li:hover {
+ background-color: blue;
+}
+
+ul li a {
+ color: white;
+}
+
+
+
+/* Function
+==============================*/
+
+
+/* Less cung cấp các function có thể được dùng để hoàn thành
+ các công việc khác nhau. */
+
+/* Function được gọi sử dụng tên của nó và truyền vào
+ các tham số được yêu cầu. */
+
+body {
+ width: round(10.25px);
+}
+
+.header {
+ background-color: lighten(#000, 0.5);
+}
+
+.footer {
+ background-color: fadeout(#000, 0.25)
+}
+
+/* Biên dịch thành: */
+
+body {
+ width: 10px;
+}
+
+.header {
+ background-color: #010101;
+}
+
+.footer {
+ background-color: rgba(0, 0, 0, 0.75);
+}
+
+/* Ta có thể định nghĩa function mới.
+ Function khá tương tự với mixin bởi chúng đều có thể được tái
+ sử dụng. Khi lựa chọn giữa việc sử dụng function hay mixin,
+ hãy nhớ mixin được tối ưu cho việc tạo ra CSS trong khi
+ function sẽ được sử dụng tốt hơn cho logic sẽ được sử dụng
+ xuyên suốt Less code. Các ví dụ trong phần 'Toán tử' là ứng cử viên
+ sáng giá cho việc dùng function có thể tái sử dụng được.
+*/
+
+/* Function này tính giá trị trung bình của hai số: */
+.average(@x, @y) {
+ @average-result: ((@x + @y) / 2);
+}
+
+div {
+ .average(16px, 50px); // gọi mixin
+ padding: @average-result; // sử dụng giá trị trả về của mixin
+}
+
+/* Biên dịch thành: */
+
+div {
+ padding: 33px;
+}
+
+
+
+/* Mở rộng (Thừa kế)
+==============================*/
+
+
+/* Mở rộng là cách để chia sẻ thuộc tính của một selector cho selector khác */
+
+.display {
+ height: 50px;
+}
+
+.display-success {
+ &:extend(.display);
+ border-color: #22df56;
+}
+
+/* Biên dịch thành: */
+.display,
+.display-success {
+ height: 50px;
+}
+.display-success {
+ border-color: #22df56;
+}
+
+/* Nên mở rộng một khai báo CSS có trước thay vì tạo một mixin mới
+ bởi cách nó nhóm các lớp có chung một style gốc.
+ Nếu thực hiện với mixin, các thuộc tính sẽ bị trùng lặp
+ cho mỗi khai báo có sử dụng mixin. Mặc dù không ảnh hưởng đến luồng công việc nhưng nó
+ tạo ra các đoạn code CSS thừa sau khi được biên dịch.
+*/
+
+
+/* Partials and Imports - Chia nhỏ và nhập vào
+==============================*/
+
+
+/* Less cho phép ta tạo các partial file (tệp con).
+ Sử dụng nó giúp ta có thể tổ chức code Less theo mô-đun có hệ thống.
+ Các tệp con thường bắt đầu với ký tự gạch dưới '_', vd: _reset.less
+ và được nhập vào file Less chính để được biên dịch thành CSS */
+
+/* Quan sát ví dụ sau, ta sẽ đặt đoạn code dưới đây vào tệp tên là _reset.less */
+
+html,
+body,
+ul,
+ol {
+ margin: 0;
+ padding: 0;
+}
+
+/* Less cung cấp cú pháp @import cho phép nhập các partial vào một file.
+ Cú pháp này trong Less sẽ nhập các file và kết hợp chúng lại với
+ code CSS được sinh ra. Nó khác với cú pháp @import của CSS,
+ bản chất là tạo một HTTP request mới để tải về tệp tin được yêu cầu. */
+
+@import 'reset';
+
+body {
+ font-size: 16px;
+ font-family: Helvetica, Arial, Sans-serif;
+}
+
+/* Biên dịch thành: */
+
+html, body, ul, ol {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ font-size: 16px;
+ font-family: Helvetica, Arial, Sans-serif;
+}
+
+
+
+/* Toán học
+==============================*/
+
+
+/* Less cung cấp các toán tử sau: +, -, *, / và %.
+ Điều này rất có ích cho việc tính toán giá trị trực tiếp
+ trong tệp Less thay vì phải tính toán thủ công.
+ Dưới đây là ví dụ về việc tạo một khung thiết kế đơn giản có hai cột. */
+
+@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;
+}
+
+/* Biên dịch thành: */
+
+body {
+ width: 100%;
+}
+
+.main-content {
+ width: 62.5%;
+}
+
+.sidebar {
+ width: 31.25%;
+}
+
+.gutter {
+ width: 6.25%;
+}
+
+
+```
+
+## Tập sử dụng Less
+
+Nếu bạn cần xài thử Less trên trình duyệt, hãy ghé qua:
+* [Codepen](http://codepen.io/)
+* [LESS2CSS](http://lesscss.org/less-preview/)
+
+## Tính tương thích
+
+Less có thể được dùng trong bất kì dự án nào miễn là ta có chương trình để biên dịch nó thành CSS. Ta cần chắc chắn rằng đoạn CSS đang dùng tương thích với các phiên bản trình duyệt mong muốn.
+
+[QuirksMode CSS](http://www.quirksmode.org/css/) và [CanIUse](http://caniuse.com) là nguồn thông tin tin cậy để kiểm tra tính tương thích của mã CSS.
+
+## Tìm hiểu thêm
+* [Tài liệu chính thức](http://lesscss.org/features/)
+* [Less CSS - Hướng dẫn cho người mới bắt đầu](http://www.hongkiat.com/blog/less-basic/) \ No newline at end of file
diff --git a/vi-vn/markdown-vi.html.markdown b/vi-vn/markdown-vi.html.markdown
new file mode 100644
index 00000000..89b59253
--- /dev/null
+++ b/vi-vn/markdown-vi.html.markdown
@@ -0,0 +1,325 @@
+---
+language: markdown
+contributors:
+ - ["Dan Turkel", "http://danturkel.com/"]
+ - ["Jacob Ward", "http://github.com/JacobCWard/"]
+translators:
+ - ["Thanh Duy Phan", "https://github.com/thanhpd"]
+filename: markdown-vi.md
+lang: vi-vn
+---
+
+
+Ngôn ngữ Markdown được sáng lập bởi John Gruber vào năm 2004. Nó được tạo ra với mục đích dễ đọc với cú pháp có thể được dễ dàng chuyển đổi qua HTML và các ngôn ngữ khác
+
+Markdown có sự khác biệt trong cách cài đặt giữa các trình phân tích cú pháp. Hướng dẫn này sẽ đề cập, giải thích tới nếu tính năng có thể được sử dụng chung hay nó chỉ áp dụng cho một trình phân tích riêng biệt.
+
+- [Phần tử HTML](#html-elements)
+- [Đầu mục](#headings)
+- [Định dạng văn bản](#simple-text-styles)
+- [Đoạn văn](#paragraphs)
+- [Danh sách](#lists)
+- [Khối code](#code-blocks)
+- [Đường kẻ ngang](#horizontal-rule)
+- [Liên kết](#links)
+- [Ảnh](#images)
+- [Khác](#miscellany)
+
+## Phần tử HTML
+Markdown là tập cha của HTML, vì vậy bất cứ file HTML nào đều là Markdown đúng.
+
+```md
+<!-- Điều này đồng nghĩa ta có thể sử dụng các phần tử HTML
+trong Markdown, ví dụ như phần tử chú thích/comment.
+Tuy nhiên, nếu sử dụng một phần tử HTML trong file Markdown,
+ta không thể sử dụng cú pháp Markdown cho nội dung bên trong phần tử đó. -->
+```
+
+## Đầu mục
+
+Ta có thể tạo các phần tử đầu mục HTML từ `<h1>` cho đến `<h6>` dễ dàng
+bằng cách thêm số lượng dấu thăng (#) đằng trước chuỗi cần tạo đầu mục.
+
+```md
+# Đây là đầu mục <h1>
+## Đây là đầu mục <h2>
+### Đây là đầu mục <h3>
+#### Đây là đầu mục <h4>
+##### Đây là đầu mục <h5>
+###### Đây là đầu mục <h6>
+```
+Markdown còn cung cấp cách khác để tạo đầu mục hạng nhất h1 và hạng nhì h2.
+
+```md
+Đây là đầu mục h1
+=============
+
+Đây là đầu mục h2
+-------------
+```
+
+## Định dạng văn bản
+
+Văn bản có thể được định dạng dễ dàng như in nghiêng hay làm đậm sử dụng Markdown.
+
+```md
+*Đoạn văn bản này được in nghiêng.*
+_Và đoạn này cũng như vậy._
+
+**Đoạn văn bản này được in đậm.**
+__Và đoạn này cũng vậy.__
+
+***Đoạn văn bản này được in nghiêng và đậm.***
+**_Cách này cũng tương tự_**
+*__Và cách này nữa__*
+```
+
+Trong cài đặt Markdown để hiển thị file của GitHub,ta còn có gạch ngang:
+
+```md
+~~Đoạn văn bản này được gạch ngang.~~
+```
+## Đoạn văn
+
+Đoạn văn bao gồm một hay nhiều dòng văn bản liên tiếp nhau được phân cách
+bởi một hay nhiều dòng trống.
+
+```md
+Đây là đoạn văn thứ nhất.
+
+Đây là đoạn văn thứ hai.
+Dòng này vẫn thuộc đoạn văn thứ hai, do không có cách dòng.
+
+
+Đây là đoạn văn thứ ba.
+```
+
+Nếu cần chèn thêm thẻ ngắt dòng `<br />` của HTML, ta có thể kết thúc đoạn văn bản
+bằng cách thêm vào từ 2 dấu cách (space) trở lên và bắt đầu đoạn văn bản mới.
+
+```md
+Dòng này kết thúc với 2 dấu cách (highlight để nhìn thấy).
+
+Có phần tử <br /> ở bên trên.
+```
+
+Khối trích dẫn được sử dụng với kí tự >
+
+```md
+> Đây là khối trích dẫn. Ta có thể
+> ngắt dòng thủ công và thêm kí tự `>` trước mỗi dòng hoặc ta có thể để dòng tự ngắt nếu cần thiệt khi quá dài.
+> Không có sự khác biệt nào, chỉ cần nó bắt đầu với kí tự `>`
+
+> Ta còn có thể dùng nhiều mức
+>> của khối trích dẫn.
+> Như vậy có tốt không?
+
+```
+
+## Danh sách
+
+Danh sách không có thứ tự có thể được tạo sử dụng dấu sao, dấu cộng hay dấu trừ đầu dòng.
+
+```md
+* Một mục
+* Một mục
+* Một mục nữa
+
+hoặc
+
++ Một mục
++ Một mục
++ Một mục khác
+
+hay
+
+- Một mục
+- Một mục
+- Một mục sau
+```
+
+Danh sách có thứ tự được tạo bởi một số theo sau bằng một dấu chấm.
+
+```md
+1. Mục thứ nhất
+2. Mục thứ hai
+3. Mục thứ ba
+```
+
+Ta không nhất thiết phải điền số thứ thự cho chỉ mục đúng mà Markdown sẽ tự hiển thị danh sách theo thứ tự đã được sắp xếp, tuy nhiên cách làm này không tốt!
+
+```md
+1. Mục thứ nhất
+1. Mục thứ hai
+1. Mục thứ ba
+```
+(Sẽ hiển thị như ví dụ trước đó)
+
+Ta còn có thể sử dụng danh sách con
+
+```md
+1. Mục thứ nhất
+2. Mục thứ hai
+3. Mục thứ ba
+ * Mục nhỏ
+ * Mục nhỏ
+4. Mục thứ tư
+```
+
+Markdown còn cung cấp danh mục (checklist). Nó sẽ hiển thị ra hộp đánh dấu dạng HTML.
+
+```md
+Boxes below without the 'x' are unchecked HTML checkboxes.
+- [ ] First task to complete.
+- [ ] Second task that needs done
+This checkbox below will be a checked HTML checkbox.
+- [x] This task has been completed
+```
+
+## Khối code
+
+Ta có thể đánh dấu một đoạn code (tương tự sử dụng phần tử HTML `<code>`) bằng việc thụt đầu dòng sử dụng bốn dấu cách (space) hoặc một dấu nhảy (tab)
+
+```md
+ This is code
+ So is this
+```
+
+Ta còn có thể thêm dấu nhảy (hoặc thêm vào bốn dấu cách nữa) để căn chỉnh phần bên trong đoạn code
+
+```md
+ my_array.each do |item|
+ puts item
+ end
+```
+
+Code hiển thị cùng dòng có thể được đánh dấu sử dụng cặp ``.
+
+```md
+John didn't even know what the `go_to()` function did!
+```
+
+Trong Markdown của GitHub, ta còn có thêm cách để hiển thị code:
+
+<pre>
+<code class="highlight">&#x60;&#x60;&#x60;ruby
+def foobar
+ puts "Hello world!"
+end
+&#x60;&#x60;&#x60;</code></pre>
+
+The above text doesn't require indenting, plus GitHub will use syntax
+highlighting of the language you specify after the \`\`\`
+Đoạn trên không cần sử dụng thụt đầu dòng, và GitHub sẽ tô sáng cú pháp sử dụng ngôn ngữ mà ta cung cấp sau đoạn kí tự \`\`\`
+
+## Kẻ ngang
+
+Dòng kẻ ngang (`<hr />`) có thể được thêm vào dễ dàng sử dụng từ 3 kí tự sao (*) hoặc gạch ngang (-), không quan trọng có khoảng cách giữa các kí tự hay không.
+
+
+```md
+***
+---
+- - -
+****************
+```
+
+## Liên kết
+
+Một trong những thứ tốt nhất khi làm việc với Markdown là khả năng tạo liên kết hết sức dễ dàng. Đoạn text hiển thị được đóng trong cặp ngoặc vuông [] kèm theo đường dẫn url trong cặp ngoặc tròn ().
+
+```md
+[Click me!](http://test.com/)
+```
+Ta còn có thể tạo tiêu đề cho liên kết sử dụng cặp ngoặc nháy bên trong cặp ngoặc tròn
+
+```md
+[Click me!](http://test.com/ "Link to Test.com")
+```
+Đường dẫn tương đối cũng hoạt động.
+
+```md
+[Go to music](/music/).
+```
+
+Markdown còn hỗ trợ liên kết kiểu tham chiếu.
+
+<pre><code class="highlight">&#x5b;<span class="nv">Nhấn vào đây</span>][<span class="ss">link1</span>] để xem thêm!
+&#x5b;<span class="nv">Ngoài ra nhấn vào đây</span>][<span class="ss">foobar</span>] nếu bạn muốn xem qua.
+
+&#x5b;<span class="nv">link1</span>]: <span class="sx">http://test.com/</span> <span class="nn">"Tuyệt!"</span>
+&#x5b;<span class="nv">foobar</span>]: <span class="sx">http://foobar.biz/</span> <span class="nn">"Tốt!"</span></code></pre>
+
+Tiêu đề có thể được đóng trong dấu nháy hay ngoặc đơn, hoặc có thể được bỏ qua. Tham chiếu có thể được đặt bất kì đâu trong văn bản và ID của tham chiếu có thể là bất kì gì miễn là nó độc nhất.
+
+Ngoài ra còn có kiểu đặt tên ngầm cho phép ta sử dụng đường dẫn làm ID.
+
+<pre><code class="highlight">&#x5b;<span class="nv">This</span>][] is a link.
+
+&#x5b;<span class="nv">this</span>]: <span class="sx">http://thisisalink.com/</span></code></pre>
+
+Nhưng nó không được sử dụng rộng rãi.
+
+## Ảnh
+
+Hiển thị ảnh tương tự như liên kết nhưng có thêm dấu chấm than đằng trước
+
+```md
+![Thuộc tính alt cho ảnh](http://imgur.com/myimage.jpg "Tiêu đề tùy chọn")
+```
+
+Và kiểu tham chiếu cũng hoạt động như vậy.
+
+<pre><code class="highlight">!&#x5b;<span class="nv">Đây là thuộc tính alt.</span>][<span class="ss">myimage</span>]
+
+&#x5b;<span class="nv">myimage</span>]: <span class="sx">relative/urls/cool/image.jpg</span> <span class="nn">"Đây là tiêu đề"</span></code></pre>
+
+## Khác
+
+### Tự động đặt liên kết
+
+```md
+<http://testwebsite.com/> tương đương với
+[http://testwebsite.com/](http://testwebsite.com/)
+```
+
+### Tự động đặt liên kết cho email
+
+```md
+<foo@bar.com>
+```
+
+### Hiển thị Kí tự đặc biệt
+
+```md
+Khi ta muốn viết *đoạn văn bản này có dấu sao bao quanh* nhưng ta không muốn nó bị in nghiêng, ta có thể sử dụng: \*đoạn văn bản này có dấu sao bao quanh\*.
+```
+
+### Phím bàn phím
+
+Trong Markdown của Github, ta có thể sử dụng thẻ `<kbd>` để thay cho phím trên bàn phím.
+
+```md
+Máy treo? Thử bấm tổ hợp
+<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd>
+```
+### Bảng biểu
+
+Bảng biểu được hỗ trợ trên Markdown của GitHub, Jira, Trello, v.v và khá khó viết:
+
+```md
+| Cột 1 | Cột2 | Cột 3 |
+| :----------- | :------: | ------------: |
+| Căn trái | Căn giữa | Căn phải |
+| blah | blah | blah |
+```
+Hoặc có thể sử dụng kết quả dưới đây
+
+```md
+Cột 1 | Cột 2 | Cột 3
+:-- | :-: | --:
+blah | blah | blah
+```
+
+---
+Để biết thêm thông tin, hãy ghé qua hướng dẫn chính thức về cú pháp của John Gruber [tại đây](http://daringfireball.net/projects/markdown/syntax) và cheatsheet của Adam Pritchard [tại đây](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).
diff --git a/vi-vn/python-vi.html.markdown b/vi-vn/python-vi.html.markdown
new file mode 100644
index 00000000..89e51d5d
--- /dev/null
+++ b/vi-vn/python-vi.html.markdown
@@ -0,0 +1,914 @@
+---
+language: Python
+filename: learnpython-vi.py
+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:
+ - ["Xuan (Sean) Luong, https://github.com/xuanluong"]
+lang: vi-vn
+
+---
+
+Python được tạo ra bởi Guido van Rossum vào đầu những năm 90s. Ngày nay nó là một trong những ngôn ngữ phổ biến
+nhất còn tồn tại. Tôi thích Python vì sự rõ ràng, trong sáng về mặt cú pháp. Về cơ bản, Python có thể coi
+như một loại mã giả (pseudocode) có thể thực thi được.
+
+Mọi phản hồi đều sẽ được tích cực ghi nhận! Bạn có thể liên lạc với tôi qua Twitter [@louiedinh](http://twitter.com/louiedinh) hoặc louiedinh [at] [google's email service]
+
+Lưu ý: Bài viết này áp dụng riêng cho Python 3. Truy cập [vào đây](http://learnxinyminutes.com/docs/pythonlegacy/) nếu bạn muốn học phiên bản cũ Python 2.7
+
+```python
+
+# Dòng bình luận (comment) bắt đầu bằng dấu thăng (#)
+
+""" Những chuỗi ký tự (string) nằm trên nhiều dòng
+ có thể được viết bằng cách dùng 3 dấu nháy " và thường
+ được dùng trong quá trình viết tài liệu (documentation).
+"""
+
+####################################################
+## 1. Các kiểu dữ liệu cơ bản và Các phép toán
+####################################################
+
+# Bạn có những con số
+3 # => 3
+
+# Tính toán với những con số là những điều có thể bạn sẽ làm
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7.0
+
+# Kết quả của phép chia số nguyên sẽ được làm tròn xuống cho cả số dương và số âm
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # phép chia số nguyên cũng áp dụng được cho kiểu dữ liệu float biểu diễn số thực
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
+
+# Kết quả của phép chia luôn là số thực
+10.0 / 3 # => 3.3333333333333335
+
+# Phép toán lấy phần dư (modulo)
+7 % 3 # => 1
+
+# Phép lũy thừa (x**y, x lũy thừa y)
+2**3 # => 8
+
+# Áp đặt thứ tự tính toán bằng dấu ngoặc
+(1 + 3) * 2 # => 8
+
+# Kiểu Boolean cũng là một kiểu dữ liệu cơ bản (Lưu ý: ký tự đầu tiên viết hoa)
+True
+False
+
+# Phủ định bằng từ khóa 'not'
+not True # => False
+not False # => True
+
+# Các phép toán với kiểu Boolean
+# Lưu ý từ khóa "and" và "or" là case-sensitive
+True and False # => False
+False or True # => True
+
+# Lưu ý khi sử dụng các phép toán của kiểu Boolean với số nguyên 'int'
+# False là 0 và True là 1
+# Đừng nhầm lẫn các phép toán Boolean cho số nguyên và các phép toán and/or trên bit (& và |)
+0 and 2 # => 0
+-5 or 0 # => -5
+0 == False # => True
+2 == True # => False
+1 == True # => True
+-5 != False != True #=> True
+
+# So sánh bằng với ==
+1 == 1 # => True
+2 == 1 # => False
+
+# So sánh không bằng với !=
+1 != 1 # => False
+2 != 1 # => True
+
+# Các phép so sánh khác
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# Các phép so sánh có thể xâu chuỗi với nhau!
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# (is vs. ==) từ khóa is kiểm tra xem 2 biến có cùng tham chiếu một đối tượng, còn == kiếm tra
+# xem hai đối tượng có cùng giá trị hay không.
+a = [1, 2, 3, 4] # a trỏ tới một danh sách (list) mới, [1, 2, 3, 4]
+b = a # b trỏ tới nơi mà a cũng đang trỏ tới
+b is a # => True, a và b cùng trỏ tới một đối tượng
+b == a # => True, đối tượng mà a và b trỏ tới có cùng giá trị
+b = [1, 2, 3, 4] # b trỏ tới một danh sách mới, [1, 2, 3, 4]
+b is a # => False, a và b không cùng trỏ tới một đối tượng
+b == a # => True, đối tượng mà a và b trỏ tới không có cùng giá trị
+
+# Chuỗi ký tự được tạo ra bằng dấu nháy kép " hoặc nháy đơn '
+"Đây là một chuỗi ký tự."
+'Đây cũng là một chuỗi ký tự.'
+
+# Chuỗi ký tự có thể được cộng với nhau can be added too! Tuy nhiên nên tránh làm như vậy
+"Xin " + "chào!" # => "Xin chào!"
+# Các chuỗi ký tự không phải là biến (literals) có thể được nối với nhau mà không cần dùng phép cộng '+'
+"Xin " "chào!" # => "Xin chào!"
+
+# Một chuỗi ký tự có thể xem như một danh sách (list) các ký tự
+"Đây là một chuỗi ký tự"[0] # => 'Đ'
+
+# Bạn có thể tìm chiều dài một chuỗi
+len("Đây là một chuỗi") # => 16
+
+# .format có thể được dùng để định dạng chuỗi, ví dụ như:
+"{} có thể được {}".format("Chuỗi ký tự", "định dạng") # => "Chuỗi ký tự có thể được định dạng"
+
+# Bạn có thể lặp lại đối số (arguments) khi định dạnh để không phải gõ nhiều lần
+"{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"
+
+# Bạn có thể dùng từ khóa nếu bạn không muốn đếm
+"{name} wants to eat {food}".format(name="Bob", food="lasagna") # => "Bob wants to eat lasagna"
+
+# Nếu code Python 3 của bạn cần phải chạy với Python 2.5 hoặc các bản cũ hơn, bạn cũng có thể
+# dùng cách định dạng cũ:
+"%s can be %s the %s way" % ("Strings", "interpolated", "old") # => "Strings can be interpolated the old way"
+
+
+# None là một đối tượng
+None # => None
+
+# Đừng dùng so sánh bằng "==" để so sánh đối tượng với None
+# Thay vào đó dùng is. Nó sẽ kiểm tra xem một đối tượng có đồng nhất với None hay không.
+"etc" is None # => False
+None is None # => True
+
+# None, 0, và chuỗi/danh sách (list)/từ điển (dict)/tuple rỗng khi chuyển về kiểu Boolean đều có giá trị là False.
+# Tất cả những giá trị khác đều là True
+bool(0) # => False
+bool("") # => False
+bool([]) # => False
+bool({}) # => False
+bool(()) # => False
+
+####################################################
+## 2. Biến và Các kiểu dữ liệu gộp (Collections)
+####################################################
+
+# Hàm print trong Python
+print("Tôi là Python. Rất hân hạnh được làm quen!") # => Tôi là Python. Rất hân hạnh được làm quen!
+
+# Hàm print mặc định in thêm ký tự xuống dòng
+# Dùng đối số tùy chọn (optional argument) để thay đổi cách kết thúc chuỗi.
+print("Hello, World", end="!") # => Hello, World!
+
+# Một cách đơn giản để lấy dữ liệu vào từ bàn phím
+input_string_var = input("Nhập dữ liệu: ") # Trả về dữ liệu vào là một chuỗi
+# Lưu ý: Trong những phiên bản cũ của Python input() có tên là raw_input()
+
+# Không cần phải khai báo biến mà chỉ có gán giá trị cho biến.
+# Quy ước là sử dụng chữ_viết_thường_có_dấu_gạch_dưới
+some_var = 5
+some_var # => 5
+
+# Truy cập một biến chưa được gán trước đó sẽ tạo ra biệt lệ (exception).
+# Đọc mục Luồng điều khiển để hiểu thêm về việc giải quyết các biệt lệ (exception handling)
+some_unknown_var # Sinh ra một biệt lệ kiểu NameError
+
+# if có thể dùng như một biểu thức
+# Tương đương với phép toán ba ngôi trong C: '?:'
+"yahoo!" if 3 > 2 else 2 # => "yahoo!"
+
+# Kiểu danh sách (list) lưu trữ chuỗi đối tượng tuần tự
+li = []
+# Bạn có thể bắt đầu với một danh sách đã có sãn các phần tử
+other_li = [4, 5, 6]
+
+# Thêm phần tử vào cuối danh sách bằng phương thức append
+li.append(1) # li bây giờ là [1]
+li.append(2) # li bây giờ là [1, 2]
+li.append(4) # li bây giờ là [1, 2, 4]
+li.append(3) # li bây giờ là [1, 2, 4, 3]
+# Xóa phần tử cuối cùng bằng phương thức pop
+li.pop() # => 3 and li is now [1, 2, 4]
+# Sau đó ta có thể đưa đối tượng trở lại danh sách
+li.append(3) # li trở lại là [1, 2, 4, 3].
+
+# Truy cập một danh sách như bạn làm với một mảng (array)
+li[0] # => 1
+# Truy cập phần tử cuối cùng
+li[-1] # => 3
+
+# Truy cập ngoài giới hạn sẽ tạo ra biệt lệ IndexError
+li[4] # Sinh ra một biệt lệ kiểu IndexError
+
+# Bạn có thể truy cập một đoạn bằng phép cắt (slice).
+# Chỉ mục bắt đầu được tính làm điểm bắt đầu còn chỉ mục kết thúc thì không, mà là chỉ mục của phần tử tiếp theo phần tử kết thúc
+# (Về mặt toán học thì đây là một đoạn đóng/mở, hay nửa đoạn)
+li[1:3] # => [2, 4]
+# Lấy từ vị trí thứ 3 đến hết
+li[2:] # => [4, 3]
+# Lấy từ đầu đến vị trí thứ 3
+li[:3] # => [1, 2, 4]
+# Lấy những phần tử có chỉ mục chẵn
+li[::2] # =>[1, 4]
+# Trả về bản sao của danh sách bị đảo ngược
+li[::-1] # => [3, 4, 2, 1]
+# Kết hợp 3 tham số để làm những phép cắt phức tạp hơn
+# li[start:end:step]
+
+# Tạo ra một bản sao sâu (deep copy) bằng phép cắt
+li2 = li[:] # => li2 = [1, 2, 4, 3] but (li2 is li) will result in false.
+
+# Xóa phần tử nào đó của danh sách bằng "del"
+del li[2] # li is now [1, 2, 3]
+
+# Xóa đi phần tử đầu tiên mang một giá trị nhất định
+li.remove(2) # li bây giờ là [1, 3]
+li.remove(2) # Sinh ra biệt lệ kiểu ValueError vì 2 không tồn tại trong danh sách
+
+# Chèn một phần tử vào một vị trí cụ thể
+li.insert(1, 2) # li bây giờ lại là [1, 2, 3]
+
+# Tìm chỉ mục của của phần tử đầu tiên mang một giá trị nhất định
+li.index(2) # => 1
+li.index(4) # Sinh ra biệt lệ a ValueError as 4 is not in the list
+
+# Bạn có thể cộng dồn các danh sách
+# Lưu ý: giá trị của li và other_li không đổi
+li + other_li # => [1, 2, 3, 4, 5, 6]
+
+# Nối danh sách bằng "extend()"
+li.extend(other_li) # Now li is [1, 2, 3, 4, 5, 6]
+
+# Kiểm tra sự tồn tại của một phần tử trong danh sách bằng "in"
+1 in li # => True
+
+# Xác định độ dài bằng "len()"
+len(li) # => 6
+
+
+# Tuple cũng giống như danh sách nhưng không thể thay đổi giá trị được (immutable)
+tup = (1, 2, 3)
+tup[0] # => 1
+tup[0] = 3 # Sinh ra biệt lệ kiểu TypeError
+
+# Lưu ý rằng tuple có độ dài là 1 phải có dấu phẩy theo sau phần tử cuối
+# nhưng tuples có độ dài khác, ngay cả tuple rỗng, thì không cần như vậy
+type((1)) # => <class 'int'>
+type((1,)) # => <class 'tuple'>
+type(()) # => <class 'tuple'>
+
+# Hầu hết các phép toán của danh sách đều áp dụng được cho tuples
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# Bạn có thể gán giá trị cho nhiều biến một lúc bằng tuple (tuple unpacking)
+a, b, c = (1, 2, 3) # a is now 1, b is now 2 and c is now 3
+# Sau đây là unpacking kiểu mở rộng
+a, *b, c = (1, 2, 3, 4) # a bây giờ là 1, b là [2, 3] và c là 4
+# Tuple được tự động tạo ra nếu bạn không để dấu ngoặc đơn
+d, e, f = 4, 5, 6
+# Hoán đổi hai biến trở nên dễ dàng
+e, d = d, e # d bây giờ là 5 và e là 4
+
+
+# Kiểu dữ liệu từ điển (dictionaries) lưu trữ ánh xạ từ các khóa (keys) đến các giá trị (values)
+empty_dict = {}
+# Sau đây là một từ điển có sẵn phần tử
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# Lưu ý rằng khóa của từ điển phải có kiểu dữ liệu thuộc loại immutable. Điều này để bảo đảm rằng
+# khóa đó luôn được chuyển hóa thành một giá trị băm (hash value) duy nhất khi tìm kiếm trong từ điển
+# Những kiểu immutable bao gồm số nguyên (int), số thực (float), chuỗi ký tự (string), hay tuple
+invalid_dict = {[1,2,3]: "123"} # => Sinh ra biệt lệ kiểu TypeError: unhashable type: 'list'
+valid_dict = {(1,2,3):[1,2,3]} # Tuy nhiên, giá trị có thể thuộc bất kỳ kiểu gì
+
+# Truy cập giá trị của một từ khóa bằng dấu []
+filled_dict["one"] # => 1
+
+# Tất cả khóa trong một từ điển có thể được chuyển thành một đối tượng khả lặp (iterable).
+# Chúng ta cần phải gọi hàm list() để chuyển một iterable thành một danh sách.
+# Chúng ta sẽ bàn về vấn đề này sau. Lưu ý - Thứ tự của khóa trong từ điển sẽ không được đảm bảo.
+# Những gì bạn thấy khi chạy dòng code dưới đây có thể sẽ không hoàn toàn giống như vậy.
+list(filled_dict.keys()) # => ["three", "two", "one"]
+
+
+# Tất cả các giá trị có thể chuyển thành một đối tượng khả lặp bằng cách gọi hàm "values()".
+# Chúng ta cũng vẫn phải gọi hàm list() nếu muốn chuyển nó thành một danh sách. Lưu ý - thứ
+# tự của giá trị cũng không được đảm bảo
+list(filled_dict.values()) # => [3, 2, 1]
+
+
+# Sự tồn tại của khóa trong từ điển có thể kiểm tra được thông qua từ khóa "in"
+"one" in filled_dict # => True
+1 in filled_dict # => False
+
+# Truy xuất giá trị của một khóa không tồn tại trong từ điển sẽ tạo ra biệt lệ KeyError
+filled_dict["four"] # KeyError
+
+# Dừng phương thức "get()" để tránh tạo ra biệt lệ KeyError
+filled_dict.get("one") # => 1
+filled_dict.get("four") # => None
+# Phương thức get hỗ trợ một đối số mặt định khi không thể tìm thấy giá trị ứng với từ khóa
+filled_dict.get("one", 4) # => 1
+filled_dict.get("four", 4) # => 4
+
+# "setdefault()" chèn một giá trị ứng với khóa nếu khóa đó không có sẵn trong từ điển
+filled_dict.setdefault("five", 5) # filled_dict["five"] is set to 5
+filled_dict.setdefault("five", 6) # filled_dict["five"] is still 5
+
+# Thêm khóa và giá trị vào từ điển
+filled_dict.update({"four":4}) # => {"one": 1, "two": 2, "three": 3, "four": 4}
+filled_dict["four"] = 4 # another way to add to dict
+
+# Xóa một khóa ra khỏi từ điển bằng từ khóa del
+del filled_dict["one"] # Removes the key "one" from filled dict
+
+# Bắt đầu từ Python 3.5 bạn có thể unpack từ điển trong một từ điển khác
+{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2}
+{'a': 1, **{'a': 2}} # => {'a': 2}
+
+
+
+# Kiểu tập hợp (set) lưu trữ ... tập hợp
+empty_set = set()
+# Khởi tạo giá trị một tập hợp với nhiều giá tri. Vâng, nhìn nó khá giống từ điển.
+some_set = {1, 1, 2, 2, 3, 4} # some_set is now {1, 2, 3, 4}
+
+# Tương tự như khóa của từ điển, phần tử của một tập hợp cũng phải là immutable
+invalid_set = {[1], 1} # => Sinh ra biệt lệ TypeError: unhashable type: 'list'
+valid_set = {(1,), 1}
+
+# Thêm một phần tử vào tập hợp
+filled_set.add(5) # filled_set is now {1, 2, 3, 4, 5}
+
+# Thực hiện phép giao hai tập hợp bằng phép toán &
+other_set = {3, 4, 5, 6}
+filled_set & other_set # => {3, 4, 5}
+
+# Thực hiện phép hợp bằng phép toán |
+filled_set | other_set # => {1, 2, 3, 4, 5, 6}
+
+# Lấy hiệu của hai tập hơp bằng phép toán -
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+
+# Lấy hiệu đối xứng bằng phép toán ^
+{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5}
+
+# Kiểm tra tập hợp bên trái là tập cha của bên phải
+{1, 2} >= {1, 2, 3} # => False
+
+# Kiểm tra xem tập hợp bên trái có phải là tập con của tập hợp bên phải
+{1, 2} <= {1, 2, 3} # => True
+
+# Kiểm tra sự tồn tại của một phần tử trong tập hợp bằng từ khóa in
+2 in filled_set # => True
+10 in filled_set # => False
+
+
+
+####################################################
+## 3. Luồng điều khiển và kiểu khả lặp
+####################################################
+
+# Đầu tiên hãy tạo ra một biến
+some_var = 5
+
+# Sau đây là một câu lệnh if. Khoảng cách lề rất quan trọng trong Python
+# Quy ước chung là dùng khoảng trắng chứ không phải ký tự tab
+# Chuỗi sau sẽ được in ra "some_var is smaller than 10"
+if some_var > 10:
+ print("some_var is totally bigger than 10.")
+elif some_var < 10: # Phần elif là tùy chọn.
+ print("some_var is smaller than 10.")
+else: # else cũng là tùy chọn.
+ print("some_var is indeed 10.")
+
+
+"""
+Lặp qua một danh sách bằng for
+in ra:
+ dog is a mammal
+ cat is a mammal
+ mouse is a mammal
+"""
+for animal in ["dog", "cat", "mouse"]:
+ # Bạn có thể dùng format() để gán một giá trị vào giữa chuỗi (string interpolation)
+ print("{} is a mammal".format(animal))
+
+"""
+"range(number)" trả về một đối tượng khả lặp kiểu số
+từ 0 đến giá trị của number
+in ra:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print(i)
+
+"""
+"range(lower, upper)" trả về một đối tượng khả lặp kiểu số
+từ giá trị lower đến giá trị upper
+in ra:
+ 4
+ 5
+ 6
+ 7
+"""
+for i in range(4, 8):
+ print(i)
+
+"""
+"range(lower, upper, step)" trả về một đối tượng khả lặp kiểu số
+từ giá trị lower đến giá trị upper, tăng dần theo giá trị
+của step. Nếu không có giá trị của step thì mặc định là 1.
+in ra:
+ 4
+ 6
+"""
+for i in range(4, 8, 2):
+ print(i)
+"""
+
+Vòng lặp while tiếp tục lặp khi điều kiện còn được thỏa mãn
+in ra:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print(x)
+ x += 1 # cách viết ngán cho x = x + 1
+
+# Handle exceptions with a try/except block
+# Đối phó với biệt lệ bằng khối lệnh try/except
+try:
+ # Dùng "raise" để ném ra một biệt lệ
+ raise IndexError("This is an index error")
+except IndexError as e:
+ pass # pass có nghĩa là không làm gì cả. Thông thường đây là nơi để khắc phụ vấn đề làm xảy ra biệt lệ
+except (TypeError, NameError):
+ pass # Nhiều biệt lệ có thể được đối phó cùng một lúc nếu cần
+else: # Không bắt buộc phải sử dụng else nhưng nếu dùng thì nó phải sau tất cả các khối except
+ print("All good!") # Chỉ thực thi nếu không có biệt lệ phát sinh
+finally: # Luôn thực thi trong mọi hoàn cảnh
+ print("We can clean up resources here")
+
+# Thay vì dùng try/finally để thu hồi tài nguyên (resources) ta có thể dùng with
+with open("myfile.txt") as f:
+ for line in f:
+ print(line)
+
+# Python hỗ trợ kiểu dữ liệu khả lặp (iterable).
+# Một đối tượng khả lặp có thể được xem như là một chuỗi các đối tượng tuần tự (sequence)
+# Đối tượng trả về bởi hàm range là một khả lặp.
+
+filled_dict = {"one": 1, "two": 2, "three": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) # => dict_keys(['one', 'two', 'three']). Đây là một đối tượng khả lặp
+
+# Ta có thể lặp qua đối tượng
+for i in our_iterable:
+ print(i) # In ra một, hai, ba
+
+# Tuy nhiên chúng ta không thể truy cập phần tử bằng chỉ mục
+our_iterable[1] # Sinh ra biệt lệ TypeError
+
+# Một đối tượng khả lặp là đối tượng có thể tạo ra một iterator
+our_iterator = iter(our_iterable)
+
+# iterator là một đối tượng ghi nhớ được trạng thái trong quá trình nó được duyệt qua
+# đối tượng kế tiếp có thể truy cập được bằng hàm next
+next(our_iterator) # => "one"
+
+# Nó ghi nhớ trạng thái trong quá trình lặp
+next(our_iterator) # => "two"
+next(our_iterator) # => "three"
+
+# Sau khi iterator đã trả về tất cả dữ liệu, nó sẽ sinh ra biệt lệ kiểu StopIteration
+next(our_iterator) # Sinh ra biệt lệ StopIteration
+
+# Ta có thể lấy tất cả phần tử của một iterator bằng cách gọi hàm list với nó
+list(filled_dict.keys()) # => Returns ["one", "two", "three"]
+
+
+####################################################
+## 4. Hàm
+####################################################
+
+# Dùng từ khóa def để định nghĩa hàm
+def add(x, y):
+ print("x is {} and y is {}".format(x, y))
+ return x + y # từ khóa return để trả về một giá trị
+
+# Gọi một hàm với đối số
+add(5, 6) # => In ra "x is 5 and y is 6" và trả về 11
+
+# Một cách khác để gọi hàm là dùng đối số có từ khóa (keyword arguments)
+add(y=6, x=5) # Đối số có từ khóa có thể xuất hiện với thứ tự bất kỳ
+
+# Bạn có thể định nghĩa hàm có số lượng đối số vị trí (positional arguments) không biết trước
+def varargs(*args):
+ return args
+
+varargs(1, 2, 3) # => (1, 2, 3)
+
+# Số lượng tham số từ khóa cũng có thể không cần biết trước
+def keyword_args(**kwargs):
+ return kwargs
+
+# Thử gọi hàm để xem điều gì xảy ra
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
+
+
+# Có thể định nghĩa hàm dùng cả hai loại đối số
+def all_the_args(*args, **kwargs):
+ print(args)
+ print(kwargs)
+"""
+all_the_args(1, 2, a=3, b=4) in ra:
+ (1, 2)
+ {"a": 3, "b": 4}
+"""
+
+# Khi gọi hàm, bạn có thể làm ngược với khi định nghĩa
+# Dùng dấu * để lấy giá trị từ args và ** với giá trị từ kwargs
+args = (1, 2, 3, 4)
+kwargs = {"a": 3, "b": 4}
+all_the_args(*args) # tương đương với foo(1, 2, 3, 4)
+all_the_args(**kwargs) # tương đương với foo(a=3, b=4)
+all_the_args(*args, **kwargs) # tương đương với foo(1, 2, 3, 4, a=3, b=4)
+
+# Trả về nhiều giá trị (gán vào một tuple)
+def swap(x, y):
+ return y, x # Trả về nhiều giá trị dưới dạng một tuple mà không cần dấu ngoặc.
+ # (Lưu ý là dấu ngoặc đơn đã được bỏ đi những vẫn có thể được thêm vào)
+
+x = 1
+y = 2
+x, y = swap(x, y) # => x = 2, y = 1
+# (x, y) = swap(x,y) # dấu ngoặc đơn đã được bỏ đi những vẫn có thể được thêm vào
+
+# Tầm vực của hàm
+x = 5
+
+def set_x(num):
+ # Biến cục bộ x không đồng nhất với biến toàn cục x
+ x = num # => 43
+ print(x) # => 43
+
+def set_global_x(num):
+ global x
+ print(x) # => 5
+ x = num # biến toàn cục x được gán giá trị là 6
+ print(x) # => 6
+
+set_x(43)
+set_global_x(6)
+
+
+# Hàm trong Python cũng là đối tượng
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) # => 13
+
+# Có những hàm không tên
+(lambda x: x > 2)(3) # => True
+(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5
+
+# Có những hàm cấp cao được hỗ trọ sẵn
+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]
+
+# list comprehension có thể dùng để hay thế map và filter
+# list comprehension lưu giá trị xuất vào một danh sách mà bản thân nó có thể lồng trong danh sách khác
+[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]
+
+# Tập hơp và từ điển cũng có thể được tao ra thông qua set comprehension và dict comprehension
+{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. Mô đun
+####################################################
+
+# Bạn có thể import một mô đun
+import math
+print(math.sqrt(16)) # => 4.0
+
+# Bạn có thể lấy một hàm cụ thể từ một mô đun
+from math import ceil, floor
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
+
+# Hoặc import tất cả hàm từ một mô đun
+# Cảnh báo: đây không phải là một cách hay
+from math import *
+
+# Có thể làm tên của module ngắn lại
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
+
+# Mô đun trong Python chỉ là những tập tin Python bình thường. Bạn
+# có thể viết mô đun của mình và import chúng. Tên của mô đun
+# cũng là tên của tập tin.
+
+# You can find out which functions and attributes
+# are defined in a module.
+# Bạn có thể liệt kê những hàm và thuộc tính
+# được định nghĩa trong một mô đun
+import math
+dir(math)
+
+# Nếu bạn có một tập tin code Python gọi là math.py ở cùng
+# thư mục với tập tin hiện tai, tập tin math.py sẽ
+# được nạp vào thay vì mô đun được cung cấp sẵn (built-in) trong Python.
+# Điều này xảy ra vì thư mục hiện tại có ưu tiên
+# hơn những thư viện cung cấp sẵn.
+
+
+####################################################
+## 6. Lớp (classes)
+####################################################
+
+# Ta dùng từ khóa "class" đề định nghĩa một lớp
+class Human:
+
+ # Một thuộc tính của lớp được chia sẽ bởi tất cả đối tượng của lớp này
+ species = "H. sapiens"
+
+ # Hàm khởi tạo cơ bản sẽ được goi khi một đối tượng được tạo ra.
+ # Lưu ý 2 dấu gạch dưới ở đầu và cuối ám chỉ đối tượng
+ # hoặc thuộc tính dùng bở Python những tồn tại trong không gian tên
+ # do người dùng kiểm soát. Phương thức (hoặc thuộc tính) như: __init__, __str__,
+ # __repr__ v.v.. là những phương thức đặc biệt.
+ # Bạn không nên tự đặt những tên như vậy.
+ def __init__(self, name):
+ # Gán đối số vào thuộc tính name của đối tượng
+ self.name = name
+
+ # Khởi tạo thuộc tính
+ self._age = 0
+
+ # Một phương thức trên đối tượng. Tất cả đều có đối số đầu tiên là "self"
+ def say(self, msg):
+ print ("{name}: {message}".format(name=self.name, message=msg))
+
+ # Một phương thức trên đối tượng khác
+ def sing(self):
+ return 'yo... yo... microphone check... one two... one two...'
+
+ # Một phương thức trên lớp được chia sẻ với mọi đối tượng
+ # Lớp đó cũng là đối số thứ nhất của phương thức đó
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # Một phương thức tĩnh được gọi mà không có lớp hay đối tượng đi kèm
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+ # Một thuộc tính chỉ giống như một hàm truy xuất.
+ # Nó biến phương thức age() thành một thuộc tính chỉ đọc cùng tên.
+ # Tuy nhiên trong Python không nhất thiết phải viết những hàm đọc và ghi quá đơn giản
+ @property
+ def age(self):
+ return self._age
+
+ # Đây là hàm để ghi giá trị cho thuộc tính
+ @age.setter
+ def age(self, age):
+ self._age = age
+
+ # Đây là hàm để xóa thuộc tính
+ @age.deleter
+ def age(self):
+ del self._age
+
+
+# Khi trình thông dịch Python đọc một tập tin mã nguồn, nó thực thi tất cả code trong đó.
+# Kiểm tra giá trị của __name__ bảo đảm rằng đoạn mã bên dưới chỉ thực thi khi
+# mô đun này là chương trình chính
+if __name__ == '__main__':
+ # Khởi tạo một đối tượng
+ i = Human(name="Ian")
+ i.say("hi") # "Ian: hi"
+ j = Human("Joel")
+ j.say("hello") # "Joel: hello"
+ # i và j là thực thể của kiểu Human, nói cách khác: chúng là những đối tượng Human
+
+ # Gọi những phương thức trên lớp
+ i.say(i.get_species()) # "Ian: H. sapiens"
+ # Thay đổi thuộc tính chung
+ Human.species = "H. neanderthalensis"
+ i.say(i.get_species()) # => "Ian: H. neanderthalensis"
+ j.say(j.get_species()) # => "Joel: H. neanderthalensis"
+
+ # Gọi phương thức tĩnh
+ print(Human.grunt()) # => "*grunt*"
+
+ # Không thể gọi phương thức tĩnh với một thực thể/đối tượng
+ # bởi vì i.grunt() sẽ tự động đặt "self" (tức là đối tượng i) làm đối số thứ nhất
+ print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
+
+ # Thay đổi thuộc tính của đối tượng
+ i.age = 42
+ # Truy cập thuộc tính
+ i.say(i.age) # => "Ian: 42"
+ j.say(j.age) # => "Joel: 0"
+ # Xóa thuộc tính
+ del i.age
+ # i.age # => dòng nãy sẽ tạo ra biệt lệ AttributeError
+
+
+####################################################
+## 6.1 Đa thừa kế
+####################################################
+
+# Một định nghĩa lớp khác
+class Bat:
+
+ species = 'Baty'
+
+ def __init__(self, can_fly=True):
+ self.fly = can_fly
+
+ # Lớp này có phương thức say
+ def say(self, msg):
+ msg = '... ... ...'
+ return msg
+
+ # Và một phương thức khác
+ def sonar(self):
+ return '))) ... ((('
+
+if __name__ == '__main__':
+ b = Bat()
+ print(b.say('hello'))
+ print(b.fly)
+
+# Để tận dụng việc mô đun hóa thành từng tập tin, bạn có thể đặt những lớp định nghĩa ở trên vào các tập tin riêng,
+# ví dụ như human.py và bat.py
+
+# Để import hàm từ tập tin khác dừng cấu trúc sau
+# from "filename-without-extension" import "function-or-class"
+
+# superhero.py
+from human import Human
+from bat import Bat
+
+# Batman thừa kế từ lớp Human và Bat
+class Batman(Human, Bat):
+
+ # Batman có giá trị riêng cho thuộc tính trên lớp species
+ species = 'Superhero'
+
+ def __init__(self, *args, **kwargs):
+ # Cách điển hình để thừa kế thuộc tính là gọi super
+ # super(Batman, self).__init__(*args, **kwargs)
+ # Tuy nhiên với đa thừa kế, super() sẽ chỉ gọi lớp cơ sở tiếp theo trong danh sách MRO.
+ # Vì thế, ta sẽ gọi cụ thể hàm __init__ của các lớp chả.
+ # Sử dụng *args và **kwargs cho phép việc truyền đối số gọn gàng hơn,
+ # trong đó mỗi lớp cha sẽ chịu trách nhiệm cho những phần thuộc về nó
+ Human.__init__(self, 'anonymous', *args, **kwargs)
+ Bat.__init__(self, *args, can_fly=False, **kwargs)
+ # ghi đè giá trị của thuộc tính name
+ self.name = 'Sad Affleck'
+
+ def sing(self):
+ return 'nan nan nan nan nan batman!'
+
+
+if __name__ == '__main__':
+ sup = Batman()
+
+ # Kiểm tra kiểu đối tượng
+ 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')
+
+ # Truy xuất thứ tự phương thức của các lớp cha (Method Resolution search Order), vốn được dùng bởi cả getattr() và super9)
+ # Thuộc tính này động và có thể được cập nhật
+ print(Batman.__mro__) # => (<class '__main__.Batman'>, <class 'human.Human'>, <class 'bat.Bat'>, <class 'object'>)
+
+ # Gọi phương thức của lớp cha nhưng dùng thuộc tính trên chính lớp hiện tại
+ print(sup.get_species()) # => Superhero
+
+ # Gọi phương thức được nạp chồng
+ print(sup.sing()) # => nan nan nan nan nan batman!
+
+ # Gọi phương thức của Human, bởi vì thứ tự thừa kế ảnh hưởng đến phương thức được gọi
+ sup.say('I agree') # => Sad Affleck: I agree
+
+ # Gọi phương thức chỉ tồn tại ở lớp cha thứ 2
+ print(sup.sonar()) # => ))) ... (((
+
+ # Thuộc tính cấp lớp được thừa kế
+ sup.age = 100
+ print(sup.age)
+
+ # Thuộc tính thừa kế từ lớp cha thứ 2 có giá trị mặc định đã bị ghi đè
+ print('Can I fly? ' + str(sup.fly))
+
+
+
+####################################################
+## 7. Phần nâng cao
+####################################################
+
+# Generator giúp ta viết những đoạn code lười biếng (áp dụng nguyên tắc lazy evaluation)
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# Generators tiết kiệm bộ nhớ vì nó chỉ tải dữ liệu khi cần
+# xử lý giá trị kế tiếp của một đối tượng khả lặp. Điều này cho phép generator thực hiện
+# những thao tác mà bình thường không làm được trên những khoảng giá trị lớn
+# Lưu ý: `range` thay thế `xrange` trong Python3.
+
+for i in double_numbers(range(1, 900000000)): # `range` là một generator.
+ print(i)
+ if i >= 30:
+ break
+
+# Cũng như danh sách có list comprehension, generator cũng có generator
+# comprehension
+values = (-x for x in [1,2,3,4,5])
+for x in values:
+ print(x) # in -1 -2 -3 -4 -5 ra màn hình dòng lệnh
+
+# Một generator cũng có thể bị ép kiểu thành danh sách
+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
+# Trong ví dụ này hàm `beg` 'phủ lên' hàm `say`. Nếu say_please là True thì nó
+# sẽ thay đội giá trị trả về
+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, "Làm ơn! Tui rất nghèo :(")
+ return msg
+
+ return wrapper
+
+
+@beg
+def say(say_please=False):
+ msg = "Mua bia cho tui nhé?"
+ return msg, say_please
+
+
+print(say()) # Mua bia cho tui nhé?
+print(say(say_please=True)) # Mua bia cho tui nhé? Làm ơn! Tui rất nghèo :(
+```
+
+## Sẵn sàng để học nhiều hơn?
+
+### Miễn phí trên mạng
+
+* [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/vi-vn/ruby-vi.html.markdown b/vi-vn/ruby-vi.html.markdown
index 73382100..1e198205 100644
--- a/vi-vn/ruby-vi.html.markdown
+++ b/vi-vn/ruby-vi.html.markdown
@@ -1,6 +1,6 @@
---
language: ruby
-filename: learnruby.rb
+filename: learnruby-vi.rb
contributors:
- ["David Underwood", "http://theflyingdeveloper.com"]
- ["Joel Walden", "http://joelwalden.net"]
diff --git a/vi-vn/sass-vi.html.markdown b/vi-vn/sass-vi.html.markdown
new file mode 100644
index 00000000..313890d4
--- /dev/null
+++ b/vi-vn/sass-vi.html.markdown
@@ -0,0 +1,590 @@
+---
+language: sass
+filename: learnsass-vi.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:
+ - ["Thanh Duy Phan", "https://github.com/thanhpd"]
+lang: vi-vn
+---
+
+Less là một ngôn ngữ mở rộng CSS/ CSS pre-processor, thêm các tính năng như biến (variable), lồng (nesting), mixin và nhiều thứ khác. Sass cùng với các CSS pre-processor khác như [Less](http://lesscss.org/) giúp lập trình viên viết được các đoạn CSS bảo trì được và không bị lặp lại (DRY - Don't Repeat Yourself).
+
+Sass có hai lựa chọn sử dụng cú pháp khác nhau. Một là SCSS, sử dụng cú pháp giống như CSS nhưng bổ sung thêm các tính năng của Sass. Hai là Sass (cú pháp nguyên bản), sử dụng thụt đầu dòng - indention thay vì ngoặc nhọn và dấu chấm phẩy.
+Bài hướng dẫn này sử dụng SCSS.
+
+Nếu bạn đọc đã quen thuộc với CSS3 thì sẽ tương đối nhanh chóng để nắm được Sass. Nó không cung cấp thuộc tính để style CSS mới nhưng đưa ra những công cụ để có thể viết CSS hiệu quả hơn và có thể bảo trì dễ dàng hơn.
+
+```sass
+
+
+// Comment (chú thích) một dòng sẽ bị xóa khi Less được biên dịch thành CSS
+
+/* Comment trên nhiều dòng sẽ được giữ lại */
+
+
+
+/* Variable - Biến
+============================== */
+
+
+
+/* Ta có thể lưu giá trị CSS (ví dụ như color) vào một biến.
+ Sử dụng ký hiệu '$' để khai báo một biến. */
+
+$primary-color: #A3A4FF;
+$secondary-color: #51527F;
+$body-font: 'Roboto', sans-serif;
+
+/* Sau khi khai báo biến, ta có thể sử dụng nó ở trong tệp stylesheet.
+ Nhờ sử dụng biến ta chỉ cần thay đổi một lần
+ tại 1 nơi để thay đổi tất cả những đoạn sử dụng biến */
+
+body {
+ background-color: $primary-color;
+ color: $secondary-color;
+ font-family: $body-font;
+}
+
+/* Đoạn code trên sẽ được biên dịch thành: */
+body {
+ background-color: #A3A4FF;
+ color: #51527F;
+ font-family: 'Roboto', sans-serif;
+}
+
+/* Cách sử dụng này giúp ta dễ dàng bảo trì hơn
+ việc phải đổi giá trị mỗi lần nó xuất hiện
+ trong tệp stylesheet. */
+
+
+
+/* Control Directive - Chỉ thị
+============================== */
+
+
+/* Sass cho phép sử dụng @if, @else, @for, @while và @each để quản lý luồng code sinh ra CSS */
+
+/* Khối điều kiện @if/@else hoạt động như các ngôn ngữ khác */
+
+$debug: true !default;
+
+@mixin debugmode {
+ @if $debug {
+ @debug "Debug mode enabled";
+
+ display: inline-block;
+ }
+ @else {
+ display: none;
+ }
+}
+
+.info {
+ @include debugmode;
+}
+
+/* Trong đoạn code trên, nếu $debug được đặt là true thì class .info sẽ được sinh ra và ngược lại.
+ Lưu ý: @debug sẽ sinh ra thông tin debug trên dòng lệnh (command line).
+ Chế độ này rất có ích khi thực hiện debug trên file SCSS. */
+
+.info {
+ display: inline-block;
+}
+
+/* @for là khối vòng lặp trên một khoảng các giá trị.
+ Nó rất có ích cho việc đặt style của một tập hợp các phần tử.
+ Có hai cách để lặp, "through" sẽ lặp tới kể cả giá trị cuối cùng, "to" sẽ lặp tới và dừng khi đến giá trị cuối cùng. */
+
+// Lặp 3 lần (không kể 4)
+@for $c from 1 to 4 {
+ div:nth-of-type(#{$c}) {
+ left: ($c - 1) * 900 / 3;
+ }
+}
+
+// Lặp 3 lần (kể cả 3)
+@for $c from 1 through 3 {
+ .myclass-#{$c} {
+ color: rgb($c * 255 / 3, $c * 255 / 3, $c * 255 / 3);
+ }
+}
+
+/* Biên dịch thành */
+
+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 tự động chuyển mã #FFFFFF thành white (trắng)
+}
+
+/* Khối lặp @while rất cơ bản: */
+
+$columns: 4;
+$column-width: 80px;
+
+@while $columns > 0 {
+ .col-#{$columns} {
+ width: $column-width;
+ left: $column-width * ($columns - 1);
+ }
+
+ $columns: $columns - 1;
+}
+
+/* Sẽ được biên dịch thành: */
+
+.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 hoạt động giống như @for, nhưng sử dụng một danh sách (list) thay vì thứ tự số đếm.
+ List được khai báo như những biến khác, sử dụng dấu cách để làm dấu phân cách. */
+
+$social-links: facebook twitter linkedin reddit;
+
+.social-links {
+ @each $sm in $social-links {
+ .icon-#{$sm} {
+ background-image: url("images/#{$sm}.png");
+ }
+ }
+}
+
+/* Sẽ sinh ra: */
+
+.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");
+}
+
+
+/* Mixin
+==============================*/
+
+/* Nếu đang viết một đoạn code cho nhiều hơn một
+ element, ta có thể sử dụng lại nó dễ dàng.
+ Sử dụng cú pháp '@mixin' kèm theo tên để tạo một mixin. */
+
+@mixin center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+}
+
+/* Ta có thể dùng mixin bằng cú pháp '@include' kèm theo tên của mixin. */
+
+div {
+ @include center;
+ background-color: $primary-color;
+}
+
+/* Được biên dịch thành: */
+div {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ left: 0;
+ right: 0;
+ background-color: #A3A4FF;
+}
+
+/* Ta có thể dùng mixin để tạo nhanh các thuộc tính. */
+
+@mixin size($width, $height) {
+ width: $width;
+ height: $height;
+}
+
+/* Trong ví dụ này ta có thể tạo nhanh 2 thuộc tính width và height
+ bằng cách sử dụng mixin size và truyền vào tham số cho width và height. */
+
+.rectangle {
+ @include size(100px, 60px);
+}
+
+.square {
+ @include size(40px, 40px);
+}
+
+/* Biên dịch thành: */
+.rectangle {
+ width: 100px;
+ height: 60px;
+}
+
+.square {
+ width: 40px;
+ height: 40px;
+}
+
+
+
+/* Function - Hàm
+============================== */
+
+
+
+/* Less cung cấp các hàm có thể được dùng để hoàn thành
+ các công việc khác nhau. */
+
+/* Hàm được gọi sử dụng tên của nó và truyền vào
+ các tham số được yêu cầu. */
+body {
+ width: round(10.25px);
+}
+
+.footer {
+ background-color: fade_out(#000000, 0.25);
+}
+
+/* Biên dịch thành: */
+
+body {
+ width: 10px;
+}
+
+.footer {
+ background-color: rgba(0, 0, 0, 0.75);
+}
+
+/* Ta có thể định nghĩa hàm mới.
+ hàm khá tương tự với mixin bởi chúng đều có thể được tái
+ sử dụng. Khi lựa chọn giữa việc sử dụng hàm hay mixin,
+ hãy nhớ mixin được tối ưu cho việc tạo ra CSS trong khi
+ hàm sẽ được sử dụng tốt hơn cho logic sẽ được sử dụng
+ xuyên suốt Less code. Các ví dụ trong phần 'Toán tử toán học' là ứng cử viên
+ sáng giá cho việc dùng hàm có thể tái sử dụng được.
+*/
+
+/* Hàm này sẽ tính độ tương đối giữa hai giá trị kích thước. */
+
+@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);
+}
+
+/* Biên dịch thành: */
+
+.main-content {
+ width: 62.5%;
+}
+
+.sidebar {
+ width: 31.25%;
+}
+
+
+
+/* Mở rộng (Thừa kế)
+============================== */
+
+
+
+/* Mở rộng là cách để chia sẻ thuộc tính của một selector cho selector khác */
+
+.display {
+ @include size(5em, 5em);
+ border: 5px solid $secondary-color;
+}
+
+.display-success {
+ @extend .display;
+ border-color: #22df56;
+}
+
+/* Biên dịch thành: */
+.display, .display-success {
+ width: 5em;
+ height: 5em;
+ border: 5px solid #51527F;
+}
+
+.display-success {
+ border-color: #22df56;
+}
+
+/* Nên mở rộng một khai báo CSS có trước thay vì tạo một mixin mới
+ bởi cách nó nhóm các lớp có chung một style gốc.
+ Nếu thực hiện với mixin, các thuộc tính sẽ bị trùng lặp
+ cho mỗi khai báo có sử dụng mixin. Mặc dù không ảnh hưởng đến luồng công việc nhưng nó
+ tạo ra các đoạn code CSS thừa sau khi được biên dịch.
+*/
+
+
+
+/* Nesting - Lồng
+============================== */
+
+
+
+/* Sass cho phép ta có thể lồng selector bên trong selector */
+
+ul {
+ list-style-type: none;
+ margin-top: 2em;
+
+ li {
+ background-color: #FF0000;
+ }
+}
+
+/* Selector bắt đầu bằng ký tự '&' sẽ thay thế ký tự '&'
+ với selector cha. */
+/* Ta cũng có thể lồng các pseudo-class với nhau */
+/* Nên lưu ý không nên lồng quá nhiều lần sẽ làm code kém tính bảo trì.
+ Kinh nghiệm cho thấy không nên lồng quá 3 lần.
+ Ví dụ: */
+
+ul {
+ list-style-type: none;
+ margin-top: 2em;
+
+ li {
+ background-color: red;
+
+ &:hover {
+ background-color: blue;
+ }
+
+ a {
+ color: white;
+ }
+ }
+}
+
+/* Biên dịch thành: */
+
+ul {
+ list-style-type: none;
+ margin-top: 2em;
+}
+
+ul li {
+ background-color: red;
+}
+
+ul li:hover {
+ background-color: blue;
+}
+
+ul li a {
+ color: white;
+}
+
+
+
+/* Partials and Imports - Chia nhỏ thành tệp con và nhập vào
+============================== */
+
+
+/* Less cho phép ta tạo các partial file (tệp con).
+ Sử dụng nó giúp ta có thể tổ chức code Less theo mô-đun có hệ thống.
+ Các tệp con thường bắt đầu với ký tự gạch dưới '_', vd: _reset.less
+ và được nhập vào file Less chính để được biên dịch thành CSS.
+ File con không được biên dịch thành file CSS riêng. */
+
+/* Quan sát ví dụ sau, ta sẽ đặt đoạn code dưới đây vào tệp tên là _reset.less */
+
+html,
+body,
+ul,
+ol {
+ margin: 0;
+ padding: 0;
+}
+
+/* Sass cung cấp cú pháp @import cho phép nhập các partial vào một file.
+ Cú pháp này trong Sass sẽ nhập các file và kết hợp chúng lại với
+ code CSS được sinh ra. Nó khác với cú pháp @import của CSS,
+ bản chất là tạo một HTTP request mới để tải về tệp tin được yêu cầu. */
+
+@import 'reset';
+
+body {
+ font-size: 16px;
+ font-family: Helvetica, Arial, Sans-serif;
+}
+
+/* Biên dịch thành: */
+
+html, body, ul, ol {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ font-size: 16px;
+ font-family: Helvetica, Arial, Sans-serif;
+}
+
+
+
+/* Placeholder Selectors - Selector trống
+============================== */
+
+
+
+/* Khai báo trống rất hữu dụng khi ta cần tạo một khai báo CSS cần được mở rộng.
+ Nếu bạn cần tạo một khai báo CSS gốc cho các lần mở rộng sau ta có thể
+ sử dụng một khai báo trống. Khai báo trống bắt đầu với kí tự '$' thay vì
+ sử dụng '.' hay '#'. Khai báo trống sẽ không xuất hiện trong code CSS được biên dịch. */
+
+%content-window {
+ font-size: 14px;
+ padding: 10px;
+ color: #000;
+ border-radius: 4px;
+}
+
+.message-window {
+ @extend %content-window;
+ background-color: #0000ff;
+}
+
+/* Biên dịch thành: */
+
+.message-window {
+ font-size: 14px;
+ padding: 10px;
+ color: #000;
+ border-radius: 4px;
+}
+
+.message-window {
+ background-color: #0000ff;
+}
+
+
+
+/* Toán tử toán học
+============================== */
+
+
+
+/* Sass cung cấp các toán tử sau: +, -, *, / và %.
+ Điều này rất có ích cho việc tính toán giá trị trực tiếp
+ trong tệp Sass thay vì phải tính toán thủ công.
+ Dưới đây là ví dụ về việc tạo một khung thiết kế đơn giản có hai cột. */
+
+$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;
+}
+
+/* Biên dịch thành: */
+
+body {
+ width: 100%;
+}
+
+.main-content {
+ width: 62.5%;
+}
+
+.sidebar {
+ width: 31.25%;
+}
+
+.gutter {
+ width: 6.25%;
+}
+
+```
+
+## SASS hay Sass?
+Bạn đã bao giờ thắc mắc liệu Sass có phải là từ viết tắt hay không? Nhiều nguwòi lầm tưởng nó là từ viết tắt nhưng thực chất tên của ngôn ngữ này lại là một từ - Sass.
+Do sự lầm tưởng như vậy và mọi người thường xuyên viết nó là "SASS", người sáng lập ra ngôn ngữ này đã đặt một cái tên hài hước cho nó là "Syntactically Awesome StyleSheets" (Thiết lập style có cú pháp một cách tuyệt vời đáng kinh ngạc).
+
+
+## Tập sử dụng Sass
+Nếu bạn muốn thử dùng Sass trên trình duyệt, hãy ghé qua [SassMeister](http://sassmeister.com/). Bạn có thể dùng cả hai cú pháp, hoặc mở cài đặt và chọn Sass hoặc SCSS.
+
+## Tính tương thích
+Sass có thể được dùng trong bất kì dự án nào miễn là ta có chương trình để biên dịch nó thành CSS. Ta cần chắc chắn rằng đoạn CSS đang dùng tương thích với các phiên bản trình duyệt mong muốn.
+
+[QuirksMode CSS](http://www.quirksmode.org/css/) và [CanIUse](http://caniuse.com) là nguồn thông tin tin cậy để kiểm tra tính tương thích của mã CSS.
+
+
+## Tìm hiểu thêm
+* [Tài liệu chính thức](http://sass-lang.com/documentation/file.SASS_REFERENCE.html)
+* [The Sass Way](http://thesassway.com/) cung cấp các hướng dẫn từ cơ bản đến nâng cao cùng với các tin tức.
diff --git a/vi-vn/typescript-vi.html.markdown b/vi-vn/typescript-vi.html.markdown
new file mode 100644
index 00000000..ba459c11
--- /dev/null
+++ b/vi-vn/typescript-vi.html.markdown
@@ -0,0 +1,193 @@
+---
+language: TypeScript
+contributors:
+ - ["Philippe Vlérick", "https://github.com/pvlerick"]
+translators:
+ - ["Thanh Duy Phan", "https://github.com/thanhpd"]
+filename: learntypescript-vi.ts
+lang: vi-vn
+---
+
+TypeScript là ngôn ngữ được viết nhằm tinh giản quá trình phát triển ứng dụng quy mô lớn được viết bằng JavaScript.
+TypeScript bổ sung thêm các khái niệm phổ biến như Class, Module, Interface, Generic và Static typing (tùy chọn) vào JavaScript.
+Ngôn ngữ này là tập lớn hơn của JavaScript: tất cả code JavaScript đều là code TypeScript đúng nên nó có thể được thêm vào các dự án một cách nhanh chóng. Trình biên dịch TypeScript sẽ sinh ra JavaScript.
+
+Bài viết này sẽ chỉ tập trung tới các cú pháp bổ sung mà TypeScript thêm vào thay vì nói đến cả các cú pháp [JavaScript](javascript-vi.html.markdown).
+
+Để thử dùng TypeScript với trình biên dịch, đi đến [Sân chơi TypeScript](http://www.typescriptlang.org/play) nơi mà bạn có thể nhập code, sử dụng chức năng hỗ trợ tự hoàn thành code - autocompletion và trực tiếp quan sát mã JavaScript được sinh ra.
+
+```ts
+// Đây là 3 khai báo kiểu biến cơ bản trong TypeScript
+// (JavaScript chỉ có kiểu của giá trị, không có kiểu của biến)
+let isDone: boolean = false;
+let lines: number = 42;
+let name: string = "Anders";
+
+// Bạn có thể bỏ khai báo kiểu của biến nếu như nó đã được suy ra từ kiểu giá trị cơ bản
+let isDone = false;
+let lines = 42;
+let name = "Anders";
+
+// Có kiểu biến "any" tương thích với mọi kiểu của biến,
+// được dùng khi ta không chắc chắn về kiểu của biến khi được khai báo
+let notSure: any = 4;
+notSure = "có thể là một biến kiểu string";
+notSure = false; // cũng có thể là biến kiểu boolean
+
+// Dùng từ khóa const cho khái báo biến không thay đổi (constant variable)
+const numLivesForCat = 9;
+numLivesForCat = 1; // Có lỗi!
+
+// Khi khai báo tập hợp ta có thể dùng mảng có kiểu được khai báo trước - typed array
+let list: number[] = [1, 2, 3];
+// Ta cũng có thể sử dụng mảng kiểu chung - generic array
+let list: Array<number> = [1, 2, 3];
+
+// Để dùng enumeration - danh sách của một tập hợp:
+enum Color { Red, Green, Blue };
+let c: Color = Color.Green;
+
+// Nếu function không trả về kết quả, sử dụng "void" cho kết quả trả về
+function bigHorribleAlert(): void {
+ alert("I'm a little annoying box!");
+}
+
+// Function trong TypeScript là first-class citizen (tạm dịch: phần tử hạng nhất), hỗ trợ thao tác tới các thực thể khác
+// (vd: truyền vào như tham số, được trả về từ function, chỉnh sửa, gán vào một biến)
+// TypeScript hỗ trợ sử dụng function với cú pháp lambda (mũi tên) và suy luận kiểu trả về
+
+// Các cú pháp dưới đây tương đương với nhau,
+// trình biên dịch sẽ tự nhận biết và sinh ra mã JavaScript giống nhau
+let f1 = function (i: number): number { return i * i; }
+// Kiểu trả về nếu không khai báo được tự suy diễn
+let f2 = function (i: number) { return i * i; }
+// Cú pháp mũi tên (arrow syntax)
+let f3 = (i: number): number => { return i * i; }
+// Cú pháp mũi tên với kiểu trả về được suy diễn
+let f4 = (i: number) => { return i * i; }
+// Cú pháp mũi tên với kiểu trả về được suy diễn
+// khi không sử dụng dấu ngoặc nhọn {} thì không cần sử dụng return
+let f5 = (i: number) => i * i;
+
+// Interface mang tính cấu trúc, mọi thứ có các đặc điểm (property) đều tương thích
+interface IPerson {
+ name: string;
+ // Đặc điểm có thể tùy chọn bằng sử dụng dấu "?"
+ age?: number;
+ // Có thể sử dụng function
+ move(): void;
+}
+
+// Object sử dụng interface IPerson nói trên
+// có thể được coi là 1 thực thể Person vì nó có đặc điểm name và chức năng move
+let p: Person = { name: "Bobby", move: () => { } };
+// Object sử dụng property tùy chọn
+let validPerson: Person = { name: "Bobby", age: 42, move: () => { } };
+// Khai báo dưới đây gây lỗi vì giá trị đặc điểm age không mang kiểu number
+let invalidPerson: Person = { name: "Bobby", age: true };
+
+// Interface cũng có thể mô tả đặc tả của function
+interface SearchFunc {
+ (source: string, subString: string): boolean;
+}
+// Chỉ có kiểu của tham số là quan trọng còn tên không quan trọng
+let mySearch: SearchFunc;
+mySearch = function (src: string, sub: string) {
+ return src.search(sub) != -1;
+}
+
+// Class - các khai báo mặc định là public
+class Point {
+ // Property
+ x: number;
+
+ // Constructor - sử dụng tham số với từ khóa public/private
+ // sẽ tạo ra property tương ứng (ví dụ với property y)
+ // Có thể khai báo giá trị mặc định
+
+ constructor(x: number, public y: number = 0) {
+ this.x = x;
+ }
+
+ // Function
+ dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
+
+ // Biến Static
+ static origin = new Point(0, 0);
+}
+
+let p1 = new Point(10, 20);
+let p2 = new Point(25); // y sử dụng giá trị mặc định là 0
+
+// Thừa kế - Inheritance
+class Point3D extends Point {
+ constructor(x: number, y: number, public z: number = 0) {
+ super(x, y); // Bắt buộc phải gọi constructor của class cha
+ }
+
+ // Overwrite/Polymorphism - Ghi đè/Đa hình
+ dist() {
+ let d = super.dist();
+ return Math.sqrt(d * d + this.z * this.z);
+ }
+}
+
+// module, "." có thể được dùng như những module con
+module Geometry {
+ export class Square {
+ constructor(public sideLength: number = 0) {
+ }
+ area() {
+ return Math.pow(this.sideLength, 2);
+ }
+ }
+}
+
+let s1 = new Geometry.Square(5);
+
+// Bí danh (alias) có thể được sử dụng để tham vấn module khác
+import G = Geometry;
+
+let s2 = new G.Square(10);
+
+// Generic
+// Class
+class Tuple<T1, T2> {
+ constructor(public item1: T1, public item2: T2) {
+ }
+}
+
+// Interface
+interface Pair<T> {
+ item1: T;
+ item2: T;
+}
+
+// Function
+let pairToTuple = function <T>(p: Pair<T>) {
+ return new Tuple(p.item1, p.item2);
+};
+
+let tuple = pairToTuple({ item1: "hello", item2: "world" });
+
+// Các thư viện viết bằng JavaScript thường đi kèm file định nghĩa kiểu để có thể sử dụng cho TypeScript
+// Thêm vào tham vấn tới file định nghĩa:
+/// <reference path="jquery.d.ts" />
+
+// Template Strings - Chuỗi dạng mẫu (string sử dụng dấu `)
+// String Interpolation - Nội suy chuỗi with với template string
+let name = 'Tyrone';
+let greeting = `Chào ${name}, bạn khỏe không?`
+// Chuỗi nhiều dòng với template string
+let multiline = `Đây là ví dụ
+cho chuỗi nhiều dòng`;
+
+```
+
+## Tìm hiểu thêm
+
+* [Website TypeScript chính thức](http://www.typescriptlang.org/)
+* [Đặc tả ngôn ngữ TypeScript] (https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)
+* [Anders Hejlsberg - Introducing TypeScript on Channel 9] (http://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript)
+* [Mã nguồn trên GitHub] (https://github.com/Microsoft/TypeScript)
+* [Definitely Typed - repository for type definitions] (http://definitelytyped.org/)
diff --git a/vim.html.markdown b/vim.html.markdown
index 96cc20cb..55649cb2 100644
--- a/vim.html.markdown
+++ b/vim.html.markdown
@@ -7,21 +7,27 @@ filename: LearnVim.txt
---
-[Vim](www.vim.org)
-(Vi IMproved) is a clone of the popular vi editor for Unix. It is a text
-editor designed for speed and increased productivity, and is ubiquitous in most
-unix-based systems. It has numerous keybindings for speedy navigation to
+[Vim](http://www.vim.org)
+(Vi IMproved) is a clone of the popular vi editor for Unix. It is a text
+editor designed for speed and increased productivity, and is ubiquitous in most
+unix-based systems. It has numerous keybindings for speedy navigation to
specific points in the file, and for fast editing.
+`vimtutor` is a an excellent application that teaches you how to use `Vim`. It comes with the vim package during installation. You should be able to just run "vimtutor" on the command line to open this tutor. It will guide you through all the major features in `vim`.
+
+
## Basics of navigating Vim
```
vim <filename> # Open <filename> in vim
+ :help <topic> # Open up built-in help docs about <topic> if any exists
:q # Quit vim
:w # Save current file
:wq # Save file and quit vim
+ ZZ # Save file and quit vim
:q! # Quit vim without saving file
# ! *forces* :q to execute, hence quiting vim without saving
+ ZQ # Quit vim without saving file
:x # Save file and quit vim, shorter version of :wq
u # Undo
@@ -32,6 +38,11 @@ specific points in the file, and for fast editing.
k # Move up one line
l # Move right one character
+ Ctrl+B # Move back one full screen
+ Ctrl+F # Move forward one full screen
+ Ctrl+D # Move forward 1/2 a screen
+ Ctrl+U # Move back 1/2 a screen
+
# Moving within the line
0 # Move to beginning of line
@@ -40,23 +51,24 @@ specific points in the file, and for fast editing.
# Searching in the text
- /word # Highlights all occurences of word after cursor
- ?word # Highlights all occurences of word before cursor
- n # Moves cursor to next occurence of word after search
+ /word # Highlights all occurrences of word after cursor
+ ?word # Highlights all occurrences of word before cursor
+ n # Moves cursor to next occurrence of word after search
N # Moves cursor to previous occerence of word
:%s/foo/bar/g # Change 'foo' to 'bar' on every line in the file
:s/foo/bar/g # Change 'foo' to 'bar' on the current line
+ :%s/\n/\r/g # Replace new line characters with new line characters
# Jumping to characters
f<character> # Jump forward and land on <character>
- t<character> # Jump forward and land right before <character>
+ t<character> # Jump forward and land right before <character>
- # For example,
+ # For example,
f< # Jump forward and land on <
t< # Jump forward and land right before <
-
+
# Moving by word
w # Move forward by one word
@@ -73,19 +85,28 @@ specific points in the file, and for fast editing.
L # Move to the bottom of the screen
```
+## Help docs:
+
+Vim has built in help documentation that can accessed with `:help <topic>`.
+For example `:help navigation` will pull up documentation about how to navigate
+your workspace!
+
+`:help` can also be used without an option. This will bring up a default help dialog
+that aims to make getting started with vim more approachable!
+
## Modes:
Vim is based on the concept on **modes**.
-Command Mode - vim starts up in this mode, used to navigate and write commands
-Insert Mode - used to make changes in your file
-Visual Mode - used to highlight text and do operations to them
-Ex Mode - used to drop down to the bottom with the ':' prompt to enter commands
+- Command Mode - vim starts up in this mode, used to navigate and write commands
+- Insert Mode - used to make changes in your file
+- Visual Mode - used to highlight text and do operations to them
+- Ex Mode - used to drop down to the bottom with the ':' prompt to enter commands
```
i # Puts vim into insert mode, before the cursor position
a # Puts vim into insert mode, after the cursor position
- v # Puts vim into visual mode
+ v # Puts vim into visual mode
: # Puts vim into ex mode
<esc> # 'Escapes' from whichever mode you're in, into Command mode
@@ -102,18 +123,18 @@ Ex Mode - used to drop down to the bottom with the ':' prompt to enter comm
## The 'Grammar' of vim
-Vim can be thought of as a set of commands in a
+Vim can be thought of as a set of commands in a
'Verb-Modifier-Noun' format, where:
-Verb - your action
-Modifier - how you're doing your action
-Noun - the object on which your action acts on
+- Verb - your action
+- Modifier - how you're doing your action
+- Noun - the object on which your action acts on
A few important examples of 'Verbs', 'Modifiers', and 'Nouns':
```
# 'Verbs'
-
+
d # Delete
c # Change
y # Yank (copy)
@@ -135,7 +156,7 @@ A few important examples of 'Verbs', 'Modifiers', and 'Nouns':
s # Sentence
p # Paragraph
b # Block
-
+
# Sample 'sentences' or commands
d2w # Delete 2 words
@@ -157,6 +178,21 @@ A few important examples of 'Verbs', 'Modifiers', and 'Nouns':
ddp # Swap position of consecutive lines, dd then p
. # Repeat previous action
:w !sudo tee % # Save the current file as root
+ :set syntax=c # Set syntax highlighting to 'c'
+ :sort # Sort all lines
+ :sort! # Sort all lines in reverse
+ :sort u # Sort all lines and remove duplicates
+ ~ # Toggle letter case of selected text
+ u # Selected text to lower case
+ U # Selected text to upper case
+ J # Join the current line with the next line
+
+ # Fold text
+ zf # Create fold from selected text
+ zo # Open current fold
+ zc # Close current fold
+ zR # Open all folds
+ zM # Close all folds
```
## Macros
@@ -180,7 +216,7 @@ Here's a sample ~/.vimrc file:
```
" Example ~/.vimrc
-" 2015.10
+" 2015.10
" Required for vim to be iMproved
set nocompatible
diff --git a/vimscript.html.markdown b/vimscript.html.markdown
new file mode 100644
index 00000000..c2934af8
--- /dev/null
+++ b/vimscript.html.markdown
@@ -0,0 +1,658 @@
+---
+language: Vimscript
+filename: learnvimscript.vim
+contributors:
+ - ["HiPhish", "http://hiphish.github.io/"]
+---
+
+```vim
+" ##############
+" Introduction
+" ##############
+"
+" Vim script (also called VimL) is the subset of Vim's ex-commands which
+" supplies a number of features one one would expect from a scripting language,
+" such as values, variables, functions or loops. Always keep in the back of
+" your mind that a Vim script file is just a sequence of ex-commands. It is
+" very common for a script to mix programming-language features and raw
+" ex-commands.
+"
+" You can run Vim script directly by entering the commands in command-line mode
+" (press `:` to enter command-line mode), or you can write them to a file
+" (without the leading `:`) and source it in a running Vim instance (`:source
+" path/to/file`). Some files are sourced automatically as part of your
+" configuration (see |startup|). This guide assumes that you are familiar
+" with ex-commands and will only cover the scripting. Help topics to the
+" relevant manual sections are included.
+"
+" See |usr_41.txt| for the official introduction to Vim script. A comment is
+" anything following an unmatched `"` until the end of the line, and `|`
+" separates instructions (what `;` does in most other languages). References to
+" the manual as surrounded with `|`, such as |help.txt|.
+
+" This is a comment
+
+" The vertical line '|' (pipe) separates commands
+echo 'Hello' | echo 'world!'
+
+" Putting a comment after a command usually works
+pwd " Displays the current working directory
+
+" Except for some commands it does not; use the command delemiter before the
+" comment (echo assumes that the quotation mark begins a string)
+echo 'Hello world!' | " Displays a message
+
+" Line breaks can be escaped by pacing a backslash as the first non-whitespace
+" character on the *following* line. Only works in script files, not on the
+" command line
+echo " Hello
+ \ world "
+
+echo [1,
+ \ 2]
+
+echo {
+ \ 'a': 1,
+ \ 'b': 2
+\}
+
+
+" #######
+" Types
+" #######
+"
+" For an overview of types see |E712|. For an overview of operators see
+" |expression-syntax|
+
+" Numbers (|expr-number|)
+" #######
+
+echo 123 | " Decimal
+echo 0b1111011 | " Binary
+echo 0173 | " Octal
+echo 0x7B | " Hexadecimal
+echo 123.0 | " Floating-point
+echo 1.23e2 | " Floating-point (scientific notation)
+
+" Note that an *integer* number with a leading `0` is in octal notation. The
+" usual arithmetic operations are supported.
+
+echo 1 + 2 | " Addition
+echo 1 - 2 | " Subtraction
+echo - 1 | " Negation (unary minus)
+echo + 1 | " Unary plus (does nothing really, but still legal)
+echo 1 * 2 | " Multiplication
+echo 1 / 2 | " Division
+echo 1 % 2 | " Modulo (remainder)
+
+" Booleans (|Boolean|)
+" ########
+"
+" The number 0 is false, every other number is true. Strings are implicitly
+" converted to numbers (see below). There are two pre-defined semantic
+" constants.
+
+echo v:true | " Evaluates to 1 or the string 'v:true'
+echo v:false | " Evaluates to 0 or the string 'v:false'
+
+" Boolean values can result from comparison of two objects.
+
+echo x == y | " Equality by value
+echo x != y | " Unequality
+echo x > y | " Greater than
+echo x >= y | " Greater than or equal
+echo x < y | " Smaller than
+echo x <= y | " Smaller than or equal
+echo x is y | " Instance identity (lists and dictionaries)
+echo x isnot y | " Instance non-identity (lists and dictionaries)
+
+" Strings are compared based on their alphanumerical ordering
+" echo 'a' < 'b'. Case sensitivity depends on the setting of 'ignorecase'
+"
+" Explicit case-sensitivity is specified by appending '#' (match case) or '?'
+" (ignore case) to the operator. Prefer explicity case sensitivity when writing
+" portable scripts.
+
+echo 'a' < 'B' | " True or false depending on 'ignorecase'
+echo 'a' <? 'B' | " True
+echo 'a' <# 'B' | " False
+
+" Regular expression matching
+echo "hi" =~ "hello" | " Regular expression match, uses 'ignorecase'
+echo "hi" =~# "hello" | " Regular expression match, case sensitive
+echo "hi" =~? "hello" | " Regular expression match, case insensitive
+echo "hi" !~ "hello" | " Regular expression unmatch, use 'ignorecase'
+echo "hi" !~# "hello" | " Regular expression unmatch, case sensitive
+echo "hi" !~? "hello" | " Regular expression unmatch, case insensitive
+
+" Boolean operations are possible.
+
+echo v:true && v:false | " Logical AND
+echo v:true || v:false | " Logical OR
+echo ! v:true | " Logical NOT
+echo v:true ? 'yes' : 'no' | " Ternary operator
+
+
+" Strings (|String|)
+" #######
+"
+" An ordered zero-indexed sequence of bytes. The encoding of text into bytes
+" depends on the option |'encoding'|.
+
+" Literal constructors
+echo "Hello world\n" | " The last two characters stand for newline
+echo 'Hello world\n' | " The last two characters are literal
+echo 'Let''s go!' | " Two single quotes become one quote character
+
+" Single-quote strings take all characters are literal, except two single
+" quotes, which are taken to be a single quote in the string itself. See
+" |expr-quote| for all possible escape sequences.
+
+" String concatenation
+" The .. operator is preferred, but only supported in since Vim 8.1.1114
+echo 'Hello ' . 'world' | " String concatenation
+echo 'Hello ' .. 'world' | " String concatenation (new variant)
+
+" String indexing
+echo 'Hello'[0] | " First byte
+echo 'Hello'[1] | " Second byte
+echo 'Hellö'[4] | " Returns a byte, not the character 'ö'
+
+" Substrings (second index is inclusive)
+echo 'Hello'[:] | " Copy of entire string
+echo 'Hello'[1:3] | " Substring, second to fourth byte
+echo 'Hello'[1:-2] | " Substring until second to last byte
+echo 'Hello'[1:] | " Substring with starting index
+echo 'Hello'[:2] | " Substring with ending index
+echo 'Hello'[-2:] | " Substring relative to end of string
+
+" A negative index is relative to the end of the string. See
+" |string-functions| for all string-related functions.
+
+" Lists (|List|)
+" #####
+"
+" An ordered zero-indexed heterogeneous sequence of arbitrary Vim script
+" objects.
+
+" Literal constructor
+echo [] | " Empty list
+echo [1, 2, 'Hello'] | " List with elements
+echo [1, 2, 'Hello', ] | " Trailing comma permitted
+echo [[1, 2], 'Hello'] | " Lists can be nested arbitrarily
+
+" List concatenation
+echo [1, 2] + [3, 4] | " Creates a new list
+
+" List indexing, negative is relative to end of list (|list-index|)
+echo [1, 2, 3, 4][2] | " Third element
+echo [1, 2, 3, 4][-1] | " Last element
+
+" List slicing (|sublist|)
+echo [1, 2, 3, 4][:] | " Shallow copy of entire list
+echo [1, 2, 3, 4][:2] | " Sublist until third item (inclusive)
+echo [1, 2, 3, 4][2:] | " Sublist from third item (inclusive)
+echo [1, 2, 3, 4][:-2] | " Sublist until second-to-last item (inclusive)
+
+" All slicing operations create new lists. To modify a list in-place use list
+" functions (|list-functions|) or assign directly to an item (see below about
+" variables).
+
+
+" Dictionaries (|Dictionary|)
+" ############
+"
+" An unordered sequence of key-value pairs, keys are always strings (numbers
+" are implicitly converted to strings).
+
+" Dictionary literal
+echo {} | " Empty dictionary
+echo {'a': 1, 'b': 2} | " Dictionary literal
+echo {'a': 1, 'b': 2, } | " Trailing comma permitted
+echo {'x': {'a': 1, 'b': 2}} | " Nested dictionary
+
+" Indexing a dictionary
+echo {'a': 1, 'b': 2}['a'] | " Literal index
+echo {'a': 1, 'b': 2}.a | " Syntactic sugar for simple keys
+
+" See |dict-functions| for dictionary manipulation functions.
+
+
+" Funcref (|Funcref|)
+" #######
+"
+" Reference to a function, uses the function name as a string for construction.
+" When stored in a variable the name of the variable has the same restrictions
+" as a function name (see below).
+
+echo function('type') | " Reference to function type()
+" Note that `funcref('type')` will throw an error because the argument must be
+" a user-defined function; see further below for defining your own functions.
+echo funcref('type') | " Reference by identity, not name
+" A lambda (|lambda|) is an anonymous function; it can only contain one
+" expression in its body, which is also its implicit return value.
+echo {x -> x * x} | " Anonymous function
+echo function('substitute', ['hello']) | " Partial function
+
+
+" Regular expression (|regular-expression|)
+" ##################
+"
+" A regular expression pattern is generally a string, but in some cases you can
+" also use a regular expression between a pair of delimiters (usually `/`, but
+" you can choose anything).
+
+" Substitute 'hello' for 'Hello'
+substitute/hello/Hello/
+
+
+" ###########################
+" Implicit type conversions
+" ###########################
+"
+" Strings are converted to numbers, and numbers to strings when necessary. A
+" number becomes its decimal notation as a string. A string becomes its
+" numerical value if it can be parsed to a number, otherwise it becomes zero.
+
+echo "1" + 1 | " Number
+echo "1" .. 1 | " String
+echo "0xA" + 1 | " Number
+
+" Strings are treated like numbers when used as booleans
+echo "true" ? 1 : 0 | " This string is parsed to 0, which is false
+
+" ###########
+" Variables
+" ###########
+"
+" Variables are bound within a scope; if no scope is provided a default is
+" chosen by Vim. Use `:let` and `:const` to bind a value and `:unlet` to unbind
+" it.
+
+let b:my_var = 1 | " Local to current buffer
+let w:my_var = 1 | " Local to current window
+let t:my_var = 1 | " Local to current tab page
+let g:my_var = 1 | " Global variable
+let l:my_var = 1 | " Local to current function (see functions below)
+let s:my_var = 1 | " Local to current script file
+let a:my_arg = 1 | " Function argument (see functions below)
+
+" The Vim scope is read-only
+echo v:true | " Special built-in Vim variables (|v:var|)
+
+" Access special Vim memory like variables
+let @a = 'Hello' | " Register
+let $PATH='' | " Environment variable
+let &textwidth = 79 | " Option
+let &l:textwidth = 79 | " Local option
+let &g:textwidth = 79 | " Global option
+
+" Access scopes as dictionaries (can be modified like all dictionaries)
+" See the |dict-functions|, especially |get()|, for access and manipulation
+echo b: | " All buffer variables
+echo w: | " All window variables
+echo t: | " All tab page variables
+echo g: | " All global variables
+echo l: | " All local variables
+echo s: | " All script variables
+echo a: | " All function arguments
+echo v: | " All Vim variables
+
+" Constant variables
+const x = 10 | " See |:const|, |:lockvar|
+
+" Function reference variables have the same restrictions as function names
+let IsString = {x -> type(x) == type('')} | " Global: capital letter
+let s:isNumber = {x -> type(x) == type(0)} | " Local: any name allowed
+
+" When omitted the scope `g:` is implied, except in functions, there `l:` is
+" implied.
+
+
+" Multiple value binding (list unpacking)
+" #######################################
+"
+" Assign values of list to multiple variables (number of items must match)
+let [x, y] = [1, 2]
+
+" Assign the remainer to a rest variable (note the semicolon)
+let [mother, father; children] = ['Alice', 'Bob', 'Carol', 'Dennis', 'Emily']
+
+
+" ##############
+" Flow control
+" ##############
+
+" Conditional (|:if|, |:elseif|, |:else|, |:endif|)
+" ###########
+"
+" Conditions are set between `if` and `endif`. They can be nested.
+
+let condition = v:true
+
+if condition
+ echo 'First condition'
+elseif another_condition
+ echo 'Second condition'
+else
+ echo 'Fail'
+endif
+
+" Loops (|:for|, |:endfor|, |:while|, |:endwhile|, |:break|, |:continue|)
+" #####
+"
+" Two types of loops: `:for` and `:while`. Use `:continue` to skip to the next
+" iteration, `:break` to break out of the loop.
+
+" For-loop (|:for|, |:endfor|)
+" ========
+"
+" For-loops iterate over lists and nothing else. If you want to iterate over
+" another sequence you need to use a function which will create a list.
+
+" Iterate over a list
+for person in ['Alice', 'Bob', 'Carol', 'Dennis', 'Emily']
+ echo 'Hello ' .. person
+endfor
+
+" Iterate over a nested list by unpacking it
+for [x, y] in [[1, 0], [0, 1], [-1, 0], [0, -1]]
+ echo 'Position: x =' .. x .. ', y = ' .. y
+endfor
+
+" Iterate over a range of numbers
+for i in range(10, 0, -1) " Count down from 10
+ echo 'T minus' .. i
+endfor
+
+" Iterate over the keys of a dictionary
+for symbol in keys({'π': 3.14, 'e': 2.71})
+ echo 'The constant ' .. symbol .. ' is a transcendent number'
+endfor
+
+" Iterate over the values of a dictionary
+for value in values({'π': 3.14, 'e': 2.71})
+ echo 'The value ' .. value .. ' approximates a transcendent number'
+endfor
+
+" Iterate over the keys and values of a dictionary
+for [symbol, value] in items({'π': 3.14, 'e': 2.71})
+ echo 'The number ' .. symbol .. ' is approximately ' .. value
+endfor
+
+" While-loops (|:while|, |:endwhile|)
+
+let there_yet = v:true
+while !there_yet
+ echo 'Are we there yet?'
+endwhile
+
+
+" Exception handling (|exception-handling|)
+" ##################
+"
+" Throw new exceptions as strings, catch them by pattern-matching a regular
+" expression against the string
+
+" Throw new exception
+throw "Wrong arguments"
+
+" Guard against an exception (the second catch matches any exception)
+try
+ source path/to/file
+catch /Cannot open/
+ echo 'Looks like that file does not exist'
+catch /.*/
+ echo 'Something went wrong, but I do not know what'
+finally
+ echo 'I am done trying'
+endtry
+
+
+" ##########
+" Functions
+" ##########
+
+" Defining functions (|:function|, |:endfunction|)
+" ##################
+
+" Unscoped function names have to start with a capital letter
+function! AddNumbersLoudly(x, y)
+ " Use a: scope to access arguments
+ echo 'Adding' .. a:x .. 'and' .. a:y | " A side effect
+ return a:x + a:y | " A return value
+endfunction
+
+" Scoped function names may start with a lower-case letter
+function! s:addNumbersLoudly(x, y)
+ echo 'Adding' .. a:x .. 'and' .. a:y
+ return a:x + a:y
+endfunction
+
+" Without the exclamation mark it would be an error to re-define a function,
+" with the exclamation mark the new definition can replace the old one. Since
+" Vim script files can be reloaded several times over the course of a session
+" it is best to use the exclamation mark unless you really know what you are
+" doing.
+
+" Function definitions can have special qualifiers following the argument list.
+
+" Range functions define two implicit arguments, which will be set to the range
+" of the ex-command
+function! FirstAndLastLine() range
+ echo [a:firstline, a:lastline]
+endfunction
+
+" Prints the first and last line that match a pattern (|cmdline-ranges|)
+/^#!/,/!#$/call FirstAndLastLine()
+
+" Aborting functions, abort once error occurs (|:func-abort|)
+function! SourceMyFile() abort
+ source my-file.vim | " Try sourcing non-existing file
+ echo 'This will never be printed'
+endfunction
+
+" Closures, functions carrying values from outer scope (|:func-closure|)
+function! MakeAdder(x)
+ function! Adder(n) closure
+ return a:n + a:x
+ endfunction
+ return funcref('Adder')
+endfunction
+let AddFive = MakeAdder(5)
+echo AddFive(3) | " Prints 8
+
+" Dictionary functions, poor man's OOP methods (|Dictionary-function|)
+function! Mylen() dict
+ return len(self.data) | " Implicit variable self
+endfunction
+let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")}
+echo mydict.len()
+
+" Alternatively, more concise
+let mydict = {'data': [0, 1, 2, 3]}
+function! mydict.len()
+ return len(self.data)
+endfunction
+
+" Calling functions (|:call|)
+" #################
+
+" Call a function for its return value, and possibly for its side effects
+let animals = keys({'cow': 'moo', 'dog': 'woof', 'cat': 'meow'})
+
+" Call a function for its side effects only, ignore potential return value
+call sign_undefine()
+
+" The call() function calls a function reference and passes parameters as a
+" list, and returns the function's result.
+echo call(function('get'), [{'a': 1, 'b': 2}, 'c', 3]) | " Prints 3
+
+" Recall that Vim script is embedded within the ex-commands, that is why we
+" cannot just call a function directly, we have to use the `:call` ex-command.
+
+" Function namespaces (|write-library-script|, |autoload|)
+" ###################
+
+" Must be defined in autoload/foo/bar.vim
+" Namspaced function names do not have to start with a capital letter
+function! foo#bar#log(value)
+ echomsg value
+endfunction
+
+call foo#bar#log('Hello')
+
+
+" #############################
+" Frequently used ex-commands
+" #############################
+
+
+" Sourcing runtime files (|'runtimepath'|)
+" ######################
+
+" Source first match among runtime paths
+runtime plugin/my-plugin.vim
+
+
+" Defining new ex-commands (|40.2|, |:command|)
+" ########################
+
+" First argument here is the name of the command, rest is the command body
+command! SwapAdjacentLines normal! ddp
+
+" The exclamation mark works the same as with `:function`. User-defined
+" commands must start with a capital letter. The `:command` command can take a
+" number of attributes (some of which have their own parameters with `=`), such
+" as `-nargs`, all of them start with a dash to set them apart from the command
+" name.
+
+command! -nargs=1 Error echoerr <args>
+
+
+" Defining auto-commands (|40.3|, |autocmd|, |autocommand-events|)
+" ######################
+
+" The arguments are "events", "patterns", rest is "commands"
+autocmd BufWritePost $MYVIMRC source $MYVIMRC
+
+" Events and patterns are separated by commas with no space between. See
+" |autocmd-events| for standard events, |User| for custom events. Everything
+" else are the ex-commands which will be executed.
+
+" Auto groups
+" ===========
+"
+" When a file is sourced multiple times the auto-commands are defined anew,
+" without deleting the old ones, causing auto-commands to pile up over time.
+" Use auto-groups and the following ritual to guard against this.
+
+augroup auto-source | " The name of the group is arbitrary
+ autocmd! | " Deletes all auto-commands in the current group
+ autocmd BufWritePost $MYVIMRC source $MYVIMRC
+augroup END | " Switch back to default auto-group
+
+" It is also possible to assign a group directly. This is useful if the
+" definition of the group is in one script and the definition of the
+" auto-command is in another script.
+
+" In one file
+augroup auto-source
+ autocmd!
+augroup END
+
+" In another file
+autocmd auto-source BufWritePost $MYVIMRC source $MYVIMRC
+
+" Executing (run-time macros of sorts)
+" ####################################
+
+" Sometimes we need to construct an ex-command where part of the command is not
+" known until runtime.
+
+let line = 3 | " Line number determined at runtime
+execute line .. 'delete' | " Delete a line
+
+" Executing normal-mode commands
+" ##############################
+"
+" Use `:normal` to play back a sequence of normal mode commands from the
+" command-line. Add an exclamation mark to ignore user mappings.
+
+normal! ggddGp | " Transplant first line to end of buffer
+
+" Window commands can be used with :normal, or with :wincmd if :normal would
+" not work
+wincmd L | " Move current window all the way to the right
+
+
+" ###########################
+" Frequently used functions
+" ###########################
+
+" Feature check
+echo has('nvim') | " Running Neovim
+echo has('python3') | " Support for Python 3 plugins
+echo has('unix') | " Running on a Unix system
+echo has('win32') | " Running on a Windows system
+
+
+" Test if something exists
+echo exists('&mouse') | " Option (exists only)
+echo exists('+mouse') | " Option (exists and works)
+echo exists('$HOSTNAME') | " Environment variable
+echo exists('*strftime') | " Built-in function
+echo exists('**s:MyFunc') | " User-defined function
+echo exists('bufcount') | " Variable (scope optional)
+echo exists('my_dict["foo"]') | " Variable (dictionary entry)
+echo exists('my_dict["foo"]') | " Variable (dictionary entry)
+echo exists(':Make') | " Command
+echo exists("#CursorHold") | " Auto-command defined for event
+echo exists("#BufReadPre#*.gz") | " Event and pattern
+echo exists("#filetypeindent") | " Auto-command group
+echo exists("##ColorScheme") | " Auto-commnand supported for event
+
+" Various dynamic values (see |expand()|)
+echo expand('%') | " Current file name
+echo expand('<cword>') | " Current word under cursor
+echo expand('%:p') | " Modifier are possible
+
+" Type tests
+" There are unique constants defined for the following types. Older versions
+" of Vim lack the type variables, see the reference " documentation for a
+" workaround
+echo type(my_var) == v:t_number | " Number
+echo type(my_var) == v:t_string | " String
+echo type(my_var) == v:t_func | " Funcref
+echo type(my_var) == v:t_list | " List
+echo type(my_var) == v:t_dict | " Dictionary
+echo type(my_var) == v:t_float | " Float
+echo type(my_var) == v:t_bool | " Explicit Boolean
+" For the null object should compare it against itself
+echo my_var is v:null
+
+" Format strings
+echo printf('%d in hexadecimal is %X', 123, 123)
+
+
+" #####################
+" Tricks of the trade
+" #####################
+
+" Source guard
+" ############
+
+" Prevent a file from being sourced multiple times; users can set the variable
+" in their configuration to prevent the plugin from loading at all.
+if exists('g:loaded_my_plugin')
+ finish
+endif
+let g:loaded_my_plugin = v:true
+
+" Default values
+" ##############
+
+" Get a default value: if the user defines a variable use it, otherwise use a
+" hard-coded default. Uses the fact that a scope is also a dictionary.
+let s:greeting = get(g:, 'my_plugin_greeting', 'Hello')
+```
diff --git a/visualbasic.html.markdown b/visualbasic.html.markdown
index 0371e6f6..221c1eb3 100644
--- a/visualbasic.html.markdown
+++ b/visualbasic.html.markdown
@@ -5,14 +5,14 @@ contributors:
filename: learnvisualbasic.vb
---
-```vb
+```
Module Module1
Sub Main()
'A Quick Overview of Visual Basic Console Applications before we dive
'in to the deep end.
'Apostrophe starts comments.
- 'To Navigate this tutorial within the Visual Basic Complier, I've put
+ 'To Navigate this tutorial within the Visual Basic Compiler, I've put
'together a navigation system.
'This navigation system is explained however as we go deeper into this
'tutorial, you'll understand what it all means.
@@ -139,7 +139,7 @@ Module Module1
'Five
Private Sub WorkingCalculator()
- Console.Title = "The Working Calculator| Learn X in Y Minutes"
+ Console.Title = "The Working Calculator | Learn X in Y Minutes"
'However if you'd like the calculator to subtract, divide, multiple and
'add up.
'Copy and paste the above again.
@@ -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/vyper.html.markdown b/vyper.html.markdown
new file mode 100644
index 00000000..fec1a79f
--- /dev/null
+++ b/vyper.html.markdown
@@ -0,0 +1,872 @@
+---
+language: Vyper
+filename: learnVyper.vy
+contributors:
+ - ["Kenny Peluso", "kennyp.herokuapp.com"]
+---
+
+> The content of this document is largely inspired by ["Learn Solidity in Y Minutes"](https:#github.com/adambard/learnxinyminutes-docs/blob/master/solidity.html.markdown)
+
+Vyper lets you program on [Ethereum](https:#www.ethereum.org/), a
+blockchain-based virtual machine that allows the creation and
+execution of smart contracts, without requiring centralized or trusted parties. It was
+designed to improve upon Solidity, another smart contract language for Ethereum, by
+limiting unsafe practices and enhancing readability; Vyper seeks to optimize the
+security and auditability of smart contracts.
+
+Vyper is an experimental, statically typed, contract programming language meant to
+resemble Python. Like objects in OOP, each contract contains state variables, functions,
+and common data types. Contract-specific features include event notifiers for listeners,
+and custom global variables, global constants.
+
+Some Ethereum contract examples include crowdfunding, voting, and blind auctions.
+
+---
+
+## Table of Contents
+
+- Intro
+- Example
+1. Data types and associated methods
+2. Data structures
+3. Simple operators
+4. Global variables of note
+5. Functions and more
+ a. functions
+ b. events
+6. Branching and loops
+7. Objects/contracts
+ a. calling external contracts
+ b. ERC20 built-in
+ c. following an interface
+8. Other keywords
+ a. selfdestruct
+9. Contract design notes
+ a. obfuscation
+ b. storage optimization
+ c. data access in blockchain
+ d. cron job
+ e. observer pattern
+10. Security
+11. Style notes
+12. Natspec comments
+- Other documents
+
+---
+
+## Intro
+
+From [the docs](https://media.readthedocs.org/pdf/vyper/latest/vyper.pdf)
+the foundational tenants of Vyper are:
+
+1. *Security*
+2. *Language and compiler simplicity*
+3. *Auditability*
+
+This allows for the following features:
+
+1. *Bounds and overflow checking*
+ - On the arithmetic and array level
+ - There are no dynamic arrays in Vyper
+2. *Support for signed integers and decimal fixed point numbers*
+3. *Decidability* - You can always compute precise upper bound on gas cost
+4. *Strong typing* - for built-in and custom types
+5. *Small and understandable compiler code*
+6. *Limited support for pure functions*
+ - Anything marked `@constant` is not allowed to change the state
+
+Following the principles and goals, Vyper does not provide the following features:
+
+1. *Modifiers* (defining parts of functions elsewhere)
+2. *Class inheritance*
+3. *Inline assembly*
+4. *Function overloading*
+5. *Operator overloading*
+6. *Recursive calling*
+7. *Infinite-length loops*
+8. *Binary fixed point* (decimal fixed point is used for its exactness)
+
+WITH THE RAPID CHANGES IN ETHEREUM, THIS DOCUMENT IS UNLIKELY TO STAY UP TO
+DATE, SO YOU SHOULD FOLLOW THE LATEST VYPER DOCS AND ETHEREUM BLOG FOR THE LATEST.
+ALL CODE HERE IS PROVIDED AS IS, WITH SUBSTANTIAL RISK OF ERRORS OR DEPRECATED CODE
+PATTERNS.
+
+This document primarily discusses syntax, and so excludes many
+popular design patterns.
+
+As Vyper and Ethereum are under active development, experimental or beta
+features are typically marked, and subject to change. Pull requests welcome.
+
+This document describes Vyper version `0.1.0-beta.8`.
+
+*All of the following code exists for educational purposes only!*
+*None of the following code should be used in production as-is!*
+
+## Example
+
+```python
+# First, a simple todo list contract
+# Implements CRUD operations for tasks
+
+# todo.vy (note .vy extension)
+### **** START EXAMPLE **** ###
+
+# Start with Natspec comment
+# used for documentation
+
+# @title SimpleBank v1
+# @author kennyp
+# @notice This is a simple bank.
+
+# Vyper contracts must obey a particular order:
+# struct -> interface -> events -> globals and constants -> functions
+# Additionally, like Python, Vyper functions must be defined in the file
+# before they're called.
+
+# Structs
+
+struct Task:
+ done: bool
+ deleted: bool
+ task: string[100]
+ metadata: bytes32
+
+# Interfaces
+
+contract AnotherContract():
+ def fetch() -> bytes32: constant
+ def inform(_taskId: uint256, _status: uint256) -> bool: modifying
+
+# Events
+
+# Events - publicize actions to external listeners
+# `indexed` means that it's easier to search/filter on this field
+TaskStatus: event({_taskId: indexed(uint256), _status: uint256})
+
+# Global Variables
+
+# State variables are values which are permanently stored in contract storage
+# State vars consist of any value persisting beyond any function's scope
+# and are permanently stored in contract storage
+
+# You can define your own, custom, unmutable constants
+CREATED: constant(uint256) = 0
+COMPLETED: constant(uint256) = 1
+DELETED: constant(uint256) = 2
+
+# The `public` built-in allows for this address to be read externally
+# without defining a `get()` constant function
+owner: public(address)
+other: public(address)
+
+# uint256 means "unsigned positive integer between 0 and 2^256 - 1"
+# Overflow protection is built-in to Vyper
+taskCount: uint256
+tasks: map(uint256, Task) # dictionary: key=uint256, value: Task struct
+
+# Private Functions
+
+# Start each function with Pythonic decorators
+# These decorators resemble Natspec but are actually enforced by Vyper's compiler
+# These decorators are:
+# @public XOR @private (either one or the other)
+# @public (if any contract/user can call it)
+# @private (if only internal functions can call it)
+# @payable (if the function is payable i.e. accepting ETH)
+# @constant (if the function is not modifying anything on-chain)
+@private
+def _changeTaskStatus( \
+ _sender: address, \
+ _taskId: uint256, \
+ _status: uint256, \
+ ):
+ # backslashes (\) allow for multi-line code
+ # Natspec comments are particularly helpful for documentation and readibility
+ # Natspec can be included using familiar Pythonic docstring syntax
+ """
+ @notice
+ @dev `_sender` MUST be `self.owner`
+ @param _sender Who is triggering this function
+ @param _task The description of the task (only useful when task added)
+ """
+ # NOTE: Private functions do not have access to `msg.sender`
+ # SIDE NOTE: `msg.sender` refers to whoever immediately called the function of
+ # immediate scope. In other words, if I call a function that calls another
+ # in-contract, public function, then `msg.sender` turns from my address to
+ # the address of the current contract.
+ assert _sender == self.owner # failed assertions cause calls/transactions to fail
+ # Note that unlike Solidity, `self.` is required to query the contract's state
+ # Control flow is Pythonic, as is much of Vyper:
+ _task: string[100] # initialized to default value
+ _data: bytes32 = sha3(convert(_sender, bytes32)) # owner is obfuscated (but still visible in logs)
+ if _status == CREATED: # control flow mimics python
+ # How a new struct is instantiated:
+ self.tasks[_taskId] = Task({ \
+ done: False, deleted: False, task: _task, metadata: _data \
+ })
+ elif _status == COMPLETED:
+ # Modifying an existing struct:
+ self.tasks[_taskId].done = True
+ elif _status == DELETED:
+ self.tasks[_taskId].deleted = True
+ AnotherContract(self.other).inform(_taskId, _status) # modifying external call
+ log.TaskStatus(_taskId, _status) # emit an event
+
+# Public Functions
+
+# Pythonic constructor - can receive none or many arguments
+@public
+def __init__(_owner: address, _other_contract: address):
+ """
+ @dev Called once and only upon contract depoyment
+ """
+ self.owner = _owner
+ self.other = _other_contract
+
+# NOTE: Pythonic whitespace rules are mandated in Vyper
+
+@public
+def addTask(_task: string[100]) -> uint256:
+ """
+ @notice Adds a task to contract
+ @param _task Description of task
+ @return Id of newly minted task
+ """
+ # msg.sender gives the address of who/what contract is calling this function
+ self._changeTaskStatus(msg.sender, self.taskCount, CREATED)
+ self.tasks[self.taskCount].task = _task
+ self.taskCount += 1
+ return self.taskCount - 1
+
+@public
+def addSpecialTask(_task: string[100]) -> uint256:
+ """
+ @notice Adds a task with metadata pulled from elsewhere
+ @param _task Description of task
+ @return Id of newly minted task
+ """
+ self._changeTaskStatus(msg.sender, self.taskCount, CREATED)
+ self.tasks[self.taskCount].task = _task
+ self.tasks[self.taskCount].metadata = AnotherContract(self.other).fetch()
+ self.taskCount += 1
+ return self.taskCount - 1
+
+@public
+def completeTask(_taskId: uint256):
+ """
+ @notice Marks a task as "completed"
+ @param _taskId Id of task to complete
+ """
+ self._changeTaskStatus(msg.sender, _taskId, COMPLETED)
+
+@public
+def deleteTask(_taskId: uint256):
+ """
+ @notice Adds a task to contract
+ @param _taskId Id of task to delete
+ """
+ self._changeTaskStatus(msg.sender, _taskId, DELETED)
+
+@public
+@constant # allows function to run locally/off blockchain
+def getTask(_taskId: uint256) -> string[100]:
+ """
+ @notice Getter for a task's description
+ @param _taskId Id of task with desired description
+ @return Description of task
+ """
+ return self.tasks[_taskId].task
+
+### **** END EXAMPLE **** ###
+
+
+# Now, the basics of Vyper
+
+
+# ---
+
+
+# 1. DATA TYPES AND ASSOCIATED METHODS
+# uint256 used for currency amount and for dates (in unix time)
+x: uint256
+
+# int of 128 bits, cannot be changed after contract deployment
+# with 'constant', compiler replaces each occurrence with actual value
+a: constant(int128) = 5
+
+# All state variables (those outside a function)
+# are by default 'internal' and accessible inside contract
+# Need to explicitly set to 'public' to allow external contracts to access
+# A getter is automatically created, but NOT a setter
+# Can only be called in the contract's scope (not within functions)
+# Add 'public' field to indicate publicly/externally accessible
+a: public(int128)
+
+# No random functions built in, use other contracts for randomness
+
+# Type casting is limited but exists
+b: int128 = 5
+x: uint256 = convert(b, uint256)
+
+# Types of accounts:
+# Contract Account: f(creator_addr, num_transactions)=address set on contract creation
+# External Account: (person/external entity): f(public_key)=address
+
+# Addresses - An address type can hold an Ethereum address which
+# equates to 20 bytes or 160 bits. It returns in hexadecimal notation
+# with a leading 0x. No arithmetic allowed
+owner: public(address)
+
+# Members can be invoked on all addresses:
+owner.balance # returns balance of address as `wei_value`
+owner.codesize # returns code size of address as `int128`
+owner.is_contract # `True` if Contract Account
+
+# All addresses can be sent ether via `send()` built-in
+@public
+@payable
+def sendWei(any_addr: address):
+ send(any_addr, msg.value)
+
+# Bytes available
+a: bytes[2]
+b: bytes[32]
+c: bytes32
+# `b` and `c` are 2 different types
+
+# Bytes are preferable to strings since Vyper currently offers better
+# support for bytes i.e. more built-ins to deal with `bytes32`, `bytes32`
+# can be returned from functions and strings[] can't be, UTF8 (string encoding)
+# uses more storage, etc.
+
+# There are no dynamically sized bytes, similar to how there are no
+# dynamic arrays
+
+# Fixed-size byte arrays (Strings)
+a: string[100]
+b: string[8]
+c: string[108] = concat(a, b) # check the latest docs for more built-ins
+
+# Time
+t1: timedelta
+t2: timestamp
+# Both types are built-in "custom type" variants of `uint256`
+# `timedelta` values can be added but not `timestamp` values
+
+# Money
+m: wei_value
+# Also has the base type `uint256` like `timestamp` and `timedelta`
+# 1 unit of WEI (a small amount of ETH i.e. ether)
+
+# Custom types
+# specify units used in the contract:
+units: {
+ cm: "centimeter",
+ km: "kilometer"
+}
+# usage:
+a: int128(cm)
+b: uint256(km)
+
+# BY DEFAULT: all values are set to 0 on instantiation
+
+# `clear()` can be called on most types
+# Does NOT destroy value, but sets value to 0, the initial value
+
+
+# ---
+
+
+# 2. DATA STRUCTURES
+# Arrays
+bytes32[5] nicknames; # static array
+bytes32[] names; # dynamic array
+uint newLength = names.push("John"); # adding returns new length of the array
+# Length
+names.length; # get length
+names.length = 1; # lengths can be set (for dynamic arrays in storage only)
+
+# Multidimensional Arrays
+# At initialization, array dimensions must be hard-coded or constants
+# Initialize a 10-column by 3-row, multidimensional fixed array
+ls: (uint256[10])[3] # parentheses are optional
+@public
+def setToThree():
+ # Multidimensional Array Access and Write
+ # access indices are reversed
+ # set element in row 2 (3rd row) column 5 (6th column) to 3
+ self.ls[2][5] = 3
+
+# Dictionaries (any simple type to any other type including structs)
+theMap: map(uint256, bytes32)
+theMap[5] = sha3("charles")
+# theMap[255] result is 0, all non-set key values return zeroes
+# To make read public, make a getter that accesses the mapping
+@public
+def getMap(_idx: uint256) -> bytes32:
+ """
+ @notice Get the value of `theMap` at `_idx`
+ """
+ return self.theMap[_idx]
+
+self.getMap(5) # returns sha3("charles") in bytes32
+
+# Nested mappings
+aMap: map(address, map(address, uint256))
+# NOTE: Mappings are only allowed as state variables
+# NOTE: Mappings are not iterable; can only be accessed
+
+# To delete (reset the mapping's value to default at a key)
+clear(balances["John"])
+clear(balances); # sets all elements to 0
+
+# Unlike other languages, CANNOT iterate through all elements in
+# mapping, without knowing source keys - can build data structure
+# on top to do this
+
+# Structs
+struct Struct:
+ owner: address
+ _balance: uint256 # balance is a reserved keyword, is a member for addresses
+
+exampleStuct: Struct
+
+@public
+def foo() -> uint256:
+ self.exampleStuct = Struct({owner: msg.sender, _balance: 5})
+ self.exampleStuct._balance = 10
+ self.exampleStuct._balance = 5 # set to new value
+ clear(self.exampleStuct._balance)
+ clear(self.exampleStuct)
+ return self.exampleStuct._balance
+
+
+# Data locations: Memory vs. storage vs. calldata - all complex types (arrays,
+# structs) have a data location
+# 'memory' does not persist, 'storage' does
+# Default is 'storage' for local and state variables; 'memory' for func params
+# stack holds small local variables
+
+# for most types, can explicitly set which data location to use
+
+
+# ---
+
+
+# 3. SIMPLE OPERATORS
+# Comparisons, bit operators and arithmetic operators are provided
+# exponentiation: **
+# modulo: %
+# maximum: max(x, y)
+# AND: bitwise_and(x, y)
+# bitwise shift: shift(x, _shift)
+# where x,y are uint256
+# _shift is int128
+
+# 4. GLOBAL VARIABLES OF NOTE
+# ** self **
+self # address of contract
+# often used at end of contract life to transfer remaining balance to party:
+self.balance # balance of current contract
+self.someFunction() # calls func externally via call, not via internal jump
+
+# ** msg - Current message received by the contract **
+# Ethereum programmers take NOTE: this `msg` object is smaller than elsewhere
+msg.sender # address of sender
+msg.value # amount of ether provided to this contract in wei, the function should be marked `@payable`
+msg.gas # remaining gas
+
+# ** tx - This transaction **
+# Ethereum programmers take NOTE: this `tx` object is smaller than elsewhere
+tx.origin # address of sender of the transaction
+
+# ** block - Information about current block **
+block.timestamp # time at current block (uses Unix time)
+# Note that `block.timestamp` can be manipulated by miners, so be careful
+block.number # current block number
+block.difficulty # current block difficulty
+
+# ** storage - Persistent storage hash **
+storage['abc'] = 'def'; # maps 256 bit words to 256 bit words
+
+
+# ---
+
+
+# 5. FUNCTIONS AND MORE
+
+# A. FUNCTIONS
+# Simple function
+function increment(uint x) returns (uint) {
+ x += 1;
+ return x;
+}
+
+# Functions can return many arguments
+@public
+@constant
+def increment(x: uint256, y: uint256) -> (uint256, uint256):
+ x += 1
+ y += 1
+ return (x, y)
+
+# Call previous functon
+@public
+@constant
+def willCall() -> (uint256, uint256):
+ return self.increment(1,1)
+
+# One should never have to call a function / hold any logic outside
+# outside the scope of a function in Vyper
+
+# '@constant'
+# indicates that function does not/cannot change persistent vars
+# Constant function execute locally, not on blockchain
+y: uint256
+@public
+@constant
+def increment(x: uint256) -> uint256:
+ x += 1
+ y += 1 # this line would fail
+ # y is a state variable => can't be changed in a constant function
+
+
+# 'Function Decorators'
+# Used like python decorators but are REQUIRED by Vyper
+# @public - visible externally and internally (default for function)
+# @private - only visible in the current contract
+# @constant - doesn't change state
+# @payable - receive ether/ETH
+# @nonrentant(<unique_key>) - Function can only be called once, both externally
+# and internally. Used to prevent reentrancy attacks
+
+# Functions hare not hoisted
+# Functions cannot be assigned to a variable
+# Functions cannot be recursive
+
+# All functions that receive ether must be marked 'payable'
+@public
+@payable
+def depositEther():
+ self.balances[msg.sender] += msg.value
+
+
+# B. EVENTS
+# Events are notify external parties; easy to search and
+# access events from outside blockchain (with lightweight clients)
+# typically declare after contract parameters
+
+# Declare
+LogSent: event({_from: indexed(address), address: indexed(_to), _amount: uint256})
+# Call
+log.LogSent(from, to, amount)
+
+/**
+For an external party (a contract or external entity), to watch using
+the Web3 Javascript library:
+
+# The following is Javascript code, not Vyper code
+Coin.LogSent().watch({}, '', function(error, result) {
+ if (!error) {
+ console.log("Coin transfer: " + result.args.amount +
+ " coins were sent from " + result.args.from +
+ " to " + result.args.to + ".");
+ console.log("Balances now:\n" +
+ "Sender: " + Coin.balances.call(result.args.from) +
+ "Receiver: " + Coin.balances.call(result.args.to));
+ }
+}
+**/
+
+# Common paradigm for one contract to depend on another (e.g., a
+# contract that depends on current exchange rate provided by another)
+
+
+# ---
+
+
+# 6. BRANCHING AND LOOPS
+
+# All basic logic blocks from Python work - including if/elif/else, for,
+# while, break, continue, return - but no switch
+
+# Syntax same as Python, but no type conversion from non-boolean
+# to boolean (comparison operators must be used to get the boolean val)
+
+# REMEMBER: Vyper does not allow resursive calls or infinite loops
+
+
+# ---
+
+
+# 7. OBJECTS/CONTRACTS
+# REMEMBER: Vyper does not allow for inheritance or imports
+
+# A. CALLING EXTERNAL CONTRACTS
+# You must define an interface to an external contract in the current contract
+
+contract InfoFeed():
+ def getInfo() -> uint256: constant
+
+info: uint256
+
+@public
+def __init__(_source: address):
+ self.info = InfoFeed(_source).getInfo()
+
+
+# B. ERC20 BUILT-IN
+# Using the `ERC20` keyword implies that the contract at the address
+# follows the ERC20 token standard, allowing you to safely call
+# functions like `transfer()`, etc.
+
+tokenAddress: address(ERC20)
+
+@public
+def transferIt(_to: address, _amt: uint256(wei)):
+ self.tokenAddress.transfer(_to, _amt)
+
+
+# C. FOLLOWING AN INTERFACE
+# Vyper is experimenting with using the following syntax at the top of
+# a `.vy` file to specify what interfaces are followed by the contract
+# This allows interfaces to be better organized, registered, and recognized
+
+import interfaces.some_interface as SomeInterface
+implements: SomeInterface
+# <rest of contract>
+
+
+# ---
+
+
+# 8. OTHER KEYWORDS
+
+# A. selfdestruct()
+# selfdestruct current contract, sending funds to address (often creator)
+selfdestruct(SOME_ADDRESS);
+
+# removes storage/code from current/future blocks
+# helps thin clients, but previous data persists in blockchain
+
+# Common pattern, lets owner end the contract and receive remaining funds
+@public
+def endItAll() {
+ assert msg.sender == self.creator # Only let the contract creator do this
+ selfdestruct(self.creator) # Makes contract inactive, returns funds
+
+# May want to deactivate contract manually, rather than selfdestruct
+# (ether sent to selfdestructed contract is lost)
+
+
+# B. sha3()
+# Encrypts strings and other data
+# Very important on the blockchain
+# Takes 1 argument, `concat()` can be called beforehand
+# All strings passed are concatenated before hash action
+sha3(concat("ab", "cd")) # returns bytes32
+
+
+# ---
+
+
+# 9. CONTRACT DESIGN NOTES
+
+# A. Obfuscation
+# All variables are publicly viewable on blockchain, so anything
+# that is private needs to be obfuscated (e.g., hashed w/secret)
+# Oftentimes, a "commit-reveal" scheme is employed
+
+# Step 1. Commit
+# Place a commitment by sending output of `sha3()`
+sha3("a secret"); # btyes32 commit
+sha3(concat("secret", "other secret", "salt")); # commit multiple things
+# The `sha3()` calculation should occur off-chain, only the bytes32
+# output should be inputted into some `commit()` function
+commits: map(address, bytes32)
+@public
+def commit(commitment: bytes32):
+ self.commits[msg.sender] = commitment
+
+# Step 2. Reveal
+# Send your previously committed data so the contract can check
+# if your commitment was honest
+@public
+def reveal(_secret: string[100], _salt: string[100]) -> bool:
+ return sha3(concat(_secret, _salt)) == self.commits[msg.sender]
+
+
+# B. Storage optimization
+# Writing to blockchain can be expensive, as data stored forever; encourages
+# smart ways to use memory (eventually, compilation will be better, but for now
+# benefits to planning data structures - and storing min amount in blockchain)
+
+# Cost can often be high for items like multidimensional arrays
+# (cost is for storing data - not declaring unfilled variables)
+
+
+# C. Data access in blockchain
+# Cannot restrict human or computer from reading contents of
+# transaction or transaction's state
+
+# While 'private' prevents other *contracts* from reading data
+# directly - any other party can still read data in blockchain
+
+# All data to start of time is stored in blockchain, so
+# anyone can observe all previous data and changes
+
+
+# D. Cron Job
+# Contracts must be manually called to handle time-based scheduling;
+# can create external code to regularly ping or provide incentives
+# (ether) for others to ping
+
+
+# E. Observer Pattern
+# An Observer Pattern lets you register as a subscriber and
+# register a function which is called by the oracle (note, the oracle
+# pays for this action to be run)
+# Some similarities to subscription in Pub/sub
+
+# This is an abstract contract, both client and server classes import,
+# the client should implement
+
+### **** START EXAMPLE **** ###
+
+contract SomeOracleCallback():
+ def oracleCallback(_value: uint256, _time: timestamp, _info: bytes32): modifying
+
+MAX_SUBS: constant(uint256) = 100
+numSubs: public(uint256) # number of subscribers
+subs: map(uint256, address) # enumerates subscribers
+
+@public
+def addSub(_sub: address) -> uint256:
+ """
+ @notice Add subscriber
+ @param _sub Address to add
+ @return Id of newly added subscriber
+ """
+ self.subs[self.numSubs] = _sub
+ self.numSubs += 1
+ return self.numSubs - 1
+
+@private
+def notify(_value: uint256, _time: timestamp, _info: bytes32) -> bool:
+ """
+ @notice Notify all subscribers
+ @dev Check `numSubs` first; Watch out for gas costs!
+ @param _value whatever
+ @param _time what have you
+ @param _info what else
+ @return True upon successful completion
+ """
+ j: uint256
+ for i in range(MAX_SUBS):
+ j = convert(i, uint256) # `i` is int128 by default
+ if j == self.numSubs:
+ return True
+ SomeOracleCallback(self.subs[j]).oracleCallback(_value, _time, _info)
+
+@public
+def doSomething():
+ """
+ @notice Do something and notify subscribers
+ """
+ # ...something...
+ whatever: uint256 = 6
+ what_have_you: timestamp
+ what_else: bytes32 = sha3("6")
+ self.notify(whatever, what_have_you, what_else)
+
+# Now, your client contract can addSubscriber by importing SomeOracleCallback
+# and registering with Some Oracle
+
+### **** END EXAMPLE **** ###
+
+
+# ---
+
+
+# 10. SECURITY
+# Bugs can be disastrous in Ethereum contracts - and even popular patterns in
+# Vyper may be found to be antipatterns
+
+# See security links at the end of this doc
+
+
+# ---
+
+
+# 11. STYLE NOTES
+# Based on Python's PEP8 style guide
+# Full Style guide: http:#solidity.readthedocs.io/en/develop/style-guide.html
+
+# Quick summary:
+# 4 spaces for indentation
+# Two lines separate contract declarations (and other top level declarations)
+# Avoid extraneous spaces in parentheses
+# Can omit curly braces for one line statement (if, for, etc)
+# else should be placed on own line
+
+# Specific to Vyper:
+# arguments: snake_case
+# events, interfaces, structs: PascalCase
+# public functions: camelCase
+# private functions: _prefaceWithUnderscore
+
+
+# ---
+
+
+# 12. NATSPEC COMMENTS
+# used for documentation, commenting, and external UIs
+
+# Contract natspec - always above contract definition
+# @title Contract title
+# @author Author name
+
+# Function natspec
+# Should include in docstring of functions in typical Pythonic fashion
+# @notice Information about what function does; shown when function to execute
+# @dev Function documentation for developer
+
+# Function parameter/return value natspec
+# @param someParam Some description of what the param does
+# @return Description of the return value
+
+```
+
+## Additional resources
+- [Installation](https://vyper.readthedocs.io/en/latest/installing-vyper.html)
+- [Vyper Docs](https://media.readthedocs.org/pdf/vyper/latest/vyper.pdf)
+- [Vyper GitHub (under active dev)](https://github.com/ethereum/vyper)
+- [Tools and Resources](https://github.com/ethereum/vyper/wiki/Vyper-tools-and-resources)
+- [Online Compiler](https://vyper.online/)
+
+## Sample contracts
+- [Uniswap](https://github.com/Uniswap/contracts-vyper)
+- [Generalized Governance](https://github.com/kpeluso/gdg)
+- [Dynamic Arrays](https://github.com/kpeluso/vyper-dynamic-array)
+
+## Security
+Vyper is secure by design, but it may be helpful to understand what Vyper is
+protecting you from.
+- [Thinking About Smart Contract Security](https:#blog.ethereum.org/2016/06/19/thinking-smart-contract-security/)
+- [Smart Contract Security](https:#blog.ethereum.org/2016/06/10/smart-contract-security/)
+- [Hacking Distributed Blog](http:#hackingdistributed.com/)
+
+## Style
+- [Vyper Style Guide WIP](https://github.com/ethereum/vyper/issues/905)
+ - Heavily derived from [Solidity's style guide](http:#solidity.readthedocs.io/en/latest/style-guide.html) ...
+ - ... which, in turn, is heavily derived from Python's [PEP 8](https:#www.python.org/dev/peps/pep-0008/) style guide.
+
+## Editors
+- [Vyper for VS Code (alpha)](https://github.com/p-/vscode-vyper)
+
+## Future To Dos
+- Update to current Vyper release
+- List of common design patterns
+
+*Feel free to send a pull request with any edits - or email* `pelusoken -/at-/ gmail`
+
diff --git a/wasm.html.markdown b/wasm.html.markdown
new file mode 100644
index 00000000..81344abe
--- /dev/null
+++ b/wasm.html.markdown
@@ -0,0 +1,312 @@
+---
+language: WebAssembly
+filename: learn-wasm.wast
+contributors:
+ - ["Dean Shaff", "http://dean-shaff.github.io"]
+---
+
+```
+;; learn-wasm.wast
+
+(module
+ ;; In WebAssembly, everything is included in a module. Moreover, everything
+ ;; can be expressed as an s-expression. Alternatively, there is the
+ ;; "stack machine" syntax, but that is not compatible with Binaryen
+ ;; intermediate representation (IR) syntax.
+
+ ;; The Binaryen IR format is *mostly* compatible with WebAssembly text format.
+ ;; There are some small differences:
+ ;; local_set -> local.set
+ ;; local_get -> local.get
+
+ ;; We have to enclose code in functions
+
+ ;; Data Types
+ (func $data_types
+ ;; WebAssembly has only four types:
+ ;; i32 - 32 bit integer
+ ;; i64 - 64 bit integer (not supported in JavaScript)
+ ;; f32 - 32 bit floating point
+ ;; f64 - 64 bit floating point
+
+ ;; We can declare local variables with the "local" keyword
+ ;; We have to declare all variables before we start doing anything
+ ;; inside the function
+
+ (local $int_32 i32)
+ (local $int_64 i64)
+ (local $float_32 f32)
+ (local $float_64 f64)
+
+ ;; These values remain uninitialized.
+ ;; To set them to a value, we can use <type>.const:
+
+ (local.set $int_32 (i32.const 16))
+ (local.set $int_32 (i64.const 128))
+ (local.set $float_32 (f32.const 3.14))
+ (local.set $float_64 (f64.const 1.28))
+ )
+
+ ;; Basic operations
+ (func $basic_operations
+
+ ;; In WebAssembly, everything is an s-expression, including
+ ;; doing math, or getting the value of some variable
+
+ (local $add_result i32)
+ (local $mult_result f64)
+
+ (local.set $add_result (i32.add (i32.const 2) (i32.const 4)))
+ ;; the value of add_result is now 6!
+
+ ;; We have to use the right data type for each operation:
+ ;; (local.set $mult_result (f32.mul (f32.const 2.0) (f32.const 4.0))) ;; WRONG! mult_result is f64!
+ (local.set $mult_result (f64.mul (f64.const 2.0) (f64.const 4.0)))
+
+ ;; WebAssembly has some builtin operations, like basic math and bitshifting.
+ ;; Notably, it does not have built in trigonometric functions.
+ ;; In order to get access to these functions, we have to either
+ ;; - implement them ourselves (not recommended)
+ ;; - import them from elsewhere (later on)
+ )
+
+ ;; Functions
+ ;; We specify arguments with the `param` keyword, and specify return values
+ ;; with the `result` keyword
+ ;; The current value on the stack is the return value of a function
+
+ ;; We can call other functions we've defined with the `call` keyword
+
+ (func $get_16 (result i32)
+ (i32.const 16)
+ )
+
+ (func $add (param $param0 i32) (param $param1 i32) (result i32)
+ (i32.add
+ (local.get $param0)
+ (local.get $param1)
+ )
+ )
+
+ (func $double_16 (result i32)
+ (i32.mul
+ (i32.const 2)
+ (call $get_16))
+ )
+
+ ;; Up until now, we haven't be able to print anything out, nor do we have
+ ;; access to higher level math functions (pow, exp, or trig functions).
+ ;; Moreover, we haven't been able to use any of the WASM functions in Javascript!
+ ;; The way we get those functions into WebAssembly
+ ;; looks different whether we're in a Node.js or browser environment.
+
+ ;; If we're in Node.js we have to do two steps. First we have to convert the
+ ;; WASM text representation into actual webassembly. If we're using Binyaren,
+ ;; we can do that with a command like the following:
+
+ ;; wasm-as learn-wasm.wast -o learn-wasm.wasm
+
+ ;; We can apply Binaryen optimizations to that file with a command like the
+ ;; following:
+
+ ;; wasm-opt learn-wasm.wasm -o learn-wasm.opt.wasm -O3 --rse
+
+ ;; With our compiled WebAssembly, we can now load it into Node.js:
+ ;; const fs = require('fs')
+ ;; const instantiate = async function (inFilePath, _importObject) {
+ ;; var importObject = {
+ ;; console: {
+ ;; log: (x) => console.log(x),
+ ;; },
+ ;; math: {
+ ;; cos: (x) => Math.cos(x),
+ ;; }
+ ;; }
+ ;; importObject = Object.assign(importObject, _importObject)
+ ;;
+ ;; var buffer = fs.readFileSync(inFilePath)
+ ;; var module = await WebAssembly.compile(buffer)
+ ;; var instance = await WebAssembly.instantiate(module, importObject)
+ ;; return instance.exports
+ ;; }
+ ;;
+ ;; const main = function () {
+ ;; var wasmExports = await instantiate('learn-wasm.wasm')
+ ;; wasmExports.print_args(1, 0)
+ ;; }
+
+ ;; The following snippet gets the functions from the importObject we defined
+ ;; in the JavaScript instantiate async function, and then exports a function
+ ;; "print_args" that we can call from Node.js
+
+ (import "console" "log" (func $print_i32 (param i32)))
+ (import "math" "cos" (func $cos (param f64) (result f64)))
+
+ (func $print_args (param $arg0 i32) (param $arg1 i32)
+ (call $print_i32 (local.get $arg0))
+ (call $print_i32 (local.get $arg1))
+ )
+ (export "print_args" (func $print_args))
+
+ ;; Loading in data from WebAssembly memory.
+ ;; Say that we want to apply the cosine function to a Javascript array.
+ ;; We need to be able to access the allocated array, and iterate through it.
+ ;; This example will modify the input array inplace.
+ ;; f64.load and f64.store expect the location of a number in memory *in bytes*.
+ ;; If we want to access the 3rd element of an array, we have to pass something
+ ;; like (i32.mul (i32.const 8) (i32.const 2)) to the f64.store function.
+
+ ;; In JavaScript, we would call `apply_cos64` as follows
+ ;; (using the instantiate function from earlier):
+ ;;
+ ;; const main = function () {
+ ;; var wasm = await instantiate('learn-wasm.wasm')
+ ;; var n = 100
+ ;; const memory = new Float64Array(wasm.memory.buffer, 0, n)
+ ;; for (var i=0; i<n; i++) {
+ ;; memory[i] = i;
+ ;; }
+ ;; wasm.apply_cos64(n)
+ ;; }
+ ;;
+ ;; This function will not work if we allocate a Float32Array on the JavaScript
+ ;; side.
+
+ (memory (export "memory") 100)
+
+ (func $apply_cos64 (param $array_length i32)
+ ;; declare the loop counter
+ (local $idx i32)
+ ;; declare the counter that will allow us to access memory
+ (local $idx_bytes i32)
+ ;; constant expressing the number of bytes in a f64 number.
+ (local $bytes_per_double i32)
+
+ ;; declare a variable for storing the value loaded from memory
+ (local $temp_f64 f64)
+
+ (local.set $idx (i32.const 0))
+ (local.set $idx_bytes (i32.const 0)) ;; not entirely necessary
+ (local.set $bytes_per_double (i32.const 8))
+
+ (block
+ (loop
+ ;; this sets idx_bytes to bytes offset of the value we're interested in.
+ (local.set $idx_bytes (i32.mul (local.get $idx) (local.get $bytes_per_double)))
+
+ ;; get the value of the array from memory:
+ (local.set $temp_f64 (f64.load (local.get $idx_bytes)))
+
+ ;; now apply the cosine function:
+ (local.set $temp_64 (call $cos (local.get $temp_64)))
+
+ ;; now store the result at the same location in memory:
+ (f64.store
+ (local.get $idx_bytes)
+ (local.get $temp_64))
+
+ ;; do it all in one step instead
+ (f64.store
+ (local.get $idx_bytes)
+ (call $cos
+ (f64.load
+ (local.get $idx_bytes))))
+
+ ;; increment the loop counter
+ (local.set $idx (i32.add (local.get $idx) (i32.const 1)))
+
+ ;; stop the loop if the loop counter is equal the array length
+ (br_if 1 (i32.eq (local.get $idx) (local.get $array_length)))
+ (br 0)
+ )
+ )
+ )
+ (export "apply_cos64" (func $apply_cos64))
+
+ ;; Wasm is a stack-based language, but for returning values more complicated
+ ;; than an int/float, a separate memory stack has to be manually managed. One
+ ;; approach is to use a mutable global to store the stack_ptr. We give
+ ;; ourselves 1MiB of memstack and grow it downwards.
+ ;;
+ ;; Below is a demonstration of how this C code **might** be written by hand
+ ;;
+ ;; typedef struct {
+ ;; int a;
+ ;; int b;
+ ;; } sum_struct_t;
+ ;;
+ ;; sum_struct_t sum_struct_create(int a, int b) {
+ ;; return (sum_struct_t){a, b};
+ ;; }
+ ;;
+ ;; int sum_local() {
+ ;; sum_struct_t s = sum_struct_create(40, 2);
+ ;; return s.a + s.b;
+ ;; }
+
+ ;; Unlike C, we must manage our own memory stack. We reserve 1MiB
+ (global $memstack_ptr (mut i32) (i32.const 65536))
+
+ ;; Structs can only be returned by reference
+ (func $sum_struct_create
+ (param $sum_struct_ptr i32)
+ (param $var$a i32)
+ (param $var$b i32)
+ ;; c// sum_struct_ptr->a = a;
+ (i32.store
+ (get_local $sum_struct_ptr)
+ (get_local $var$a)
+ )
+
+ ;; c// sum_struct_ptr->b = b;
+ (i32.store offset=4
+ (get_local $sum_struct_ptr)
+ (get_local $var$b)
+ )
+ )
+
+ (func $sum_local (result i32)
+ (local $var$sum_struct$a i32)
+ (local $var$sum_struct$b i32)
+ (local $local_memstack_ptr i32)
+
+ ;; reserve memstack space
+ (i32.sub
+ (get_global $memstack_ptr)
+ (i32.const 8)
+ )
+ tee_local $local_memstack_ptr ;; tee both stores and returns given value
+ set_global $memstack_ptr
+
+ ;; call the function, storing the result in the memstack
+ (call $sum_struct_create
+ ((;$sum_struct_ptr=;) get_local $local_memstack_ptr)
+ ((;$var$a=;) i32.const 40)
+ ((;$var$b=;) i32.const 2)
+ )
+
+ ;; retrieve values from struct
+ (set_local $var$sum_struct$a
+ (i32.load offset=0 (get_local $local_memstack_ptr))
+ )
+ (set_local $var$sum_struct$b
+ (i32.load offset=4 (get_local $local_memstack_ptr))
+ )
+
+ ;; unreserve memstack space
+ (set_global $memstack_ptr
+ (i32.add
+ (get_local $local_memstack_ptr)
+ (i32.const 8)
+ )
+ )
+
+ (i32.add
+ (get_local $var$sum_struct$a)
+ (get_local $var$sum_struct$b)
+ )
+ )
+ (export "sum_local" (func $sum_local))
+)
+
+```
diff --git a/whip.html.markdown b/whip.html.markdown
index e7e5e427..c692714a 100644
--- a/whip.html.markdown
+++ b/whip.html.markdown
@@ -3,6 +3,7 @@ language: whip
contributors:
- ["Tenor Biel", "http://github.com/L8D"]
- ["Saurabh Sandav", "http://github.com/SaurabhSandav"]
+ - ["Paulo Henrique Rodrigues Pinheiro", "https://github.com/paulohrpinheiro"]
author: Tenor Biel
author_url: http://github.com/L8D
filename: whip.lisp
@@ -232,6 +233,7 @@ undefined ; user to indicate a value that hasn't been set
(words "foobar nachos cheese") ; => ("foobar" "nachos" "cheese")
; Join list of strings together.
(unwords ("foo" "bar")) ; => "foobar"
+; Successor and Predecessor
(pred 21) ; => 20
(succ 20) ; => 21
```
diff --git a/wolfram.html.markdown b/wolfram.html.markdown
index 4514006d..5fddbc82 100644
--- a/wolfram.html.markdown
+++ b/wolfram.html.markdown
@@ -123,8 +123,8 @@ myHash[["Green"]] (* 2, use it *)
myHash[["Green"]] := 5 (* 5, update it *)
myHash[["Puce"]] := 3.5 (* 3.5, extend it *)
KeyDropFrom[myHash, "Green"] (* Wipes out key Green *)
-Keys[myHash] (* {Red} *)
-Values[myHash] (* {1} *)
+Keys[myHash] (* {Red, Puce} *)
+Values[myHash] (* {1, 3.5} *)
(* And you can't do any demo of Wolfram without showing this off *)
Manipulate[y^2, {y, 0, 20}] (* Return a reactive user interface that displays y^2
diff --git a/xml.html.markdown b/xml.html.markdown
index b4b54330..2a258d94 100644
--- a/xml.html.markdown
+++ b/xml.html.markdown
@@ -100,8 +100,9 @@ This is what makes XML versatile. It is human readable too. The following docume
A XML document is *well-formed* if it is syntactically correct. However, it is possible to add more constraints to the document, using Document Type Definitions (DTDs). A document whose elements are attributes are declared in a DTD and which follows the grammar specified in that DTD is called *valid* with respect to that DTD, in addition to being well-formed.
+Declaring a DTD externally:
+
```xml
-<!-- Declaring a DTD externally: -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE bookstore SYSTEM "Bookstore.dtd">
<!-- Declares that bookstore is our root element and 'Bookstore.dtd' is the path
@@ -114,8 +115,11 @@ A XML document is *well-formed* if it is syntactically correct. However, it is p
<price>30.00</price>
</book>
</bookstore>
+```
-<!-- The DTD file: -->
+The DTD file (Bookstore.dtd):
+
+```
<!ELEMENT bookstore (book+)>
<!-- The bookstore element may contain one or more child book elements. -->
<!ELEMENT book (title, price)>
@@ -128,10 +132,11 @@ A XML document is *well-formed* if it is syntactically correct. However, it is p
only contain text which is read by the parser and must not contain children.
Compare with CDATA, or character data. -->
<!ELEMENT price (#PCDATA)>
-]>
+```
-<!-- The DTD could be declared inside the XML file itself.-->
+The DTD could be declared inside the XML file itself:
+```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE bookstore [
diff --git a/yaml.html.markdown b/yaml.html.markdown
index 95adbd83..6dc5905e 100644
--- a/yaml.html.markdown
+++ b/yaml.html.markdown
@@ -2,8 +2,8 @@
language: yaml
filename: learnyaml.yaml
contributors:
- - ["Adam Brenecki", "https://github.com/adambrenecki"]
- - ["Suhas SG", "https://github.com/jargnar"]
+- [Leigh Brenecki, 'https://leigh.net.au']
+- [Suhas SG, 'https://github.com/jargnar']
---
YAML is a data serialisation language designed to be directly writable and
@@ -11,9 +11,11 @@ readable by humans.
It's a strict superset of JSON, with the addition of syntactically
significant newlines and indentation, like Python. Unlike Python, however,
-YAML doesn't allow literal tab characters at all.
+YAML doesn't allow literal tab characters for indentation.
```yaml
+--- # document start
+
# Comments in YAML look like this.
################
@@ -27,13 +29,17 @@ another_key: Another value goes here.
a_number_value: 100
scientific_notation: 1e+12
# The number 1 will be interpreted as a number, not a boolean. if you want
-# it to be intepreted as a boolean, use true
+# it to be interpreted as a boolean, use true
boolean: true
null_value: null
key with spaces: value
# Notice that strings don't need to be quoted. However, they can be.
-however: "A string, enclosed in quotes."
-"Keys can be quoted too.": "Useful if you want to put a ':' in your key."
+however: 'A string, enclosed in quotes.'
+'Keys can be quoted too.': "Useful if you want to put a ':' in your key."
+single quotes: 'have ''one'' escape pattern'
+double quotes: "have many: \", \0, \t, \u263A, \x0d\x0a == \r\n, and more."
+# UTF-8/16/32 characters need to be encoded
+Superscript two: \u00B2
# Multiple-line strings can be written either as a 'literal block' (using |),
# or a 'folded block' (using '>').
@@ -59,12 +65,12 @@ folded_style: >
# COLLECTION TYPES #
####################
-# Nesting is achieved by indentation.
+# Nesting uses indentation. 2 space indent is preferred (but not required).
a_nested_map:
- key: value
- another_key: Another Value
- another_nested_map:
- hello: hello
+ key: value
+ another_key: Another Value
+ another_nested_map:
+ hello: hello
# Maps don't have to have string keys.
0.25: a float key
@@ -72,8 +78,8 @@ a_nested_map:
# Keys can also be complex, like multi-line objects
# We use ? followed by a space to indicate the start of a complex key.
? |
- This is a key
- that has multiple lines
+ This is a key
+ that has multiple lines
: and this is its value
# YAML also allows mapping between sequences with the complex key syntax
@@ -81,24 +87,28 @@ a_nested_map:
# An example
? - Manchester United
- Real Madrid
-: [ 2001-01-01, 2002-02-02 ]
+: [2001-01-01, 2002-02-02]
-# Sequences (equivalent to lists or arrays) look like this:
+# Sequences (equivalent to lists or arrays) look like this
+# (note that the '-' counts as indentation):
a_sequence:
- - Item 1
- - Item 2
- - 0.5 # sequences can contain disparate types.
- - Item 4
- - key: value
- another_key: another_value
- -
- - This is a sequence
- - inside another sequence
+ - Item 1
+ - Item 2
+ - 0.5 # sequences can contain disparate types.
+ - Item 4
+ - key: value
+ another_key: another_value
+ -
+ - This is a sequence
+ - inside another sequence
+ - - - Nested sequence indicators
+ - can be collapsed
# Since YAML is a superset of JSON, you can also write JSON-style maps and
# sequences:
json_map: {"key": "value"}
json_seq: [3, 2, 1, "takeoff"]
+and quotes are optional: {key: [3, 2, 1, takeoff]}
#######################
# EXTRA YAML FEATURES #
@@ -111,15 +121,19 @@ other_anchor: *anchor_name
# Anchors can be used to duplicate/inherit properties
base: &base
- name: Everyone has same name
+ name: Everyone has same name
+
+# The regexp << is called Merge Key Language-Independent Type. It is used to
+# indicate that all the keys of one or more specified maps should be inserted
+# into the current map.
-foo: &foo
- <<: *base
- age: 10
+foo:
+ <<: *base
+ age: 10
-bar: &bar
- <<: *base
- age: 20
+bar:
+ <<: *base
+ age: 20
# foo and bar would also have name: Everyone has same name
@@ -132,7 +146,7 @@ python_complex_number: !!python/complex 1+2j
# We can also use yaml complex keys with language specific tags
? !!python/tuple [5, 7]
: Fifty Seven
-# Would be {(5, 7): 'Fifty Seven'} in python
+# Would be {(5, 7): 'Fifty Seven'} in Python
####################
# EXTRA YAML TYPES #
@@ -147,25 +161,28 @@ date: 2002-12-14
# The !!binary tag indicates that a string is actually a base64-encoded
# representation of a binary blob.
gif_file: !!binary |
- R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
- OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
- +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
- AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
# YAML also has a set type, which looks like this:
set:
- ? item1
- ? item2
- ? item3
+ ? item1
+ ? item2
+ ? item3
+or: {item1, item2, item3}
-# Like Python, sets are just maps with null values; the above is equivalent to:
+# Sets are just maps with null values; the above is equivalent to:
set2:
- item1: null
- item2: null
- item3: null
+ item1: null
+ item2: null
+ item3: null
+
+... # document end
```
### More Resources
-+ [YAML official website](http://yaml.org/)
-+ [Online YAML Validator](http://codebeautify.org/yaml-validator)
++ [YAML official website](https://yaml.org/)
++ [Online YAML Validator](http://www.yamllint.com/)
diff --git a/zfs.html.markdown b/zfs.html.markdown
index 3fe05896..6795b1fa 100644
--- a/zfs.html.markdown
+++ b/zfs.html.markdown
@@ -24,6 +24,7 @@ VDEV's offer better reliability and safety than a RAID card. It is discouraged
RAID setup with ZFS, as ZFS expects to directly manage the underlying disks.
Types of VDEV's
+
* stripe (a single disk, no redundancy)
* mirror (n-way mirrors supported)
* raidz
@@ -60,6 +61,7 @@ single host can have 2^64 storage pools. The limits are huge.
### Storage Pools
Actions:
+
* List
* Status
* Destroy
@@ -147,6 +149,7 @@ $ zpool destroy test
### Datasets
Actions:
+
* Create
* List
* Rename
@@ -218,7 +221,7 @@ Delete dataset
```bash
# Datasets cannot be deleted if they have any snapshots
-zfs destroy tank/root/home
+$ zfs destroy tank/root/home
```
Get / set properties of a dataset
@@ -267,6 +270,7 @@ ZFS snapshots are one of the things about zfs that are a really big deal
* They are easy to automate.
Actions:
+
* Create
* Delete
* Rename
@@ -290,6 +294,7 @@ tank/home/sarlalian@now 0 - 259M -
tank/home/alice@now 0 - 156M -
tank/home/bob@now 0 - 156M -
...
+```
Destroy snapshots
@@ -309,13 +314,13 @@ Renaming Snapshots
$ zfs rename tank/home/sarlalian@now tank/home/sarlalian@today
$ zfs rename tank/home/sarlalian@now today
-# zfs rename -r tank/home@now @yesterday
+$ zfs rename -r tank/home@now @yesterday
```
Accessing snapshots
```bash
-# CD Into a snapshot directory
+# CD into a snapshot directory
$ cd /home/.zfs/snapshot/
```
@@ -331,11 +336,11 @@ $ zfs send tank/home/sarlalian@now | zfs recv backups/home/sarlalian
# Send a snapshot to a remote host
$ zfs send tank/home/sarlalian@now | ssh root@backup_server 'zfs recv tank/home/sarlalian'
-# Send full dataset with snapshos to new host
+# Send full dataset with snapshots to new host
$ zfs send -v -R tank/home@now | ssh root@backup_server 'zfs recv tank/home'
```
-Cloneing Snapshots
+Cloning Snapshots
```bash
# Clone a snapshot
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/awk-cn.html.markdown b/zh-cn/awk-cn.html.markdown
new file mode 100644
index 00000000..8ee2db2c
--- /dev/null
+++ b/zh-cn/awk-cn.html.markdown
@@ -0,0 +1,327 @@
+---
+category: tool
+tool: awk
+contributors:
+ - ["Marshall Mason", "http://github.com/marshallmason"]
+translators:
+ - ["Tian Zhipeng", "https://github.com/tianzhipeng-git"]
+filename: learnawk-cn.awk
+lang: zh-cn
+---
+
+AWK是POSIX兼容的UNIX系统中的标准工具. 它像简化版的Perl, 非常适用于文本处理任务和其他脚本类需求.
+它有着C风格的语法, 但是没有分号, 没有手动内存管理, 没有静态类型.
+他擅长于文本处理, 你可以通过shell脚本调用AWK, 也可以用作独立的脚本语言.
+
+为什么使用AWK而不是Perl, 大概是因为AWK是UNIX的一部分, 你总能依靠它, 而Perl已经前途未卜了.
+AWK比Perl更易读. 对于简单的文本处理脚本, 特别是按行读取文件, 按分隔符分隔处理, AWK极可能是正确的工具.
+
+```awk
+#!/usr/bin/awk -f
+
+# 注释使用井号
+
+# AWK程序由一系列 模式(patterns) 和 动作(actions) 组成.
+# 最重要的模式叫做 BEGIN. 动作由大括号包围.
+BEGIN {
+
+ # BEGIN在程序最开始运行. 在这里放一些在真正处理文件之前的准备和setup的代码.
+ # 如果没有文本文件要处理, 那就把BEGIN作为程序的主入口吧.
+
+ # 变量是全局的. 直接赋值使用即可, 无需声明.
+ count = 0
+
+ # 运算符和C语言系一样
+ a = count + 1
+ b = count - 1
+ c = count * 1
+ d = count / 1 # 整数除法
+ e = count % 1 # 取余
+ f = count ^ 1 # 取幂
+
+ a += 1
+ b -= 1
+ c *= 1
+ d /= 1
+ e %= 1
+ f ^= 1
+
+ # 自增1, 自减1
+ a++
+ b--
+
+ # 前置运算, 返回增加之后的值
+ ++a
+ --b
+
+ # 注意, 不需要分号之类的标点来分隔语句
+
+ # 控制语句
+ if (count == 0)
+ print "Starting with count of 0"
+ else
+ print "Huh?"
+
+ # 或者三目运算符
+ print (count == 0) ? "Starting with count of 0" : "Huh?"
+
+ # 多行的代码块用大括号包围
+ while (a < 10) {
+ print "String concatenation is done" " with a series" " of"
+ " space-separated strings"
+ print a
+
+ a++
+ }
+
+ for (i = 0; i < 10; i++)
+ print "Good ol' for loop"
+
+ # 标准的比较运算符
+ a < b # 小于
+ a <= b # 小于或等于
+ a != b # 不等于
+ a == b # 等于
+ a > b # 大于
+ a >= b # 大于或等于
+
+ # 也有逻辑运算符
+ a && b # 且
+ a || b # 或
+
+ # 并且有超实用的正则表达式匹配
+ if ("foo" ~ "^fo+$")
+ print "Fooey!"
+ if ("boo" !~ "^fo+$")
+ print "Boo!"
+
+ # 数组
+ arr[0] = "foo"
+ arr[1] = "bar"
+ # 不幸的是, 没有其他方式初始化数组. 必须像这样一行一行的赋值.
+
+ # 关联数组, 类似map或dict的用法.
+ assoc["foo"] = "bar"
+ assoc["bar"] = "baz"
+
+ # 多维数组. 但是有一些局限性这里不提了.
+ multidim[0,0] = "foo"
+ multidim[0,1] = "bar"
+ multidim[1,0] = "baz"
+ multidim[1,1] = "boo"
+
+ # 可以检测数组包含关系
+ if ("foo" in assoc)
+ print "Fooey!"
+
+ # 可以使用in遍历数组
+ for (key in assoc)
+ print assoc[key]
+
+ # 命令行参数是一个叫ARGV的数组
+ for (argnum in ARGV)
+ print ARGV[argnum]
+
+ # 可以从数组中移除元素
+ # 在 防止awk把文件参数当做数据来处理 时delete功能很有用.
+ delete ARGV[1]
+
+ # 命令行参数的个数是一个叫ARGC的变量
+ print ARGC
+
+ # AWK有很多内置函数, 分为三类, 会在接下来定义的各个函数中介绍.
+
+ return_value = arithmetic_functions(a, b, c)
+ string_functions()
+ io_functions()
+}
+
+# 定义函数
+function arithmetic_functions(a, b, c, d) {
+
+ # 或许AWK最让人恼火的地方是没有局部变量, 所有东西都是全局的,
+ # 对于短的脚本还好, 对于长一些的就会成问题.
+
+ # 这里有一个技巧, 函数参数是对函数局部可见的, 并且AWK允许定义多余的参数,
+ # 因此可以像上面那样把局部变量插入到函数声明中.
+ # 为了方便区分普通参数(a,b,c)和局部变量(d), 可以多键入一些空格.
+
+ # 现在介绍数学类函数
+
+ # 多数AWK实现中包含标准的三角函数
+ localvar = sin(a)
+ localvar = cos(a)
+ localvar = atan2(a, b) # arc tangent of b / a
+
+ # 对数
+ localvar = exp(a)
+ localvar = log(a)
+
+ # 平方根
+ localvar = sqrt(a)
+
+ # 浮点型转为整型
+ localvar = int(5.34) # localvar => 5
+
+ # 随机数
+ srand() # 接受随机种子作为参数, 默认使用当天的时间
+ localvar = rand() # 0到1之间随机
+
+ # 函数返回
+ return localvar
+}
+
+function string_functions( localvar, arr) {
+
+ # AWK, 作为字符处理语言, 有很多字符串相关函数, 其中大多数都严重依赖正则表达式.
+
+ # 搜索并替换, 第一个出现的 (sub) or 所有的 (gsub)
+ # 都是返回替换的个数
+ localvar = "fooooobar"
+ sub("fo+", "Meet me at the ", localvar) # localvar => "Meet me at the bar"
+ gsub("e+", ".", localvar) # localvar => "m..t m. at th. bar"
+
+ # 搜索匹配正则的字符串
+ # index() 也是搜索, 不支持正则
+ match(localvar, "t") # => 4, 't'在4号位置.
+ # (译者注: awk是1开始计数的,不是常见的0-base)
+
+ # 按分隔符分隔
+ split("foo-bar-baz", arr, "-") # a => ["foo", "bar", "baz"]
+
+ # 其他有用的函数
+ sprintf("%s %d %d %d", "Testing", 1, 2, 3) # => "Testing 1 2 3"
+ substr("foobar", 2, 3) # => "oob"
+ substr("foobar", 4) # => "bar"
+ length("foo") # => 3
+ tolower("FOO") # => "foo"
+ toupper("foo") # => "FOO"
+}
+
+function io_functions( localvar) {
+
+ # 你已经见过的print函数
+ print "Hello world"
+
+ # 也有printf
+ printf("%s %d %d %d\n", "Testing", 1, 2, 3)
+
+ # AWK本身没有文件句柄, 当你使用需要文件的东西时会自动打开文件,
+ # 做文件I/O时, 字符串就是打开的文件句柄. 这看起来像Shell
+ print "foobar" >"/tmp/foobar.txt"
+
+ # 现在"/tmp/foobar.txt"字符串是一个文件句柄, 你可以关闭它
+ close("/tmp/foobar.txt")
+
+ # 在shell里运行一些东西
+ system("echo foobar") # => prints foobar
+
+ # 从标准输入中读一行, 并存储在localvar中
+ getline localvar
+
+ # 从管道中读一行, 并存储在localvar中
+ "echo foobar" | getline localvar # localvar => "foobar"
+ close("echo foobar")
+
+ # 从文件中读一行, 并存储在localvar中
+ getline localvar <"/tmp/foobar.txt"
+ close("/tmp/foobar.txt")
+}
+
+# 正如开头所说, AWK程序由一系列模式和动作组成. 你已经看见了重要的BEGIN pattern,
+# 其他的pattern在你需要处理来自文件或标准输入的的数据行时才用到.
+#
+# 当你给AWK程序传参数时, 他们会被视为要处理文件的文件名, 按顺序全部会处理.
+# 可以把这个过程看做一个隐式的循环, 遍历这些文件中的所有行.
+# 然后这些模式和动作就是这个循环里的switch语句一样
+
+/^fo+bar$/ {
+
+ # 这个动作会在匹配这个正则(/^fo+bar$/)的每一行上执行. 不匹配的则会跳过.
+ # 先让我们打印它:
+ print
+
+ # 哦, 没有参数, 那是因为print有一个默认参数 $0.
+ # $0 是当前正在处理的行, 自动被创建好了.
+
+ # 你可能猜到有其他的$变量了.
+ # 每一行在动作执行前会被分隔符分隔. 像shell中一样, 每个字段都可以用$符访问
+
+ # 这个会打印这行的第2和第4个字段
+ print $2, $4
+
+ # AWK自动定义了许多其他的变量帮助你处理行. 最常用的是NF变量
+ # 打印这一行的字段数
+ print NF
+
+ # 打印这一行的最后一个字段
+ print $NF
+}
+
+# 每一个模式其实是一个true/false判断, 上面那个正则其实也是一个true/false判断, 只不过被部分省略了.
+# 没有指定时默认使用当前处理的整行($0)进行匹配. 因此, 完全版本是这样:
+
+$0 ~ /^fo+bar$/ {
+ print "Equivalent to the last pattern"
+}
+
+a > 0 {
+ # 只要a是整数, 这块会在每一行上执行.
+}
+
+# 就是这样, 处理文本文件, 一次读一行, 对行做一些操作.
+# 按分隔符分隔, 这在UNIX中很常见, awk都帮你做好了.
+# 你所需要做的是基于自己的需求写一些模式和动作.
+
+# 这里有一个快速的例子, 展示了AWK所擅长做的事.
+# 它从标准输入读一个名字, 打印这个first name下所有人的平均年龄.
+# 示例数据:
+#
+# Bob Jones 32
+# Jane Doe 22
+# Steve Stevens 83
+# Bob Smith 29
+# Bob Barker 72
+#
+# 示例脚本:
+
+BEGIN {
+
+ # 首先, 问用户要一个名字
+ print "What name would you like the average age for?"
+
+ # 从标准输入获取名字
+ getline name <"/dev/stdin"
+}
+
+# 然后, 用给定的名字匹配每一行的第一个字段.
+$1 == name {
+
+ # 这里我们要使用几个有用的变量, 已经提前为我们加载好的:
+ # $0 是整行
+ # $3 是第三个字段, 就是我们所感兴趣的年龄
+ # NF 字段数, 这里是3
+ # NR 至此为止的行数
+ # FILENAME 在处理的文件名
+ # FS 在使用的字段分隔符, 这里是空格" "
+ # ...等等, 还有很多, 在帮助文档中列出.
+
+ # 跟踪 总和以及行数
+ sum += $3
+ nlines++
+}
+
+# 另一个特殊的模式叫END. 它会在处理完所有行之后运行. 不像BEGIN, 它只会在有输入的时候运行.
+# 它在所有文件依据给定的模式和动作处理完后运行, 目的通常是输出一些最终报告, 做一些数据聚合操作.
+
+END {
+ if (nlines)
+ print "The average age for " name " is " sum / nlines
+}
+
+```
+更多:
+
+* [Awk 教程](http://www.grymoire.com/Unix/Awk.html)
+* [Awk 手册](https://linux.die.net/man/1/awk)
+* [The GNU Awk 用户指南](https://www.gnu.org/software/gawk/manual/gawk.html) GNU Awk在大多数Linux中预装
diff --git a/zh-cn/bf-cn.html.markdown b/zh-cn/bf-cn.html.markdown
index 6cea3012..2d2a114a 100644
--- a/zh-cn/bf-cn.html.markdown
+++ b/zh-cn/bf-cn.html.markdown
@@ -1,11 +1,13 @@
---
language: bf
-lang: zh-cn
+filename: brainfuck-cn.bf
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]
translators:
- ["lyuehh", "https://github.com/lyuehh"]
+lang: zh-cn
+
---
Brainfuck 是一个极小的只有8个指令的图灵完全的编程语言。
diff --git a/zh-cn/c++-cn.html.markdown b/zh-cn/c++-cn.html.markdown
index d71aa8d6..e0d6b6fe 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() {
@@ -567,6 +567,6 @@ void doSomethingWithAFile(const std::string& filename)
```
扩展阅读:
-<http://cppreference.com/w/cpp> 提供了最新的语法参考。
-
-可以在 <http://cplusplus.com> 找到一些补充资料。
+* [CPP Reference](http://cppreference.com/w/cpp) 提供了最新的语法参考。
+* 可以在 [CPlusPlus](http://cplusplus.com) 找到一些补充资料。
+* 可以在 [TheChernoProject - C ++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb)上找到涵盖语言基础和设置编码环境的教程。
diff --git a/zh-cn/c-cn.html.markdown b/zh-cn/c-cn.html.markdown
index 1e10416e..7286fa9f 100644
--- a/zh-cn/c-cn.html.markdown
+++ b/zh-cn/c-cn.html.markdown
@@ -41,7 +41,7 @@ enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT};
void function_1(char c);
void function_2(void);
-// 如果函数出现在main()之后,那么必须在main()之前
+// 如果函数调用在main()之后,那么必须声明在main()之前
// 先声明一个函数原型
int add_two_ints(int x1, int x2); // 函数原型
@@ -128,7 +128,7 @@ printf("Enter the array size: "); // 询问用户数组长度
char buf[0x100];
fgets(buf, sizeof buf, stdin);
-// stroul 将字符串解析为无符号整数
+// strtoul 将字符串解析为无符号整数
size_t size = strtoul(buf, NULL, 10);
int var_length_array[size]; // 声明VLA
printf("sizeof array = %zu\n", sizeof var_length_array);
@@ -612,7 +612,7 @@ typedef void (*my_fnp_type)(char *);
最好找一本 [K&R, aka "The C Programming Language", “C程序设计语言”](https://en.wikipedia.org/wiki/The_C_Programming_Language)。它是关于C最重要的一本书,由C的创作者撰写。不过需要留意的是它比较古老了,因此有些不准确的地方。
-另一个比较好的资源是 [Learn C the hard way](http://c.learncodethehardway.org/book/)
+另一个比较好的资源是 [Learn C the hard way](http://learncodethehardway.org/c/)
如果你有问题,请阅读[compl.lang.c Frequently Asked Questions](http://c-faq.com/)。
diff --git a/zh-cn/clojure-macro-cn.html.markdown b/zh-cn/clojure-macro-cn.html.markdown
index 9324841e..23b2f203 100644
--- a/zh-cn/clojure-macro-cn.html.markdown
+++ b/zh-cn/clojure-macro-cn.html.markdown
@@ -142,11 +142,9 @@ lang: zh-cn
## 扩展阅读
-[Clojure for the Brave and True](http://www.braveclojure.com/)系列的编写宏
-http://www.braveclojure.com/writing-macros/
+[Clojure for the Brave and True](http://www.braveclojure.com/)
+[系列的编写宏](http://www.braveclojure.com/writing-macros/)
-官方文档
-http://clojure.org/macros
+[官方文档](http://clojure.org/macros)
-何时使用宏?
-http://dunsmor.com/lisp/onlisp/onlisp_12.html
+[何时使用宏?](https://lispcast.com/when-to-use-a-macro/)
diff --git a/zh-cn/common-lisp-cn.html.markdown b/zh-cn/common-lisp-cn.html.markdown
index c7fe7e2c..b8979ed0 100644
--- a/zh-cn/common-lisp-cn.html.markdown
+++ b/zh-cn/common-lisp-cn.html.markdown
@@ -289,7 +289,7 @@ nil ; 逻辑假,或者空列表
;; (通过键)检索对应的值
(gethash 'a *m*) ; => 1, t
-;; 注意此处有一细节:Common Lisp往往返回多个值。`gethash`返回的两个值是t,代表找到了这个元素;返回nil表示没有找到这个元素。
+;; 注意此处有一细节:Common Lisp往往返回多个值。`gethash`返回的第二个值是t,代表找到了这个元素;返回nil表示没有找到这个元素。
;;(译者注:返回的第一个值表示给定的键所对应的值或者nil;)
;;(第二个是一个布尔值,表示在哈希表中是否存在这个给定的键)
;; 例如,如果可以找到给定的键所对应的值,则返回一个t,否则返回nil
diff --git a/zh-cn/crystal-cn.html.markdown b/zh-cn/crystal-cn.html.markdown
new file mode 100644
index 00000000..14805114
--- /dev/null
+++ b/zh-cn/crystal-cn.html.markdown
@@ -0,0 +1,567 @@
+---
+language: crystal
+filename: learncrystal-cn.cr
+contributors:
+ - ["Vitalii Elenhaupt", "http://veelenga.com"]
+ - ["Arnaud Fernandés", "https://github.com/TechMagister/"]
+translators:
+ - ["Xuty", "https://github.com/xtyxtyx"]
+lang: zh-cn
+---
+
+```crystal
+
+# 这是一行注释
+
+# 一切都是对象(object)
+nil.class #=> Nil
+100.class #=> Int32
+true.class #=> Bool
+
+# nil, false 以及空指针是假值(falsey values)
+!nil #=> true : Bool
+!false #=> true : Bool
+!0 #=> false : Bool
+
+# 整数类型
+
+1.class #=> Int32
+
+# 四种有符号整数
+1_i8.class #=> Int8
+1_i16.class #=> Int16
+1_i32.class #=> Int32
+1_i64.class #=> Int64
+
+# 四种无符号整数
+1_u8.class #=> UInt8
+1_u16.class #=> UInt16
+1_u32.class #=> UInt32
+1_u64.class #=> UInt64
+
+2147483648.class #=> Int64
+9223372036854775808.class #=> UInt64
+
+# 二进制数
+0b1101 #=> 13 : Int32
+
+# 八进制数
+0o123 #=> 83 : Int32
+
+# 十六进制数
+0xFE012D #=> 16646445 : Int32
+0xfe012d #=> 16646445 : Int32
+
+# 浮点数类型
+
+1.0.class #=> Float64
+
+# Crystal中有两种浮点数
+1.0_f32.class #=> Float32
+1_f32.class #=> Float32
+
+1e10.class #=> Float64
+1.5e10.class #=> Float64
+1.5e-7.class #=> Float64
+
+# 字符类型
+
+'a'.class #=> Char
+
+# 八进制字符
+'\101' #=> 'A' : Char
+
+# Unicode字符
+'\u0041' #=> 'A' : Char
+
+# 字符串
+
+"s".class #=> String
+
+# 字符串不可变(immutable)
+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
+
+# 多行字符串
+"这是一个
+ 多行字符串"
+
+# 书写带有引号的字符串
+%(hello "world") #=> "hello \"world\""
+
+# 符号类型
+# 符号是不可变的常量,本质上是Int32类型
+# 符号通常被用来代替字符串,来高效地传递特定的值
+
+:symbol.class #=> Symbol
+
+sentence = :question? # :"question?" : Symbol
+
+sentence == :question? #=> true : Bool
+sentence == :exclamation! #=> false : Bool
+sentence == "question?" #=> false : Bool
+
+# 数组类型(Array)
+
+[1, 2, 3].class #=> Array(Int32)
+[1, "hello", 'x'].class #=> Array(Int32 | String | Char)
+
+# 必须为空数组指定类型
+[] # Syntax error: for empty arrays use '[] of ElementType'
+[] of Int32 #=> [] : Array(Int32)
+Array(Int32).new #=> [] : Array(Int32)
+
+# 数组可以通过下标访问
+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)
+
+# 使用负位置编号,从后往前访问数组
+array[-1] #=> 5
+
+# With a start index and size
+# 使用起始位置编号+大小
+array[2, 3] #=> [3, 4, 5]
+
+# 使用范围(range)访问数组
+array[1..3] #=> [2, 3, 4]
+
+# 向尾部添加元素
+array << 6 #=> [1, 2, 3, 4, 5, 6]
+
+# 删除尾部元素
+array.pop #=> 6
+array #=> [1, 2, 3, 4, 5]
+
+# 删除首部元素
+array.shift #=> 1
+array #=> [2, 3, 4, 5]
+
+# 检查元素是否存在与数组之中
+array.includes? 3 #=> true
+
+# 一种特殊语法,用来创建字符串数组或符号数组
+%w(one two three) #=> ["one", "two", "three"] : Array(String)
+%i(one two three) #=> [:one, :two, :three] : Array(Symbol)
+
+# 对于定义了`new`和`#<<`方法的类,可以用以下语法创建新对象
+set = Set{1, 2, 3} #=> [1, 2, 3]
+set.class #=> Set(Int32)
+
+# 以下代码与上方等同
+set = Set(typeof(1, 2, 3)).new
+set << 1
+set << 2
+set << 3
+
+# 哈希表类型(Hash)
+
+{1 => 2, 3 => 4}.class #=> Hash(Int32, Int32)
+{1 => 2, 'a' => 3}.class #=> Hash(Int32 | Char, Int32)
+
+# 必须为空哈希表指定类型
+{} # Syntax error
+{} of Int32 => Int32 # {}
+Hash(Int32, Int32).new # {}
+
+# 可以使用键(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
+
+# 检查某一键哈希表中是否存在
+hash.has_key? "color" #=> true
+
+# 对于定义了`#[]=`方法的类,可以使用以下语法创建对象
+class MyType
+ def []=(key, value)
+ puts "do stuff"
+ end
+end
+
+MyType{"foo" => "bar"}
+
+# 以上与下列代码等同
+tmp = MyType.new
+tmp["foo"] = "bar"
+tmp
+
+# 范围类型(Range)
+
+1..10 #=> Range(Int32, Int32)
+Range.new(1, 10).class #=> Range(Int32, Int32)
+
+# 包含或不包含端点
+(3..5).to_a #=> [3, 4, 5]
+(3...5).to_a #=> [3, 4]
+
+# 检查某一值是否在范围内
+(1..8).includes? 2 #=> true
+
+# 元组类型(Tuple)
+
+# 元组类型尺寸固定,不可变,储存在栈中
+# 元组可以有不同类型的对象组成
+{1, "hello", 'x'}.class #=> Tuple(Int32, String, Char)
+
+# 使用下标访问元组
+tuple = {:key1, :key2}
+tuple[1] #=> :key2
+tuple[2] #=> syntax error : Index out of bound
+
+# 将元组中的元素赋值给变量
+a, b, c = {:a, 'b', "c"}
+a #=> :a
+b #=> 'b'
+c #=> "c"
+
+# 命名元组类型(NamedTuple)
+
+tuple = {name: "Crystal", year: 2011} # NamedTuple(name: String, year: Int32)
+tuple[:name] # => "Crystal" (String)
+tuple[:year] # => 2011 (Int32)
+
+# 命名元组的键可以是字符串常量
+{"this is a key": 1} # => NamedTuple("this is a key": Int32)
+
+# 过程类型(Proc)
+# 过程代表一个函数指针,以及可选的上下文(闭包)
+# 过程通常使用字面值创建
+proc = ->(x : Int32) { x.to_s }
+proc.class # Proc(Int32, String)
+
+# 或者使用`new`方法创建
+Proc(Int32, String).new { |x| x.to_s }
+
+# 使用`call`方法调用过程
+proc.call 10 #=> "10"
+
+# 控制语句(Control statements)
+
+if true
+ "if 语句"
+elsif false
+ "else-if, 可选"
+else
+ "else, 同样可选"
+end
+
+puts "可以将if后置" if true
+
+# 将if作为表达式
+a = if 2 > 1
+ 3
+ else
+ 4
+ end
+
+a #=> 3
+
+# 条件表达式
+a = 1 > 2 ? 3 : 4 #=> 4
+
+# `case`语句
+cmd = "move"
+
+action = case cmd
+ when "create"
+ "Creating..."
+ when "copy"
+ "Copying..."
+ when "move"
+ "Moving..."
+ when "delete"
+ "Deleting..."
+end
+
+action #=> "Moving..."
+
+# 循环
+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
+
+# 更好的做法是使用`each`
+(0..3).each do |index|
+ puts "Index: #{index}"
+end
+# Index: 0
+# Index: 1
+# Index: 2
+# Index: 3
+
+# 变量的类型取决于控制语句中表达式的类型
+if a < 3
+ a = "hello"
+else
+ a = true
+end
+typeof a #=> (Bool | String)
+
+if a && b
+ # 此处`a`与`b`均为Nil
+end
+
+if a.is_a? String
+ a.class #=> String
+end
+
+# 函数(Functions)
+
+def double(x)
+ x * 2
+end
+
+# 函数(以及所有代码块)均将最末尾表达式的值作为返回值
+double(2) #=> 4
+
+# 在没有歧义的情况下,括号可以省略
+double 3 #=> 6
+
+double double 3 #=> 12
+
+def sum(x, y)
+ x + y
+end
+
+# 使用逗号分隔参数
+sum 3, 4 #=> 7
+
+sum sum(3, 4), 5 #=> 12
+
+# yield
+# 所有函数都有一个默认生成、可选的代码块(block)参数
+# 在函数中可以使用yield调用此代码块
+
+def surround
+ puts '{'
+ yield
+ puts '}'
+end
+
+surround { puts "hello world" }
+
+# {
+# hello world
+# }
+
+
+# 可将代码块作为参数传给函数
+# "&" 表示对代码块参数的引用
+def guests(&block)
+ block.call "some_argument"
+end
+
+# 使用星号"*"将参数转换成元组
+def guests(*array)
+ array.each { |guest| puts guest }
+end
+
+# 如果函数返回数组,可以将其解构
+def foods
+ ["pancake", "sandwich", "quesadilla"]
+end
+breakfast, lunch, dinner = foods
+breakfast #=> "pancake"
+dinner #=> "quesadilla"
+
+# 按照约定,所有返回布尔值的方法都以问号结尾
+5.even? # false
+5.odd? # true
+
+# 以感叹号结尾的方法,都有一些破坏性(destructive)行为,比如改变调用接收者(receiver)
+# 对于某些方法,带有感叹号的版本将改变调用接收者,而不带有感叹号的版本返回新值
+company_name = "Dunder Mifflin"
+company_name.gsub "Dunder", "Donald" #=> "Donald Mifflin"
+company_name #=> "Dunder Mifflin"
+company_name.gsub! "Dunder", "Donald"
+company_name #=> "Donald Mifflin"
+
+
+# 使用`class`关键字来定义类(class)
+class Human
+
+ # 类变量,由类的所有实例所共享
+ @@species = "H. sapiens"
+
+ # `name`的类型为`String`
+ @name : String
+
+ # 构造器方法(initializer)
+ # 其中@name、@age为简写,相当于
+ #
+ # def initialize(name, age = 0)
+ # @name = name
+ # @age = age
+ # end
+ #
+ # `age`为可选参数,如果未指定,则使用默认值0
+ def initialize(@name, @age = 0)
+ end
+
+ # @name的setter方法
+ def name=(name)
+ @name = name
+ end
+
+ # @name的getter方法
+ def name
+ @name
+ end
+
+ # 上述getter与setter的定义可以用property宏简化
+ property :name
+
+ # 也可用getter与setter宏独立创建getter与setter
+ getter :name
+ setter :name
+
+ # 此处的`self.`使`say`成为类方法
+ def self.say(msg)
+ puts msg
+ end
+
+ def species
+ @@species
+ end
+end
+
+
+# 将类实例化
+jim = Human.new("Jim Halpert")
+
+dwight = Human.new("Dwight K. Schrute")
+
+# 调用一些实例方法
+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"
+
+# 调用类方法
+Human.say("Hi") #=> 输出 Hi ,返回 nil
+
+# 带有`@`前缀的变量为实例变量
+class TestClass
+ @var = "I'm an instance var"
+end
+
+# 带有`@@`前缀的变量为类变量
+class TestClass
+ @@var = "I'm a class var"
+end
+# 首字母大写的变量为常量
+Var = "这是一个常量"
+Var = "无法再次被赋值" # 常量`Var`已经被初始化
+
+# 在crystal中类也是对象(object),因此类也有实例变量(instance variable)
+# 类变量的定义由类以及类的派生类所共有,但类变量的值是独立的
+
+# 基类
+class Human
+ @@foo = 0
+
+ def self.foo
+ @@foo
+ end
+
+ def self.foo=(value)
+ @@foo = value
+ end
+end
+
+# 派生类
+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
+
+# include <Module> 将模块(module)中的方法添加为实例方法
+# extend <Module> 将模块中的方法添加为类方法
+
+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)
+class MyException < Exception
+end
+
+# 再定义一个异常类
+class MyAnotherException < Exception; end
+
+ex = begin
+ raise MyException.new
+rescue ex1 : IndexError
+ "ex1"
+rescue ex2 : MyException | MyAnotherException
+ "ex2"
+rescue ex3 : Exception
+ "ex3"
+rescue ex4 # 捕捉任何类型的异常
+ "ex4"
+end
+
+ex #=> "ex2"
+
+```
+
+## 参考资料
+
+- [官方网站](https://crystal-lang.org/)
+- [官方文档](https://crystal-lang.org/docs/overview/)
+- [在线运行代码](https://play.crystal-lang.org/#/cr)
+- [Github仓库](https://github.com/crystal-lang/crystal)
diff --git a/zh-cn/css-cn.html.markdown b/zh-cn/css-cn.html.markdown
index dc6dcc4f..ec937dfb 100644
--- a/zh-cn/css-cn.html.markdown
+++ b/zh-cn/css-cn.html.markdown
@@ -132,7 +132,7 @@ div.some-parent.class-name {}
font-family: Arial;
font-family: "Courier New"; /* 使用双引号包裹含空格的字体名称 */
font-family: "Courier New", Trebuchet, Arial; /* 如果第一个
- 字体没找到,浏览器会使用第二个字体,一次类推 */
+ 字体没找到,浏览器会使用第二个字体,以此类推 */
}
```
diff --git a/zh-cn/dart-cn.html.markdown b/zh-cn/dart-cn.html.markdown
index 6a6562bc..79db8e5c 100644
--- a/zh-cn/dart-cn.html.markdown
+++ b/zh-cn/dart-cn.html.markdown
@@ -176,23 +176,47 @@ example13() {
match(s2);
}
-// 布尔表达式必需被解析为 true 或 false,
-// 因为不支持隐式转换。
+// 布尔表达式支持隐式转换以及动态类型
example14() {
- var v = true;
- if (v) {
- print("Example14 value is true");
+ var a = true;
+ if (a) {
+ print("Example14 true, a is $a");
}
- v = null;
+ a = null;
+ if (a) {
+ print("Example14 true, a is $a");
+ } else {
+ print("Example14 false, a is $a"); // 执行到这里
+ }
+
+ // 动态类型的null可以转换成bool型
+ var b;// b是动态类型
+ b = "abc";
try {
- if (v) {
- // 不会执行
+ if (b) {
+ print("Example14 true, b is $b");
} else {
- // 不会执行
+ print("Example14 false, b is $b");
}
} catch (e) {
- print("Example14 null value causes an exception: '${e}'");
+ print("Example14 error, b is $b"); // 这段代码可以执行但是会报错
}
+ b = null;
+ if (b) {
+ print("Example14 true, b is $b");
+ } else {
+ print("Example14 false, b is $b"); // 这行到这里
+ }
+
+ // 静态类型的null不能转换成bool型
+ var c = "abc";
+ c = null;
+ // 编译出错
+ // if (c) {
+ // print("Example14 true, c is $c");
+ // } else {
+ // print("Example14 false, c is $c");
+ // }
}
// try/catch/finally 和 throw 语句用于异常处理。
@@ -492,8 +516,8 @@ main() {
Dart 有一个综合性网站。它涵盖了 API 参考、入门向导、文章以及更多,
还包括一个有用的在线试用 Dart 页面。
-http://www.dartlang.org/
-http://try.dartlang.org/
+* [https://www.dartlang.org](https://www.dartlang.org)
+* [https://try.dartlang.org](https://try.dartlang.org)
diff --git a/zh-cn/dynamic-programming-cn.html.markdown b/zh-cn/dynamic-programming-cn.html.markdown
new file mode 100644
index 00000000..b75c5404
--- /dev/null
+++ b/zh-cn/dynamic-programming-cn.html.markdown
@@ -0,0 +1,57 @@
+---
+category: Algorithms & Data Structures
+name: Dynamic Programming
+contributors:
+ - ["Akashdeep Goel", "http://github.com/akashdeepgoel"]
+filename: dynamic-programming-cn.html.markdown
+lang: zh-cn
+translators:
+ - ["EtaoinWu", "https://github.com/EtaoinWu"]
+---
+
+# 动态规划
+
+## 简介
+
+动态规划是一种实用的技巧,它可以用来解决一系列特定问题。它的思路很简单,如果你对某个给定的输入解决了一个问题,那么你可以保存已有信息,以避免重复计算,节约计算时间。
+
+记住,只有那些没有办法记住历史的才被迫做更多的苦力。(Fibonacci就是一个显然的例子)
+
+## 解决问题的方式
+
+1. *自顶向下* : 利用分支策略分解问题。如果你已经解决过当前子问题了,那么就返回已有信息。如果当前子问题没有计算过,那么就对它进行计算。这样的方法很易于思考、很直观。这被称作“记忆化”。
+
+2. *自底向上* : 首先分析问题,将问题分解为不同规模的问题,并决定它们的顺序,按顺序计算,直到解决给定规模的问题。这样的流程可以保证在解决较大的问题之前解决(它所依赖的)较小的问题。这种流程被称作“动态规划”。
+
+## 动态规划的例子
+
+最长上升子序列问题。给定`S= {a[1] , a[2] , a[3], a[4], ............., a[n-1], a[n] }`,求出一个子序列,使得对于所有在这个子序列中所有满足`j<i`的`j`与`i`,满足`aj<ai`。首先我们要讨论以原序列的第`i`个元素结尾的最长上升子序列`dp[i]`。那么答案是整个dp序列的最大值。考虑`dp[i]`,它的最后一个元素为`a[i]`。枚举它的倒数第二个元素`a[j]`,则`a[j]<a[i]`成立。则`dp[i]`就是所有这样的`dp[j]`的最大值加上1(最后一个元素)。这个算法具有*O(n^2)*的时间复杂度。
+
+此算法的伪代码:
+
+```python
+for i=0 to n-1
+ dp[i]=0
+ for j=0 to i-1
+ if (a[i] > a[j] and dp[i]<dp[j])
+ LS[i] = LS[j]
+ dp[i]=dp[i]+1
+for i=0 to n-1
+ if (largest < dp[i])
+ largest = dp[i]
+```
+
+这个算法的复杂度可以通过将数组换为其他数据结构来优化,来获得*O(n * log n)*的时间复杂度。
+
+同样的思路可以求出有向无环图上的最大路径。
+
+### 一些著名的动态规划问题及其实现
+
+- Floyd Warshall 算法 - [教程与C实现源码](http://www.thelearningpoint.net/computer-science/algorithms-all-to-all-shortest-paths-in-graphs---floyd-warshall-algorithm-with-c-program-source-code)
+- 整数背包问题 - [教程与C实现源码](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---the-integer-knapsack-problem)
+- 最长公共子序列问题 - [教程与C实现源码](http://www.thelearningpoint.net/computer-science/algorithms-dynamic-programming---longest-common-subsequence)
+
+## 在线资源
+
+* [codechef](https://www.codechef.com/wiki/tutorial-dynamic-programming)
+* [洛谷](https://www.luogu.org/problem/lists?name=&orderitem=pid&tag=3)
diff --git a/zh-cn/elisp-cn.html.markdown b/zh-cn/elisp-cn.html.markdown
index 06f38d77..3f6ccbcf 100644
--- a/zh-cn/elisp-cn.html.markdown
+++ b/zh-cn/elisp-cn.html.markdown
@@ -293,7 +293,7 @@ lang: zh-cn
(hello-to-bonjour)
-;; 给这些名字上个色:
+;; 给这些名字加粗:
(defun boldify-names ()
(switch-to-buffer-other-window "*test*")
@@ -340,5 +340,6 @@ lang: zh-cn
;; - Kevin Montuori
;; - Arne Babenhauserheide
;; - Alan Schmitt
+;; - spacegoing
```
diff --git a/zh-cn/fortran95-cn.html.markdown b/zh-cn/fortran95-cn.html.markdown
new file mode 100644
index 00000000..e28d309f
--- /dev/null
+++ b/zh-cn/fortran95-cn.html.markdown
@@ -0,0 +1,435 @@
+---
+language: Fortran
+filename: learnfortran-cn.f95
+contributors:
+ - ["Robert Steed", "https://github.com/robochat"]
+translators:
+ - ["Corvusnest", "https://github.com/Corvusnest"]
+lang: zh-cn
+---
+
+Fortran 是最古老的计算机语言之一。它由IBM开发于1950年用于数值运算(Fortran 为 "Formula
+Translation" 的缩写)。虽然该语言已年代久远,但目前仍用于高性能计算,如天气预报。
+该语言仍在持续发展,并且基本保持向下兼容。知名的版本为 Fortran 77, Fortran 90,
+Fortran 95, Fortran 2003, Fortran 2008 与 Fortran 2015。
+
+这篇概要将讨论 Fortran 95 的一些特征。因为它是目前所广泛采用的标准版本,并且与最新版本的内容
+也基本相同(而 Fortran 77 则是一个非常不同的版本)。
+
+```fortran
+
+! 这是一行注释
+
+
+program example !声明一个叫做 example 的程序
+
+ ! 代码只能放在程序、函数、子程序或者模块内部
+ ! 推荐使用缩进,但不是必须的。
+
+ ! 声明变量
+ ! ===================
+
+ ! 所有的声明必须放在语句与表达式之前
+
+ implicit none !阻止变量的隐式声明 (推荐!)
+ ! Implicit none 必须在每一个 函数/程序/模块 中进行声明
+
+ ! 重要 - Fortran 对大小写不敏感
+ real z
+ REAL Z2
+
+ real :: v,x ! 警告: 默认值取决于编译器!
+ real :: a = 3, b=2E12, c = 0.01
+ integer :: i, j, k=1, m
+ real, parameter :: PI = 3.1415926535897931 !声明一个常量
+ logical :: y = .TRUE. , n = .FALSE. !布尔值
+ complex :: w = (0,1) !sqrt(-1) (译注: 定义复数,此为-1的平方根)
+ character (len=3) :: month !长度为3的字符串
+
+ real :: array(6) !声明长度为6的浮点数数组
+ real, dimension(4) :: arrayb !声明数组的另一种方法
+ integer :: arrayc(-10:10) !有着自定义索引的数组
+ real :: array2d(3,2) !多维数组
+
+ ! 分隔符 '::' 并不总是必要的,但推荐使用
+
+ ! 还存在很多其他的变量特征:
+ real, pointer :: p !声明一个指针
+
+ integer, parameter :: LP = selected_real_kind(20)
+ real (kind = LP) :: d !长精度变量
+
+ ! 警告:在声明期间初始化变量将导致在函数内发生问题,因为这将自动具备了 “save” 属性,
+ ! 因此变量的值在函数的多次调用期间将被存储。一般来说,除了常量,应分开声明与初始化!
+
+ ! 字符串
+ ! =======
+
+ character :: a_char = 'i'
+ character (len = 6) :: a_str = "qwerty"
+ character (len = 30) :: str_b
+ character (len = *), parameter :: a_long_str = "This is a long string."
+ !可以通过使用 (len=*) 来自动判断长度,但只对常量有效
+
+ str_b = a_str // " keyboard" !通过 // 操作符来连接字符串
+
+
+ ! 任务与计算
+ ! =======================
+
+ Z = 1 !向之前声明的变量 z 赋值 (大小写不敏感).
+ j = 10 + 2 - 3
+ a = 11.54 / (2.3 * 3.1)
+ b = 2**3 !幂
+
+
+ ! 控制流程语句 与 操作符
+ ! ===================================
+
+ !单行 if 语句
+ if (z == a) b = 4 !判别句永远需要放在圆括号内
+
+ if (z /= a) then !z 不等于 a
+ ! 其他的比较运算符: < > <= >= == /=
+ b = 4
+ else if (z .GT. a) then !z 大于(Greater) a
+ ! 文本形式的比较运算符: .LT. .GT. .LE. .GE. .EQ. .NE.
+ b = 6
+ else if (z < a) then !'then' 必须放在该行
+ b = 5 !执行部分必须放在新的一行里
+ else
+ b = 10
+ end if !结束语句需要 'if' (也可以用 'endif').
+
+
+ if (.NOT. (x < c .AND. v >= a .OR. z == z)) then !布尔操作符
+ inner: if (.TRUE.) then !可以为 if 结构命名
+ b = 1
+ endif inner !接下来必须命名 endif 语句.
+ endif
+
+
+ i = 20
+ select case (i)
+ case (0) !当 i == 0
+ j=0
+ case (1:10) !当 i 为 1 到 10 之内 ( 1 <= i <= 10 )
+ j=1
+ case (11:) !当 i>=11
+ j=2
+ case default
+ j=3
+ end select
+
+
+ month = 'jan'
+ ! 状态值可以为整数、布尔值或者字符类型
+ ! Select 结构同样可以被命名
+ monthly: select case (month)
+ case ("jan")
+ j = 0
+ case default
+ j = -1
+ end select monthly
+
+ do i=2,10,2 !从2到10(包含2和10)以2为步进值循环
+ innerloop: do j=1,3 !循环同样可以被命名
+ exit !跳出循环
+ end do innerloop
+ cycle !重复跳入下一次循环
+ enddo
+
+
+ ! Goto 语句是存在的,但强烈不建议使用
+ goto 10
+ stop 1 !立即停止程序 (返回一个设定的状态码).
+10 j = 201 !这一行被标注为 10 行 (line 10)
+
+
+ ! 数组
+ ! ======
+ array = (/1,2,3,4,5,6/)
+ array = [1,2,3,4,5,6] !当使用 Fortran 2003 版本.
+ arrayb = [10.2,3e3,0.41,4e-5]
+ array2d = reshape([1.0,2.0,3.0,4.0,5.0,6.0], [3,2])
+
+ ! Fortran 数组索引起始于 1
+ ! (默认下如此,也可以为数组定义不同的索引起始)
+ v = array(1) !获取数组的第一个元素
+ v = array2d(2,2)
+
+ print *, array(3:5) !打印从第3到第五5之内的所有元素
+ print *, array2d(1,:) !打印2维数组的第一列
+
+ array = array*3 + 2 !可为数组设置数学表达式
+ array = array*array !数组操作支持元素级(操作) (element-wise)
+ !array = array*array2d !这两类数组并不是同一个维度的
+
+ ! 有很多内置的数组操作函数
+ c = dot_product(array,array) !点乘 (点积)
+ ! 用 matmul() 来进行矩阵运算.
+ c = sum(array)
+ c = maxval(array)
+ print *, minloc(array)
+ c = size(array)
+ print *, shape(array)
+ m = count(array > 0)
+
+ ! 遍历一个数组 (一般使用 Product() 函数).
+ v = 1
+ do i = 1, size(array)
+ v = v*array(i)
+ end do
+
+ ! 有条件地执行元素级操作
+ array = [1,2,3,4,5,6]
+ where (array > 3)
+ array = array + 1
+ elsewhere (array == 2)
+ array = 1
+ elsewhere
+ array = 0
+ end where
+
+ ! 隐式DO循环可以很方便地创建数组
+ array = [ (i, i = 1,6) ] !创建数组 [1,2,3,4,5,6]
+ array = [ (i, i = 1,12,2) ] !创建数组 [1,3,5,7,9,11]
+ array = [ (i**2, i = 1,6) ] !创建数组 [1,4,9,16,25,36]
+ array = [ (4,5, i = 1,3) ] !创建数组 [4,5,4,5,4,5]
+
+
+ ! 输入/输出
+ ! ============
+
+ print *, b !向命令行打印变量 'b'
+
+ ! 我们可以格式化输出
+ print "(I6)", 320 !打印 ' 320'
+ print "(I6.4)", 3 !打印 ' 0003'
+ print "(F6.3)", 4.32 !打印 ' 4.320'
+
+
+ ! 该字母与数值规定了给定的数值与字符所用于打印输出的类型与格式
+ ! 字母可为 I (整数), F (浮点数), E (工程格式),
+ ! L (逻辑/布尔值), A (字符) ...
+ print "(I3)", 3200 !如果数值无法符合格式将打印 '***'
+
+ ! 可以同时设定多种格式
+ print "(I5,F6.2,E6.2)", 120, 43.41, 43.41
+ print "(3I5)", 10, 20, 30 !连续打印3个整数 (字段宽度 = 5).
+ print "(2(I5,F6.2))", 120, 43.42, 340, 65.3 !连续分组格式
+
+ ! 我们也可以从终端读取输入
+ read *, v
+ read "(2F6.2)", v, x !读取2个数值
+
+ ! 读取文件
+ open(unit=11, file="records.txt", status="old")
+ ! 文件被引用带有一个单位数 'unit', 为一个取值范围在9-99的整数
+ ! 'status' 可以为 {'old','replace','new'} 其中之一
+ read(unit=11, fmt="(3F10.2)") a, b, c
+ close(11)
+
+ ! 写入一个文件
+ open(unit=12, file="records.txt", status="replace")
+ write(12, "(F10.2,F10.2,F10.2)") c, b, a
+ close(12)
+ ! 在讨论范围之外的还有更多的细节与可用功能,并于老版本的 Fortran 保持兼容
+
+
+ ! 内置函数
+ ! ==================
+
+ ! Fortran 拥有大约 200 个内置函数/子程序
+ ! 例子
+ call cpu_time(v) !以秒为单位设置时间
+ k = ior(i,j) !2个整数的位或运算
+ v = log10(x) !以10为底的log运算
+ i = floor(b) !返回一个最接近的整数小于或等于x (地板数)
+ v = aimag(w) !复数的虚数部分
+
+
+ ! 函数与子程序
+ ! =======================
+
+ ! 一个子程序会根据输入值运行一些代码并会导致副作用 (side-effects) 或修改输入值
+ ! (译者注: 副作用是指对子程序/函数外的环境产生影响,如修改变量)
+
+ call routine(a,c,v) !调用子程序
+
+ ! 一个函数会根据输入的一系列数值来返回一个单独的值
+ ! 但输入值仍然可能被修改以及产生副作用
+
+ m = func(3,2,k) !调用函数
+
+ ! 函数可以在表达式内被调用
+ Print *, func2(3,2,k)
+
+ ! 一个纯函数不会去修改输入值或产生副作用
+ m = func3(3,2,k)
+
+
+contains ! 用于定义程序内部的副程序(sub-programs)的区域
+
+ ! Fortran 拥有一些不同的方法去定义函数
+
+ integer function func(a,b,c) !一个返回一个整数的函数
+ implicit none !最好也在函数内将含蓄模式关闭 (implicit none)
+ integer :: a,b,c !输入值类型定义在函数内部
+ if (a >= 2) then
+ func = a + b + c !返回值默认为函数名
+ return !可以在函数内任意时间返回当前值
+ endif
+ func = a + c
+ ! 在函数的结尾不需要返回语句
+ end function func
+
+
+ function func2(a,b,c) result(f) !将返回值声明为 'f'
+ implicit none
+ integer, intent(in) :: a,b !可以声明让变量无法被函数修改
+ integer, intent(inout) :: c
+ integer :: f !函数的返回值类型在函数内声明
+ integer :: cnt = 0 !注意 - 隐式的初始化变量将在函数的多次调用间被存储
+ f = a + b - c
+ c = 4 !变动一个输入变量的值
+ cnt = cnt + 1 !记录函数的被调用次数
+ end function func2
+
+
+ pure function func3(a,b,c) !一个没有副作用的纯函数
+ implicit none
+ integer, intent(in) :: a,b,c
+ integer :: func3
+ func3 = a*b*c
+ end function func3
+
+
+ subroutine routine(d,e,f)
+ implicit none
+ real, intent(inout) :: f
+ real, intent(in) :: d,e
+ f = 2*d + 3*e + f
+ end subroutine routine
+
+
+end program example ! 函数定义完毕 -----------------------
+
+! 函数与子程序的外部声明对于生成程序清单来说,需要一个接口声明(即使它们在同一个源文件内)(见下)
+! 使用 'contains' 可以很容易地在模块或程序内定义它们
+
+elemental real function func4(a) result(res)
+! 一个元函数(elemental function) 为一个纯函数使用一个标量输入值
+! 但同时也可以用在一个数组并对其中的元素分别处理,之后返回一个新的数组
+ real, intent(in) :: a
+ res = a**2 + 1.0
+end function func4
+
+
+! 模块
+! =======
+
+! 模块十分适合于存放与复用相关联的一组声明、函数与子程序
+
+module fruit
+ real :: apple
+ real :: pear
+ real :: orange
+end module fruit
+
+
+module fruity
+
+ ! 声明必须按照顺序: 模块、接口、变量
+ ! (同样可在程序内声明模块和接口)
+
+ use fruit, only: apple, pear ! 使用来自于 fruit 模块的 apple 和 pear
+ implicit none !在模块导入后声明
+
+ private !使得模块内容为私有(private)(默认为公共 public)
+ ! 显式声明一些变量/函数为公共
+ public :: apple,mycar,create_mycar
+ ! 声明一些变量/函数为私有(在当前情况下没必要)(译注: 因为前面声明了模块全局 private)
+ private :: func4
+
+ ! 接口
+ ! ==========
+ ! 在模块内显式声明一个外部函数/程序
+ ! 一般最好将函数/程序放进 'contains' 部分内
+ interface
+ elemental real function func4(a) result(res)
+ real, intent(in) :: a
+ end function func4
+ end interface
+
+ ! 重载函数可以通过已命名的接口来定义
+ interface myabs
+ ! 可以通过使用 'module procedure' 关键词来包含一个已在模块内定义的函数
+ module procedure real_abs, complex_abs
+ end interface
+
+ ! 派生数据类型
+ ! ==================
+ ! 可创建自定义数据结构
+ type car
+ character (len=100) :: model
+ real :: weight !(公斤 kg)
+ real :: dimensions(3) !例: 长宽高(米)
+ character :: colour
+ end type car
+
+ type(car) :: mycar !声明一个自定义类型的变量
+ ! 用法具体查看 create_mycar()
+
+ ! 注: 模块内没有可执行的语句
+
+contains
+
+ subroutine create_mycar(mycar)
+ ! 展示派生数据类型的使用
+ implicit none
+ type(car),intent(out) :: mycar
+
+ ! 通过 '%' 操作符来访问(派生数据)类型的元素
+ mycar%model = "Ford Prefect"
+ mycar%colour = 'r'
+ mycar%weight = 1400
+ mycar%dimensions(1) = 5.0 !索引默认起始值为 1 !
+ mycar%dimensions(2) = 3.0
+ mycar%dimensions(3) = 1.5
+
+ end subroutine
+
+ real function real_abs(x)
+ real :: x
+ if (x<0) then
+ real_abs = -x
+ else
+ real_abs = x
+ end if
+ end function real_abs
+
+ real function complex_abs(z)
+ complex :: z
+ ! 过长的一行代码可通过延续符 '&' 来换行
+ complex_abs = sqrt(real(z)**2 + &
+ aimag(z)**2)
+ end function complex_abs
+
+
+end module fruity
+
+```
+
+### 更多资源
+
+了解更多的 Fortran 信息:
+
++ [wikipedia](https://en.wikipedia.org/wiki/Fortran)
++ [Fortran_95_language_features](https://en.wikipedia.org/wiki/Fortran_95_language_features)
++ [fortranwiki.org](http://fortranwiki.org)
++ [www.fortran90.org/](http://www.fortran90.org)
++ [list of Fortran 95 tutorials](http://www.dmoz.org/Computers/Programming/Languages/Fortran/FAQs%2C_Help%2C_and_Tutorials/Fortran_90_and_95/)
++ [Fortran wikibook](https://en.wikibooks.org/wiki/Fortran)
++ [Fortran resources](http://www.fortranplus.co.uk/resources/fortran_resources.pdf)
++ [Mistakes in Fortran 90 Programs That Might Surprise You](http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html)
diff --git a/zh-cn/git-cn.html.markdown b/zh-cn/git-cn.html.markdown
index 4ef3ffb8..63d740a1 100644
--- a/zh-cn/git-cn.html.markdown
+++ b/zh-cn/git-cn.html.markdown
@@ -131,7 +131,7 @@ $ git help init
```bash
-# 显示分支,为跟踪文件,更改和其他不同
+# 显示分支,未跟踪文件,更改和其他不同
$ git status
# 查看其他的git status的用法
@@ -234,7 +234,7 @@ $ git diff HEAD
# 在搜索结果中显示行号
$ git config --global grep.lineNumber true
-# 是搜索结果可读性更好
+# 使得搜索结果可读性更好
$ git config --global alias.g "grep --break --heading --line-number"
```
diff --git a/zh-cn/go-cn.html.markdown b/zh-cn/go-cn.html.markdown
index fa4540a2..2953acf3 100644
--- a/zh-cn/go-cn.html.markdown
+++ b/zh-cn/go-cn.html.markdown
@@ -6,7 +6,8 @@ contributors:
- ["Sonia Keys", "https://github.com/soniakeys"]
- ["pantaovay", "https://github.com/pantaovay"]
- ["lidashuang", "https://github.com/lidashuang"]
-
+ - ["Tim Zhang", "https://github.com/ttimasdf"]
+
---
发明Go语言是出于更好地完成工作的需要。Go不是计算机科学的最新发展潮流,但它却提供了解决现实问题的最新最快的方法。
@@ -27,7 +28,10 @@ package main
// Import语句声明了当前文件引用的包。
import (
"fmt" // Go语言标准库中的包
+ "io/ioutil" // 包含一些输入输出函数
+ m "math" // 数学标准库,在此文件中别名为m
"net/http" // 一个web服务器包
+ "os" // 系统底层函数,如文件读写
"strconv" // 字符串转换
)
@@ -36,7 +40,7 @@ import (
func main() {
// 往标准输出打印一行。
// 用包名fmt限制打印函数。
- fmt.Println("Hello world!")
+ fmt.Println("你好世界")
// 调用当前包的另一个函数。
beyondHello()
@@ -54,7 +58,11 @@ func beyondHello() {
learnTypes() // 少于y分钟,学的更多!
}
-// 多变量和多返回值的函数
+/* <- 快看快看我是跨行注释_(:з」∠)_
+Go语言的函数可以有多个参数和 *多个* 返回值。
+在这个函数中, `x`、`y` 是参数,
+`sum`、`prod` 是返回值的标识符(可以理解为名字)且类型为int
+*/
func learnMultiple(x, y int) (sum, prod int) {
return x + y, x * y // 返回两个值
}
@@ -62,11 +70,11 @@ func learnMultiple(x, y int) (sum, prod int) {
// 内置变量类型和关键词
func learnTypes() {
// 短声明给你所想。
- s := "Learn Go!" // String类型
+ str := "少说话多读书!" // String类型
+
+ s2 := `这是一个
+可以换行的字符串` // 同样是String类型
- s2 := `A "raw" string literal
-can include line breaks.` // 同样是String类型
-
// 非ascii字符。Go使用UTF-8编码。
g := 'Σ' // rune类型,int32的别名,使用UTF-8编码
@@ -80,16 +88,29 @@ can include line breaks.` // 同样是String类型
// 字符转换
n := byte('\n') // byte是uint8的别名
- // 数组类型编译的时候大小固定。
+ // 数组(Array)类型的大小在编译时即确定
var a4 [4] int // 有4个int变量的数组,初始为0
a3 := [...]int{3, 1, 5} // 有3个int变量的数组,同时进行了初始化
- // Slice 可以动态的增删。Array和Slice各有千秋,但是使用slice的地方更多些。
- s3 := []int{4, 5, 9} // 和a3相比,这里没有省略号
- s4 := make([]int, 4) // 分配一个有4个int型变量的slice,全部被初始化为0
-
- var d2 [][]float64 // 声明而已,什么都没有分配
- bs := []byte("a slice") // 类型转换的语法
+ // Array和slice各有所长,但是slice可以动态的增删,所以更多时候还是使用slice。
+ s3 := []int{4, 5, 9} // 回去看看 a3 ,是不是这里没有省略号?
+ s4 := make([]int, 4) // 分配4个int大小的内存并初始化为0
+ var d2 [][]float64 // 这里只是声明,并未分配内存空间
+ bs := []byte("a slice") // 进行类型转换
+
+ // 切片(Slice)的大小是动态的,它的长度可以按需增长
+ // 用内置函数 append() 向切片末尾添加元素
+ // 要增添到的目标是 append 函数第一个参数,
+ // 多数时候数组在原内存处顺次增长,如
+ s := []int{1, 2, 3} // 这是个长度3的slice
+ s = append(s, 4, 5, 6) // 再加仨元素,长度变为6了
+ fmt.Println(s) // 更新后的数组是 [1 2 3 4 5 6]
+
+ // 除了向append()提供一组原子元素(写死在代码里的)以外,我们
+ // 还可以用如下方法传递一个slice常量或变量,并在后面加上省略号,
+ // 用以表示我们将引用一个slice、解包其中的元素并将其添加到s数组末尾。
+ s = append(s, []int{7, 8, 9}...) // 第二个参数是一个slice常量
+ fmt.Println(s) // 更新后的数组是 [1 2 3 4 5 6 7 8 9]
p, q := learnMemory() // 声明p,q为int型变量的指针
fmt.Println(*p, *q) // * 取值
@@ -100,11 +121,27 @@ can include line breaks.` // 同样是String类型
// 在Go语言中未使用的变量在编译的时候会报错,而不是warning。
// 下划线 _ 可以使你“使用”一个变量,但是丢弃它的值。
- _,_,_,_,_,_,_,_,_ = s2, g, f, u, pi, n, a3, s4, bs
+ _, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs
+ // 通常的用法是,在调用拥有多个返回值的函数时,
+ // 用下划线抛弃其中的一个参数。下面的例子就是一个脏套路,
+ // 调用os.Create并用下划线变量扔掉它的错误代码。
+ // 因为我们觉得这个文件一定会成功创建。
+ file, _ := os.Create("output.txt")
+ fmt.Fprint(file, "这句代码还示范了如何写入文件呢")
+ file.Close()
+
// 输出变量
fmt.Println(s, c, a4, s3, d2, m)
- learnFlowControl() // 回到流程控制
+ learnFlowControl() // 回到流程控制
+}
+
+// 和其他编程语言不同的是,go支持有名称的变量返回值。
+// 声明返回值时带上一个名字允许我们在函数内的不同位置
+// 只用写return一个词就能将函数内指定名称的变量返回
+func learnNamedReturns(x, y int) (z int) {
+ z = x * y
+ return // z is implicit here, because we named it earlier.
}
// Go全面支持垃圾回收。Go有指针,但是不支持指针运算。
@@ -126,7 +163,7 @@ func expensiveComputation() int {
func learnFlowControl() {
// If需要花括号,括号就免了
if true {
- fmt.Println("told ya")
+ fmt.Println("这句话肯定被执行")
}
// 用go fmt 命令可以帮你格式化代码,所以不用怕被人吐槽代码风格了,
// 也不用容忍别人的代码风格。
@@ -146,15 +183,28 @@ func learnFlowControl() {
}
// 和if一样,for也不用括号
for x := 0; x < 3; x++ { // ++ 自增
- fmt.Println("iteration", x)
+ fmt.Println("遍历", x)
}
// x在这里还是1。为什么?
// for 是go里唯一的循环关键字,不过它有很多变种
for { // 死循环
- break // 骗你的
+ break // 骗你的
continue // 不会运行的
}
+
+ // 用range可以枚举 array、slice、string、map、channel等不同类型
+ // 对于channel,range返回一个值,
+ // array、slice、string、map等其他类型返回一对儿
+ for key, value := range map[string]int{"one": 1, "two": 2, "three": 3} {
+ // 打印map中的每一个键值对
+ fmt.Printf("索引:%s, 值为:%d\n", key, value)
+ }
+ // 如果你只想要值,那就用前面讲的下划线扔掉没用的
+ for _, name := range []string{"Bob", "Bill", "Joe"} {
+ fmt.Printf("你是。。 %s\n", name)
+ }
+
// 和for一样,if中的:=先给y赋值,然后再和x作比较。
if y := expensiveComputation(); y > x {
x = y
@@ -163,17 +213,55 @@ func learnFlowControl() {
xBig := func() bool {
return x > 100 // x是上面声明的变量引用
}
- fmt.Println("xBig:", xBig()) // true (上面把y赋给x了)
+ fmt.Println("xBig:", xBig()) // true (上面把y赋给x了)
x /= 1e5 // x变成10
fmt.Println("xBig:", xBig()) // 现在是false
+ // 除此之外,函数体可以在其他函数中定义并调用,
+ // 满足下列条件时,也可以作为参数传递给其他函数:
+ // a) 定义的函数被立即调用
+ // b) 函数返回值符合调用者对类型的要求
+ fmt.Println("两数相加乘二: ",
+ func(a, b int) int {
+ return (a + b) * 2
+ }(10, 2)) // Called with args 10 and 2
+ // => Add + double two numbers: 24
+
// 当你需要goto的时候,你会爱死它的!
goto love
love:
+ learnFunctionFactory() // 返回函数的函数多棒啊
+ learnDefer() // 对defer关键字的简单介绍
learnInterfaces() // 好东西来了!
}
+func learnFunctionFactory() {
+ // 空行分割的两个写法是相同的,不过第二个写法比较实用
+ fmt.Println(sentenceFactory("原谅")("当然选择", "她!"))
+
+ d := sentenceFactory("原谅")
+ fmt.Println(d("当然选择", "她!"))
+ fmt.Println(d("你怎么可以", "她?"))
+}
+
+// Decorator在一些语言中很常见,在go语言中,
+// 接受参数作为其定义的一部分的函数是修饰符的替代品
+func sentenceFactory(mystring string) func(before, after string) string {
+ return func(before, after string) string {
+ return fmt.Sprintf("%s %s %s", before, mystring, after) // new string
+ }
+}
+
+func learnDefer() (ok bool) {
+ // defer表达式在函数返回的前一刻执行
+ defer fmt.Println("defer表达式执行顺序为后进先出(LIFO)")
+ defer fmt.Println("\n这句话比上句话先输出,因为")
+ // 关于defer的用法,例如用defer关闭一个文件,
+ // 就可以让关闭操作与打开操作的代码更近一些
+ return true
+}
+
// 定义Stringer为一个接口类型,有一个方法String
type Stringer interface {
String() string
@@ -194,9 +282,9 @@ func (p pair) String() string { // p被叫做“接收器”
func learnInterfaces() {
// 花括号用来定义结构体变量,:=在这里将一个结构体变量赋值给p。
p := pair{3, 4}
- fmt.Println(p.String()) // 调用pair类型p的String方法
- var i Stringer // 声明i为Stringer接口类型
- i = p // 有效!因为p实现了Stringer接口(类似java中的塑型)
+ fmt.Println(p.String()) // 调用pair类型p的String方法
+ var i Stringer // 声明i为Stringer接口类型
+ i = p // 有效!因为p实现了Stringer接口(类似java中的塑型)
// 调用i的String方法,输出和上面一样
fmt.Println(i.String())
@@ -205,14 +293,28 @@ func learnInterfaces() {
fmt.Println(p) // 输出和上面一样,自动调用String函数。
fmt.Println(i) // 输出和上面一样。
+ learnVariadicParams("great", "learning", "here!")
+}
+
+// 有变长参数列表的函数
+func learnVariadicParams(myStrings ...interface{}) {
+ // 枚举变长参数列表的每个参数值
+ // 下划线在这里用来抛弃枚举时返回的数组索引值
+ for _, param := range myStrings {
+ fmt.Println("param:", param)
+ }
+
+ // 将可变参数列表作为其他函数的参数列表
+ fmt.Println("params:", fmt.Sprintln(myStrings...))
+
learnErrorHandling()
}
func learnErrorHandling() {
- // ", ok"用来判断有没有正常工作
+ // ", ok"用来判断有没有正常工作
m := map[int]string{3: "three", 4: "four"}
if x, ok := m[1]; !ok { // ok 为false,因为m中没有1
- fmt.Println("no one there")
+ fmt.Println("别找了真没有")
} else {
fmt.Print(x) // 如果x在map中的话,x就是那个值喽。
}
@@ -245,17 +347,17 @@ func learnConcurrency() {
cs := make(chan string) // 操作string的channel
cc := make(chan chan string) // 操作channel的channel
- go func() { c <- 84 }() // 开始一个goroutine来发送一个新的数字
+ go func() { c <- 84 }() // 开始一个goroutine来发送一个新的数字
go func() { cs <- "wordy" }() // 发送给cs
// Select类似于switch,但是每个case包括一个channel操作。
// 它随机选择一个准备好通讯的case。
select {
case i := <-c: // 从channel接收的值可以赋给其他变量
- fmt.Println("it's a", i)
+ fmt.Println("这是……", i)
case <-cs: // 或者直接丢弃
- fmt.Println("it's a string")
- case <-cc: // 空的,还没作好通讯的准备
- fmt.Println("didn't happen.")
+ fmt.Println("这是个字符串!")
+ case <-cc: // 空的,还没作好通讯的准备
+ fmt.Println("别瞎想")
}
// 上面c或者cs的值被取到,其中一个goroutine结束,另外一个一直阻塞。
@@ -265,22 +367,43 @@ func learnConcurrency() {
// http包中的一个简单的函数就可以开启web服务器。
func learnWebProgramming() {
// ListenAndServe第一个参数指定了监听端口,第二个参数是一个接口,特定是http.Handler。
- err := http.ListenAndServe(":8080", pair{})
- fmt.Println(err) // 不要无视错误。
+ go func() {
+ err := http.ListenAndServe(":8080", pair{})
+ fmt.Println(err) // 不要无视错误。
+ }()
+
+ requestServer()
}
// 使pair实现http.Handler接口的ServeHTTP方法。
func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// 使用http.ResponseWriter返回数据
- w.Write([]byte("You learned Go in Y minutes!"))
+ w.Write([]byte("Y分钟golang速成!"))
+}
+
+func requestServer() {
+ resp, err := http.Get("http://localhost:8080")
+ fmt.Println(err)
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ fmt.Printf("\n服务器消息: `%s`", string(body))
}
```
## 更进一步
-Go的根源在[Go官方网站](http://golang.org/)。
-在那里你可以学习入门教程,通过浏览器交互式地学习,而且可以读到很多东西。
+关于Go的一切你都可以在[Go官方网站](http://golang.org/)找到。
+在那里你可以获得教程参考,在线试用,和更多的资料。
+在简单的尝试过后,在[官方文档](https://golang.org/doc/)那里你会得到你所需要的所有资料、关于编写代码的规范、库和命令行工具的文档与Go的版本历史。
+
+强烈推荐阅读语言定义部分,很简单而且很简洁!(赶时髦!)
-强烈推荐阅读语言定义部分,很简单而且很简洁!(as language definitions go these days.)
+你还可以前往[Go在线体验中心](https://play.golang.org/p/tnWMjr16Mm)进,在浏览器里修改并运行这些代码,一定要试一试哦!你可以将[https://play.golang.org](https://play.golang.org)当作一个[REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop),在那里体验语言特性或运行自己的代码,连环境都不用配!
学习Go还要阅读Go[标准库的源代码](http://golang.org/src/),全部文档化了,可读性非常好,可以学到go,go style和go idioms。在[文档](http://golang.org/pkg/)中点击函数名,源代码就出来了!
+
+[Go by example](https://gobyexample.com/)也是一个学习的好地方。
+
+
+
+Go Mobile添加了对移动平台的支持(Android and iOS)。你可以完全用go语言来创造一个app或编写一个可以从Java或Obj-C调用的函数库,敬请参考[Go Mobile page](https://github.com/golang/go/wiki/Mobile)。
diff --git a/zh-cn/groovy-cn.html.markdown b/zh-cn/groovy-cn.html.markdown
index 562a0284..0e7a020c 100644
--- a/zh-cn/groovy-cn.html.markdown
+++ b/zh-cn/groovy-cn.html.markdown
@@ -219,10 +219,12 @@ for (i in array) {
//遍历映射
def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy']
-x = 0
+x = ""
for ( e in map ) {
x += e.value
+ x += " "
}
+assert x.equals("Roberto Grails Groovy ")
/*
运算符
diff --git a/zh-cn/haskell-cn.html.markdown b/zh-cn/haskell-cn.html.markdown
index b0b1183f..d653c58c 100644
--- a/zh-cn/haskell-cn.html.markdown
+++ b/zh-cn/haskell-cn.html.markdown
@@ -66,7 +66,7 @@ not False -- True
----------------------------------------------------
--- 列表和元组
+-- 2. 列表和元组
----------------------------------------------------
-- 一个列表中的每一个元素都必须是相同的类型。
@@ -128,7 +128,7 @@ snd ("haskell", 1) -- 1
-- 一个接受两个变量的简单函数
add a b = a + b
--- 注意,如果你使用 ghci (Hakell 解释器),你需要使用 `let`,也就是
+-- 注意,如果你使用 ghci (Haskell 解释器),你需要使用 `let`,也就是
-- let add a b = a + b
-- 调用函数
diff --git a/zh-cn/html-cn.html.markdown b/zh-cn/html-cn.html.markdown
new file mode 100644
index 00000000..6f60d5ce
--- /dev/null
+++ b/zh-cn/html-cn.html.markdown
@@ -0,0 +1,121 @@
+---
+language: html
+filename: learnhtml-cn.html
+contributors:
+ - ["Christophe THOMAS", "https://github.com/WinChris"]
+translators:
+ - ["zxyqwe", "https://github.com/zxyqwe"]
+lang: zh-cn
+---
+
+HTML是超文本标记语言的缩写。
+这门语言可以让我们为万维网创造页面。
+这是一门标记语言,它允许我们用代码来指示网页上文字和数据应该如何显示。
+实际上html文件是简单的文本文件。
+什么是标记?标记是通过使用开始和结束标签包围数据的方法,来组织管理页面上的数据。
+这些标记对它们环绕的文本有重要的意义。
+和其它计算机语言意义,HTML有很多版本。这里我们将讨论HTML5。
+
+**注意:** 你可以在类似[codepen](http://codepen.io/pen/)的网站上的教程中,尝试不同的标签和元素带来的效果,理解它们如何起效,并且逐渐熟悉这门语言。
+本文主要关注HTML的语法和一些有用的小窍门。
+
+
+```html
+<!-- 注释要像本行一样被包围起来! -->
+
+<!-- #################### 标签 #################### -->
+
+<!-- 下面是一个我们将要分析的HTML文件的例子。 -->
+
+<!doctype html>
+ <html>
+ <head>
+ <title>我的网站</title>
+ </head>
+ <body>
+ <h1>Hello, world!</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>标签关闭)。 -->
+<!-- 头部包含一些不显示的描述和额外信息;这些是元数据。 -->
+
+<head>
+ <title>我的网站</title><!-- <title>标签告诉浏览器在浏览器窗口的标题区和标签栏应该显示什么标题。 -->
+</head>
+
+<!-- 在<head>区域之后,我们可以看到<body>标签 -->
+<!-- 在这点之前的内容都不会显示在浏览器的窗口中。 -->
+<!-- 我们必须在正文区填上需要显示的内容。 -->
+
+<body>
+ <h1>Hello, world!</h1> <!-- h1标签创建了一个标题 -->
+ <!-- <h1>标签可以有一些副标题,从最重要的(h2)到最细微的(h6)。 -->
+ <a href = "http://codepen.io/anon/pen/xwjLbZ">来看看这里有什么</a> <!-- 一个指向href=""属性中URL的超链接 -->
+ <p>这是一个段落。</p> <!-- <p>标签让我们在html页面中显示文字 -->
+ <p>这是另外一个段落。</p>
+ <ul> <!-- <ul>标签创建了一个项目符合列表。 -->
+ <!-- 如果需要一个编号列表,我们可以使用<ol>标签。这样会在在第一项前显示1.,第二项前显示2.,以此类推。 -->
+ <li>这是一个非计数列表的一项(项目符合列表)</li>
+ <li>这是另一项</li>
+ <li>这是列表中的最后一项</li>
+ </ul>
+</body>
+
+<!-- 好了,创建一个HTML文件就是这么简单。 -->
+
+<!-- 当然我们还可以加入很多额外的HTML标签类型。 -->
+
+<!-- 插入图片。 -->
+<img src="http://i.imgur.com/XWG0O.gif"/> <!-- 图片源是由src=""属性指明的 -->
+<!-- 图片源可以是一个URL或者你电脑上一个文件的路径。 -->
+
+<!-- 创建表格也没问题。 -->
+
+<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`后缀。
+
+## 扩展阅读
+
+* [维基百科](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/zh-cn/java-cn.html.markdown b/zh-cn/java-cn.html.markdown
index 1e9c38f6..27003f3e 100644
--- a/zh-cn/java-cn.html.markdown
+++ b/zh-cn/java-cn.html.markdown
@@ -108,7 +108,7 @@ public class LearnJava {
boolean [] booleanArray = new boolean[100];
// 声明并初始化数组也可以这样:
- int [] y = {9000, 1000, 1337};
+ int [] intArray = {9000, 1000, 1337};
// 随机访问数组中的元素
System.out.println("intArray @ 0: " + intArray[0]);
@@ -309,7 +309,7 @@ class Bicycle {
name = "Bontrager";
}
- // 一下是一个含有参数的构造函数
+ // 以下是一个含有参数的构造函数
public Bicycle(int startCadence, int startSpeed, int startGear, String name) {
this.gear = startGear;
this.cadence = startCadence;
diff --git a/zh-cn/javascript-cn.html.markdown b/zh-cn/javascript-cn.html.markdown
index bdef0099..45e30932 100644
--- a/zh-cn/javascript-cn.html.markdown
+++ b/zh-cn/javascript-cn.html.markdown
@@ -4,7 +4,7 @@ category: language
name: javascript
filename: javascript-zh.js
contributors:
- - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Leigh Brenecki", "https://leigh.net.au"]
- ["Ariel Krakowski", "http://www.learneroo.com"]
translators:
- ["Chenbo Li", "http://binarythink.net"]
@@ -12,16 +12,13 @@ translators:
lang: zh-cn
---
-Javascript于1995年由网景公司的Brendan Eich发明。
-最初发明的目的是作为一个简单的网站脚本语言,来作为
-复杂网站应用java的补充。但由于它与网页结合度很高并且由浏览器内置支持,
-所以javascript变得比java在前端更为流行了。
+Javascript 于 1995 年由网景公司的 Brendan Eich 发明。最初它作为一种简单的,用于开发网站的脚本语言而被发明出来,是用于开发复杂网站的 Java 的补充。但由于它与网页结合度很高并且在浏览器中得到内置的支持,所以在网页前端领域 Javascript 变得比 Java 更流行了。
-不过 JavaScript 可不仅仅只用于浏览器: Node.js,一个基于Google Chrome V8引擎的独立运行时环境,也越来越流行。
+不过,Javascript 不仅用于网页浏览器,一个名为 Node.js 的项目提供了面向 Google Chrome V8 引擎的独立运行时环境,它正在变得越来越流行。
很欢迎来自您的反馈,您可以通过下列方式联系到我:
-[@adambrenecki](https://twitter.com/adambrenecki), 或者
-[adam@brenecki.id.au](mailto:adam@brenecki.id.au).
+[@ExcitedLeigh](https://twitter.com/ExcitedLeigh), 或者
+[l@leigh.net.au](mailto:l@leigh.net.au).
```js
// 注释方式和C很像,这是单行注释
diff --git a/zh-cn/jquery-cn.html.markdown b/zh-cn/jquery-cn.html.markdown
new file mode 100644
index 00000000..4b23274e
--- /dev/null
+++ b/zh-cn/jquery-cn.html.markdown
@@ -0,0 +1,131 @@
+---
+category: tool
+tool: jquery
+contributors:
+ - ["Sawyer Charles", "https://github.com/xssc"]
+translators:
+ - ["zxyqwe", "https://github.com/zxyqwe"]
+lang: zh-cn
+filename: jquery-cn.js
+---
+
+jQuery是JavaScript的一个函数库,它可以帮你“写更少,做更多”。它集成了很多常见的JavaScript任务并且很容易调用。jQuery被世界各地的很多的大公司和开发者使用。它包括了AJAX,事件处理,文档操作以及很多其它功能,并且更加简单和快速。
+
+正因为jQuery是JavaScript的一个函数库,所以你需要[首先学习JavaScript](https://learnxinyminutes.com/docs/javascript/)
+
+```js
+
+
+///////////////////////////////////
+// 1. 选择器
+
+// jQuery中的选择器被用来选择一个元素
+var page = $(window); // 选择整个视窗
+
+// 选择器可以作为CSS选择器使用
+var paragraph = $('p'); // 选择所有段落元素
+var table1 = $('#table1'); // 选择id为table1的元素
+var squares = $('.square'); // 选择所有类是square的元素
+var square_p = $('p.square') // 选择具有square类的所有段落
+
+
+///////////////////////////////////
+// 2. 事件和效果
+// jQuery非常善于处理当事件触发的时候应该做什么
+// 一个非常常见的事件就是文档的就绪事件
+// 你可以用ready方法,在所有元素完成加载的时候执行
+$(document).ready(function(){
+ // 只有文档加载完成以后代码才会执行
+});
+// 你也可以用定义了的函数
+function onAction() {
+ // 本函数在事件触发的时候被执行
+}
+$('#btn').click(onAction); // 当点击的时候调用onAction函数
+
+// 其它常见的事件:
+$('#btn').dblclick(onAction); // 双击
+$('#btn').hover(onAction); // 划过
+$('#btn').focus(onAction); // 聚焦
+$('#btn').blur(onAction); // 失焦
+$('#btn').submit(onAction); // 提交
+$('#btn').select(onAction); // 当元素被选中
+$('#btn').keydown(onAction); // 当一个按键被按下
+$('#btn').keyup(onAction); // 当一个按键被抬起
+$('#btn').keypress(onAction); // 当一个按键被按住
+$('#btn').mousemove(onAction); // 当鼠标在移动
+$('#btn').mouseenter(onAction); // 鼠标移入元素
+$('#btn').mouseleave(onAction); // 鼠标离开元素
+
+
+// 如果不提供任何参数的话,那么这些方法可以触发事件
+// 而不是定义处理事件的方法
+$('#btn').dblclick(); // 触发元素上的双击
+
+// 你可以只用选择器一次而处理多个事件
+$('#btn').on(
+ {dblclick: myFunction1} // 双击的时候触发
+ {blur: myFunction1} // 失焦的时候触发
+);
+
+// 你可以用一些效果函数来移动或隐藏元素
+$('.table').hide(); // 隐藏元素
+
+// 注意:在这些方法中调用函数会仍然隐藏元素
+$('.table').hide(function(){
+ // 元素先隐藏然后函数被执行
+});
+
+// 你可以在变量中储存选择器
+var tables = $('.table');
+
+// 一些基本的文档操作方法有:
+tables.hide(); // 隐藏元素
+tables.show(); // 显示元素
+tables.toggle(); // 对被选元素进行隐藏和显示的切换
+tables.fadeOut(); // 淡出
+tables.fadeIn(); // 淡入
+tables.fadeToggle(); // 对被选元素进行淡入和淡出显示的切换
+tables.fadeTo(0.5); // 把被选元素逐渐改变至给定的不透明度(0和1之间)
+tables.slideUp(); // 通过调整高度来滑动隐藏被选元素
+tables.slideDown(); // 对被选元素进行滑动隐藏和滑动显示的切换
+tables.slideToggle(); // 对被选元素进行滑动隐藏和滑动显示的切换
+
+// 上面所有的方法接受速度参数(毫秒)和一个回调函数
+tables.hide(1000, myFunction); // 持续一秒的隐藏动画然后执行函数
+
+// fadeTo要求提供透明度参数作为第二个参数
+tables.fadeTo(2000, 0.1, myFunction); // 通过2秒钟将透明度变为0.1然后执行函数
+
+// 你可以用animate方法实现一些略微高级的效果
+tables.animate({margin-top:"+=50", height: "100px"}, 500, myFunction);
+// animate方法接受一个包含CSS和值的对象作为目标,
+// 其次是可选的速度参数,
+// 以及最后的回调函数
+
+///////////////////////////////////
+// 3. 操作
+
+// 这些类似效果函数但是可以做更多
+$('div').addClass('taming-slim-20'); // 给所有div添加类taming-slim-20
+
+// 常见操作方法
+$('p').append('Hello world'); // 添加到元素末尾
+$('p').attr('class'); // 获取属性
+$('p').attr('class', 'content'); // 设置属性
+$('p').hasClass('taming-slim-20'); // 如果有类则为真
+$('p').height(); // 获取和设置元素的高度
+
+
+// 对于很多的操作函数来说,获取元素的信息
+// 仅仅是第一个符合元素的
+$('p').height(); // 仅仅获取第一个p标签的高度
+
+// 你可以用each来迭代所有元素
+var heights = [];
+$('p').each(function() {
+ heights.push($(this).height()); // 把所有p标签的高度加入数组
+});
+
+
+```
diff --git a/zh-cn/json-cn.html.markdown b/zh-cn/json-cn.html.markdown
index 3a8db2cf..73d3eb57 100644
--- a/zh-cn/json-cn.html.markdown
+++ b/zh-cn/json-cn.html.markdown
@@ -8,12 +8,21 @@ filename: learnjson-cn.json
lang: zh-cn
---
-因为JSON是一个极其简单的数据交换形式,这个最有可能将会是曾经最简单
-的Learn X in Y Minutes。
+因为JSON是一个极其简单的数据交换格式,本教程最有可能成为有史以来最简单的
+Learn X in Y Minutes。
-最纯正形式的JSON没有实际的注解,但是大多数解析器将会
-接受C-风格(//, /\* \*/)的注解。为了这个目的,但是,
-一切都将会是100%有效的JSON。幸亏,它是不言自明的。
+纯正的JSON实际上没有注释,但是大多数解析器都
+接受C-风格(//, /\* \*/)的注释。为了兼容性,最好不要在其中写这样形式的注释。
+
+因此,本教程的一切都会是100%有效的JSON。幸亏,它的表达能力很丰富。
+
+支持的数据类型:
+
+- 字符串: "hello", "\"A quote.\"", "\u0abe", "Newline.\n"
+- 数字: 23, 0.11, 12e10, 3.141e-10, 1.23e+4
+- 对象: { "key": "value" }
+- 数组: ["Values"]
+- 其他: true, false, null
```json
{
diff --git a/zh-cn/julia-cn.html.markdown b/zh-cn/julia-cn.html.markdown
index 1f91d52c..b350b6dc 100644
--- a/zh-cn/julia-cn.html.markdown
+++ b/zh-cn/julia-cn.html.markdown
@@ -2,16 +2,24 @@
language: Julia
filename: learn-julia-zh.jl
contributors:
- - ["Jichao Ouyang", "http://oyanglul.us"]
+ - ["Leah Hanson", "http://leahhanson.us"]
+ - ["Pranit Bauva", "https://github.com/pranitbauva1997"]
+ - ["Daniel YC Lin", "https://github.com/dlintw"]
translators:
- ["Jichao Ouyang", "http://oyanglul.us"]
+ - ["woclass", "https://github.com/inkydragon"]
lang: zh-cn
---
-```ruby
-# 单行注释只需要一个井号
+Julia 是一种新的同像函数式编程语言(homoiconic functional language),它专注于科学计算领域。
+虽然拥有同像宏(homoiconic macros)、一级函数(first-class functions)和底层控制等全部功能,但 Julia 依旧和 Python 一样易于学习和使用。
+
+示例代码基于 Julia 1.0.0
+
+```julia
+# 单行注释只需要一个井号「#」
#= 多行注释
- 只需要以 '#=' 开始 '=#' 结束
+ 只需要以「#=」开始「=#」结束
还可以嵌套.
=#
@@ -19,41 +27,41 @@ lang: zh-cn
## 1. 原始类型与操作符
####################################################
-# Julia 中一切皆是表达式。
-
-# 这是一些基本数字类型.
-3 # => 3 (Int64)
-3.2 # => 3.2 (Float64)
-2 + 1im # => 2 + 1im (Complex{Int64})
-2//3 # => 2//3 (Rational{Int64})
-
-# 支持所有的普通中缀操作符。
-1 + 1 # => 2
-8 - 1 # => 7
-10 * 2 # => 20
-35 / 5 # => 7.0
-5 / 2 # => 2.5 # 用 Int 除 Int 永远返回 Float
-div(5, 2) # => 2 # 使用 div 截断小数点
-5 \ 35 # => 7.0
-2 ^ 2 # => 4 # 次方, 不是二进制 xor
-12 % 10 # => 2
+# Julia 中一切皆为表达式
+
+# 这是一些基本数字类型
+typeof(3) # => Int64
+typeof(3.2) # => Float64
+typeof(2 + 1im) # => Complex{Int64}
+typeof(2 // 3) # => Rational{Int64}
+
+# 支持所有的普通中缀操作符
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7.0
+10 / 2 # => 5.0 # 整数除法总是返回浮点数
+div(5, 2) # => 2 # 使用 div 可以获得整除的结果
+5 \ 35 # => 7.0
+2^2 # => 4 # 幂运算,不是异或 (xor)
+12 % 10 # => 2
# 用括号提高优先级
(1 + 3) * 2 # => 8
-# 二进制操作符
-~2 # => -3 # 非
-3 & 5 # => 1 # 与
-2 | 4 # => 6 # 或
-2 $ 4 # => 6 # 异或
-2 >>> 1 # => 1 # 逻辑右移
-2 >> 1 # => 1 # 算术右移
-2 << 1 # => 4 # 逻辑/算术 右移
-
-# 可以用函数 bits 查看二进制数。
-bits(12345)
+# 位操作符
+~2 # => -3 # 按位非 (not)
+3 & 5 # => 1 # 按位与 (and)
+2 | 4 # => 6 # 按位或 (or)
+xor(2, 4) # => 6 # 按位异或 (xor)
+2 >>> 1 # => 1 # 逻辑右移
+2 >> 1 # => 1 # 算术右移
+2 << 1 # => 4 # 逻辑/算术左移
+
+# 可以用函数 bitstring 查看二进制数。
+bitstring(12345)
# => "0000000000000000000000000000000000000000000000000011000000111001"
-bits(12345.0)
+bitstring(12345.0)
# => "0100000011001000000111001000000000000000000000000000000000000000"
# 布尔值是原始类型
@@ -61,40 +69,50 @@ true
false
# 布尔操作符
-!true # => false
-!false # => true
-1 == 1 # => true
-2 == 1 # => false
-1 != 1 # => false
-2 != 1 # => true
-1 < 10 # => true
-1 > 10 # => false
-2 <= 2 # => true
-2 >= 2 # => true
-# 比较可以串联
+!true # => false
+!false # => true
+1 == 1 # => true
+2 == 1 # => false
+1 != 1 # => false
+2 != 1 # => true
+1 < 10 # => true
+1 > 10 # => false
+2 <= 2 # => true
+2 >= 2 # => true
+
+# 链式比较
1 < 2 < 3 # => true
2 < 3 < 2 # => false
-# 字符串可以由 " 创建
+# 字符串可以由「"」创建
"This is a string."
-# 字符字面量可用 ' 创建
+# 字符字面量可用「'」创建
'a'
+# 字符串使用 UTF-8 编码
# 可以像取数组取值一样用 index 取出对应字符
-"This is a string"[1] # => 'T' # Julia 的 index 从 1 开始 :(
-# 但是对 UTF-8 无效,
-# 因此建议使用遍历器 (map, for loops, 等).
+ascii("This is a string")[1]
+# => 'T': ASCII/Unicode U+0054 (category Lu: Letter, uppercase)
+# Julia 的 index 从 1 开始 :(
+# 但只有在字符串仅由 ASCII 字符构成时,字符串才能够被安全的引索
+# 因此建议使用遍历器 (map, for loops, 等)
# $ 可用于字符插值:
"2 + 2 = $(2 + 2)" # => "2 + 2 = 4"
# 可以将任何 Julia 表达式放入括号。
-# 另一种格式化字符串的方式是 printf 宏.
-@printf "%d is less than %f" 4.5 5.3 # 5 is less than 5.300000
+# 另一种输出格式化字符串的方法是使用标准库 Printf 中的 Printf 宏
+using Printf
+@printf "%d is less than %f\n" 4.5 5.3 # => 5 is less than 5.300000
# 打印字符串很容易
-println("I'm Julia. Nice to meet you!")
+println("I'm Julia. Nice to meet you!") # => I'm Julia. Nice to meet you!
+
+# 字符串可以按字典序进行比较
+"good" > "bye" # => true
+"good" == "good" # => true
+"1 + 2 = 3" == "1 + 2 = $(1 + 2)" # => true
####################################################
## 2. 变量与集合
@@ -106,12 +124,12 @@ some_var # => 5
# 访问未声明变量会抛出异常
try
- some_other_var # => ERROR: some_other_var not defined
+ some_other_var # => ERROR: UndefVarError: some_other_var not defined
catch e
println(e)
end
-# 变量名需要以字母开头.
+# 变量名必须以下划线或字母开头
# 之后任何字母,数字,下划线,叹号都是合法的。
SomeOtherVar123! = 6 # => 6
@@ -122,66 +140,93 @@ SomeOtherVar123! = 6 # => 6
# 注意 Julia 的命名规约:
#
-# * 变量名为小写,单词之间以下划线连接('\_')。
+# * 名称可以用下划线「_」分割。
+# 不过一般不推荐使用下划线,除非不用变量名就会变得难于理解
#
-# * 类型名以大写字母开头,单词以 CamelCase 方式连接。
+# * 类型名以大写字母开头,单词以 CamelCase 方式连接,无下划线。
#
# * 函数与宏的名字小写,无下划线。
#
-# * 会改变输入的函数名末位为 !。
+# * 会改变输入的函数名末位为「!」。
# 这类函数有时被称为 mutating functions 或 in-place functions.
-# 数组存储一列值,index 从 1 开始。
-a = Int64[] # => 0-element Int64 Array
+# 数组存储一列值,index 从 1 开始
+a = Int64[] # => 0-element Array{Int64,1}
+
+# 一维数组可以以逗号分隔值的方式声明
+b = [4, 5, 6] # => 3-element Array{Int64,1}: [4, 5, 6]
+b = [4; 5; 6] # => 3-element Array{Int64,1}: [4, 5, 6]
+b[1] # => 4
+b[end] # => 6
-# 一维数组可以以逗号分隔值的方式声明。
-b = [4, 5, 6] # => 包含 3 个 Int64 类型元素的数组: [4, 5, 6]
-b[1] # => 4
-b[end] # => 6
+# 二维数组以分号分隔维度
+matrix = [1 2; 3 4] # => 2×2 Array{Int64,2}: [1 2; 3 4]
-# 二维数组以分号分隔维度。
-matrix = [1 2; 3 4] # => 2x2 Int64 数组: [1 2; 3 4]
+# 指定数组的类型
+b = Int8[4, 5, 6] # => 3-element Array{Int8,1}: [4, 5, 6]
# 使用 push! 和 append! 往数组末尾添加元素
-push!(a,1) # => [1]
-push!(a,2) # => [1,2]
-push!(a,4) # => [1,2,4]
-push!(a,3) # => [1,2,4,3]
-append!(a,b) # => [1,2,4,3,4,5,6]
+push!(a, 1) # => [1]
+push!(a, 2) # => [1,2]
+push!(a, 4) # => [1,2,4]
+push!(a, 3) # => [1,2,4,3]
+append!(a, b) # => [1,2,4,3,4,5,6]
-# 用 pop 弹出末尾元素
-pop!(b) # => 6 and b is now [4,5]
+# 用 pop 弹出尾部的元素
+pop!(b) # => 6
+b # => [4,5]
-# 可以再放回去
-push!(b,6) # b 又变成了 [4,5,6].
+# 再放回去
+push!(b, 6) # => [4,5,6]
+b # => [4,5,6]
-a[1] # => 1 # 永远记住 Julia 的 index 从 1 开始!
+a[1] # => 1 # 永远记住 Julia 的引索从 1 开始!而不是 0!
-# 用 end 可以直接取到最后索引. 可用作任何索引表达式
+# 用 end 可以直接取到最后索引。它可以用在任何索引表达式中
a[end] # => 6
-# 还支持 shift 和 unshift
-shift!(a) # => 返回 1,而 a 现在时 [2,4,3,4,5,6]
-unshift!(a,7) # => [7,2,4,3,4,5,6]
+# 数组还支持 popfirst! 和 pushfirst!
+popfirst!(a) # => 1
+a # => [2,4,3,4,5,6]
+pushfirst!(a, 7) # => [7,2,4,3,4,5,6]
+a # => [7,2,4,3,4,5,6]
# 以叹号结尾的函数名表示它会改变参数的值
-arr = [5,4,6] # => 包含三个 Int64 元素的数组: [5,4,6]
-sort(arr) # => [4,5,6]; arr 还是 [5,4,6]
-sort!(arr) # => [4,5,6]; arr 现在是 [4,5,6]
+arr = [5,4,6] # => 3-element Array{Int64,1}: [5,4,6]
+sort(arr) # => [4,5,6]
+arr # => [5,4,6]
+sort!(arr) # => [4,5,6]
+arr # => [4,5,6]
-# 越界会抛出 BoundsError 异常
+# 数组越界会抛出 BoundsError
try
- a[0] # => ERROR: BoundsError() in getindex at array.jl:270
- a[end+1] # => ERROR: BoundsError() in getindex at array.jl:270
+ a[0]
+ # => ERROR: BoundsError: attempt to access 7-element Array{Int64,1} at
+ # index [0]
+ # => Stacktrace:
+ # => [1] getindex(::Array{Int64,1}, ::Int64) at .\array.jl:731
+ # => [2] top-level scope at none:0
+ # => [3] ...
+ # => in expression starting at ...\LearnJulia.jl:203
+ a[end + 1]
+ # => ERROR: BoundsError: attempt to access 7-element Array{Int64,1} at
+ # index [8]
+ # => Stacktrace:
+ # => [1] getindex(::Array{Int64,1}, ::Int64) at .\array.jl:731
+ # => [2] top-level scope at none:0
+ # => [3] ...
+ # => in expression starting at ...\LearnJulia.jl:211
catch e
println(e)
end
-# 错误会指出发生的行号,包括标准库
-# 如果你有 Julia 源代码,你可以找到这些地方
+# 报错时错误会指出出错的文件位置以及行号,标准库也一样
+# 你可以在 Julia 安装目录下的 share/julia 文件夹里找到这些标准库
# 可以用 range 初始化数组
-a = [1:5] # => 5-element Int64 Array: [1,2,3,4,5]
+a = [1:5;] # => 5-element Array{Int64,1}: [1,2,3,4,5]
+# 注意!分号不可省略
+a2 = [1:5] # => 1-element Array{UnitRange{Int64},1}: [1:5]
# 可以切割数组
a[1:3] # => [1, 2, 3]
@@ -189,11 +234,13 @@ a[2:end] # => [2, 3, 4, 5]
# 用 splice! 切割原数组
arr = [3,4,5]
-splice!(arr,2) # => 4 ; arr 变成了 [3,5]
+splice!(arr, 2) # => 4
+arr # => [3,5]
# 用 append! 连接数组
b = [1,2,3]
-append!(a,b) # a 变成了 [1, 2, 3, 4, 5, 1, 2, 3]
+append!(a, b) # => [1, 2, 3, 4, 5, 1, 2, 3]
+a # => [1, 2, 3, 4, 5, 1, 2, 3]
# 检查元素是否在数组中
in(1, a) # => true
@@ -201,240 +248,258 @@ in(1, a) # => true
# 用 length 获得数组长度
length(a) # => 8
-# Tuples 是 immutable 的
-tup = (1, 2, 3) # => (1,2,3) # an (Int64,Int64,Int64) tuple.
+# 元组(Tuples)是不可变的
+tup = (1, 2, 3) # => (1,2,3)
+typeof(tup) # => Tuple{Int64,Int64,Int64}
tup[1] # => 1
-try:
- tup[1] = 3 # => ERROR: no method setindex!((Int64,Int64,Int64),Int64,Int64)
+try
+ tup[1] = 3
+ # => ERROR: MethodError: no method matching
+ # setindex!(::Tuple{Int64,Int64,Int64}, ::Int64, ::Int64)
catch e
println(e)
end
-# 大多数组的函数同样支持 tuples
+# 大多数组的函数同样支持元组
length(tup) # => 3
-tup[1:2] # => (1,2)
-in(2, tup) # => true
+tup[1:2] # => (1,2)
+in(2, tup) # => true
-# 可以将 tuples 元素分别赋给变量
-a, b, c = (1, 2, 3) # => (1,2,3) # a is now 1, b is now 2 and c is now 3
+# 可以将元组的元素解包赋给变量
+a, b, c = (1, 2, 3) # => (1,2,3)
+a # => 1
+b # => 2
+c # => 3
# 不用括号也可以
-d, e, f = 4, 5, 6 # => (4,5,6)
+d, e, f = 4, 5, 6 # => (4,5,6)
+d # => 4
+e # => 5
+f # => 6
# 单元素 tuple 不等于其元素值
(1,) == 1 # => false
-(1) == 1 # => true
+(1) == 1 # => true
# 交换值
-e, d = d, e # => (5,4) # d is now 5 and e is now 4
+e, d = d, e # => (5,4)
+d # => 5
+e # => 4
-# 字典Dictionaries store mappings
-empty_dict = Dict() # => Dict{Any,Any}()
+# 字典用于储存映射(mappings)(键值对)
+empty_dict = Dict() # => Dict{Any,Any} with 0 entries
# 也可以用字面量创建字典
-filled_dict = ["one"=> 1, "two"=> 2, "three"=> 3]
-# => Dict{ASCIIString,Int64}
+filled_dict = Dict("one" => 1, "two" => 2, "three" => 3)
+# => Dict{String,Int64} with 3 entries:
+# => "two" => 2, "one" => 1, "three" => 3
# 用 [] 获得键值
filled_dict["one"] # => 1
# 获得所有键
keys(filled_dict)
-# => KeyIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
+# => Base.KeySet for a Dict{String,Int64} with 3 entries. Keys:
+# => "two", "one", "three"
# 注意,键的顺序不是插入时的顺序
# 获得所有值
values(filled_dict)
-# => ValueIterator{Dict{ASCIIString,Int64}}(["three"=>3,"one"=>1,"two"=>2])
+# => Base.ValueIterator for a Dict{String,Int64} with 3 entries. Values:
+# => 2, 1, 3
# 注意,值的顺序也一样
# 用 in 检查键值是否已存在,用 haskey 检查键是否存在
-in(("one", 1), filled_dict) # => true
-in(("two", 3), filled_dict) # => false
-haskey(filled_dict, "one") # => true
-haskey(filled_dict, 1) # => false
+in(("one" => 1), filled_dict) # => true
+in(("two" => 3), filled_dict) # => false
+haskey(filled_dict, "one") # => true
+haskey(filled_dict, 1) # => false
# 获取不存在的键的值会抛出异常
try
- filled_dict["four"] # => ERROR: key not found: four in getindex at dict.jl:489
+ filled_dict["four"] # => ERROR: KeyError: key "four" not found
catch e
println(e)
end
# 使用 get 可以提供默认值来避免异常
# get(dictionary,key,default_value)
-get(filled_dict,"one",4) # => 1
-get(filled_dict,"four",4) # => 4
+get(filled_dict, "one", 4) # => 1
+get(filled_dict, "four", 4) # => 4
-# 用 Sets 表示无序不可重复的值的集合
-empty_set = Set() # => Set{Any}()
-# 初始化一个 Set 并定义其值
-filled_set = Set(1,2,2,3,4) # => Set{Int64}(1,2,3,4)
+# Set 表示无序不可重复的值的集合
+empty_set = Set() # => Set(Any[])
+# 初始化一个带初值的 Set
+filled_set = Set([1, 2, 2, 3, 4]) # => Set([4, 2, 3, 1])
-# 添加值
-push!(filled_set,5) # => Set{Int64}(5,4,2,3,1)
+# 新增值
+push!(filled_set, 5) # => Set([4, 2, 3, 5, 1])
-# 检查是否存在某值
-in(2, filled_set) # => true
-in(10, filled_set) # => false
+# 检查 Set 中是否存在某值
+in(2, filled_set) # => true
+in(10, filled_set) # => false
# 交集,并集,差集
-other_set = Set(3, 4, 5, 6) # => Set{Int64}(6,4,5,3)
-intersect(filled_set, other_set) # => Set{Int64}(3,4,5)
-union(filled_set, other_set) # => Set{Int64}(1,2,3,4,5,6)
-setdiff(Set(1,2,3,4),Set(2,3,5)) # => Set{Int64}(1,4)
-
+other_set = Set([3, 4, 5, 6]) # => Set([4, 3, 5, 6])
+intersect(filled_set, other_set) # => Set([4, 3, 5])
+union(filled_set, other_set) # => Set([4, 2, 3, 5, 6, 1])
+setdiff(Set([1,2,3,4]), Set([2,3,5])) # => Set([4, 1])
####################################################
-## 3. 控制流
+## 3. 控制语句
####################################################
# 声明一个变量
some_var = 5
-# 这是一个 if 语句,缩进不是必要的
+# 这是一个 if 语句块,其中的缩进不是必须的
if some_var > 10
println("some_var is totally bigger than 10.")
-elseif some_var < 10 # elseif 是可选的.
+elseif some_var < 10 # elseif 是可选的
println("some_var is smaller than 10.")
-else # else 也是可选的.
+else # else 也是可选的
println("some_var is indeed 10.")
end
-# => prints "some var is smaller than 10"
+# => some_var is smaller than 10.
# For 循环遍历
-# Iterable 类型包括 Range, Array, Set, Dict, 以及 String.
-for animal=["dog", "cat", "mouse"]
+# 可迭代的类型包括:Range, Array, Set, Dict 和 AbstractString
+for animal = ["dog", "cat", "mouse"]
println("$animal is a mammal")
- # 可用 $ 将 variables 或 expression 转换为字符串into strings
+ # 你可以用 $ 将变量或表达式插入字符串中
end
-# prints:
-# dog is a mammal
-# cat is a mammal
-# mouse is a mammal
+# => dog is a mammal
+# => cat is a mammal
+# => mouse is a mammal
-# You can use 'in' instead of '='.
+# 你也可以不用「=」而使用「in」
for animal in ["dog", "cat", "mouse"]
println("$animal is a mammal")
end
-# prints:
-# dog is a mammal
-# cat is a mammal
-# mouse is a mammal
+# => dog is a mammal
+# => cat is a mammal
+# => mouse is a mammal
-for a in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"]
- println("$(a[1]) is a $(a[2])")
+for pair in Dict("dog" => "mammal", "cat" => "mammal", "mouse" => "mammal")
+ from, to = pair
+ println("$from is a $to")
end
-# prints:
-# dog is a mammal
-# cat is a mammal
-# mouse is a mammal
+# => mouse is a mammal
+# => cat is a mammal
+# => dog is a mammal
+# 注意!这里的输出顺序和上面的不同
-for (k,v) in ["dog"=>"mammal","cat"=>"mammal","mouse"=>"mammal"]
+for (k, v) in Dict("dog" => "mammal", "cat" => "mammal", "mouse" => "mammal")
println("$k is a $v")
end
-# prints:
-# dog is a mammal
-# cat is a mammal
-# mouse is a mammal
+# => mouse is a mammal
+# => cat is a mammal
+# => dog is a mammal
# While 循环
-x = 0
-while x < 4
- println(x)
- x += 1 # x = x + 1
+let x = 0
+ while x < 4
+ println(x)
+ x += 1 # x = x + 1 的缩写
+ end
end
-# prints:
-# 0
-# 1
-# 2
-# 3
+# => 0
+# => 1
+# => 2
+# => 3
# 用 try/catch 处理异常
try
- error("help")
+ error("help")
catch e
- println("caught it $e")
+ println("caught it $e")
end
# => caught it ErrorException("help")
-
####################################################
## 4. 函数
####################################################
-# 用关键字 'function' 可创建一个新函数
-#function name(arglist)
-# body...
-#end
+# 关键字 function 用于定义函数
+# function name(arglist)
+# body...
+# end
function add(x, y)
println("x is $x and y is $y")
- # 最后一行语句的值为返回
+ # 函数会返回最后一行的值
x + y
end
-add(5, 6) # => 在 "x is 5 and y is 6" 后会打印 11
+add(5, 6)
+# => x is 5 and y is 6
+# => 11
+
+# 更紧凑的定义函数
+f_add(x, y) = x + y # => f_add (generic function with 1 method)
+f_add(3, 4) # => 7
+
+# 函数可以将多个值作为元组返回
+fn(x, y) = x + y, x - y # => fn (generic function with 1 method)
+fn(3, 4) # => (7, -1)
# 还可以定义接收可变长参数的函数
function varargs(args...)
return args
- # 关键字 return 可在函数内部任何地方返回
+ # 使用 return 可以在函数内的任何地方返回
end
# => varargs (generic function with 1 method)
varargs(1,2,3) # => (1,2,3)
-# 省略号 ... 被称为 splat.
+# 省略号「...」称为 splat
# 刚刚用在了函数定义中
-# 还可以用在函数的调用
-# Array 或者 Tuple 的内容会变成参数列表
-Set([1,2,3]) # => Set{Array{Int64,1}}([1,2,3]) # 获得一个 Array 的 Set
-Set([1,2,3]...) # => Set{Int64}(1,2,3) # 相当于 Set(1,2,3)
+# 在调用函数时也可以使用它,此时它会把数组或元组解包为参数列表
+add([5,6]...) # 等价于 add(5,6)
-x = (1,2,3) # => (1,2,3)
-Set(x) # => Set{(Int64,Int64,Int64)}((1,2,3)) # 一个 Tuple 的 Set
-Set(x...) # => Set{Int64}(2,3,1)
+x = (5, 6) # => (5,6)
+add(x...) # 等价于 add(5,6)
-
-# 可定义可选参数的函数
-function defaults(a,b,x=5,y=6)
+# 可定义带可选参数的函数
+function defaults(a, b, x=5, y=6)
return "$a $b and $x $y"
end
+# => defaults (generic function with 3 methods)
-defaults('h','g') # => "h g and 5 6"
-defaults('h','g','j') # => "h g and j 6"
-defaults('h','g','j','k') # => "h g and j k"
+defaults('h', 'g') # => "h g and 5 6"
+defaults('h', 'g', 'j') # => "h g and j 6"
+defaults('h', 'g', 'j', 'k') # => "h g and j k"
try
- defaults('h') # => ERROR: no method defaults(Char,)
- defaults() # => ERROR: no methods defaults()
+ defaults('h') # => ERROR: MethodError: no method matching defaults(::Char)
+ defaults() # => ERROR: MethodError: no method matching defaults()
catch e
println(e)
end
-# 还可以定义键值对的参数
-function keyword_args(;k1=4,name2="hello") # note the ;
- return ["k1"=>k1,"name2"=>name2]
+# 还可以定义带关键字参数的函数
+function keyword_args(;k1=4, name2="hello") # 注意分号 ';'
+ return Dict("k1" => k1, "name2" => name2)
end
+# => keyword_args (generic function with 1 method)
-keyword_args(name2="ness") # => ["name2"=>"ness","k1"=>4]
-keyword_args(k1="mine") # => ["k1"=>"mine","name2"=>"hello"]
-keyword_args() # => ["name2"=>"hello","k1"=>4]
+keyword_args(name2="ness") # => ["name2"=>"ness", "k1"=>4]
+keyword_args(k1="mine") # => ["name2"=>"hello", "k1"=>"mine"]
+keyword_args() # => ["name2"=>"hello", "k1"=>4]
-# 可以组合各种类型的参数在同一个函数的参数列表中
+# 可以在一个函数中组合各种类型的参数
function all_the_args(normal_arg, optional_positional_arg=2; keyword_arg="foo")
println("normal arg: $normal_arg")
println("optional arg: $optional_positional_arg")
println("keyword arg: $keyword_arg")
end
+# => all_the_args (generic function with 2 methods)
all_the_args(1, 3, keyword_arg=4)
-# prints:
-# normal arg: 1
-# optional arg: 3
-# keyword arg: 4
+# => normal arg: 1
+# => optional arg: 3
+# => keyword arg: 4
# Julia 有一等函数
function create_adder(x)
@@ -443,14 +508,16 @@ function create_adder(x)
end
return adder
end
+# => create_adder (generic function with 1 method)
# 这是用 "stabby lambda syntax" 创建的匿名函数
(x -> x > 2)(3) # => true
-# 这个函数和上面的 create_adder 一模一样
+# 这个函数和上面的 create_adder 是等价的
function create_adder(x)
y -> x + y
end
+# => create_adder (generic function with 1 method)
# 你也可以给内部函数起个名字
function create_adder(x)
@@ -459,18 +526,19 @@ function create_adder(x)
end
adder
end
+# => create_adder (generic function with 1 method)
-add_10 = create_adder(10)
-add_10(3) # => 13
-
+add_10 = create_adder(10) # => (::getfield(Main, Symbol("#adder#11")){Int64})
+ # (generic function with 1 method)
+add_10(3) # => 13
# 内置的高阶函数有
-map(add_10, [1,2,3]) # => [11, 12, 13]
-filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+map(add_10, [1,2,3]) # => [11, 12, 13]
+filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
-# 还可以使用 list comprehensions 替代 map
-[add_10(i) for i=[1, 2, 3]] # => [11, 12, 13]
-[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+# 还可以使用 list comprehensions 让 map 更美观
+[add_10(i) for i = [1, 2, 3]] # => [11, 12, 13]
+[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
####################################################
## 5. 类型
@@ -482,248 +550,315 @@ filter(x -> x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
typeof(5) # => Int64
# 类型是一等值
-typeof(Int64) # => DataType
-typeof(DataType) # => DataType
+typeof(Int64) # => DataType
+typeof(DataType) # => DataType
# DataType 是代表类型的类型,也代表他自己的类型
-# 类型可用作文档化,优化,以及调度
-# 并不是静态检查类型
+# 类型可用于文档化代码、执行优化以及多重派分(dispatch)
+# Julia 并不只是静态的检查类型
# 用户还可以自定义类型
-# 跟其他语言的 records 或 structs 一样
-# 用 `type` 关键字定义新的类型
+# 就跟其它语言的 record 或 struct 一样
+# 用 `struct` 关键字定义新的类型
-# type Name
+# struct Name
# field::OptionalType
# ...
# end
-type Tiger
- taillength::Float64
- coatcolor # 不附带类型标注的相当于 `::Any`
+struct Tiger
+ taillength::Float64
+ coatcolor # 不带类型标注相当于 `::Any`
end
-# 构造函数参数是类型的属性
-tigger = Tiger(3.5,"orange") # => Tiger(3.5,"orange")
+# 默认构造函数的参数是类型的属性,按类型定义中的顺序排列
+tigger = Tiger(3.5, "orange") # => Tiger(3.5, "orange")
# 用新类型作为构造函数还会创建一个类型
-sherekhan = typeof(tigger)(5.6,"fire") # => Tiger(5.6,"fire")
+sherekhan = typeof(tigger)(5.6, "fire") # => Tiger(5.6, "fire")
-# struct 类似的类型被称为具体类型
-# 他们可被实例化但不能有子类型
+# 类似 struct 的类型被称为具体类型
+# 它们可被实例化,但不能有子类型
# 另一种类型是抽象类型
-# abstract Name
-abstract Cat # just a name and point in the type hierarchy
+# 抽象类型名
+abstract type Cat end # 仅仅是指向类型结构层次的一个名称
-# 抽象类型不能被实例化,但是可以有子类型
+# 抽象类型不能被实例化,但可以有子类型
# 例如,Number 就是抽象类型
-subtypes(Number) # => 6-element Array{Any,1}:
- # Complex{Float16}
- # Complex{Float32}
- # Complex{Float64}
- # Complex{T<:Real}
- # ImaginaryUnit
- # Real
-subtypes(Cat) # => 0-element Array{Any,1}
-
-# 所有的类型都有父类型; 可以用函数 `super` 得到父类型.
+subtypes(Number) # => 2-element Array{Any,1}:
+ # => Complex
+ # => Real
+subtypes(Cat) # => 0-element Array{Any,1}
+
+# AbstractString,类如其名,也是一个抽象类型
+subtypes(AbstractString) # => 4-element Array{Any,1}:
+ # => String
+ # => SubString
+ # => SubstitutionString
+ # => Test.GenericString
+
+# 所有的类型都有父类型。可以用函数 `supertype` 得到父类型
typeof(5) # => Int64
-super(Int64) # => Signed
-super(Signed) # => Real
-super(Real) # => Number
-super(Number) # => Any
-super(super(Signed)) # => Number
-super(Any) # => Any
-# 所有这些类型,除了 Int64, 都是抽象类型.
-
-# <: 是类型集成操作符
-type Lion <: Cat # Lion 是 Cat 的子类型
- mane_color
- roar::String
+supertype(Int64) # => Signed
+supertype(Signed) # => Integer
+supertype(Integer) # => Real
+supertype(Real) # => Number
+supertype(Number) # => Any
+supertype(supertype(Signed)) # => Real
+supertype(Any) # => Any
+# 除了 Int64 外,其余的类型都是抽象类型
+typeof("fire") # => String
+supertype(String) # => AbstractString
+supertype(AbstractString) # => Any
+supertype(SubString) # => AbstractString
+
+# <: 是子类型化操作符
+struct Lion <: Cat # Lion 是 Cat 的子类型
+ mane_color
+ roar::AbstractString
end
# 可以继续为你的类型定义构造函数
-# 只需要定义一个同名的函数
-# 并调用已有的构造函数设置一个固定参数
-Lion(roar::String) = Lion("green",roar)
-# 这是一个外部构造函数,因为他再类型定义之外
-
-type Panther <: Cat # Panther 也是 Cat 的子类型
- eye_color
- Panther() = new("green")
- # Panthers 只有这个构造函数,没有默认构造函数
+# 只需要定义一个与类型同名的函数,并调用已有的构造函数得到正确的类型
+Lion(roar::AbstractString) = Lion("green", roar) # => Lion
+# 这是一个外部构造函数,因为它在类型定义之外
+
+struct Panther <: Cat # Panther 也是 Cat 的子类型
+ eye_color
+ Panther() = new("green")
+ # Panthers 只有这个构造函数,没有默认构造函数
end
-# 使用内置构造函数,如 Panther,可以让你控制
-# 如何构造类型的值
-# 应该尽可能使用外部构造函数而不是内部构造函数
+# 像 Panther 一样使用内置构造函数,让你可以控制如何构建类型的值
+# 应该尽量使用外部构造函数,而不是内部构造函数
####################################################
## 6. 多分派
####################################################
-# 在Julia中, 所有的具名函数都是类属函数
-# 这意味着他们都是有很大小方法组成的
-# 每个 Lion 的构造函数都是类属函数 Lion 的方法
+# Julia 中所有的函数都是通用函数,或者叫做泛型函数(generic functions)
+# 也就是说这些函数都是由许多小方法组合而成的
+# Lion 的每一种构造函数都是通用函数 Lion 的一个方法
# 我们来看一个非构造函数的例子
+# 首先,让我们定义一个函数 meow
-# Lion, Panther, Tiger 的 meow 定义为
+# Lion, Panther, Tiger 的 meow 定义分别为
function meow(animal::Lion)
- animal.roar # 使用点符号访问属性
+ animal.roar # 使用点记号「.」访问属性
end
+# => meow (generic function with 1 method)
function meow(animal::Panther)
- "grrr"
+ "grrr"
end
+# => meow (generic function with 2 methods)
function meow(animal::Tiger)
- "rawwwr"
+ "rawwwr"
end
+# => meow (generic function with 3 methods)
# 试试 meow 函数
-meow(tigger) # => "rawwr"
-meow(Lion("brown","ROAAR")) # => "ROAAR"
+meow(tigger) # => "rawwwr"
+meow(Lion("brown", "ROAAR")) # => "ROAAR"
meow(Panther()) # => "grrr"
-# 再看看层次结构
-issubtype(Tiger,Cat) # => false
-issubtype(Lion,Cat) # => true
-issubtype(Panther,Cat) # => true
+# 回顾类型的层次结构
+Tiger <: Cat # => false
+Lion <: Cat # => true
+Panther <: Cat # => true
-# 定义一个接收 Cats 的函数
+# 定义一个接收 Cat 类型的函数
function pet_cat(cat::Cat)
- println("The cat says $(meow(cat))")
+ println("The cat says $(meow(cat))")
end
+# => pet_cat (generic function with 1 method)
-pet_cat(Lion("42")) # => prints "The cat says 42"
+pet_cat(Lion("42")) # => The cat says 42
try
- pet_cat(tigger) # => ERROR: no method pet_cat(Tiger,)
+ pet_cat(tigger) # => ERROR: MethodError: no method matching pet_cat(::Tiger)
catch e
println(e)
end
# 在面向对象语言中,通常都是单分派
-# 这意味着分派方法是通过第一个参数的类型决定的
-# 在Julia中, 所有参数类型都会被考虑到
+# 这意味着使用的方法取决于第一个参数的类型
+# 而 Julia 中选择方法时会考虑到所有参数的类型
-# 让我们定义有多个参数的函数,好看看区别
-function fight(t::Tiger,c::Cat)
- println("The $(t.coatcolor) tiger wins!")
+# 让我们定义一个有更多参数的函数,这样我们就能看出区别
+function fight(t::Tiger, c::Cat)
+ println("The $(t.coatcolor) tiger wins!")
end
# => fight (generic function with 1 method)
-fight(tigger,Panther()) # => prints The orange tiger wins!
-fight(tigger,Lion("ROAR")) # => prints The orange tiger wins!
+fight(tigger, Panther()) # => The orange tiger wins!
+fight(tigger, Lion("ROAR")) # => fight(tigger, Lion("ROAR"))
-# 让我们修改一下传入具体为 Lion 类型时的行为
-fight(t::Tiger,l::Lion) = println("The $(l.mane_color)-maned lion wins!")
+# 让我们修改一下传入 Lion 类型时的行为
+fight(t::Tiger, l::Lion) = println("The $(l.mane_color)-maned lion wins!")
# => fight (generic function with 2 methods)
-fight(tigger,Panther()) # => prints The orange tiger wins!
-fight(tigger,Lion("ROAR")) # => prints The green-maned lion wins!
+fight(tigger, Panther()) # => The orange tiger wins!
+fight(tigger, Lion("ROAR")) # => The green-maned lion wins!
-# 把 Tiger 去掉
-fight(l::Lion,c::Cat) = println("The victorious cat says $(meow(c))")
+# 我们不需要一只老虎参与战斗
+fight(l::Lion, c::Cat) = println("The victorious cat says $(meow(c))")
# => fight (generic function with 3 methods)
-fight(Lion("balooga!"),Panther()) # => prints The victorious cat says grrr
+fight(Lion("balooga!"), Panther()) # => The victorious cat says grrr
try
- fight(Panther(),Lion("RAWR")) # => ERROR: no method fight(Panther,Lion)
-catch
+ fight(Panther(), Lion("RAWR"))
+ # => ERROR: MethodError: no method matching fight(::Panther, ::Lion)
+ # => Closest candidates are:
+ # => fight(::Tiger, ::Lion) at ...
+ # => fight(::Tiger, ::Cat) at ...
+ # => fight(::Lion, ::Cat) at ...
+ # => ...
+catch e
+ println(e)
end
-# 在试试让 Cat 在前面
-fight(c::Cat,l::Lion) = println("The cat beats the Lion")
-# => Warning: New definition
-# fight(Cat,Lion) at none:1
-# is ambiguous with
-# fight(Lion,Cat) at none:2.
-# Make sure
-# fight(Lion,Lion)
-# is defined first.
-#fight (generic function with 4 methods)
-
-# 警告说明了无法判断使用哪个 fight 方法
-fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The victorious cat says rarrr
-# 结果在老版本 Julia 中可能会不一样
-
-fight(l::Lion,l2::Lion) = println("The lions come to a tie")
-fight(Lion("RAR"),Lion("brown","rarrr")) # => prints The lions come to a tie
-
-
-# Under the hood
-# 你还可以看看 llvm 以及生成的汇编代码
-
-square_area(l) = l * l # square_area (generic function with 1 method)
-
-square_area(5) #25
-
-# 给 square_area 一个整形时发生什么
-code_native(square_area, (Int32,))
- # .section __TEXT,__text,regular,pure_instructions
- # Filename: none
- # Source line: 1 # Prologue
- # push RBP
- # mov RBP, RSP
- # Source line: 1
- # movsxd RAX, EDI # Fetch l from memory?
- # imul RAX, RAX # Square l and store the result in RAX
- # pop RBP # Restore old base pointer
- # ret # Result will still be in RAX
-
-code_native(square_area, (Float32,))
- # .section __TEXT,__text,regular,pure_instructions
- # Filename: none
- # Source line: 1
- # push RBP
- # mov RBP, RSP
- # Source line: 1
- # vmulss XMM0, XMM0, XMM0 # Scalar single precision multiply (AVX)
- # pop RBP
- # ret
-
-code_native(square_area, (Float64,))
- # .section __TEXT,__text,regular,pure_instructions
- # Filename: none
- # Source line: 1
- # push RBP
- # mov RBP, RSP
- # Source line: 1
- # vmulsd XMM0, XMM0, XMM0 # Scalar double precision multiply (AVX)
- # pop RBP
- # ret
- #
-# 注意 只要参数中又浮点类型,Julia 就使用浮点指令
+# 试试把 Cat 放在前面
+fight(c::Cat, l::Lion) = println("The cat beats the Lion")
+# => fight (generic function with 4 methods)
+
+# 由于无法判断该使用哪个 fight 方法,而产生了错误
+try
+ fight(Lion("RAR"), Lion("brown", "rarrr"))
+ # => ERROR: MethodError: fight(::Lion, ::Lion) is ambiguous. Candidates:
+ # => fight(c::Cat, l::Lion) in Main at ...
+ # => fight(l::Lion, c::Cat) in Main at ...
+ # => Possible fix, define
+ # => fight(::Lion, ::Lion)
+ # => ...
+catch e
+ println(e)
+end
+# 在不同版本的 Julia 中错误信息可能有所不同
+
+fight(l::Lion, l2::Lion) = println("The lions come to a tie")
+# => fight (generic function with 5 methods)
+fight(Lion("RAR"), Lion("brown", "rarrr")) # => The lions come to a tie
+
+
+# 深入编译器之后
+# 你还可以看看 llvm 以及它生成的汇编代码
+
+square_area(l) = l * l # => square_area (generic function with 1 method)
+square_area(5) # => 25
+
+# 当我们喂给 square_area 一个整数时会发生什么?
+code_native(square_area, (Int32,), syntax = :intel)
+ # .text
+ # ; Function square_area {
+ # ; Location: REPL[116]:1 # 函数序言 (Prologue)
+ # push rbp
+ # mov rbp, rsp
+ # ; Function *; {
+ # ; Location: int.jl:54
+ # imul ecx, ecx # 求 l 的平方,并把结果放在 ECX 中
+ # ;}
+ # mov eax, ecx
+ # pop rbp # 还原旧的基址指针(base pointer)
+ # ret # 返回值放在 EAX 中
+ # nop dword ptr [rax + rax]
+ # ;}
+# 使用 syntax 参数指定输出语法。默认为 AT&T 格式,这里指定为 Intel 格式
+
+code_native(square_area, (Float32,), syntax = :intel)
+ # .text
+ # ; Function square_area {
+ # ; Location: REPL[116]:1
+ # push rbp
+ # mov rbp, rsp
+ # ; Function *; {
+ # ; Location: float.jl:398
+ # vmulss xmm0, xmm0, xmm0 # 标量双精度乘法 (AVX)
+ # ;}
+ # pop rbp
+ # ret
+ # nop word ptr [rax + rax]
+ # ;}
+
+code_native(square_area, (Float64,), syntax = :intel)
+ # .text
+ # ; Function square_area {
+ # ; Location: REPL[116]:1
+ # push rbp
+ # mov rbp, rsp
+ # ; Function *; {
+ # ; Location: float.jl:399
+ # vmulsd xmm0, xmm0, xmm0 # 标量双精度乘法 (AVX)
+ # ;}
+ # pop rbp
+ # ret
+ # nop word ptr [rax + rax]
+ # ;}
+
+# 注意!只要参数中有浮点数,Julia 就会使用浮点指令
# 让我们计算一下圆的面积
-circle_area(r) = pi * r * r # circle_area (generic function with 1 method)
-circle_area(5) # 78.53981633974483
-
-code_native(circle_area, (Int32,))
- # .section __TEXT,__text,regular,pure_instructions
- # Filename: none
- # Source line: 1
- # push RBP
- # mov RBP, RSP
- # Source line: 1
- # vcvtsi2sd XMM0, XMM0, EDI # Load integer (r) from memory
- # movabs RAX, 4593140240 # Load pi
- # vmulsd XMM1, XMM0, QWORD PTR [RAX] # pi * r
- # vmulsd XMM0, XMM0, XMM1 # (pi * r) * r
- # pop RBP
- # ret
- #
-
-code_native(circle_area, (Float64,))
- # .section __TEXT,__text,regular,pure_instructions
- # Filename: none
- # Source line: 1
- # push RBP
- # mov RBP, RSP
- # movabs RAX, 4593140496
- # Source line: 1
- # vmulsd XMM1, XMM0, QWORD PTR [RAX]
- # vmulsd XMM0, XMM1, XMM0
- # pop RBP
- # ret
- #
+circle_area(r) = pi * r * r # => circle_area (generic function with 1 method)
+circle_area(5) # => 78.53981633974483
+
+code_native(circle_area, (Int32,), syntax = :intel)
+ # .text
+ # ; Function circle_area {
+ # ; Location: REPL[121]:1
+ # push rbp
+ # mov rbp, rsp
+ # ; Function *; {
+ # ; Location: operators.jl:502
+ # ; Function *; {
+ # ; Location: promotion.jl:314
+ # ; Function promote; {
+ # ; Location: promotion.jl:284
+ # ; Function _promote; {
+ # ; Location: promotion.jl:261
+ # ; Function convert; {
+ # ; Location: number.jl:7
+ # ; Function Type; {
+ # ; Location: float.jl:60
+ # vcvtsi2sd xmm0, xmm0, ecx # 从内存中读取整数 r
+ # movabs rax, 497710928 # 读取 pi
+ # ;}}}}}
+ # ; Function *; {
+ # ; Location: float.jl:399
+ # vmulsd xmm1, xmm0, qword ptr [rax] # pi * r
+ # vmulsd xmm0, xmm1, xmm0 # (pi * r) * r
+ # ;}}
+ # pop rbp
+ # ret
+ # nop dword ptr [rax]
+ # ;}
+
+code_native(circle_area, (Float64,), syntax = :intel)
+ # .text
+ # ; Function circle_area {
+ # ; Location: REPL[121]:1
+ # push rbp
+ # mov rbp, rsp
+ # movabs rax, 497711048
+ # ; Function *; {
+ # ; Location: operators.jl:502
+ # ; Function *; {
+ # ; Location: promotion.jl:314
+ # ; Function *; {
+ # ; Location: float.jl:399
+ # vmulsd xmm1, xmm0, qword ptr [rax]
+ # ;}}}
+ # ; Function *; {
+ # ; Location: float.jl:399
+ # vmulsd xmm0, xmm1, xmm0
+ # ;}
+ # pop rbp
+ # ret
+ # nop dword ptr [rax + rax]
+ # ;}
```
+
+## 拓展阅读材料
+
+你可以在 [Julia 中文文档](http://docs.juliacn.com/latest/) / [Julia 文档(en)](https://docs.julialang.org/)
+中获得关于 Julia 的更多细节。
+
+如果有任何问题可以去 [Julia 中文社区](http://discourse.juliacn.com/) / [官方社区(en)](https://discourse.julialang.org/) 提问,大家对待新手都非常的友好。
diff --git a/zh-cn/kotlin-cn.html.markdown b/zh-cn/kotlin-cn.html.markdown
index 1fd12f5b..f6dcd847 100644
--- a/zh-cn/kotlin-cn.html.markdown
+++ b/zh-cn/kotlin-cn.html.markdown
@@ -22,7 +22,7 @@ package com.learnxinyminutes.kotlin
/*
Kotlin程序的入口点是一个"main"函数
-该函数传递一个包含任何命令行参数的数组。
+该函数传递一个包含所有命令行参数的数组。
*/
fun main(args: Array<String>) {
/*
@@ -38,7 +38,7 @@ fun main(args: Array<String>) {
所以我们不必要每次都去明确指定它。
我们可以像这样明确地声明一个变量的类型:
*/
- val foo : Int = 7
+ val foo: Int = 7
/*
可以采取和Java类似的方法来表示一个字符串。
@@ -67,10 +67,10 @@ fun helloWorld(val name : String) {
模板表达式从一个美元符号($)开始。
*/
val fooTemplateString = "$fooString has ${fooString.length} characters"
- println(fooTemplateString)
+ println(fooTemplateString) // => 输出 My String Is Here! has 18 characters
/*
- 当某个变量的值可以为 null 的时候,我们必须被明确指定它是可为空的。
+ 当某个变量的值可以为 null 的时候,我们必须明确指定它是可为空的。
在变量声明处的类型后面加上?来标识它是可为空的。
我们可以用?.操作符来访问可为空的变量。
我们可以用?:操作符来指定一个在变量为空时使用的替代值。
@@ -96,24 +96,24 @@ fun helloWorld(val name : String) {
println(hello()) // => Hello, world!
/*
- 用"vararg"关键字来修饰一个函数的参数来允许可变参数传递给该函数
+ 函数的可变参数可使用 "vararg" 关键字来修饰
*/
fun varargExample(vararg names: Int) {
println("Argument has ${names.size} elements")
}
- varargExample() // => Argument has 0 elements
- varargExample(1) // => Argument has 1 elements
- varargExample(1, 2, 3) // => Argument has 3 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
@@ -122,15 +122,14 @@ fun helloWorld(val name : String) {
fun not(f: (Int) -> Boolean) : (Int) -> Boolean {
return {n -> !f.invoke(n)}
}
- // 命名函数可以用::运算符被指定为参数。
+ // 普通函数可以用::运算符传入引用作为函数参数。
val notOdd = not(::odd)
val notEven = not(::even)
- // 匿名函数可以被指定为参数。
+ // lambda 表达式可以直接作为参数传递。
val notZero = not {n -> n == 0}
/*
- 如果一个匿名函数只有一个参数
- 那么它的声明可以被省略(连同->)。
- 这个参数的名字是"it"。
+ 如果一个 lambda 表达式只有一个参数
+ 那么它的声明可以省略(连同->),内部以 "it" 引用。
*/
val notPositive = not {it > 0}
for (i in 0..4) {
@@ -152,7 +151,7 @@ fun helloWorld(val name : String) {
注意,Kotlin没有"new"关键字。
*/
val fooExampleClass = ExampleClass(7)
- // 可以使用一个点号来调用成员函数。
+ // 可以使用一个点号来调用成员方法。
println(fooExampleClass.memberFunction(4)) // => 11
/*
如果使用"infix"关键字来标记一个函数
@@ -162,7 +161,7 @@ fun helloWorld(val name : String) {
/*
数据类是创建只包含数据的类的一个简洁的方法。
- "hashCode"、"equals"和"toString"方法将被自动生成。
+ "hashCode"、"equals"和"toString"方法将自动生成。
*/
data class DataClassExample (val x: Int, val y: Int, val z: Int)
val fooData = DataClassExample(1, 2, 4)
@@ -178,13 +177,13 @@ fun helloWorld(val name : String) {
// "with"函数类似于JavaScript中的"with"用法。
data class MutableDataClassExample (var x: Int, var y: Int, var z: Int)
- val fooMutableDate = MutableDataClassExample(7, 4, 9)
- with (fooMutableDate) {
+ val fooMutableData = MutableDataClassExample(7, 4, 9)
+ with (fooMutableData) {
x -= 2
y += 2
z--
}
- println(fooMutableDate) // => MutableDataClassExample(x=5, y=6, z=8)
+ println(fooMutableData) // => MutableDataClassExample(x=5, y=6, z=8)
/*
我们可以使用"listOf"函数来创建一个list。
diff --git a/zh-cn/lambda-calculus-cn.html.markdown b/zh-cn/lambda-calculus-cn.html.markdown
new file mode 100644
index 00000000..7719ee71
--- /dev/null
+++ b/zh-cn/lambda-calculus-cn.html.markdown
@@ -0,0 +1,223 @@
+---
+category: Algorithms & Data Structures
+name: Lambda Calculus
+lang: zh-cn
+contributors:
+ - ["Max Sun", "http://github.com/maxsun"]
+ - ["Yan Hui Hang", "http://github.com/yanhh0"]
+translators:
+ - ["Maoyin Sun", "https://github.com/simonmysun"]
+---
+
+# Lambda 演算
+
+Lambda 演算(lambda calculus, λ-calculus),
+最初由[阿隆佐·邱奇][]([Alonzo Church][])提出,
+是世界上最小的编程语言.
+尽管没有数字, 字符串, 布尔或者任何非函数的数据类型,
+lambda 演算仍可以表示任何图灵机.
+
+[阿隆佐·邱奇]: https://zh.wikipedia.org/wiki/%E9%98%BF%E9%9A%86%E4%BD%90%C2%B7%E9%82%B1%E5%A5%87
+[Alonzo Church]: https://en.wikipedia.org/wiki/Alonzo_Church
+
+Lambda 演算由三种元素组成: **变量**(variables)、**函数**(functions)和**应用**(applications)。
+
+| 名称 | 语法 | 示例 | 解释 |
+|------|----------------------|-----------|--------------------------------------------------|
+| 变量 | `<变量名>` | `x` | 一个名为"x"的变量 |
+| 函数 | `λ<参数>.<函数体>` | `λx.x` | 一个以"x"(前者)为参数、以"x"(后者)为函数体的函数 |
+| 应用 | `<函数><变量或函数>` | `(λx.x)a` | 以"a"为参数调用函数"λx.x" |
+
+最基本的函数为恒等函数: `λx.x`, 它等价于`f(x) = x`.
+第一个"x"为函数的参数, 第二个为函数体.
+
+## 自由变量和约束变量:
+
+- 在函数`λx.x`中, "x"被称作约束变量因为它同时出现在函数体和函数参数中.
+- 在`λx.y`中, "y"被称作自由变量因为它没有被预先声明.
+
+## 求值:
+
+求值操作是通过[β-归约][]([β-Reduction][])完成的,
+它本质上是词法层面上的替换.
+
+[β-归约]: https://zh.wikipedia.org/wiki/%CE%9B%E6%BC%94%E7%AE%97#'%22%60UNIQ--postMath-0000006F-QINU%60%22'-%E6%AD%B8%E7%B4%84
+[β-Reduction]: https://en.wikipedia.org/wiki/Lambda_calculus#Beta_reduction
+
+当对表达式`(λx.x)a`求值时, 我们将函数体中所有出现的"x"替换为"a".
+
+- `(λx.x)a`计算结果为: `a`
+- `(λx.y)a`计算结果为: `y`
+
+你甚至可以创建高阶函数:
+
+- `(λx.(λy.x))a`计算结果为: `λy.a`
+
+尽管 lambda 演算传统上仅支持单个参数的函数,
+但我们可以通过一种叫作[柯里化][]([Currying][])的技巧创建多个参数的函数.
+
+[柯里化]: https://zh.wikipedia.org/wiki/%E6%9F%AF%E9%87%8C%E5%8C%96
+[Currying]: https://en.wikipedia.org/wiki/Currying
+
+- `(λx.λy.λz.xyz)`等价于`f(x, y, z) = ((x y) z)`
+
+有时`λxy.<body>`与`λx.λy.<body>`可以互换使用.
+
+----
+
+认识到传统的 **lambda 演算没有数字, 字符或者任何非函数的数据类型**很重要.
+
+## 布尔逻辑:
+
+在 lambda 演算中没有"真"或"假". 甚至没有 1 或 0.
+
+作为替换:
+
+`T`表示为: `λx.λy.x`
+
+`F`表示为: `λx.λy.y`
+
+首先, 我们可以定义一个"if"函数`λbtf`, 它当`b`为真时返回`t`,
+`b`为假时返回`f`
+
+`IF`等价于: `λb.λt.λf.b t f`
+
+通过`IF`, 我们可以定义基本的布尔逻辑运算符:
+
+`a AND b`等价于: `λab.IF a b F`
+
+`a OR b`等价于: `λab.IF a T b`
+
+`NOT a`等价于: `λa.IF a F T`
+
+*注意: `IF a b c`本质上指: `IF((a b) c)`*
+
+## 数字:
+
+尽管 lambda 演算中没有数字,
+我们还可以用[邱奇编码][]([Church numerals][])将数字嵌入到 lambda 演算中.
+
+[邱奇编码]: https://zh.wikipedia.org/wiki/%E9%82%B1%E5%A5%87%E7%BC%96%E7%A0%81
+[Church numerals]: https://en.wikipedia.org/wiki/Church_encoding
+
+对于任意数字 n: <code>n = λf.f<sup>n</sup></code> 所以:
+
+`0 = λf.λx.x`
+
+`1 = λf.λx.f x`
+
+`2 = λf.λx.f(f x)`
+
+`3 = λf.λx.f(f(f x))`
+
+要增加一个邱奇数, 我们使用后继函数`S(n) = n + 1`:
+
+`S = λn.λf.λx.f((n f) x)`
+
+使用后继函数, 我们可以定义加法:
+
+`ADD = λab.(a S)b`
+
+**挑战**: 试定义乘法函数!
+
+## 变得更小: SKI, SK 和 Iota
+
+### SKI 组合子演算
+
+令 S, K, I 为下列函数:
+
+`I x = x`
+
+`K x y = x`
+
+`S x y z = x z (y z)`
+
+我们可以将 lambda 演算中的表达式转换为 SKI 组合子演算中的表达式:
+
+1. `λx.x = I`
+2. `λx.c = Kc`
+3. `λx.(y z) = S (λx.y) (λx.z)`
+
+以邱奇数 2 为例:
+
+`2 = λf.λx.f(f x)`
+
+对于里面的部分 `λx.f(f x)`:
+
+```
+ λx.f(f x)
+= S (λx.f) (λx.(f x)) (case 3)
+= S (K f) (S (λx.f) (λx.x)) (case 2, 3)
+= S (K f) (S (K f) I) (case 2, 1)
+```
+
+所以:
+
+```
+ 2
+= λf.λx.f(f x)
+= λf.(S (K f) (S (K f) I))
+= λf.((S (K f)) (S (K f) I))
+= S (λf.(S (K f))) (λf.(S (K f) I)) (case 3)
+```
+
+对于第一个参数`λf.(S (K f))`有:
+
+```
+ λf.(S (K f))
+= S (λf.S) (λf.(K f)) (case 3)
+= S (K S) (S (λf.K) (λf.f)) (case 2, 3)
+= S (K S) (S (K K) I) (case 2, 3)
+```
+
+对于第二个参数`λf.(S (K f) I)`有:
+
+```
+ λf.(S (K f) I)
+= λf.((S (K f)) I)
+= S (λf.(S (K f))) (λf.I) (case 3)
+= S (S (λf.S) (λf.(K f))) (K I) (case 2, 3)
+= S (S (K S) (S (λf.K) (λf.f))) (K I) (case 1, 3)
+= S (S (K S) (S (K K) I)) (K I) (case 1, 2)
+```
+
+综上:
+
+```
+ 2
+= S (λf.(S (K f))) (λf.(S (K f) I))
+= S (S (K S) (S (K K) I)) (S (S (K S) (S (K K) I)) (K I))
+```
+
+如果展开这个表达式, 我们最终又会得到邱奇数 2 的相同的表达式.
+
+### SK 组合子演算
+
+SKI 组合子演算还可以进一步简化. 我们可以通过`I = SKK`移除 I 组合子.
+我们可以将所有的 `I` 替换为 `SKK`.
+
+### ι 组合子
+
+SK 组合子仍不是最简的. 定义:
+
+```
+ι = λf.((f S) K)
+```
+
+我们有:
+
+```
+I = ιι
+K = ι(ιI) = ι(ι(ιι))
+S = ι(K) = ι(ι(ι(ιι)))
+```
+
+## 更多阅读:
+
+1. [A Tutorial Introduction to the Lambda Calculus](http://www.inf.fu-berlin.de/lehre/WS03/alpi/lambda.pdf)(英文)
+2. [Cornell CS 312 Recitation 26: The Lambda Calculus](https://courses.cs.cornell.edu/cs312/2008sp/recitations/rec26.html)(英文)
+3. [Wikipedia - Lambda Calculus](https://en.wikipedia.org/wiki/Lambda_calculus)(英文)
+4. [Wikipedia - SKI combinator calculus](https://en.wikipedia.org/wiki/SKI_combinator_calculus)(英文)
+5. [Wikipedia - Iota and Jot](https://en.wikipedia.org/wiki/Iota_and_Jot)(英文)
+6. [λ演算 - 维基百科,自由的百科全书](https://zh.wikipedia.org/wiki/SKI%E7%BB%84%E5%90%88%E5%AD%90%E6%BC%94%E7%AE%97)
+7. [SKI组合子演算 - 维基百科,自由的百科全书](https://zh.wikipedia.org/wiki/SKI%E7%BB%84%E5%90%88%E5%AD%90%E6%BC%94%E7%AE%97)
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/livescript-cn.html.markdown b/zh-cn/livescript-cn.html.markdown
index fea00bc1..cc7daab1 100644
--- a/zh-cn/livescript-cn.html.markdown
+++ b/zh-cn/livescript-cn.html.markdown
@@ -1,6 +1,6 @@
---
language: LiveScript
-filename: learnLivescript.ls
+filename: learnLivescript-cn.ls
contributors:
- ["Christina Whyte", "http://github.com/kurisuwhyte/"]
translators:
diff --git a/zh-cn/make-cn.html.markdown b/zh-cn/make-cn.html.markdown
new file mode 100644
index 00000000..641714ef
--- /dev/null
+++ b/zh-cn/make-cn.html.markdown
@@ -0,0 +1,263 @@
+---
+category: tool
+tool: make
+contributors:
+- ["Robert Steed", "https://github.com/robochat"]
+- ["Jichao Ouyang", "https://github.com/jcouyang"]
+translators:
+- ["Jichao Ouyang", "https://github.com/jcouyang"]
+filename: Makefile-cn
+lang: zh-cn
+---
+
+Makefile 用于定义如何创建目标文件, 比如如何从源码到可执行文件. 创建这一工具的目标是
+减少不必要的编译或者任务.是传说中的 Stuart Feldman 在 1976 年花了一个周末写出来的,
+而今仍然使用广泛, 特别是在 Unix 和 Linux 系统上.
+
+虽然每个语言可能都有相应的或多或少提供 make 的功能, 比如 ruby 的 rake, node 的 gulp, broccoli
+, scala 的 sbt 等等. 但是 make 的简洁与高效, 和只做一件事并做到极致的风格, 使其至今仍是无可替代的,
+甚至与其他构建工具一起使用也并无冲突.
+
+尽管有许多的分支和变体, 这篇文章针对是标准的 GNU make.
+
+```make
+# 这行表示注释
+
+# 文件名一定要叫 Makefile, 大小写区分, 使用 `make <target>` 生成 target
+# 如果想要取别的名字, 可以用 `make -f "filename" <target>`.
+
+# 重要的事情 - 只认识 TAB, 空格是不认的, 但是在 GNU Make 3.82 之后, 可以通过
+# 设置参数 .RECIPEPREFIX 进行修改
+
+#-----------------------------------------------------------------------
+# 初级
+#-----------------------------------------------------------------------
+
+# 创建一个 target 的规则非常简单
+# targets : prerequisites
+# recipe
+# …
+# prerequisites(依赖) 是可选的, recipe(做法) 也可以多个或者不给.
+
+# 下面这个任务没有给 prerequisites, 只会在目标文件 file0.txt 文件不存在时执行
+file0.txt:
+ echo "foo" > file0.txt
+ # 试试 `make file0.txt`
+ # 或者直接 `make`, 因为第一个任务是默认任务.
+ # 注意: 即使是这些注释, 如果前面有 TAB, 也会发送给 shell, 注意看 `make file0.txt` 输出
+
+# 如果提供 prerequisites, 则只有 prerequisites 比 target 新时会执行
+# 比如下面这个任务只有当 file0.txt 比 file1.txt 新时才会执行.
+file1.txt: file0.txt
+ cat file0.txt > file1.txt
+ # 这里跟shell里的命令式一模一样.
+ @cat file0.txt >> file1.txt
+ # @ 不会把命令打印到 stdout.
+ -@echo 'hello'
+ # - 意思是发生错误了也没关系.
+ # 试试 `make file1.txt` 吧.
+
+# targets 和 prerequisites 都可以是多个, 以空格分割
+file2.txt file3.txt: file0.txt file1.txt
+ touch file2.txt
+ touch file3.txt
+
+# 如果声明重复的 target, make 会给一个 warning, 后面会覆盖前面的
+# 比如重复定义 file2.txt 会得到这样的 warning
+# Makefile:46: warning: overriding commands for target `file2.txt'
+# Makefile:40: warning: ignoring old commands for target `file2.txt'
+file2.txt: file0.txt
+ touch file2.txt
+
+# 但是如果不定义任何 recipe, 就不会冲突, 只是多了依赖关系
+file2.txt: file0.txt file3.txt
+
+#-----------------------------------------------------------------------
+# Phony(假的) Targets
+#-----------------------------------------------------------------------
+
+# phony targets 意思是 tagets 并不是文件, 可以想象成一个任务的名字而已.
+# 因为不是文件, 无法比对是否有更新, 所以每次make都会执行.
+all: maker process
+
+# 依赖于 phony target 的 target 也会每次 make 都执行, 即使 target 是文件
+ex0.txt ex1.txt: maker
+
+# target 的声明顺序并不重要, 比如上面的 all 的依赖 maker 现在才声明
+maker:
+ touch ex0.txt ex1.txt
+
+# 如果定义的 phony target 与文件名重名, 可以用 .PHONY 显式地指明哪些 targets 是 phony
+.PHONY: all maker process
+# This is a special target. There are several others.
+
+# 常用的 phony target 有: all clean install ...
+
+#-----------------------------------------------------------------------
+# 变量与通配符
+#-----------------------------------------------------------------------
+
+process: file*.txt | dir/a.foo.b # 可以用通配符匹配多个文件作为prerequisites
+ @echo $^ # $^ 是 prerequisites
+ @echo $@ # $@ 代表 target, 如果 target 为多个, $@ 代表当前执行的那个
+ @echo $< # $< prerequisite 中的第一个
+ @echo $? # $? 需要更新的 prerequisite 文件列表
+ @echo $+ # $+ 所有依赖, 包括重复的
+ @echo $| # $| 竖线后面的 order-only prerequisites
+
+a.%.b:
+ @echo $* # $* match 的target % 那部分, 包括路径, 比如 `make dir/a.foo.b` 会打出 `dir/foo`
+
+# 即便分开定义依赖, $^ 依然能拿到
+process: ex1.txt file0.txt
+# 非常智能的, ex1.txt 会被找到, file0.txt 会被去重.
+
+#-----------------------------------------------------------------------
+# 模式匹配
+#-----------------------------------------------------------------------
+
+# 可以让 make 知道如何转换某些文件到其他格式
+# 比如 从 svg 到 png
+%.png: %.svg
+ inkscape --export-png $^
+
+# 一旦有需要 foo.png 这个任务就会运行
+
+# 路径会被忽略, 所以上面的 target 能匹配所有 png
+# 但是如果加了路径, make 会找到最接近的匹配, 如果
+# make small/foo.png (在这之前要先有 small/foo.svg 这个文件)
+# 则会匹配下面这个规则
+small/%.png: %.svg
+ inkscape --export-png --export-dpi 30 $^
+
+%.png: %.svg
+ @echo 重复定义会覆盖前面的, 现在 inkscape 没用了
+
+# make 已经有一些内置的规则, 比如从 *.c 到 *.o
+
+#-----------------------------------------------------------------------
+# 变量
+#-----------------------------------------------------------------------
+# 其实是宏 macro
+
+# 变量都是字符串类型, 下面这俩是一样一样的
+
+name = Ted
+name2="Sarah"
+
+echo:
+ @echo $(name)
+ @echo ${name2}
+ @echo $name # 这个会被蠢蠢的解析成 $(n)ame.
+ @echo \"$(name3)\" # 未声明的变量会被处理成空字符串.
+ @echo $(name4)
+ @echo $(name5)
+# 你可以通过4种方式设置变量.
+# 按以下顺序由高到低:
+# 1: 命令行参数. 比如试试 `make echo name3=JICHAO`
+# 2: Makefile 里面的
+# 3: shell 中的环境变量
+# 4: make 预设的一些变量
+
+name4 ?= Jean
+# 问号意思是如果 name4 被设置过了, 就不设置了.
+
+override name5 = David
+# 用 override 可以防止命令行参数设置的覆盖
+
+name4 +=grey
+# 用加号可以连接 (中间用空格分割).
+
+# 在依赖的地方设置变量
+echo: name2 = Sara2
+
+# 还有一些内置的变量
+echo_inbuilt:
+ echo $(CC)
+ echo ${CXX)}
+ echo $(FC)
+ echo ${CFLAGS)}
+ echo $(CPPFLAGS)
+ echo ${CXXFLAGS}
+ echo $(LDFLAGS)
+ echo ${LDLIBS}
+
+#-----------------------------------------------------------------------
+# 变量 2
+#-----------------------------------------------------------------------
+
+# 加个冒号可以声明 Simply expanded variables 即时扩展变量, 即只在声明时扩展一次
+# 之前的等号声明时 recursively expanded 递归扩展
+
+var := hello
+var2 := $(var) hello
+
+# 这些变量会在其引用的顺序求值
+# 比如 var3 声明时找不到 var4, var3 会扩展成 `and good luck`
+var3 := $(var4) and good luck
+# 但是一般的变量会在调用时递归扩展, 先扩展 var5, 再扩展 var4, 所以是正常的
+var5 = $(var4) and good luck
+var4 := good night
+
+echoSEV:
+ @echo $(var)
+ @echo $(var2)
+ @echo $(var3)
+ @echo $(var4)
+ @echo $(var5)
+
+#-----------------------------------------------------------------------
+# 函数
+#-----------------------------------------------------------------------
+
+# make 自带了一些函数.
+# wildcard 会将后面的通配符变成一串文件路径
+all_markdown:
+ @echo $(wildcard *.markdown)
+# patsubst 可以做替换, 比如下面会把所有 markdown
+# 后缀的文件重命名为 md 后缀
+substitue: *
+ @echo $(patsubst %.markdown,%.md,$* $^)
+
+# 函数调用格式是 $(func arg0,arg1,arg2...)
+
+# 试试
+ls: *
+ @echo $(filter %.txt, $^)
+ @echo $(notdir $^)
+ @echo $(join $(dir $^),$(notdir $^))
+
+#-----------------------------------------------------------------------
+# Directives
+#-----------------------------------------------------------------------
+
+# 可以用 include 引入别的 Makefile 文件
+# include foo.mk
+
+sport = tennis
+# 流程控制语句 (如if else 等等) 顶格写
+report:
+ifeq ($(sport),tennis)
+ @echo 'game, set, match'
+else
+ @echo "They think it's all over; it is now"
+endif
+
+# 还有 ifneq, ifdef, ifndef
+
+foo = true
+
+# 不只是 recipe, 还可以写在外面哟
+ifdef $(foo)
+bar = 'bar'
+endif
+
+hellobar:
+ @echo bar
+```
+
+### 资源
+
++ GNU Make 官方文档 [HTML](https://www.gnu.org/software/make/manual/) [PDF](https://www.gnu.org/software/make/manual/make.pdf)
++ [software carpentry tutorial](http://swcarpentry.github.io/make-novice/)
++ learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html)
diff --git a/zh-cn/markdown-cn.html.markdown b/zh-cn/markdown-cn.html.markdown
index 87ed46ad..707d6927 100644
--- a/zh-cn/markdown-cn.html.markdown
+++ b/zh-cn/markdown-cn.html.markdown
@@ -4,45 +4,74 @@ contributors:
- ["Dan Turkel", "http://danturkel.com/"]
translators:
- ["Fangzhou Chen","https://github.com/FZSS"]
+ - ["Luffy Zhong", "https://github.com/mengzhongshi"]
+ - ["Yuchen Liu", "https://github.com/smallg0at"]
filename: learnmarkdown-cn.md
lang: zh-cn
---
Markdown 由 John Gruber 于 2004年创立. 它旨在成为一门容易读写的语法结构,并可以便利地转换成 HTML(以及其他很多)格式。
-欢迎您多多反馈以及分支和请求合并。
-
-
-```markdown
-<!-- Markdown 是 HTML 的父集,所以任何 HTML 文件都是有效的 Markdown。
-这意味着我们可以在 Markdown 里使用任何 HTML 元素,比如注释元素,
+在不同的解析器中,Markdown 的实现方法有所不同。
+此教程会指出哪些特征是通用,哪一些只对某一解析器有效。
+
+- [HTML标签](#HTML标签)
+- [标题](#标题)
+- [文本样式](#文本样式)
+- [段落](#段落)
+- [列表](#列表)
+- [代码块](#代码块)
+- [水平线分隔](#水平线分隔)
+- [链接](#链接)
+- [图片](#图片)
+- [杂项](#杂项)
+
+## HTML标签
+Markdown 是 HTML 的父集,所以任何 HTML 文件都是有效的 Markdown。
+
+```md
+<!--这意味着我们可以在 Markdown 里使用任何 HTML 元素,比如注释元素,
且不会被 Markdown 解析器所影响。不过如果你在 Markdown 文件内创建了 HTML 元素,
你将无法在 HTML 元素的内容中使用 Markdown 语法。-->
+```
-<!-- 在不同的解析器中,Markdown 的实现方法有所不同。
-此教程会指出当某功能是否通用及是否只对某一解析器有效。 -->
+## 标题
-<!-- 标头 -->
-<!-- 通过在文本前加上不同数量的hash(#), 你可以创建相对应的 <h1>
-到 <h6> HTML元素。-->
+通过在文本前加上不同数量的hash(#), 你可以创建相对应的 `<h1>` 到 `<h6>` HTML元素。
+```md
# 这是一个 <h1>
## 这是一个 <h2>
### 这是一个 <h3>
#### 这是一个 <h4>
##### 这是一个 <h5>
###### 这是一个 <h6>
+```
-<!-- 对于 <h1> 和 <h2> 元素,Markdown 额外提供了两种添加方式。 -->
+实际效果(最终显示时会因设置而看起来不同):
+# 这是一个
+## 这也是一个
+### 这还是一个
+#### 这依旧是一个
+##### 这真的是一个
+###### 这...是一个
+
+
+对于 `<h1>` 和 `<h2>` 元素,Markdown 额外提供了两种添加方式。
+
+```md
这是一个 h1
=============
这是一个 h2
-------------
+```
-<!-- 简易文本样式 -->
-<!-- 文本的斜体,粗体,和删除线在 Markdown 中可以轻易地被实现。-->
+## 文本样式
+文本的*斜体*,**粗体**在 Markdown 中可以轻易实现。
+
+```md
*此文本为斜体。*
_此文本也是。_
@@ -52,40 +81,57 @@ __此文本也是__
***此文本是斜体加粗体。***
**_或者这样。_**
*__这个也是!__*
+```
-<!-- 在 GitHub 采用的 Markdown 中 -->
+GitHub 也支持 Markdown,在 GitHub 的 Markdown 解析器中,我们可以使用~~删除线~~:
+```md
~~此文本为删除线效果。~~
+```
+## 段落
-<!-- 单个段落由一句或多句邻近的句子组成,这些句子由一个或多个空格分隔。-->
+段落由一个句子或是多个中间没有空行的句子组成,每个段落由一个或是多个空行分隔开来。
+(注:部分解析器有无需空行就能换行的设置,这个主要看个人喜好)
+```md
这是第一段落. 这句话在同一个段落里,好玩么?
现在我是第二段落。
这句话也在第二段落!
+
这句话在第三段落!
+```
+
+如果你想插入一个 `<br />` 标签,你可以在段末加入两个以上的空格,然后另起一
+段。
-<!-- 如果你插入一个 HTML中的<br />标签,你可以在段末加入两个以上的空格,
-然后另起一段。-->
+(译者注:试了一下,很多解析器,并不需要空两个空格,直接换行就会添加一个`<br />`)
+```md
此段落结尾有两个空格(选中以显示)。
上文有一个 <br /> !
+```
+
+段落引用可由 `>` 字符轻松实现。
-<!-- 段落引用可由 > 字符轻松实现。-->
+> 对的很轻松
-> 这是一个段落引用. 你可以
-> 手动断开你的句子,然后在每句句子前面添加 “>” 字符。或者让你的句子变得很长,以至于他们自动得断开。
-> 只要你的文字以“>” 字符开头,两种方式无异。
+```md
+> 这是一个段落引用。 你可以
+> 手动断开你的句子,然后在每句句子前面添加 `>` 字符。或者让你的句子变得很长,以至于他们自动得换行。
+> 只要你的文字以 `>` 字符开头,两种方式无异。
-> 你也对文本进行
+> 你也可以对文本进行
>> 多层引用
> 这多机智啊!
+```
-<!-- 序列 -->
-<!-- 无序序列可由星号,加号或者减号来建立 -->
+## 列表
+- 无序列表可由星号,加号或者减号来创建
+```md
* 项目
* 项目
* 另一个项目
@@ -102,139 +148,211 @@ __此文本也是__
- 项目
- 最后一个项目
-<!-- 有序序列可由数字加点来实现 -->
+```
+
+有序序列可由数字加上点 `.` 来实现
+```md
1. 项目一
2. 项目二
3. 项目三
+```
-<!-- 即使你的标签数字有误,Markdown 依旧会呈现出正确的序号,
-不过这并不是一个好主意-->
+即使你的数字标签有误,Markdown 依旧会呈现出正确的序号,
+不过这并不是一个好主意
+```md
1. 项目一
1. 项目二
1. 项目三
-<!-- (此段与前例一模一样) -->
+```
+(此段与上面效果一模一样)
-<!-- 你也可以使用子序列 -->
+你也可以使用子列表
+```md
1. 项目一
2. 项目二
3. 项目三
* 子项目
* 子项目
4. 项目四
+```
-<!-- 代码段落 -->
-<!-- 代码段落(HTML中 <code>标签)可以由缩进四格(spaces)
-或者一个制表符(tab)实现-->
+你甚至可以使用任务列表,它将会生成 HTML 的选择框(checkboxes)标签。
+
+```md
+下面方框里包含 'x' 的列表,将会生成选中效果的选择框。
+- [ ] 任务一需要完成
+- [ ] 任务二需要完成
+下面这个选择框将会是选中状态
+- [x] 这个任务已经完成
+```
+- [ ] 你看完了这个任务(注:此选择框是无法直接更改的,即禁用状态。)
+## 代码块
+
+代码块(HTML中 `<code>` 标签)可以由缩进四格(spaces)
+或者一个制表符(tab)实现
+
+```md
This is code
- So is this
+ So is this
+```
-<!-- 在你的代码中,你仍然使用tab可以进行缩进操作 -->
+在你的代码中,你仍然使用tab(或者四个空格)可以进行缩进操作
+```md
my_array.each do |item|
puts item
end
+```
-<!-- 内联代码可由反引号 ` 实现 -->
+内联代码可由反引号 ` 实现
-John 甚至不知道 `go_to()` 方程是干嘛的!
+```md
+John 甚至不知道 `go_to()` 函数是干嘛的!
+```
-<!-- 在GitHub的 Markdown中,对于代码你可以使用特殊的语法 -->
+在GitHub的 Markdown(GitHub Flavored Markdown)解析器中,你可以使用特殊的语法表示代码块
-\`\`\`ruby <!-- 插入时记得移除反斜线, 仅留```ruby ! -->
+<pre>
+<code class="highlight">&#x60;&#x60;&#x60;ruby
def foobar
puts "Hello world!"
end
-\`\`\` <!-- 这里也是,移除反斜线,仅留 ``` -->
+&#x60;&#x60;&#x60;</code></pre>
+
+以上代码不需要缩进,而且 GitHub 会根据\`\`\`后指定的语言来进行语法高亮显示
-<!-- 以上代码不需要缩进,而且 GitHub 会根据```后表明的语言来进行语法高亮 -->
+## 水平线分隔
-<!-- 水平线 (<hr />) -->
-<!-- 水平线可由三个或以上的星号或者减号创建,可带可不带空格。 -->
+水平线(`<hr/>`)可由三个或以上的星号或是减号创建,它们之间可以带或不带空格
+```md
***
---
- - -
****************
-<!-- 链接 -->
-<!-- Markdown 最棒的地方就是简易的链接制作。链接文字放在中括号[]内,
-在随后的括弧()内加入url。-->
+下面这个就是示例
+```
+---
+
+## 链接
+Markdown 最棒的地方就是便捷的书写链接。把链接文字放在中括号[]内,
+在随后的括弧()内加入url就可以了。
+
+```md
[点我点我!](http://test.com/)
-<!-- 你也可以为链接加入一个标题:在括弧内使用引号 -->
+```
+
+你也可以在小括号内使用引号,为链接加上一个标题(title)
+```md
[点我点我!](http://test.com/ "连接到Test.com")
+```
+相对路径也可以有
-<!-- 相对路径也可以有 -->
-
+```md
[去 music](/music/).
+```
-<!-- Markdown同样支持引用样式的链接 -->
-
-[点此链接][link1]以获取更多信息!
-[看一看这个链接][foobar] 如果你愿意的话.
+Markdown同样支持引用形式的链接
-[link1]: http://test.com/ "Cool!"
-[foobar]: http://foobar.biz/ "Alright!"
+```md
+[点此链接][link1] 以获取更多信息!
+[看一看这个链接][foobar] 如果你愿意的话。
+[link1]: http://test.com/
+[foobar]: http://foobar.biz/
+```
-<!-- 链接的标题可以处于单引号中,括弧中或是被忽略。引用名可以在文档的任意何处,
-并且可以随意命名,只要名称不重复。-->
+对于引用形式,链接的标题可以处于单引号中,括弧中或是忽略。引用名可以在文档的任何地方,并且可以随意命名,只要名称不重复。
-<!-- “隐含式命名” 的功能可以让链接文字作为引用名 -->
+“隐含式命名” 的功能可以让链接文字作为引用名
+```md
[This][] is a link.
+[This]: http://thisisalink.com/
+```
-[this]: http://thisisalink.com/
-
-<!-- 但这并不常用 -->
-
-<!-- 图像 -->
-<!-- 图像与链接相似,只需在前添加一个感叹号 -->
+但这并不常用
-![这是我图像的悬停文本(alt text)](http://imgur.com/myimage.jpg "可选命名")
+## 图片
+图片与链接相似,只需在前添加一个感叹号
-<!-- 引用样式也同样起作用 -->
+```md
+![这是alt,请把鼠标放在图片上](http://imgur.com/myimage.jpg "这是title")
+```
-![这是我的悬停文本.][myimage]
+引用形式也同样起作用
-[myimage]: relative/urls/cool/image.jpg "在此输入标题"
+```md
+![这是alt][myimage]
+[myimage]: relative/urls/cool/image.jpg
+```
-<!-- 杂项 -->
-<!-- 自动链接 -->
+## 杂项
+### 自动链接
+```md
<http://testwebsite.com/> 与
[http://testwebsite.com/](http://testwebsite.com/) 等同
+```
-<!-- 电子邮件的自动链接 -->
+### 电子邮件的自动链接
+```md
<foo@bar.com>
+```
-<!-- 转义字符 -->
+### 转义字符
+```md
我希望 *将这段文字置于星号之间* 但是我不希望它被
-斜体化, 所以我就: \*这段置文字于星号之间\*。
+斜体化, 这么做: \*这段置文字于星号之间\*。
+```
+对比一下:*将这段文字置于星号之间* 和 \*将这段文字置于星号之间\*
-<!-- 表格 -->
-<!-- 表格只被 GitHub 的 Markdown 支持,并且有一点笨重,但如果你真的要用的话: -->
+### 键盘上的功能键
-| 第一列 | 第二列 | 第三列 |
-| :---------- | :------: | ----------: |
-| 左对齐 | 居个中 | 右对齐 |
-| 某某某 | 某某某 | 某某某 |
+在 GitHub 的 Markdown 中,你可以使用 `<kbd>` 标签来表示功能键。
-<!-- 或者, 同样的 -->
+```md
+你的电脑死机了?试试
+<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd>
+```
+<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Del</kbd>
-第一列 | 第二列 | 第三列
-:-- | :-: | --:
-这太丑了 | 药不能 | 停
+(译注:可能由于网站本身样式问题,效果不明显)
-<!-- 结束! -->
+### 表格
+下面示例的表格长这样:
+
+| 第一列 | 第二列 | 第三列 |
+| :----------- | :-------: | ----------: |
+| 我是左对齐 | 居个中 | 右对齐 |
+| 注意 | 冒 | 号 |
+
+工整一点的写法是这样的:
+
+```md
+| 第一列 | 第二列 | 第三列 |
+| :----------- | :-------: | ----------: |
+| 我是左对齐 | 居个中 | 右对齐 |
+| 注意 | 冒 | 号 |
```
+好吧,强行对齐字符是很难的。但是,至少比下面这种写法好一点——
+
+```md
+我是超级超级长的第一列 | 第二列 | 第三列
+:-- | :-: | --:
+这真的太丑了 | 药不能 | 停!!!!
+```
+真的是*看着令人头晕*
+
更多信息, 请于[此处](http://daringfireball.net/projects/Markdown/syntax)参见 John Gruber 关于语法的官方帖子,及于[此处](https://github.com/adam-p/Markdown-here/wiki/Markdown-Cheatsheet) 参见 Adam Pritchard 的摘要笔记。
diff --git a/zh-cn/matlab-cn.html.markdown b/zh-cn/matlab-cn.html.markdown
index 77ba765a..d215755c 100644
--- a/zh-cn/matlab-cn.html.markdown
+++ b/zh-cn/matlab-cn.html.markdown
@@ -1,16 +1,21 @@
---
language: Matlab
+filename: matlab-cn.m
contributors:
- ["mendozao", "http://github.com/mendozao"]
- ["jamesscottbrown", "http://jamesscottbrown.com"]
translators:
- ["sunxb10", "https://github.com/sunxb10"]
lang: zh-cn
+
---
-MATLAB 是 MATrix LABoratory (矩阵实验室)的缩写,它是一种功能强大的数值计算语言,在工程和数学领域中应用广泛。
+MATLAB 是 MATrix LABoratory(矩阵实验室)的缩写。
+它是一种功能强大的数值计算语言,在工程和数学领域中应用广泛。
-如果您有任何需要反馈或交流的内容,请联系本教程作者[@the_ozzinator](https://twitter.com/the_ozzinator)、[osvaldo.t.mendoza@gmail.com](mailto:osvaldo.t.mendoza@gmail.com)。
+如果您有任何需要反馈或交流的内容,请联系本教程作者:
+[@the_ozzinator](https://twitter.com/the_ozzinator)
+或 [osvaldo.t.mendoza@gmail.com](mailto:osvaldo.t.mendoza@gmail.com)。
```matlab
% 以百分号作为注释符
@@ -43,7 +48,7 @@ edit('myfunction.m') % 在编辑器中打开指定函数或脚本
type('myfunction.m') % 在命令窗口中打印指定函数或脚本的源码
profile on % 打开 profile 代码分析工具
-profile of % 关闭 profile 代码分析工具
+profile off % 关闭 profile 代码分析工具
profile viewer % 查看 profile 代码分析工具的分析结果
help command % 在命令窗口中显示指定命令的帮助文档
@@ -111,7 +116,7 @@ b(2) % ans = 符
% 元组(cell 数组)
a = {'one', 'two', 'three'}
a(1) % ans = 'one' - 返回一个元组
-char(a(1)) % ans = one - 返回一个字符串
+a{1} % ans = one - 返回一个字符串
% 结构体
@@ -208,8 +213,8 @@ size(A) % 返回矩阵的行数和列数,ans = 3 3
A(1, :) =[] % 删除矩阵的第 1 行
A(:, 1) =[] % 删除矩阵的第 1 列
-transpose(A) % 矩阵转置,等价于 A'
-ctranspose(A) % 矩阵的共轭转置(对矩阵中的每个元素取共轭复数)
+transpose(A) % 矩阵(非共轭)转置,等价于 A.' (注意!有个点)
+ctranspose(A) % 矩阵的共轭转置(对矩阵中的每个元素取共轭复数),等价于 A'
% 元素运算 vs. 矩阵运算
@@ -217,18 +222,20 @@ ctranspose(A) % 矩阵的共轭转置(对矩阵中的每个元素取共轭复
% 在运算符加上英文句点就是对矩阵中的元素进行元素计算
% 示例如下:
A * B % 矩阵乘法,要求 A 的列数等于 B 的行数
-A .* B % 元素乘法,要求 A 和 B 形状一致(A 的行数等于 B 的行数, A 的列数等于 B 的列数)
-% 元素乘法的结果是与 A 和 B 形状一致的矩阵,其每个元素等于 A 对应位置的元素乘 B 对应位置的元素
+A .* B % 元素乘法,要求 A 和 B 形状一致,即两矩阵行列数完全一致
+ % 元素乘法的结果是与 A 和 B 形状一致的矩阵
+ % 其每个元素等于 A 对应位置的元素乘 B 对应位置的元素
% 以下函数中,函数名以 m 结尾的执行矩阵运算,其余执行元素运算:
exp(A) % 对矩阵中每个元素做指数运算
expm(A) % 对矩阵整体做指数运算
sqrt(A) % 对矩阵中每个元素做开方运算
-sqrtm(A) % 对矩阵整体做开放运算(即试图求出一个矩阵,该矩阵与自身的乘积等于 A 矩阵)
+sqrtm(A) % 对矩阵整体做开方运算(即试图求出一个矩阵,该矩阵与自身的乘积等于 A 矩阵)
% 绘图
-x = 0:.10:2*pi; % 生成一向量,其元素从 0 开始,以 0.1 的间隔一直递增到 2*pi(pi 就是圆周率)
+x = 0:0.1:2*pi; % 生成一向量,其元素从 0 开始,以 0.1 的间隔一直递增到 2*pi
+ % 其中 pi 为圆周率
y = sin(x);
plot(x,y)
xlabel('x axis')
@@ -286,7 +293,10 @@ clf clear % 清除图形窗口中的图像,并重置图像属性
% 也可以用 gcf 函数返回当前图像的句柄
h = plot(x, y); % 在创建图像时显式地保存图像句柄
set(h, 'Color', 'r')
-% 颜色代码:'y' 黄色,'m' 洋红色,'c' 青色,'r' 红色,'g' 绿色,'b' 蓝色,'w' 白色,'k' 黑色
+% 颜色代码:
+% 'y' 黄色,'m' 洋红,'c' 青色
+% 'r' 红色,'g' 绿色,'b' 蓝色
+% 'w' 白色,'k' 黑色
set(h, 'Color', [0.5, 0.5, 0.4])
% 也可以使用 RGB 值指定颜色
set(h, 'LineStyle', '--')
@@ -326,7 +336,8 @@ load('myFileName.mat') % 将指定文件中的变量载入到当前工作空间
% 与脚本文件类似,同样以 .m 作为后缀名
% 但函数文件可以接受用户输入的参数并返回运算结果
% 并且函数拥有自己的工作空间(变量域),不必担心变量名称冲突
-% 函数文件的名称应当与其所定义的函数的名称一致(比如下面例子中函数文件就应命名为 double_input.m)
+% 函数文件的名称应当与其所定义的函数的名称一致
+% 比如下面例子中函数文件就应命名为 double_input.m
% 使用 'help double_input.m' 可返回函数定义中第一行注释信息
function output = double_input(x)
% double_input(x) 返回 x 的 2 倍
@@ -461,14 +472,16 @@ triu(x) % 返回 x 的上三角这部分
tril(x) % 返回 x 的下三角这部分
cross(A, B) % 返回 A 和 B 的叉积(矢量积、外积)
dot(A, B) % 返回 A 和 B 的点积(数量积、内积),要求 A 和 B 必须等长
-transpose(A) % A 的转置,等价于 A'
+transpose(A) % 矩阵(非共轭)转置,等价于 A.' (注意!有个点)
fliplr(A) % 将一个矩阵左右翻转
flipud(A) % 将一个矩阵上下翻转
% 矩阵分解
-[L, U, P] = lu(A) % LU 分解:PA = LU,L 是下三角阵,U 是上三角阵,P 是置换阵
-[P, D] = eig(A) % 特征值分解:AP = PD,D 是由特征值构成的对角阵,P 的各列就是对应的特征向量
-[U, S, V] = svd(X) % 奇异值分解:XV = US,U 和 V 是酉矩阵,S 是由奇异值构成的半正定实数对角阵
+[L, U, P] = lu(A) % LU 分解:PA = LU,L 是下三角阵,U 是上三角阵,P 是置换阵
+[P, D] = eig(A) % 特征值分解:AP = PD
+ % D 是由特征值构成的对角阵,P 的各列就是对应的特征向量
+[U, S, V] = svd(X) % 奇异值分解:XV = US
+ % U 和 V 是酉矩阵,S 是由奇异值构成的半正定实数对角阵
% 常用向量函数
max % 最大值
@@ -487,5 +500,5 @@ perms(x) % x 元素的全排列
## 相关资料
-* 官方网页:[http://http://www.mathworks.com/products/matlab/](http://www.mathworks.com/products/matlab/)
-* 官方论坛:[http://www.mathworks.com/matlabcentral/answers/](http://www.mathworks.com/matlabcentral/answers/)
+* 官方网页:[MATLAB - 技术计算语言 - MATLAB & Simulink](https://ww2.mathworks.cn/products/matlab.html)
+* 官方论坛:[MATLAB Answers - MATLAB Central](https://ww2.mathworks.cn/matlabcentral/answers/)
diff --git a/zh-cn/opencv-cn.html.markdown b/zh-cn/opencv-cn.html.markdown
new file mode 100644
index 00000000..06b997d5
--- /dev/null
+++ b/zh-cn/opencv-cn.html.markdown
@@ -0,0 +1,145 @@
+---
+category: tool
+tool: OpenCV
+filename: learnopencv.py
+contributors:
+ - ["Yogesh Ojha", "http://github.com/yogeshojha"]
+translators:
+ - ["GengchenXU", "https://github.com/GengchenXU"]
+lang: zh-cn
+---
+### Opencv
+
+Opencv(开源计算机视觉)是一个编程功能库,主要面向实时计算机视觉。最初由英特尔开发,后来由Willow Garage,然后Itseez(后来被英特尔收购)支持。Opencv 目前支持多种语言,如C++、Python、Java 等
+
+#### 安装
+有关在计算机上安装 OpenCV,请参阅这些文章。
+
+* Windows 安装说明: [https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.html#install-opencv-python-in-windows]()
+* Mac 安装说明 (High Sierra): [https://medium.com/@nuwanprabhath/installing-opencv-in-macos-high-sierra-for-python-3-89c79f0a246a]()
+* Linux 安装说明 (Ubuntu 18.04): [https://www.pyimagesearch.com/2018/05/28/ubuntu-18-04-how-to-install-opencv]()
+
+### 在这里,我们将专注于 OpenCV 的 python 实现
+
+```python
+# OpenCV读取图片
+import cv2
+img = cv2.imread('cat.jpg')
+
+# 显示图片
+# imshow() 函数被用来显示图片
+cv2.imshow('Image',img)
+# 第一个参数是窗口的标题,第二个参数是image
+# 如果你得到错误,对象类型为None,你的图像路径可能是错误的。请重新检查图像包
+cv2.waitKey(0)
+# waitKey() 是一个键盘绑定函数,参数以毫秒为单位。对于GUI事件,必须使用waitKey()函数。
+
+# 保存图片
+cv2.imwrite('catgray.png',img)
+# 第一个参数是文件名,第二个参数是图像
+
+# 转换图像灰度
+gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+
+# 从摄像头捕捉视频
+cap = cv2.VideoCapture(0)
+#0 是你的相机,如果你有多台相机,你需要输入他们的id
+while(True):
+ # 一帧一帧地获取
+ _, frame = cap.read()
+ cv2.imshow('Frame',frame)
+ # 当用户按下q ->退出
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+# 相机必须释放
+cap.release()
+
+# 在文件中播放视频
+cap = cv2.VideoCapture('movie.mp4')
+while(cap.isOpened()):
+ _, frame = cap.read()
+ # 灰度播放视频
+ gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
+ cv2.imshow('frame',gray)
+ if cv2.waitKey(1) & 0xFF == ord('q'):
+ break
+cap.release()
+
+# 在OpenCV中画线
+# cv2.line(img,(x,y),(x1,y1),(color->r,g,b->0 to 255),thickness)(注 color颜色rgb参数 thickness粗细)
+cv2.line(img,(0,0),(511,511),(255,0,0),5)
+
+# 画矩形
+# cv2.rectangle(img,(x,y),(x1,y1),(color->r,g,b->0 to 255),thickness)
+# 粗细= -1用于填充矩形
+cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)
+
+# 画圆
+cv2.circle(img,(xCenter,yCenter), radius, (color->r,g,b->0 to 255), thickness)
+cv2.circle(img,(200,90), 100, (0,0,255), -1)
+
+# 画椭圆
+cv2.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
+
+# 在图像上增加文字
+cv2.putText(img,"Hello World!!!", (x,y), cv2.FONT_HERSHEY_SIMPLEX, 2, 255)
+
+# 合成图像
+img1 = cv2.imread('cat.png')
+img2 = cv2.imread('openCV.jpg')
+dst = cv2.addWeighted(img1,0.5,img2,0.5,0)
+
+# 阈值图像
+# 二进制阈值
+_,thresImg = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
+# Adaptive Thresholding
+adapThres = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,2)
+
+# 模糊的形象
+# 高斯模糊
+blur = cv2.GaussianBlur(img,(5,5),0)
+# 模糊中值
+medianBlur = cv2.medianBlur(img,5)
+
+# Canny 边缘检测
+img = cv2.imread('cat.jpg',0)
+edges = cv2.Canny(img,100,200)
+
+# 用Haar Cascades进行人脸检测
+# 下载 Haar Cascades 在 https://github.com/opencv/opencv/blob/master/data/haarcascades/
+import cv2
+import numpy as np
+face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
+eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
+
+img = cv2.imread('human.jpg')
+gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
+
+aces = face_cascade.detectMultiScale(gray, 1.3, 5)
+for (x,y,w,h) in faces:
+ cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
+ roi_gray = gray[y:y+h, x:x+w]
+ roi_color = img[y:y+h, x:x+w]
+ eyes = eye_cascade.detectMultiScale(roi_gray)
+ for (ex,ey,ew,eh) in eyes:
+ cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
+
+cv2.imshow('img',img)
+cv2.waitKey(0)
+
+cv2.destroyAllWindows()
+# destroyAllWindows() destroys all windows.
+# 如果您希望销毁特定窗口,请传递您创建的窗口的确切名称。
+```
+
+### 进一步阅读:
+
+* Download Cascade from [https://github.com/opencv/opencv/blob/master/data/haarcascades]()
+* OpenCV 绘图函数 [https://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html]()
+* 最新的语言参考 [https://opencv.org]()
+* 更多的资源 [https://en.wikipedia.org/wiki/OpenCV]()
+* 优秀的的 OpenCV 教程
+ * [https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html]()
+ * [https://realpython.com/python-opencv-color-spaces]()
+ * [https://pyimagesearch.com]()
+ * [https://www.learnopencv.com]()
diff --git a/zh-cn/perl-cn.html.markdown b/zh-cn/perl-cn.html.markdown
index 5b0d6179..4421da6e 100644
--- a/zh-cn/perl-cn.html.markdown
+++ b/zh-cn/perl-cn.html.markdown
@@ -10,9 +10,9 @@ translators:
lang: zh-cn
---
-Perl 5是一个功能强大、特性齐全的编程语言,有25年的历史。
+Perl 是一个功能强大、特性齐全的编程语言,有25年的历史。
-Perl 5可以在包括便携式设备和大型机的超过100个平台上运行,既适用于快速原型构建,也适用于大型项目开发。
+Perl 可以在包括便携式设备和大型机的超过100个平台上运行,既适用于快速原型构建,也适用于大型项目开发。
```perl
# 单行注释以#号开头
diff --git a/zh-cn/powershell-cn.html.markdown b/zh-cn/powershell-cn.html.markdown
new file mode 100644
index 00000000..6ab34e9f
--- /dev/null
+++ b/zh-cn/powershell-cn.html.markdown
@@ -0,0 +1,325 @@
+---
+category: tool
+tool: powershell
+contributors:
+ - ["Wouter Van Schandevijl", "https://github.com/laoujin"]
+translators:
+ - ["Feng Gao", "https://github.com/gaufung"]
+filename: LearnPowershell-cn.ps1
+lang: zh-cn
+---
+
+PowerShell 是 Windows 平台下的脚本语言同时也是配置管理框架,它是建立在微软 .Net Framework 之上,Windows 7 以及之后版本都内置 Poweshell。下面的示例中都是 PoweShell 脚本的一部分或者直接能够在 Shell 交互窗口中执行。
+
+与 Bash 最大的不同是你大部分操作的东西是对象而不是普通的文本。
+
+[延伸阅读](https://technet.microsoft.com/en-us/library/bb978526.aspx)
+
+如果你不确定你的环境,执行如下操作:
+
+```powershell
+Get-ExecutionPolicy -List
+Set-ExecutionPolicy AllSigned
+# Execution Policy 包含以下:
+# - Restricted: 不会运行脚本。
+# - RemoteSigned: 只会运行受信任的发行商下载的脚本。
+# - AllSigned: 运行需要被信任发行商签名的脚本。
+# - Unrestricted: 运行所有脚本
+help about_Execution_Policies # 查看更多信息
+
+# 当前 PowerShell 版本
+$PSVersionTable
+```
+
+获取帮助
+
+```powershell
+# 查找命令
+Get-Command about_* # 别名: gcm
+Get-Command -Verb Add
+Get-Alias ps
+Get-Alias -Definition Get-Process
+
+Get-Help ps | less # 别名: help
+ps | Get-Member # 别名: gm
+
+Show-Command Get-EventLog # GUI 填充参数
+
+Update-Help # 管理员运行
+```
+
+接下来是教程
+
+```powershell
+# 正如你看到的,每一行开头是 # 都是注释
+
+# 简单的 Hello World 实例
+echo Hello world!
+# echo 是 Write-Output (cmdlet) 的别名
+# 大部分 cmdlet 和函数都遵循 "动词-名词" 命名规则。
+
+# 每个命令都从新的一行开始或者是一个分号
+echo 'This is the first line'; echo 'This is the second line'
+
+# 声明一个变量如下:
+$aString="Some string"
+# 或者像这样:
+$aNumber = 5 -as [double]
+$aList = 1,2,3,4,5
+$anEmptyList = @()
+$aString = $aList -join '--' # 也包含 join 方法
+$aHashtable = @{name1='val1'; name2='val2'}
+
+# 使用变量:
+echo $aString
+echo "Interpolation: $aString"
+echo "$aString has length of $($aString.Length)"
+echo '$aString'
+echo @"
+This is a Here-String
+$aString
+"@
+# 注意 ' (单引号) 不是变量的一部分
+# 在这里字符串也可以是单引号
+
+# 内置变量:
+# 下面是一些有用的内置变量,比如:
+echo "Booleans: $TRUE and $FALSE"
+echo "Empty value: $NULL"
+echo "Last program's return value: $?"
+echo "Exit code of last run Windows-based program: $LastExitCode"
+echo "The last token in the last line received by the session: $$"
+echo "The first token: $^"
+echo "Script's PID: $PID"
+echo "Full path of current script directory: $PSScriptRoot"
+echo 'Full path of current script: ' + $MyInvocation.MyCommand.Path
+echo "FUll path of current directory: $Pwd"
+echo "Bound arguments in a function, script or code block: $PSBoundParameters"
+echo "Unbound arguments: $($Args -join ', ')."
+# 更多的内置类型: `help about_Automatic_Variables`
+
+# 内联其他文件 (点操作符)
+. .\otherScriptName.ps1
+
+
+### 控制流
+# 下面是条件判断结构
+if ($Age -is [string]) {
+ echo 'But.. $Age cannot be a string!'
+} elseif ($Age -lt 12 -and $Age -gt 0) {
+ echo 'Child (Less than 12. Greater than 0)'
+} else {
+ echo 'Adult'
+}
+
+# Switch 语句比其他语言更强大
+$val = "20"
+switch($val) {
+ { $_ -eq 42 } { "The answer equals 42"; break }
+ '20' { "Exactly 20"; break }
+ { $_ -like 's*' } { "Case insensitive"; break }
+ { $_ -clike 's*'} { "clike, ceq, cne for case sensitive"; break }
+ { $_ -notmatch '^.*$'} { "Regex matching. cnotmatch, cnotlike, ..."; break }
+ { 'x' -contains 'x'} { "FALSE! -contains is for lists!"; break }
+ default { "Others" }
+}
+
+# 经典的 For 循环
+for($i = 1; $i -le 10; $i++) {
+ "Loop number $i"
+}
+# 或者可以更简洁
+1..10 | % { "Loop number $_" }
+
+# PowerShell 还提供其他循环方式
+foreach ($var in 'val1','val2','val3') { echo $var }
+# while () {}
+# do {} while ()
+# do {} until ()
+
+# 异常处理
+try {} catch {} finally {}
+try {} catch [System.NullReferenceException] {
+ echo $_.Exception | Format-List -Force
+}
+
+
+### Providers
+# 列出当前目录下的文件和子目录
+ls # 或者 `dir`
+cd ~ # 回到主目录
+
+Get-Alias ls # -> Get-ChildItem
+# 这些 cmdlet 有更加通用的名称,因为它不仅仅只操作当前目录,这一点和其他脚本语言不同。
+cd HKCU: # 跳转 HKEY_CURRENT_USER 注册表中的值
+
+# 获取当前会话中的提供者
+Get-PSProvider
+
+
+### 管道
+# Cmdlets 中的参数用来控制它们的行为:
+Get-ChildItem -Filter *.txt -Name # 获取所有 txt 文件名。
+# 需要输入足够多的参数来确保没有歧义。
+ls -fi *.txt -n # -f 是不可以的因为 -Force 同样存在。
+# 使用 `Get-Help Get-ChildItem -Full` 来查看全部参数。
+
+# 之前 cmdlet 获取的结果输出可以作为一下个输入。
+# `$_` 指代当前管道处理的对象。
+ls | Where-Object { $_.Name -match 'c' } | Export-CSV export.txt
+ls | ? { $_.Name -match 'c' } | ConvertTo-HTML | Out-File export.html
+
+# 如果对管道的对象感到疑惑,使用 `Get-Member` 来查看该对象的可使用的方法和属性。
+ls | Get-Member
+Get-Date | gm
+
+# ` 是行连续标识符,或者在每一行结尾添加一个 |
+Get-Process | Sort-Object ID -Descending | Select-Object -First 10 Name,ID,VM `
+ | Stop-Process -WhatIf
+
+Get-EventLog Application -After (Get-Date).AddHours(-2) | Format-List
+
+# 使用 % 作为 ForEach-Object 的简称。
+(a,b,c) | ForEach-Object `
+ -Begin { "Starting"; $counter = 0 } `
+ -Process { "Processing $_"; $counter++ } `
+ -End { "Finishing: $counter" }
+
+# Get-Process 返回包含三列的表
+# 第三列是使用 2 位精度数值表示 VM 属性
+# 计算出来的列也可以表示更多的信息:
+# `@{name='lbl';expression={$_}`
+ps | Format-Table ID,Name,@{n='VM(MB)';e={'{0:n2}' -f ($_.VM / 1MB)}} -autoSize
+
+
+### 函数
+# [string] 注记是可选的。
+function foo([string]$name) {
+ echo "Hey $name, have a function"
+}
+
+# 调用你的函数
+foo "Say my name"
+
+# 函数可以包含命名参数、参数的注记和可解析的文档
+<#
+.SYNOPSIS
+Setup a new website
+.DESCRIPTION
+Creates everything your new website needs for much win
+.PARAMETER siteName
+The name for the new website
+.EXAMPLE
+New-Website -Name FancySite -Po 5000
+New-Website SiteWithDefaultPort
+New-Website siteName 2000 # ERROR! Port argument could not be validated
+('name1','name2') | New-Website -Verbose
+#>
+function New-Website() {
+ [CmdletBinding()]
+ param (
+ [Parameter(ValueFromPipeline=$true, Mandatory=$true)]
+ [Alias('name')]
+ [string]$siteName,
+ [ValidateSet(3000,5000,8000)]
+ [int]$port = 3000
+ )
+ BEGIN { Write-Verbose 'Creating new website(s)' }
+ PROCESS { echo "name: $siteName, port: $port" }
+ END { Write-Verbose 'Website(s) created' }
+}
+
+
+### 都是 .NET
+# PS 中的字符串事实上就是 .NET 的 System.String 类型
+# 所有 .NET 方法和属性都可用
+'string'.ToUpper().Replace('G', 'ggg')
+# 或者更加 PowerShell 一点
+'string'.ToUpper() -replace 'G', 'ggg'
+
+# 不确定这样的话 .NET 方法如何调用
+'string' | gm
+
+# 调用静态 .NET 方法的语法:
+[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
+
+# 注意 .NET 方法调用必须使用括号,然而 PS 函数调用不能使用括号;
+# 如果你调用 cmdlet/PS 函数使用了括号,就相当于传递了参数列表。
+$writer = New-Object System.IO.StreamWriter($path, $true)
+$writer.Write([Environment]::NewLine)
+$writer.Dispose()
+
+### IO
+# 从输入读入一个值
+$Name = Read-Host "What's your name?"
+echo "Hello, $Name!"
+[int]$Age = Read-Host "What's your age?"
+
+# Test-Path, Split-Path, Join-Path, Resolve-Path
+# Get-Content filename # 返回字符串数组 string[]
+# Set-Content, Add-Content, Clear-Content
+Get-Command ConvertTo-*,ConvertFrom-*
+
+
+### 有用的东西
+# 更新 PATH
+$env:PATH = [System.Environment]::GetEnvironmentVariable("Path", "Machine") +
+ ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
+
+# 找到 Python 的 PATH
+$env:PATH.Split(";") | Where-Object { $_ -like "*python*"}
+
+# 改变工作目录而不需要记住之前的路径
+Push-Location c:\temp # 改变工作目录至 c:\temp
+Pop-Location # 改变到之前的工作目录
+# 别名: pushd 和 popd
+
+# 在下载之后解除目录阻塞
+Get-ChildItem -Recurse | Unblock-File
+
+# Windows 资源管理器打开当前目录
+ii .
+
+# 按任意键退出
+$host.UI.RawUI.ReadKey()
+return
+
+# 创建快捷方式
+$WshShell = New-Object -comObject WScript.Shell
+$Shortcut = $WshShell.CreateShortcut($link)
+$Shortcut.TargetPath = $file
+$Shortcut.WorkingDirectory = Split-Path $file
+$Shortcut.Save()
+```
+
+
+配置你的 PowerShell
+
+```powershell
+# $Profile 是文件 `Microsoft.PowerShell_profile.ps1` 完整路径
+# 下面所有的代码都在 PS 会话开始的时候执行
+if (-not (Test-Path $Profile)) {
+ New-Item -Type file -Path $Profile -Force
+ notepad $Profile
+}
+# 更多信息: `help about_profiles`
+# 更多关于 Shell 有用的信息,确保查看下面的 PSReadLine 项目。
+```
+
+更多项目
+
+* [Channel9](https://channel9.msdn.com/Search?term=powershell%20pipeline#ch9Search&lang-en=en) PowerShell 教程
+* [PSGet](https://github.com/psget/psget) PowerShell NuGet 包
+* [PSReadLine](https://github.com/lzybkr/PSReadLine/) 仿 bash 按行读取( Window10 默认包含)
+* [Posh-Git](https://github.com/dahlbyk/posh-git/) Git 命令提示 (推荐!)
+* [PSake](https://github.com/psake/psake) 自动构建工作
+* [Pester](https://github.com/pester/Pester) BDD 测试框架
+* [Jump-Location](https://github.com/tkellogg/Jump-Location) Poweshell 中 `cd` 来跳转目录
+* [PowerShell Community Extensions](http://pscx.codeplex.com/) (废弃)
+
+尚未涉及
+
+* WMI: Windows 管理规范 (Get-CimInstance)
+* 多任务: Start-Job -scriptBlock {...},
+* 代码签名
+* 远程 (Enter-PSSession/Exit-PSSession; Invoke-Command)
diff --git a/zh-cn/pyqt-cn.html.markdown b/zh-cn/pyqt-cn.html.markdown
new file mode 100644
index 00000000..55e5bbe3
--- /dev/null
+++ b/zh-cn/pyqt-cn.html.markdown
@@ -0,0 +1,80 @@
+---
+category: tool
+tool: PyQT
+filename: learnpyqt.py
+contributors:
+ - ["Nathan Hughes", "https://github.com/sirsharpest"]
+translators:
+ - ["kdxcxs", "https://github.com/kdxcxs"]
+ - ["lsvih", "https://github.com/lsvih"]
+ - ["imlonghao", "https://github.com/imlonghao"]
+lang: zh-cn
+---
+
+**Qt** 是一个用 C++ 实现的著名跨平台软件开发框架。只需少量更改有时候甚至不需要更改代码就能在多个软硬件平台上运行,同时拥有原生应用程序的功能和速度。
+
+
+以下内容改编自 [Aleksey Kholovchuk](https://github.com/vortexxx192) 编写的 C++ 版 QT 简介,并用 pyqt 重构原文代码,实现了部分相同的功能。
+
+```python
+import sys
+from PyQt4 import QtGui
+
+def window():
+ # 创建应用对象
+ app = QtGui.QApplication(sys.argv)
+ # 创建一个 widget,作为 label 的父控件
+ w = QtGui.QWidget()
+ # 在 widget 中添加一个 label 子控件
+ b = QtGui.QLabel(w)
+ # 设置 label 的文字
+ b.setText("Hello World!")
+ # 设置 widget 的尺寸和位置
+ w.setGeometry(100, 100, 200, 50)
+ b.move(50, 20)
+ # 设置窗口的标题
+ w.setWindowTitle("PyQt")
+ # 显示 widget 及其所有子控件
+ w.show()
+ # 下面让程序跑起来,这行代码会启动事件循环并阻塞直到应用程序退出。
+ sys.exit(app.exec_())
+if __name__ == '__main__':
+ window()
+```
+
+为了运用 pyqt 中一些更高级的功能,我们需要开始学习使用其他控件。下文演示了如何弹出对话框,该对话框在用户确认操作或输入信息等情况下经常用到。
+
+```Python
+import sys
+from PyQt4.QtGui import *
+from PyQt4.QtCore import *
+def window():
+ app = QApplication(sys.argv)
+ w = QWidget()
+ # 创建一个按钮并添加到 widget 控件 w
+ b = QPushButton(w)
+ b.setText("Press me")
+ b.move(50, 50)
+ # 当按钮 b 被点击时调用 showdialog 函数
+ # 注意函数调用时没有“()”,这样函数就能以对象的方式传入而非传入执行它所得到的返回值
+ # 更多关于 pyqt 函数调用、传参等的内容见 pyqt 的信号机制
+ b.clicked.connect(showdialog)
+ w.setWindowTitle("PyQt Dialog")
+ w.show()
+ sys.exit(app.exec_())
+
+# 对话框窗口创建函数
+# 当窗口中的按钮被点击时退出本程序
+def showdialog():
+ d = QDialog()
+ b1 = QPushButton("ok", d)
+ b1.move(50, 50)
+ d.setWindowTitle("Dialog")
+ # 这里的模态实现了在对话框弹出时阻塞程序同时屏蔽父窗口
+ d.setWindowModality(Qt.ApplicationModal)
+ # 当按钮被点击时整个进程将会结束
+ b1.clicked.connect(sys.exit)
+ d.exec_()
+if __name__ == '__main__':
+ window()
+```
diff --git a/zh-cn/python-cn.html.markdown b/zh-cn/python-cn.html.markdown
index deb94cdc..6c5556fc 100644
--- a/zh-cn/python-cn.html.markdown
+++ b/zh-cn/python-cn.html.markdown
@@ -1,302 +1,342 @@
---
-language: python
+language: Python
contributors:
- - ["Louie Dinh", "http://ldinh.ca"]
+ - ["Louie Dinh", "http://pythonpracticeprojects.com"]
+ - ["Steven Basart", "http://github.com/xksteven"]
+ - ["Andre Polykanine", "https://github.com/Oire"]
translators:
- - ["Chenbo Li", "http://binarythink.net"]
-filename: learnpython-zh.py
+ - ["Geoff Liu", "http://geoffliu.me"]
+filename: learnpython-cn.py
lang: zh-cn
---
-Python 由 Guido Van Rossum 在90年代初创建。 它现在是最流行的语言之一
-我喜爱python是因为它有极为清晰的语法,甚至可以说,它就是可以执行的伪代码
+Python 是由吉多·范罗苏姆(Guido Van Rossum)在 90 年代早期设计。
+它是如今最常用的编程语言之一。它的语法简洁且优美,几乎就是可执行的伪代码。
-很欢迎来自您的反馈,你可以在[@louiedinh](http://twitter.com/louiedinh) 和 louiedinh [at] [google's email service] 这里找到我
+欢迎大家斧正。英文版原作 Louie Dinh [@louiedinh](http://twitter.com/louiedinh)
+邮箱 louiedinh [at] [谷歌的信箱服务]。中文翻译 Geoff Liu。
-注意: 这篇文章针对的版本是Python 2.7,但大多也可使用于其他Python 2的版本
-如果是Python 3,请在网络上寻找其他教程
+注意:这篇教程是基于 Python 3 写的。如果你想学旧版 Python 2,我们特别有[另一篇教程](http://learnxinyminutes.com/docs/pythonlegacy/)。
```python
-# 单行注释
-""" 多行字符串可以用
- 三个引号包裹,不过这也可以被当做
- 多行注释
+# 用井字符开头的是单行注释
+
+""" 多行字符串用三个引号
+ 包裹,也常被用来做多
+ 行注释
"""
####################################################
-## 1. 原始数据类型和操作符
+## 1. 原始数据类型和运算符
####################################################
-# 数字类型
+# 整数
3 # => 3
-# 简单的算数
+# 算术没有什么出乎意料的
1 + 1 # => 2
8 - 1 # => 7
10 * 2 # => 20
-35 / 5 # => 7
-# 整数的除法会自动取整
-5 / 2 # => 2
+# 但是除法例外,会自动转换成浮点数
+35 / 5 # => 7.0
+5 / 3 # => 1.6666666666666667
+
+# 整数除法的结果都是向下取整
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # 浮点数也可以
+-5 // 3 # => -2
+-5.0 // 3.0 # => -2.0
+
+# 浮点数的运算结果也是浮点数
+3 * 2.0 # => 6.0
+
+# 模除
+7 % 3 # => 1
-# 要做精确的除法,我们需要引入浮点数
-2.0 # 浮点数
-11.0 / 4.0 # => 2.75 精确多了
+# x的y次方
+2**4 # => 16
-# 括号具有最高优先级
+# 用括号决定优先级
(1 + 3) * 2 # => 8
-# 布尔值也是基本的数据类型
+# 布尔值
True
False
-# 用 not 来取非
+# 用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
-# 字符串通过 " 或 ' 括起来
-"This is a string."
-'This is also a string.'
+# 字符串用单引双引都可以
+"这是个字符串"
+'这也是个字符串'
-# 字符串通过加号拼接
+# 用加号连接字符串
"Hello " + "world!" # => "Hello world!"
-# 字符串可以被视为字符的列表
+# 字符串可以被当作字符列表
"This is a string"[0] # => 'T'
-# % 可以用来格式化字符串
-"%s can be %s" % ("strings", "interpolated")
+# 用.format来格式化字符串
+"{} can be {}".format("strings", "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"
-# 也可以用 format 方法来格式化字符串
-# 推荐使用这个方法
-"{0} can be {1}".format("strings", "formatted")
-# 也可以用变量名代替数字
-"{name} wants to eat {food}".format(name="Bob", food="lasagna")
+# 如果不想数参数,可以用关键字
+"{name} wants to eat {food}".format(name="Bob", food="lasagna")
+# => "Bob wants to eat lasagna"
-# None 是对象
+# 如果你的Python3程序也要在Python2.5以下环境运行,也可以用老式的格式化语法
+"%s can be %s the %s way" % ("strings", "interpolated", "old")
+
+# None是一个对象
None # => None
-# 不要用相等 `==` 符号来和None进行比较
-# 要用 `is`
+# 当与None进行比较时不要用 ==,要用is。is是用来比较两个变量是否指向同一个对象。
"etc" is None # => False
None is None # => True
-# 'is' 可以用来比较对象的相等性
-# 这个操作符在比较原始数据时没多少用,但是比较对象时必不可少
-
-# None, 0, 和空字符串都被算作 False
-# 其他的均为 True
-0 == False # => True
-"" == False # => True
+# None,0,空字符串,空列表,空字典都算是False
+# 所有其他值都是True
+bool(0) # => False
+bool("") # => False
+bool([]) # => False
+bool({}) # => False
####################################################
## 2. 变量和集合
####################################################
-# 很方便的输出
-print "I'm Python. Nice to meet you!"
+# print是内置的打印函数
+print("I'm Python. Nice to meet you!")
-
-# 给变量赋值前不需要事先声明
-some_var = 5 # 一般建议使用小写字母和下划线组合来做为变量名
+# 在给变量赋值前不用提前声明
+# 传统的变量命名是小写,用下划线分隔单词
+some_var = 5
some_var # => 5
# 访问未赋值的变量会抛出异常
-# 可以查看控制流程一节来了解如何异常处理
-some_other_var # 抛出 NameError
+# 参考流程控制一段来学习异常处理
+some_unknown_var # 抛出NameError
-# if 语句可以作为表达式来使用
-"yahoo!" if 3 > 2 else 2 # => "yahoo!"
-
-# 列表用来保存序列
+# 用列表(list)储存序列
li = []
-# 可以直接初始化列表
+# 创建列表时也可以同时赋给元素
other_li = [4, 5, 6]
-# 在列表末尾添加元素
-li.append(1) # li 现在是 [1]
-li.append(2) # li 现在是 [1, 2]
-li.append(4) # li 现在是 [1, 2, 4]
-li.append(3) # li 现在是 [1, 2, 4, 3]
-# 移除列表末尾元素
-li.pop() # => 3 li 现在是 [1, 2, 4]
-# 重新加进去
-li.append(3) # li is now [1, 2, 4, 3] again.
-
-# 像其他语言访问数组一样访问列表
+# 用append在列表最后追加元素
+li.append(1) # li现在是[1]
+li.append(2) # li现在是[1, 2]
+li.append(4) # li现在是[1, 2, 4]
+li.append(3) # li现在是[1, 2, 4, 3]
+# 用pop从列表尾部删除
+li.pop() # => 3 且li现在是[1, 2, 4]
+# 把3再放回去
+li.append(3) # li变回[1, 2, 4, 3]
+
+# 列表存取跟数组一样
li[0] # => 1
-# 访问最后一个元素
+# 取出最后一个元素
li[-1] # => 3
-# 越界会抛出异常
-li[4] # 抛出越界异常
+# 越界存取会造成IndexError
+li[4] # 抛出IndexError
-# 切片语法需要用到列表的索引访问
-# 可以看做数学之中左闭右开区间
+# 列表有切割语法
li[1:3] # => [2, 4]
-# 省略开头的元素
+# 取尾
li[2:] # => [4, 3]
-# 省略末尾的元素
+# 取头
li[:3] # => [1, 2, 4]
+# 隔一个取一个
+li[::2] # =>[1, 4]
+# 倒排列表
+li[::-1] # => [3, 4, 2, 1]
+# 可以用三个参数的任何组合来构建切割
+# li[始:终:步伐]
-# 删除特定元素
-del li[2] # li 现在是 [1, 2, 3]
+# 用del删除任何一个元素
+del li[2] # li is now [1, 2, 3]
-# 合并列表
-li + other_li # => [1, 2, 3, 4, 5, 6] - 并不会不改变这两个列表
+# 列表可以相加
+# 注意:li和other_li的值都不变
+li + other_li # => [1, 2, 3, 4, 5, 6]
-# 通过拼接来合并列表
-li.extend(other_li) # li 是 [1, 2, 3, 4, 5, 6]
+# 用extend拼接列表
+li.extend(other_li) # li现在是[1, 2, 3, 4, 5, 6]
-# 用 in 来返回元素是否在列表中
-1 in li # => True
+# 用in测试列表是否包含值
+1 in li # => True
-# 返回列表长度
-len(li) # => 6
+# 用len取列表长度
+len(li) # => 6
-# 元组类似于列表,但它是不可改变的
+# 元组是不可改变的序列
tup = (1, 2, 3)
-tup[0] # => 1
-tup[0] = 3 # 类型错误
-
-# 对于大多数的列表操作,也适用于元组
-len(tup) # => 3
-tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
-tup[:2] # => (1, 2)
-2 in tup # => True
-
-# 你可以将元组解包赋给多个变量
-a, b, c = (1, 2, 3) # a 是 1,b 是 2,c 是 3
-# 如果不加括号,将会被自动视为元组
+tup[0] # => 1
+tup[0] = 3 # 抛出TypeError
+
+# 列表允许的操作元组大都可以
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# 可以把元组合列表解包,赋值给变量
+a, b, c = (1, 2, 3) # 现在a是1,b是2,c是3
+# 元组周围的括号是可以省略的
d, e, f = 4, 5, 6
-# 现在我们可以看看交换两个数字是多么容易的事
-e, d = d, e # d 是 5,e 是 4
+# 交换两个变量的值就这么简单
+e, d = d, e # 现在d是5,e是4
-# 字典用来储存映射关系
+# 用字典表达映射关系
empty_dict = {}
-# 字典初始化
+# 初始化的字典
filled_dict = {"one": 1, "two": 2, "three": 3}
-# 字典也用中括号访问元素
-filled_dict["one"] # => 1
+# 用[]取值
+filled_dict["one"] # => 1
+
+
+# 用 keys 获得所有的键。
+# 因为 keys 返回一个可迭代对象,所以在这里把结果包在 list 里。我们下面会详细介绍可迭代。
+# 注意:字典键的顺序是不定的,你得到的结果可能和以下不同。
+list(filled_dict.keys()) # => ["three", "two", "one"]
-# 把所有的键保存在列表中
-filled_dict.keys() # => ["three", "two", "one"]
-# 键的顺序并不是唯一的,得到的不一定是这个顺序
-# 把所有的值保存在列表中
-filled_dict.values() # => [3, 2, 1]
-# 和键的顺序相同
+# 用values获得所有的值。跟keys一样,要用list包起来,顺序也可能不同。
+list(filled_dict.values()) # => [3, 2, 1]
-# 判断一个键是否存在
-"one" in filled_dict # => True
-1 in filled_dict # => False
-# 查询一个不存在的键会抛出 KeyError
-filled_dict["four"] # KeyError
+# 用in测试一个字典是否包含一个键
+"one" in filled_dict # => True
+1 in filled_dict # => False
-# 用 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
+# 访问不存在的键会导致KeyError
+filled_dict["four"] # KeyError
-# setdefault 是一个更安全的添加字典元素的方法
-filled_dict.setdefault("five", 5) # filled_dict["five"] 的值为 5
-filled_dict.setdefault("five", 6) # filled_dict["five"] 的值仍然是 5
+# 用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"] # 从filled_dict中把one删除
+
+
+# 用set表达集合
empty_set = set()
-# 初始化一个集合
-some_set = set([1, 2, 2, 3, 4]) # some_set 现在是 set([1, 2, 3, 4])
+# 初始化一个集合,语法跟字典相似。
+some_set = {1, 1, 2, 2, 3, 4} # some_set现在是{1, 2, 3, 4}
-# Python 2.7 之后,大括号可以用来表示集合
-filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+# 可以把集合赋值于变量
+filled_set = some_set
-# 向集合添加元素
-filled_set.add(5) # filled_set 现在是 {1, 2, 3, 4, 5}
+# 为集合添加元素
+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 # => {3, 4, 5}
-# 用 | 来计算集合的并
-filled_set | other_set # => {1, 2, 3, 4, 5, 6}
+# | 取并集
+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}
-# 用 in 来判断元素是否存在于集合中
-2 in filled_set # => True
-10 in filled_set # => False
+# in 测试集合是否包含元素
+2 in filled_set # => True
+10 in filled_set # => False
####################################################
-## 3. 控制流程
+## 3. 流程控制和迭代器
####################################################
-# 新建一个变量
+# 先随便定义一个变量
some_var = 5
-# 这是个 if 语句,在 python 中缩进是很重要的。
-# 下面的代码片段将会输出 "some var is smaller than 10"
+# 这是个if语句。注意缩进在Python里是有意义的
+# 印出"some_var比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."
+ print("some_var比10大")
+elif some_var < 10: # elif句是可选的
+ print("some_var比10小")
+else: # else也是可选的
+ print("some_var就是10")
"""
-用for循环遍历列表
-输出:
+用for循环语句遍历列表
+打印:
dog is a mammal
cat is a mammal
mouse is a mammal
"""
for animal in ["dog", "cat", "mouse"]:
- # 你可以用 % 来格式化字符串
- print "%s is a mammal" % animal
+ print("{} is a mammal".format(animal))
"""
-`range(number)` 返回从0到给定数字的列表
-输出:
+"range(number)"返回数字列表从0到给的数字
+打印:
0
1
2
3
"""
for i in range(4):
- print i
+ print(i)
"""
-while 循环
-输出:
+while循环直到条件不满足
+打印:
0
1
2
@@ -304,173 +344,289 @@ while 循环
"""
x = 0
while x < 4:
- print x
- x += 1 # x = x + 1 的简写
-
-# 用 try/except 块来处理异常
+ print(x)
+ x += 1 # x = x + 1 的简写
-# Python 2.6 及以上适用:
+# 用try/except块处理异常状况
try:
- # 用 raise 来抛出异常
+ # 用raise抛出异常
raise IndexError("This is an index error")
except IndexError as e:
- pass # pass 就是什么都不做,不过通常这里会做一些恢复工作
+ pass # pass是无操作,但是应该在这里处理错误
+except (TypeError, NameError):
+ pass # 可以同时处理不同类的错误
+else: # else语句是可选的,必须在所有的except之后
+ print("All good!") # 只有当try运行完没有错误的时候这句才会运行
+
+
+# Python提供一个叫做可迭代(iterable)的基本抽象。一个可迭代对象是可以被当作序列
+# 的对象。比如说上面range返回的对象就是可迭代的。
+
+filled_dict = {"one": 1, "two": 2, "three": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) # => dict_keys(['one', 'two', 'three']),是一个实现可迭代接口的对象
+
+# 可迭代对象可以遍历
+for i in our_iterable:
+ print(i) # 打印 one, two, three
+
+# 但是不可以随机访问
+our_iterable[1] # 抛出TypeError
+
+# 可迭代对象知道怎么生成迭代器
+our_iterator = iter(our_iterable)
+
+# 迭代器是一个可以记住遍历的位置的对象
+# 用__next__可以取得下一个元素
+our_iterator.__next__() # => "one"
+
+# 再一次调取__next__时会记得位置
+our_iterator.__next__() # => "two"
+our_iterator.__next__() # => "three"
+
+# 当迭代器所有元素都取出后,会抛出StopIteration
+our_iterator.__next__() # 抛出StopIteration
+
+# 可以用list一次取出迭代器所有的元素
+list(filled_dict.keys()) # => Returns ["one", "two", "three"]
+
####################################################
## 4. 函数
####################################################
-# 用 def 来新建函数
+# 用def定义新函数
def add(x, y):
- print "x is %s and y is %s" % (x, y)
- return x + y # 通过 return 来返回值
+ 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(5, 6) # => 印出"x is 5 and y is 6"并且返回11
-# 通过关键字赋值来调用函数
-add(y=6, x=5) # 顺序是无所谓的
+# 也可以用关键字参数来调用函数
+add(y=6, x=5) # 关键字参数可以用任何顺序
-# 我们也可以定义接受多个变量的函数,这些变量是按照顺序排列的
+
+# 我们可以定义一个可变参数函数
def varargs(*args):
return args
-varargs(1, 2, 3) # => (1,2,3)
+varargs(1, 2, 3) # => (1, 2, 3)
-# 我们也可以定义接受多个变量的函数,这些变量是按照关键字排列的
+# 我们也可以定义一个关键字可变参数函数
def keyword_args(**kwargs):
return kwargs
-# 实际效果:
-keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
+# 我们来看看结果是什么:
+keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
+
-# 你也可以同时将一个函数定义成两种形式
+# 这两种可变参数可以混着用
def all_the_args(*args, **kwargs):
- print args
- print kwargs
+ print(args)
+ print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) prints:
(1, 2)
{"a": 3, "b": 4}
"""
-# 当调用函数的时候,我们也可以进行相反的操作,把元组和字典展开为参数
+# 调用可变参数函数时可以做跟上面相反的,用*展开序列,用**展开字典。
args = (1, 2, 3, 4)
kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # 等价于 foo(1, 2, 3, 4)
-all_the_args(**kwargs) # 等价于 foo(a=3, b=4)
-all_the_args(*args, **kwargs) # 等价于 foo(1, 2, 3, 4, a=3, b=4)
+all_the_args(*args) # 相当于 all_the_args(1, 2, 3, 4)
+all_the_args(**kwargs) # 相当于 all_the_args(a=3, b=4)
+all_the_args(*args, **kwargs) # 相当于 all_the_args(1, 2, 3, 4, a=3, b=4)
+
+
+# 函数作用域
+x = 5
+
+def setX(num):
+ # 局部作用域的x和全局域的x是不同的
+ x = num # => 43
+ print (x) # => 43
-# 函数在 python 中是一等公民
+def setGlobalX(num):
+ global x
+ print (x) # => 5
+ x = num # 现在全局域的x被赋值
+ print (x) # => 6
+
+setX(43)
+setGlobalX(6)
+
+
+# 函数在Python是一等公民
def create_adder(x):
def adder(y):
return x + y
return adder
add_10 = create_adder(10)
-add_10(3) # => 13
+add_10(3) # => 13
-# 匿名函数
-(lambda x: x > 2)(3) # => True
+# 也有匿名函数
+(lambda x: x > 2)(3) # => True
-# 内置高阶函数
-map(add_10, [1, 2, 3]) # => [11, 12, 13]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+# 内置的高阶函数
+map(add_10, [1, 2, 3]) # => [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
-# 可以用列表方法来对高阶函数进行更巧妙的引用
+# 用列表推导式可以简化映射和过滤。列表推导式的返回值是另一个列表。
[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
-[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
+[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
####################################################
## 5. 类
####################################################
-# 我们新建的类是从 object 类中继承的
+
+# 定义一个继承object的类
class Human(object):
- # 类属性,由所有类的对象共享
+ # 类属性,被所有此类的实例共用。
species = "H. sapiens"
- # 基本构造函数
+ # 构造方法,当实例被初始化时被调用。注意名字前后的双下划线,这是表明这个属
+ # 性或方法对Python有特殊意义,但是允许用户自行定义。你自己取名时不应该用这
+ # 种格式。
def __init__(self, name):
- # 将参数赋给对象成员属性
+ # Assign the argument to the instance's name attribute
self.name = name
- # 成员方法,参数要有 self
+ # 实例方法,第一个参数总是self,就是这个实例对象
def say(self, msg):
- return "%s: %s" % (self.name, msg)
+ return "{name}: {message}".format(name=self.name, message=msg)
- # 类方法由所有类的对象共享
- # 这类方法在调用时,会把类本身传给第一个参数
+ # 类方法,被所有此类的实例共用。第一个参数是这个类对象。
@classmethod
def get_species(cls):
return cls.species
- # 静态方法是不需要类和对象的引用就可以调用的方法
+ # 静态方法。调用时没有实例或类的绑定。
@staticmethod
def grunt():
return "*grunt*"
-# 实例化一个类
+# 构造一个实例
i = Human(name="Ian")
-print i.say("hi") # 输出 "Ian: hi"
+print(i.say("hi")) # 印出 "Ian: hi"
j = Human("Joel")
-print j.say("hello") # 输出 "Joel: hello"
+print(j.say("hello")) # 印出 "Joel: hello"
-# 访问类的方法
-i.get_species() # => "H. sapiens"
+# 调用一个类方法
+i.get_species() # => "H. sapiens"
-# 改变共享属性
+# 改一个共用的类属性
Human.species = "H. neanderthalensis"
-i.get_species() # => "H. neanderthalensis"
-j.get_species() # => "H. neanderthalensis"
+i.get_species() # => "H. neanderthalensis"
+j.get_species() # => "H. neanderthalensis"
-# 访问静态变量
-Human.grunt() # => "*grunt*"
+# 调用静态方法
+Human.grunt() # => "*grunt*"
####################################################
## 6. 模块
####################################################
-# 我们可以导入其他模块
+# 用import导入模块
import math
-print math.sqrt(16) # => 4
+print(math.sqrt(16)) # => 4.0
-# 我们也可以从一个模块中导入特定的函数
+# 也可以从模块中导入个别值
from math import ceil, floor
-print ceil(3.7) # => 4.0
-print floor(3.7) # => 3.0
+print(ceil(3.7)) # => 4.0
+print(floor(3.7)) # => 3.0
-# 从模块中导入所有的函数
-# 警告:不推荐使用
+# 可以导入一个模块中所有值
+# 警告:不建议这么做
from math import *
-# 简写模块名
+# 如此缩写模块名字
import math as m
-math.sqrt(16) == m.sqrt(16) # => True
+math.sqrt(16) == m.sqrt(16) # => True
-# Python的模块其实只是普通的python文件
-# 你也可以创建自己的模块,并且导入它们
-# 模块的名字就和文件的名字相同
+# Python模块其实就是普通的Python文件。你可以自己写,然后导入,
+# 模块的名字就是文件的名字。
-# 也可以通过下面的方法查看模块中有什么属性和方法
+# 你可以这样列出一个模块里所有的值
import math
dir(math)
+####################################################
+## 7. 高级用法
+####################################################
+
+# 用生成器(generators)方便地写惰性运算
+def double_numbers(iterable):
+ for i in iterable:
+ yield i + i
+
+# 生成器只有在需要时才计算下一个值。它们每一次循环只生成一个值,而不是把所有的
+# 值全部算好。
+#
+# range的返回值也是一个生成器,不然一个1到900000000的列表会花很多时间和内存。
+#
+# 如果你想用一个Python的关键字当作变量名,可以加一个下划线来区分。
+range_ = range(1, 900000000)
+# 当找到一个 >=30 的结果就会停
+# 这意味着 `double_numbers` 不会生成大于30的数。
+for i in double_numbers(range_):
+ print(i)
+ if i >= 30:
+ break
+
+
+# 装饰器(decorators)
+# 这个例子中,beg装饰say
+# beg会先调用say。如果返回的say_please为真,beg会改变返回的字符串。
+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 :(
```
-## 更多阅读
+## 想继续学吗?
-希望学到更多?试试下面的链接:
+### 线上免费材料(英文)
* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
* [Dive Into Python](http://www.diveintopython.net/)
-* [The Official Docs](http://docs.python.org/2.6/)
+* [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 Module of the Week](http://pymotw.com/2/)
+* [Python Module of the Week](http://pymotw.com/3/)
+* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
+
+### 书籍(也是英文)
+
+* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
+* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
+* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
+
diff --git a/zh-cn/python3-cn.html.markdown b/zh-cn/python3-cn.html.markdown
deleted file mode 100644
index 76455a46..00000000
--- a/zh-cn/python3-cn.html.markdown
+++ /dev/null
@@ -1,629 +0,0 @@
----
-language: python3
-contributors:
- - ["Louie Dinh", "http://pythonpracticeprojects.com"]
- - ["Steven Basart", "http://github.com/xksteven"]
- - ["Andre Polykanine", "https://github.com/Oire"]
-translators:
- - ["Geoff Liu", "http://geoffliu.me"]
-filename: learnpython3-cn.py
-lang: zh-cn
----
-
-Python是由吉多·范罗苏姆(Guido Van Rossum)在90年代早期设计。它是如今最常用的编程
-语言之一。它的语法简洁且优美,几乎就是可执行的伪代码。
-
-欢迎大家斧正。英文版原作Louie Dinh [@louiedinh](http://twitter.com/louiedinh)
-或着Email louiedinh [at] [谷歌的信箱服务]。中文翻译Geoff Liu。
-
-注意:这篇教程是特别为Python3写的。如果你想学旧版Python2,我们特别有另一篇教程。
-
-```python
-
-# 用井字符开头的是单行注释
-
-""" 多行字符串用三个引号
- 包裹,也常被用来做多
- 行注释
-"""
-
-####################################################
-## 1. 原始数据类型和运算符
-####################################################
-
-# 整数
-3 # => 3
-
-# 算术没有什么出乎意料的
-1 + 1 # => 2
-8 - 1 # => 7
-10 * 2 # => 20
-
-# 但是除法例外,会自动转换成浮点数
-35 / 5 # => 7.0
-5 / 3 # => 1.6666666666666667
-
-# 整数除法的结果都是向下取整
-5 // 3 # => 1
-5.0 // 3.0 # => 1.0 # 浮点数也可以
--5 // 3 # => -2
--5.0 // 3.0 # => -2.0
-
-# 浮点数的运算结果也是浮点数
-3 * 2.0 # => 6.0
-
-# 模除
-7 % 3 # => 1
-
-# 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
-
-# 字符串用单引双引都可以
-"这是个字符串"
-'这也是个字符串'
-
-# 用加号连接字符串
-"Hello " + "world!" # => "Hello world!"
-
-# 字符串可以被当作字符列表
-"This is a string"[0] # => 'T'
-
-# 用.format来格式化字符串
-"{} can be {}".format("strings", "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"
-
-# 如果你的Python3程序也要在Python2.5以下环境运行,也可以用老式的格式化语法
-"%s can be %s the %s way" % ("strings", "interpolated", "old")
-
-# None是一个对象
-None # => None
-
-# 当与None进行比较时不要用 ==,要用is。is是用来比较两个变量是否指向同一个对象。
-"etc" is None # => False
-None is None # => True
-
-# None,0,空字符串,空列表,空字典都算是False
-# 所有其他值都是True
-bool(0) # => False
-bool("") # => False
-bool([]) #=> False
-bool({}) #=> False
-
-
-####################################################
-## 2. 变量和集合
-####################################################
-
-# print是内置的打印函数
-print("I'm Python. Nice to meet you!")
-
-# 在给变量赋值前不用提前声明
-# 传统的变量命名是小写,用下划线分隔单词
-some_var = 5
-some_var # => 5
-
-# 访问未赋值的变量会抛出异常
-# 参考流程控制一段来学习异常处理
-some_unknown_var # 抛出NameError
-
-# 用列表(list)储存序列
-li = []
-# 创建列表时也可以同时赋给元素
-other_li = [4, 5, 6]
-
-# 用append在列表最后追加元素
-li.append(1) # li现在是[1]
-li.append(2) # li现在是[1, 2]
-li.append(4) # li现在是[1, 2, 4]
-li.append(3) # li现在是[1, 2, 4, 3]
-# 用pop从列表尾部删除
-li.pop() # => 3 且li现在是[1, 2, 4]
-# 把3再放回去
-li.append(3) # li变回[1, 2, 4, 3]
-
-# 列表存取跟数组一样
-li[0] # => 1
-# 取出最后一个元素
-li[-1] # => 3
-
-# 越界存取会造成IndexError
-li[4] # 抛出IndexError
-
-# 列表有切割语法
-li[1:3] # => [2, 4]
-# 取尾
-li[2:] # => [4, 3]
-# 取头
-li[:3] # => [1, 2, 4]
-# 隔一个取一个
-li[::2] # =>[1, 4]
-# 倒排列表
-li[::-1] # => [3, 4, 2, 1]
-# 可以用三个参数的任何组合来构建切割
-# li[始:终:步伐]
-
-# 用del删除任何一个元素
-del li[2] # li is now [1, 2, 3]
-
-# 列表可以相加
-# 注意: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
-
-# 列表允许的操作元组大都可以
-len(tup) # => 3
-tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
-tup[:2] # => (1, 2)
-2 in tup # => True
-
-# 可以把元组合列表解包,赋值给变量
-a, b, c = (1, 2, 3) # 现在a是1,b是2,c是3
-# 元组周围的括号是可以省略的
-d, e, f = 4, 5, 6
-# 交换两个变量的值就这么简单
-e, d = d, e # 现在d是5,e是4
-
-
-# 用字典表达映射关系
-empty_dict = {}
-# 初始化的字典
-filled_dict = {"one": 1, "two": 2, "three": 3}
-
-# 用[]取值
-filled_dict["one"] # => 1
-
-
-# 用keys获得所有的键。因为keys返回一个可迭代对象,所以在这里把结果包在list里。我们下面会详细介绍可迭代。
-# 注意:字典键的顺序是不定的,你得到的结果可能和以下不同。
-list(filled_dict.keys()) # => ["three", "two", "one"]
-
-
-# 用values获得所有的值。跟keys一样,要用list包起来,顺序也可能不同。
-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"] # 从filled_dict中把one删除
-
-
-# 用set表达集合
-empty_set = set()
-# 初始化一个集合,语法跟字典相似。
-some_set = {1, 1, 2, 2, 3, 4} # some_set现在是{1, 2, 3, 4}
-
-# 可以把集合赋值于变量
-filled_set = some_set
-
-# 为集合添加元素
-filled_set.add(5) # filled_set现在是{1, 2, 3, 4, 5}
-
-# & 取交集
-other_set = {3, 4, 5, 6}
-filled_set & other_set # => {3, 4, 5}
-
-# | 取并集
-filled_set | other_set # => {1, 2, 3, 4, 5, 6}
-
-# - 取补集
-{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
-
-# in 测试集合是否包含元素
-2 in filled_set # => True
-10 in filled_set # => False
-
-
-####################################################
-## 3. 流程控制和迭代器
-####################################################
-
-# 先随便定义一个变量
-some_var = 5
-
-# 这是个if语句。注意缩进在Python里是有意义的
-# 印出"some_var比10小"
-if some_var > 10:
- print("some_var比10大")
-elif some_var < 10: # elif句是可选的
- print("some_var比10小")
-else: # else也是可选的
- print("some_var就是10")
-
-
-"""
-用for循环语句遍历列表
-打印:
- dog is a mammal
- cat is a mammal
- mouse is a mammal
-"""
-for animal in ["dog", "cat", "mouse"]:
- print("{} is a mammal".format(animal))
-
-"""
-"range(number)"返回数字列表从0到给的数字
-打印:
- 0
- 1
- 2
- 3
-"""
-for i in range(4):
- print(i)
-
-"""
-while循环直到条件不满足
-打印:
- 0
- 1
- 2
- 3
-"""
-x = 0
-while x < 4:
- print(x)
- x += 1 # x = x + 1 的简写
-
-# 用try/except块处理异常状况
-try:
- # 用raise抛出异常
- raise IndexError("This is an index error")
-except IndexError as e:
- pass # pass是无操作,但是应该在这里处理错误
-except (TypeError, NameError):
- pass # 可以同时处理不同类的错误
-else: # else语句是可选的,必须在所有的except之后
- print("All good!") # 只有当try运行完没有错误的时候这句才会运行
-
-
-# Python提供一个叫做可迭代(iterable)的基本抽象。一个可迭代对象是可以被当作序列
-# 的对象。比如说上面range返回的对象就是可迭代的。
-
-filled_dict = {"one": 1, "two": 2, "three": 3}
-our_iterable = filled_dict.keys()
-print(our_iterable) # => range(1,10) 是一个实现可迭代接口的对象
-
-# 可迭代对象可以遍历
-for i in our_iterable:
- print(i) # 打印 one, two, three
-
-# 但是不可以随机访问
-our_iterable[1] # 抛出TypeError
-
-# 可迭代对象知道怎么生成迭代器
-our_iterator = iter(our_iterable)
-
-# 迭代器是一个可以记住遍历的位置的对象
-# 用__next__可以取得下一个元素
-our_iterator.__next__() #=> "one"
-
-# 再一次调取__next__时会记得位置
-our_iterator.__next__() #=> "two"
-our_iterator.__next__() #=> "three"
-
-# 当迭代器所有元素都取出后,会抛出StopIteration
-our_iterator.__next__() # 抛出StopIteration
-
-# 可以用list一次取出迭代器所有的元素
-list(filled_dict.keys()) #=> Returns ["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 = (1, 2, 3, 4)
-kwargs = {"a": 3, "b": 4}
-all_the_args(*args) # 相当于 foo(1, 2, 3, 4)
-all_the_args(**kwargs) # 相当于 foo(a=3, b=4)
-all_the_args(*args, **kwargs) # 相当于 foo(1, 2, 3, 4, a=3, b=4)
-
-
-# 函数作用域
-x = 5
-
-def setX(num):
- # 局部作用域的x和全局域的x是不同的
- x = num # => 43
- print (x) # => 43
-
-def setGlobalX(num):
- global x
- print (x) # => 5
- x = num # 现在全局域的x被赋值
- print (x) # => 6
-
-setX(43)
-setGlobalX(6)
-
-
-# 函数在Python是一等公民
-def create_adder(x):
- def adder(y):
- return x + y
- return adder
-
-add_10 = create_adder(10)
-add_10(3) # => 13
-
-# 也有匿名函数
-(lambda x: x > 2)(3) # => True
-
-# 内置的高阶函数
-map(add_10, [1, 2, 3]) # => [11, 12, 13]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
-
-# 用列表推导式可以简化映射和过滤。列表推导式的返回值是另一个列表。
-[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
-[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
-
-####################################################
-## 5. 类
-####################################################
-
-
-# 定义一个继承object的类
-class Human(object):
-
- # 类属性,被所有此类的实例共用。
- species = "H. sapiens"
-
- # 构造方法,当实例被初始化时被调用。注意名字前后的双下划线,这是表明这个属
- # 性或方法对Python有特殊意义,但是允许用户自行定义。你自己取名时不应该用这
- # 种格式。
- def __init__(self, name):
- # Assign the argument to the instance's name attribute
- self.name = name
-
- # 实例方法,第一个参数总是self,就是这个实例对象
- def say(self, msg):
- return "{name}: {message}".format(name=self.name, message=msg)
-
- # 类方法,被所有此类的实例共用。第一个参数是这个类对象。
- @classmethod
- def get_species(cls):
- return cls.species
-
- # 静态方法。调用时没有实例或类的绑定。
- @staticmethod
- def grunt():
- return "*grunt*"
-
-
-# 构造一个实例
-i = Human(name="Ian")
-print(i.say("hi")) # 印出 "Ian: hi"
-
-j = Human("Joel")
-print(j.say("hello")) # 印出 "Joel: hello"
-
-# 调用一个类方法
-i.get_species() # => "H. sapiens"
-
-# 改一个共用的类属性
-Human.species = "H. neanderthalensis"
-i.get_species() # => "H. neanderthalensis"
-j.get_species() # => "H. neanderthalensis"
-
-# 调用静态方法
-Human.grunt() # => "*grunt*"
-
-
-####################################################
-## 6. 模块
-####################################################
-
-# 用import导入模块
-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
-
-# 可以导入一个模块中所有值
-# 警告:不建议这么做
-from math import *
-
-# 如此缩写模块名字
-import math as m
-math.sqrt(16) == m.sqrt(16) # => True
-
-# Python模块其实就是普通的Python文件。你可以自己写,然后导入,
-# 模块的名字就是文件的名字。
-
-# 你可以这样列出一个模块里所有的值
-import math
-dir(math)
-
-
-####################################################
-## 7. 高级用法
-####################################################
-
-# 用生成器(generators)方便地写惰性运算
-def double_numbers(iterable):
- for i in iterable:
- yield i + i
-
-# 生成器只有在需要时才计算下一个值。它们每一次循环只生成一个值,而不是把所有的
-# 值全部算好。这意味着double_numbers不会生成大于15的数字。
-#
-# range的返回值也是一个生成器,不然一个1到900000000的列表会花很多时间和内存。
-#
-# 如果你想用一个Python的关键字当作变量名,可以加一个下划线来区分。
-range_ = range(1, 900000000)
-# 当找到一个 >=30 的结果就会停
-for i in double_numbers(range_):
- print(i)
- if i >= 30:
- break
-
-
-# 装饰器(decorators)
-# 这个例子中,beg装饰say
-# beg会先调用say。如果返回的say_please为真,beg会改变返回的字符串。
-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 :(
-```
-
-## 想继续学吗?
-
-### 线上免费材料(英文)
-
-* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
-* [Dive Into Python](http://www.diveintopython.net/)
-* [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 Module of the Week](http://pymotw.com/3/)
-* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
-
-### 书籍(也是英文)
-
-* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20)
-* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20)
-* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20)
-
diff --git a/zh-cn/pythonlegacy-cn.html.markdown b/zh-cn/pythonlegacy-cn.html.markdown
new file mode 100644
index 00000000..f8aa2332
--- /dev/null
+++ b/zh-cn/pythonlegacy-cn.html.markdown
@@ -0,0 +1,476 @@
+---
+language: Python 2 (legacy)
+contributors:
+ - ["Louie Dinh", "http://ldinh.ca"]
+translators:
+ - ["Chenbo Li", "http://binarythink.net"]
+filename: learnpythonlegacy-zh.py
+lang: zh-cn
+---
+
+Python 由 Guido Van Rossum 在90年代初创建。 它现在是最流行的语言之一
+我喜爱python是因为它有极为清晰的语法,甚至可以说,它就是可以执行的伪代码
+
+很欢迎来自您的反馈,你可以在[@louiedinh](http://twitter.com/louiedinh) 和 louiedinh [at] [google's email service] 这里找到我
+
+注意: 这篇文章针对的版本是Python 2.7,但大多也可使用于其他Python 2的版本
+如果是Python 3,请在网络上寻找其他教程
+
+```python
+
+# 单行注释
+""" 多行字符串可以用
+ 三个引号包裹,不过这也可以被当做
+ 多行注释
+"""
+
+####################################################
+## 1. 原始数据类型和操作符
+####################################################
+
+# 数字类型
+3 # => 3
+
+# 简单的算数
+1 + 1 # => 2
+8 - 1 # => 7
+10 * 2 # => 20
+35 / 5 # => 7
+
+# 整数的除法会自动取整
+5 / 2 # => 2
+
+# 要做精确的除法,我们需要引入浮点数
+2.0 # 浮点数
+11.0 / 4.0 # => 2.75 精确多了
+
+# 括号具有最高优先级
+(1 + 3) * 2 # => 8
+
+# 布尔值也是基本的数据类型
+True
+False
+
+# 用 not 来取非
+not True # => False
+not False # => True
+
+# 相等
+1 == 1 # => True
+2 == 1 # => False
+
+# 不等
+1 != 1 # => False
+2 != 1 # => True
+
+# 更多的比较操作符
+1 < 10 # => True
+1 > 10 # => False
+2 <= 2 # => True
+2 >= 2 # => True
+
+# 比较运算可以连起来写!
+1 < 2 < 3 # => True
+2 < 3 < 2 # => False
+
+# 字符串通过 " 或 ' 括起来
+"This is a string."
+'This is also a string.'
+
+# 字符串通过加号拼接
+"Hello " + "world!" # => "Hello world!"
+
+# 字符串可以被视为字符的列表
+"This is a string"[0] # => 'T'
+
+# % 可以用来格式化字符串
+"%s can be %s" % ("strings", "interpolated")
+
+# 也可以用 format 方法来格式化字符串
+# 推荐使用这个方法
+"{0} can be {1}".format("strings", "formatted")
+# 也可以用变量名代替数字
+"{name} wants to eat {food}".format(name="Bob", food="lasagna")
+
+# None 是对象
+None # => None
+
+# 不要用相等 `==` 符号来和None进行比较
+# 要用 `is`
+"etc" is None # => False
+None is None # => True
+
+# 'is' 可以用来比较对象的相等性
+# 这个操作符在比较原始数据时没多少用,但是比较对象时必不可少
+
+# None, 0, 和空字符串都被算作 False
+# 其他的均为 True
+0 == False # => True
+"" == False # => True
+
+
+####################################################
+## 2. 变量和集合
+####################################################
+
+# 很方便的输出
+print "I'm Python. Nice to meet you!"
+
+
+# 给变量赋值前不需要事先声明
+some_var = 5 # 一般建议使用小写字母和下划线组合来做为变量名
+some_var # => 5
+
+# 访问未赋值的变量会抛出异常
+# 可以查看控制流程一节来了解如何异常处理
+some_other_var # 抛出 NameError
+
+# if 语句可以作为表达式来使用
+"yahoo!" if 3 > 2 else 2 # => "yahoo!"
+
+# 列表用来保存序列
+li = []
+# 可以直接初始化列表
+other_li = [4, 5, 6]
+
+# 在列表末尾添加元素
+li.append(1) # li 现在是 [1]
+li.append(2) # li 现在是 [1, 2]
+li.append(4) # li 现在是 [1, 2, 4]
+li.append(3) # li 现在是 [1, 2, 4, 3]
+# 移除列表末尾元素
+li.pop() # => 3 li 现在是 [1, 2, 4]
+# 重新加进去
+li.append(3) # li is now [1, 2, 4, 3] again.
+
+# 像其他语言访问数组一样访问列表
+li[0] # => 1
+# 访问最后一个元素
+li[-1] # => 3
+
+# 越界会抛出异常
+li[4] # 抛出越界异常
+
+# 切片语法需要用到列表的索引访问
+# 可以看做数学之中左闭右开区间
+li[1:3] # => [2, 4]
+# 省略开头的元素
+li[2:] # => [4, 3]
+# 省略末尾的元素
+li[:3] # => [1, 2, 4]
+
+# 删除特定元素
+del li[2] # li 现在是 [1, 2, 3]
+
+# 合并列表
+li + other_li # => [1, 2, 3, 4, 5, 6] - 并不会改变这两个列表
+
+# 通过拼接来合并列表
+li.extend(other_li) # li 是 [1, 2, 3, 4, 5, 6]
+
+# 用 in 来返回元素是否在列表中
+1 in li # => True
+
+# 返回列表长度
+len(li) # => 6
+
+
+# 元组类似于列表,但它是不可改变的
+tup = (1, 2, 3)
+tup[0] # => 1
+tup[0] = 3 # 类型错误
+
+# 对于大多数的列表操作,也适用于元组
+len(tup) # => 3
+tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6)
+tup[:2] # => (1, 2)
+2 in tup # => True
+
+# 你可以将元组解包赋给多个变量
+a, b, c = (1, 2, 3) # a 是 1,b 是 2,c 是 3
+# 如果不加括号,将会被自动视为元组
+d, e, f = 4, 5, 6
+# 现在我们可以看看交换两个数字是多么容易的事
+e, d = d, e # d 是 5,e 是 4
+
+
+# 字典用来储存映射关系
+empty_dict = {}
+# 字典初始化
+filled_dict = {"one": 1, "two": 2, "three": 3}
+
+# 字典也用中括号访问元素
+filled_dict["one"] # => 1
+
+# 把所有的键保存在列表中
+filled_dict.keys() # => ["three", "two", "one"]
+# 键的顺序并不是唯一的,得到的不一定是这个顺序
+
+# 把所有的值保存在列表中
+filled_dict.values() # => [3, 2, 1]
+# 和键的顺序相同
+
+# 判断一个键是否存在
+"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
+
+
+# 集合储存无顺序的元素
+empty_set = set()
+# 初始化一个集合
+some_set = set([1, 2, 2, 3, 4]) # some_set 现在是 set([1, 2, 3, 4])
+
+# Python 2.7 之后,大括号可以用来表示集合
+filled_set = {1, 2, 2, 3, 4} # => {1 2 3 4}
+
+# 向集合添加元素
+filled_set.add(5) # filled_set 现在是 {1, 2, 3, 4, 5}
+
+# 用 & 来计算集合的交
+other_set = {3, 4, 5, 6}
+filled_set & other_set # => {3, 4, 5}
+
+# 用 | 来计算集合的并
+filled_set | other_set # => {1, 2, 3, 4, 5, 6}
+
+# 用 - 来计算集合的差
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+
+# 用 in 来判断元素是否存在于集合中
+2 in filled_set # => True
+10 in filled_set # => False
+
+
+####################################################
+## 3. 控制流程
+####################################################
+
+# 新建一个变量
+some_var = 5
+
+# 这是个 if 语句,在 python 中缩进是很重要的。
+# 下面的代码片段将会输出 "some var 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"]:
+ # 你可以用 % 来格式化字符串
+ print "%s is a mammal" % animal
+
+"""
+`range(number)` 返回从0到给定数字的列表
+输出:
+ 0
+ 1
+ 2
+ 3
+"""
+for i in range(4):
+ print i
+
+"""
+while 循环
+输出:
+ 0
+ 1
+ 2
+ 3
+"""
+x = 0
+while x < 4:
+ print x
+ x += 1 # x = x + 1 的简写
+
+# 用 try/except 块来处理异常
+
+# Python 2.6 及以上适用:
+try:
+ # 用 raise 来抛出异常
+ raise IndexError("This is an index error")
+except IndexError as e:
+ pass # pass 就是什么都不做,不过通常这里会做一些恢复工作
+
+
+####################################################
+## 4. 函数
+####################################################
+
+# 用 def 来新建函数
+def add(x, y):
+ print "x is %s and y is %s" % (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 = (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)
+
+# 函数在 python 中是一等公民
+def create_adder(x):
+ def adder(y):
+ return x + y
+ return adder
+
+add_10 = create_adder(10)
+add_10(3) # => 13
+
+# 匿名函数
+(lambda x: x > 2)(3) # => True
+
+# 内置高阶函数
+map(add_10, [1, 2, 3]) # => [11, 12, 13]
+filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+
+# 可以用列表方法来对高阶函数进行更巧妙的引用
+[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13]
+[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7]
+
+####################################################
+## 5. 类
+####################################################
+
+# 我们新建的类是从 object 类中继承的
+class Human(object):
+
+ # 类属性,由所有类的对象共享
+ species = "H. sapiens"
+
+ # 基本构造函数
+ def __init__(self, name):
+ # 将参数赋给对象成员属性
+ self.name = name
+
+ # 成员方法,参数要有 self
+ def say(self, msg):
+ return "%s: %s" % (self.name, msg)
+
+ # 类方法由所有类的对象共享
+ # 这类方法在调用时,会把类本身传给第一个参数
+ @classmethod
+ def get_species(cls):
+ return cls.species
+
+ # 静态方法是不需要类和对象的引用就可以调用的方法
+ @staticmethod
+ def grunt():
+ return "*grunt*"
+
+
+# 实例化一个类
+i = Human(name="Ian")
+print i.say("hi") # 输出 "Ian: hi"
+
+j = Human("Joel")
+print j.say("hello") # 输出 "Joel: hello"
+
+# 访问类的方法
+i.get_species() # => "H. sapiens"
+
+# 改变共享属性
+Human.species = "H. neanderthalensis"
+i.get_species() # => "H. neanderthalensis"
+j.get_species() # => "H. neanderthalensis"
+
+# 访问静态变量
+Human.grunt() # => "*grunt*"
+
+
+####################################################
+## 6. 模块
+####################################################
+
+# 我们可以导入其他模块
+import math
+print math.sqrt(16) # => 4.0
+
+# 我们也可以从一个模块中导入特定的函数
+from math import ceil, floor
+print ceil(3.7) # => 4.0
+print floor(3.7) # => 3.0
+
+# 从模块中导入所有的函数
+# 警告:不推荐使用
+from math import *
+
+# 简写模块名
+import math as m
+math.sqrt(16) == m.sqrt(16) # => True
+
+# Python的模块其实只是普通的python文件
+# 你也可以创建自己的模块,并且导入它们
+# 模块的名字就和文件的名字相同
+
+# 也可以通过下面的方法查看模块中有什么属性和方法
+import math
+dir(math)
+
+
+```
+
+## 更多阅读
+
+希望学到更多?试试下面的链接:
+
+* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)
+* [Dive Into Python](http://www.diveintopython.net/)
+* [The Official Docs](http://docs.python.org/2.6/)
+* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
+* [Python Module of the Week](http://pymotw.com/2/)
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/racket-cn.html.markdown b/zh-cn/racket-cn.html.markdown
index 8ef3671f..b373e1d9 100644
--- a/zh-cn/racket-cn.html.markdown
+++ b/zh-cn/racket-cn.html.markdown
@@ -444,7 +444,7 @@ n ; => 6
(set-box! n* (add1 (unbox n*)))
(unbox n*) ; => 6
-;; 很多 Racket 诗句类型是不可变的 (对,列表,等),有一些既是可变的
+;; 很多 Racket 数据类型是不可变的 (对,列表,等),有一些既是可变的
;; 又是不可变的 (字符串,向量,散列表
;; 等...)
diff --git a/zh-cn/red-cn.html.markdown b/zh-cn/red-cn.html.markdown
new file mode 100644
index 00000000..85812990
--- /dev/null
+++ b/zh-cn/red-cn.html.markdown
@@ -0,0 +1,208 @@
+---
+name: Red
+category: language
+language: Red
+filename: LearnRed-zh.red
+contributors:
+ - ["Arnold van Hofwegen", "https://github.com/iArnold"]
+translators:
+ - ["Limo Saplf", "https://github.com/saplf"]
+lang: zh-cn
+---
+
+Red 的编写是出于工作需要,该语言的作者想要使用 REBOL,但它有许多缺陷。
+当时 REBOL 还没有开源,由于它是一门解释型语言,这就意味着它比编译型语言效率低。
+
+Red 使用 C 语言级别的 Red/System,是一门涉及所有编程领域的语言。
+Red 基于 REBOL 编写,它继承了 REBOL 的灵活性,同时也包含了许多 C 语言能做的底层实现。
+
+Red 将会成为世界上第一门全栈式编程语言,这意味着它可以完成几乎所有的编程任务,从底层到抽象,无需其他工具的参与。
+而且,Red 支持交叉编译,任意两个平台之间,不需要任何 GCC 之类的工具链的支持。
+所有的工作,仅仅需要一个不到 1 MB 的二进制可执行文件。
+
+准备好你的 Red 第一课了吗?
+
+```red
+所有 header 之前的文字都是注释,只要你不使用 "red" 关键字,其中的 "r" 大写。
+这是词法分析器的一个缺陷,所以大多数时候,你都应该直接以 header 开始程序或者脚本的编写。
+
+red 脚本的 header 由关键字,首字母大写的 "red" 开始,后跟一个空格,再跟一对方括号 []。
+方括号里可以写上一些关于这段脚本或者程序的相关信息:
+作者,文件名,版本号,license,程序功能的简介,它依赖的其他文件。
+red/System 的 header 和 red header 类似,仅仅是说明 "red/System" 而非 "red"。
+
+
+Red []
+
+; 这是一条行注释
+
+print "Hello Red World" ; 另一条注释
+
+comment {
+ 这是多行注释。
+ 你刚刚看到的就是 Red 版的 Hello World。
+}
+
+; 程序的入口就是第一句可执行的代码
+; 不需要把它放在 'main' 函数里
+
+; 变量名以一个字母开始,可以包含数字,
+; 只包含 A ~ F 字符和数字的变量名不能以 'h' 结尾,
+; 因为这是 Red 和 Red/System 中十六进制数字的表达方式。
+
+; 给变量赋值使用冒号 ":"
+my-name: "Red"
+reason-for-using-the-colon: {使用冒号作为赋值符号
+ 是为了能够让 "=" 能够用来作为比较符号,这本来就是 "="
+ 存在的意义!还记得上学时学的,y = x + 1 、 x = 1,
+ 以及推导出的 y = 2 吗?
+}
+is-this-name-valid?: true
+
+; 用 print 打印输出,prin 打印不带换行的输出
+
+prin "我的名字是 " print my-name
+; 我的名字是 Red
+
+print ["我的名字是 " my-name lf]
+; 我的名字是 Red
+
+; 注意到了吗:语句没有以分号结尾 ;-)
+
+;
+; 数据类型
+;
+; 如果你了解 Rebol,你可能就会注意到它有许多数据类型。
+; Red 并没有囊括它所有的类型,但由于 Red 想要尽可能的
+; 接近 Rebol,所以它也会有很多数据类型。
+; 类型以叹号结尾,但要注意,变量名也是可以以叹号结尾的。
+; 一些内置类型有 integer! string! block!
+
+; 使用变量前需要声明吗?
+; Red 能够分辨什么时候使用什么变量,变量声明并非必要的。
+; 一般认为,声明变量是较好的编码实践,但 Red 并不会强制这点。
+; 你可以声明一个变量然后指定它的类型,而一个变量的类型就
+; 指定了它的字节大小。
+
+; integer! 类型的变量通常是 4 字节,32位
+my-integer: 0
+; Red 的整型包含符号,暂时不支持无符号类型,但以后会支持的。
+
+; 怎样判断一个变量的类型?
+type? my-integer
+; integer!
+
+; 一个变量的初始化可以使用另一个同样刚刚初始化的变量:
+i2: 1 + i1: 1
+
+; 算数运算符
+i1 + i2 ; 3
+i2 - i1 ; 1
+i2 * i1 ; 2
+i1 / i2 ; 0 (0.5,但截取为 0)
+
+; 比较运算符都差不多,但和其他语言不一样的是相等的比较,
+; Red 使用单个的 '='。
+; Red 有一个类似 boolean 的类型,它的值是 true 和 false,
+; 但也可以使用 on/off 或者 yes/on
+
+3 = 2 ; false
+3 != 2 ; true
+3 > 2 ; true
+3 < 2 ; false
+2 <= 2 ; true
+2 >= 2 ; true
+
+;
+; 控制流
+;
+; if
+; 如果给定的条件为 true 则执行一段代码块。
+; if 没有返回值,所以不能用作表达式。
+if a < 0 [print "a 是负值"]
+
+; either
+; 如果给定的条件为 true 则执行一段代码块,否则就
+; 执行另一段可选的代码块。如果两个代码块中最后一个表达式
+; 的类型相同, either 就可以用作表达式。
+either a > 0 [
+ msg: "正值"
+][
+ either a = 0 [
+ msg: "零"
+ ][
+ msg: "负值"
+ ]
+]
+print ["a 是 " msg lf]
+
+; 还可以有另一种写法
+; (因为两条路径的返回值相同,所以可以这么写):
+
+msg: either a > 0 [
+ "正值"
+][
+ either a = 0 [
+ "零"
+ ][
+ "负值"
+ ]
+]
+print ["a 是 " msg lf]
+
+; util
+; 循环执行一段代码块,直到满足给定的条件为止。
+; util 没有返回值,所以它不能用在表示式中。
+c: 5
+util [
+ prin "o"
+ c: c - 1
+ c = 0 ; 终止循环的条件
+]
+; 输出:ooooo
+; 需要注意的是,即使条件从一开始就不满足,
+; 这个循环也至少会执行一次。
+
+; while
+; 当满足给定的条件,就执行一段代码。
+; while 没有返回值,不能用在表达式中。
+c: 5
+while [c > 0][
+ prin "o"
+ c: c - 1
+]
+; 输出:ooooo
+
+;
+; 函数
+;
+; 函数示例
+twice: function [a [integer!] /one return: [integer!]][
+ c: 2
+ a: a * c
+ either one [a + 1][a]
+]
+b: 3
+print twice b ; 输出 6
+
+; 使用 #include 和 %文件名 来导入外部文件
+#include %includefile.red
+; 现在就可以使用 includefile.red 中的函数了。
+
+```
+
+## 更进一步
+
+Red 相关的源码信息在 [Red 语言主页](http://www.red-lang.org)。
+
+源代码的 [github 库](https://github.com/red/red)。
+
+Red/System 特性在 [这里](http://static.red-lang.org/red-system-specs-light.html)。
+
+想要了解更多关于 Rebol 和 Red 的信息,加入 [Gitter 聊天室](https://gitter.im/red/red)。如果你无法加入,也可以给我们发[邮件](mailto:red-langNO_SPAM@googlegroups.com)。
+
+也可以在 [Stack Overflow](stackoverflow.com/questions/tagged/red) 上查阅、提交问题。
+
+也许你现在就要试一试 Red ?可以在线尝试 [try Rebol and Red site](http://tryrebol.esperconsultancy.nl)。
+
+你也可以通过学习一些 [Rebol](http://www.rebol.com/docs.html) 来学习 Red。
diff --git a/zh-cn/ruby-cn.html.markdown b/zh-cn/ruby-cn.html.markdown
index 657a913d..9918c022 100644
--- a/zh-cn/ruby-cn.html.markdown
+++ b/zh-cn/ruby-cn.html.markdown
@@ -6,11 +6,25 @@ contributors:
- ["David Underwood", "http://theflyingdeveloper.com"]
- ["Joel Walden", "http://joelwalden.net"]
- ["Luke Holder", "http://twitter.com/lukeholder"]
+ - ["Tristan Hume", "http://thume.ca/"]
+ - ["Nick LaMuro", "https://github.com/NickLaMuro"]
+ - ["Marcos Brizeno", "http://www.about.me/marcosbrizeno"]
+ - ["Ariel Krakowski", "http://www.learneroo.com"]
+ - ["Dzianis Dashkevich", "https://github.com/dskecse"]
+ - ["Levi Bostian", "https://github.com/levibostian"]
+ - ["Rahil Momin", "https://github.com/iamrahil"]
+ - ["Gabriel Halley", "https://github.com/ghalley"]
+ - ["Persa Zula", "http://persazula.com"]
+ - ["Jake Faris", "https://github.com/farisj"]
+ - ["Corey Ward", "https://github.com/coreyward"]
+ - ["Jannik Siebert", "https://github.com/janniks"]
+ - ["Keith Miyake", "https://github.com/kaymmm"]
- ["lidashuang", "https://github.com/lidashuang"]
- ["ftwbzhao", "https://github.com/ftwbzhao"]
translators:
- ["Lin Xiangyu", "https://github.com/oa414"]
- ["Jiang Haiyun", "https://github.com/haiiiiiyun"]
+ - ["woclass", "https://github.com/inkydragon"]
---
```ruby
@@ -18,26 +32,27 @@ translators:
=begin
这是多行注释
-没人用这个
-你也不该用
=end
-# 首先,也是最重要的,所有东西都是对象
+# 在 Ruby 中,(几乎)所有东西都是对象
# 数字是对象
-
-3.class #=> Fixnum
-
+3.class #=> Integer
3.to_s #=> "3"
+# 字符串是对象
+"Hello".class #=> String
+
+# 甚至方法也是对象
+"Hello".method(:class).class #=> Method
-# 一些基本的算术符号
-1 + 1 #=> 2
-8 - 1 #=> 7
-10 * 2 #=> 20
-35 / 5 #=> 7
-2**5 #=> 32
-5 % 3 #=> 2
+# 一些基本的算术操作
+1 + 1 #=> 2
+8 - 1 #=> 7
+10 * 2 #=> 20
+35 / 5 #=> 7
+2 ** 5 #=> 32
+5 % 3 #=> 2
# 位运算符
3 & 5 #=> 1
@@ -48,6 +63,7 @@ translators:
# 实际上是调用对象的方法
1.+(3) #=> 4
10.* 5 #=> 50
+100.methods.include?(:/) #=> true
# 特殊的值也是对象
nil # 相当于其它语言中的 null
@@ -66,11 +82,11 @@ false.class #=> FalseClass
1 != 1 #=> false
2 != 1 #=> true
-# 除了false自己,nil是唯一的另一个值为false的对象
-
-!nil #=> true
-!false #=> true
-!0 #=> false
+# 除了 false 自己,nil 是唯一的另一个值为 false 的对象
+!!nil #=> false
+!!false #=> false
+!!0 #=> true
+!!"" #=> true
# 更多比较
1 < 10 #=> true
@@ -90,11 +106,11 @@ true || false #=> true
!true #=> false
# 也有优先级更低的逻辑运算符
-# 它们用于控制流结构中,用来串接语句,直到返回true或false。
+# 它们用于控制流结构中,用来串接语句,直到返回 true 或 false。
-# `do_something_else` 只当 `do_something` 返回true时才会被调用
+# `do_something_else` 只当 `do_something` 返回 true 时才会被调用
do_something() and do_something_else()
-# `log_error` 只当 `do_something` 返回false时才会被调用
+# `log_error` 只当 `do_something` 返回 false 时才会被调用
do_something() or log_error()
@@ -114,6 +130,7 @@ placeholder = "use string interpolation"
'hello ' + 'world' #=> "hello world"
'hello ' + 3 #=> TypeError: can't convert Fixnum into String
'hello ' + 3.to_s #=> "hello 3"
+"hello #{3}" #=> "hello 3"
# 合并字符串及其运算符
'hello ' * 3 #=> "hello hello hello "
@@ -141,7 +158,7 @@ x = y = 10 #=> 10
x #=> 10
y #=> 10
-# 按照惯例,使用类似snake_case风格的变量名
+# 按照惯例,使用类似 snake_case 风格的变量名
snake_case = true
# 使用有意义的变量名
@@ -174,6 +191,7 @@ array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
# 数组可以被索引
# 从前面开始
array[0] #=> 1
+array.first #=> 1
array[12] #=> nil
# 像运算符一样,[var] 形式的访问
@@ -189,13 +207,13 @@ array.last #=> 5
# 同时指定开始的位置和长度
array[2, 3] #=> [3, 4, 5]
+# 或者指定一个区间
+array[1..3] #=> [2, 3, 4]
+
# 将数组逆序
a=[1,2,3]
a.reverse! #=> [3,2,1]
-# 或者指定一个区间
-array[1..3] #=> [2, 3, 4]
-
# 像这样往数组增加一个元素
array << 6 #=> [1, 2, 3, 4, 5, 6]
# 或者像这样
@@ -217,14 +235,18 @@ hash['number'] #=> 5
# 查询一个不存在的键将会返回nil
hash['nothing here'] #=> nil
-# 从Ruby 1.9开始,用符号作为键的时候有特别的记号表示:
+# 从 Ruby 1.9 开始,用符号作为键的时候有特别的记号表示:
new_hash = { defcon: 3, action: true }
new_hash.keys #=> [:defcon, :action]
+# 检查键值是否存在
+hash.key?(:defcon) #=> true
+hash.value?(3) #=> true
+
# 小贴士:数组和哈希表都是可枚举的
-# 它们共享一些有用的方法,比如each,map,count等等
+# 它们共享一些有用的方法,比如 each, map, count 等等
# 控制流
@@ -236,6 +258,8 @@ else
"else, also optional"
end
+# 循环
+
for counter in 1..5
puts "iteration #{counter}"
end
@@ -246,14 +270,14 @@ end
#=> iteration 5
-# 但是,没有人用for循环。
-# 你应该使用"each"方法,然后再传给它一个块。
-# 所谓块就是可以传给像"each"这样的方法的代码段。
-# 它类似于其它语言中的lambdas, 匿名函数或闭包。
+# 但是,没有人用 for 循环。
+# 你应该使用 "each" 方法,然后再传给它一个块。
+# 所谓块就是可以传给像 "each" 这样的方法的代码段。
+# 它类似于其它语言中的 lambdas, 匿名函数或闭包。
#
-# 区间上的"each"方法会对区间中的每个元素运行一次块代码。
-# 我们将counter作为一个参数传给了块。
-# 调用带有块的"each"方法看起来如下:
+# 区间上的 "each" 方法会对区间中的每个元素运行一次块代码。
+# 我们将 counter 作为一个参数传给了块。
+# 调用带有块的 "each" 方法看起来如下:
(1..5).each do |counter|
puts "iteration #{counter}"
@@ -275,7 +299,7 @@ hash.each do |key, value|
puts "#{key} is #{value}"
end
-# 如果你还需要索引值,可以使用"each_with_index",并且定义
+# 如果你还需要索引值,可以使用 "each_with_index",并且定义
# 一个索引变量
array.each_with_index do |element, index|
puts "#{element} is number #{index} in the array"
@@ -293,7 +317,7 @@ end
#=> iteration 5
# Ruby 中还有很多有用的循环遍历函数,
-# 如"map","reduce","inject"等等。
+# 如 "map", "reduce", "inject" 等等。
# 以map为例,它会遍历数组,并根据你在
# 块中定义的逻辑对它进行处理,然后返回
# 一个全新的数组。
@@ -388,19 +412,26 @@ surround { puts 'hello world' }
# {
# hello world
# }
+# => nil
# 可以向函数传递一个块
# "&"标记传递的块是一个引用
def guests(&block)
- block.call 'some_argument'
+ block.class #=> Proc
+ block.call(4)
end
+guests { |n| "You have #{n} guests." }
+# => "You have 4 guests."
+
# 可以传递多个参数,这些参数会转成一个数组,
# 这也是使用星号符 ("*") 的原因:
def guests(*array)
array.each { |guest| puts guest }
end
+# 结构
+
# 如果函数返回一个数组,在赋值时可以进行拆分:
def foods
['pancake', 'sandwich', 'quesadilla']
@@ -409,21 +440,42 @@ breakfast, lunch, dinner = foods
breakfast #=> 'pancake'
dinner #=> 'quesadilla'
-# 按照惯例,所有返回布尔值的方法都以?结尾
+# 有些情况下,你会想使用解构操作符 `*` 来解构数组
+ranked_competitors = ["John", "Sally", "Dingus", "Moe", "Marcy"]
+
+def best(first, second, third)
+ puts "Winners are #{first}, #{second}, and #{third}."
+end
+
+best *ranked_competitors.first(3) #=> Winners are John, Sally, and Dingus.
+
+# 结构操作符也可放在参数里面
+def best(first, second, third, *others)
+ puts "Winners are #{first}, #{second}, and #{third}."
+ puts "There were #{others.count} other participants."
+end
+
+best *ranked_competitors
+#=> Winners are John, Sally, and Dingus.
+#=> There were 2 other participants.
+
+# 按照惯例,所有返回布尔值的方法都以 ? 结尾
5.even? # false
5.odd? # true
-# 如果方法名末尾有!,表示会做一些破坏性的操作,比如修改调用者自身。
-# 很多方法都会有一个!的版本来进行修改,和一个非!的版本
-# 只用来返回更新了的结果
+# 如果方法名末尾有感叹号 !,表示会做一些破坏性的操作,比如修改调用者自身。
+# 很多方法都会有一个 ! 的版本来进行修改,
+# 和一个只返回更新结果的非 ! 版本
company_name = "Dunder Mifflin"
company_name.upcase #=> "DUNDER MIFFLIN"
company_name #=> "Dunder Mifflin"
-company_name.upcase! # we're mutating company_name this time!
+# 这次我们修改了 company_name
+company_name.upcase! #=> "DUNDER MIFFLIN"
company_name #=> "DUNDER MIFFLIN"
+# 类
-# 用class关键字定义一个类
+# 用 class 关键字定义一个类
class Human
# 一个类变量,它被这个类的所有实例变量共享
@@ -431,30 +483,30 @@ class Human
# 基本构造函数
def initialize(name, age = 0)
- # 将参数值赋给实例变量"name"
+ # 将参数值赋给实例变量 "name"
@name = name
- # 如果没有给出age,那么会采用参数列表中的默认值
+ # 如果没有给出 age,那么会采用参数列表中的默认值
@age = age
end
- # 基本的setter方法
+ # 基本的 setter 方法
def name=(name)
@name = name
end
- # 基本地getter方法
+ # 基本地 getter 方法
def name
@name
end
- # 以上的功能也可以用下面的attr_accessor来封装
+ # 以上的功能也可以用下面的 attr_accessor 来封装
attr_accessor :name
- # Getter/setter方法也可以像这样单独创建
+ # Getter/setter 方法也可以像这样单独创建
attr_reader :name
attr_writer :name
- # 类方法通过使用self与实例方法区别开来。
+ # 类方法通过使用 self 与实例方法区别开来。
# 它只能通过类来调用,不能通过实例调用。
def self.say(msg)
puts "#{msg}"
@@ -468,7 +520,6 @@ end
# 初始化一个类
jim = Human.new("Jim Halpert")
-
dwight = Human.new("Dwight K. Schrute")
# 让我们来调用一些方法
@@ -483,15 +534,15 @@ dwight.name #=> "Dwight K. Schrute"
Human.say('Hi') #=> "Hi"
# 变量的作用域由它们的名字格式定义
-# 以$开头的变量具有全局域
+# 以 $ 开头的变量具有全局域
$var = "I'm a global var"
defined? $var #=> "global-variable"
-# 以@开头的变量具有实例作用域
+# 以 @ 开头的变量具有实例作用域
@var = "I'm an instance var"
defined? @var #=> "instance-variable"
-# 以@@开头的变量具有类作用域
+# 以 @@ 开头的变量具有类作用域
@@var = "I'm a class var"
defined? @@var #=> "class variable"
@@ -568,7 +619,6 @@ Book.foo # => 'foo'
Book.new.foo # => NoMethodError: undefined method `foo'
# 当包含或扩展一个模块时,相应的回调代码会被执行。
-
module ConcernExample
def self.included(base)
base.extend(ClassMethods)
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/) 上提供了教程(初学者-高级)和文章。
diff --git a/zh-cn/solidity-cn.html.markdown b/zh-cn/solidity-cn.html.markdown
new file mode 100644
index 00000000..ec684997
--- /dev/null
+++ b/zh-cn/solidity-cn.html.markdown
@@ -0,0 +1,825 @@
+---
+language: Solidity
+filename: learnSolidity-cn.sol
+lang: zh-cn
+contributors:
+ - ["Nemil Dalal", "https://www.nemil.com"]
+ - ["Joseph Chow", ""]
+ - ["Bhoomtawath Plinsut", "https://github.com/varshard"]
+ - ["Shooter", "https://github.com/liushooter"]
+translators:
+ - ["Bob Jiang", "https://github.com/bobjiang"]
+---
+
+Solidity 使你在[以太坊](https://www.ethereum.org/)上编程,一个基于区块链的虚拟机,
+允许创建和执行智能合约,无需中心化的或可信的一方。
+
+Solidity 是一种与 Javascript 和 C 的相似的、静态类型的合约编程语言。与OOP(面向对象)中
+的对象一样,每个合约都包含状态变量、函数和公共数据类型。合约特定功能包括修饰符(guard)子句,
+事件通知的侦听器及自定义的全局变量。
+
+以太坊合约的例子包括众筹、投票以及盲拍(私密拍卖)。
+
+Solidity 代码中存在高风险和高成本的错误,因此你必须非常小心地进行测试并慢慢地发布。**随着
+以太坊的快速变化,本文档不可能是最新的,所以你应该关注最新的的 solidity 聊天室和以太网博客。
+照搬这里的代码,会存在重大错误或弃用代码模式的风险。(说人话--别照抄例子中的代码)**
+
+与其他代码不同,可能还需要添加如暂停、弃用和限制使用的设计模式,来降低风险。本文档主要讨论语法,
+因此排除了许多流行的设计模式。
+
+由于 Solidity 和以太坊正在积极开发,通常会标记为实验或 beta 特性,并很可能会更改。因此欢迎
+提交更改请求。
+
+```javascript
+// 首先,一个简单的银行合约
+// 允许存款、取款、以及检查余额
+
+// simple_bank.sol (注意 .sol 后缀)
+/* **** 例子开始 **** */
+
+// 声明源文件的编译器版本
+pragma solidity ^0.4.19;
+
+// 开始 Natspec 注释(三个斜杠)
+// 用作文档 - 及UI元素、动作的描述性数据
+
+/// @title SimpleBank
+/// @author nemild
+
+/* 'contract' 和其他语言的 'class' 类似 (类变量、继承等) */
+contract SimpleBank { // 单词首字母大写
+ // 声明函数外的状态变量,合约生命周期内可用
+
+ // 地址映射到余额的字典,总是要小心数字的溢出攻击
+ mapping (address => uint) private balances;
+
+ // "private" 的意思是其他合约不能直接查询余额,但对于区块链上的其他方来说,数据仍然是可见的。
+
+ address public owner;
+ // 'public' 使用户或合约可以从外部读取(不可写)
+
+ // Events(事件) - 向外部监听器发布动作
+ event LogDepositMade(address accountAddress, uint amount);
+
+ // Constructor(构造函数)(译者注:solidity 从0.4.22开始使用 constructor() 作为构造函数)
+ function SimpleBank() public {
+ // msg 提供了发送给合约的消息详情
+ // msg.sender 是合约的调用者(这里是合约创建者的地址)
+ owner = msg.sender;
+ }
+
+ /// @notice 存款 ether (以太币)
+ /// @return 存款后用户的余额
+ function deposit() public payable returns (uint) {
+ // 使用 'require' 来检测用户的输入,'assert' 是内部常量
+ // 我们要确保不会发生溢出问题(上溢)
+ require((balances[msg.sender] + msg.value) >= balances[msg.sender]);
+
+ balances[msg.sender] += msg.value;
+ // 状态变量不需要 "this." 或 "self."
+ // 默认情况下,所有值都设置为数据类型的初始值
+
+ LogDepositMade(msg.sender, msg.value); // 触发事件
+
+ return balances[msg.sender];
+ }
+
+ /// @notice 从银行取款以太币 (ether)
+ /// @dev 不会返回任何多余的以太币(ether)
+ /// @param withdrawAmount 取款的数量
+ /// @return 用户还剩下的余额
+ function withdraw(uint withdrawAmount) public returns (uint remainingBal) {
+ require(withdrawAmount <= balances[msg.sender]);
+
+ // 注意在发送任何交易,即通过 .transfer .send 调用外部函数之前,马上减掉取款数量
+ // 这可以允许调用者使用递归请求大于其余额的金额。目标是在调用外部函数之前提交状态,
+ // 包括.transfer / .send
+ balances[msg.sender] -= withdrawAmount;
+
+ // 这会自动引发失败,也就是说还原了更新的余额
+ msg.sender.transfer(withdrawAmount);
+
+ return balances[msg.sender];
+ }
+
+ /// @notice 获取余额
+ /// @return 用户的余额
+ // 'view' 防止函数编辑状态变量;允许函数本地运行或链下运行
+ function balance() view public returns (uint) {
+ return balances[msg.sender];
+ }
+}
+// ** 例子结束 **
+
+
+// 下面, solidity 基础
+
+// 1. 数据类型与关联的方法
+// uint 类型用作现金数量(没有双浮点型或单浮点型)及日期(用 unix 时间)
+uint x;
+
+// 256字节的 int, 实例化后不能改变
+int constant a = 8;
+int256 constant a = 8; // 和上一行一样,这里256字节显性化了
+uint constant VERSION_ID = 0x123A1; // 16进制常量
+// 'constant' 关键字, 编译器在每个出现的地方替换为实际的值
+
+// 所有的状态变量(函数之外的那些),默认是 'internal' 的,只能在合约及所有继承的合约内
+// 可以访问。需要显性的设置为 'public' 才能允许外部合约访问。
+int256 public a = 8;
+
+// 对于 int 和 uint,可以显性的设置位数(从8位到256位,8位跳跃),如int8, int16, int24
+uint8 b;
+int64 c;
+uint248 e;
+
+// 当心不要溢出以及免收此类攻击,例如,对于加法最好这么做:
+uint256 c = a + b;
+assert(c >= a); // assert 测试内部不变的值;require 用来测试用户输入
+// 更多通用算法问题的例子,参考 Zeppelin's SafeMath library
+// https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol
+
+
+// 没有内建的随机函数,使用其他合约获得随机数
+
+// 类型转换
+int x = int(b);
+
+bool b = true; // 或 'var b = true;' 隐含的类型
+
+// 地址 - 20个字节或160位以太坊地址(16进制数字),不允许进行运算
+address public owner;
+
+// 账户类型:
+// 合约账户:在创建时设置地址(创建者地址函数,交易发送)
+// 外部账户:(个人账户)从公钥创建的地址
+
+// 'public' 的含义是自动创建的 getter 方法,而不是 setter 方法可以公开的、外部访问。
+
+// 所有地址都可以进行转账
+owner.transfer(SOME_BALANCE); // 失败后还原
+
+// 还可以调用较低级别的 .send , 转账失败会返回 false
+if (owner.send) {}
+// 记住:用 'if' 包着 send 函数,因为合约地址执行这些函数转账时,可能会失败
+// 另外,确保转账前先减掉余额,因为存在递归调用的风险。
+
+// 检查余额
+owner.balance; // 所有者的余额(用户或合约)
+
+
+// 字符类型,从1到32位可用
+byte a; // byte 等同于 byte1
+bytes2 b;
+bytes32 c;
+
+// 动态大小的字符
+bytes m; // 特殊的数组,等同于 byte[],比 byte1 到 byte32 更贵
+// 尽可能不用 bytes
+
+// 等同于 bytes,但不允许长度或索引的访问
+string n = "hello"; // UTF8存储,注意双引号而不是单引号
+// 字符功能未来会增加,推荐使用 bytes32 或 bytes
+
+// 推断类型
+// var 会根据第一次赋值决定类型,不能用来作为函数的参数
+var a = true;
+// 小心使用,推断可能带来错误的类型,例如,int8,而计数器需要的是 int16
+
+// 函数可以用 var 类型赋值给变量
+function a(uint x) returns (uint) {
+ return x * 2;
+}
+var f = a;
+f(22); // 调用
+
+// 默认的,所有值实例化后都设为 0
+
+// 大多数类型上可以调用删除(不会销毁值,而是设置为0,初始值)
+uint x = 5;
+
+
+// 集合
+(x, y) = (2, 7); // 多值的赋值
+
+
+// 2. 数据结构
+// 数组
+bytes32[5] nicknames; // 静态数组
+bytes32[] names; // 动态数组
+uint newLength = names.push("John"); // 添加返回数组的新长度
+// 长度
+names.length; // 获得数组长度
+names.length = 1; // 可以设定长度(仅针对 storage 中的动态数组)
+
+// 多维数组
+uint x[][5]; // 5个动态数组元素的数组(和多数语言的顺序相反)
+
+// 字典类型 (任一类型到其他类型的映射)
+mapping (string => uint) public balances;
+balances["charles"] = 1;
+// balances["ada"]得到 0, 所有没有设定key值的,返回0
+// 'public' 允许跟着(调用)另一份合约
+contractName.balances("charles"); // returns 1
+// 'public' 创建 getter (而不是 setter )如下:
+function balances(string _account) returns (uint balance) {
+ return balances[_account];
+}
+
+// 内嵌的 mapping
+mapping (address => mapping (address => uint)) public custodians;
+
+// 删除
+delete balances["John"];
+delete balances; // 所有元素设为 0
+
+// 不像其他语言,不知道 keys 的话不能列出 mapping 中的所有元素 - 可以在这之上构建数据结构
+
+// 结构
+struct Bank {
+ address owner;
+ uint balance;
+}
+Bank b = Bank({
+ owner: msg.sender,
+ balance: 5
+});
+// 或
+Bank c = Bank(msg.sender, 5);
+
+c.balance = 5; // 设为新值
+delete b;
+// 设为初始值,结构内所有变量设为0,除了 mapping
+
+// 枚举
+enum State { Created, Locked, Inactive }; // 常常作为状态机
+State public state; // 声明枚举变量
+state = State.Created;
+// 枚举类型可以显性化的转换为 ints
+uint createdState = uint(State.Created); // 0
+
+// 数据位置:内存(Memory) vs. 存储(storage) vs. 调用数据(calldata)
+// 所有复杂类型(数据、结构)都有一个数据位置,内存数据不持久,而存储的数据是持久的。
+// 本地变量和状态变量默认是存储,函数参数默认是内存。堆栈存放较小的本地变量
+
+// 多数类型,可以显性化的设定使用的数据位置
+
+
+// 3. 简单操作符
+// solidity 提供了比较、位运算及数学运算的功能
+// 指数运算: **
+// 异或运算: ^
+// 按位取反: ~
+
+
+// 4. 值得注意的全局变量
+// ** this **
+this; // 合约的地址
+// 常常用在合约生命周期结束前,转走剩下的余额
+this.balance;
+this.someFunction(); // 通过 call 的方式而不是内部跳转的方式,从外部调用函数
+
+// ** msg - 合约收到的当前消息 ** **
+msg.sender; // 发送者的地址
+msg.value; // 该合约内的以太币数量(单位 wei),该函数应该标记为 "payable"
+msg.data; // 字符,完整的调用数据
+msg.gas; // 剩余 gas
+
+// ** tx - 交易信息 **
+tx.origin; // 本次交易的发送者地址
+tx.gasprice; // 本次交易的 gas price
+
+// ** block - 当前区块信息 **
+now; // 当前时间(大概)block.timestamp的别名 (采用的 Unix 时间)
+// 注意这个可能被矿工操纵,因此请小心使用
+
+block.number; // 当前区块号
+block.difficulty; // 当前区块难度
+block.blockhash(1); // 返回 bytes32,只对最近 256 个区块有效
+block.gasLimit();
+
+// ** 存储 - 持久化存储哈希 **
+storage['abc'] = 'def'; // 256 位单词 到 256 位单词的映射
+
+
+// 4. 函数及更多
+// A. 函数
+// 简单函数
+function increment(uint x) returns (uint) {
+ x += 1;
+ return x;
+}
+
+// 函数可以通过指定返回的参数名,来返回多个参数
+function increment(uint x, uint y) returns (uint x, uint y) {
+ x += 1;
+ y += 1;
+}
+// 调用前一个函数
+uint (a,b) = increment(1,1);
+
+// 'view' ('constant'的别名)
+// 表明函数不会改变持久化的变量,View函数会本地执行,而不是链上运行。
+// 注意:constant 关键字很快会废弃。
+uint y = 1;
+
+function increment(uint x) view returns (uint x) {
+ x += 1;
+ y += 1; // 这一行会失败
+ // y 是一个状态变量,不能在 view 的函数里改变 y
+}
+
+// 'pure' 比 'view' 或 'constant' 更加严格,甚至不允许读取状态变量
+// 具体的规则很复杂,请参考
+// view/pure:
+// http://solidity.readthedocs.io/en/develop/contracts.html#view-functions
+
+// '函数可见性指示器'
+// 'view'可以有以下修饰符,包括:
+// public - 内部及外部可见(函数的默认值)
+// external - 仅外部可见(包括 this 发起的调用)
+// private - 仅当前合约可见
+// internal - 仅当前合约及继承的合约可见
+
+// 通常,显性的标记每个函数是个好主意
+
+// 函数的挂起 - 可以将函数赋值给变量
+function a() {
+ var z = b;
+ b();
+}
+
+function b() {
+
+}
+
+// 所有接收 ether 的函数必须标记为 'payable'
+function depositEther() public payable {
+ balances[msg.sender] += msg.value;
+}
+
+
+// 首选循环来递归(最大的调用堆栈深度是 1024),另外不要设置没有限制的循环,
+// 因为这可能会达到 gas limit
+
+// B. 事件
+// 事件通知外部各方; 易于搜索和访问来自外部区块链(使用轻客户端)的事件
+// 通常在合约参数之后声明
+
+// 通常,首字母大写并在前面加上 Log ,防止与函数混淆
+
+// 声明
+event LogSent(address indexed from, address indexed to, uint amount); // 注意 capital first letter
+
+// 调用
+LogSent(from, to, amount);
+
+/*
+ // 对于外部方(合约或外部实体),使用 Web3 Javascript 库来监听
+ // 以下是javascript代码,不是solidity代码
+ Coin.LogSent().watch({}, '', function(error, result) {
+ if (!error) {
+ console.log("Coin transfer: " + result.args.amount +
+ " coins were sent from " + result.args.from +
+ " to " + result.args.to + ".");
+ console.log("Balances now:\n" +
+ "Sender: " + Coin.balances.call(result.args.from) +
+ "Receiver: " + Coin.balances.call(result.args.to));
+ }
+ }
+
+*/
+
+// 一个合约依赖另一个合约的共同范例(例如,合约取决于另一个合约提供的当前汇率)
+
+// C. 修饰器
+// 修饰器验证函数的输入,例如最小余额或用户身份验证; 类似于其他语言的保护子句
+
+// '_' (下划线)经常用在代码的最后一行,表明被调用的函数放在那里
+modifier onlyAfter(uint _time) { require (now >= _time); _; }
+modifier onlyOwner { require(msg.sender == owner) _; }
+// 常用于状态机
+modifier onlyIfStateA (State currState) { require(currState == State.A) _; }
+
+// 修饰器紧跟在函数声明之后
+function changeOwner(newOwner)
+onlyAfter(someTime)
+onlyOwner()
+onlyIfState(State.A)
+{
+ owner = newOwner;
+}
+
+// 下划线可以包含在代码结束之前,但明显地返回将跳过后面的代码,因此谨慎使用
+modifier checkValue(uint amount) {
+ _;
+ if (msg.value > amount) {
+ uint amountToRefund = amount - msg.value;
+ msg.sender.transfer(amountToRefund);
+ }
+}
+
+
+// 6. 判断和循环
+
+// 所有基本的逻辑判断都有效 - 包括 if else, for, while, break, continue
+// return - 但不跳转
+
+// 语法同 javascript, 但没有从非布尔值到布尔值的类型转换
+// (必须使用比较操作符获得布尔变量值)
+
+// 请注意由用户行为决定的循环 - 因为合约对于代码块具有最大量的 gas 限制 -
+// 如果超过限制该代码则将失败
+// 例如:
+for(uint x = 0; x < refundAddressList.length; x++) {
+ refundAddressList[x].transfer(SOME_AMOUNT);
+}
+
+// 上述两个错误:
+// 1. 转账失败会阻塞循环完成,钱被占用
+// 2. 该循环可能会很长(根据需要赔偿的用户数量而定),并且也可能由于超过一个区块最大 gas 限制
+// 而总是失败。你应该让人们自己从他们的子账户取款并标记取款完成
+// 例如,首选拉动式的付款,而不是推动式的付款
+
+
+// 7. 对象与合约
+
+// A. 调用外部合约
+contract InfoFeed {
+ function info() returns (uint ret) { return 42; }
+}
+
+contract Consumer {
+ InfoFeed feed; // 指向区块链上的一个合约
+
+ // 设置 feed 为已存在的合约实例
+ function setFeed(address addr) {
+ // 当心类型自动转换;不会调用构造函数
+ feed = InfoFeed(addr);
+ }
+
+ // 设置 feed 为一个合约的新实例
+ function createNewFeed() {
+ feed = new InfoFeed(); // 创建新实例,调用构造函数
+ }
+
+ function callFeed() {
+ // 最后的括号调用合约,可选择的增加自定义的 ether 或 gas 价格
+ feed.info.value(10).gas(800)();
+ }
+}
+
+// B. 继承
+
+// 和顺序有关,最后继承的合约(如 'def')可以覆盖之前已继承合约的部分
+contract MyContract is abc, def("a custom argument to def") {
+
+// 覆盖函数
+ function z() {
+ if (msg.sender == owner) {
+ def.z(); // 调用覆盖的函数
+ super.z(); // 调用继承的上层合约的函数
+ }
+ }
+}
+
+// 抽象函数
+function someAbstractFunction(uint x);
+// 不可以编译,因此用在基础或抽象合约中,等待实现
+
+// C. 导入
+
+import "filename";
+import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol";
+
+
+// 8. 其他关键字
+
+// A. 自毁
+// 自毁当前的合约,转账资金到一个地址(常常是创建者的地址)
+selfdestruct(SOME_ADDRESS);
+
+// 从当前或以后的区块中移除存储或代码,会帮助客户端瘦身,但之前的数据会永久在区块链中
+
+// 常见模式,让所有者结束合约并收回剩余的资金
+function remove() {
+ if(msg.sender == creator) { // 只有合约的创建者可以这么做
+ selfdestruct(creator); // 自毁合约,返还资金
+ }
+}
+
+// 可能希望手动停用合约,而不是自毁
+// (发送到自毁合约的 ether 会丢失掉)
+
+
+// 9. 注意合约的设计
+
+// A. 困惑
+// 区块链上所有变量都是公开可见的,因此任何私有的需求变得很困惑。(好比哈希的秘密)
+
+// 步骤: 1. 承诺某事, 2. 揭示承诺
+keccak256("some_bid_amount", "some secret"); // commit
+
+// 以后调用合约的 reveal 函数,展示出用 SHA3 哈希的 bid 加 secret
+reveal(100, "mySecret");
+
+// B. 存储优化
+// 写入区块链可能很昂贵,因为数据是永久存储的;鼓励用巧妙的方法使用内存
+//(最终,编译会更好,但现在有利于规划数据结构 - 并将最小数量存储在区块链中)
+
+// 多维数组这样的变量可能会成本很高
+// (成本用于存储数据 - 而不是声明未填充的变量)
+
+// C. 区块链中的数据访问
+// 不能限制人或计算机读取交易或交易状态的内容
+
+// 然而 'private' 可以防止其他*合约*直接读取数据 - 任意其他方仍然可以从区块链读取数据
+
+// 从开始的所有数据都存在区块链上,因此任何人都可以查看之前的所有数据和变化
+
+// D. 定时任务
+// 必须手动调用合约来处理时间相关的调度;也可以创建外部代码来定期的ping,
+// 或为其他人提供激励(以太)
+
+// E. 观察者模式
+//观察者模式允许您注册为订阅者,然后注册一个由oracle调用的函数
+//(注意,oracle 需要付费来运行此操作)。与 Pub / sub 中的订阅有些相似之处
+
+// 这是一个抽象合约,包括客户端和服务器端的类的导入,客户端应该要实现
+contract SomeOracleCallback {
+ function oracleCallback(int _value, uint _time, bytes32 info) external;
+}
+
+contract SomeOracle {
+ SomeOracleCallback[] callbacks; // 所有订阅者的数组
+
+ // 注册订阅者
+ function addSubscriber(SomeOracleCallback a) {
+ callbacks.push(a);
+ }
+
+ function notify(value, time, info) private {
+ for(uint i = 0;i < callbacks.length; i++) {
+ // 所有调用的订阅者必须实现 oracleCallback
+ callbacks[i].oracleCallback(value, time, info);
+ }
+ }
+
+ function doSomething() public {
+ // 实现的代码
+
+ // 通知所有的订阅者
+ notify(_value, _time, _info);
+ }
+}
+
+// 现在你的客户端合约可以通过 importing SomeOracleCallback 和注册某些 Oracle 来
+// addSubscriber 添加订阅者
+
+// F. 状态机
+// 参见如下的例子,枚举类型的 State 和 修饰器 inState
+
+
+// *** 例子: 众筹的例子(与 Kickstarter 大致相似)***
+// ** 开始例子 **
+
+// CrowdFunder.sol
+pragma solidity ^0.4.19;
+
+/// @title CrowdFunder
+/// @author nemild
+/// @translator bobjiang
+contract CrowdFunder {
+ // 由创建者创建的变量
+ address public creator;
+ address public fundRecipient; // 创建者可能和收件人不同
+ uint public minimumToRaise; // 需要提示,否则每个人都会得到退款
+ string campaignUrl;
+ byte constant version = 1;
+
+ // 数据结构
+ enum State {
+ Fundraising,
+ ExpiredRefund,
+ Successful
+ }
+ struct Contribution {
+ uint amount;
+ address contributor;
+ }
+
+ // 状态变量State variables
+ State public state = State.Fundraising; // 创建时实例化
+ uint public totalRaised;
+ uint public raiseBy;
+ uint public completeAt;
+ Contribution[] contributions;
+
+ event LogFundingReceived(address addr, uint amount, uint currentTotal);
+ event LogWinnerPaid(address winnerAddress);
+
+ modifier inState(State _state) {
+ require(state == _state);
+ _;
+ }
+
+ modifier isCreator() {
+ require(msg.sender == creator);
+ _;
+ }
+
+ // 允许合约销毁之前,最终合约状态后要等待24周
+ modifier atEndOfLifecycle() {
+ require(((state == State.ExpiredRefund || state == State.Successful) &&
+ completeAt + 24 weeks < now));
+ _;
+ }
+
+ function CrowdFunder(
+ uint timeInHoursForFundraising,
+ string _campaignUrl,
+ address _fundRecipient,
+ uint _minimumToRaise)
+ public
+ {
+ creator = msg.sender;
+ fundRecipient = _fundRecipient;
+ campaignUrl = _campaignUrl;
+ minimumToRaise = _minimumToRaise;
+ raiseBy = now + (timeInHoursForFundraising * 1 hours);
+ }
+
+ function contribute()
+ public
+ payable
+ inState(State.Fundraising)
+ returns(uint256 id)
+ {
+ contributions.push(
+ Contribution({
+ amount: msg.value,
+ contributor: msg.sender
+ }) // 采用数组,因此可以遍历
+ );
+ totalRaised += msg.value;
+
+ LogFundingReceived(msg.sender, msg.value, totalRaised);
+
+ checkIfFundingCompleteOrExpired();
+ return contributions.length - 1; // 返回 id
+ }
+
+ function checkIfFundingCompleteOrExpired()
+ public
+ {
+ if (totalRaised > minimumToRaise) {
+ state = State.Successful;
+ payOut();
+
+ // 可以激励在这里发起状态改变的人
+ } else if ( now > raiseBy ) {
+ state = State.ExpiredRefund; // 支持者可以通过调用 getRefund(id) 收取退款
+ }
+ completeAt = now;
+ }
+
+ function payOut()
+ public
+ inState(State.Successful)
+ {
+ fundRecipient.transfer(this.balance);
+ LogWinnerPaid(fundRecipient);
+ }
+
+ function getRefund(uint256 id)
+ inState(State.ExpiredRefund)
+ public
+ returns(bool)
+ {
+ require(contributions.length > id && id >= 0 && contributions[id].amount != 0 );
+
+ uint256 amountToRefund = contributions[id].amount;
+ contributions[id].amount = 0;
+
+ contributions[id].contributor.transfer(amountToRefund);
+
+ return true;
+ }
+
+ function removeContract()
+ public
+ isCreator()
+ atEndOfLifecycle()
+ {
+ selfdestruct(msg.sender);
+ // 创建者获得所有未被声明的钱
+ }
+}
+// ** 结束例子 **
+
+// 10. 其他原生的函数
+
+// 货币单位
+// 货币使用 wei 来定义,以太币的最小单位 = 1 wei;
+uint minAmount = 1 wei;
+uint a = 1 finney; // 1 ether == 1000 finney
+// 其他单位,请参阅: http://ether.fund/tool/converter
+
+// 时间单位
+1 == 1 second
+1 minutes == 60 seconds
+
+// 可以乘以带时间单位的变量,因为单位不会存储在变量中
+uint x = 5;
+(x * 1 days); // 5 天
+
+// 小心闰秒闰年与平等声明的时间
+// (相反,首选大于或小于)
+
+// 加密算法
+// 传递的所有字符串在哈希操作之前需要连接在一起
+sha3("ab", "cd");
+ripemd160("abc");
+sha256("def");
+
+// 11. 安全
+
+// 以太坊的合约中,错误可能是灾难性的 - 即使在 solidity 中是流行的模式,也可能发现是反模式的
+
+// 参见文档底部的安全链接
+
+// 12. 较低层次的函数
+// call - 较低层次,不会经常使用,不提供类型安全性
+successBoolean = someContractAddress.call('function_name', 'arg1', 'arg2');
+
+// callcode - 在调用合约的*上下文*中执行的目标地址上的代码
+// 提供库功能
+someContractAddress.callcode('function_name');
+
+
+// 13. 注意风格
+// 基于 Python 的 PEP8 风格指南
+// 全部风格指南: http://solidity.readthedocs.io/en/develop/style-guide.html
+
+// 快速总结:
+// 4个空格缩进
+// 两行隔开合约声明(和其他高级别的声明)
+// 避免括号内留出多余的空格
+// 可以省略一行语句的花括号 (if, for, 等)
+// else 应该单独一行
+
+
+// 14. NATSPEC 注释
+// 用于文档、注释和外部UI
+
+// 合约的 natspec - 总是在合约定义的上面
+/// @title 合约标题
+/// @author 作者名字
+
+// 函数的 natspec
+/// @notice 函数做什么的相关信息;展示什么时候执行该函数、
+/// @dev 开发者使用的函数文档
+
+// 函数参数、返回值的 natspec
+/// @param 有关参数用途的描述
+/// @return 返回值的描述
+```
+
+## 更多资源
+- [Solidity Docs](https://solidity.readthedocs.org/en/latest/)
+- [Smart Contract Best Practices](https://github.com/ConsenSys/smart-contract-best-practices)
+- [EthFiddle - The JsFiddle for Solidity](https://ethfiddle.com/)
+- [Browser-based Solidity Editor](https://remix.ethereum.org/)
+- [Gitter Solidity Chat room](https://gitter.im/ethereum/solidity)
+- [Modular design strategies for Ethereum Contracts](https://docs.erisindustries.com/tutorials/solidity/)
+
+## 重要的库文件
+- [Zeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/): Libraries that provide common contract patterns (crowdfuding, safemath, etc)
+
+## 示例合约
+- [Dapp Bin](https://github.com/ethereum/dapp-bin)
+- [Solidity Baby Step Contracts](https://github.com/fivedogit/solidity-baby-steps/tree/master/contracts)
+- [ConsenSys Contracts](https://github.com/ConsenSys/dapp-store-contracts)
+- [State of Dapps](http://dapps.ethercasts.com/)
+
+## 安全
+- [Thinking About Smart Contract Security](https://blog.ethereum.org/2016/06/19/thinking-smart-contract-security/)
+- [Smart Contract Security](https://blog.ethereum.org/2016/06/10/smart-contract-security/)
+- [Hacking Distributed Blog](http://hackingdistributed.com/)
+
+## 风格
+- [Solidity Style Guide](http://solidity.readthedocs.io/en/latest/style-guide.html): Ethereum's style guide is heavily derived from Python's [PEP 8](https://www.python.org/dev/peps/pep-0008/) style guide.
+
+## 编辑器
+- [Emacs Solidity Mode](https://github.com/ethereum/emacs-solidity)
+- [Vim Solidity](https://github.com/tomlion/vim-solidity)
+- Editor Snippets ([Ultisnips format](https://gist.github.com/nemild/98343ce6b16b747788bc))
+
+## Future to Dos
+- 新关键字: protected, inheritable
+- 常见设计模式列表 (throttling, RNG, version upgrade)
+- 常见的安全反模式
+
+请随意发送 pull request 或者发邮件给作者 nemild -/at-/ gmail
+
+或者发邮件给译者 jiangxb -/at-/ gmail.com
diff --git a/zh-cn/sql.html.markdown b/zh-cn/sql.html.markdown
new file mode 100644
index 00000000..9d430bd1
--- /dev/null
+++ b/zh-cn/sql.html.markdown
@@ -0,0 +1,105 @@
+---
+language: SQL
+filename: learnsql.sql
+contributors:
+ - ["Bob DuCharme", "http://bobdc.com/"]
+translators:
+ - ["Shuxin Shu", "https://github.com/NamelessAshone"]
+lang: zh-cn
+---
+
+结构化查询语言(SQL)是一个ISO标准语言,用于创建和管理数据库,
+这种数据库存储一系列表。不同的实现通常会添加特有的语言扩展;
+[不同SQL实现的比较(Comparison of different SQL implementat-
+ions)](http://troels.arvin.dk/db/rdbms/)是一份很好的产品差
+异参考文档。
+
+不同的实现通常会提供一个命令行用于交互式键入命令和显示输出,
+同时这些实现也会提供一种执行脚本文件的方法。(如何退出命令行
+就是就是SQL中尚未被标准化部分的一个典型例子,绝大多数SQL实
+现支持关键字QUIT、EXIT或者两者。)
+
+本文的实例命令假设你已经加载了[github](https://github.com/datacharmer/test_db)上的[MySQL示例员工数据库](https://dev.mysql.com/doc/employee/en/)。
+运行脚本的语法取决于你使用的SQL实现。通常是一个命令行工具。
+
+```sql
+
+-- 注释以两个连字符开始。命令以分号结束。
+
+-- SQL关键字大小写不敏感。在下文的示例命令中关键字大写,
+-- 因为大写更容易区分数据库、表和列名。
+
+-- 创建和删除一个数据库。数据库名和表名是大小写敏感的。
+CREATE DATABASE someDatabase;
+DROP DATABASE someDatabase;
+
+-- 列出可用的数据库。
+SHOW DATABASES;
+
+-- 使用某个已经存在的数据库
+USE employees;
+
+-- 从当前的departments表,选择所有的行和列
+-- 解释器的默认行为是将结果打印在屏幕上。
+SELECT * FROM departments;
+
+-- 检索departments表中所有的行,但只取dept_no和dept_name列。
+-- 一条命令可以跨越多行
+SELECT dept_no,
+ dept_name FROM departments;
+
+-- 检索departments表中所有的行,但是只输出5行。
+SELECT * FROM departments LIMIT 5;
+
+-- 检索departments表中dept_name列包含子串'en'的行。
+SELECT dept_name FROM departments WHERE dept_name LIKE '%en%';
+
+-- 检索departmnets表中所有dept_name列值为'S'开头并且'S'后接4个字符的行。
+SELECT * FROM departments WHERE dept_name LIKE 'S____';
+
+-- 检索title表中所有行,不显示重复的行。
+SELECT DISTINCT title FROM titles;
+
+-- 和上面的查询相同,但是以title的值排序(大小写敏感)。
+SELECT DISTINCT title FROM titles ORDER BY title;
+
+-- 计算departments表的总行数。
+SELECT COUNT(*) FROM departments;
+
+-- 计算departments表中dept_name列以'en'字段开头的行的数量。
+SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%';
+
+-- 不同表中信息的JOIN: titles表显示谁有什么工作,员工编号,
+-- 入职离职时间。检索这些信息,但是使用员工编号作为employees表
+-- 的交叉引用,而不是直接使用员工编号,来获得每个员工的名和姓。
+-- (同时只取10行)
+
+SELECT employees.first_name, employees.last_name,
+ titles.title, titles.from_date, titles.to_date
+FROM titles INNER JOIN employees ON
+ employees.emp_no = titles.emp_no LIMIT 10;
+
+-- 列出所有数据库中所有的表。不同实现通常提供各自的快捷命令
+-- 来列出当前使用数据库的所有表。
+SELECT * FROM INFORMATION_SCHEMA.TABLES
+WHERE TABLE_TYPE='BASE TABLE';
+
+-- 在当前使用的数据库中,创建一个名为tablename1的表,包含下
+-- 述两列。许多其它选项可用于定制列,比如列的数据类型。
+CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20));
+
+-- 向tablename1表插入一行数据。假设该表已经定义并且接受这些值。
+INSERT INTO tablename1 VALUES('Richard','Mutt');
+
+-- 更新tablename1表中lname为'Mutt'的行fname的值改为'John'。
+UPDATE tablename1 SET fname='John' WHERE lname='Mutt';
+
+-- 删除tablename1表lname列以'M'开头的行。
+DELETE FROM tablename1 WHERE lname like 'M%';
+
+-- 删除tablename1表的所有行,留下空表。
+DELETE FROM tablename1;
+
+-- 删除整个tablename1表。
+DROP TABLE tablename1;
+```
diff --git a/zh-cn/standard-ml-cn.html.markdown b/zh-cn/standard-ml-cn.html.markdown
new file mode 100644
index 00000000..269d6bc3
--- /dev/null
+++ b/zh-cn/standard-ml-cn.html.markdown
@@ -0,0 +1,438 @@
+---
+language: "Standard ML"
+contributors:
+ - ["Simon Shine", "http://shine.eu.org/"]
+ - ["David Pedersen", "http://lonelyproton.com/"]
+ - ["James Baker", "http://www.jbaker.io/"]
+ - ["Leo Zovic", "http://langnostic.inaimathi.ca/"]
+filename: standard-ml-cn.html
+translators:
+ - ["Buqian Zheng", "https://github.com/zhengbuqian"]
+lang: zh-cn
+---
+
+Standard ML是一门拥有类型推断和一些副作用的函数式编程语言。学习Standard ML的一些
+难点在于:递归、模式匹配和类型推断(猜测正确的类型但是决不允许隐式类型转换)。与Haskell的
+不同之处在于Standard ML拥有引用,允许对变量进行更新。
+
+```ocaml
+(* Standard ML的注释以 (* 开头,以 *) 结束。注释可以嵌套,也就意味着所有的 (* 标签都
+ 需要由一个 *) 结束。这条注释就是两个嵌套的注释的例子。*)
+
+(* 一个Standard ML程序包括声明,例如值声明: *)
+val rent = 1200
+val phone_no = 5551337
+val pi = 3.14159
+val negative_number = ~15 (* 是的,一元运算符用波浪符号`~`表示 *)
+
+(* 你当然也可以显示的声明类型,但这并不是必须的,因为ML会自动推断出值的类型。*)
+val diameter = 7926 : int
+val e = 2.718 : real
+val name = "Bobby" : string
+
+(* 同样重要的还有函数: *)
+fun is_large(x : int) = if x > 37 then true else false
+
+(* 浮点数被叫做实数: "real". *)
+val tau = 2.0 * pi (* 两个real可以相乘 *)
+val twice_rent = 2 * rent (* 两个int也可以相乘 *)
+(* val meh = 1.25 * 10 *) (* 但是你不能让int和real相乘。 *)
+val yeh = 1.25 * (Real.fromInt 10) (* ...除非你显示的把一个转换为另一个*)
+
+(* +, - 和 * 被重载过,所以可以作用于int和real。*)
+(* 但是除法有单独的运算符: *)
+val real_division = 14.0 / 4.0 (* 结果是 3.5 *)
+val int_division = 14 div 4 (* 结果是 3, 向下取整 *)
+val int_remainder = 14 mod 4 (* 结果是 2, 因为 3*4 = 12 *)
+
+(* ~ 有时其实是函数 (比如被放在变量前面的时候) *)
+val negative_rent = ~(rent) (* 即使rent是"real"也正确 *)
+
+(* 当然也有布尔值和相关的运算符 *)
+val got_milk = true
+val got_bread = false
+val has_breakfast = got_milk andalso got_bread (* 'andalso' 是运算符 *)
+val has_something = got_milk orelse got_bread (* 'orelse' 是运算符 *)
+val is_sad = not(has_something) (* not 是一个函数 *)
+
+(* 很多值都可以用判等性运算符进行比较: = 和 <> *)
+val pays_same_rent = (rent = 1300) (* false *)
+val is_wrong_phone_no = (phone_no <> 5551337) (* false *)
+
+(* <> 运算符就是其他大部分语言里的 != 。 *)
+(* 'andalso' 和 'orelse' 在很多其他语言里被叫做 && 和 || 。 *)
+
+(* 实际上,上面大部分的圆括号都是不需要的。比如表达上面内容的一些不同的方式: *)
+fun is_large x = x > 37
+val is_sad = not has_something
+val pays_same_rent = rent = 1300 (* 看起来很奇怪,但是就是这样的。 *)
+val is_wrong_phone_no = phone_no <> 5551337
+val negative_rent = ~rent (* ~ rent (注意空格) 也正确 *)
+
+(* 圆括号大部分时候用来把东西们组合在一起 *)
+val some_answer = is_large (5 + 5) (* 没有圆括号的话会出错! *)
+(* val some_answer = is_large 5 + 5 *) (* 会被理解为: (is_large 5) + 5. 错了! *)
+
+(* 除了boolean, int, real,Standard ML也有char和string *)
+val foo = "Hello, World!\n" (* \n是换行的转移字符 *)
+val one_letter = #"a" (* 这种酷炫的语法表示一个字符a *)
+
+val combined = "Hello " ^ "there, " ^ "fellow!\n" (* 拼接字符串 *)
+
+val _ = print foo (* 你可以打印一些东西,这儿我们队打印的结果并不感兴趣,因此 *)
+val _ = print combined (* 用 _ 把结果丢掉了 *)
+(* val _ = print one_letter *) (* 只有字符串才能被这样打印 *)
+
+
+val bar = [ #"H", #"e", #"l", #"l", #"o" ] (* SML 也有列表! *)
+(* val _ = print bar *) (* 然而列表和string是不同的 *)
+
+(* 当然这二者可以相互转换。String是一个库,implode和size是这个库里接受string作为
+ 参数的函数。*)
+val bob = String.implode bar (* 结果是 "Hello" *)
+val bob_char_count = String.size bob (* 结果是 5 *)
+val _ = print (bob ^ "\n") (* 为了好看加了个换行符 *)
+
+(* 列表可以包含任意类型的元素 *)
+val numbers = [1, 3, 3, 7, 229, 230, 248] (* : int list *)
+val names = [ "Fred", "Jane", "Alice" ] (* : string list *)
+
+(* 列表甚至可以包含列表! *)
+val groups = [ [ "Alice", "Bob" ],
+ [ "Huey", "Dewey", "Louie" ],
+ [ "Bonnie", "Clyde" ] ] (* : string list list *)
+
+val number_count = List.length numbers (* 结果是 7 *)
+
+(* 你可以使用 :: 操作符把单个值放到同样类型列表的最前面。
+ :: 叫做con操作符(名字来自Lisp) *)
+val more_numbers = 13 :: numbers (* 结果是 [13, 1, 3, 3, 7, ...] *)
+val more_groups = ["Batman","Superman"] :: groups
+
+(* 拥有同样类型元素的列表可以使用 @ 操作符连接起来 *)
+val guest_list = [ "Mom", "Dad" ] @ [ "Aunt", "Uncle" ]
+
+(* 使用 :: 操作符也能完成这项工作。但是这有点绕,因为左手边必须是单个元素
+ 而右边必须是这种元素的列表 *)
+val guest_list = "Mom" :: "Dad" :: [ "Aunt", "Uncle" ]
+val guest_list = "Mom" :: ("Dad" :: ("Aunt" :: ("Uncle" :: [])))
+
+(* 如果你有很多同样类型的列表,也可以整个拼接成一个。 *)
+val everyone = List.concat groups (* [ "Alice", "Bob", "Huey", ... ] *)
+
+(* 列表可以包含任意(无限)数量的元素 *)
+val lots = [ 5, 5, 5, 6, 4, 5, 6, 5, 4, 5, 7, 3 ] (* still just an int list *)
+
+(* 但是列表只能包含一种类型的元素 *)
+(* val bad_list = [ 1, "Hello", 3.14159 ] : ??? list *)
+
+(* 而元组Tuples则可以包含有限固定数量的不同类型的元素 *)
+val person1 = ("Simon", 28, 3.14159) (* : string * int * real *)
+
+(* 你甚至可以让列表和元组相互嵌套 *)
+val likes = [ ("Alice", "ice cream"),
+ ("Bob", "hot dogs"),
+ ("Bob", "Alice") ] (* : (string * string) list *)
+
+val mixup = [ ("Alice", 39),
+ ("Bob", 37),
+ ("Eve", 41) ] (* : (string * int) list *)
+
+val good_bad_stuff =
+ (["ice cream", "hot dogs", "chocolate"],
+ ["liver", "paying the rent" ]) (* : string list * string list *)
+
+(* 记录Record是每个位置带名字的元组 *)
+
+val rgb = { r=0.23, g=0.56, b=0.91 } (* : {b:real, g:real, r:real} *)
+
+(* 使用Record时不需要提前声明每个位置的名字。 有不同名字的Record属于不同的类型
+ 即使他们的值的类型是相同的。比如说:*)
+val Hsl = { H=310.3, s=0.51, l=0.23 } (* : {H:real, l:real, s:real} *)
+val Hsv = { H=310.3, s=0.51, v=0.23 } (* : {H:real, s:real, v:real} *)
+
+(* ...如果你想判断 `Hsv = Hsl` 或者 `rgb = Hsl` 的话,会得到一个类型错误。虽然他们都包含3个
+ real,但是由于名字不同,其类型也不同。 *)
+
+(* 可以使用 # 符号取出元组的值 *)
+
+val H = #H Hsv (* : real *)
+val s = #s Hsl (* : real *)
+
+(* 函数! *)
+fun add_them (a, b) = a + b (* 一个简单的加法函数 *)
+val test_it = add_them (3, 4) (* 结果是 7 *)
+
+(* 复杂函数通常会为了可读性写成多行 *)
+fun thermometer temp =
+ if temp < 37
+ then "Cold"
+ else if temp > 37
+ then "Warm"
+ else "Normal"
+
+val test_thermo = thermometer 40 (* 结果是 "Warm" *)
+
+(* if 实际上是表达式而不是声明。一个函数体只可以包含一个表达式。但是还是有一些小技巧
+ 让一个函数做更多的事。 *)
+
+(* 函数也可以使用调用自己的结果 (递归!) *)
+fun fibonacci n =
+ if n = 0 then 0 else (* 终止条件 *)
+ if n = 1 then 1 else (* 终止条件 *)
+ fibonacci (n - 1) + fibonacci (n - 2) (* 递归 *)
+
+(* 有的时候,手写出递归函数的执行过程能帮助理解递归概念:
+
+ fibonacci 4
+ ~> fibonacci (4 - 1) + fibonacci (4 - 2)
+ ~> fibonacci 3 + fibonacci 2
+ ~> (fibonacci (3 - 1) + fibonacci (3 - 2)) + fibonacci 2
+ ~> (fibonacci 2 + fibonacci 1) + fibonacci 2
+ ~> ((fibonacci (2 - 1) + fibonacci (2 - 2)) + fibonacci 1) + fibonacci 2
+ ~> ((fibonacci 1 + fibonacci 0) + fibonacci 1) + fibonacci 2
+ ~> ((1 + fibonacci 0) + fibonacci 1) + fibonacci 2
+ ~> ((1 + 0) + fibonacci 1) + fibonacci 2
+ ~> (1 + fibonacci 1) + fibonacci 2
+ ~> (1 + 1) + fibonacci 2
+ ~> 2 + fibonacci 2
+ ~> 2 + (fibonacci (2 - 1) + fibonacci (2 - 2))
+ ~> 2 + (fibonacci (2 - 1) + fibonacci (2 - 2))
+ ~> 2 + (fibonacci 1 + fibonacci 0)
+ ~> 2 + (1 + fibonacci 0)
+ ~> 2 + (1 + 0)
+ ~> 2 + 1
+ ~> 3 第四个斐波那契数
+
+ *)
+
+(* 函数不能改变它引用的值。它只能暂时的使用同名的新变量来覆盖这个值。也就是说,变量其实是
+ 常数,只有在递归的时候才表现的比较像变量。因此,变量也被叫做值绑定。举个例子: *)
+
+val x = 42
+fun answer(question) =
+ if question = "What is the meaning of life, the universe and everything?"
+ then x
+ else raise Fail "I'm an exception. Also, I don't know what the answer is."
+val x = 43
+val hmm = answer "What is the meaning of life, the universe and everything?"
+(* 现在 hmm 的值是 42。 这是因为函数 answer 引用的x是函数定义之前的x。 *)
+
+(* 函数通过接受一个元组来接受多个参数。 *)
+fun solve2 (a : real, b : real, c : real) =
+ ((~b + Math.sqrt(b * b - 4.0 * a * c)) / (2.0 * a),
+ (~b - Math.sqrt(b * b - 4.0 * a * c)) / (2.0 * a))
+
+(* 有时候同样的计算会被计算多次,因此把结果保存下来以重复使用是很有必要的。
+ 这时可以使用 let 绑定。 *)
+fun solve2 (a : real, b : real, c : real) =
+ let val discr = b * b - 4.0 * a * c
+ val sqr = Math.sqrt discr
+ val denom = 2.0 * a
+ in ((~b + sqr) / denom,
+ (~b - sqr) / denom)
+ end
+
+(* 模式匹配是函数式编程的一个精巧的部分,它是实现 if 的另一种方式。
+ 斐波那契函数可以被重写为如下方式: *)
+fun fibonacci 0 = 0 (* 终止条件 *)
+ | fibonacci 1 = 1 (* 终止条件 *)
+ | fibonacci n = fibonacci (n - 1) + fibonacci (n - 2) (* 递归 *)
+
+(* 模式匹配也可以用于比如元组、列表和记录的复合类型。"fun solve2 (a, b, c) = ..."
+ 的写法实际上也是对于一个三元素元组的模式匹配。类似但是比较不直观的是你也可以从列表的开头
+ 对列表元素进行匹配。 *)
+fun first_elem (x::xs) = x
+fun second_elem (x::y::xs) = y
+fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs
+ | evenly_positioned_elems [odd] = [] (* 终止条件:丢弃结果 *)
+ | evenly_positioned_elems [] = [] (* 终止条件 *)
+
+(* 匹配记录的时候,比如使用每个位置的名字,每个位置的值都需要绑定,但是顺序并不重要。 *)
+
+fun rgbToTup {r, g, b} = (r, g, b) (* fn : {b:'a, g:'b, r:'c} -> 'c * 'b * 'a *)
+fun mixRgbToTup {g, b, r} = (r, g, b) (* fn : {b:'a, g:'b, r:'c} -> 'c * 'b * 'a *)
+
+(* 如果传入参数 {r=0.1, g=0.2, b=0.3},上面的两个函数都会返回 (0.1, 0.2, 0.3)。
+ 但是传入参数 {r=0.1, g=0.2, b=0.3, a=0.4} 的话则会得到类型错误 *)
+
+(* 高阶函数: 可以接受其他函数作为参数的函数
+ 函数只不过是另一种类型的值,不需要依附与一个名字而存在。
+ 没有名字的函数被叫做匿名函数或者lambda表达式或者闭包(因为匿名函数也依赖于词法作用域)*)
+val is_large = (fn x => x > 37)
+val add_them = fn (a,b) => a + b
+val thermometer =
+ fn temp => if temp < 37
+ then "Cold"
+ else if temp > 37
+ then "Warm"
+ else "Normal"
+
+(* 下面的代码就是用了匿名函数,结果是 "ColdWarm" *)
+val some_result = (fn x => thermometer (x - 5) ^ thermometer (x + 5)) 37
+
+(* 这是一个作用于列表的高阶函数 *)
+(* map f l
+ 把f从左至右作用于l的每一个元素,并返回结果组成的列表。 *)
+val readings = [ 34, 39, 37, 38, 35, 36, 37, 37, 37 ] (* 先定义一个列表 *)
+val opinions = List.map thermometer readings (* 结果是 [ "Cold", "Warm", ... ] *)
+
+(* filter 函数用于筛选列表 *)
+val warm_readings = List.filter is_large readings (* 结果是 [39, 38] *)
+
+(* 你也可以创建自己的高阶函数。函数也可以通过 curry 来接受多个参数。
+ 从语法上来说,curry就是使用空格来分隔参数,而不是逗号和括号。 *)
+fun map f [] = []
+ | map f (x::xs) = f(x) :: map f xs
+
+(* map 的类型是 ('a -> 'b) -> 'a list -> 'b list ,这就是多态。 *)
+(* 'a 被叫做类型变量 *)
+
+
+(* 函数可以被声明为中缀的。 *)
+val plus = add_them (* plus 现在和 add_them 是同一个函数。 *)
+infix plus (* plus 现在是一个中缀操作符。 *)
+val seven = 2 plus 5 (* seven 现在被绑定上了 7 *)
+
+(* 函数也可以在声明之前就声明为中缀 *)
+infix minus
+fun x minus y = x - y (* 这样有点不容易判断哪个是参数。 *)
+val four = 8 minus 4 (* four 现在被绑定上了 4 *)
+
+(* 中缀函数/操作符也可以使用 'op' 函数变回前缀函数。 *)
+val n = op + (5, 5) (* n is now 10 *)
+
+(* 'op' 在结合高阶函数的时候非常有用,因为高阶函数接受的是函数而不是操作符作为参数。
+ 大部分的操作符其实都是中缀函数。 *)
+(* foldl f init [x1, x2, ..., xn]
+ 返回
+ f(xn, ...f(x2, f(x1, init))...)
+ 或者如果列表为空时返回 init *)
+val sum_of_numbers = foldl op+ 0 [1, 2, 3, 4, 5]
+
+
+(* 可以很方便的使用 datatype 定义或简单或复杂的数据结构。 *)
+datatype color = Red | Green | Blue
+
+(* 这个函数接受 color 之一作为参数。 *)
+fun say(col) =
+ if col = Red then "You are red!" else
+ if col = Green then "You are green!" else
+ if col = Blue then "You are blue!" else
+ raise Fail "Unknown color"
+
+val _ = print (say(Red) ^ "\n")
+
+(* datatype 经常和模式匹配一起使用。 *)
+fun say Red = "You are red!"
+ | say Green = "You are green!"
+ | say Blue = "You are blue!"
+ | say _ = raise Fail "Unknown color"
+
+
+(* 一个二叉树 datatype *)
+datatype 'a btree = Leaf of 'a
+ | Node of 'a btree * 'a * 'a btree (* 三个参数的构造器 *)
+
+(* 一颗二叉树: *)
+val myTree = Node (Leaf 9, 8, Node (Leaf 3, 5, Leaf 7))
+
+(* 画出来应该是这个样子:
+
+ 8
+ / \
+ leaf -> 9 5
+ / \
+ leaf -> 3 7 <- leaf
+ *)
+
+(* 这个函数计算所有节点值的和。 *)
+fun count (Leaf n) = n
+ | count (Node (leftTree, n, rightTree)) = count leftTree + n + count rightTree
+
+val myTreeCount = count myTree (* myTreeCount is now bound to 32 *)
+
+
+(* 异常! *)
+(* 使用关键字 'raise' 来抛出异常: *)
+fun calculate_interest(n) = if n < 0.0
+ then raise Domain
+ else n * 1.04
+
+(* 使用 "handle" 关键字来处理异常 *)
+val balance = calculate_interest ~180.0
+ handle Domain => ~180.0 (* x 现在的值是 ~180.0 *)
+
+(* 某些异常还包含额外信息 *)
+(* 一些内建异常的例子: *)
+fun failing_function [] = raise Empty (* 空列表异常 *)
+ | failing_function [x] = raise Fail "This list is too short!"
+ | failing_function [x,y] = raise Overflow (* 用作计算 *)
+ | failing_function xs = raise Fail "This list is too long!"
+
+(* 使用 'handle' 时也可以使用模式匹配来保证异常都被处理。 *)
+val err_msg = failing_function [1,2] handle Fail _ => "Fail was raised"
+ | Domain => "Domain was raised"
+ | Empty => "Empty was raised"
+ | _ => "Unknown exception"
+
+(* err_msg 的值会是 "Unknown exception"
+ 因为 Overflow 没有在模式中列出,因此匹配到了通配符_。 *)
+
+(* 我们也可以定义自己的异常 *)
+exception MyException
+exception MyExceptionWithMessage of string
+exception SyntaxError of string * (int * int)
+
+(* 文件读写! *)
+(* 把一首诗写进文件: *)
+fun writePoem(filename) =
+ let val file = TextIO.openOut(filename)
+ val _ = TextIO.output(file, "Roses are red,\nViolets are blue.\n")
+ val _ = TextIO.output(file, "I have a gun.\nGet in the van.\n")
+ in TextIO.closeOut(file)
+ end
+
+(* 把一首诗读进一个字符串列表: *)
+fun readPoem(filename) =
+ let val file = TextIO.openIn filename
+ val poem = TextIO.inputAll file
+ val _ = TextIO.closeIn file
+ in String.tokens (fn c => c = #"\n") poem
+ end
+
+val _ = writePoem "roses.txt"
+val test_poem = readPoem "roses.txt" (* gives [ "Roses are red,",
+ "Violets are blue.",
+ "I have a gun.",
+ "Get in the van." ] *)
+
+(* 我们还可以创建指向值的引用,引用可以被更新。 *)
+val counter = ref 0 (* 使用 ref 函数创建一个引用。 *)
+
+(* 使用赋值运算符给引用复制 *)
+fun set_five reference = reference := 5
+
+(* 使用解引用运算符得到引用的值 *)
+fun equals_five reference = !reference = 5
+
+(* 递归很复杂的时候,也可以使用 while 循环 *)
+fun decrement_to_zero r = if !r < 0
+ then r := 0
+ else while !r >= 0 do r := !r - 1
+
+(* 这将会返回 unit (也就是什么都没有,一个0元素的元组) *)
+
+(* 要返回值,可以使用分号来分开表达式。 *)
+fun decrement_ret x y = (x := !x - 1; y)
+```
+
+## 阅读更多
+
+* 安装交互式编译器 (REPL),如:
+ [Poly/ML](http://www.polyml.org/),
+ [Moscow ML](http://mosml.org),
+ [SML/NJ](http://smlnj.org/).
+* 上Coursera上的课程 [Programming Languages](https://www.coursera.org/course/proglang).
+* 购买 Larry C. Paulson 写的 *ML for the Working Programmer* 书。
+* 使用 [StackOverflow's sml 标签](http://stackoverflow.com/questions/tagged/sml).
diff --git a/zh-cn/swift-cn.html.markdown b/zh-cn/swift-cn.html.markdown
index cba9252d..18bc52ed 100644
--- a/zh-cn/swift-cn.html.markdown
+++ b/zh-cn/swift-cn.html.markdown
@@ -110,7 +110,7 @@ anyObjectVar = "Changed value to a string, not good practice, but possible."
//
-// Mark: 数组与字典(关联数组)
+// MARK: 数组与字典(关联数组)
//
/*
@@ -214,9 +214,9 @@ func greet(name: String, day: String) -> String {
}
greet("Bob", day: "Tuesday")
-// 第一个参数表示外部参数名和内部参数名使用同一个名称。
+// 第一个参数`_`表示不使用外部参数名,忽略`_`表示外部参数名和内部参数名使用同一个名称。
// 第二个参数表示外部参数名使用 `externalParamName` ,内部参数名使用 `localParamName`
-func greet2(requiredName requiredName: String, externalParamName localParamName: String) -> String {
+func greet2(_ requiredName: String, externalParamName localParamName: String) -> String {
return "Hello \(requiredName), the day is \(localParamName)"
}
greet2(requiredName:"John", externalParamName: "Sunday") // 调用时,使用命名参数来指定参数的值
@@ -250,7 +250,7 @@ var increment = makeIncrementer()
increment(7)
// 强制进行指针传递 (引用传递),使用 `inout` 关键字修饰函数参数
-func swapTwoInts(inout a: Int, inout b: Int) {
+func swapTwoInts(a: inout Int, b: inout Int) {
let tempA = a
a = b
b = tempA
@@ -445,47 +445,47 @@ if let circle = myEmptyCircle {
// 枚举可以像类一样,拥有方法
enum Suit {
- case Spades, Hearts, Diamonds, Clubs
+ case spades, hearts, diamonds, clubs
func getIcon() -> String {
switch self {
- case .Spades: return "♤"
- case .Hearts: return "♡"
- case .Diamonds: return "♢"
- case .Clubs: return "♧"
+ case .spades: return "♤"
+ case .hearts: return "♡"
+ case .diamonds: return "♢"
+ case .clubs: return "♧"
}
}
}
// 当变量类型明确指定为某个枚举类型时,赋值时可以省略枚举类型
-var suitValue: Suit = .Hearts
+var suitValue: Suit = .hearts
// 非整型的枚举类型需要在定义时赋值
enum BookName: String {
- case John = "John"
- case Luke = "Luke"
+ case john = "John"
+ case luke = "Luke"
}
-print("Name: \(BookName.John.rawValue)")
+print("Name: \(BookName.john.rawValue)")
// 与特定数据类型关联的枚举
enum Furniture {
// 和 Int 型数据关联的枚举记录
- case Desk(height: Int)
+ case desk(height: Int)
// 和 String, Int 关联的枚举记录
- case Chair(brand: String, height: Int)
+ case chair(brand: String, height: Int)
func description() -> String {
switch self {
- case .Desk(let height):
+ case .desk(let height):
return "Desk with \(height) cm"
- case .Chair(let brand, let height):
+ case .chair(let brand, let height):
return "Chair of \(brand) with \(height) cm"
}
}
}
-var desk: Furniture = .Desk(height: 80)
+var desk: Furniture = .desk(height: 80)
print(desk.description()) // "Desk with 80 cm"
-var chair = Furniture.Chair(brand: "Foo", height: 40)
+var chair = Furniture.chair(brand: "Foo", height: 40)
print(chair.description()) // "Chair of Foo with 40 cm"
@@ -521,7 +521,7 @@ class MyShape: Rect {
// 在 optional 属性,方法或下标运算符后面加一个问号,可以优雅地忽略 nil 值,返回 nil。
// 这样就不会引起运行时错误 (runtime error)
- if let reshape = self.delegate?.canReshape?() where reshape {
+ if let reshape = self.delegate?.canReshape?() {
// 注意语句中的问号
self.delegate?.reshape?()
}
@@ -575,10 +575,10 @@ print(foundAtIndex == 2) // true
// 自定义运算符可以以下面的字符打头:
// / = - + * % < > ! & | ^ . ~
// 甚至是 Unicode 的数学运算符等
-prefix operator !!! {}
+prefix operator !!!
// 定义一个前缀运算符,使矩形的边长放大三倍
-prefix func !!! (inout shape: Square) -> Square {
+prefix func !!! (shape: inout Square) -> Square {
shape.sideLength *= 3
return shape
}
@@ -591,8 +591,8 @@ print(mySquare.sideLength) // 4
print(mySquare.sideLength) // 12
// 运算符也可以是泛型
-infix operator <-> {}
-func <-><T: Equatable> (inout a: T, inout b: T) {
+infix operator <->
+func <-><T: Equatable> (a: inout T, b: inout T) {
let c = a
a = b
b = c
diff --git a/zh-cn/typescript-cn.html.markdown b/zh-cn/typescript-cn.html.markdown
index 2651b1cb..5d6153da 100644
--- a/zh-cn/typescript-cn.html.markdown
+++ b/zh-cn/typescript-cn.html.markdown
@@ -9,97 +9,103 @@ filename: learntypescript-cn.ts
lang: zh-cn
---
-TypeScript是一门为开发大型JavaScript应用而设计的语言。TypeScript在JavaScript的基础上增加了类、模块、接口、泛型和静态类型(可选)等常见的概念。它是JavaScript的一个超集:所有JavaScript代码都是有效的TypeScript代码,所以任何JavaScript项目都可以无缝引入TypeScript. TypeScript编译器会把TypeScript代码编译成JavaScript代码。
+TypeScript 是一门为开发大型 JavaScript 应用而设计的语言。TypeScript 在 JavaScript 的基础上增加了类、模块、接口、泛型和静态类型(可选)等常见的概念。它是 JavaScript 的超集:所有 JavaScript 代码都是有效的 TypeScript 代码,因此任何 JavaScript 项目都可以无缝引入 TypeScript,TypeScript 编译器最终会把 TypeScript 代码编译成 JavaScript 代码。
-本文只关注TypeScript额外增加的区别于[JavaScript](../javascript-cn/)的语法,.
+本文只关注 TypeScript 额外增加的区别于 [JavaScript](../javascript-cn/) 的语法,.
-如需测试TypeScript编译器,你可以在[Playground](http://www.typescriptlang.org/Playground)码代码,它会自动编译成JavaScript代码然后直接显示出来。
+如需测试 TypeScript 编译器,你可以到 [Playground](https://www.typescriptlang.org/play/) 编写代码,它会自动将你编写的 TypeScript 代码编译成 JavaScript 代码后,在右侧即时展示出来。
-```js
-// TypeScript有三种基本类型
-var isDone: boolean = false;
-var lines: number = 42;
-var name: string = "Anders";
+```ts
+// TypeScript 有三种基本类型,布尔类型、数值类型、字符串类型
+let isDone: boolean = false;
+let lines: number = 42;
+let name: string = 'Anders';
-// 如果不知道是什么类型,可以使用"any"(任意)类型
-var notSure: any = 4;
-notSure = "maybe a string instead";
-notSure = false; // 亦可,定义为布尔型
+// 如果不知道是什么类型,可以使用 "any" (任意)类型
+let notSure: any = 4;
+notSure = '可以重新赋值,转换为字符串类型';
+notSure = false; // 亦可,重新定义为布尔类型
-// 对于集合的声明, 有类型化数组和泛型数组
-var list: number[] = [1, 2, 3];
-// 另外一种,使用泛型数组
-var list: Array<number> = [1, 2, 3];
+// 使用 const 关键字将一个字面量修饰为常量
+const numLivesForCat = 9;
+numLivesForCat = 1; // 常量不能重新被赋值,所以这里会报错
+
+// TypeScript 中的 collection 有两种表示形式, 一种是有类型的数组,另一种是泛型数组
+let list: number[] = [1, 2, 3];
+// 或者,使用泛型数组
+let list: Array<number> = [1, 2, 3];
// 枚举:
-enum Color {Red, Green, Blue};
-var c: Color = Color.Green;
+enum Color {Red, Green, Blue}
+let c: Color = Color.Green;
-// 最后,"void"用于函数没有任何返回的特殊情况下
+// 最后是 "void",它用于表明函数没有任何返回值的特殊情况
function bigHorribleAlert(): void {
- alert("I'm a little annoying box!");
+ alert('我是个烦人的弹出框!');
}
-// 函数是"第一等公民"(first class citizens), 支持使用箭头表达式和类型推断
-
-// 以下是相等的,TypeScript编译器会把它们编译成相同的JavaScript代码
-var f1 = function(i: number): number { return i * i; }
-// 返回推断类型的值
-var f2 = function(i: number) { return i * i; }
-var f3 = (i: number): number => { return i * i; }
-// 返回推断类型的值
-var f4 = (i: number) => { return i * i; }
-// 返回推断类型的值, 单行程式可以不需要return关键字和大括号
-var f5 = (i: number) => i * i;
-
-// 接口是结构化的,任何具有这些属性的对象都与该接口兼容
+// 函数是"一等公民"(first class citizens), 支持使用 lambda 胖箭头表达式和类型推断
+
+// 以下 f1-f5 五个函数是等价的,TypeScript 编译器会把它们编译成相同的 JavaScript 代码(可以到 Playground 验证)
+// 一般的函数
+let f1 = function(i: number): number { return i * i; };
+// 根据返回值推断函数返回类型
+let f2 = function(i: number) { return i * i; };
+// 胖箭头表达式
+let f3 = (i: number): number => { return i * i; };
+// 根据返回值推断返回类型的胖箭头表达式
+let f4 = (i: number) => { return i * i; };
+// 根据返回值推断返回类型的胖箭头表达式, 省略花括号的同时,可以同时省去 return 关键字
+let f5 = (i: number) => i * i;
+
+// 接口是结构化的,任何具备接口中声明的全部属性的对象,都与该接口兼容
interface Person {
name: string;
- // 可选属性,使用"?"标识
+ // 使用 "?" 标识,表明该属性是一个非必需属性
age?: number;
// 函数
move(): void;
}
-// 实现"Person"接口的对象,当它有了"name"和"move"方法之后可被视为一个"Person"
-var p: Person = { name: "Bobby", move: () => {} };
-// 带了可选参数的对象
-var validPerson: Person = { name: "Bobby", age: 42, move: () => {} };
-// 因为"age"不是"number"类型所以这不是一个"Person"
-var invalidPerson: Person = { name: "Bobby", age: true };
+// 实现 "Person" 接口的对象,当它具备 "name" 属性和 "move" 方法之后可被视为一个 "Person"
+let p: Person = { name: 'Bobby', move: () => {} };
+// 带可选属性的对象
+let validPerson: Person = { name: 'Bobby', age: 42, move: () => {} };
+// 由于该对象 "age" 属性的类型不是 "number" ,所以这不是一个 "Person"
+let invalidPerson: Person = { name: 'Bobby', age: true };
// 接口同样可以描述一个函数的类型
interface SearchFunc {
(source: string, subString: string): boolean;
}
-// 参数名并不重要,参数类型才是重要的
-var mySearch: SearchFunc;
+// 参数名并不重要,参数类型才是最重要的
+let mySearch: SearchFunc;
mySearch = function(src: string, sub: string) {
- return src.search(sub) != -1;
-}
+ return src.search(sub) !== -1;
+};
-// 类 - 成员默认为公共的(public)
+// 类 - 成员访问权限默认都是公共的 (public)
class Point {
- // 属性
+ // 成员属性
x: number;
- // 构造器 - 这里面的public/private关键字会为属性生成样板代码和初始化值
- // 这个例子中,y会被同x一样定义,不需要额外代码
- // 同样支持默认值
+ // 构造器 - 在构造器中使用 public/private 关键字修饰的变量,会被声明为类的成员属性。
+ // 下面这个例子中,y 会像 x 一样被声明定义为类成员属性,而不再需要额外代码
+ // 声明时,同样支持指定默认值
constructor(x: number, public y: number = 0) {
this.x = x;
}
- // 函数
+ // 成员函数
dist() { return Math.sqrt(this.x * this.x + this.y * this.y); }
// 静态成员
static origin = new Point(0, 0);
}
-var p1 = new Point(10 ,20);
-var p2 = new Point(25); //y为0
+let p1 = new Point(10 , 20);
+let p2 = new Point(25); // y 为构造器中指定的默认值:0
// 继承
class Point3D extends Point {
@@ -107,14 +113,14 @@ class Point3D extends Point {
super(x, y); // 必须显式调用父类的构造器
}
- // 重写
+ // 重写父类中的 dist() 函数
dist() {
- var d = super.dist();
+ let d = super.dist();
return Math.sqrt(d * d + this.z * this.z);
}
}
-// 模块, "."可以作为子模块的分隔符
+// 模块, "." 符号可以作为子模块的分隔符
module Geometry {
export class Square {
constructor(public sideLength: number = 0) {
@@ -125,12 +131,12 @@ module Geometry {
}
}
-var s1 = new Geometry.Square(5);
+let s1 = new Geometry.Square(5);
-// 引入模块并定义本地别名
+// 为模块创建一个本地别名
import G = Geometry;
-var s2 = new G.Square(10);
+let s2 = new G.Square(10);
// 泛型
// 类
@@ -146,21 +152,21 @@ interface Pair<T> {
}
// 以及函数
-var pairToTuple = function<T>(p: Pair<T>) {
+let pairToTuple = function<T>(p: Pair<T>) {
return new Tuple(p.item1, p.item2);
};
-var tuple = pairToTuple({ item1:"hello", item2:"world"});
+let tuple = pairToTuple({ item1: 'hello', item2: 'world'});
// 引用定义文件
-// <reference path="jquery.d.ts" />
+/// <reference path="jquery.d.ts" />
// 模板字符串(使用反引号的字符串)
// 嵌入变量的模板字符串
-var name = 'Tyrone';
-var greeting = `Hi ${name}, how are you?`
+let name = 'Tyrone';
+let greeting = `Hi ${name}, how are you?`;
// 有多行内容的模板字符串
-var multiline = `This is an example
+let multiline = `This is an example
of a multiline string`;
```
diff --git a/zh-cn/vim-cn.html.markdown b/zh-cn/vim-cn.html.markdown
index 5298351a..22dbace6 100644
--- a/zh-cn/vim-cn.html.markdown
+++ b/zh-cn/vim-cn.html.markdown
@@ -10,7 +10,7 @@ lang: zh-cn
---
-[Vim](www.vim.org)
+[Vim](http://www.vim.org)
(Vi IMproved) 是 Unix 上的流行编辑器 vi 的克隆版本。这个文本编辑器
是为性能和提升效率而设计的,并且在大多数基于 unix 的系统上普遍存在。
它有大量的快捷键可用来快速导航到文件的特定位置,以便进行快速编辑。
@@ -56,14 +56,16 @@ lang: zh-cn
t<字符> # 向前跳移到 <字符> 的左侧
# 例如,
- f< # 向前跣到 < 上
+    f<               # 向前跳移到 < 上
t< # 向前跳移到 < 的左侧
# 按词移动
+ # 默认一个单词由字母,数字和下划线组成
- w # 前移一个词
- b # 后移一个词
- e # 移到当前词的末尾
+    w               # 移动到下一个词首
+    b               # 移动到前一个词首
+    e               # 移动到下一个词尾
+
# 移动的其它命令
diff --git a/zh-cn/visualbasic-cn.html.markdown b/zh-cn/visualbasic-cn.html.markdown
index 59f18fe2..e30041b3 100644
--- a/zh-cn/visualbasic-cn.html.markdown
+++ b/zh-cn/visualbasic-cn.html.markdown
@@ -5,10 +5,10 @@ contributors:
translators:
- ["Abner Chou", "http://cn.abnerchou.me"]
lang: zh-cn
-filename: learnvisualbasic.vb-cn
+filename: learnvisualbasic-cn.vb
---
-```vb
+```
Module Module1
Sub Main()
@@ -77,7 +77,7 @@ Module Module1
' 使用 private subs 声明函数。
Private Sub HelloWorldOutput()
' 程序名
- Console.Title = "Hello World Ouput | Learn X in Y Minutes"
+ Console.Title = "Hello World Output | Learn X in Y Minutes"
' 使用 Console.Write("") 或者 Console.WriteLine("") 来输出文本到屏幕上
' 对应的 Console.Read() 或 Console.Readline() 用来读取键盘输入
Console.WriteLine("Hello World")
diff --git a/zh-cn/yaml-cn.html.markdown b/zh-cn/yaml-cn.html.markdown
index bbda20e9..cfa22dfb 100644
--- a/zh-cn/yaml-cn.html.markdown
+++ b/zh-cn/yaml-cn.html.markdown
@@ -1,43 +1,50 @@
---
language: yaml
contributors:
- - ["Adam Brenecki", "https://github.com/adambrenecki"]
+ - ["Leigh Brenecki", "https://github.com/adambrenecki"]
translators:
- ["Zach Zhang", "https://github.com/checkcheckzz"]
- ["Jiang Haiyun", "https://github.com/haiiiiiyun"]
+ - ["Wen Sun", "https://github.com/HermitSun"]
filename: learnyaml-cn.yaml
lang: zh-cn
---
-YAML 是一个数据序列化语言,被设计成人类直接可写可读的。
+YAML 是一种数据序列化语言,旨在让人类直接可写可读。
-它是 JSON 的严格超集,增加了语法显著换行符和缩进,就像 Python。但和 Python 不一样,
-YAML 根本不容许文字制表符。
+它是 JSON 的严格超集,增加了*在语法上有意义的*(syntactically significant)换行符和缩进,就像 Python 一样。但和 Python 的不同之处在于,YAML 不允许使用*文字制表符*(literal tab characters)来表示缩进。
```yaml
-# YAML 中的注解看起来像这样。
+--- # 文档开头
+
+# YAML 中的注释看起来像这样。
################
# 标量类型 #
################
-# 我们的根对象 (它们在整个文件里延续) 将会是一个映射,
-# 它等价于在别的语言里的一个字典,哈西表或对象。
+# 我们的根对象 (贯穿整个文档的始终) 是一个映射(map),
+# 它等价于其它语言中的一个字典(dictionary),哈希表(hash)或对象(object)。
key: value
another_key: Another value goes here.
a_number_value: 100
-# 如果你想将数字 1 作为值,你必须要将它括在引号中。
-# 不然 YAML 解析器会假定它是一个布尔值 true。
+# 数字 1 会被解释为数值,而不是一个布尔值。
+# 如果你想要的是一个布尔值,使用 true。
scientific_notation: 1e+12
boolean: true
null_value: null
key with spaces: value
-# 注意到字符串不需要被括在引号中。但是,它们可以被括起来。
-"Keys can be quoted too.": "Useful if you want to put a ':' in your key."
-
-# 多行字符串既可以写成像一个'文字块'(使用 |),
-# 或像一个'折叠块'(使用 '>')。
+# 注意,字符串可以不括在引号里。当然,也可以括在引号里。
+however: 'A string, enclosed in quotes.'
+'Keys can be quoted too.': "Useful if you want to put a ':' in your key."
+single quotes: 'have ''one'' escape pattern'
+double quotes: "have many: \", \0, \t, \u263A, \x0d\x0a == \r\n, and more."
+# UTF-8/16/32字符需要指明编码(通过\u)。
+Superscript two: \u00B2
+
+# 多行字符串既可以写成一个'字面量块'(使用 '|'),
+# 也可以写成一个'折叠块'(使用 '>')。
literal_block: |
This entire block of text will be the value of the 'literal_block' key,
with line breaks being preserved.
@@ -60,85 +67,92 @@ folded_style: >
# 集合类型 #
####################
-# 嵌套是通过缩进完成的。
+# 嵌套是通过缩进完成的。推荐使用 2 个空格的缩进(但非必须)。
a_nested_map:
- key: value
- another_key: Another Value
- another_nested_map:
- hello: hello
+ key: value
+ another_key: Another Value
+ another_nested_map:
+ hello: hello
-# 映射的键值不必是字符串。
+# 映射的键不必是字符串。
0.25: a float key
-# 键值也可以是复合型的,比如多行对象
-# 我们用 ? 后跟一个空格来表示一个复合键的开始。
+# 键也可以是复合(complex)的,比如多行对象
+# 我们用 '?' 后跟一个空格来表示一个复合键的开始。
? |
- This is a key
- that has multiple lines
+ This is a key
+ that has multiple lines
: and this is its value
# YAML 也允许使用复杂键语法表示序列间的映射关系。
-# 但有些语言的解析器可能会不支持。
+# 但有些解析器可能会不支持。
# 一个例子:
? - Manchester United
- Real Madrid
: [ 2001-01-01, 2002-02-02 ]
-# 序列 (等价于列表或数组) 看起来像这样:
+# 序列 (sequences,等价于列表 list 或数组 array ) 看起来像这样:
+# 注意 '-' 也算缩进:
a_sequence:
- - Item 1
- - Item 2
- - 0.5 # 序列可以包含不同类型。
- - Item 4
- - key: value
- another_key: another_value
- -
- - This is a sequence
- - inside another sequence
+ - Item 1
+ - Item 2
+ - 0.5 # 序列可以包含不同类型。
+ - Item 4
+ - key: value
+ another_key: another_value
+ -
+ - This is a sequence
+ - inside another sequence
+ - - - Nested sequence indicators
+ - can be collapsed
# 因为 YAML 是 JSON 的超集,你也可以写 JSON 风格的映射和序列:
json_map: {"key": "value"}
json_seq: [3, 2, 1, "takeoff"]
+and quotes are optional: {key: [3, 2, 1, takeoff]}
#######################
# 其余的 YAML 特性 #
#######################
-# YAML 还有一个方便的特性叫 '锚',它能让你很容易在文档中进行文本复用。
+# YAML 还有一个方便的特性叫“锚”(anchors)。你可以使用它在文档中轻松地完成文本复用。
# 如下两个键会有相同的值:
anchored_content: &anchor_name This string will appear as the value of two keys.
other_anchor: *anchor_name
# 锚也可被用来复制/继承属性
base: &base
- name: Everyone has same name
+ name: Everyone has same name
+
+# '<<'称为语言无关的合并键类型(Merge Key Language-Independent Type).
+# 它表明一个或多个指定映射中的所有键值会插入到当前的映射中。
foo: &foo
- <<: *base
- age: 10
+ <<: *base
+ age: 10
bar: &bar
- <<: *base
- age: 20
+ <<: *base
+ age: 20
# foo 和 bar 将都含有 name: Everyone has same name
-# YAML 还有标签,你可以用它显示地声明类型。
+# YAML 还有标签(tags),你可以用它显式地声明类型。
explicit_string: !!str 0.5
-# 一些解析器实现特定语言的标签,就像这个针对 Python 的复数类型。
+# 一些解析器实现了特定语言的标签,就像这个针对Python的复数类型的标签。
python_complex_number: !!python/complex 1+2j
-# 我们也可以在 YAML 的复合键中使用特定语言的标签
+# 我们也可以在 YAML 的复合键中使用特定语言的标签:
? !!python/tuple [5, 7]
: Fifty Seven
-# 将会是 Python 中的 {(5, 7): 'Fifty Seven'}
+# 将会是 Python 中的 {(5, 7): 'Fifty Seven'}
####################
# 其余的 YAML 类型 #
####################
-# 除了字符串和数字,YAML 还能理解其它标量。
-# ISO 格式的日期和日期时间文本也可以被解析。
+# 除了字符串和数字,YAML 还支持其它标量。
+# ISO 格式的日期和时间字面量也可以被解析。
datetime: 2001-12-15T02:59:43.1Z
datetime_with_spaces: 2001-12-14 21:59:43.10 -5
date: 2002-12-14
@@ -146,25 +160,29 @@ date: 2002-12-14
# 这个 !!binary 标签表明这个字符串实际上
# 是一个用 base64 编码表示的二进制 blob。
gif_file: !!binary |
- R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
- OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
- +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
- AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
-# YAML 还有一个集合类型,它看起来像这样:
+# YAML 还有一个集合(set)类型,它看起来像这样:
set:
- ? item1
- ? item2
- ? item3
+ ? item1
+ ? item2
+ ? item3
+or: {item1, item2, item3}
-# 像 Python 一样,集合仅是值为 null 的映射;上面的集合等价于:
+# 集合只是值均为 null 的映射;上面的集合等价于:
set2:
- item1: null
- item2: null
- item3: null
+ item1: null
+ item2: null
+ item3: null
+
+... # 文档结束
```
### 更多资源
+ [YAML official website](http://yaml.org/)
++ [Online YAML Converter](http://yamlonline.com)
+ [Online YAML Validator](http://codebeautify.org/yaml-validator)
diff --git a/zh-tw/dart-tw.html.markdown b/zh-tw/dart-tw.html.markdown
new file mode 100644
index 00000000..5a9241c2
--- /dev/null
+++ b/zh-tw/dart-tw.html.markdown
@@ -0,0 +1,566 @@
+---
+language: dart
+lang: zh-tw
+filename: learndart-tw.dart
+contributors:
+ - ["Joao Pedrosa", "https://github.com/jpedrosa/"]
+translators:
+ - ["Bob Lu", "https://github.com/LuPoYi/"]
+---
+
+Dart 是程式語言領域的新人。
+它借鑒了許多其他主流語言,並且不會偏離它的兄弟語言 JavaScript 太多。
+就像 JavaScript 一樣,Dart 的目標是提供良好的瀏覽器整合性。
+
+Dart 最有爭議的特性必然是它的可選類型。
+
+```javascript
+import "dart:collection";
+import "dart:math" as DM;
+
+// 歡迎進入15分鐘的 Dart 學習。 http://www.dartlang.org/
+// 這是一個可實際執行的範例。你可以用 Dart 執行它
+// 或者線上執行! 可以把程式碼複製/貼上到這個網站。 http://try.dartlang.org/
+
+// 函數宣告和方法宣告看起來一樣。
+// 函數宣告可以是巢狀的。宣告使用這種 name() {} 的形式,
+// 或者 name() => 單行表示式; 的形式。
+// 右箭頭的宣告形式會直接地返回表示式的結果。
+example1() {
+ example1nested1() {
+ example1nested2() => print("Example1 nested 1 nested 2");
+ example1nested2();
+ }
+ example1nested1();
+}
+
+// 匿名函數沒有函數名。
+example2() {
+ example2nested1(fn) {
+ fn();
+ }
+ example2nested1(() => print("Example2 nested 1"));
+}
+
+// 當宣告函數類型的參數的時候,宣告中可以包含
+// 函數參數需要的參數,指定所需的參數名即可。
+example3() {
+ example3nested1(fn(informSomething)) {
+ fn("Example3 nested 1");
+ }
+ example3planB(fn) { // 或者不宣告函數參數的參數
+ fn("Example3 plan B");
+ }
+ example3nested1((s) => print(s));
+ example3planB((s) => print(s));
+}
+
+// 函數有可以訪問到外層變數的閉包。
+var example4Something = "Example4 nested 1";
+example4() {
+ example4nested1(fn(informSomething)) {
+ fn(example4Something);
+ }
+ example4nested1((s) => print(s));
+}
+
+// 下面這個包含 sayIt 方法的類別宣告,同樣有一個可以訪問外層變數的閉包,
+// 就像前面的函數一樣。
+var example5method = "Example5 sayIt";
+class Example5Class {
+ sayIt() {
+ print(example5method);
+ }
+}
+example5() {
+ // 創建一個 Example5Class 類的匿名實例,
+ // 並呼叫它的 sayIt 方法。
+ new Example5Class().sayIt();
+}
+
+// 類別的宣告使用這種形式 class name { [classBody] }.
+// classBody 中可以包含實例方法和變數,
+// 還可以包含類別方法和變數。
+class Example6Class {
+ var example6InstanceVariable = "Example6 instance variable";
+ sayIt() {
+ print(example6InstanceVariable);
+ }
+}
+example6() {
+ new Example6Class().sayIt();
+}
+
+// 類別方法和變數使用 static 宣告。
+class Example7Class {
+ static var example7ClassVariable = "Example7 class variable";
+ static sayItFromClass() {
+ print(example7ClassVariable);
+ }
+ sayItFromInstance() {
+ print(example7ClassVariable);
+ }
+}
+example7() {
+ Example7Class.sayItFromClass();
+ new Example7Class().sayItFromInstance();
+}
+
+// 定數非常方便,但是對於在函數/方法的外層的定數有一個限制,
+// 類別的外層或外面的定數必須是常數。
+// 字串和數字預設是常數。
+// 但是 array 和 map 不是。他們需要用 "const" 宣告為常數。
+var example8Array = const ["Example8 const array"],
+ example8Map = const {"someKey": "Example8 const map"};
+example8() {
+ print(example8Array[0]);
+ print(example8Map["someKey"]);
+}
+
+// Dart 中的迴圈使用標準的 for () {} 或 while () {} 的形式,
+// 以及更加現代的 for (.. in ..) {} 的形式, 或者
+// 以 forEach 開頭並具有許多特性支援函數回呼的形式。
+var example9Array = const ["a", "b"];
+example9() {
+ for (var i = 0; i < example9Array.length; i++) {
+ print("Example9 for loop '${example9Array[i]}'");
+ }
+ var i = 0;
+ while (i < example9Array.length) {
+ print("Example9 while loop '${example9Array[i]}'");
+ i++;
+ }
+ for (var e in example9Array) {
+ print("Example9 for-in loop '${e}'");
+ }
+ example9Array.forEach((e) => print("Example9 forEach loop '${e}'"));
+}
+
+// 透過迴圈遍歷字串中的每個字元或者取出其子字串。
+var example10S = "ab";
+example10() {
+ for (var i = 0; i < example10S.length; i++) {
+ print("Example10 String character loop '${example10S[i]}'");
+ }
+ for (var i = 0; i < example10S.length; i++) {
+ print("Example10 substring loop '${example10S.substring(i, i + 1)}'");
+ }
+}
+
+// 支援兩種數字格式 int 和 double。
+example11() {
+ var i = 1 + 320, d = 3.2 + 0.01;
+ print("Example11 int ${i}");
+ print("Example11 double ${d}");
+}
+
+// DateTime 提供了日期/時間的方法。
+example12() {
+ var now = new DateTime.now();
+ print("Example12 now '${now}'");
+ now = now.add(new Duration(days: 1));
+ print("Example12 tomorrow '${now}'");
+}
+
+// 支援正規表達式。
+example13() {
+ var s1 = "some string", s2 = "some", re = new RegExp("^s.+?g\$");
+ match(s) {
+ if (re.hasMatch(s)) {
+ print("Example13 regexp matches '${s}'");
+ } else {
+ print("Example13 regexp doesn't match '${s}'");
+ }
+ }
+ match(s1);
+ match(s2);
+}
+
+// 布林運算式支持隱式轉換以及動態類型
+example14() {
+ var a = true;
+ if (a) {
+ print("Example14 true, a is $a");
+ }
+ a = null;
+ if (a) {
+ print("Example14 true, a is $a");
+ } else {
+ print("Example14 false, a is $a"); // 執行到這裡
+ }
+
+// 動態類型的null可以轉換成bool型
+ var b; // b是動態類型
+ b = "abc";
+ try {
+ if (b) {
+ print("Example14 true, b is $b");
+ } else {
+ print("Example14 false, b is $b");
+ }
+ } catch (e) {
+ print("Example14 error, b is $b"); // 這段程式碼可以執行但是會報錯
+ }
+ b = null;
+ if (b) {
+ print("Example14 true, b is $b");
+ } else {
+ print("Example14 false, b is $b"); // 執行到這裡
+ }
+
+ // 靜態類型的null不能轉換成bool型
+ var c = "abc";
+ c = null;
+ // 編譯出錯
+ // if (c) {
+ // print("Example14 true, c is $c");
+ // } else {
+ // print("Example14 false, c is $c");
+ // }
+}
+
+// try/catch/finally 和 throw 語句用於例外處理。
+// throw 語句可以使用任何物件作為參數。
+example15() {
+ try {
+ try {
+ throw "Some unexpected error.";
+ } catch (e) {
+ print("Example15 an exception: '${e}'");
+ throw e; // Re-throw
+ }
+ } catch (e) {
+ print("Example15 catch exception being re-thrown: '${e}'");
+ } finally {
+ print("Example15 Still run finally");
+ }
+}
+
+// 想要有效地動態創建長字串,
+// 應該使用 StringBuffer。或者 join 一個字串的陣列。
+example16() {
+ var sb = new StringBuffer(), a = ["a", "b", "c", "d"], e;
+ for (e in a) { sb.write(e); }
+ print("Example16 dynamic string created with "
+ "StringBuffer '${sb.toString()}'");
+ print("Example16 join string array '${a.join()}'");
+}
+
+// 字串連接只需讓相鄰的字串相連,
+// 不需要額外的操作運算符號。
+example17() {
+ print("Example17 "
+ "concatenate "
+ "strings "
+ "just like that");
+}
+
+// 字串使用單引號或雙引號做分隔,二者並沒有實際的差異。
+// 這種靈活性可以很好地避免內容中需要轉義換行的情況。
+// 例如,字串內容裡的 HTML 屬性使用了雙引號。
+example18() {
+ print('Example18 <a href="etc">'
+ "Don't can't I'm Etc"
+ '</a>');
+}
+
+// 用三個單引號或三個雙引號表示的字串
+// 可以跨越多行,並且包含換行。
+example19() {
+ print('''Example19 <a href="etc">
+Example19 Don't can't I'm Etc
+Example19 </a>''');
+}
+
+// 字串可以使用 $ 符號插入內容。
+// 使用 $ { [expression] } 的形式,表示式的值會被插入到字串中。
+// $ 跟著一個變數名會插入變數的值。
+// 如果要在字符串中插入 $ ,可以使用 \$ 的轉義形式取代。
+example20() {
+ var s1 = "'\${s}'", s2 = "'\$s'";
+ print("Example20 \$ interpolation ${s1} or $s2 works.");
+}
+
+// 可選類型允許作為 API 的標註,並且可以輔助 IDE,
+// 這樣 IDE 可以更好地提供重構、自動完成和錯誤檢測功能。
+// 目前為止我們還沒有宣告任何類型,並且程式可以執行。
+// 事實上,類型在執行時會被忽略。
+// 類型甚至可以是錯的,並且程式依然可以執行,
+// 好像和類型完全無關一樣。
+// 有一個執行時參數可以讓程式進入檢查模式,它會在執行時檢查類型錯誤。
+// 這在開發時很有用,但是由於增加了額外的檢查會使程式變慢,
+// 因此應該避免在部署時使用。
+class Example21 {
+ List<String> _names;
+ Example21() {
+ _names = ["a", "b"];
+ }
+ List<String> get names => _names;
+ set names(List<String> list) {
+ _names = list;
+ }
+ int get length => _names.length;
+ void add(String name) {
+ _names.add(name);
+ }
+}
+
+void example21() {
+ Example21 o = new Example21();
+ o.add("c");
+ print("Example21 names '${o.names}' and length '${o.length}'");
+ o.names = ["d", "e"];
+ print("Example21 names '${o.names}' and length '${o.length}'");
+}
+
+// 類型的繼承形式是 class name extends AnotherClassName {} 。
+class Example22A {
+ var _name = "Some Name!";
+ get name => _name;
+}
+class Example22B extends Example22A {}
+example22() {
+ var o = new Example22B();
+ print("Example22 class inheritance '${o.name}'");
+}
+
+// 類型也可以使用 mixin 的形式 :
+// class name extends SomeClass with AnotherClassName {}.
+// 必需繼承某個類型才能 mixin 另一個類型。
+// 當前 mixin 的模板類型不能有建構子。
+// Mixin 主要是用來和輔助的類型共享方法的,
+// 這樣單一繼承就不會影響程式碼重覆使用。
+// Mixin 宣告在類型定義的 "with" 後面。
+class Example23A {}
+class Example23Utils {
+ addTwo(n1, n2) {
+ return n1 + n2;
+ }
+}
+class Example23B extends Example23A with Example23Utils {
+ addThree(n1, n2, n3) {
+ return addTwo(n1, n2) + n3;
+ }
+}
+example23() {
+ var o = new Example23B(), r1 = o.addThree(1, 2, 3),
+ r2 = o.addTwo(1, 2);
+ print("Example23 addThree(1, 2, 3) results in '${r1}'");
+ print("Example23 addTwo(1, 2) results in '${r2}'");
+}
+
+// 類型的建構子和類型名相同,形式為
+// SomeClass() : super() {}, 其中 ": super()" 的部分是可選的,
+// 它用來傳遞參數給父類型的建構子。
+class Example24A {
+ var _value;
+ Example24A({value: "someValue"}) {
+ _value = value;
+ }
+ get value => _value;
+}
+class Example24B extends Example24A {
+ Example24B({value: "someOtherValue"}) : super(value: value);
+}
+example24() {
+ var o1 = new Example24B(),
+ o2 = new Example24B(value: "evenMore");
+ print("Example24 calling super during constructor '${o1.value}'");
+ print("Example24 calling super during constructor '${o2.value}'");
+}
+
+// 對於簡單的類型,有一種設置構造函數參數的快捷方式。
+// 只需要使用 this.parameterName 的前綴,
+// 它就會把參數設置為同名的實例變數。
+class Example25 {
+ var value, anotherValue;
+ Example25({this.value, this.anotherValue});
+}
+example25() {
+ var o = new Example25(value: "a", anotherValue: "b");
+ print("Example25 shortcut for constructor '${o.value}' and "
+ "'${o.anotherValue}'");
+}
+
+// 可以在大括號 {} 中宣告命名參數。
+// 大括號 {} 中宣告的參數的順序是隨意的。
+// 在中括號 [] 中宣告的參數也是可選的。
+example26() {
+ var _name, _surname, _email;
+ setConfig1({name, surname}) {
+ _name = name;
+ _surname = surname;
+ }
+ setConfig2(name, [surname, email]) {
+ _name = name;
+ _surname = surname;
+ _email = email;
+ }
+ setConfig1(surname: "Doe", name: "John");
+ print("Example26 name '${_name}', surname '${_surname}', "
+ "email '${_email}'");
+ setConfig2("Mary", "Jane");
+ print("Example26 name '${_name}', surname '${_surname}', "
+ "email '${_email}'");
+}
+
+// 使用 final 宣告的變數只能被設置一次。
+// 在類型裡面,final 實例變數可以通過常數的建構子參數設置。
+class Example27 {
+ final color1, color2;
+ // 更靈活一點的方法是在冒號 : 後面設置 final 實例變數。
+ Example27({this.color1, color2}) : color2 = color2;
+}
+example27() {
+ final color = "orange", o = new Example27(color1: "lilac", color2: "white");
+ print("Example27 color is '${color}'");
+ print("Example27 color is '${o.color1}' and '${o.color2}'");
+}
+
+// 要導入一個函式庫,使用 import "libraryPath" 的形式,或者如果要導入的是
+// 核心庫使用 import "dart:libraryName" 。還有一個稱為 "pub" 的套件管理工具,
+// 它使用 import "package:packageName" 的約定形式。
+// 看下這個文件頂部的 import "dart:collection"; 語法。
+// 導入語句必需在其它程式碼宣告之前出現。 IterableBase 來自於 dart:collection 。
+class Example28 extends IterableBase {
+ var names;
+ Example28() {
+ names = ["a", "b"];
+ }
+ get iterator => names.iterator;
+}
+example28() {
+ var o = new Example28();
+ o.forEach((name) => print("Example28 '${name}'"));
+}
+
+// 對於控制流程,我們有:
+// * 必需帶 break 的標準 switch 語法
+// * if-else 和三元運算子 ..?..:..
+// * 閉包和匿名函數
+// * break, continue 和 return 語法
+example29() {
+ var v = true ? 30 : 60;
+ switch (v) {
+ case 30:
+ print("Example29 switch statement");
+ break;
+ }
+ if (v < 30) {
+ } else if (v > 30) {
+ } else {
+ print("Example29 if-else statement");
+ }
+ callItForMe(fn()) {
+ return fn();
+ }
+ rand() {
+ v = new DM.Random().nextInt(50);
+ return v;
+ }
+ while (true) {
+ print("Example29 callItForMe(rand) '${callItForMe(rand)}'");
+ if (v != 30) {
+ break;
+ } else {
+ continue;
+ }
+ // 不會到這裡。
+ }
+}
+
+// 解析 int,把 double 轉成 int,或者使用 ~/ 運算符號在除法計算時僅保留整數位。
+// 讓我們也來場猜數遊戲吧。
+example30() {
+ var gn,
+ tooHigh = false,
+ n,
+ n2 = (2.0).toInt(),
+ top = int.parse("123") ~/ n2,
+ bottom = 0;
+ top = top ~/ 6;
+ gn = new DM.Random().nextInt(top + 1); // +1 because nextInt top is exclusive
+ print("Example30 Guess a number between 0 and ${top}");
+ guessNumber(i) {
+ if (n == gn) {
+ print("Example30 Guessed right! The number is ${gn}");
+ } else {
+ tooHigh = n > gn;
+ print("Example30 Number ${n} is too "
+ "${tooHigh ? 'high' : 'low'}. Try again");
+ }
+ return n == gn;
+ }
+
+ n = (top - bottom) ~/ 2;
+ while (!guessNumber(n)) {
+ if (tooHigh) {
+ top = n - 1;
+ } else {
+ bottom = n + 1;
+ }
+ n = bottom + ((top - bottom) ~/ 2);
+ }
+}
+
+// 選填位置參數:
+// 參數定義使用方括號 [ ],傳入參數是選填的。
+example31() {
+ findVolume31(int length, int breath, [int height]) {
+ print('length = $length, breath = $breath, height = $height');
+ }
+
+ findVolume31(10,20,30); // 可執行
+ findVolume31(10,20); // 也可執行
+}
+
+// 選填命名參數:
+// 參數定義使用大括號 { }, 傳入參數是選填的。
+// 必須傳入參數名稱及參數值,並以 : 分隔
+// 大括號的順序沒有差別
+// 這種類型參數可以幫我們避免多個參數傳入時造成混淆。
+example32() {
+ findVolume32(int length, int breath, {int height}) {
+ print('length = $length, breath = $breath, height = $height');
+ }
+
+ findVolume32(10,20,height:30); // 可執行 & 參數名稱在這邊有傳入
+ findVolume32(10,20); // 也可執行
+}
+
+// 選填預設參數:
+// 與選填命名參數相同,此外,我們為此參數定義的預設值
+// 如果沒有傳入值,就使用預設值
+example33() {
+ findVolume33(int length, int breath, {int height=10}) {
+ print('length = $length, breath = $breath, height = $height');
+ }
+
+ findVolume33(10,20,height:30); // 可執行
+ findVolume33(10,20); // 可執行
+}
+
+// 程式的唯一入口點是 main 函式。
+// 在程式開始執行 main 函式之前,不會執行任何外部程式碼。
+// 這樣有助於更快加載甚至是延遲加載程式啟動時所需要的部分;
+main() {
+ print("Learn Dart in 15 minutes!");
+ [
+ example1, example2, example3, example4, example5,
+ example6, example7, example8, example9, example10,
+ example11, example12, example13, example14, example15,
+ example16, example17, example18, example19, example20,
+ example21, example22, example23, example24, example25,
+ example26, example27, example28, example29,
+ example30 // 增加此註解可阻止dart formatter把所有項目都換行
+ ].forEach((ef) => ef());
+}
+
+```
+
+## 延伸閱讀
+
+Dart 有一個綜合性網站。它涵蓋了 API 參考、入門教學、文章以及更多,
+還包括一個有用的線上試用 Dart 頁面。
+* [https://www.dartlang.org](https://www.dartlang.org)
+* [https://try.dartlang.org](https://try.dartlang.org)
diff --git a/zh-tw/pcre-tw.html.markdown b/zh-tw/pcre-tw.html.markdown
new file mode 100644
index 00000000..5f681d46
--- /dev/null
+++ b/zh-tw/pcre-tw.html.markdown
@@ -0,0 +1,84 @@
+---
+language: PCRE
+filename: pcre-tw.txt
+contributors:
+ - ["Sachin Divekar", "http://github.com/ssd532"]
+translators:
+ - ["Michael Yeh", "https://hinet60613.github.io/"]
+lang: zh-tw
+---
+
+正規表達式(regular expression,或縮寫為regex, regexp)是一種用來表示搜尋模式的特殊字串。例如,你可以用`/^[a-z]+:/`來從網址`http://github.com`中擷取出`http:`這段http協定名稱。
+
+相容Perl正規表達式(Perl Compatible Regular Expressions, PCRE)是一個實作正規表達式的C語言函式庫。此函式庫在1997年被開發出來,在當時面對複雜字串處理時大多會選擇使用Perl。也因為如此,PCRE大多的正規表達式語法都很酷似Perl。PCRE語法被廣泛運用在許多大專案中,包括PHP、Apache、R等。
+
+PCRE中的超字元(metacharacter)主要可以分為以下兩類:
+
+* 在中括號外會被辨識的字元
+
+```
+ \ 通用跳脫字元
+ ^ 字串開頭 或 行首
+ $ 字串結尾 或 行尾
+ . 除了換行符號外的任何字元
+ [ 字元集合定義開始
+ | 支流開始
+ ( 子串模式定義開始
+ ) 子串模式定義結束
+ ? extends the meaning of (
+ 同時為數量0或1配對
+ also quantifier minimizer
+ * 量詞 至少0個 至多無限個
+ + 量詞 至少1個 至多無限個
+ 同時為佔有型量詞
+ { 最大/最小量詞開始
+```
+
+* 在中括號內會被辨識的超字元,在中括號外會被視為字元集合使用
+
+```
+ \ 通用跳脫字元
+ ^ 非字元集合的字,但只會抓到第一個符合的字元
+ - 字元範圍
+ [ POSIX字元集合(若後面接POSIX格式)
+ ] 字元集合定義結束
+```
+
+PCRE提供了一些通用的字元類型,可被當作字元集合使用
+
+```
+ \d 任何數字字元
+ \D 任何非數字字元
+ \h 任何水平空白字元
+ \H 任何非水平空白字元
+ \s 任何空白字元
+ \S 任何非空白至元
+ \v 任何垂直空白字元
+ \V 任何非垂直空白字元
+ \w 任何英文字
+ \W 任何非英文字
+```
+
+## 範例
+
+我們以字串 `66.249.64.13 - - [18/Sep/2004:11:07:48 +1000] "GET /robots.txt HTTP/1.0" 200 468 "-" "Googlebot/2.1"` 作為範例,這是一個標準的Apache存取記錄。
+
+| 正規表達式 | 結果 | 說明 |
+| :---- | :-------------- | :------ |
+| GET | GET | GET 抓取 GET 字串 (會分別大小寫) |
+| \d+.\d+.\d+.\d+ | 66.249.64.13 | `\d+` 抓取數字字元,數量由 `+` 定義為至少一個至多無限個。 `\.` 抓取 `.` 字元 |
+| (\d+\.){3}\d+ | 66.249.64.13 | `(\d+\.){3}` 會試著抓取剛好三次的 (`\d+\.`) |
+| \[.+\] | [18/Sep/2004:11:07:48 +1000] | `.+` 抓取除了換行符號以外的任何字元, `.` 表示任意字元 |
+| ^\S+ | 66.249.64.13 | `^` 為行首, `\S+` 抓取至少一個非空白字元 |
+| \+[0-9]+ | +1000 | `\+` 抓取 `+` 字元。 `[0-9]` 字元集表示剛好一個數字字元。 可以用 `\+\d+` 達到相同效果。 |
+
+以上範例皆可在 https://regex101.com/ 測試,步驟如下:
+
+1. 複製範例字串到 `TEST STRING` 區域
+2. 複製正規表達式字串到 `Regular Expression` 區域
+3. 網頁會顯示自動表達式抓取結果
+
+
+## 更多資料
+
+
diff --git a/zh-tw/python-tw.html.markdown b/zh-tw/pythonlegacy-tw.html.markdown
index 553181d8..575897e2 100644
--- a/zh-tw/python-tw.html.markdown
+++ b/zh-tw/pythonlegacy-tw.html.markdown
@@ -1,5 +1,5 @@
---
-language: python
+language: Python 2 (legacy)
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
- ["Amin Bandali", "http://aminbandali.com"]
@@ -7,7 +7,7 @@ contributors:
- ["evuez", "http://github.com/evuez"]
translators:
- ["Michael Yeh", "https://hinet60613.github.io/"]
-filename: learnpython-tw.py
+filename: learnpythonlegacy-tw.py
lang: zh-tw
---
@@ -16,7 +16,7 @@ Python是在1990年代早期由Guido Van Rossum創建的。它是現在最流行
非常歡迎各位給我們任何回饋! 你可以在[@louiedinh](http://twitter.com/louiedinh) 或 louiedinh [at] [google's email service]聯絡到我。
註: 本篇文章適用的版本為Python 2.7,但大部分的Python 2.X版本應該都適用。 Python 2.7將會在2020年停止維護,因此建議您可以從Python 3開始學Python。
-Python 3.X可以看這篇[Python 3 教學 (英文)](http://learnxinyminutes.com/docs/python3/).
+Python 3.X可以看這篇[Python 3 教學 (英文)](http://learnxinyminutes.com/docs/python/).
讓程式碼同時支援Python 2.7和3.X是可以做到的,只要引入
[`__future__` imports](https://docs.python.org/2/library/__future__.html) 模組.
@@ -627,7 +627,7 @@ i.age # => raises an AttributeError
# 你可以引入模組來做使用
import math
-print math.sqrt(16) # => 4
+print math.sqrt(16) # => 4.0
# math.sqrt()為取根號
# 你可以只從模組取出特定幾個函式