summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitattributes2
-rw-r--r--.mailmap1
-rw-r--r--CONTRIBUTING.markdown2
-rw-r--r--ansible.html.markdown26
-rw-r--r--ar-ar/python-ar.html.markdown (renamed from ar-ar/python3-ar.html.markdown)6
-rw-r--r--asymptotic-notation.html.markdown62
-rw-r--r--bash.html.markdown11
-rw-r--r--bg-bg/perl-bg.html.markdown7
-rw-r--r--c++.html.markdown2
-rw-r--r--c.html.markdown13
-rw-r--r--cmake.html.markdown49
-rw-r--r--cobol.html.markdown198
-rw-r--r--common-lisp.html.markdown2
-rw-r--r--coq.html.markdown208
-rw-r--r--crystal.html.markdown4
-rw-r--r--cs-cz/javascript.html.markdown2
-rw-r--r--cs-cz/python.html.markdown (renamed from cs-cz/python3.html.markdown)9
-rw-r--r--csharp.html.markdown26
-rw-r--r--css.html.markdown19
-rw-r--r--d.html.markdown1
-rw-r--r--dart.html.markdown499
-rw-r--r--de-de/bash-de.html.markdown2
-rw-r--r--de-de/bc.html.markdown102
-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/elm-de.html.markdown376
-rw-r--r--de-de/html-de.html.markdown16
-rw-r--r--de-de/java-de.html.markdown2
-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.markdown43
-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/python-de.html.markdown609
-rw-r--r--de-de/python3-de.html.markdown655
-rw-r--r--de-de/pythonlegacy-de.html.markdown766
-rw-r--r--de-de/ruby-de.html.markdown782
-rw-r--r--de-de/vim-de.html.markdown282
-rw-r--r--de-de/yaml-de.html.markdown2
-rw-r--r--docker.html.markdown146
-rw-r--r--dynamic-programming.html.markdown16
-rw-r--r--el-gr/python-gr.html.markdown1031
-rw-r--r--el-gr/vim-gr.html.markdown267
-rw-r--r--elixir.html.markdown11
-rw-r--r--es-es/c-es.html.markdown3
-rw-r--r--es-es/clojure-es.html.markdown236
-rw-r--r--es-es/factor-es.html.markdown200
-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/pcre-es.html.markdown84
-rw-r--r--es-es/perl-es.html.markdown16
-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)325
-rw-r--r--es-es/raku-es.html.markdown (renamed from es-es/perl6-es.html.markdown)508
-rw-r--r--es-es/ruby-es.html.markdown2
-rw-r--r--es-es/sql-es.html.markdown115
-rw-r--r--es-es/yaml-es.html.markdown2
-rw-r--r--fa-ir/javascript-fa.html.markdown6
-rw-r--r--fr-fr/crystal-fr.html.markdown2
-rw-r--r--fr-fr/elisp-fr.html.markdown10
-rw-r--r--fr-fr/fsharp-fr.html.markdown3
-rw-r--r--fr-fr/javascript-fr.html.markdown22
-rw-r--r--fr-fr/perl-fr.html.markdown4
-rw-r--r--fr-fr/python-fr.html.markdown802
-rw-r--r--fr-fr/python3-fr.html.markdown732
-rw-r--r--fr-fr/pythonlegacy-fr.html.markdown488
-rw-r--r--fsharp.html.markdown4
-rw-r--r--git.html.markdown4
-rw-r--r--go.html.markdown43
-rw-r--r--groovy.html.markdown2
-rw-r--r--haskell.html.markdown159
-rw-r--r--hdl.html.markdown231
-rw-r--r--hu-hu/pythonlegacy-hu.html.markdown (renamed from hu-hu/python-hu.html.markdown)6
-rw-r--r--hu-hu/yaml-hu.html.markdown2
-rw-r--r--it-it/bash-it.html.markdown21
-rw-r--r--it-it/elixir-it.html.markdown52
-rw-r--r--it-it/javascript-it.html.markdown2
-rw-r--r--it-it/python-it.html.markdown952
-rw-r--r--it-it/python3-it.html.markdown1016
-rw-r--r--it-it/pythonlegacy-it.html.markdown778
-rw-r--r--it-it/sql-it.html.markdown112
-rw-r--r--it-it/zfs-it.html.markdown361
-rw-r--r--ja-jp/python-jp.html.markdown (renamed from ja-jp/python3-jp.html.markdown)38
-rw-r--r--janet.html.markdown328
-rw-r--r--java.html.markdown12
-rw-r--r--javascript.html.markdown4
-rw-r--r--jsonnet.html.markdown139
-rw-r--r--kdb+.html.markdown2
-rw-r--r--ko-kr/javascript-kr.html.markdown6
-rw-r--r--ko-kr/pythonlegacy-kr.html.markdown (renamed from ko-kr/python-kr.html.markdown)4
-rw-r--r--ko-kr/vim-kr.html.markdown56
-rw-r--r--ko-kr/yaml-kr.html.markdown2
-rw-r--r--latex.html.markdown2
-rw-r--r--lbstanza.html.markdown282
-rw-r--r--ldpl.html.markdown13
-rw-r--r--linker.html.markdown2
-rw-r--r--lua.html.markdown2
-rw-r--r--matlab.html.markdown2
-rw-r--r--mips.html.markdown111
-rw-r--r--moonscript.html.markdown2
-rw-r--r--ms-my/javascript-my.html.markdown2
-rw-r--r--nim.html.markdown2
-rw-r--r--nix.html.markdown2
-rw-r--r--nl-nl/json-nl.html.markdown13
-rw-r--r--nl-nl/yaml-nl.html.markdown2
-rw-r--r--opencv.html.markdown22
-rw-r--r--p5.html.markdown2
-rw-r--r--pascal.html.markdown2
-rw-r--r--perl.html.markdown4
-rw-r--r--php.html.markdown10
-rw-r--r--pl-pl/bf-pl.html.markdown2
-rw-r--r--pl-pl/perl-pl.html.markdown4
-rw-r--r--pl-pl/pythonlegacy-pl.html.markdown (renamed from pl-pl/python-pl.html.markdown)6
-rw-r--r--powershell.html.markdown961
-rw-r--r--processing.html.markdown12
-rw-r--r--pt-br/c-pt.html.markdown3
-rw-r--r--pt-br/clojure-macros-pt.html.markdown16
-rw-r--r--pt-br/clojure-pt.html.markdown599
-rw-r--r--pt-br/elisp-pt.html.markdown2
-rw-r--r--pt-br/haskell-pt.html.markdown4
-rw-r--r--pt-br/javascript-pt.html.markdown6
-rw-r--r--pt-br/markdown-pt.html.markdown210
-rw-r--r--pt-br/pascal-pt.html.markdown3
-rw-r--r--pt-br/perl-pt.html.markdown4
-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/sass-pt.html.markdown67
-rw-r--r--pt-br/vim-pt.html.markdown11
-rw-r--r--pt-br/whip-pt.html.markdown2
-rw-r--r--pt-br/yaml-pt.html.markdown2
-rw-r--r--python.html.markdown975
-rw-r--r--python3.html.markdown1054
-rw-r--r--pythonlegacy.html.markdown827
-rw-r--r--qsharp.html.markdown204
-rw-r--r--raku-pod.html.markdown (renamed from perl6-pod.html.markdown)90
-rw-r--r--raku.html.markdown119
-rw-r--r--raylib.html.markdown146
-rw-r--r--red.html.markdown2
-rw-r--r--ro-ro/pythonlegacy-ro.html.markdown (renamed from ro-ro/python-ro.html.markdown)4
-rw-r--r--rst.html.markdown6
-rw-r--r--ru-ru/c-ru.html.markdown2
-rw-r--r--ru-ru/javascript-ru.html.markdown4
-rw-r--r--ru-ru/pascal-ru.html.markdown217
-rw-r--r--ru-ru/perl-ru.html.markdown30
-rw-r--r--ru-ru/python-ru.html.markdown224
-rw-r--r--ru-ru/pythonlegacy-ru.html.markdown (renamed from ru-ru/python3-ru.html.markdown)226
-rw-r--r--ru-ru/ruby-ru.html.markdown2
-rw-r--r--ru-ru/yaml-ru.html.markdown2
-rw-r--r--ruby.html.markdown29
-rw-r--r--rust.html.markdown14
-rw-r--r--sass.html.markdown2
-rw-r--r--scala.html.markdown5
-rw-r--r--set-theory.html.markdown132
-rw-r--r--smalltalk.html.markdown95
-rw-r--r--sql.html.markdown41
-rw-r--r--standard-ml.html.markdown5
-rw-r--r--swift.html.markdown7
-rw-r--r--ta_in/css-ta.html.markdown42
-rw-r--r--ta_in/javascript-ta.html.markdown6
-rw-r--r--ta_in/xml-ta.html.markdown52
-rwxr-xr-xtoml.html.markdown33
-rw-r--r--tr-tr/c-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--typescript.html.markdown20
-rw-r--r--uk-ua/cypher-ua.html.markdown2
-rw-r--r--uk-ua/go-ua.html.markdown2
-rw-r--r--uk-ua/javascript-ua.html.markdown2
-rw-r--r--uk-ua/pythonlegacy-ua.html.markdown (renamed from uk-ua/python-ua.html.markdown)4
-rw-r--r--vi-vn/python-vi.html.markdown (renamed from vi-vn/python3-vi.html.markdown)6
-rw-r--r--vim.html.markdown5
-rw-r--r--vimscript.html.markdown658
-rw-r--r--wasm.html.markdown87
-rw-r--r--yaml.html.markdown2
-rw-r--r--zh-cn/c-cn.html.markdown4
-rw-r--r--zh-cn/css-cn.html.markdown2
-rw-r--r--zh-cn/git-cn.html.markdown2
-rw-r--r--zh-cn/javascript-cn.html.markdown6
-rw-r--r--zh-cn/make-cn.html.markdown8
-rw-r--r--zh-cn/markdown-cn.html.markdown2
-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.markdown632
-rw-r--r--zh-cn/pythonlegacy-cn.html.markdown476
-rw-r--r--zh-cn/racket-cn.html.markdown2
-rw-r--r--zh-cn/yaml-cn.html.markdown61
-rw-r--r--zh-tw/dart-tw.html.markdown566
-rw-r--r--zh-tw/pythonlegacy-tw.html.markdown (renamed from zh-tw/python-tw.html.markdown)6
197 files changed, 20832 insertions, 10507 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/.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/CONTRIBUTING.markdown b/CONTRIBUTING.markdown
index 18a5a5d7..3dfd38ce 100644
--- a/CONTRIBUTING.markdown
+++ b/CONTRIBUTING.markdown
@@ -83,7 +83,7 @@ addition or not.
## Building the site locally
-You can buid the site locally to test your changes. Follow the steps below.
+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.
diff --git a/ansible.html.markdown b/ansible.html.markdown
index 41a8c9b5..30dfba13 100644
--- a/ansible.html.markdown
+++ b/ansible.html.markdown
@@ -30,9 +30,9 @@ But ansible is way more! It provides execution plans, an API, library, and callb
#### Pros
-* It is an agent-less tools In most scenarios, it use ssh as a transport layer.
+* 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 ssh concept - you already
+* 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)
@@ -176,7 +176,7 @@ instances in the cloud, execute shell command). The simplest module is called
Example of modules:
* Module: `ping` - the simplest module that is useful to verify host connectivity
-* Module: `shell` - a module that executes shell command on a specified host(s).
+* Module: `shell` - a module that executes a shell command on a specified host(s).
```bash
@@ -204,13 +204,13 @@ the module subsystem (useful to install python2.7)
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 allow you to execute command remotly on
+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**.
-Playbook consist of multiple elements -
+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)
@@ -247,7 +247,7 @@ Note: Example playbook is explained in the next chapter: 'Roles'
### Inventory
-Inventory is a set of objects or hosts, against which we are executing our
+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`).
@@ -303,11 +303,11 @@ Role can be included in your playbook (executed via your playbook).
```
#### For remaining examples we would use additional repository
-This example install ansible in `virtualenv` so it is independend from a system.
-You need to initialize it into your shell-context with `source environment.sh`
+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]()
+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
@@ -513,7 +513,7 @@ $ # Now we would run the above playbook with roles
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
+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
@@ -551,7 +551,7 @@ 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 during runtime.
+configure ansible to use them during runtime.
```bash
# Try (this would fail)
@@ -588,7 +588,7 @@ You might like to know, that you can build your inventory dynamically.
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 most popular Cloud providers and a lot of in-house
+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)
@@ -614,7 +614,7 @@ callback_whitelist = profile_tasks
### facts-cache and ansible-cmdb
-You can pull some information about your environment from another hosts.
+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.
diff --git a/ar-ar/python3-ar.html.markdown b/ar-ar/python-ar.html.markdown
index e1a12690..f89c2f25 100644
--- a/ar-ar/python3-ar.html.markdown
+++ b/ar-ar/python-ar.html.markdown
@@ -1,5 +1,5 @@
---
-language: python3
+language: Python
contributors:
- ["Louie Dinh", "http://pythonpracticeprojects.com"]
- ["Steven Basart", "http://github.com/xksteven"]
@@ -11,7 +11,7 @@ contributors:
translators:
- ["Ahmad Hegazy", "https://github.com/ahegazy"]
lang: ar-ar
-filename: learnpython3-ar.py
+filename: learnpython-ar.py
---
لقد أُنشئت لغة البايثون بواسطة جايدو ڤان روسم في بداية التسعينات. هي الأن أحد أشهر اللغات الموجودة.
@@ -19,7 +19,7 @@ filename: learnpython3-ar.py
ردود أفعالكم عن المقال مُقدرة بشدة. يمكنكم التواصل مع الكاتب الاساسي من خلال [@louiedinh](http://twitter.com/louiedinh) أو louiedinh [at] [google's email service]
-ملحوظة: هذا المقال يُطبق على بايثون 3 فقط. راجع المقال [هنا](http://learnxinyminutes.com/docs/python/) إذا أردت تعلم لغة البايثون نسخة 2.7 الأقدم
+ملحوظة: هذا المقال يُطبق على بايثون 3 فقط. راجع المقال [هنا](http://learnxinyminutes.com/docs/pythonlegacy/) إذا أردت تعلم لغة البايثون نسخة 2.7 الأقدم
```python
diff --git a/asymptotic-notation.html.markdown b/asymptotic-notation.html.markdown
index 7a7989d3..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,7 +91,7 @@ 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 constants c (c > 0) and n<sub>0</sub>, `f(n)` <= `c g(n)` for every input size
@@ -139,7 +141,7 @@ 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 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>).
@@ -188,8 +190,8 @@ _**asymptotically tight bound**_ on the growth rate of runtime of an algorithm.
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/bash.html.markdown b/bash.html.markdown
index 856db706..7ca4285b 100644
--- a/bash.html.markdown
+++ b/bash.html.markdown
@@ -23,7 +23,7 @@ translators:
---
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.
+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.
@@ -88,6 +88,11 @@ echo ${Variable: -5} # => tring
# 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
@@ -225,7 +230,9 @@ 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
+# "\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
diff --git a/bg-bg/perl-bg.html.markdown b/bg-bg/perl-bg.html.markdown
index 2ae7a8fd..e6da8965 100644
--- a/bg-bg/perl-bg.html.markdown
+++ b/bg-bg/perl-bg.html.markdown
@@ -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 f3dc8e20..59aad210 100644
--- a/c++.html.markdown
+++ b/c++.html.markdown
@@ -202,7 +202,7 @@ int main()
cout << "Your favorite number is " << myInt << "\n";
// prints "Your favorite number is <myInt>"
- cerr << "Used for error messages";
+ cerr << "Used for error messages";
}
//////////
diff --git a/c.html.markdown b/c.html.markdown
index 7975a1c2..a57be1dc 100644
--- a/c.html.markdown
+++ b/c.html.markdown
@@ -10,6 +10,7 @@ contributors:
- ["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.
@@ -88,10 +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
- // (however, C99-compliant compilers allow declarations near the point where
- // the value is used)
+ // 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;
@@ -820,7 +823,7 @@ 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).
diff --git a/cmake.html.markdown b/cmake.html.markdown
index 32a7b758..9ea68a42 100644
--- a/cmake.html.markdown
+++ b/cmake.html.markdown
@@ -6,25 +6,25 @@ contributors:
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
@@ -45,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"
@@ -127,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
@@ -172,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..7d94d8c9
--- /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 DIVSION.
+ *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) with start 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 DIVSION.
+ 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/common-lisp.html.markdown b/common-lisp.html.markdown
index b12e50ca..1f2bb366 100644
--- a/common-lisp.html.markdown
+++ b/common-lisp.html.markdown
@@ -69,7 +69,7 @@ t ; another atom, denoting true
;;; is a good starting point. Third party libraries can be easily installed with
;;; Quicklisp
-;;; CL is usually developed with a text editor and a Real Eval Print
+;;; 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".
diff --git a/coq.html.markdown b/coq.html.markdown
index 115d9ff8..4c1ad690 100644
--- a/coq.html.markdown
+++ b/coq.html.markdown
@@ -25,19 +25,20 @@ Inside Proof General `Ctrl+C Ctrl+<Enter>` will evaluate up to your cursor.
(*** 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. *)
+(* 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. *)
+(* 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. *)
+(* There exists a large number of vernacular commands for querying
+ information. These can be very useful. *)
Compute (1 + 1). (* 2 : nat *) (* Compute a result. *)
@@ -46,48 +47,50 @@ 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 *)
+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 "+".
+(* Locate tells you where notation is coming from. Very helpful when you
+ encounter new notation. *)
-(* Calling a function with insufficient number of arguments
- does not cause an error, it produces a new function. *)
+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. *)
+
+(* 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.*)
-(* 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 *)
@@ -104,11 +107,12 @@ end with
| (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. *)
+(* 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: *)
@@ -119,16 +123,18 @@ 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.
+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 *)
+(* 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 @ *)
+(* 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 *)
@@ -168,17 +174,19 @@ let rec factorial n = match n with
(*** Notation ***)
-(* Coq has a very powerful Notation system that can be used to write expressions in more
- natural forms. *)
+(* 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. *)
+(* 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 *)
-(* Imports the Zarith module containing definitions related to the integers Z *)
-Require Import ZArith.
+Require Import ZArith.
(* Notation scopes can be opened *)
Open Scope Z_scope.
@@ -187,7 +195,7 @@ Open Scope Z_scope.
Compute 1 + 7. (* 8 : Z *)
(* Integer equality checking *)
-Compute 1 =? 2. (* false : bool *)
+Compute 1 =? 2. (* false : bool *)
(* Locate is useful for finding the origin and definition of notations *)
Locate "_ =? _". (* Z.eqb x y : Z_scope *)
@@ -199,10 +207,10 @@ 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. *)
+(* 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.
@@ -230,17 +238,19 @@ Bound to classes nat Nat.t
"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. *)
+(* 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 *)
-Compute 2. (* 2 : nat *) (* only 1 and 0 are interpreted as fractions by Q_scope *)
+
+(* 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 *)
+Compute (1 # 3) ?= (2 # 6). (* Eq : comparison *)
Close Scope Q_scope.
Compute ( (2 # 3) / (1 # 5) )%Q. (* 10 # 3 : Q *)
@@ -279,40 +289,43 @@ Definition my_fst2 {A B : Type} (x : A * B) : A := let (a,b) := x in
(*** Lists ***)
-(* Lists are built by using cons and nil or by using notation available in list_scope. *)
+(* 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.
+Compute (1 :: 2 :: 3 :: nil)%list.
(* There is also list notation available in the ListNotations modules *)
Require Import List.
-Import ListNotations.
+Import ListNotations.
Compute [1 ; 2 ; 3]. (* [1; 2; 3] : list nat *)
-(*
-There are a large number of list manipulation functions available, including:
+(* There is a large number of list manipulation functions available,
+ including:
• length
-• head : first element (with default)
+• 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
+• flat_map : applying a function returning lists
• fold_left : iterator (from head to tail)
-• fold_right : iterator (from tail to head)
+• 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.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 *)
+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 ***)
@@ -342,16 +355,19 @@ Close Scope string_scope.
• 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)
+
+• 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
+• 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,...)
+• 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
@@ -360,18 +376,20 @@ Close Scope string_scope.
(*** User-defined data types ***)
-(* Because Coq is dependently typed, defining type aliases is no different than defining
- an alias for a value. *)
+(* 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 *)
+(* 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. *)
+(* 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
@@ -379,23 +397,28 @@ Inductive my_number := plus_infinity
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 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 *)
+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. *)
-(* 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.
+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 **)
@@ -427,31 +450,38 @@ 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. *)
+(* 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 *)
-(* 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.
-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. *)
-(* 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. *)
+(* 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 *)
+(* 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
@@ -465,8 +495,10 @@ Proof. intros n. induction n.
- 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.
+
+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
diff --git a/crystal.html.markdown b/crystal.html.markdown
index 9fae9da3..ae027a8d 100644
--- a/crystal.html.markdown
+++ b/crystal.html.markdown
@@ -229,7 +229,7 @@ b #=> 'b'
c #=> "c"
# Procs represent a function pointer with an optional context (the closure data)
-# It is typically created with a proc litteral
+# It is typically created with a proc literal
proc = ->(x : Int32) { x.to_s }
proc.class # Proc(Int32, String)
# Or using the new method
@@ -551,4 +551,4 @@ ex #=> "ex2"
## Additional resources
-- [Official Documentation](http://crystal-lang.org/)
+- [Official Documentation](https://crystal-lang.org/)
diff --git a/cs-cz/javascript.html.markdown b/cs-cz/javascript.html.markdown
index c05a9138..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"]
diff --git a/cs-cz/python3.html.markdown b/cs-cz/python.html.markdown
index bd3690a8..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
diff --git a/csharp.html.markdown b/csharp.html.markdown
index 37573e01..b965c2d4 100644
--- a/csharp.html.markdown
+++ b/csharp.html.markdown
@@ -653,10 +653,10 @@ on a new line! ""Wow!"", the masses cried";
return ++count;
}
- // A delegate is a reference to a method
+ // A delegate is a reference to a method.
// To reference the Increment method,
- // first declare a delegate with the same signature
- // ie. takes no arguments and returns an int
+ // 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
@@ -727,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).
@@ -1091,7 +1091,7 @@ on a new line! ""Wow!"", the masses cried";
// Spell failed
return false;
}
- // Other exceptions, or MagicServiceException where Code is not 42
+ // Other exceptions, or MagicServiceException where Code is not 42
catch(Exception ex) when (LogException(ex))
{
// Execution never reaches this block
@@ -1215,7 +1215,7 @@ namespace Csharp7
Console.WriteLine(tt.GetLastName());
}
}
-
+
// PATTERN MATCHING
class PatternMatchingTest
{
@@ -1315,8 +1315,10 @@ namespace Csharp7
* [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](https://www.dotnetperls.com/)
- * [C# in Depth](https://manning.com/skeet3)
- * [Programming C# 5.0](http://shop.oreilly.com/product/0636920024064)
- * [LINQ Pocket Reference](http://shop.oreilly.com/product/9780596519254)
- * [Windows Forms Programming in C#](https://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
+ * [DotNetPerls](http://www.dotnetperls.com)
+ * [C# in Depth](http://manning.com/skeet2)
+ * [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)
+ * [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 64dc097c..b8adc886 100644
--- a/css.html.markdown
+++ b/css.html.markdown
@@ -164,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 */
@@ -179,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 */
@@ -317,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/d.html.markdown b/d.html.markdown
index d2a57cae..93c08da2 100644
--- a/d.html.markdown
+++ b/d.html.markdown
@@ -212,6 +212,7 @@ found in the wonderful `std.algorithm` module!
```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
diff --git a/dart.html.markdown b/dart.html.markdown
index 07f755f7..b215474a 100644
--- a/dart.html.markdown
+++ b/dart.html.markdown
@@ -2,127 +2,228 @@
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).
```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() {
nested1() {
nested2() => print("Example1 nested 1 nested 2");
nested2();
}
+
nested1();
}
-// Anonymous functions don't include a name.
+/// Anonymous functions don't include a name but can take number of arguments
example2() {
- nested1(fn) {
+ //// Explicit return type.
+ nested1(Function<void> fn) {
fn();
}
+
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() {
- planA(fn(informSomething)) {
+ planA(fn(String informSomething)) {
fn("Example3 plan A");
}
- planB(fn) { // Or don't declare number of parameters.
+ planB(fn) {
+ // Or don't declare number of parameters.
fn("Example3 plan B");
}
+
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() {
nested1(fn(informSomething)) {
fn(example4Something);
}
+
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 instanceVariable = "Example6 instance variable";
sayIt() {
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 classVariable = "Example7 class variable";
static sayItFromClass() {
print(classVariable);
}
+
sayItFromInstance() {
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 example8Array = const ["Example8 const array"],
- example8Map = const {"someKey": "Example8 const map"};
+/// 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");
+ }
+}
+
+
+/// 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(example8Array[0]);
print(example8Map["someKey"]);
+ print(explicitList[0]);
}
-// 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.
+/// 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 < example9Array.length; i++) {
+ for (int i = 0; i < example9Array.length; i++) {
print("Example9 for loop '${example9Array[i]}'");
}
var i = 0;
@@ -130,13 +231,15 @@ example9() {
print("Example9 while loop '${example9Array[i]}'");
i++;
}
- for (var e in example9Array) {
+ for (final e in example9Array) {
print("Example9 for-in loop '${e}'");
}
+
example9Array.forEach((e) => print("Example9 forEach loop '${e}'"));
+
}
-// To loop over the characters of a string or to extract a substring.
+/// To loop over the characters of a string or to extract a substring.
var example10String = "ab";
example10() {
for (var i = 0; i < example10String.length; i++) {
@@ -147,14 +250,37 @@ example10() {
}
}
-// 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,11 +298,12 @@ example13() {
print("Example13 regexp doesn't match '${s}'");
}
}
+
match(s1);
match(s2);
}
-// Boolean expressions support implicit conversions and dynamic type
+/// Boolean expressions support implicit conversions and dynamic type
example14() {
var a = true;
if (a) {
@@ -186,11 +313,11 @@ example14() {
if (a) {
print("true, a is $a");
} else {
- print("false, a is $a"); // runs here
+ print("false, a is $a"); /// runs here
}
- // dynamic typed null can be convert to bool
- var b;// b is dynamic type
+ /// dynamic typed null can be convert to bool
+ var b;/// b is dynamic type
b = "abc";
try {
if (b) {
@@ -199,35 +326,35 @@ example14() {
print("false, b is $b");
}
} catch (e) {
- print("error, b is $b"); // this could be run but got error
+ 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
+ print("false, b is $b"); /// runs here
}
- // statically typed null can not be convert to bool
+ /// 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");
- // }
+ /// 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}'");
@@ -236,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 "
@@ -255,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() {
@@ -302,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");
@@ -315,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"}) {
@@ -362,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() {
@@ -434,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) {
@@ -459,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) {
@@ -470,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) {
@@ -488,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) {
@@ -503,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());
}
```
@@ -526,6 +720,3 @@ Dart has a comprehensive web-site. It covers API reference, tutorials, articles
useful Try Dart online.
[https://www.dartlang.org](https://www.dartlang.org)
[https://try.dartlang.org](https://try.dartlang.org)
-
-
-
diff --git a/de-de/bash-de.html.markdown b/de-de/bash-de.html.markdown
index 3fb3e71f..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:
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..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/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/html-de.html.markdown b/de-de/html-de.html.markdown
index 0bf58f9c..8b5597e7 100644
--- a/de-de/html-de.html.markdown
+++ b/de-de/html-de.html.markdown
@@ -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>
diff --git a/de-de/java-de.html.markdown b/de-de/java-de.html.markdown
index e8ac5bda..e52087ec 100644
--- a/de-de/java-de.html.markdown
+++ b/de-de/java-de.html.markdown
@@ -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 cf90dc29..1bae332c 100644
--- a/de-de/make-de.html.markdown
+++ b/de-de/make-de.html.markdown
@@ -11,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
@@ -44,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.
@@ -59,7 +60,7 @@ 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.
+# 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.
@@ -67,8 +68,8 @@ file2.txt file3.txt: file0.txt file1.txt
# 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.
@@ -89,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
@@ -114,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
@@ -171,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).
@@ -179,9 +180,9 @@ 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}
@@ -196,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)
@@ -215,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/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/python-de.html.markdown b/de-de/python-de.html.markdown
index ee77683e..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
-# 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
+# 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
@@ -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):
@@ -386,72 +493,24 @@ 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. Module
+## 5. Klassen
####################################################
-# 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.
+# 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, 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.
+ # 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.
+ # 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...'
+ 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
@@ -464,269 +523,87 @@ class Human(object):
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))
+
+# 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.2 Multiple Inheritance
+## 6. Module
####################################################
-# Eine weitere Klassendefinition
-# bat.py
+# Wir können Module importieren
+import math
+print(math.sqrt(16)) #=> 4.0
-class Bat:
+# 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
- species = 'Baty'
+# Wir können auch alle Funktionen eines Moduls importieren
+# Warnung: Dies wird nicht empfohlen
+from math import *
- def __init__(self, can_fly=True):
- self.fly = can_fly
+# Wir können Modulnamen abkürzen
+import math as m
+math.sqrt(16) == m.sqrt(16) #=> True
- # This class also has a say method
- def say(self, msg):
- msg = '... ... ...'
- return msg
+# 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)
- # 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.
+## 7. Fortgeschritten
+####################################################
+
+# Generatoren helfen, um Code schnell und einfach zu schreiben
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.
+
+# 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
-# 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.
+# 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):
@@ -737,13 +614,14 @@ 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()) # Can you buy me a beer?
print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
```
@@ -752,15 +630,18 @@ print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
### 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 4ef997a1..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 implizit 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 deklarierten 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 ist nun 5 und e ist nun 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 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
-####################################################
-
-# 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 machen, 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.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 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/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/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 ff45dc8d..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
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 c73b1845..3e3c0413 100644
--- a/dynamic-programming.html.markdown
+++ b/dynamic-programming.html.markdown
@@ -3,6 +3,7 @@ category: Algorithms & Data Structures
name: Dynamic Programming
contributors:
- ["Akashdeep Goel", "http://github.com/akashdeepgoel"]
+ - ["Miltiadis Stouras", "https://github.com/mstou"]
---
# Dynamic Programming
@@ -22,7 +23,7 @@ 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:
@@ -48,6 +49,15 @@ for i=0 to n-1
## 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/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/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/elixir.html.markdown b/elixir.html.markdown
index 7af29202..8b80c582 100644
--- a/elixir.html.markdown
+++ b/elixir.html.markdown
@@ -1,7 +1,7 @@
---
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"]
@@ -439,7 +439,7 @@ 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
@@ -451,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)
+* [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/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/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/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/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/python-es.html.markdown b/es-es/python-es.html.markdown
index 2b8f498a..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.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
@@ -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 3236e73a..0a7304e9 100644
--- a/es-es/python3-es.html.markdown
+++ b/es-es/pythonlegacy-es.html.markdown
@@ -1,25 +1,26 @@
---
-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]
-```python
+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.
"""
@@ -30,49 +31,69 @@ Es básicamente pseudocódigo ejecutable.
# 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
-# 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
+# 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
-# Cuando usas un float, los resultados son floats
-3 * 2.0 # => 6.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
+
+# 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,41 +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")
+# % pueden ser usados para formatear strings, como esto:
+"%s pueden ser %s" % ("strings", "interpolados")
-# 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"
+# 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/conjuntos 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(set()) #=> 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
@@ -128,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
@@ -158,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]
@@ -174,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]
-# Verifica 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
@@ -200,7 +217,7 @@ d, e, f = 4, 5, 6
e, d = d, e # d ahora es 5 y e ahora es 4
-# Diccionarios relacionan llaves y valores
+# Diccionarios almacenan mapeos
dicc_vacio = {}
# Aquí está un diccionario prellenado
dicc_lleno = {"uno": 1, "dos": 2, "tres": 3}
@@ -208,16 +225,16 @@ 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.
-# Verifica la existencia de una llave en el diccionario con 'in'
+# Chequea la existencia de una llave en el diccionario con 'in'
"uno" in dicc_lleno #=> True
1 in dicc_lleno #=> False
@@ -231,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}
@@ -257,7 +275,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}
-# Verifica la existencia en un conjunto con 'in'
+# Chequea la existencia en un conjunto con 'in'
2 in conjunto_lleno #=> True
10 in conjunto_lleno #=> False
@@ -266,30 +284,32 @@ conjunto_lleno | otro_conjunto #=> {1, 2, 3, 4, 5, 6}
## 3. Control de Flujo
####################################################
-# Creemos una variable para experimentar
-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 iterables (listas, cadenas, diccionarios, tuplas, generadores...)
+For itera sobre listas
imprime:
perro es un mamifero
gato es un mamifero
raton es un mamifero
"""
for animal in ["perro", "gato", "raton"]:
- print("{} es un mamifero".format(animal))
+ # Puedes usar % para interpolar strings formateados
+ print "%s es un mamifero" % animal
"""
-`range(número)` retorna un generador de números
+`range(número)` retorna una lista de números
desde cero hasta el número dado
imprime:
0
@@ -298,7 +318,7 @@ imprime:
3
"""
for i in range(4):
- print(i)
+ print i
"""
While itera hasta que una condición no se cumple.
@@ -310,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) #=> 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
@@ -360,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
@@ -369,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
@@ -385,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
@@ -423,28 +410,23 @@ 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. 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)
@@ -454,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*"
@@ -485,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
@@ -513,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?
@@ -563,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/perl6-es.html.markdown b/es-es/raku-es.html.markdown
index bf3ae65e..e916d0fd 100644
--- a/es-es/perl6-es.html.markdown
+++ b/es-es/raku-es.html.markdown
@@ -1,8 +1,8 @@
---
name: perl6
category: language
-language: perl6
-filename: perl6-es.p6
+language: Raku
+filename: learnraku-es.raku
contributors:
- ["vendethiel", "http://github.com/vendethiel"]
- ["Samantha McVey", "https://cry.nu"]
@@ -11,10 +11,10 @@ translators:
lang: es-es
---
-Perl 6 es un lenguaje de programación altamente capaz y con características
+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 Perl 6 se llama [Rakudo](http://rakudo.org), el cual
+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,
@@ -26,7 +26,7 @@ mientras que un solo signo de número (#) indica notas.
# Un comentario de una sola línea comienza con un signo de número
#`(
- Comentarios multilíneas usan #` y signos de encerradura tales
+ Comentarios multilíneas usan #` y signos de encerradura tales
como (), [], {}, 「」, etc.
)
```
@@ -34,28 +34,28 @@ mientras que un solo signo de número (#) indica notas.
## Variables
```perl6
-## En Perl 6, se declara una variable lexical usando `my`
+## En Raku, se declara una variable lexical usando `my`
my $variable;
-## Perl 6 tiene 3 tipos básicos de variables: escalares, arrays, y hashes.
+## Raku tiene 3 tipos básicos de variables: escalares, arrays, y hashes.
```
### Escalares
```perl6
-# Un escalar representa un solo valor. Variables escalares comienzan
+# Un escalar representa un solo valor. Variables escalares comienzan
# con un `$`
my $str = 'Cadena';
-# Las comillas inglesas ("") permiten la intepolación (lo cual veremos
+# 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
+## 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 Perl 6.
+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
@@ -70,7 +70,7 @@ my $bool-forzado = so $str; # Y puedes usar el operador prefijo `so` que
my @array = 'a', 'b', 'c';
# equivalente a:
my @letras = <a b c>; # array de palabras, delimitado por espacios.
- # Similar al qw de perl5, o el %w de Ruby.
+ # 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
@@ -83,7 +83,7 @@ say "Interpola todos los elementos de un array usando [] : @array[]";
@array[0, 1] = 5, 6; # Asigna varios valores
my @llaves = 0, 2;
-@array[@llaves] = @letras; # Asignación usando un array que contiene valores
+@array[@llaves] = @letras; # Asignación usando un array que contiene valores
# índices
say @array; #=> a 6 b
```
@@ -93,19 +93,19 @@ say @array; #=> a 6 b
```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
+## 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
+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, Perl 6 te permite crear un hash usando un array
+## 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>;
@@ -122,7 +122,7 @@ my %hash = :w(1), # equivalente a `w => 1`
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 Perl 6 no tiene
+ # (`{llave1}` no funciona, debido a que Raku no tiene
# palabras desnudas (barewords en inglés))
```
@@ -133,7 +133,7 @@ say %hash<llave2>; # Si es una cadena de texto, puedes actualmente usar <>
## creadas con la palabra clave `sub`.
sub di-hola { say "¡Hola, mundo!" }
-## Puedes proveer argumentos (tipados). Si especificado,
+## 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) {
@@ -165,7 +165,7 @@ 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
+ say "Podría returnar `(Any)` (valor de Perl parecido al 'null') si no me pasan
un argumento, o returnaré mi argumento";
$arg;
}
@@ -173,7 +173,7 @@ con-opcional; # devuelve Any
con-opcional(); # devuelve Any
con-opcional(1); # devuelve 1
-## También puedes proveer un argumento por defecto para
+## También puedes proveer un argumento por defecto para
## cuando los argumentos no son proveídos:
sub hola-a($nombre = "Mundo") {
say "¡Hola, $nombre!";
@@ -190,10 +190,10 @@ sub con-nombre($arg-normal, :$nombrado) {
}
con-nombre(1, nombrado => 6); #=> 7
## Sin embargo, debes tener algo en cuenta aquí:
-## Si pones comillas alrededor de tu llave, Perl 6 no será capaz de verla
+## 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:
+## un argumento posicional, lo que significa que el siguiente ejemplo
+## falla:
con-nombre(1, 'nombrado' => 6);
con-nombre(2, :nombrado(5)); #=> 7
@@ -205,7 +205,7 @@ sub con-nombre-mandatorio(:$str!) {
}
con-nombre-mandatorio(str => "Mi texto"); #=> Mi texto!
con-nombre-mandatorio; # error al tiempo de ejecución:
- # "Required named parameter not passed"
+ # "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"
@@ -226,7 +226,7 @@ sub nombrado-definido(:$def = 5) {
nombrado-definido; #=> 5
nombrado-definido(def => 15); #=> 15
-## Dado que puedes omitir los paréntesis para invocar una función sin
+## 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;
@@ -240,8 +240,8 @@ sub muchos($principal, *@resto) { #`*@` (slurpy) consumirá lo restante
say @resto.join(' / ') ~ "!";
}
say muchos('Feliz', 'Cumpleaño', 'Cumpleaño'); #=> Feliz / Cumpleaño!
- # Nota que el asterisco (*) no
- # consumió el parámetro frontal.
+ # 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" `|`
@@ -256,12 +256,12 @@ concat3(|@array); #=> a, b, c
## Contenedores
```perl6
-## En Perl 6, valores son actualmente almacenados en "contenedores".
-## El operador de asignación le pregunta al contenedor en su izquierda
+## 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
+## Si realmente necesitas hacerlo, puedes preguntar por un contenedor
## mutable usando `is rw`:
sub mutar($n is rw) {
$n++;
@@ -276,7 +276,7 @@ mutar $m; # ¡$n es ahora 43!
## dado que no contenedor ha sido pasado y números enteros son inmutables
## por naturaleza:
-mutar 42; # Parámetro '$n' esperaba un contenedor mutable,
+mutar 42; # Parámetro '$n' esperaba un contenedor mutable,
# pero recibió un valor Int
## Si en cambio quieres una copia, debes usar `is copy`.
@@ -286,7 +286,7 @@ mutar 42; # Parámetro '$n' esperaba un contenedor mutable,
my $x = 42;
sub x-almacena() is rw { $x }
x-almacena() = 52; # En este caso, los paréntesis son mandatorios
- # (porque de otra forma, Perl 6 piensa que la función
+ # (porque de otra forma, Raku piensa que la función
# `x-almacena` es un identificador).
say $x; #=> 52
```
@@ -297,9 +297,9 @@ say $x; #=> 52
```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
+## "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!";
@@ -316,8 +316,8 @@ unless False {
## 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
+## - 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;
@@ -338,21 +338,21 @@ say $edad > 18 ?? "Eres un adulto" !! "Eres menor de 18";
##
## `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 Perl 6 usan esta variable (por ejemplo,
+##
+## 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
+## 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 –
+ 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`)
+ # i.e. (`$a ~~ True`)
# por lo tanto puedes también poner condiciones "normales".
# Este `when` es equivalente a este `if`:
# if $_ ~~ ($_.chars > 50) {...}
@@ -373,12 +373,12 @@ given "foo bar" {
## 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`
+ 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
+ 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.
@@ -391,29 +391,29 @@ for @array -> $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
+## 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.
+ # 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
+ 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
+ redo if $_ == 4; # Re-hacer la iteración, manteniendo la
# misma variable tópica (`$_`)
- last if $_ == 5; # Salir fuera del bucle (como `break`
+ 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 Perl 6.
+## 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";
}
@@ -423,7 +423,7 @@ if computación-larga() -> $resultado {
```perl6
## Dados que los lenguajes de la familia Perl son lenguages basados
-## mayormente en operadores, los operadores de Perl 6 son actualmente
+## 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).
@@ -455,7 +455,7 @@ if computación-larga() -> $resultado {
(1, 2) eqv (1, 3);
## - Operador de coincidencia inteligente (smart matching): `~~`
-## Asocia (aliasing en inglés) el lado izquierda a la variable $_
+## 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:
@@ -464,8 +464,8 @@ if computación-larga() -> $resultado {
'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
+## 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/;
@@ -475,12 +475,12 @@ 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
+## 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
+## Coincidencia inteligente contra un booleano siempre devuelve ese
## booleano (y lanzará una advertencia).
1 ~~ True; # True
@@ -502,13 +502,13 @@ False ~~ True; # True
## Esto también funciona como un atajo para `0..^N`:
^10; # significa 0..^10
-## Esto también nos permite demostrar que Perl 6 tiene arrays
+## 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, Perl 6 "cosificará" los elementos que
+## 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.
@@ -517,14 +517,14 @@ say @array[^10]; # puedes pasar arrays como subíndices y devolverá
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,
+## 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
+## 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,
@@ -546,7 +546,7 @@ $a && $b && $c; # Devuelve 0, el primer valor que es False
$b || $a; # 1
## Y porque tu lo querrás, también tienes operadores de asignación
-## compuestos:
+## 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.
@@ -555,8 +555,8 @@ $b %%= 5; # divisible por y asignación. Equivalente $b = $b %% 5;
## ¡Más sobre subrutinas!
```perl6
-## Como dijimos anteriormente, Perl 6 tiene subrutinas realmente poderosas.
-## Veremos unos conceptos claves que la hacen mejores que en cualquier otro
+## Como dijimos anteriormente, Raku tiene subrutinas realmente poderosas.
+## Veremos unos conceptos claves que la hacen mejores que en cualquier otro
## lenguaje :-).
```
@@ -602,14 +602,14 @@ sub fst(*@ [$fst]) { # o simplemente: `sub fst($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
+## 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
+## 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)
@@ -621,11 +621,11 @@ sub siguiente-indice($n) {
}
my $nuevo-n= siguiente-indice(3); # $nuevo-n es ahora 4
-## Este es cierto para todo, excepto para las construcciones de bucles
+## 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)
+## (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
@@ -639,19 +639,19 @@ my @list3 = lista-de(3); #=> (0, 1, 2)
```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
+## `-> {}` 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"
+## 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`
+ # 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);
}
@@ -685,7 +685,7 @@ map(sub ($a, $b) { $a + $b + 3 }, @array); # (aquí con `sub`)
### Acerca de tipos...
```perl6
-## Perl 6 es gradualmente tipado. Esto quiere decir que tu especifica el
+## 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.
@@ -703,7 +703,7 @@ subset EnteroGrande of Int where * > 500;
### Despacho Múltiple (Multiple Dispatch)
```perl6
-## Perl 6 puede decidir que variante de una subrutina invocar basado en el
+## 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`:
@@ -740,9 +740,9 @@ multi sin_ti-o-contigo {
}
## 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.
+## en muchos lugares.
##
-## - `is`, por ejemplo, es actualmente un `multi sub` llamado
+## - `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!) {}
@@ -754,7 +754,7 @@ multi sin_ti-o-contigo {
## Ámbito (Scoping)
```perl6
-## En Perl 6, a diferencia de otros lenguajes de scripting, (tales como
+## 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.
@@ -770,7 +770,7 @@ sub externo {
}
outer()(); #=> 'Foo Bar'
-## Como puedes ver, `$archivo-en-ámbito` y `$ámbito-externo`
+## 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).
@@ -779,12 +779,12 @@ outer()(); #=> 'Foo Bar'
## Twigils
```perl6
-## Hay muchos `twigils` especiales (sigilos compuestos) en Perl 6.
-## Los twigils definen el ámbito de las variables.
+## 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 Perl 6:
+## Los twigils ! y . son usados con los objetos de Raku:
## ! Atributo (miembro de la clase)
## . Método (no una variable realmente)
@@ -820,20 +820,20 @@ di_ambito(); #=> 1 100 Cambiamos el valor de $*ambito_din_2 en invoca_a_di_ambit
```perl6
## Para invocar a un método en un objeto, agrega un punto seguido por el
-## nombre del objeto:
+## 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
+## 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
+## 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 Perl 6 ("SixModel") es muy flexible, y te permite
+## 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.perl6.org/language/objects.html).
+## (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.
@@ -858,7 +858,7 @@ class Clase-Atrib {
};
## 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
+## 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
@@ -870,12 +870,12 @@ $class-obj.otro-atrib = 10; # En cambio, esto funciona porque el atributo
### Herencia de Objeto
```perl6
-## Perl 6 también tiene herencia (junto a herencia múltiple)
+## 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.
+## Aprenderemos acerca de BUILD más adelante.
class Padre {
has $.edad;
@@ -890,7 +890,7 @@ class Padre {
# 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 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');
@@ -899,19 +899,19 @@ $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
+$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:
+## (`.=` 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
+## 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`.
```
@@ -932,7 +932,7 @@ 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
+ ## 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++;
@@ -945,17 +945,17 @@ class Item does PrintableVal {
## 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.
+ ## 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
+## Excepciones están construidas al tope de las clases, en el paquete
## `X` (como `X::IO`).
-## En Perl 6, excepciones son lanzadas automáticamente.
+## 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.
@@ -966,16 +966,16 @@ die 'Error!'; #=> Error!
## O más explícitamente:
die X::AdHoc.new(payload => 'Error!');
-## En Perl 6, `orelse` es similar al operador `or`, excepto que solamente
+## 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
+## 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
+## 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.
@@ -986,7 +986,7 @@ open 'foo' orelse say "Algo pasó {.exception}";
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
+## 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.
```
@@ -994,8 +994,8 @@ open 'foo' orelse say "Algo pasó $_"; #=> Algo pasó
### 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
+## 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 $!.
@@ -1003,12 +1003,12 @@ 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 Perl 6 se pone el bloque `CATCH`
+## 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
+## 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ó: $_" } }
@@ -1022,9 +1022,9 @@ try {
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
+ ## Cualquier otra excepción será levantada de nuevo, dado que no
## tenemos un `default`.
- ## Básicamente, si un `when`
+ ## 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`.
@@ -1032,14 +1032,14 @@ try {
}
}
-## En Perl 6, excepciones poseen ciertas sutilezas. Algunas
-## subrutinas en Perl 6 devuelven un `Failure`, el cual es un tipo de
+## 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
+## 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
+## 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.
@@ -1053,27 +1053,27 @@ try {
## 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).
+## 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
+## 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
+## 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
+## 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 5, no deberías declarar paquetes usando
+## 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
+## para declarar una clase, o si solamente quieres exportar
## variables/subrutinas, puedes usar `module`.
module Hello::World { # forma de llaves
@@ -1083,11 +1083,11 @@ module Hello::World { # forma de llaves
}
unit module Parse::Text; # forma de ámbito de archivo
-grammar Parse::Text::Grammar { # Una gramática (grammar en inglés) es un paquete,
+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
+## 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;
@@ -1098,13 +1098,13 @@ my $acciones = JSON::Tiny::Actions.new;
## Declaradores
```perl6
-## En Perl 6, tu obtienes diferentes comportamientos basado en como declaras
+## 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
+## (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
@@ -1132,7 +1132,7 @@ Var::Incrementar::Inc; #=> 3 # Nota como el valor de $nuestra-var fue
Var::Incrementar::no-disponible; #=> Could not find symbol '&no-disponible'
## * `constant` (ocurre al tiempo `BEGIN`)
-## Puedes usar la palabra clave `constant` para declarar una
+## Puedes usar la palabra clave `constant` para declarar una
## variable/símbolo al tiempo de compilación:
constant Pi = 3.14;
constant $var = 1;
@@ -1151,11 +1151,11 @@ sub aleatorio-fijo {
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
+## 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
+ state $valor = rand; # Esto imprimirá un valor diferente
# por cada valor de `$a`
}
for ^5 -> $b {
@@ -1165,11 +1165,11 @@ for ^5 -> $a {
}
```
-## Phasers
+## Phasers
```perl6
-## Un phaser en Perl 6 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
+## 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!)
@@ -1191,13 +1191,13 @@ 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, " ~
+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 " ~
+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, " ~
+ 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.";
@@ -1209,7 +1209,7 @@ for 0..2 {
}
POST {
- say "Impone una postcondAsserts a poscondición a la salida de un bloque, " ~
+ 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.";
@@ -1250,14 +1250,14 @@ sub do-db-stuff {
## Prefijos de sentencias
```perl6
-## Los prefijos de sentencias actúan como los phasers: Ellos afectan el
+## 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
+## - `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):
##
@@ -1289,7 +1289,7 @@ say join ',', gather if False {
## - `eager` - Evalúa una sentencia ávidamente (forza contexto ávido)
## No intentes esto en casa:
##
-## eager 1..*; # esto probablemente se colgará por un momento
+## eager 1..*; # esto probablemente se colgará por un momento
## # (y podría fallar...).
##
## Pero considera lo siguiente:
@@ -1302,13 +1302,13 @@ constant tres-veces = eager gather for ^3 { say take $_ }; #=> 0 1 2
## Iterables
```perl6
-## En Perl 6, los iterables son objetos que pueden ser iterados similar
-## a la construcción `for`.
+## 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
+## - `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`.
@@ -1333,7 +1333,7 @@ quietly { warn 'Esto es una advertencia!' }; #=> No salida
## ¡Todo el mundo ama los operadores! Tengamos más de ellos.
## La lista de precedencia puede ser encontrada aquí:
-## https://docs.perl6.org/language/operators#Operator_Precedence
+## https://docs.raku.org/language/operators#Operator_Precedence
## Pero primero, necesitamos un poco de explicación acerca
## de la asociatividad:
@@ -1356,7 +1356,7 @@ $a ! $b ! $c; # con asociatividad de lista `!`, esto es `infix:<>`
## 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 Perl 6, todos los operadores son actualmente solo subrutinas.
+## 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
@@ -1374,14 +1374,14 @@ sub postfix:<!>(Int $n) {
}
say 5!; #=> 120
# Operadores sufijos (postfix) van *directamente* después del témino.
- # No espacios en blanco. Puedes usar paréntesis para disambiguar,
+ # 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
+ # almacenada en la variable `$r`. De lo contrario, te estaría
# refiriendo a la variable (no a la función), como con `&r`.
}
}
@@ -1399,33 +1399,33 @@ say [5]; #=> 3125
# un circunfijo va alrededor. De nuevo, no espacios en blanco.
sub postcircumfix:<{ }>(Str $s, Int $idx) {
- ## un pos-circunfijo es
+ ## 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 Perl 6 usa esto.
+## 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
+postcircumfix:<{ }>(%h, $llave, :delete); # (puedes invocar
# operadores de esta forma)
-## ¡*Todos* usan los mismos bloques básicos!
+## ¡*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
+## (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
+## ¡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*.
@@ -1434,14 +1434,14 @@ postcircumfix:<{ }>(%h, $llave, :delete); # (puedes invocar
## * 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
+## 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
+## 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 `+`,
+## 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`
@@ -1461,20 +1461,20 @@ 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
+## 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
+## 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
+## 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
+(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:<+>
+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
@@ -1487,13 +1487,13 @@ say [[&add]] 1, 2, 3; #=> 6
## Y para terminar la lista de operadores:
## * El operador secuencia
-## El operador secuencia es uno de la más poderosas características de
-## Perl 6: Está compuesto, en la izquierda, de la lista que quieres que
-## Perl 6 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
+## 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 Perl 6 no puede deducir el final
+#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
@@ -1505,8 +1505,8 @@ my @fib = 1, 1, *+* ... *; # lista infinita perezosa de la serie fibonacci,
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),
+## 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
@@ -1519,29 +1519,29 @@ say @fib[^10]; #=> 1 1 2 3 5 8 13 21 34 55
## Expresiones Regulares
```perl6
-## Estoy seguro que has estado esperando por esta parte. Bien, ahora que
-## sabes algo acerca de Perl 6, podemos comenzar. Primeramente, tendrás
-## que olvidarte acerca de "PCRE regexps" (perl-compatible regexps)
+## 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
+## 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.
##
-## Perl 6 tiene muchas características relacionadas con RegExps. Después de
+## 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
+## 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
+## Nota aparte: Todavía tienes acceso a los regexes PCRE usando el
## mofificador `:P5` (Sin embargo, no lo discutiremos en este tutorial).
##
-## En esencia, Perl 6 implementa PEG ("Parsing Expression Grammars")
+## 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
+## 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`
+## - 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
@@ -1550,48 +1550,48 @@ say @fib[^10]; #=> 1 1 2 3 5 8 13 21 34 55
say so 'a' ~~ /a/; #=> True
say so 'a' ~~ / a /; #=> True # ¡Más legible con los espacios!
-## Nota al lector (del traductor):
+## 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
+## 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
+## 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.)
+## (seguida de una `n`, etc.)
-## En todos nuestros ejemplos, vamos a usar el operador de
-## "coincidencia inteligente" contra una expresión regular ("regexp" or
+## 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
+## 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
+## 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,
+## 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 Perl 6, puedes tener un carácter alfanumérico como un literal,
+## 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`. 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,
+## 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, Perl 6
+## 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
+## 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
+## 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`
@@ -1603,7 +1603,7 @@ say so 'abc' ~~ m[a b c]; #=> `True`
## minúsculas y mayúsculas:
say so 'ABC' ~~ m:i{a b c}; #=> `True`
-## Sin embargo, es importante para como los modificadores son aplicados
+## Sin embargo, es importante para como los modificadores son aplicados
## (lo cual verás más abajo)...
## Cuantificando - `?`, `+`, `*` y `**`.
@@ -1612,7 +1612,7 @@ 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
+## ... 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
@@ -1642,7 +1642,7 @@ so 'abbbbbbc' ~~ / a b**3..* c /; # `True` (rangos infinitos no son un problem
## - `<[]>` - Clases de carácteres
## Las clases de carácteres son equivalentes a las clases `[]` de PCRE,
-## pero usan una sintaxis de Perl 6:
+## pero usan una sintaxis de Raku:
say 'fooa' ~~ / f <[ o a ]>+ /; #=> 'fooa'
## Puedes usar rangos:
@@ -1663,7 +1663,7 @@ 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
+so 'foo!' ~~ / <-[ a..z ] + [ f o ]> + /; # True (el signo + no reemplaza la
# parte de la izquierda)
```
@@ -1671,7 +1671,7 @@ so 'foo!' ~~ / <-[ a..z ] + [ f o ]> + /; # True (el signo + no reemplaza la
```perl6
## Grupo: Puedes agrupar partes de tu regexp con `[]`.
-## Estos grupos *no son* capturados (como con `(?:)` en PCRE).
+## 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`.
@@ -1680,15 +1680,15 @@ so 'foo012012bar' ~~ / foo [ '01' <[0..9]> ] + bar /;
## 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,
+## 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,
+## 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ó
+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」
@@ -1696,15 +1696,15 @@ say $/[0]; #=> 「ABC」 「ABC」
# 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
+## 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
+## 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」
@@ -1718,22 +1718,22 @@ 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]`,
+## 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]`
+## 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"
+ # 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.
@@ -1743,9 +1743,9 @@ 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
+## 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.
+## 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
@@ -1759,19 +1759,19 @@ so 'ayc' ~~ / a [ b | y ] c /; # `True`. Obviamente suficiente...
## 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
+## 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)
+## 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
+## Nota: la primera coincidencia `or` todavía existen, pero ahora se
## deletrea `||`
'foo' ~~ / fo || foo /; # `fo` ahora.
```
@@ -1779,19 +1779,19 @@ so 'ayc' ~~ / a [ b | y ] c /; # `True`. Obviamente suficiente...
## Extra: la subrutina MAIN
```perl6
-## La subrutina `MAIN` se invoca cuando tu ejecuta un archivo de Perl 6
-## directamente. Es realmente poderosa porque Perl 6 actualmente parsea
-## los argumentos y los pasas a la subrutina. También maneja argumentos
+## 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:
-## $ perl6 cli.pl
+## $ raku cli.pl
## Uso:
## t.pl <nombre>
-## Y dado que una subrutina regular en Perl 6, puedes tener múltiples
+## Y dado que una subrutina regular en Raku, puedes tener múltiples
## despachos:
-## (usando un "Bool" por un argumento nombrado para que podamos hacer
+## (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
@@ -1800,7 +1800,7 @@ multi MAIN('add', $key, $value, Bool :$replace) { ... }
multi MAIN('remove', $key) { ... }
multi MAIN('import', File, Str :$as) { ... } # omitiendo parámetros nombrados
## Esto produce:
-## $ perl6 cli.pl
+## $ raku cli.pl
## Uso:
## t.pl [--replace] add <key> <value>
## t.pl remove <key>
@@ -1814,7 +1814,7 @@ multi MAIN('import', File, Str :$as) { ... } # omitiendo parámetros nombrados
### Lista de cosas
```perl6
-## Consideramos que por ahora ya sabes lo básico de Perl 6.
+## 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.
@@ -1825,13 +1825,13 @@ multi MAIN('import', File, Str :$as) { ... } # omitiendo parámetros nombrados
## (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
+$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
+## * Operador (por defecto) de circuito corto
## Al igual que `or` y `||`, pero devuelve el primer valor *defined*
## (definido):
say Any // Nil // 0 // 5; #=> 0
@@ -1843,9 +1843,9 @@ 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
+## 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
+## 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> {
@@ -1861,25 +1861,25 @@ for <well met young hero we shall meet later> {
}
## 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`),
+## (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
+## 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
+## `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`
+ # 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ó
+ # (y por lo tanto no coincidió
# inmediamente).
## Un flip-flop puede cambiar estado cuantas veces se necesite:
@@ -1901,35 +1901,35 @@ for (1, 3, 60, 3, 40, 60) { # Nota: los paréntesis son superfluos aquí
## 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
+ # pero el `^` lo hace *que no se ejecute* en la
# primera iteración
#=> b c
}
-## - `===` es la identidad de valor y usa `.WHICH`
+## - `===` es la identidad de valor y usa `.WHICH`
## en los objetos para compararlos.
-## - `=:=` es la identidad de contenedor y usa `VAR()`
+## - `=:=` 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 Perl 6](https://docs.perl6.org/). Esto es un recurso
- grandioso acerca de Perl 6. Si estás buscando por algo en particular, usa la
+ - 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 Perl 6!)
- - Leer el [Perl 6 Advent Calendar](http://perl6advent.wordpress.com/). Este es
- un gran recurso de fragmentos de código de Perl 6 y explicaciones. Si la documentación
+ 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 Perl 6.c fue lanzado.
- - Unirte a `#perl6` en `irc.freenode.net`. Las personas aquí son siempre serviciales.
- - Chequear la [fuente de las funciones y clases de Perl 6
- ](https://github.com/rakudo/rakudo/tree/nom/src/core). Rakudo está principalmente
- escrito en Perl 6 (con mucho de NQP, "Not Quite Perl" ("No Perl Todavía"), un
- subconjunto de Perl 6 que es más fácil de implementar y optimizar).
- - Leer [documentos acerca del diseño del lenguaje](http://design.perl6.org).
+ 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/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/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/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/fr-fr/crystal-fr.html.markdown b/fr-fr/crystal-fr.html.markdown
index 2bb17fc5..02ab3b2b 100644
--- a/fr-fr/crystal-fr.html.markdown
+++ b/fr-fr/crystal-fr.html.markdown
@@ -350,7 +350,7 @@ sum 3, 4 #=> 7
sum sum(3, 4), 5 #=> 12
# yield
-# Toutes les méthodes on un paramètre optionel et implicite de type bloc
+# 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 '{'
diff --git a/fr-fr/elisp-fr.html.markdown b/fr-fr/elisp-fr.html.markdown
index 2e0a9408..f9bf589c 100644
--- a/fr-fr/elisp-fr.html.markdown
+++ b/fr-fr/elisp-fr.html.markdown
@@ -328,9 +328,9 @@ lang: fr-fr
(other-window 1))
;; Cette fonction introduit `re-search-forward' : au lieu de chercher
-;; la chaîne "Bonjour", nous cherchons un "pattern" en utilisant une
-;; "expression régulière" (le préfixe "re-" signifie "regular
-;; expression").
+;; 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
@@ -343,7 +343,7 @@ lang: fr-fr
(boldify-names)
-;; `add-text-properties' ajoute des propriétés textuelles telle que
+;; `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.)
@@ -361,7 +361,7 @@ lang: fr-fr
;; 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 suggetions :
+;; Merci à ces personnes pour leurs retours et suggestions :
;; - Wes Hardaker
;; - notbob
;; - Kevin Montuori
diff --git a/fr-fr/fsharp-fr.html.markdown b/fr-fr/fsharp-fr.html.markdown
index 3fd41676..dda9945f 100644
--- a/fr-fr/fsharp-fr.html.markdown
+++ b/fr-fr/fsharp-fr.html.markdown
@@ -140,7 +140,8 @@ module FunctionExamples =
let a = add 1 2
printfn "1+2 = %i" a
- // partial application to "bake in" parameters (?)
+ // 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
diff --git a/fr-fr/javascript-fr.html.markdown b/fr-fr/javascript-fr.html.markdown
index faa22863..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
---
@@ -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/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/python-fr.html.markdown b/fr-fr/python-fr.html.markdown
index 0ae410de..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.0
+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 7112cd90..00000000
--- a/fr-fr/python3-fr.html.markdown
+++ /dev/null
@@ -1,732 +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"]
- - ["Julien M'Poy", "http://github.com/groovytron"]
-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 plus 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"
-
-# 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")
-
-
-# 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) # Maintenant li contient [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'appeler 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 "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"
-
- # 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 à 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 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/)
-
-### En ligne et gratuit (en français)
-
-* [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/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/fsharp.html.markdown b/fsharp.html.markdown
index 064a9fdd..c140d6b1 100644
--- a/fsharp.html.markdown
+++ b/fsharp.html.markdown
@@ -633,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 aa96c90a..a40ef01b 100644
--- a/git.html.markdown
+++ b/git.html.markdown
@@ -82,12 +82,12 @@ 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)
diff --git a/go.html.markdown b/go.html.markdown
index ae99535b..b727e59d 100644
--- a/go.html.markdown
+++ b/go.html.markdown
@@ -12,6 +12,8 @@ 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
@@ -30,6 +32,12 @@ Go comes with a good standard library and a sizeable community.
/* Multi-
line comment */
+ /* A build tag is a line comment starting with // +build
+ and can be execute 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
@@ -102,6 +110,11 @@ can include line breaks.` // Same string type.
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 a5. No ellipsis here.
@@ -109,6 +122,11 @@ can include line breaks.` // Same string type.
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,
@@ -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.
@@ -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.
@@ -428,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.
@@ -441,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 89ca973a..0d589c10 100644
--- a/groovy.html.markdown
+++ b/groovy.html.markdown
@@ -184,7 +184,7 @@ class Foo {
Methods with optional parameters
*/
-// A mthod can have default values for parameters
+// A method can have default values for parameters
def say(msg = 'Hello', name = 'world') {
"$msg $name!"
}
diff --git a/haskell.html.markdown b/haskell.html.markdown
index 90d47c27..1cc79ec9 100644
--- a/haskell.html.markdown
+++ b/haskell.html.markdown
@@ -293,7 +293,13 @@ 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
@@ -304,7 +310,62 @@ say Red = "You are Red!"
say Blue = "You are Blue!"
say Green = "You are Green!"
--- Your data types can have parameters too:
+-- 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
+
+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
@@ -313,8 +374,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,
@@ -395,7 +546,7 @@ main'' = do
----------------------------------------------------
--- 9. The Haskell REPL
+-- 10. The Haskell REPL
----------------------------------------------------
-- Start the repl by typing `ghci`.
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/hu-hu/python-hu.html.markdown b/hu-hu/pythonlegacy-hu.html.markdown
index 01f1c414..b5922766 100644
--- a/hu-hu/python-hu.html.markdown
+++ b/hu-hu/pythonlegacy-hu.html.markdown
@@ -1,5 +1,5 @@
---
-language: python
+language: Python 2 (legacy)
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
- ["Amin Bandali", "https://aminb.org"]
@@ -9,7 +9,7 @@ contributors:
- ["habi", "http://github.com/habi"]
translators:
- ["Tamás Diószegi", "https://github.com/ditam"]
-filename: learnpython-hu.py
+filename: learnpythonlegacy-hu.py
lang: hu-hu
---
@@ -23,7 +23,7 @@ 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/python3/)
+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
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/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/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/javascript-it.html.markdown b/it-it/javascript-it.html.markdown
index 68bf6287..1d776535 100644
--- a/it-it/javascript-it.html.markdown
+++ b/it-it/javascript-it.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:
- ["vinniec", "https://github.com/vinniec"]
diff --git a/it-it/python-it.html.markdown b/it-it/python-it.html.markdown
index 794e7a70..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"]
+ - ["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.0
+ # 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/python3-it.html.markdown b/it-it/python3-it.html.markdown
deleted file mode 100644
index 04f78cff..00000000
--- a/it-it/python3-it.html.markdown
+++ /dev/null
@@ -1,1016 +0,0 @@
----
-language: python3
-filename: learnpython3-it.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"]
- - ["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
----
-
-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 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 documentazione
-"""
-
-####################################################
-## 1. Tipi di dati primitivi ed Operatori
-####################################################
-
-# Ci sono i numeri
-3 # => 3
-
-# La matematica è quello che vi aspettereste
-1 + 1 # => 2
-8 - 1 # => 7
-10 * 2 # => 20
-35 / 5 # => 7.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
-
-# Il risultato di una divisione è sempre un numero decimale (float)
-10.0 / 3 # => 3.3333333333333335
-
-# Operazione Modulo
-7 % 3 # => 1
-
-# Elevamento a potenza (x alla y-esima potenza)
-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
-
-# Note sull'uso di operatori Bool con interi
-# 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
-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
-
-# ('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! 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'
-
-# Puoi conoscere la lunghezza di una stringa
-len("Questa è una stringa") # => 20
-
-# .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"
-
-# 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
-
-# Non usare il simbolo di uguaglianza "==" per comparare oggetti a None
-# Usa "is" invece
-"etc" is None # => 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 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 = 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
-# 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.
-some_unknown_var # Genera un errore di nome
-
-# if può essere usato come un'espressione
-# È l'equivalente dell'operatore ternario in C
-"yahoo!" if 3 > 2 else 2 # => "yahoo!"
-
-# Le liste immagazzinano sequenze
-li = []
-# Puoi partire con una lista pre-riempita
-other_li = [4, 5, 6]
-
-# 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]
-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
-# Guarda l'ultimo elemento
-li[-1] # => 3
-
-# Guardare al di fuori dei limiti genera 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]
-
-# 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]
-
-# 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
-
-# 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
-
-# Esamina la lunghezza con "len()"
-len(li) # => 6
-
-
-# Le tuple sono come le liste ma immutabili.
-tup = (1, 2, 3)
-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
-
-# Puoi scompattare le tuple (o liste) in variabili
-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
-
-# 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}
-
-# 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
-
-# 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"]
-
-
-# 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
-
-# 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
-# Il metodo get supporta un argomento di default quando il valore è mancante
-filled_dict.get("uno", 4) # => 1
-filled_dict.get("quattro", 4) # => 4
-
-
-# "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
-
-# Rimuovi una chiave da un dizionario con del
-del filled_dict["uno"] # Rimuove la chiave "uno" dal dizionario
-
-# 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}
-
-# 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 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}
-some_set & other_set # => {3, 4, 5}
-
-# Fai unioni su set con |
-some_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 some_set # => True
-10 in some_set # => False
-
-
-
-####################################################
-## 3. Control Flow e oggetti Iterabili
-####################################################
-
-# Dichiariamo una variabile
-some_var = 5
-
-# Questo è un controllo if. L'indentazione è molto importante in python!
-# 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 è 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, 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 format() per interpolare le stringhe formattate.
- print("{} è un mammifero".format(animale))
-
-"""
-"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)
-
-"""
-"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)
-
-"""
-"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
-Il seguente codice scriverà:
- 0
- 1
- 2
- 3
-"""
-x = 0
-while x < 4:
- print(x)
- x += 1 # Forma compatta per x = x + 1
-
-# Gestione delle eccezioni con un blocco try/except
-try:
- # Usa "raise" per generare un errore
- raise IndexError("Questo è un IndexError")
-except IndexError as e:
- 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 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")
-
-# 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)
-
-# 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
-####################################################
-
-# Usa "def" per creare nuove funzioni
-def aggiungi(x, y):
- 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) # => 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) # In questo modo non è necessario rispettare l'ordine degli argomenti
-
-# Puoi definire funzioni che accettano un numero non definito di argomenti
-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)
-
-
-# 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 è 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
-
-set_x(43)
-set_global_x(6)
-
-
-# Python ha "first class functions"
-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
-
-# È 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]
-
-list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [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 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
-####################################################
-
-# 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 l'istruzione "class" per creare una classe
-class Human:
-
- # Un attributo della classe. E' condiviso tra tutte le istanze delle classe
- species = "H. sapiens"
-
- # 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
-
- # Un metodo dell'istanza. Tutti i metodi prendo "self" come primo argomento
- def say(self, 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 chiamati con la classe chiamante come primo argomento
- @classmethod
- def get_species(cls):
- return cls.species
-
- # Un metodo statico è chiamato senza classe o istanza di riferimento
- @staticmethod
- def grunt():
- return "*grunt*"
-
- # 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 una property
- @age.setter
- def age(self, age):
- self._age = age
-
- # Questo metodo permette di cancellare una property
- @age.deleter
- def age(self):
- del self._age
-
-# 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
-
-
-####################################################
-## 6.1 Ereditarietà (Inheritance)
-####################################################
-
-# L'ereditarietà consente di definire nuove classi figlio che ereditano metodi e
-# variabili dalla loro classe genitore.
-
-# 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.
-
-# Per importare le funzioni da altri file usa il seguente formato
-# from "nomefile-senza-estensione" import "funzione-o-classe"
-
-from human import Human
-
-# 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)
-
- #Le classi figlio possono sovrascrivere gli attributi dei loro genitori
- species = 'Superhuman'
-
- # 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":
-
- def __init__(self, name, movie=False,
- superpowers=["super strength", "bulletproofing"]):
-
- # aggiungi ulteriori attributi della classe
- self.fictional = True
- self.movie = movie
- self.superpowers = superpowers
-
- # 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)
-
- # Sovrascrivere il metodo "sing"
- def sing(self):
- return 'Dun, dun, DUN!'
-
- # Aggiungi un ulteriore metodo dell'istanza
- 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")
-
- # 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))
-
-####################################################
-## 6.2 Ereditarietà multipla
-####################################################
-
-# Un'altra definizione di classe
-# bat.py
-class Bat:
-
- species = 'Baty'
-
- 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'
-
- 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
-
-# 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
-
-# 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) # prints -1 -2 -3 -4 -5 to console/terminal
-
-# 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" avvolge/wrappa "say".
-# Se say_please è True, cambierà il messaggio restituito.
-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)
-* [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/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/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/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/python3-jp.html.markdown b/ja-jp/python-jp.html.markdown
index b9731411..18e7d1b8 100644
--- a/ja-jp/python3-jp.html.markdown
+++ b/ja-jp/python-jp.html.markdown
@@ -1,5 +1,5 @@
---
-language: python3
+language: Python
contributors:
- ["Louie Dinh", "http://pythonpracticeprojects.com"]
- ["Steven Basart", "http://github.com/xksteven"]
@@ -11,7 +11,7 @@ contributors:
translators:
- ["kakakaya", "https://github.com/kakakaya"]
- ["Ryota Kayanuma", "https://github.com/PicoSushi"]
-filename: learnpython3-jp.py
+filename: learnpython-jp.py
lang: ja-jp
---
@@ -21,7 +21,7 @@ lang: ja-jp
フィードバッグは大歓迎です! [@louiedinh](http://twitter.com/louiedinh) または louiedinh [at] [google's email service] にご連絡下さい!
-Note: この記事はPython 3に内容を絞っています。もし古いPython 2.7を学習したいなら、 [こちら](http://learnxinyminutes.com/docs/python/) をご確認下さい。
+Note: この記事はPython 3に内容を絞っています。もし古いPython 2.7を学習したいなら、 [こちら](http://learnxinyminutes.com/docs/pythonlegacy/) をご確認下さい。
```python
# 1行のコメントは番号記号(#)から始まります。
@@ -160,8 +160,8 @@ len("This is a string") # => 16
name = "Reiko"
f"She said her name is {name}." # => "She said her name is Reiko"
-# 基本的に、任意のPythonの文を中括弧に書くことができ、それは評価されて出力されます。
-f"{name} is {len(name)} characters long."
+# 基本的に、任意のPythonの文を中括弧に書くことができ、それは文字列で出力されます。
+f"{name} is {len(name)} characters long." # => "Reiko is 5 characters long."
# None はオブジェクトです(大文字からです!)
None # => None
@@ -191,7 +191,7 @@ print("I'm Python. Nice to meet you!") # => I'm Python. Nice to meet you!
print("Hello, World", end="!") # => Hello, World!
# コンソールから入力を得るための簡単な例
-input_string_var = input("Enter some data: ") # 入力を文字列として返します
+input_string_var = input("Enter some data: ") # 入力を文字列として返します。
# Note: Python の初期のバージョンでは、 input() は raw_input() という名前で存在します。
# Pythonでは変数の宣言は存在せず、代入のみです。
@@ -201,7 +201,7 @@ some_var # => 5
# 代入されていない変数へのアクセスは例外を引き起こします。
# 例外の取り扱いについては、3章の制御の流れをご確認ください。
-some_unknown_var # NameError を送出します
+some_unknown_var # NameError を送出します。
# ifは式として使用できます。
# C言語の「?:(三項演算子)」に対応する例:
@@ -228,7 +228,7 @@ li[0] # => 1
li[-1] # => 3
# 範囲外の要素を参照すると IndexError になります。
-li[4] # IndexError が発生します
+li[4] # IndexError が発生します。
# スライス構文により範囲を参照できます。
# 開始部分のインデックスに対応する部分は含まれますが、終了部分のインデックスに対応する部分は含まれません。
@@ -238,28 +238,28 @@ li[2:] # => [4, 3]
# 末尾を取り除いたリスト
li[:3] # => [1, 2, 4]
# 1つ飛ばしで選択する
-li[::2] # =>[1, 4]
+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になる。
+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.remove(2) # 2 はリストの中に存在しないので、 ValueError が発生します。
# 要素を好きなところに挿入できます。
li.insert(1, 2) # li は [1, 2, 3] に戻りました。
# "index"で引数の要素が最初に出現する場所のインデックスを得られます。
li.index(2) # => 1
-li.index(4) # 4はリストの中に存在しないので、 ValueError が発生します。
+li.index(4) # 4 はリストの中に存在しないので、 ValueError が発生します。
# リスト同士を足すこともできます。
# Note: li と other_li の値は変更されません。
@@ -295,11 +295,11 @@ tup[:2] # => (1, 2)
# タプルやリストから複数の変数に代入することができます。
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 になります。
+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 は e になります。
+e, d = d, e # d は 5、 e は 4 になります。
# 辞書はマップ(キーと値の組み合わせ)を保存できます。
@@ -373,7 +373,7 @@ 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}のままです。
+filled_set.add(5) # 以前の {1, 2, 3, 4, 5} のままです。
# & により、集合同士の共通部分が得られます。
other_set = {3, 4, 5, 6}
@@ -453,7 +453,7 @@ for i in range(4, 8):
"""
"range(lower, upper, step)" は、lower の数値から upper の数値までが、
-step 刻みで表現されるiterableを返します
+step 刻みで表現されるiterableを返します。
step が与えられない場合、デフォルトは1になります。
出力:
4
@@ -552,7 +552,7 @@ varargs(1, 2, 3) # => (1, 2, 3)
def keyword_args(**kwargs):
return kwargs
-# 何が起こるか、試してみましょう
+# 何が起こるか、試してみましょう。
keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"}
@@ -591,7 +591,7 @@ x = 5
def set_x(num):
- # ローカル変数の x はグローバル変数の x とは異なります
+ # ローカル変数の x はグローバル変数の x とは異なります。
x = num # => 43
print(x) # => 43
@@ -783,7 +783,7 @@ if __name__ == '__main__':
from human import Human
-# 親クラスを子クラスのパラメータとして指定します
+# 親クラスを子クラスのパラメータとして指定します。
class Superhero(Human):
# もし子クラスが親クラスの全ての定義を変更なしで継承する場合、"pass"キーワードのみを書くだけで良いです。
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 ca0b04c2..79769352 100644
--- a/java.html.markdown
+++ b/java.html.markdown
@@ -289,7 +289,7 @@ public class LearnJava {
// interface. This allows the execution time of basic
// operations, such as get and insert element, to remain
// constant-amortized even for large sets.
- // TreeMap - A Map that is sorted by its keys. Each modification
+ // 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.
@@ -381,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);
@@ -470,11 +470,11 @@ public class LearnJava {
// <second value>"
int foo = 5;
String bar = (foo < 10) ? "A" : "B";
- System.out.println("bar : " + bar); // Prints "bar : A", because the
+ 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
@@ -918,7 +918,7 @@ public class Lambdas {
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
+ // 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
@@ -998,6 +998,8 @@ The links provided here below are just to get an understanding of the topic, fee
* [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 ce9772ca..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
---
@@ -188,7 +188,7 @@ 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"
+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]
diff --git a/jsonnet.html.markdown b/jsonnet.html.markdown
new file mode 100644
index 00000000..9fe4edbe
--- /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 doucment have 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/kdb+.html.markdown b/kdb+.html.markdown
index 027b6571..680c01c1 100644
--- a/kdb+.html.markdown
+++ b/kdb+.html.markdown
@@ -771,6 +771,6 @@ select from splayed / (the columns are read from disk on request)
* [*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](http://code.kx.com/q/ref/card/)
+* [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/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/python-kr.html.markdown b/ko-kr/pythonlegacy-kr.html.markdown
index 0145754d..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
diff --git a/ko-kr/vim-kr.html.markdown b/ko-kr/vim-kr.html.markdown
index cd0fa236..76063143 100644
--- a/ko-kr/vim-kr.html.markdown
+++ b/ko-kr/vim-kr.html.markdown
@@ -5,12 +5,13 @@ 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은 속도와 생산성을 위해
+(Vi IMproved)은 유닉스에서 인기 있는 vi 에디터의 클론입니다. Vim은 속도와 생산성을 위해
설계된 텍스트 에디터로, 대부분의 유닉스 기반 시스템에 내장되어 있습니다. 다양한 단축 키를 통해
파일 안에서 빠르게 이동하고 편집할 수 있습니다.
@@ -18,19 +19,21 @@ lang: ko-kr
```
vim <filename> # vim으로 <filename> 열기
+ :help <topic> # (존재하는 경우에) <topic>에 대한, 내장된 도움말 문서 열기
:q # vim 종료
:w # 현재 파일 저장
:wq # 파일 저장 후 종료
+ ZZ # 파일 저장 후 종료
:q! # 저장하지 않고 종료
# ! *강제로* :q를 실행하여, 저장 없이 종료
- :x # 파일 저장 후 종료 (짧은 :wq)
+ :x # 파일 저장 후 종료 (:wq의 축약)
u # 동작 취소
CTRL+R # 되돌리기
h # 한 글자 왼쪽으로 이동
- j # 아래로 한 줄 이동
- k # 위로 한 줄 이동
+ j # 한 줄 아래로 이동
+ k # 한 줄 위로 이동
l # 한 글자 오른쪽으로 이동
# 줄 안에서의 이동
@@ -38,6 +41,11 @@ lang: ko-kr
0 # 줄 시작으로 이동
$ # 줄 끝으로 이동
^ # 줄의 공백이 아닌 첫 문자로 이동
+
+ Ctrl+B # 한 화면 뒤로 이동
+ Ctrl+F # 한 화면 앞으로 이동
+ Ctrl+D # 반 화면 앞으로 이동
+ Ctrl+U # 반 화면 뒤로 이동
# 텍스트 검색
@@ -48,6 +56,8 @@ lang: ko-kr
:%s/foo/bar/g # 파일 모든 줄에 있는 'foo'를 'bar'로 치환
:s/foo/bar/g # 현재 줄에 있는 'foo'를 'bar'로 치환
+ :%s/foo/bar/gc # 사용자에게 확인을 요구하는, 모든 줄에 있는 'foo'를 'bar'로 치환
+ :%s/\n/\r/g # 한 종류의 개행 문자에서 다른 종류의 것으로 치환 (\n에서 \r로)
# 문자로 이동
@@ -74,14 +84,22 @@ lang: ko-kr
L # 화면 바닥으로 이동
```
+## 도움말 문서
+
+Vim은 `:help <topic>` 명령을 통해 접근할 수 있는 도움말 문서를 내장하고 있습니다.
+예를 들어, `:help navigation` 은 당신의 작업 공간을 탐색하는 방법에 대한 문서를 표시합니다!
+
+`:help`는 옵션 없이도 사용할 수 있습니다. 이는 기본 도움말 대화 상자를 표시합니다.
+이 대화 상자는 Vim을 시작하는 것이 보다 용이하도록 도와줍니다.
+
## 모드
Vim은 **모드**의 개념에 기초를 두고 있습니다.
-명령어 모드 - vim을 시작하면 처음에 이 모드입니다. 이동과 명령어 입력에 사용합니다.
-삽입 모드 - 파일을 수정합니다.
-비주얼 모드 - 텍스트를 하이라이트하고 그 텍스트에 대한 작업을 합니다.
-실행 모드 - ':' 이후 명령어를 입력합니다.
+- 명령어 모드 - vim은 이 모드로 시작됩니다. 이동과 명령어 입력에 사용합니다.
+- 삽입 모드 - 파일을 수정합니다.
+- 비주얼 모드 - 텍스트를 하이라이트하고 그 텍스트에 대한 작업을 합니다.
+- 실행 모드 - ':' 이후 명령어를 입력합니다.
```
i # 커서 위치 앞에서 삽입 모드로 변경
@@ -97,11 +115,11 @@ Vim은 **모드**의 개념에 기초를 두고 있습니다.
d # 선택한 객체 삭제
dd # 현재 줄 삭제
p # 커서 위치 뒤에 복사한 텍스트 붙여넣기
- P # 커서 위치 뒤에 복사한 텍스트 붙여넣기
+ P # 커서 위치 앞에 복사한 텍스트 붙여넣기
x # 현재 커서 위치의 문자 삭제
```
-## vim의 문법
+## vim의 '문법'
Vim의 명령어는 '서술어-수식어-목적어'로 생각할 수 있습니다.
@@ -134,7 +152,7 @@ Vim의 명령어는 '서술어-수식어-목적어'로 생각할 수 있습니
w # 단어를
s # 문장을
p # 문단을
- b # 블락을
+ b # 블록을
# 예시 '문장' (명령어)
@@ -157,6 +175,22 @@ Vim의 명령어는 '서술어-수식어-목적어'로 생각할 수 있습니
ddp # 이어지는 줄과 위치 맞바꾸기 (dd 후 p)
. # 이전 동작 반복
:w !sudo tee % # 현재 파일을 루트 권한으로 저장
+ :set syntax=c # 문법 강조를 'C'의 것으로 설정
+ :sort # 모든 줄을 정렬
+ :sort! # 모든 줄을 역순으로 정렬
+ :sort u # 모든 줄을 정렬하고, 중복되는 것을 삭제
+ ~ # 선택된 텍스트의 대/소문자 토글
+ u # 선택된 텍스트를 소문자로 바꾸기
+ U # 선택된 텍스트를 대문자로 바꾸기
+
+ # 텍스트 폴딩
+ zf # 선택된 텍스트 위치에서 폴딩 만들기
+ zo # 현재 폴딩 펴기
+ zc # 현재 폴딩 접기
+ zR # 모든 폴딩 펴기
+ zM # 모든 폴딩 접기
+ zi # 폴딩 접기/펴기 토글
+ zd # 접은 폴딩 삭제
```
## 매크로
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/latex.html.markdown b/latex.html.markdown
index c980f5e5..e8bc6064 100644
--- a/latex.html.markdown
+++ b/latex.html.markdown
@@ -141,7 +141,7 @@ 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.
+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)$
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
index cc95f5fb..86603d94 100644
--- a/ldpl.html.markdown
+++ b/ldpl.html.markdown
@@ -165,19 +165,6 @@ display myNumber crlf
exit
```
-## Topics Not Covered
-
- * [Command line arguments](https://docs.ldpl-lang.org/variables-in-ldpl/command-line-arguments)
- * [Error variables](https://docs.ldpl-lang.org/variables-in-ldpl/errorcode-and-errortext)
- * [Import other files](https://docs.ldpl-lang.org/structure-of-ldpl-source-code/importing-other-sources)
- * [Identifier naming schemes](https://docs.ldpl-lang.org/naming-rules)
- * [Text Statements](https://docs.ldpl-lang.org/text-statements/join-and-in)
- * [List Statements](https://docs.ldpl-lang.org/list-statements/push-to)
- * [Map Statements](https://docs.ldpl-lang.org/vector-statements/clear)
- * [File loading / writing](https://docs.ldpl-lang.org/i-o-statements/load-file-in)
- * [Executing commands](https://docs.ldpl-lang.org/i-o-statements/execute)
- * [Extending LDPL with C++](https://docs.ldpl-lang.org/extensions/c++-extensions)
-
## Further Reading
* [LDPL Docs](https://docs.ldpl-lang.org)
diff --git a/linker.html.markdown b/linker.html.markdown
index ebe6233d..42839e05 100644
--- a/linker.html.markdown
+++ b/linker.html.markdown
@@ -5,5 +5,5 @@ contributors:
- ["Alexander Kovalchuk", "https://github.com/Zamuhrishka"]
---
-This article is available in [Russian](http://localhost:4567/docs/ru-ru/linker-ru/).
+This article is available in [Russian](https://learnxinyminutes.com/docs/ru-ru/linker-ru/).
diff --git a/lua.html.markdown b/lua.html.markdown
index 0a7c4f00..53e396be 100644
--- a/lua.html.markdown
+++ b/lua.html.markdown
@@ -116,7 +116,7 @@ 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:
diff --git a/matlab.html.markdown b/matlab.html.markdown
index 5790bcc6..4ca31857 100644
--- a/matlab.html.markdown
+++ b/matlab.html.markdown
@@ -234,7 +234,7 @@ A' % Concise version of complex transpose
% 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.
diff --git a/mips.html.markdown b/mips.html.markdown
index 4134d3fa..33d4f87c 100644
--- a/mips.html.markdown
+++ b/mips.html.markdown
@@ -20,12 +20,12 @@ gateways and routers.
# 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
+ # 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)
+ # (32-bit value)
arr1: .word 1, 2, 3, 4, 5 # Array of words
arr2: .byte 'a', 'b' # Array of chars (1 byte each)
@@ -39,28 +39,30 @@ gateways and routers.
_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)
+ .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
+.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 firsts
+ _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 (indicating
- # type of functionality)
- syscall # Perform the specified syscall with
- # the given argument ($a0)
+ 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
@@ -79,22 +81,24 @@ gateways and routers.
# Types of load/store instructions
la $t0, label # Copy the address of a value in
- # memory specified by the label into
- # register $t0
+ # 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
+ # 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, 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
+ # specified in $s0 and offset of
+ # 8 bytes
# Same idea using 'sb' and 'sh' for bytes and halfwords. 'sa' does not exist
### Math ###
@@ -108,20 +112,22 @@ gateways and routers.
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'
+ 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
+ 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)
+ # 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
@@ -139,14 +145,15 @@ gateways and routers.
# 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 backwards, as seen
+ # 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
+ 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
@@ -155,8 +162,9 @@ gateways and routers.
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 reuslt in $s0 (1 for true)
+ 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)
@@ -183,14 +191,14 @@ gateways and routers.
# 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)
+ 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
+ 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:
@@ -201,12 +209,14 @@ gateways and routers.
## LOOPS ##
_loops:
# The basic structure of loops is having an exit condition and a jump
- instruction to continue its execution
+ # instruction to continue its execution
li $t0, 0
while:
- bgt $t0, 10, end_while # While $t0 is less than 10, keep iterating
+ 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
+ j while # Jump back to the beginning of
+ # the loop
end_while:
# 2D Matrix Traversal
@@ -246,7 +256,8 @@ gateways and routers.
# 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
+ # the previous PC in $ra since jal will automatically overwrite
+ # on each call
li $a0, 3
jal fact
@@ -289,12 +300,12 @@ gateways and routers.
## MACROS ##
_macros:
- # Macros are extremly useful for substituting repeated code blocks with a
+ # 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 new lines (since these can be very repetitive)
+ # Macro for printing newlines (since these can be very repetitive)
.macro println()
la $a0, newline # New line string stored here
li $v0, 4
@@ -338,7 +349,7 @@ gateways and routers.
buffer: .space 128 # Allocates a block in memory, does
# not automatically clear
# These blocks of memory are aligned
- # next each other
+ # next to each other
.text
la $s0, list # Load address of list
diff --git a/moonscript.html.markdown b/moonscript.html.markdown
index 941578e7..193d7f97 100644
--- a/moonscript.html.markdown
+++ b/moonscript.html.markdown
@@ -192,7 +192,7 @@ 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 i > 1 and i < 3]
+slice = [item for item in *items when item > 1 and item < 3]
-- `for` clauses inside of list comprehensions can be chained.
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 1e17d8f0..9730e579 100644
--- a/nim.html.markdown
+++ b/nim.html.markdown
@@ -28,7 +28,7 @@ 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
diff --git a/nix.html.markdown b/nix.html.markdown
index 5941f0e6..dde5dbec 100644
--- a/nix.html.markdown
+++ b/nix.html.markdown
@@ -279,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".
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/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/opencv.html.markdown b/opencv.html.markdown
index f8763b35..d1f7ec51 100644
--- a/opencv.html.markdown
+++ b/opencv.html.markdown
@@ -14,9 +14,9 @@ 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]()
-* Mac Installation Instructions (High Sierra): [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]()
+* 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
@@ -133,12 +133,12 @@ cv2.destroyAllWindows()
### Further Reading:
-* Download Cascade from [https://github.com/opencv/opencv/blob/master/data/haarcascades]()
-* OpenCV drawing Functions [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]()
-* Additional resources may be found at [https://en.wikipedia.org/wiki/OpenCV]()
+* 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://realpython.com/python-opencv-color-spaces]()
- * [https://pyimagesearch.com]()
- * [https://www.learnopencv.com]()
+ * [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/p5.html.markdown b/p5.html.markdown
index be22d3e5..f6084b98 100644
--- a/p5.html.markdown
+++ b/p5.html.markdown
@@ -7,7 +7,7 @@ contributors:
filename: p5.js
---
-p5.js is a JavaScript library that starts with the original goal of [Processing](http://processing.org"), to make coding accessible for artists, designers, educators, and beginners, and reinterprets this for today's web.
+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
diff --git a/pascal.html.markdown b/pascal.html.markdown
index 9fb51c3b..a505a38f 100644
--- a/pascal.html.markdown
+++ b/pascal.html.markdown
@@ -15,7 +15,7 @@ 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
-//Anathomy of a Pascal Program
+//Anatomy of a Pascal Program
//this is a comment
{
this is a
diff --git a/perl.html.markdown b/perl.html.markdown
index 08001ab0..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.
diff --git a/php.html.markdown b/php.html.markdown
index 40c9dd01..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
@@ -289,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');
diff --git a/pl-pl/bf-pl.html.markdown b/pl-pl/bf-pl.html.markdown
index 54772961..09c85362 100644
--- a/pl-pl/bf-pl.html.markdown
+++ b/pl-pl/bf-pl.html.markdown
@@ -7,7 +7,7 @@ contributors:
- ["Mathias Bynens", "http://mathiasbynens.be/"]
translators:
- ["Jakub Młokosiewicz", "https://github.com/hckr"]
- - ["Mateusz Burniak", "https://gitbub.com/matbur"]
+ - ["Mateusz Burniak", "https://github.com/matbur"]
lang: pl-pl
---
diff --git a/pl-pl/perl-pl.html.markdown b/pl-pl/perl-pl.html.markdown
index 3e27cc4f..43d68b05 100644
--- a/pl-pl/perl-pl.html.markdown
+++ b/pl-pl/perl-pl.html.markdown
@@ -12,10 +12,10 @@ 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 222f753f..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"]
diff --git a/powershell.html.markdown b/powershell.html.markdown
index db29bf96..9087dad8 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,105 +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
+#>
-```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
+####################################################
+## 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
-```powershell
-# 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
-$anEmptyList = @()
-$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
@@ -122,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
<#
@@ -220,112 +455,352 @@ 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) {
+[System.Collections.ArrayList]$firstSectionArray = @()
+[System.Collections.ArrayList]$secondSectionArray = @()
+[System.Collections.Stack]$stack = @()
+ for ($index = 0; $index -lt $targetArray.Count; $index++) {
+ if ($index -lt $start) {
+ $firstSectionArray.Add($targetArray[$index]) > $null
+ }
+ elseif ($index -ge $start -and $index -le $end) {
+ $stack.Push($targetArray[$index])
+ }
+ else {
+ $secondSectionArray.Add($targetArray[$index]) > $null
+ }
+ }
+ $finalArray = $firstSectionArray + $stack.ToArray() + $secondSectionArray
+ Write-Output $finalArray
+}
+
+Format-Range 2 6 # => '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
-Configuring your shell
+Get-Help ps | less # alias: help
+ps | Get-Member # alias: gm
-```powershell
-# $Profile is the full path for your `Microsoft.PowerShell_profile.ps1`
-# All code there will be executed when the PS session starts
-if (-not (Test-Path $Profile)) {
- New-Item -Type file -Path $Profile -Force
- notepad $Profile
+Show-Command Get-WinEvent # Display GUI to fill in the parameters
+
+Update-Help # Run as admin
+```
+
+If you are uncertain about your environment:
+
+```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
+```
+
+```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
index e437ee95..777c6981 100644
--- a/processing.html.markdown
+++ b/processing.html.markdown
@@ -140,7 +140,7 @@ SomeRandomClass myObjectInstantiated = new SomeRandomClass();
// Arithmetic
1 + 1 // 2
-2 - 1 // 0
+2 - 1 // 1
2 * 3 // 6
3 / 2 // 1
3.0 / 2 // 1.5
@@ -150,7 +150,7 @@ SomeRandomClass myObjectInstantiated = new SomeRandomClass();
// operations.
float f = sq(3); // f = 9.0
float p = pow(3, 3); // p = 27.0
-int a = abs(-13) // a = 13
+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
@@ -191,6 +191,8 @@ 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:
@@ -209,7 +211,7 @@ switch(value) {
// Iterative statements
// For Statements - Again, the same syntax as in Java
-for(int i = 0; i < 5; i ++){
+for(int i = 0; i < 5; i++){
print(i); // prints from 0 to 4
}
@@ -354,14 +356,14 @@ 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(color); // By now, the background colour should be white.
+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, 255, 200); // stroke colour set to yellow with transparency
+stroke(255, 255, 0, 200); // stroke colour set to yellow with transparency
// set to a lower value.
// Images
diff --git a/pt-br/c-pt.html.markdown b/pt-br/c-pt.html.markdown
index e1c27958..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
---
@@ -641,7 +642,7 @@ typedef void (*minha_função_type)(char *);
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).
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 409394f2..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,369 +19,551 @@ 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
-; Use . para chamar métodos. Ou, use o atalho ".method"
-(. (Date.) getTime) ; <a timestamp>
-(.getTime (Date.)) ; exatamente a mesma coisa.
+; Para chamar métodos estáticos dentro de classes Java, use /
+(System/currentTimeMillis) ; => retorna um timestamp
-; Use / para chamar métodos estáticos
-(System/currentTimeMillis) ; <a timestamp> (o módulo System está sempre presente)
+; Note que não é preciso importar o módulo System, pois ele 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.
+
+; 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 {}))
+
+; Para acessar o valor de um atom, você pode usar a função deref ou o operador @:
+@atom-mapa ; => {}
+(deref atom-mapa) ; => {}
-; O atom é o mais simples. Passe pra ele um valor inicial
-(def my-atom (atom {}))
+; 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)
-; Atualize o atom com um swap!.
-; swap! pega uma função e 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)
+; Observe que essas chamadas alteraram de fato o valor de atom-mapa. Seu novo valor é:
+@atom-mapa ; => {:a 1 :b 2}
-; Use '@' para desreferenciar um atom e acessar seu valor
-my-atom ;=> Atom<#...> (Retorna o objeto do Atom)
-@my-atom ; => {:a 1 :b 2}
+; Isso é diferente de fazer:
+(def atom-mapa-2 (atom {}))
+(def atom-mapa-3 (assoc @atom-mapa-2 :a 1))
-; Abaixo um contador simples usando um atom
-(def counter (atom 0))
-(defn inc-counter []
- (swap! counter inc))
+; 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}
-(inc-counter)
-(inc-counter)
-(inc-counter)
-(inc-counter)
-(inc-counter)
+(class atom-mapa-2) ; => clojure.lang.Atom
+(class atom-mapa-3) ; => clojure.lang.PersistentArrayMap
-@counter ; => 5
+; 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.
-; Outras construção STM são refs e agents.
+; 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:
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/haskell-pt.html.markdown b/pt-br/haskell-pt.html.markdown
index 181aa471..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 ...
diff --git a/pt-br/javascript-pt.html.markdown b/pt-br/javascript-pt.html.markdown
index f12d275b..e38804f3 100644
--- a/pt-br/javascript-pt.html.markdown
+++ b/pt-br/javascript-pt.html.markdown
@@ -2,7 +2,7 @@
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"]
@@ -20,8 +20,8 @@ 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,
diff --git a/pt-br/markdown-pt.html.markdown b/pt-br/markdown-pt.html.markdown
index 1a26e406..dc50cac1 100644
--- a/pt-br/markdown-pt.html.markdown
+++ b/pt-br/markdown-pt.html.markdown
@@ -4,7 +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
---
@@ -12,9 +14,12 @@ 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)
+## 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
@@ -23,29 +28,36 @@ de remarcação. No entanto, se você criar um elemento HTML em seu arquivo Mark
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ífico para um determinado interpretador -->
+Este guia vai tentar esclarecer quando as características são universais, ou quando eles são específicos para um determinado interpretador -->
+
+
+## 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 cerquilhas (#) -->
# 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á._
@@ -55,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á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
@@ -107,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. Item três
+```
+
+<!-- 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 -->
-<!-- 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 -->
+```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
+```
+
+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 -->
+## 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 ` -->
-
-John não sabia nem o que o função 'goto()' fazia!
+Código embutido pode ser criada usando o caractere de crase `` ` ``
-<!-- 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/pascal-pt.html.markdown b/pt-br/pascal-pt.html.markdown
index 3a37271a..72302695 100644
--- a/pt-br/pascal-pt.html.markdown
+++ b/pt-br/pascal-pt.html.markdown
@@ -4,6 +4,7 @@ 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
@@ -157,7 +158,7 @@ BEGIN
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'; //concatenção de strings
+ 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) }
diff --git a/pt-br/perl-pt.html.markdown b/pt-br/perl-pt.html.markdown
index 217861f9..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.
diff --git a/pt-br/python-pt.html.markdown b/pt-br/python-pt.html.markdown
index 82b70117..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.0
+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 bc5f801c..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"]
- - ["Monique Baptista", "https://github.com/bfmonique"]
-lang: pt-br
-filename: learnpython3-pt.py
----
-
-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.
-
-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].
-
-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 são 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ênteses
-(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
-
-# '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
-
-# 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 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
-
-# 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.0
-
-# 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/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/vim-pt.html.markdown b/pt-br/vim-pt.html.markdown
index d7617bbe..cc304381 100644
--- a/pt-br/vim-pt.html.markdown
+++ b/pt-br/vim-pt.html.markdown
@@ -5,6 +5,7 @@ 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
---
@@ -24,6 +25,7 @@ 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 # Salva o arquivo e fecha o vim (atalho para :wq)
@@ -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/whip-pt.html.markdown b/pt-br/whip-pt.html.markdown
index 7bdeec25..b11faf28 100644
--- a/pt-br/whip-pt.html.markdown
+++ b/pt-br/whip-pt.html.markdown
@@ -71,7 +71,7 @@ false
(= 1 1) ; => true
(equal 2 1) ; => false
-; Por exemplo, inigualdade pode ser verificada combinando as funções
+; Por exemplo, desigualdade pode ser verificada combinando as funções
;`not` e `equal`.
(! (= 2 1)) ; => true
diff --git a/pt-br/yaml-pt.html.markdown b/pt-br/yaml-pt.html.markdown
index 07903325..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
diff --git a/python.html.markdown b/python.html.markdown
index 0cc33a80..27b2b22a 100644
--- a/python.html.markdown
+++ b/python.html.markdown
@@ -1,32 +1,22 @@
---
-language: python
+language: Python
contributors:
- - ["Louie Dinh", "http://ldinh.ca"]
- - ["Amin Bandali", "https://aminb.org"]
+ - ["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"]
- - ["asyne", "https://github.com/justblah"]
- - ["habi", "http://github.com/habi"]
- ["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
@@ -34,67 +24,72 @@ Python 3 tutorial.
""" Multiline strings can be written
using three "s, and are often used
- as comments
+ as documentation.
"""
####################################################
-# 1. Primitive Datatypes and Operators
+## 1. Primitive Datatypes and Operators
####################################################
# You have numbers
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
-
-# Division is a bit tricky. It is integer division and floors the results
-# automatically.
-5 / 2 # => 2
+35 / 5 # => 7.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
+# 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
-# 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
-# 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 values are primitives (Note: the capitalization)
+True # => True
+False # => 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
+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
+# True and False are actually 1 and 0 but with different keywords
+True + True # => 2
+True * 8 # => 8
+False - 5 # => -5
-# negate with not
-not True # => False
-not False # => True
+# 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
@@ -110,93 +105,88 @@ 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! But try not to do this.
"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)
+# 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 statement inside the braces and it will be output in the string.
+f"{name} is {len(name)} characters long." # => "Reiko is 5 characters long."
-# 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
+# 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
+## 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()
-
-# No need to declare variables before assigning to them.
-some_var = 5 # Convention is to use lower_case_with_underscores
+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()
+
+# 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 = []
@@ -204,21 +194,17 @@ li = []
other_li = [4, 5, 6]
# Add stuff to the end of a list with append
-li.append(1) # li is now [1]
-li.append(2) # li is now [1, 2]
-li.append(4) # li is now [1, 2, 4]
-li.append(3) # li is now [1, 2, 4, 3]
+li.append(1) # li is now [1]
+li.append(2) # li is now [1, 2]
+li.append(4) # li is now [1, 2, 4]
+li.append(3) # li is now [1, 2, 4, 3]
# Remove from the end with pop
-li.pop() # => 3 and li is now [1, 2, 4]
+li.pop() # => 3 and li is now [1, 2, 4]
# Let's put it back
-li.append(3) # li is now [1, 2, 4, 3] again.
+li.append(3) # li is now [1, 2, 4, 3] again.
# Access a list like you would any array
-li[0] # => 1
-# 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
@@ -226,39 +212,39 @@ 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]
+# 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]
-# 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) # 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
@@ -266,82 +252,109 @@ li.index(7) # Raises a ValueError as 7 is not in the list
# Examine the length with "len()"
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
+# 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
+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
+# 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
-# 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
-# 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_dict.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
+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
+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("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])
+# 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}
+
+
-# 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
+# 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}
@@ -357,37 +370,37 @@ filled_set | other_set # => {1, 2, 3, 4, 5, 6}
{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5}
# Check if set on the left is a superset of set on the right
-{1, 2} >= {1, 2, 3} # => False
+{1, 2} >= {1, 2, 3} # => False
# Check if set on the left is a subset of set on the right
-{1, 2} <= {1, 2, 3} # => True
+{1, 2} <= {1, 2, 3} # => True
# Check for existence in a set with in
-2 in filled_set # => True
+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
+# 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."
-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 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
@@ -397,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
@@ -410,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
@@ -422,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.
@@ -434,72 +469,121 @@ 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
####################################################
-# 4. Functions
+## 4. Functions
####################################################
# Use "def" to create new functions
def add(x, y):
- print "x is {0} and y is {1}".format(x, y)
+ 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 args, which will be interpreted as a tuple by using *
+# 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 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"}
# 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)
@@ -507,38 +591,36 @@ 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 all_the_args(1, 2, 3, 4)
-all_the_args(**kwargs) # equivalent to all_the_args(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)
@@ -548,55 +630,98 @@ set_global_x(6)
def create_adder(x):
def adder(y):
return x + y
-
return adder
-
add_10 = create_adder(10)
-add_10(3) # => 13
+add_10(3) # => 13
# There are also anonymous functions
-(lambda x: x > 2)(3) # => True
+(lambda x: 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]
+# 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'} # => {'a', 'b', 'c'}
-{x: x ** 2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
+{x for x in 'abcddeef' if x 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
@@ -610,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
@@ -627,160 +752,254 @@ 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*"
+
+ # Cannot call static method with instance of object
+ # because i.grunt() will automatically put "self" (the object i) as an argument
+ print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
+
+ # 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
-j = Human("Joel")
-print j.say("hello") # prints out "Joel: hello"
-# Call our class method
-i.get_species() # => "H. sapiens"
+####################################################
+## 6.1 Inheritance
+####################################################
-# Change the shared attribute
-Human.species = "H. neanderthalensis"
-i.get_species() # => "H. neanderthalensis"
-j.get_species() # => "H. neanderthalensis"
+# Inheritance allows new child classes to be defined that inherit methods and
+# variables from their parent class.
-# Call the static method
-Human.grunt() # => "*grunt*"
+# 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.
-# Update the property
-i.age = 42
+# To take advantage of modularization by file you could place the classes above in their own files,
+# say, human.py
-# Get the property
-i.age # => 42
+# To import functions from other files use the following format
+# from "filename-without-extension" import "function-or-class"
-# Delete the property
-del i.age
-i.age # => raises an AttributeError
+from human import Human
-####################################################
-# 6. Modules
-####################################################
-# You can import modules
-import math
+# Specify the parent class(es) as parameters to the class definition
+class Superhero(Human):
-print math.sqrt(16) # => 4.0
+ # 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
-# You can get specific functions from a module
-from math import ceil, floor
+ # Child classes can override their parents' attributes
+ species = 'Superhuman'
-print ceil(3.7) # => 4.0
-print floor(3.7) # => 3.0
+ # 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"]):
-# You can import all functions from a module.
-# Warning: this is not recommended
-from math import *
+ # add additional class attributes:
+ self.fictional = True
+ self.movie = movie
+ # be aware of mutable default values, since defaults are shared
+ self.superpowers = superpowers
-# You can shorten module names
-import math as m
+ # 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)
-math.sqrt(16) == m.sqrt(16) # => True
-# you can also test that the functions are equivalent
-from math import sqrt
+ # override the sing method
+ def sing(self):
+ return 'Dun, dun, DUN!'
-math.sqrt == m.sqrt == sqrt # => True
+ # add an additional instance method
+ def boast(self):
+ for power in self.superpowers:
+ print("I wield the power of {pow}!".format(pow=power))
-# 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
+if __name__ == '__main__':
+ sup = Superhero(name="Tick")
-dir(math)
+ # Instance type checks
+ if isinstance(sup, Human):
+ print('I am human')
+ if type(sup) is Superhero:
+ print('I am a superhero')
+ # 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'>)
-# 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.
+ # 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))
####################################################
-# 7. Advanced
+## 6.2 Multiple Inheritance
####################################################
-# Generators
-# A generator "generates" values as they are requested instead of storing
-# everything up front
+# Another class definition
+# bat.py
+class Bat:
-# 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
+ species = 'Baty'
+ def __init__(self, can_fly=True):
+ self.fly = can_fly
-# 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
+ # 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)
+
+
+# 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):
-# We could instead use a generator to "generate" the doubled value as the item
-# is being requested
-def double_numbers_generator(iterable):
+ 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
+
+
+
+####################################################
+## 7. Advanced
+####################################################
+
+# Generators help you make lazy code.
+def double_numbers(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])
+values = (-x for x in [1,2,3,4,5])
for x in values:
print(x) # prints -1 -2 -3 -4 -5 to console/terminal
# You can also cast a generator comprehension directly to a list.
-values = (-x for x in [1, 2, 3, 4, 5])
+values = (-x for x in [1,2,3,4,5])
gen_to_list = list(values)
print(gen_to_list) # => [-1, -2, -3, -4, -5]
+
# Decorators
-# 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
+# In this example `beg` wraps `say`. If say_please is True then it
+# will change the returned message.
from functools import wraps
@@ -801,8 +1020,8 @@ def say(say_please=False):
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?
@@ -810,18 +1029,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/)
+* [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/)
-
-### 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](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/python3.html.markdown b/python3.html.markdown
deleted file mode 100644
index d09c2819..00000000
--- a/python3.html.markdown
+++ /dev/null
@@ -1,1054 +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"]
- - ["Rommel Martinez", "https://ebzzry.io"]
- - ["Roberto Fernandez Diaz", "https://github.com/robertofd1995"]
- - ["caminsha", "https://github.com/caminsha"]
-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 documentation.
-"""
-
-####################################################
-## 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
-
-# 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
-
-# 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**3 # => 8
-
-# 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
-
-# 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
-
-# Inequality is !=
-1 != 1 # => False
-2 != 1 # => True
-
-# More comparisons
-1 < 10 # => True
-1 > 10 # => False
-2 <= 2 # => True
-2 >= 2 # => True
-
-# 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! But try not to do this.
-"Hello " + "world!" # => "Hello world!"
-# 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'
-
-# 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"
-
-# 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 statement 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. This checks for equality of object identity.
-"etc" is None # => 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 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 = input("Enter some data: ") # Returns the data as a string
-# Note: In earlier versions of Python, input() method was named as raw_input()
-
-# 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_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.
-# The start index is included, the end index is not
-# (It's a closed/open range for you mathy types.)
-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]
-
-# 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 # 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
-
-
-# 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
-
-# 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 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
-
-# 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}
-
-# 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}
-
-# 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!
-# 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.")
-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)
-
-"""
-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
-"""
-list = ["dog", "cat", "mouse"]
-for i, value in enumerate(list):
- print(i, value)
-
-"""
-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)
-
-# 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
-
-
-####################################################
-## 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 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)
-
-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
-# 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. 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
-
- # 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.
- # There's no need to write trivial getters and setters in Python, though.
- @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*"
-
- # Cannot call static method with instance of object
- # because i.grunt() will automatically put "self" (the object i) as an argument
- print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
-
- # 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
-
- # 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)
-
- # override the sing method
- def sing(self):
- return 'Dun, dun, DUN!'
-
- # add an additional instance method
- 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")
-
- # Instance type checks
- if isinstance(sup, Human):
- print('I am human')
- if type(sup) is Superhero:
- print('I am a superhero')
-
- # 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.2 Multiple Inheritance
-####################################################
-
-# Another class definition
-# 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)
-
-
-# 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
-
-
-
-####################################################
-## 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/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/perl6-pod.html.markdown b/raku-pod.html.markdown
index 80a501b8..7e9b6fc3 100644
--- a/perl6-pod.html.markdown
+++ b/raku-pod.html.markdown
@@ -5,9 +5,9 @@ contributors:
filename: learnpod.pod6
---
-Pod is an easy-to-use and purely descriptive mark-up language,
+Pod is an easy-to-use and purely descriptive mark-up language,
with no presentational components. Besides its use for documenting
-Raku Perl 6 programs and modules, Pod can be utilized to write language
+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
@@ -49,12 +49,12 @@ generate documentation.
```
=begin pod
-A very simple Raku Perl 6 Pod document. All the other directives go here!
+A very simple Raku Pod document. All the other directives go here!
=end pod
```
-Pod documents usually coexist with Raku Perl 6 code. If by themselves,
+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.
@@ -65,7 +65,7 @@ directives.
Text can be easily styled as bold, italic, underlined or verbatim (for code
formatting) using the following formatting codes: `B<>`, `I<>`, `U<>`
-and `C<>`.
+and `C<>`.
```
B<This text is in Bold.>
@@ -83,7 +83,7 @@ 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
Headings are created by using the `=headN` directive where `N` is the
heading level.
@@ -145,7 +145,7 @@ Unordered lists can be created using the `=item` directive.
```
Sublists are achieved with items at each level specified using the `=item1`,
-`=item2`, `=item3`, `...`, `=itemN` etc. directives. The `=item` directive
+`=item2`, `=item3`, `...`, `=itemN` etc. directives. The `=item` directive
defaults to `=item1`.
```
@@ -157,7 +157,7 @@ defaults to `=item1`.
=item1 Item four
```
-Definition lists that define terms or commands use the `=defn` directive.
+Definition lists that define terms or commands use the `=defn` directive.
This is equivalent to the `<dl>` element in HTML.
```
@@ -186,13 +186,13 @@ As shown in the [Basic Text Formatting](#basic-text-formatting) section,
inline code can be created using the `C<>` code.
```
-In Raku Perl 6, there are several functions/methods to output text. Some of them
+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 Raku Perl 6 compiler, everything
+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.
@@ -206,21 +206,21 @@ order to prevent Pod blocks from being rendered by any renderer, use the
To create inline comments, use the `Z<>` code.
```
-Pod is awesome Z<Of course it is!>. And Raku Perl 6 too!
+Pod is awesome Z<Of course it is!>. And Raku too!
```
-Given that the Perl interpreter never executes embedded Pod blocks,
+Given that the Raku interpreter never executes embedded Pod blocks,
comment blocks can also be used as an alternative form of nestable block
-comments in Raku Perl 6.
+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.
+being optional.
```
-Raku Perl 6 homepage is L<https://perl6.org>.
+Raku homepage is L<https://raku.org>.
L<Click me!|http://link.org/>.
```
@@ -242,7 +242,7 @@ 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.perl6.org/language/tables>.
+<https://docs.raku.org/language/tables>.
```
=begin table
@@ -287,7 +287,7 @@ For example:
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
+The general syntax is
```
=begin BLOCK_TYPE
@@ -304,7 +304,7 @@ Top level heading
```
This type of blocks is useful for creating headings, list items, code blocks,
-etc. with multiple paragraphs. For example,
+etc. with multiple paragraphs. For example,
* a multiline item of a list
@@ -345,7 +345,7 @@ say pow(6); #=> 36
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
+`typename` of the block. The general syntax is
```
=for BLOCK_TYPE
@@ -360,10 +360,10 @@ 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
+contents right after the `typename` of the block. Thus the following
are more general syntaxes for these blocks:
* Delimited blocks
@@ -384,16 +384,16 @@ BLOCK DATA
```
The configuration information is provided in a format akin to the
-["colon pair"](https://docs.perl6.org/language/glossary#index-entry-Colon_Pair)
-syntax in Raku Perl 6. The following table is a simplified version of the
-different ways in which configuration info can be supplied. Please go to
-<https://docs.perl6.org/language/pod#Configuration_information> for a more
+["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', 'Perl6') |
-| Hash | :key{$key1 => $value1, ...} | :feeds{url => 'perl6.org'} |
+| 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') |
@@ -450,7 +450,7 @@ we get the following output:
</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
+when Pod is converted to HTML, it might not be preserved when converted
to Markdown.
### Block Pre-configuration
@@ -549,48 +549,48 @@ a Pod document, enclose them in a `E<>` code.
For example:
```
-Raku Perl 6 makes considerable use of the E<171> and E<187> characters.
-Raku Perl 6 makes considerable use of the E<laquo> and E<raquo> characters.
+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 Perl 6 makes considerable use of the « and » characters.
-Raku Perl 6 makes considerable use of the « and » characters.
+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 Raku Perl 6 compiler installed. In addition, you must install
+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 Raku Perl 6,
-[look here](https://perl6.org/downloads/).
+For instructions about installing Rakudo for running raku programs,
+[look here](https://raku.org/downloads/).
Run the following command to generate a certain output:
```
-perl6 --doc=TARGET input.pod6 > output.html
+raku --doc=TARGET input.pod6 > output.html
```
with `TARGET` being `Markdown`, `HTML`, `Text`, etc. Thus to generate
Markdown from Pod, run this:
```
-perl6 --doc=Markdown input.pod6 > output.html
+raku --doc=Markdown input.pod6 > output.html
```
## Accessing Pod
-In order to access Pod documentation from within a Raku Perl 6 program,
+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,
+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 Perl 6 code and the Pod documentation
+If we place the following piece of Raku code and the Pod documentation
in the section [Semantic blocks](#semantic-blocks) in the same file:
```
@@ -615,8 +615,8 @@ AUTHOR
DESCRIPTION
```
-## Additional Information
+## Additional Information
-* <https://docs.perl6.org/language/pod> for the Pod documentation.
-* <https://docs.perl6.org/language/tables> for advices about Pod tables.
-* <https://design.perl6.org/S26.html> for the Pod specification.
+* <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
index 4f397589..16035615 100644
--- a/raku.html.markdown
+++ b/raku.html.markdown
@@ -15,7 +15,7 @@ the JVM and the [MoarVM](http://moarvm.com).
Meta-note:
-* Although the pound sign (`#`) is used for sentences and notes, Pod-styled
+* 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.
@@ -23,7 +23,7 @@ Meta-note:
* `#=>` 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.
+ from the text.
```perl6
####################################################
@@ -95,7 +95,7 @@ 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 perl5's qw, or Ruby's %w.
+# of words, delimited by space. Similar to perl's qw, or Ruby's %w.
@array = 1, 2, 4;
@@ -152,7 +152,7 @@ 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
####################################################
@@ -265,9 +265,9 @@ takes-a-bool('config', :bool); # OUTPUT: «config takes True␤»
takes-a-bool('config', :!bool); # OUTPUT: «config takes False␤»
=begin comment
-Since paranthesis 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.
+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.
@@ -276,7 +276,7 @@ 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
+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*.
@@ -284,8 +284,8 @@ else". You can have as many parameters *before* a slurpy one, but not *after*.
sub as-many($head, *@rest) {
@rest.join(' / ') ~ " !";
}
-say as-many('Happy', 'Happy', 'Birthday'); # OUTPUT: «Happy / Birthday !␤»
-say 'Happy', ['Happy', 'Birthday'], 'Day'; # OUTPUT: «Happy / Birthday / Day !␤»
+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.
@@ -298,7 +298,7 @@ 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, $('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
@@ -508,7 +508,7 @@ given "foo bar" {
# can also be a C-style `for` loop:
loop {
say "This is an infinite loop !";
- last;
+ last;
}
# In the previous example, `last` breaks out of the loop very much
# like the `break` keyword in other languages.
@@ -614,8 +614,8 @@ say Int === Int; # OUTPUT: «True␤»
# Here are some common comparison semantics:
# String or numeric equality
-say 'Foo' ~~ 'Foo'; # OUTPU: «True␤», if strings are equal.
-say 12.5 ~~ 12.50; # OUTPU: «True␤», if numbers are equal.
+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.
@@ -624,7 +624,7 @@ say $obj; # OUTPUT: «「a」␤»
say $obj.WHAT; # OUTPUT: «(Match)␤»
# Hashes
-say 'key' ~~ %hash; # OUTPUT:«True␤», if key exists in hash.
+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␤»
@@ -652,7 +652,7 @@ say 'a' le 'b'; # OUTPUT: «True␤»
# 5.2 Range constructor
#
-say 3 .. 7; # OUTPUT: «3..7␤», both included.
+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.
@@ -665,7 +665,7 @@ 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,
+# 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␤»
@@ -769,7 +769,7 @@ sub unpack_array( @array [$fst, $snd] ) {
# (^ remember the `[]` to interpolate the array)
}
unpack_array(@tail);
-# OUTPUT: «My first is 3, my second is 3! All in all, I'm 2 3.␤»
+# 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:
@@ -800,7 +800,7 @@ fst(1); # OUTPUT: «1␤»
=begin comment
You can also destructure hashes (and classes, which you'll learn about later).
-The syntax is basically the same as
+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.
@@ -842,7 +842,7 @@ 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
+# You can create a lambda by using a pointy block (`-> {}`), a
# block (`{}`) or creating a `sub` without a name.
my &lambda1 = -> $argument {
@@ -858,18 +858,18 @@ my &lambda3 = sub ($argument) {
}
=begin comment
-Both pointy blocks and blocks are pretty much the same thing, except that
+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
+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 latern on.
+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,
+# 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
@@ -1088,7 +1088,7 @@ sub call_say_dyn {
# $*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).
@@ -1162,7 +1162,7 @@ class Human {
};
# Create a new instance of Human class.
-# NOTE: Only attributes declared with the `.` twigil can be set via the
+# 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(
@@ -1317,7 +1317,7 @@ method on the `$_` variable to access the exception
open 'foo' orelse say "Something happened {.exception}";
# This also works:
-open 'foo' orelse say "Something happened $_";
+open 'foo' orelse say "Something happened $_";
# OUTPUT: «Something happened Failed to open file foo: no such file or directory␤»
=begin comment
@@ -1431,15 +1431,15 @@ 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 5).
+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.
+# as something else later.
module Hello::World { # bracketed form
- # declarations here
+ # declarations here
}
# The file-scoped form which extends until the end of the file. For
@@ -1520,7 +1520,7 @@ fixed-rand for ^10; # will print the same number 10 times
for ^5 -> $a {
sub foo {
# This will be a different value for every value of `$a`
- state $val = rand;
+ state $val = rand;
}
for ^5 -> $b {
# This will print the same value 5 times, but only 5. Next iteration
@@ -1558,9 +1558,9 @@ END { say "Runs at run time, as late as possible, only once" }
#
# 14.3 Block phasers
#
-ENTER { say "[*] Runs everytime you enter a block, repeats on loop blocks" }
+ENTER { say "[*] Runs every time you enter a block, repeats on loop blocks" }
LEAVE {
- say "Runs everytime you leave a block, even when an exception
+ say "Runs every time you leave a block, even when an exception
happened. Repeats on loop blocks."
}
@@ -1610,7 +1610,7 @@ for ^5 {
#
# 14.6 Role/class phasers
#
-COMPOSE {
+COMPOSE {
say "When a role is composed into a class. /!\ NOT YET IMPLEMENTED"
}
@@ -1619,9 +1619,9 @@ say "This code took " ~ (time - CHECK time) ~ "s to compile";
# ... or clever organization:
class DB {
- method start-transaction { say "Starting transation!" }
- method commit { say "Commiting transaction..." }
- method rollback { say "Something went wrong. Rollingback!" }
+ method start-transaction { say "Starting transaction!" }
+ method commit { say "Committing transaction..." }
+ method rollback { say "Something went wrong. Rolling back!" }
}
sub do-db-stuff {
@@ -1647,7 +1647,7 @@ braces `{` and `}`.
=end comment
#
-# 15.1 `do` - It runs a block or a statement as a term.
+# 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
@@ -1805,7 +1805,7 @@ sub postfix:<!>( Int $n ) {
}
say 5!; # OUTPUT: «120␤»
-# Postfix operators ('after') have to come *directly* after the term.
+# 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')
@@ -1898,7 +1898,7 @@ 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 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␤»
@@ -2078,19 +2078,19 @@ 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 /; # OUTPU: «True␤», they're all optional
-say so 'abc' ~~ / a b* c /; # OUTPU: «True␤»
-say so 'abbbbc' ~~ / a b* c /; # OUTPU: «True␤»
-say so 'aec' ~~ / a b* c /; # OUTPU: «False␤», "b"(s) are optional, not replaceable.
+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 /; # OUTPU: «True␤», exactly one time
-say so 'abc' ~~ / a b**1..3 c /; # OUTPU: «True␤», one to three times
-say so 'abbbc' ~~ / a b**1..3 c /; # OUTPU: «True␤»
-say so 'abbbbbbc' ~~ / a b**1..3 c /; # OUTPU: «Fals␤», too much
-say so 'abbbbbbc' ~~ / a b**3..* c /; # OUTPU: «True␤», infinite ranges are ok
+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
@@ -2150,7 +2150,7 @@ say so 'fooABCABCbar' ~~ / foo ( 'A' <[A..Z]> 'C' ) + bar /; # OUTPUT: «True␤
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」␤»,
+say $/[0]; # OUTPUT: «「ABC」 「ABC」␤»,
# The corner brackets (「..」) represent (and are) `Match` objects. In the
# previous example, we have an array of them.
@@ -2202,8 +2202,8 @@ 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 /; # OUTPU: «True␤», Either "b" or "y".
-say so 'ayc' ~~ / a [ b | y ] c /; # OUTPU: «True␤», Obviously enough...
+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
@@ -2218,7 +2218,7 @@ To decide which part is the "longest", it first splits the regex in two parts:
yet introduced), literals, characters classes and quantifiers.
* The "procedural part" includes everything else: back-references,
- code assertions, and other things that can't traditionnaly be represented
+ 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.
@@ -2268,7 +2268,7 @@ 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
@@ -2358,7 +2358,7 @@ side, once its left side changed:
# 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␤»,
+.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> {
@@ -2392,21 +2392,20 @@ 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](http://perl6advent.wordpress.com/). This
+- 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 6.c was released.
+stable and `Raku v6.c` was released.
-- Come along on `#raku` at `irc.freenode.net`. The folks here are
+- 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/nom/src/core). Rakudo is
+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/red.html.markdown b/red.html.markdown
index 74538bd7..34c4bcd9 100644
--- a/red.html.markdown
+++ b/red.html.markdown
@@ -216,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/python-ro.html.markdown b/ro-ro/pythonlegacy-ro.html.markdown
index ada0c034..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
---
diff --git a/rst.html.markdown b/rst.html.markdown
index 2423622e..bdc73c7a 100644
--- a/rst.html.markdown
+++ b/rst.html.markdown
@@ -49,9 +49,11 @@ Subtitles with dashes
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 \*.
+
Lists are similar to Markdown, but a little more involved.
-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:
+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
@@ -86,7 +88,7 @@ There are multiple ways to make links:
- 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/
```
diff --git a/ru-ru/c-ru.html.markdown b/ru-ru/c-ru.html.markdown
index 389c8bc9..ba3c19ee 100644
--- a/ru-ru/c-ru.html.markdown
+++ b/ru-ru/c-ru.html.markdown
@@ -471,7 +471,7 @@ 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).
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/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/python-ru.html.markdown b/ru-ru/python-ru.html.markdown
index 6087a686..9133549d 100644
--- a/ru-ru/python-ru.html.markdown
+++ b/ru-ru/python-ru.html.markdown
@@ -1,23 +1,23 @@
---
-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"]
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
# Однострочные комментарии начинаются с символа решётки.
@@ -37,16 +37,9 @@ filename: learnpython-ru.py
1 + 1 #=> 2
8 - 1 #=> 7
10 * 2 #=> 20
-35 / 5 #=> 7
-# А вот деление немного сложнее. В этом случае происходит деление
-# целых чисел, и результат автоматически округляется в меньшую сторону.
-5 / 2 #=> 2
-
-# Чтобы делить правильно, сначала нужно немного узнать о числах
-# с плавающей запятой.
-2.0 # Это число с плавающей запятой
-11.0 / 4.0 #=> 2.75 Вооот... Так гораздо лучше
+# Кроме деления, которое по умолчанию возвращает число с плавающей запятой
+35 / 5 # => 7.0
# Результат целочисленного деления округляется в меньшую сторону
# как для положительных, так и для отрицательных чисел.
@@ -55,6 +48,10 @@ filename: learnpython-ru.py
-5 // 3 # => -2
-5.0 // 3.0 # => -2.0
+# Когда вы используете числа с плавающей запятой,
+# результатом будет также число с плавающей запятой
+3 * 2.0 # => 6.0
+
# Остаток от деления
7 % 3 # => 1
@@ -64,6 +61,14 @@ filename: learnpython-ru.py
# Приоритет операций указывается скобками
(1 + 3) * 2 #=> 8
+# Для логических (булевых) значений существует отдельный примитивный тип
+True
+False
+
+# Для отрицания используется ключевое слово not
+not True #=> False
+not False #=> True
+
# Логические операторы
# Обратите внимание: ключевые слова «and» и «or» чувствительны к регистру букв
True and False #=> False
@@ -76,10 +81,6 @@ False or True #=> True
2 == True #=> False
1 == True #=> True
-# Для отрицания используется ключевое слово not
-not True #=> False
-not False #=> True
-
# Равенство — это ==
1 == 1 #=> True
2 == 1 #=> False
@@ -94,7 +95,7 @@ not False #=> True
2 <= 2 #=> True
2 >= 2 #=> True
-# Сравнения могут быть записаны цепочкой!
+# Сравнения могут быть записаны цепочкой:
1 < 2 < 3 #=> True
2 < 3 < 2 #=> False
@@ -102,75 +103,70 @@ not False #=> True
"Это строка."
'Это тоже строка.'
-# И строки тоже можно складывать!
+# И строки тоже могут складываться! Хотя лучше не злоупотребляйте этим.
"Привет " + "мир!" #=> "Привет мир!"
-# ... или умножать
-"Привет" * 3 # => "ПриветПриветПривет"
+# Строки можно умножать.
+"aa" * 4 #=> "aaaaaaaa"
# Со строкой можно работать, как со списком символов
"Это строка"[0] #=> 'Э'
-# Символ % используется для форматирования строк, например:
-"%s могут быть %s" % ("строки", "интерполированы")
-
-# Новый способ форматирования строк — использование метода format.
-# Это предпочитаемый способ.
+# Метод 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
-0 == False #=> True
-"" == False #=> True
+bool(0) # => False
+bool("") # => False
+bool([]) #=> False
+bool({}) #=> False
####################################################
## 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. Приятно познакомиться!")
# Объявлять переменные перед инициализацией не нужно.
-some_var = 5 # По соглашению используется нижний_регистр_с_подчёркиваниями
+# По соглашению используется нижний_регистр_с_подчёркиваниями
+some_var = 5
some_var #=> 5
# При попытке доступа к неинициализированной переменной
# выбрасывается исключение.
-# См. раздел «Поток управления» для информации об исключениях.
-some_other_var # Выбрасывает ошибку именования
-
-# if может быть использован как выражение
-"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
+# Об исключениях см. раздел «Поток управления и итерируемые объекты».
+some_unknown_var # Выбрасывает ошибку именования
# Списки хранят последовательности
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]
@@ -183,10 +179,6 @@ li.append(3) # [1, 2, 4, 3].
# Обращайтесь со списком, как с обычным массивом
li[0] #=> 1
-# Присваивайте новые значения уже инициализированным индексам с помощью =
-li[0] = 42
-li[0] # => 42
-li[0] = 1 # Обратите внимание: возвращаемся на исходное значение
# Обратимся к последнему элементу
li[-1] #=> 3
@@ -208,11 +200,11 @@ li[::-1] # => [3, 4, 2, 1]
# li[начало:конец:шаг]
# Удаляем произвольные элементы из списка оператором del
-del li[2] # li теперь [1, 2, 3]
+del li[2] # [1, 2, 3]
# Вы можете складывать, или, как ещё говорят, конкатенировать списки
-li + other_li #=> [1, 2, 3, 4, 5, 6] — Замечание: li и other_li не изменяются
# Обратите внимание: значения li и other_li при этом не изменились.
+li + other_li #=> [1, 2, 3, 4, 5, 6] — Замечание: li и other_li не изменяются
# Объединять списки можно методом extend
li.extend(other_li) # Теперь li содержит [1, 2, 3, 4, 5, 6]
@@ -242,6 +234,7 @@ d, e, f = 4, 5, 6
# Обратите внимание, как легко поменять местами значения двух переменных
e, d = d, e # теперь d == 5, а e == 4
+
# Словари содержат ассоциативные массивы
empty_dict = {}
# Вот так описывается предзаполненный словарь
@@ -251,13 +244,17 @@ filled_dict = {"one": 1, "two": 2, "three": 3}
# что индекс — у словарей он называется ключом — не обязан быть числом
filled_dict["one"] #=> 1
-# Можно получить все ключи в виде списка с помощью метода keys
-filled_dict.keys() #=> ["three", "two", "one"]
+# Все ключи в виде списка получаются с помощью метода keys().
+# Его вызов нужно обернуть в list(), так как обратно мы получаем
+# итерируемый объект, о которых поговорим позднее.
+list(filled_dict.keys()) # => ["three", "two", "one"]
# Замечание: сохранение порядка ключей в словаре не гарантируется
# Ваши результаты могут не совпадать с этими.
-# Можно получить и все значения в виде списка, используйте метод values
-filled_dict.values() #=> [3, 2, 1]
+# Все значения в виде списка можно получить с помощью values().
+# И снова нам нужно обернуть вызов в list(), чтобы превратить
+# итерируемый объект в список.
+list(filled_dict.values()) # => [3, 2, 1]
# То же самое замечание насчёт порядка ключей справедливо и здесь
# При помощи оператора in можно проверять ключи на вхождение в словарь
@@ -274,29 +271,28 @@ filled_dict.get("four") #=> None
# возвращено при отсутствии указанного ключа
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() вставляет пару ключ-значение, только если такого ключа нет
+# Метод 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 # Другой способ добавления элементов
-# Множества содержат... ну, в общем, множества
-# (которые похожи на списки, только в них не может быть дублирующихся элементов)
-empty_set = set()
-# Инициализация множества набором значений
-some_set = set([1,2,2,3,4]) # some_set теперь равно set([1, 2, 3, 4])
+# Удаляйте ключи из словаря с помощью оператора del
+del filled_dict["one"] # Удаляет ключ «one» из словаря
-# Порядок сортировки не гарантируется, хотя иногда они выглядят отсортированными
-another_set = set([4, 3, 2, 2, 1]) # another_set теперь set([1, 2, 3, 4])
-# Начиная с Python 2.7, вы можете использовать {}, чтобы объявить множество
+# Множества содержат... ну, в общем, множества
+empty_set = set()
+# Инициализация множества набором значений.
+# Да, оно выглядит примерно как словарь… ну извините, так уж вышло.
filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
+# Множеству можно назначать новую переменную
+filled_set = some_set
+
# Добавление новых элементов в множество
filled_set.add(5) # filled_set равно {1, 2, 3, 4, 5}
@@ -316,7 +312,7 @@ filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
####################################################
-## 3. Поток управления
+## 3. Поток управления и итерируемые объекты
####################################################
# Для начала заведём переменную
@@ -332,17 +328,13 @@ else: # Это тоже необязательно.
print("some_var равно 10.")
-"""
-Циклы For проходят по спискам
-
-Результат:
- собака — это млекопитающее
- кошка — это млекопитающее
- мышь — это млекопитающее
-"""
+# Циклы For проходят по спискам. Результат:
+ # собака — это млекопитающее
+ # кошка — это млекопитающее
+ # мышь — это млекопитающее
for animal in ["собака", "кошка", "мышь"]:
- # Можете использовать оператор % для интерполяции форматированных строк
- print("%s — это млекопитающее" % animal)
+ # Можете использовать format() для интерполяции форматированных строк
+ print("{} — это млекопитающее".format(animal))
"""
«range(число)» возвращает список чисел
@@ -370,8 +362,6 @@ while x < 4:
x += 1 # Краткая запись для x = x + 1
# Обрабатывайте исключения блоками try/except
-
-# Работает в Python 2.6 и выше:
try:
# Чтобы выбросить ошибку, используется raise
raise IndexError("Это ошибка индекса")
@@ -384,6 +374,37 @@ 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) #=> dict_keys(['one', 'two', 'three']). Это объект, реализующий интерфейс 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"]
####################################################
@@ -401,8 +422,7 @@ add(5, 6) #=> выводит «x равен 5, а y равен 6» и возвр
# Другой способ вызова функции — вызов с именованными аргументами
add(y=6, x=5) # Именованные аргументы можно указывать в любом порядке.
-# Вы можете определить функцию, принимающую переменное число аргументов,
-# которые будут интерпретированы как кортеж, если вы не используете *
+# Вы можете определить функцию, принимающую переменное число аргументов
def varargs(*args):
return args
@@ -410,8 +430,7 @@ varargs(1, 2, 3) #=> (1,2,3)
# А также можете определить функцию, принимающую переменное число
-# именованных аргументов, которые будут интерпретированы как словарь,
-# если вы не используете **
+# именованных аргументов
def keyword_args(**kwargs):
return kwargs
@@ -436,14 +455,6 @@ 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
@@ -502,7 +513,7 @@ class Human(object):
# Метод экземпляра. Все методы принимают self в качестве первого аргумента
def say(self, msg):
- return "%s: %s" % (self.name, msg)
+ return "{name}: {message}".format(name=self.name, message=msg)
# Метод класса разделяется между всеми экземплярами
# Они вызываются с указыванием вызывающего класса в качестве первого аргумента
@@ -555,9 +566,6 @@ 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-файлы. Вы
# можете писать свои модули и импортировать их. Название
@@ -581,15 +589,14 @@ def double_numbers(iterable):
# Он не возвращает все значения разом, а создаёт каждое из них при каждой
# итерации. Это значит, что значения больше 15 в double_numbers
# обработаны не будут.
-# Обратите внимание: xrange — это генератор, который делает то же, что и range.
+# Обратите внимание: range — это тоже генератор.
# Создание списка чисел от 1 до 900000000 требует много места и времени.
-# xrange создаёт объект генератора, а не список сразу, как это делает range.
# Если нам нужно имя переменной, совпадающее с ключевым словом Python,
# мы используем подчёркивание в конце
-xrange_ = xrange(1, 900000000)
+range_ = range(1, 900000000)
# Будет удваивать все числа, пока результат не превысит 30
-for i in double_numbers(xrange_):
+for i in double_numbers(range_):
print(i)
if i >= 30:
break
@@ -630,9 +637,10 @@ 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/)
+* [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/)
+* [Python Module of the Week](http://pymotw.com/3/)
* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182)
### Платные
diff --git a/ru-ru/python3-ru.html.markdown b/ru-ru/pythonlegacy-ru.html.markdown
index bf80fed2..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,70 +102,75 @@ False or True #=> True
"Это строка."
'Это тоже строка.'
-# И строки тоже могут складываться! Хотя лучше не злоупотребляйте этим.
+# И строки тоже можно складывать!
"Привет " + "мир!" #=> "Привет мир!"
-# Строки можно умножать.
-"aa" * 4 #=> "aaaaaaaa"
+# ... или умножать
+"Привет" * 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]
@@ -179,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
@@ -200,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]
@@ -234,7 +242,6 @@ d, e, f = 4, 5, 6
# Обратите внимание, как легко поменять местами значения двух переменных
e, d = d, e # теперь d == 5, а e == 4
-
# Словари содержат ассоциативные массивы
empty_dict = {}
# Вот так описывается предзаполненный словарь
@@ -244,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 можно проверять ключи на вхождение в словарь
@@ -271,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 не устанавливает значение элемента словаря)
+
+# Присваивайте значение ключам так же, как и в списках
+filled_dict["four"] = 4 # теперь filled_dict["four"] => 4
-# Метод setdefault вставляет пару ключ-значение, только если такого ключа нет
+# Метод 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])
-# Множеству можно назначать новую переменную
-filled_set = some_set
+# Порядок сортировки не гарантируется, хотя иногда они выглядят отсортированными
+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}
@@ -312,7 +316,7 @@ filled_set | other_set #=> {1, 2, 3, 4, 5, 6}
####################################################
-## 3. Поток управления и итерируемые объекты
+## 3. Поток управления
####################################################
# Для начала заведём переменную
@@ -328,13 +332,17 @@ else: # Это тоже необязательно.
print("some_var равно 10.")
-# Циклы For проходят по спискам. Результат:
- # собака — это млекопитающее
- # кошка — это млекопитающее
- # мышь — это млекопитающее
+"""
+Циклы For проходят по спискам
+
+Результат:
+ собака — это млекопитающее
+ кошка — это млекопитающее
+ мышь — это млекопитающее
+"""
for animal in ["собака", "кошка", "мышь"]:
- # Можете использовать format() для интерполяции форматированных строк
- print("{} — это млекопитающее".format(animal))
+ # Можете использовать оператор % для интерполяции форматированных строк
+ print("%s — это млекопитающее" % animal)
"""
«range(число)» возвращает список чисел
@@ -362,6 +370,8 @@ while x < 4:
x += 1 # Краткая запись для x = x + 1
# Обрабатывайте исключения блоками try/except
+
+# Работает в Python 2.6 и выше:
try:
# Чтобы выбросить ошибку, используется raise
raise IndexError("Это ошибка индекса")
@@ -374,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"]
####################################################
@@ -422,7 +401,8 @@ add(5, 6) #=> выводит «x равен 5, а y равен 6» и возвр
# Другой способ вызова функции — вызов с именованными аргументами
add(y=6, x=5) # Именованные аргументы можно указывать в любом порядке.
-# Вы можете определить функцию, принимающую переменное число аргументов
+# Вы можете определить функцию, принимающую переменное число аргументов,
+# которые будут интерпретированы как кортеж, если вы не используете *
def varargs(*args):
return args
@@ -430,7 +410,8 @@ varargs(1, 2, 3) #=> (1,2,3)
# А также можете определить функцию, принимающую переменное число
-# именованных аргументов
+# именованных аргументов, которые будут интерпретированы как словарь,
+# если вы не используете **
def keyword_args(**kwargs):
return kwargs
@@ -455,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
@@ -513,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)
# Метод класса разделяется между всеми экземплярами
# Они вызываются с указыванием вызывающего класса в качестве первого аргумента
@@ -566,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-файлы. Вы
# можете писать свои модули и импортировать их. Название
@@ -589,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
@@ -637,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 b1fd04e1..8b263be6 100644
--- a/ru-ru/ruby-ru.html.markdown
+++ b/ru-ru/ruby-ru.html.markdown
@@ -480,7 +480,7 @@ class Human
@name
end
- # Тоже самое можно определить с помощью att_accessor
+ # Тоже самое можно определить с помощью attr_accessor
attr_accessor :name
# Также можно создать методы только для записи или чтения
diff --git a/ru-ru/yaml-ru.html.markdown b/ru-ru/yaml-ru.html.markdown
index 0f805681..ddaed2b6 100644
--- a/ru-ru/yaml-ru.html.markdown
+++ b/ru-ru/yaml-ru.html.markdown
@@ -2,7 +2,7 @@
language: yaml
filename: learnyaml-ru.yaml
contributors:
-- [Adam Brenecki, 'https://github.com/adambrenecki']
+- [Leigh Brenecki, 'https://github.com/adambrenecki']
- [Suhas SG, 'https://github.com/jargnar']
translators:
- [Sergei Babin, 'https://github.com/serzn1']
diff --git a/ruby.html.markdown b/ruby.html.markdown
index f437adcf..4b96b71c 100644
--- a/ruby.html.markdown
+++ b/ruby.html.markdown
@@ -23,6 +23,15 @@ contributors:
```ruby
# This is a comment
+=begin
+This is a multi-line comment.
+The beginning line must start with "=begin"
+and the ending line must start with "=end".
+
+You can do this, or start each line in
+a multi-line comment with the # character.
+=end
+
# In Ruby, (almost) everything is an object.
# This includes numbers...
3.class #=> Integer
@@ -172,6 +181,9 @@ array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
# Arrays can contain different types of items.
[1, 'hello', false] #=> [1, "hello", false]
+# You might prefer %w instead of quotes
+%w[foo bar baz] #=> ["foo", "bar", "baz"]
+
# Arrays can be indexed.
# From the front...
array[0] #=> 1
@@ -247,7 +259,7 @@ else
'else, also optional'
end
-# If a condition controls invokation of a single statement rather than a block of code
+# 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?
@@ -315,6 +327,11 @@ 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'
@@ -421,6 +438,16 @@ def guests(*array)
array.each { |guest| puts guest }
end
+# 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.
diff --git a/rust.html.markdown b/rust.html.markdown
index 92794e69..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.
@@ -176,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) //
diff --git a/sass.html.markdown b/sass.html.markdown
index 224db80e..860e550a 100644
--- a/sass.html.markdown
+++ b/sass.html.markdown
@@ -16,7 +16,7 @@ This tutorial is written using SCSS.
If you're already familiar with CSS3, you'll be able to pick up Sass relatively quickly. It does not provide any new styling properties but rather the tools to write your CSS more efficiently and make maintenance much easier.
-```sass
+```scss
//Single line comments are removed when Sass is compiled to CSS.
diff --git a/scala.html.markdown b/scala.html.markdown
index c7a8842e..08fd37e4 100644
--- a/scala.html.markdown
+++ b/scala.html.markdown
@@ -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
diff --git a/set-theory.html.markdown b/set-theory.html.markdown
new file mode 100644
index 00000000..6fb657ed
--- /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 1, i.e. `|∅| = 1`.
+
+## 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/smalltalk.html.markdown b/smalltalk.html.markdown
index ae7ecb0e..58dccae4 100644
--- a/smalltalk.html.markdown
+++ b/smalltalk.html.markdown
@@ -30,7 +30,8 @@ The most basic operation is to send a message to an object
`anObject aMessage`
There are three sorts of messages
-- unary - a single string that may be several words conjoined in what we call camelcase form, with no arguments. For example 'size', 'reverseBytes', 'convertToLargerFormatPixels'
+
+- 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:'
@@ -38,21 +39,23 @@ There are three sorts of messages
`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
- doWierdThing:
- 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
-```
+We find a proper exact match and start to execute the code:
+
+```smalltalk
doSomethingWith: argumentObject
-"A comment about what this code is meant to do and any known limitations, problems, where it might be further documented etc"
-self size > 4 ifTrue: [^argumentObject sizeRelatingTo: self].
+ 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.
@@ -94,7 +97,7 @@ Taken from [Smalltalk Cheatsheet](http://www.angelfire.com/tx4/cus/notes/smallta
`"Period (.) is the statement separator. Not required on last line of a method"`
#### 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"
@@ -108,26 +111,17 @@ Transcript endEntry. "flush the output buffer"
```
#### Assignment:
-```
+```smalltalk
| x y |
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"
```
#### Constants:
-```
+```smalltalk
| b |
b := true. "true constant"
b := false. "false constant"
@@ -147,7 +141,7 @@ x := #('abc' 2 $a). "mixing of types allowed"
```
#### Booleans:
-```
+```smalltalk
| b x y |
x := 1. y := 2.
b := (x = y). "equals"
@@ -185,7 +179,7 @@ b := $A isLowercase. "test if lower case character"
```
#### Arithmetic expressions:
-```
+```smalltalk
| x |
x := 6 + 3. "addition"
x := 6 - 3. "subtraction"
@@ -241,7 +235,7 @@ x := 100 atRandom. "quick random number"
```
#### Bitwise Manipulation:
-```
+```smalltalk
| b x |
x := 16rFF bitAnd: 16r0F. "and bits"
x := 16rF0 bitOr: 16r0F. "or bits"
@@ -257,7 +251,7 @@ b := 16rFF noMask: 16r0F. "test if all bits set in mask clear in recei
```
#### Conversion:
-```
+```smalltalk
| x |
x := 3.99 asInteger. "convert number to integer (truncates in Squeak)"
x := 3.99 asFraction. "convert number to fraction"
@@ -281,7 +275,7 @@ 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"
@@ -304,7 +298,7 @@ Transcript show: (x value: 'First' value: 'Second'); cr. "use block with argu
- 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"
@@ -319,7 +313,7 @@ x := 3 + 2; * 100. "result=300. Sends message to same
```
#### Conditional Statements:
-```
+```smalltalk
| x |
x > 10 ifTrue: [Transcript show: 'ifTrue'; cr]. "if then"
x > 10 ifFalse: [Transcript show: 'ifFalse'; cr]. "if else"
@@ -359,7 +353,7 @@ result := (switch at: $B) value.
```
#### Iteration statements:
-```
+```smalltalk
| x y |
x := 4. y := 1.
[x > 0] whileTrue: [x := x - 1. y := y * 2]. "while true loop"
@@ -371,7 +365,7 @@ x timesRepeat: [y := y * 2]. "times repeat loop (i := 1 to x
```
#### Character:
-```
+```smalltalk
| x y |
x := $A. "character assignment"
y := x isLowercase. "test if lower case"
@@ -391,10 +385,10 @@ y := $A max: $B.
```
#### Symbol:
-```
+```smalltalk
| b x y |
x := #Hello. "symbol assignment"
-y := 'String', 'Concatenation'. "symbol concatenation (result is string)"
+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"
@@ -413,7 +407,7 @@ y := x asSet. "convert symbol to set collect
```
#### String:
-```
+```smalltalk
| b x y |
x := 'This is a string'. "string assignment"
x := 'String', 'Concatenation'. "string concatenation"
@@ -447,7 +441,7 @@ 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"
@@ -490,7 +484,7 @@ y := x asSet. "convert to set collection"
#### 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"
@@ -537,7 +531,7 @@ y := x asSet. "convert to set collection"
#### 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"
@@ -583,7 +577,7 @@ y := x asSet. "convert to set collection"
#### 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"
@@ -619,7 +613,7 @@ 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"
@@ -649,7 +643,7 @@ y := x asSet. "convert to set collection"
```
#### Interval:
-```
+```smalltalk
| b x y sum max |
x := Interval from: 5 to: 10. "create interval object"
x := 5 to: 10.
@@ -679,7 +673,7 @@ y := x asSet. "convert to set collection"
```
#### Associations:
-```
+```smalltalk
| x y |
x := #myVar->'hello'.
y := x key.
@@ -690,7 +684,7 @@ y := x value.
#### IdentityDictionary:
uses identity test (== rather than =)
-```
+```smalltalk
| b x y |
x := Dictionary new. "allocate collection"
x add: #a->4;
@@ -757,7 +751,7 @@ Smalltalk removeKey: #CMRDictionary ifAbsent: []. "remove user dictionary fr
```
#### Internal Stream:
-```
+```smalltalk
| b x ios |
ios := ReadStream on: 'Hello read stream'.
ios := ReadStream on: 'Hello read stream' from: 1 to: 5.
@@ -785,7 +779,7 @@ b := ios atEnd.
```
#### FileStream:
-```
+```smalltalk
| b x ios |
ios := FileStream newFileNamed: 'ios.txt'.
ios nextPut: $H; cr.
@@ -805,7 +799,7 @@ ios close.
```
#### Date:
-```
+```smalltalk
| x y |
x := Date today. "create date for today"
x := Date dateAndTimeNow. "create date from current time/date"
@@ -839,7 +833,7 @@ 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"
@@ -859,7 +853,7 @@ b := (x <= Time now). "comparison"
```
#### Point:
-```
+```smalltalk
| x y |
x := 200@100. "obtain a new point"
y := x x. "x coordinate"
@@ -884,12 +878,12 @@ x := 20@5 dotProduct: 10@2. "sum of product (x1*x2 + y1*y2)"
```
#### Rectangle:
-```
+```smalltalk
Rectangle fromUser.
```
#### Pen:
-```
+```smalltalk
| myPen |
Display restoreAfter: [
Display fillWhite.
@@ -917,7 +911,7 @@ Display height. "get display height"
```
#### Dynamic Message Calling/Compiling:
-```
+```smalltalk
| receiver message result argument keyword1 keyword2 argument1 argument2 |
"unary message"
@@ -957,7 +951,7 @@ result := (Message
```
#### Class/Meta-Class:
-```
+```smalltalk
| b x |
x := String name. "class name"
x := String category. "organization category"
@@ -990,7 +984,7 @@ Object withAllSubclasses size. "get total number of class entries"
```
#### Debugging:
-```
+```smalltalk
| a b x |
x yourself. "returns receiver"
String browse. "browse specified class"
@@ -1013,8 +1007,13 @@ Transcript show: a, b; cr.
```
#### Miscellaneous
-```
+```smalltalk
| x |
+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
diff --git a/sql.html.markdown b/sql.html.markdown
index 2bece208..5edf0f7c 100644
--- a/sql.html.markdown
+++ b/sql.html.markdown
@@ -9,14 +9,14 @@ Structured Query Language (SQL) is an ISO standard language for creating and wor
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.
+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
+-- 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.
@@ -26,47 +26,47 @@ DROP DATABASE someDatabase;
-- List available databases.
SHOW DATABASES;
--- Use a particular existing database.
+-- 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.
+-- 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.
+-- 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.
+-- 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'.
+-- 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.
+-- 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.
+-- 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.
+-- 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
+-- 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
+-- 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.)
@@ -85,12 +85,12 @@ WHERE TABLE_TYPE='BASE TABLE';
-- 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 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'.
+-- for all rows that have an lname value of 'Mutt'.
UPDATE tablename1 SET fname='John' WHERE lname='Mutt';
-- Delete rows from the tablename1 table
@@ -100,6 +100,11 @@ 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.
+-- 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 0ba42f39..9d6b104d 100644
--- a/standard-ml.html.markdown
+++ b/standard-ml.html.markdown
@@ -2,8 +2,8 @@
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/"]
@@ -479,3 +479,4 @@ fun decrement_ret x y = (x := !x - 1; y)
* Follow the Coursera course [Programming Languages](https://www.coursera.org/course/proglang).
* 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/swift.html.markdown b/swift.html.markdown
index 1f9fe897..689c5191 100644
--- a/swift.html.markdown
+++ b/swift.html.markdown
@@ -692,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")
@@ -904,7 +909,7 @@ func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? {
}
return nil
}
-findIndex(array: [1, 2, 3, 4], valueToFind: 3) // 2
+findIndex(array: [1, 2, 3, 4], valueToFind: 3) // Optional(2)
// You can extend types with generics as well
extension Array where Array.Element == Int {
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/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/toml.html.markdown b/toml.html.markdown
index 385a2437..2b234965 100755
--- a/toml.html.markdown
+++ b/toml.html.markdown
@@ -12,7 +12,7 @@ It is an alternative to YAML and JSON. It aims to be more human friendly than JS
Be warned, TOML's spec is still changing a lot. Until it's marked as 1.0, you
should assume that it is unstable and act accordingly. This document follows TOML v0.4.0.
-```
+```toml
# Comments in TOML look like this.
################
@@ -117,7 +117,7 @@ date4 = 1979-05-27 # without offset or 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"
@@ -171,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
@@ -220,7 +223,27 @@ 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.
@@ -245,11 +268,11 @@ color = "gray"
[[fruit.color]]
name = "yellow"
note = "I am an array item in banana fruit's table/map"
-```
-
-In JSON land, this code will be:
+```
+The equivalent in JSON would be:
```json
+
{
"fruit": [
{
diff --git a/tr-tr/c-tr.html.markdown b/tr-tr/c-tr.html.markdown
index 6042a609..4ef12527 100644
--- a/tr-tr/c-tr.html.markdown
+++ b/tr-tr/c-tr.html.markdown
@@ -477,7 +477,7 @@ 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
diff --git a/tr-tr/python-tr.html.markdown b/tr-tr/python-tr.html.markdown
index 99a3eb4e..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.0
+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 b78d517f..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"]
- - ["Batuhan Osman T.", "https://github.com/BTaskaya"]
-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(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 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/typescript.html.markdown b/typescript.html.markdown
index 00f0cbc5..f7a41ce1 100644
--- a/typescript.html.markdown
+++ b/typescript.html.markdown
@@ -114,7 +114,7 @@ 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);
@@ -137,7 +137,7 @@ class Point3D extends Point {
}
// Overwrite
- dist() {
+ dist(): number {
let d = super.dist();
return Math.sqrt(d * d + this.z * this.z);
}
@@ -257,8 +257,24 @@ 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'
```
diff --git a/uk-ua/cypher-ua.html.markdown b/uk-ua/cypher-ua.html.markdown
index e1eef5a2..0911793b 100644
--- a/uk-ua/cypher-ua.html.markdown
+++ b/uk-ua/cypher-ua.html.markdown
@@ -1,6 +1,6 @@
---
language: cypher
-filename: LearnCypher.cql
+filename: LearnCypher-ua.cql
contributors:
- ["Théo Gauchoux", "https://github.com/TheoGauchoux"]
translators:
diff --git a/uk-ua/go-ua.html.markdown b/uk-ua/go-ua.html.markdown
index 933b34f9..f980f7b1 100644
--- a/uk-ua/go-ua.html.markdown
+++ b/uk-ua/go-ua.html.markdown
@@ -2,7 +2,7 @@
name: Go
category: language
language: Go
-filename: learngo.go
+filename: learngo-ua.go
contributors:
- ["Sonia Keys", "https://github.com/soniakeys"]
- ["Christopher Bess", "https://github.com/cbess"]
diff --git a/uk-ua/javascript-ua.html.markdown b/uk-ua/javascript-ua.html.markdown
index 6a64a623..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
diff --git a/uk-ua/python-ua.html.markdown b/uk-ua/pythonlegacy-ua.html.markdown
index 4091e433..e2a6d19e 100644
--- a/uk-ua/python-ua.html.markdown
+++ b/uk-ua/pythonlegacy-ua.html.markdown
@@ -1,5 +1,5 @@
---
-language: python
+language: Python 2 (legacy)
lang: uk-ua
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
@@ -10,7 +10,7 @@ contributors:
- ["habi", "http://github.com/habi"]
translators:
- ["Oleh Hromiak", "https://github.com/ogroleg"]
-filename: learnpython-ua.py
+filename: learnpythonlegacy-ua.py
---
Мову Python створив Гвідо ван Россум на початку 90-х. Наразі це одна з
diff --git a/vi-vn/python3-vi.html.markdown b/vi-vn/python-vi.html.markdown
index f6cce1a3..89e51d5d 100644
--- a/vi-vn/python3-vi.html.markdown
+++ b/vi-vn/python-vi.html.markdown
@@ -1,6 +1,6 @@
---
-language: python3
-filename: learnpython3-vi.py
+language: Python
+filename: learnpython-vi.py
contributors:
- ["Louie Dinh", "http://pythonpracticeprojects.com"]
- ["Steven Basart", "http://github.com/xksteven"]
@@ -19,7 +19,7 @@ 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/python/) nếu bạn muốn học phiên bản cũ Python 2.7
+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
diff --git a/vim.html.markdown b/vim.html.markdown
index 5b84a3ea..55649cb2 100644
--- a/vim.html.markdown
+++ b/vim.html.markdown
@@ -13,6 +13,9 @@ 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
```
@@ -24,6 +27,7 @@ specific points in the file, and for fast editing.
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
@@ -181,6 +185,7 @@ A few important examples of 'Verbs', 'Modifiers', and 'Nouns':
~ # 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
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/wasm.html.markdown b/wasm.html.markdown
index 98bfc000..81344abe 100644
--- a/wasm.html.markdown
+++ b/wasm.html.markdown
@@ -61,7 +61,7 @@ contributors:
;; 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))) ;; 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.
@@ -222,6 +222,91 @@ contributors:
)
)
(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/yaml.html.markdown b/yaml.html.markdown
index f1393c09..4f10a128 100644
--- a/yaml.html.markdown
+++ b/yaml.html.markdown
@@ -2,7 +2,7 @@
language: yaml
filename: learnyaml.yaml
contributors:
-- [Adam Brenecki, 'https://github.com/adambrenecki']
+- [Leigh Brenecki, 'https://leigh.net.au']
- [Suhas SG, 'https://github.com/jargnar']
---
diff --git a/zh-cn/c-cn.html.markdown b/zh-cn/c-cn.html.markdown
index 8566e811..7286fa9f 100644
--- a/zh-cn/c-cn.html.markdown
+++ b/zh-cn/c-cn.html.markdown
@@ -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/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/git-cn.html.markdown b/zh-cn/git-cn.html.markdown
index d471ab5d..63d740a1 100644
--- a/zh-cn/git-cn.html.markdown
+++ b/zh-cn/git-cn.html.markdown
@@ -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/javascript-cn.html.markdown b/zh-cn/javascript-cn.html.markdown
index 360f7c65..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"]
@@ -17,8 +17,8 @@ Javascript 于 1995 年由网景公司的 Brendan Eich 发明。最初它作为
不过,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/make-cn.html.markdown b/zh-cn/make-cn.html.markdown
index 76dde941..641714ef 100644
--- a/zh-cn/make-cn.html.markdown
+++ b/zh-cn/make-cn.html.markdown
@@ -23,7 +23,7 @@ Makefile 用于定义如何创建目标文件, 比如如何从源码到可执行
```make
# 这行表示注释
-# 文件名一定要交 Makefile, 大小写区分, 使用 `make <target>` 生成 target
+# 文件名一定要叫 Makefile, 大小写区分, 使用 `make <target>` 生成 target
# 如果想要取别的名字, 可以用 `make -f "filename" <target>`.
# 重要的事情 - 只认识 TAB, 空格是不认的, 但是在 GNU Make 3.82 之后, 可以通过
@@ -87,7 +87,7 @@ ex0.txt ex1.txt: maker
maker:
touch ex0.txt ex1.txt
-# 如果定义的 phony target 与文件名重名, 可以用 .PHONY 显示的指明哪些 targets 是 phony
+# 如果定义的 phony target 与文件名重名, 可以用 .PHONY 显式地指明哪些 targets 是 phony
.PHONY: all maker process
# This is a special target. There are several others.
@@ -116,7 +116,7 @@ process: ex1.txt file0.txt
# 模式匹配
#-----------------------------------------------------------------------
-# 可以让 make 知道如何转换某些文件到别格式
+# 可以让 make 知道如何转换某些文件到其他格式
# 比如 从 svg 到 png
%.png: %.svg
inkscape --export-png $^
@@ -149,7 +149,7 @@ echo:
@echo $(name)
@echo ${name2}
@echo $name # 这个会被蠢蠢的解析成 $(n)ame.
- @echo \"$(name3)\" # 为声明的变量或扩展成空字符串.
+ @echo \"$(name3)\" # 未声明的变量会被处理成空字符串.
@echo $(name4)
@echo $(name5)
# 你可以通过4种方式设置变量.
diff --git a/zh-cn/markdown-cn.html.markdown b/zh-cn/markdown-cn.html.markdown
index 9b3d96ab..707d6927 100644
--- a/zh-cn/markdown-cn.html.markdown
+++ b/zh-cn/markdown-cn.html.markdown
@@ -211,7 +211,7 @@ GitHub 也支持 Markdown,在 GitHub 的 Markdown 解析器中,我们可以
内联代码可由反引号 ` 实现
```md
-John 甚至不知道 `go_to()` 方程是干嘛的!
+John 甚至不知道 `go_to()` 函数是干嘛的!
```
在GitHub的 Markdown(GitHub Flavored Markdown)解析器中,你可以使用特殊的语法表示代码块
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 65f125d1..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.0
+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 fd962305..00000000
--- a/zh-cn/python3-cn.html.markdown
+++ /dev/null
@@ -1,632 +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)
-邮箱 louiedinh [at] [谷歌的信箱服务]。中文翻译 Geoff Liu。
-
-注意:这篇教程是基于 Python 3 写的。如果你想学旧版 Python 2,我们特别有[另一篇教程](http://learnxinyminutes.com/docs/python/)。
-
-```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) # => 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 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
-
-# 生成器只有在需要时才计算下一个值。它们每一次循环只生成一个值,而不是把所有的
-# 值全部算好。
-#
-# 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/)
-* [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/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/yaml-cn.html.markdown b/zh-cn/yaml-cn.html.markdown
index 3ba2afd8..cfa22dfb 100644
--- a/zh-cn/yaml-cn.html.markdown
+++ b/zh-cn/yaml-cn.html.markdown
@@ -1,29 +1,31 @@
---
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
@@ -33,16 +35,16 @@ scientific_notation: 1e+12
boolean: true
null_value: null
key with spaces: value
-# 注意,字符串不必被括在引号中,但也可以被括起来。
+# 注意,字符串可以不括在引号里。当然,也可以括在引号里。
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 字符需要被转义(encoded)
+# 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.
@@ -65,7 +67,7 @@ folded_style: >
# 集合类型 #
####################
-# 嵌套是通过缩进完成的。推荐使用 2 个空格的缩进(但非必须)
+# 嵌套是通过缩进完成的。推荐使用 2 个空格的缩进(但非必须)。
a_nested_map:
key: value
another_key: Another Value
@@ -75,22 +77,22 @@ a_nested_map:
# 映射的键不必是字符串。
0.25: a float key
-# 键也可以是复合型的,比如多行对象
-# 我们用 ? 后跟一个空格来表示一个复合键的开始。
+# 键也可以是复合(complex)的,比如多行对象
+# 我们用 '?' 后跟一个空格来表示一个复合键的开始。
? |
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
@@ -113,7 +115,7 @@ 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
@@ -122,8 +124,8 @@ other_anchor: *anchor_name
base: &base
name: Everyone has same name
-# The regexp << is called Merge Key Language-Independent Type.
-# 它表明指定映射的所有键值会插入到当前的映射中。
+# '<<'称为语言无关的合并键类型(Merge Key Language-Independent Type).
+# 它表明一个或多个指定映射中的所有键值会插入到当前的映射中。
foo: &foo
<<: *base
@@ -135,22 +137,22 @@ bar: &bar
# 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
@@ -163,23 +165,24 @@ gif_file: !!binary |
+f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
-# YAML 还有一个集合类型,它看起来像这样:
+# YAML 还有一个集合(set)类型,它看起来像这样:
set:
? item1
? item2
? item3
or: {item1, item2, item3}
-# 集合只是值为 null 的映射;上面的集合等价于:
+# 集合只是值均为 null 的映射;上面的集合等价于:
set2:
item1: null
item2: null
item3: null
-... # document end
+... # 文档结束
```
### 更多资源
+ [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/python-tw.html.markdown b/zh-tw/pythonlegacy-tw.html.markdown
index cd7481d7..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) 模組.