1
0
mirror of https://github.com/adambard/learnxinyminutes-docs.git synced 2025-08-06 23:06:49 +02:00

Merge remote-tracking branch 'upstream/master' into master

This commit is contained in:
Dimitris Kokkonis
2020-10-10 12:31:09 +02:00
252 changed files with 33163 additions and 13037 deletions

2
.gitattributes vendored
View File

@@ -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

1
.mailmap Normal file
View File

@@ -0,0 +1 @@
Leigh Brenecki <l@leigh.net.au> <adam@brenecki.id.au>

View File

@@ -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.

View File

@@ -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.

View File

@@ -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

View File

@@ -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 dont evaluate by best case because those
conditions arent what youre 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 youre 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.
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.
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.
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.

View File

@@ -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

View File

@@ -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`

View File

@@ -199,10 +199,10 @@ int main()
cin >> myInt;
// cout can also be formatted
cout << "Your favorite number is " << myInt << "\n";
cout << "Your favorite number is " << myInt << '\n';
// prints "Your favorite number is <myInt>"
cerr << "Used for error messages";
cerr << "Used for error messages";
}
//////////
@@ -461,7 +461,7 @@ void Dog::print() const
Dog::~Dog()
{
std::cout << "Goodbye " << name << "\n";
std::cout << "Goodbye " << name << '\n';
}
int main() {
@@ -504,7 +504,7 @@ void OwnedDog::setOwner(const std::string& dogsOwner)
void OwnedDog::print() const
{
Dog::print(); // Call the print function in the base Dog class
std::cout << "Dog is owned by " << owner << "\n";
std::cout << "Dog is owned by " << owner << '\n';
// Prints "Dog is <name> and weights <weight>"
// "Dog is owned by <owner>"
}
@@ -818,51 +818,51 @@ void doSomethingWithAFile(const std::string& filename)
// Smart Pointer
/////////////////////
// Generally a smart pointer is a class, which wraps a "raw pointer" (usage of "new"
// Generally a smart pointer is a class which wraps a "raw pointer" (usage of "new"
// respectively malloc/calloc in C). The goal is to be able to
// manage the lifetime of the object being point to without explicitly deleting
// manage the lifetime of the object being pointed to without ever needing to explicitly delete
// the object. The term itself simply describes a set of pointers with the
// mentioned abstraction.
// Basically smart pointers should preferred over raw pointers, to prevent
// risky memory leaks, which happens if you forget to delete the object.
// Smart pointers should preferred over raw pointers, to prevent
// risky memory leaks, which happen if you forget to delete an object.
// Usage of a raw pointer:
Dog* ptr = new Dog();
ptr->bark();
delete ptr;
// With the usage of smart pointers you dont have to worry about the deletion
// of a object anymore.
// A smart pointer describes a policy, to count the references on the
// pointer. As matter of fact the objects gets destroyed when the last
// reference on the object gets destroyed.
// By using a smart pointer, you don't have to worry about the deletion
// of the object anymore.
// A smart pointer describes a policy, to count the references to the
// pointer. The object gets destroyed when the last
// reference to the object gets destroyed.
// Usage of "std::shared_ptr":
void foo()
{
// Its not longer necessary to delete the Dog.
// It's no longer necessary to delete the Dog.
std::shared_ptr<Dog> doggo(new Dog());
doggo->bark();
}
// Beware of possible circular references!!!
// There will be always a reference, so it will be never destroyed!
std::shared_ptr<Dog> doggo_one (new Dog());
std::shared_ptr<Dog> doggo_two (new Dog());
std::shared_ptr<Dog> doggo_one(new Dog());
std::shared_ptr<Dog> doggo_two(new Dog());
doggo_one = doggo_two; // p1 references p2
doggo_two = doggo_one; // p2 references p1
// As mentioned before there is a set of smart pointers. The way you have to
// use it, is always the same.
// This leads us to question, when to use which one?
// std::unique_ptr - use it when you just want to hold one reference on
// the same object.
// std::shared_ptr - use it when you want to hold multiple references on the
// same object and want to make sure that it´s de-allocated
// when all refences are gone.
// std::weak_ptr - use it when you want to hold multiple references from
// different places for references for which it´s no problem
// tp de-allocate.
// There are several kinds of smart pointers.
// The way you have to use them is always the same.
// This leads us to the question: when should we use each kind of smart pointer?
// std::unique_ptr - use it when you just want to hold one reference to
// the object.
// std::shared_ptr - use it when you want to hold multiple references to the
// same object and want to make sure that it's deallocated
// when all references are gone.
// std::weak_ptr - use it when you want to access
// the underlying object of a std::shared_ptr without causing that object to stay allocated.
// Weak pointers are used to prevent circular referencing.
/////////////////////
@@ -915,7 +915,7 @@ ST.erase(20); // Will erase element with value 20
// Set ST: 10 30
// To iterate through Set we use iterators
set<int>::iterator it;
for(it=ST.begin();it<ST.end();it++) {
for(it=ST.begin();it!=ST.end();it++) {
cout << *it << endl;
}
// Output:
@@ -946,7 +946,7 @@ mymap.insert(pair<char,int>('Z',26));
// To iterate
map<char,int>::iterator it;
for (it=mymap.begin(); it!=mymap.end(); ++it)
std::cout << it->first << "->" << it->second << '\n';
std::cout << it->first << "->" << it->second << std::cout;
// Output:
// A->1
// Z->26
@@ -1117,33 +1117,33 @@ const int maxL = 15;
auto second = make_tuple(maxN, maxL);
// Printing elements of 'first' tuple
cout << get<0>(first) << " " << get<1>(first) << "\n"; //prints : 10 A
cout << get<0>(first) << " " << get<1>(first) << '\n'; //prints : 10 A
// Printing elements of 'second' tuple
cout << get<0>(second) << " " << get<1>(second) << "\n"; // prints: 1000000000 15
cout << get<0>(second) << " " << get<1>(second) << '\n'; // prints: 1000000000 15
// Unpacking tuple into variables
int first_int;
char first_char;
tie(first_int, first_char) = first;
cout << first_int << " " << first_char << "\n"; // prints : 10 A
cout << first_int << " " << first_char << '\n'; // prints : 10 A
// We can also create tuple like this.
tuple<int, char, double> third(11, 'A', 3.14141);
// tuple_size returns number of elements in a tuple (as a constexpr)
cout << tuple_size<decltype(third)>::value << "\n"; // prints: 3
cout << tuple_size<decltype(third)>::value << '\n'; // prints: 3
// tuple_cat concatenates the elements of all the tuples in the same order.
auto concatenated_tuple = tuple_cat(first, second, third);
// concatenated_tuple becomes = (10, 'A', 1e9, 15, 11, 'A', 3.14141)
cout << get<0>(concatenated_tuple) << "\n"; // prints: 10
cout << get<3>(concatenated_tuple) << "\n"; // prints: 15
cout << get<5>(concatenated_tuple) << "\n"; // prints: 'A'
cout << get<0>(concatenated_tuple) << '\n'; // prints: 10
cout << get<3>(concatenated_tuple) << '\n'; // prints: 15
cout << get<5>(concatenated_tuple) << '\n'; // prints: 'A'
///////////////////////////////////

View File

@@ -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).

176
ca-es/html-ca.html.markdown Normal file
View File

@@ -0,0 +1,176 @@
---
language: html
filename: html-ca.md
contributors:
- ["Christophe THOMAS", "https://github.com/WinChris"]
translators:
- ["Marc Auledas", "https://github.com/Auledas"]
lang: ca-es
---
HTML significa llenguatge de marques d'hipertext (HyperText Markup Language).
És un llenguatge que permet escriure pàgines pel sistema web (World Wide Web).
És un llenguatge de marques que permet escriure pàgines web fent servir codi per indicar
com s'ha de visualitzar el text i les dades. De fet, els fitxers html són simples
fitxers de text.
Què són les 'marques'? Són un mètode d'organitzar les dades d'una pàgina mitjançant
etiquetes d'obertura i tancament. Aquestes marques serveixen per donar
significat al text que hi ha entre les etiquetes. Com d'altres llenguatges de marques,
hi ha moltes versions de l'HTML. Aquí es desenvoluparà l'HTML5.
**NOTA:** Pots provar les diferents etiquetes i elements a mesura que progressis a través
del tutorial a pàgines web com [codepen](http://codepen.io/pen/). D'aquesta manera podràs
veure'n els efectes, entendre com funcionen i familiaritzar-te amb el llenguatge. Aquest
article tracta principalment la sintaxi de l'HTML i alguns consells útils.
```html
<!-- Els comentaris s'escriuen com aquesta línia! -->
<!--
Els comentaris
poden
ocupar
múltiples
línies!
-->
<!-- #################### Les etiquetes #################### -->
<!-- Aquí hi ha un exemple de fitxer HTML que analitzarem. -->
<!doctype html>
<html>
<head>
<title>El meu lloc web</title>
</head>
<body>
<h1>Hola, món!</h1>
<a href="http://codepen.io/anon/pen/xwjLbZ">
Fes una ullada a com es veu això.
</a>
<p>Això és un paràgraf.</p>
<p>Això és un altre paràgraf.</p>
<ul>
<li>Això és un element d'una llista no enumerada (llista de punts).</li>
<li>Això és un altre element.</li>
<li>I aquest és l'últim element de la llista.</li>
</ul>
</body>
</html>
<!--
Un fitxer HTML sempre comença indicant al navegador que la pàgina és HTML.
-->
<!doctype html>
<!-- Després d'això, es comença obrint l'etiqueta <html>. -->
<html>
<!-- Aquesta etiqueta s'ha de tancar al final del fitxer amb </html>. -->
</html>
<!-- No s'ha d'escriure res més després d'aquesta etiqueta final. -->
<!-- Entremig (entre les etiquetes d'obertura i tancament <html></html>), trobem: -->
<!-- Una capçalera definida per <head> (que s'ha de tancar emprant </head>). -->
<!--
La capçalera conté descripcions i informació addicional que no es mostra,
això són les metadades.
-->
<head>
<!--
L'etiqueta <title> indica al navegador el títol que s'ha de visualitzar
a la finestra del buscador, a la barra del títol, i al nom de la pestanya.
-->
<title>El meu lloc web</title>
</head>
<!-- Després de la secció <head>, trobem l'etiqueta <body> -->
<!-- Fins a aquest punt, res del que s'ha fet apareixerà a la finestra del navegador. -->
<!-- Hem d'emplenar el cos amb el contingut per visualitzar. -->
<body>
<!-- L'etiqueta h1 crea el títol. -->
<h1>Hola, món!</h1>
<!--
També es poden fer subtítols per <h1>, que van des del més important <h2>
fins al més precís <h6>.
-->
<!-- També es poden crear enllaços fent servir l'atribut href="" -->
<a href="http://codepen.io/anon/pen/xwjLbZ">
Fes una ullada a com es veu això.
</a>
<!-- L'etiqueta <p> permet incloure text a una pàgina HTML. -->
<p>Això és un paràgraf.</p>
<p>Això és un altre paràgraf.</p>
<!-- L'etiqueta <ul> crea una llista de punts. -->
<!--
Per tenir una llista enumerada s'hauria de fer servir <ol>, en comptes d'<ul>.
El primer element seria 1, el segon element 2, etc.
-->
<ul>
<li>Això és un element d'una llista no enumerada (llista de punts).</li>
<li>Això és un altre element.</li>
<li>I aquest és l'últim element de la llista.</li>
</ul>
</body>
<!-- I això és tot, crear un fitxer HTML pot ser molt simple. -->
<!-- Però és possible afegir molts altres tipus d'etiquetes HTML addicionals. -->
<!-- L'etiqueta <img /> es fa servir per afegir imatges. -->
<!--
L'origen de la imatge s'indica fent servir l'atribut src=""
L'origen pot ser una adreça URL o la ruta a un arxiu del teu ordinador.
-->
<img src="http://i.imgur.com/XWG0O.gif"/>
<!-- També es poden crear taules. -->
<!-- L'etiqueta <table> obre la taula. -->
<table>
<!-- <tr> permet crear files. -->
<tr>
<!-- <th> permet posar títol a la columna d'una taula. -->
<th>Primera capçalera</th>
<th>Segona capçalera</th>
</tr>
<tr>
<!-- <td> permet crear cel·les d'una taula. -->
<td>Primera fila, primera columna</td>
<td>Primera fila, segona columna</td>
</tr>
<tr>
<td>Segona fila, primera columna</td>
<td>Segona fila, segona columna</td>
</tr>
</table>
```
## Ús
Els arxius HTML acaben amb les extensions `.html` o `.htm`. El tipus MIME és `text/html`.
**HTML NO és un llenguatge de programació**
## Per aprendre'n més
* [Viquipèdia](https://ca.wikipedia.org/wiki/Hyper_Text_Markup_Language)
* [Tutorial HTML](https://developer.mozilla.org/ca/docs/Web/HTML)
* [W3School](http://www.w3schools.com/html/html_intro.asp)

View File

@@ -416,3 +416,6 @@ Clojuredocs.org has documentation with examples for most core functions:
Clojure-doc.org (yes, really) has a number of getting started articles:
[http://clojure-doc.org/](http://clojure-doc.org/)
Clojure for the Brave and True has a great introduction to Clojure and a free online version:
[https://www.braveclojure.com/clojure-for-the-brave-and-true/](https://www.braveclojure.com/clojure-for-the-brave-and-true/)

View File

@@ -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/)

198
cobol.html.markdown Normal file
View File

@@ -0,0 +1,198 @@
---
language: COBOL
contributors:
- ["Hyphz", "http://github.com/hyphz/"]
filename: learn.COB
---
COBOL is a business-oriented language revised multiple times since its original design in 1960. It is claimed to still be used in over 80% of
organizations.
```cobol
*COBOL. Coding like it's 1985.
*Compiles with GnuCOBOL in OpenCobolIDE 4.7.6.
*COBOL has significant differences between legacy (COBOL-85)
*and modern (COBOL-2002 and COBOL-2014) versions.
*Legacy versions require columns 1-6 to be blank (they are used
*to store the index number of the punched card..)
*A '*' in column 7 means a comment.
*In legacy COBOL, a comment can only be a full line.
*Modern COBOL doesn't require fixed columns and uses *> for
*a comment, which can appear in the middle of a line.
*Legacy COBOL also imposes a limit on maximum line length.
*Keywords have to be in capitals in legacy COBOL,
*but are case insensitive in modern.
*Although modern COBOL allows you to use mixed-case characters
*it is still common to use all caps when writing COBOL code.
*This is what most professional COBOL developers do.
*COBOL statements end with a period.
*COBOL code is broken up into 4 divisions.
*Those divisions, in order, are:
*IDENTIFICATION DIVISION.
*ENVIRONMENT DIVISION.
*DATA DIVISION.
*PROCEDURE DIVISION.
*First, we must give our program an ID.
*Identification division can include other values too,
*but they are comments only. Program-id is the only one that is mandatory.
IDENTIFICATION DIVISION.
PROGRAM-ID. LEARN.
AUTHOR. JOHN DOE.
DATE-WRITTEN. 05/02/2020.
*Let's declare some variables.
*We do this in the WORKING-STORAGE section within the DATA DIVISION.
*Each data item (aka variable) 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 DIVISION.
DISPLAY "STARTING PROGRAM".
MOVE "HELLO WORLD" TO THE-MESSAGE.
DISPLAY THE-MESSAGE.
STOP RUN.
*The above code will output:
*STARTING PROGRAM
*HELLO WORLD
********COBOL can perform math***************
ADD 1 TO AGE GIVING NEW-AGE.
SUBTRACT 1 FROM COUNT.
DIVIDE VAR-1 INTO VAR-2 GIVING VAR-3.
COMPUTE TOTAL-COUNT = COUNT1 PLUS COUNT2.
*********PERFORM********************
*The PERFORM keyword allows you to jump to another specified section of the code,
*and then to return to the next executable
*statement once the specified section of code is completed.
*You must write the full word, PERFORM, you cannot abbreviate it.
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLOCOBOL.
PROCEDURE DIVISION.
FIRST-PARA.
DISPLAY 'THIS IS IN FIRST-PARA'.
PERFORM THIRD-PARA THRU FOURTH-PARA. *>skip second-para and perfrom 3rd & 4th
*> then after performing third and fourth,
*> return here and continue the program until STOP RUN.
SECOND-PARA.
DISPLAY 'THIS IS IN SECOND-PARA'.
STOP RUN.
THIRD-PARA.
DISPLAY 'THIS IS IN THIRD-PARA'.
FOURTH-PARA.
DISPLAY 'THIS IS IN FOURTH-PARA'.
*When you compile and execute the above program, it produces the following result:
THIS IS IN FIRST-PARA
THIS IS IN THIRD-PARA
THIS IS IN FOURTH-PARA
THIS IS IN SECOND-PARA
**********Combining variables together using STRING ***********
*Now it is time to learn about two related COBOL verbs: string and unstring.
*The string verb is used to concatenate, or put together, two or more stings.
*Unstring is used, not surprisingly, to separate a
*string into two or more smaller strings.
*It is important that you remember to use delimited by when you
*are using string or unstring in your program.
IDENTIFICATION DIVISION.
PROGRAM-ID. LEARNING.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 FULL-NAME PIC X(20).
01 FIRST-NAME PIC X(13) VALUE "BOB GIBBERISH".
01 LAST-NAME PIC X(5) VALUE "COBB".
PROCEDURE DIVISION.
STRING FIRST-NAME DELIMITED BY SPACE
" "
LAST-NAME DELIMITED BY SIZE
INTO FULL-NAME
END-STRING.
DISPLAY "THE FULL NAME IS: "FULL-NAME.
STOP RUN.
*The above code will output:
THE FULL NAME IS: BOB COBB
*Lets 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/)

View File

@@ -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".

510
coq.html.markdown Normal file
View File

@@ -0,0 +1,510 @@
---
language: Coq
filename: learncoq.v
contributors:
- ["Philip Zucker", "http://www.philipzucker.com/"]
---
The Coq system is a proof assistant. It is designed to build and verify mathematical proofs. The Coq system contains the functional programming language Gallina and is capable of proving properties about programs written in this language.
Coq is a dependently typed language. This means that the types of the language may depend on the values of variables. In this respect, it is similar to other related languages such as Agda, Idris, F*, Lean, and others. Via the Curry-Howard correspondence, programs, properties and proofs are formalized in the same language.
Coq is developed in OCaml and shares some syntactic and conceptual similarity with it. Coq is a language containing many fascinating but difficult topics. This tutorial will focus on the programming aspects of Coq, rather than the proving. It may be helpful, but not necessary to learn some OCaml first, especially if you are unfamiliar with functional programming. This tutorial is based upon its OCaml equivalent
The standard usage model of Coq is to write it with interactive tool assistance, which operates like a high powered REPL. Two common such editors are the CoqIDE and Proof General Emacs mode.
Inside Proof General `Ctrl+C Ctrl+<Enter>` will evaluate up to your cursor.
```coq
(*** Comments ***)
(* Comments are enclosed in (* and *). It's fine to nest comments. *)
(* There are no single-line comments. *)
(*** Variables and functions ***)
(* The Coq proof assistant can be controlled and queried by a command
language called the vernacular. Vernacular keywords are capitalized and
the commands end with a period. Variable and function declarations are
formed with the Definition vernacular. *)
Definition x := 10.
(* Coq can sometimes infer the types of arguments, but it is common practice
to annotate with types. *)
Definition inc_nat (x : nat) : nat := x + 1.
(* There exists a large number of vernacular commands for querying
information. These can be very useful. *)
Compute (1 + 1). (* 2 : nat *) (* Compute a result. *)
Check tt. (* tt : unit *) (* Check the type of an expressions *)
About plus. (* Prints information about an object *)
(* Print information including the definition *)
Print true. (* Inductive bool : Set := true : Bool | false : Bool *)
Search nat. (* Returns a large list of nat related values *)
Search "_ + _". (* You can also search on patterns *)
Search (?a -> ?a -> bool). (* Patterns can have named parameters *)
Search (?a * ?a).
(* Locate tells you where notation is coming from. Very helpful when you
encounter new notation. *)
Locate "+".
(* Calling a function with insufficient number of arguments does not cause
an error, it produces a new function. *)
Definition make_inc x y := x + y. (* make_inc is int -> int -> int *)
Definition inc_2 := make_inc 2. (* inc_2 is int -> int *)
Compute inc_2 3. (* Evaluates to 5 *)
(* Definitions can be chained with "let ... in" construct. This is roughly
the same to assigning values to multiple variables before using them in
expressions in imperative languages. *)
Definition add_xy : nat := let x := 10 in
let y := 20 in
x + y.
(* Pattern matching is somewhat similar to switch statement in imperative
languages, but offers a lot more expressive power. *)
Definition is_zero (x : nat) :=
match x with
| 0 => true
| _ => false (* The "_" pattern means "anything else". *)
end.
(* You can define recursive function definition using the Fixpoint
vernacular.*)
Fixpoint factorial n := match n with
| 0 => 1
| (S n') => n * factorial n'
end.
(* Function application usually doesn't need parentheses around arguments *)
Compute factorial 5. (* 120 : nat *)
(* ...unless the argument is an expression. *)
Compute factorial (5-1). (* 24 : nat *)
(* You can define mutually recursive functions using "with" *)
Fixpoint is_even (n : nat) : bool := match n with
| 0 => true
| (S n) => is_odd n
end with
is_odd n := match n with
| 0 => false
| (S n) => is_even n
end.
(* As Coq is a total programming language, it will only accept programs when
it can understand they terminate. It can be most easily seen when the
recursive call is on a pattern matched out subpiece of the input, as then
the input is always decreasing in size. Getting Coq to understand that
functions terminate is not always easy. See the references at the end of
the article for more on this topic. *)
(* Anonymous functions use the following syntax: *)
Definition my_square : nat -> nat := fun x => x * x.
Definition my_id (A : Type) (x : A) : A := x.
Definition my_id2 : forall A : Type, A -> A := fun A x => x.
Compute my_id nat 3. (* 3 : nat *)
(* You can ask Coq to infer terms with an underscore *)
Compute my_id _ 3.
(* An implicit argument of a function is an argument which can be inferred
from contextual knowledge. Parameters enclosed in {} are implicit by
default *)
Definition my_id3 {A : Type} (x : A) : A := x.
Compute my_id3 3. (* 3 : nat *)
(* Sometimes it may be necessary to turn this off. You can make all
arguments explicit again with @ *)
Compute @my_id3 nat 3.
(* Or give arguments by name *)
Compute my_id3 (A:=nat) 3.
(* Coq has the ability to extract code to OCaml, Haskell, and Scheme *)
Require Extraction.
Extraction Language OCaml.
Extraction "factorial.ml" factorial.
(* The above produces a file factorial.ml and factorial.mli that holds:
type nat =
| O
| S of nat
(** val add : nat -> nat -> nat **)
let rec add n m =
match n with
| O -> m
| S p -> S (add p m)
(** val mul : nat -> nat -> nat **)
let rec mul n m =
match n with
| O -> O
| S p -> add m (mul p m)
(** val factorial : nat -> nat **)
let rec factorial n = match n with
| O -> S O
| S n' -> mul n (factorial n')
*)
(*** Notation ***)
(* Coq has a very powerful Notation system that can be used to write
expressions in more natural forms. *)
Compute Nat.add 3 4. (* 7 : nat *)
Compute 3 + 4. (* 7 : nat *)
(* Notation is a syntactic transformation applied to the text of the program
before being evaluated. Notation is organized into notation scopes. Using
different notation scopes allows for a weak notion of overloading. *)
(* Imports the Zarith module holding definitions related to the integers Z *)
Require Import ZArith.
(* Notation scopes can be opened *)
Open Scope Z_scope.
(* Now numerals and addition are defined on the integers. *)
Compute 1 + 7. (* 8 : Z *)
(* Integer equality checking *)
Compute 1 =? 2. (* false : bool *)
(* Locate is useful for finding the origin and definition of notations *)
Locate "_ =? _". (* Z.eqb x y : Z_scope *)
Close Scope Z_scope.
(* We're back to nat being the default interpretation of "+" *)
Compute 1 + 7. (* 8 : nat *)
(* Scopes can also be opened inline with the shorthand % *)
Compute (3 * -7)%Z. (* -21%Z : Z *)
(* Coq declares by default the following interpretation scopes: core_scope,
type_scope, function_scope, nat_scope, bool_scope, list_scope, int_scope,
uint_scope. You may also want the numerical scopes Z_scope (integers) and
Q_scope (fractions) held in the ZArith and QArith module respectively. *)
(* You can print the contents of scopes *)
Print Scope nat_scope.
(*
Scope nat_scope
Delimiting key is nat
Bound to classes nat Nat.t
"x 'mod' y" := Nat.modulo x y
"x ^ y" := Nat.pow x y
"x ?= y" := Nat.compare x y
"x >= y" := ge x y
"x > y" := gt x y
"x =? y" := Nat.eqb x y
"x <? y" := Nat.ltb x y
"x <=? y" := Nat.leb x y
"x <= y <= z" := and (le x y) (le y z)
"x <= y < z" := and (le x y) (lt y z)
"n <= m" := le n m
"x < y <= z" := and (lt x y) (le y z)
"x < y < z" := and (lt x y) (lt y z)
"x < y" := lt x y
"x / y" := Nat.div x y
"x - y" := Init.Nat.sub x y
"x + y" := Init.Nat.add x y
"x * y" := Init.Nat.mul x y
*)
(* Coq has exact fractions available as the type Q in the QArith module.
Floating point numbers and real numbers are also available but are a more
advanced topic, as proving properties about them is rather tricky. *)
Require Import QArith.
Open Scope Q_scope.
Compute 1. (* 1 : Q *)
(* Only 1 and 0 are interpreted as fractions by Q_scope *)
Compute 2. (* 2 : nat *)
Compute (2 # 3). (* The fraction 2/3 *)
Compute (1 # 3) ?= (2 # 6). (* Eq : comparison *)
Close Scope Q_scope.
Compute ( (2 # 3) / (1 # 5) )%Q. (* 10 # 3 : Q *)
(*** Common data structures ***)
(* Many common data types are included in the standard library *)
(* The unit type has exactly one value, tt *)
Check tt. (* tt : unit *)
(* The option type is useful for expressing computations that might fail *)
Compute None. (* None : option ?A *)
Check Some 3. (* Some 3 : option nat *)
(* The type sum A B allows for values of either type A or type B *)
Print sum.
Check inl 3. (* inl 3 : nat + ?B *)
Check inr true. (* inr true : ?A + bool *)
Check sum bool nat. (* (bool + nat)%type : Set *)
Check (bool + nat)%type. (* Notation for sum *)
(* Tuples are (optionally) enclosed in parentheses, items are separated
by commas. *)
Check (1, true). (* (1, true) : nat * bool *)
Compute prod nat bool. (* (nat * bool)%type : Set *)
Definition my_fst {A B : Type} (x : A * B) : A := match x with
| (a,b) => a
end.
(* A destructuring let is available if a pattern match is irrefutable *)
Definition my_fst2 {A B : Type} (x : A * B) : A := let (a,b) := x in
a.
(*** Lists ***)
(* Lists are built by using cons and nil or by using notation available in
list_scope. *)
Compute cons 1 (cons 2 (cons 3 nil)). (* (1 :: 2 :: 3 :: nil)%list : list nat *)
Compute (1 :: 2 :: 3 :: nil)%list.
(* There is also list notation available in the ListNotations modules *)
Require Import List.
Import ListNotations.
Compute [1 ; 2 ; 3]. (* [1; 2; 3] : list nat *)
(* There is a large number of list manipulation functions available,
including:
• length
• head : first element (with default)
• tail : all but first element
• app : appending
• rev : reverse
• nth : accessing n-th element (with default)
• map : applying a function
• flat_map : applying a function returning lists
• fold_left : iterator (from head to tail)
• fold_right : iterator (from tail to head)
*)
Definition my_list : list nat := [47; 18; 34].
Compute List.length my_list. (* 3 : nat *)
(* All functions in coq must be total, so indexing requires a default value *)
Compute List.nth 1 my_list 0. (* 18 : nat *)
Compute List.map (fun x => x * 2) my_list. (* [94; 36; 68] : list nat *)
Compute List.filter (fun x => Nat.eqb (Nat.modulo x 2) 0) my_list.
(* [18; 34] : list nat *)
Compute (my_list ++ my_list)%list. (* [47; 18; 34; 47; 18; 34] : list nat *)
(*** Strings ***)
Require Import Strings.String.
(* Use double quotes for string literals. *)
Compute "hi"%string.
Open Scope string_scope.
(* Strings can be concatenated with the "++" operator. *)
Compute String.append "Hello " "World". (* "Hello World" : string *)
Compute "Hello " ++ "World". (* "Hello World" : string *)
(* Strings can be compared for equality *)
Compute String.eqb "Coq is fun!" "Coq is fun!". (* true : bool *)
Compute "no" =? "way". (* false : bool *)
Close Scope string_scope.
(*** Other Modules ***)
(* Other Modules in the standard library that may be of interest:
• Logic : Classical logic and dependent equality
• Arith : Basic Peano arithmetic
• PArith : Basic positive integer arithmetic
• NArith : Basic binary natural number arithmetic
• ZArith : Basic relative integer arithmetic
• Numbers : Various approaches to natural, integer and cyclic numbers
(currently axiomatically and on top of 2^31 binary words)
• Bool : Booleans (basic functions and results)
• Lists : Monomorphic and polymorphic lists (basic functions and results),
Streams (infinite sequences defined with co-inductive types)
• Sets : Sets (classical, constructive, finite, infinite, power set, etc.)
• FSets : Specification and implementations of finite sets and finite maps
(by lists and by AVL trees)
• Reals : Axiomatization of real numbers (classical, basic functions,
integer part, fractional part, limit, derivative, Cauchy series,
power series and results,...)
• Relations : Relations (definitions and basic results)
• Sorting : Sorted list (basic definitions and heapsort correctness)
• Strings : 8-bits characters and strings
• Wellfounded : Well-founded relations (basic results)
*)
(*** User-defined data types ***)
(* Because Coq is dependently typed, defining type aliases is no different
than defining an alias for a value. *)
Definition my_three : nat := 3.
Definition my_nat : Type := nat.
(* More interesting types can be defined using the Inductive vernacular.
Simple enumeration can be defined like so *)
Inductive ml := OCaml | StandardML | Coq.
Definition lang := Coq. (* Has type "ml". *)
(* For more complicated types, you will need to specify the types of the
constructors. *)
(* Type constructors don't need to be empty. *)
Inductive my_number := plus_infinity
| nat_value : nat -> my_number.
Compute nat_value 3. (* nat_value 3 : my_number *)
(* Record syntax is sugar for tuple-like types. It defines named accessor
functions for the components. Record types are defined with the notation
{...} *)
Record Point2d (A : Set) := mkPoint2d { x2 : A ; y2 : A }.
(* Record values are constructed with the notation {|...|} *)
Definition mypoint : Point2d nat := {| x2 := 2 ; y2 := 3 |}.
Compute x2 nat mypoint. (* 2 : nat *)
Compute mypoint.(x2 nat). (* 2 : nat *)
(* Types can be parameterized, like in this type for "list of lists of
anything". 'a can be substituted with any type. *)
Definition list_of_lists a := list (list a).
Definition list_list_nat := list_of_lists nat.
(* Types can also be recursive. Like in this type analogous to
built-in list of naturals. *)
Inductive my_nat_list :=
EmptyList | NatList : nat -> my_nat_list -> my_nat_list.
Compute NatList 1 EmptyList. (* NatList 1 EmptyList : my_nat_list *)
(** Matching type constructors **)
Inductive animal := Dog : string -> animal | Cat : string -> animal.
Definition say x :=
match x with
| Dog x => (x ++ " says woof")%string
| Cat x => (x ++ " says meow")%string
end.
Compute say (Cat "Fluffy"). (* "Fluffy says meow". *)
(** Traversing data structures with pattern matching **)
(* Recursive types can be traversed with pattern matching easily.
Let's see how we can traverse a data structure of the built-in list type.
Even though the built-in cons ("::") looks like an infix operator,
it's actually a type constructor and can be matched like any other. *)
Fixpoint sum_list l :=
match l with
| [] => 0
| head :: tail => head + (sum_list tail)
end.
Compute sum_list [1; 2; 3]. (* Evaluates to 6 *)
(*** A Taste of Proving ***)
(* Explaining the proof language is out of scope for this tutorial, but here
is a taste to whet your appetite. Check the resources below for more. *)
(* A fascinating feature of dependently type based theorem provers is that
the same primitive constructs underly the proof language as the
programming features. For example, we can write and prove the
proposition A and B implies A in raw Gallina *)
Definition my_theorem : forall A B, A /\ B -> A :=
fun A B ab => match ab with
| (conj a b) => a
end.
(* Or we can prove it using tactics. Tactics are a macro language to help
build proof terms in a more natural style and automate away some
drudgery. *)
Theorem my_theorem2 : forall A B, A /\ B -> A.
Proof.
intros A B ab. destruct ab as [ a b ]. apply a.
Qed.
(* We can prove easily prove simple polynomial equalities using the
automated tactic ring. *)
Require Import Ring.
Require Import Arith.
Theorem simple_poly : forall (x : nat), (x + 1) * (x + 2) = x * x + 3 * x + 2.
Proof. intros. ring. Qed.
(* Here we prove the closed form for the sum of all numbers 1 to n using
induction *)
Fixpoint sumn (n : nat) : nat :=
match n with
| 0 => 0
| (S n') => n + (sumn n')
end.
Theorem sum_formula : forall n, 2 * (sumn n) = (n + 1) * n.
Proof. intros n. induction n.
- reflexivity. (* 0 = 0 base case *)
- simpl. ring [IHn]. (* induction step *)
Qed.
```
With this we have only scratched the surface of Coq. It is a massive
ecosystem with many interesting and peculiar topics leading all the way up
to modern research.
## Further reading
* [The Coq reference manual](https://coq.inria.fr/refman/)
* [Software Foundations](https://softwarefoundations.cis.upenn.edu/)
* [Certified Programming with Dependent Types](http://adam.chlipala.net/cpdt/)
* [Mathematical Components](https://math-comp.github.io/mcb/)
* [Coq'Art: The Calculus of Inductive Constructions](http://www.cse.chalmers.se/research/group/logic/TypesSS05/resources/coq/CoqArt/)
* [FRAP](http://adam.chlipala.net/frap/)

View File

@@ -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/)

View File

@@ -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"]

View File

@@ -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
@@ -137,12 +138,14 @@ None # => None
"něco" is None # => False
None is None # => True
# None, 0, a prázdný řetězec/seznam/slovník se vyhodnotí jako False
# None, 0, a prázdný řetězec/seznam/N-tice/slovník/množina se vyhodnotí jako False
# Vše ostatní se vyhodnotí jako True
bool(0) # => False
bool("") # => False
bool([]) # => False
bool({}) # => False
bool(0) # => False
bool("") # => False
bool([]) # => False
bool(tuple()) # => False
bool({}) # => False
bool(set()) # => False
####################################################
@@ -602,18 +605,21 @@ dir(math)
# Generátory jsou funkce, které místo return obsahují yield
def nasobicka_2(sekvence):
for i in sekvence:
print("Zpracovávám číslo {}".format(i))
yield 2 * i
# Generátor generuje hodnoty postupně, jak jsou potřeba. Místo toho, aby vrátil
# celou sekvenci s prvky vynásobenými dvěma, provádí jeden výpočet v každé iteraci.
# To znamená, že čísla větší než 15 se v metodě nasobicka_2 vůbec nezpracují.
for nasobek in nasobicka_2([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]):
# Vypíše postupně: "Zpracovávám číslo 1", ..., "Zpracovávám číslo 5"
if nasobek >= 10:
break
# Funkce range() je také generátor - vytváření seznamu 900000000 prvků by zabralo
# hodně času i paměti, proto se místo toho čísla generují postupně.
for i in nasobicka_2(range(900000000)):
print(i) # Vypíše čísla 0, 2, 4, 6, 8, ... 30
if i >= 30:
for nasobek in nasobicka_2(range(900000000)):
# Vypíše postupně: "Zpracovávám číslo 1", ..., "Zpracovávám číslo 5"
if nasobek >= 10:
break
@@ -633,7 +639,7 @@ def nekolikrat(puvodni_funkce):
def pozdrav(jmeno):
print("Měj se {}!".format(jmeno))
pozdrav("Pepo") # Vypíše 3x: Měj se Pepo!
pozdrav("Pepo") # Vypíše 3x: "Měj se Pepo!"
```
## Co dál?

View File

@@ -14,20 +14,22 @@ filename: LearnCSharp.cs
C# is an elegant and type-safe object-oriented language that enables developers to build a variety of secure and robust applications that run on the .NET Framework.
[Read more here.](http://msdn.microsoft.com/en-us/library/vstudio/z1zx9t92.aspx)
[Read more here.](https://docs.microsoft.com/dotnet/csharp/getting-started/introduction-to-the-csharp-language-and-the-net-framework)
```c#
// Single-line comments start with //
/*
Multi-line comments look like this
*/
/// <summary>
/// This is an XML documentation comment which can be used to generate external
/// documentation or provide context help within an IDE
/// </summary>
/// <param name="firstParam">This is some parameter documentation for firstParam</param>
/// <returns>Information on the returned value of a function</returns>
//public void MethodOrClassOrOtherWithParsableHelp(string firstParam) {}
public void MethodOrClassOrOtherWithParsableHelp(string firstParam) {}
// Specify the namespaces this source code will be using
// The namespaces below are all part of the standard .NET Framework Class Library
@@ -254,7 +256,7 @@ on a new line! ""Wow!"", the masses cried";
int fooWhile = 0;
while (fooWhile < 100)
{
//Iterated 100 times, fooWhile 0->99
// Iterated 100 times, fooWhile 0->99
fooWhile++;
}
@@ -273,10 +275,10 @@ on a new line! ""Wow!"", the masses cried";
} while (fooDoWhile < 100);
//for loop structure => for(<start_statement>; <conditional>; <step>)
// for loop structure => for(<start_statement>; <conditional>; <step>)
for (int fooFor = 0; fooFor < 10; fooFor++)
{
//Iterated 10 times, fooFor 0->9
// Iterated 10 times, fooFor 0->9
}
// For Each Loop
@@ -287,7 +289,7 @@ on a new line! ""Wow!"", the masses cried";
// (The ToCharArray() could be removed, because a string also implements IEnumerable)
foreach (char character in "Hello World".ToCharArray())
{
//Iterated over all the characters in the string
// Iterated over all the characters in the string
}
// Switch Case
@@ -329,7 +331,7 @@ on a new line! ""Wow!"", the masses cried";
// Convert String To Integer
// this will throw a FormatException on failure
int.Parse("123");//returns an integer version of "123"
int.Parse("123"); // returns an integer version of "123"
// try parse will default to type default on failure
// in this case: 0
@@ -373,7 +375,7 @@ on a new line! ""Wow!"", the masses cried";
Console.Read();
} // End main method
// CONSOLE ENTRY A console application must have a main method as an entry point
// CONSOLE ENTRY - A console application must have a main method as an entry point
public static void Main(string[] args)
{
OtherInterestingFeatures();
@@ -404,7 +406,7 @@ on a new line! ""Wow!"", the masses cried";
ref int maxCount, // Pass by reference
out int count)
{
//the argument passed in as 'count' will hold the value of 15 outside of this function
// the argument passed in as 'count' will hold the value of 15 outside of this function
count = 15; // out param must be assigned before control leaves the method
}
@@ -552,7 +554,7 @@ on a new line! ""Wow!"", the masses cried";
}
// PARALLEL FRAMEWORK
// http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx
// https://devblogs.microsoft.com/csharpfaq/parallel-programming-in-net-framework-4-getting-started/
var words = new List<string> {"dog", "cat", "horse", "pony"};
@@ -564,11 +566,11 @@ on a new line! ""Wow!"", the masses cried";
}
);
//Running this will produce different outputs
//since each thread finishes at different times.
//Some example outputs are:
//cat dog horse pony
//dog horse pony cat
// Running this will produce different outputs
// since each thread finishes at different times.
// Some example outputs are:
// cat dog horse pony
// dog horse pony cat
// DYNAMIC OBJECTS (great for working with other languages)
dynamic student = new ExpandoObject();
@@ -651,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
@@ -725,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).
@@ -865,7 +867,7 @@ on a new line! ""Wow!"", the masses cried";
}
}
//Method to display the attribute values of this Object.
// Method to display the attribute values of this Object.
public virtual string Info()
{
return "Gear: " + Gear +
@@ -960,7 +962,7 @@ on a new line! ""Wow!"", the masses cried";
/// <summary>
/// Used to connect to DB for LinqToSql example.
/// EntityFramework Code First is awesome (similar to Ruby's ActiveRecord, but bidirectional)
/// http://msdn.microsoft.com/en-us/data/jj193542.aspx
/// https://docs.microsoft.com/ef/ef6/modeling/code-first/workflows/new-database
/// </summary>
public class BikeRepository : DbContext
{
@@ -1069,7 +1071,7 @@ on a new line! ""Wow!"", the masses cried";
{
private static bool LogException(Exception ex)
{
/* log exception somewhere */
// log exception somewhere
return false;
}
@@ -1089,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
@@ -1117,12 +1119,12 @@ on a new line! ""Wow!"", the masses cried";
[Obsolete("Use NewMethod instead", false)]
public static void ObsoleteMethod()
{
/* obsolete code */
// obsolete code
}
public static void NewMethod()
{
/* new code */
// new code
}
public static void Main()
@@ -1154,9 +1156,9 @@ namespace Learning.More.CSharp
}
}
//New C# 7 Feature
//Install Microsoft.Net.Compilers Latest from Nuget
//Install System.ValueTuple Latest from Nuget
// New C# 7 Feature
// Install Microsoft.Net.Compilers Latest from Nuget
// Install System.ValueTuple Latest from Nuget
using System;
namespace Csharp7
{
@@ -1213,7 +1215,7 @@ namespace Csharp7
Console.WriteLine(tt.GetLastName());
}
}
// PATTERN MATCHING
class PatternMatchingTest
{
@@ -1310,13 +1312,13 @@ namespace Csharp7
## Further Reading
* [C# language reference](https://docs.microsoft.com/dotnet/csharp/language-reference/)
* [Learn .NET](https://dotnet.microsoft.com/learn)
* [C# Coding Conventions](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions)
* [DotNetPerls](http://www.dotnetperls.com)
* [C# in Depth](http://manning.com/skeet2)
* [Programming C#](http://shop.oreilly.com/product/0636920024064.do)
* [LINQ](http://shop.oreilly.com/product/9780596519254.do)
* [MSDN Library](http://msdn.microsoft.com/en-us/library/618ayhy6.aspx)
* [ASP.NET MVC Tutorials](http://www.asp.net/mvc/tutorials)
* [ASP.NET Web Matrix Tutorials](http://www.asp.net/web-pages/tutorials)
* [ASP.NET Web Forms Tutorials](http://www.asp.net/web-forms/tutorials)
* [Programming C# 5.0](http://shop.oreilly.com/product/0636920024064.do)
* [LINQ Pocket Reference](http://shop.oreilly.com/product/9780596519254.do)
* [Windows Forms Programming in C#](http://www.amazon.com/Windows-Forms-Programming-Chris-Sells/dp/0321116208)
* [C# Coding Conventions](http://msdn.microsoft.com/en-us/library/vstudio/ff926074.aspx)
* [freeCodeCamp - C# Tutorial for Beginners](https://www.youtube.com/watch?v=GhQdlIFylQ8)

View File

@@ -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

View File

@@ -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

View File

@@ -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;
import "dart:math" as math;
// 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/
/// 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
// 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.
/// 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"};
example8() {
print(example8Array[0]);
print(example8Map["someKey"]);
/// Dart supports Generics.
/// Generics refers to the technique of writing the code for a class
/// without specifying the data type(s) that the class works on.
/// Source: https://stackoverflow.com/questions/4560890/what-are-generics-in-c
/// Type `T` refers to any type that has been instantiated
/// you can call whatever you want
/// Programmers uses the convention in the following
/// T - Type(used for class and primitype types)
/// E - Element(used for List, Set, or Iterable)
/// K,V - Key Value(used for Map)
class GenericExample<T>{
void printType(){
print("$T")
}
// methods can also have generics
genericMethod<M>(){
print("class:$T, method: $M");
}
}
// Loops in Dart take the form of standard for () {} or while () {} loops,
// slightly more modern for (.. in ..) {}, or functional callbacks with many
// supported features, starting with forEach.
/// List are similar to arrays but list is a child of Iterable<E>
/// Therefore Maps, List, LinkedList are all child of Iterable<E> to be able to loop using the keyword `for`
/// Important things to remember:
/// () - Iterable<E>
/// [] - List<E>
/// {} - Map<K,V>
/// List are great, but there's a restriction for what List can be
/// outside of function/method bodies. List on the outer scope of class
/// or outside of class have to be constant. Strings and numbers are constant
/// by default. But arrays and maps are not. They can be made constant by
/// declaring them "const". Kind of similar to Javascript's Object.freeze()
const example8List = ["Example8 const array"];
const example8Map = {"someKey": "Example8 const map"};
/// Declare List or Maps as Objects.
List<String> explicitList = new List<String>();
Map<String,dynamic> explicitMaps = new Map<String,dynamic>();
explicitList.add("SomeArray");
example8() {
print(example8Map["someKey"]);
print(explicitList[0]);
}
/// Assigning a list from one variable to another will not be the same result.
/// Because dart is pass-reference-by-value.
/// So when you assign an existing list to a new variable.
/// Instead of List, it becomes an Iterable
var iterableExplicitList = explicitList;
print(iterableExplicitList) // ("SomeArray"); "[]" becomes "()"
var newExplicitLists = explicitList.toList() // Converts Iterable<E> to List<E>
/// Loops in Dart take the form of standard for () {} or while () {} loops,
/// slightly more modern for (.. in ..) {}, or functional callbacks with many
/// supported features, starting with forEach,map and where.
var example9Array = const ["a", "b"];
example9() {
for (var i = 0; i < 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)

View File

@@ -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:
@@ -217,7 +217,7 @@ done
function foo ()
{
echo "Argumente funktionieren wie bei skripts: $@"
echo Und: $1 $2..."
echo "Und: $1 $2..."
echo "Dies ist eine Funktion"
return 0
}

102
de-de/bc.html.markdown Normal file
View File

@@ -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```.

View File

@@ -9,6 +9,7 @@ contributors:
- ["Ankush Goyal", "http://github.com/ankushg07"]
- ["Jatin Dhankhar", "https://github.com/jatindhankhar"]
- ["Maximilian Sonnenburg", "https://github.com/LamdaLamdaLamda"]
- ["caminsha", "https://github.com/caminsha"]
lang: de-de
---
@@ -22,9 +23,9 @@ entworfen wurde um,
- Objektorientierung zu unterstützen
- generische Programmierung zu unterstützen
Durch seinen Syntax kann sie durchaus schwieriger und komplexer als neuere Sprachen sein.
Durch seine Syntax kann sie durchaus schwieriger und komplexer als neuere Sprachen sein.
Sie ist weit verbreitet, weil sie in Maschinen-Code kompiliert, welches direkt vom Prozessor ausgeführt
Sie ist weit verbreitet, weil sie in Maschinen-Code kompiliert, welcher direkt vom Prozessor ausgeführt
werden kann und somit eine strikte Kontrolle über die Hardware bietet und gleichzeitig
High-Level-Features wie generics, exceptions und Klassen enthält.
@@ -36,7 +37,7 @@ weitverbreitesten Programmiersprachen.
// Vergleich zu C
//////////////////
// C ist fast eine Untermenge von C++ und teilt sich grundsätzlich den
// C ist fast eine Untermenge von C++ und teilt sich grundsätzlich die
// Syntax für Variablen Deklarationen, primitiven Typen und Funktionen.
// Wie in C ist der Programmeinsprungpunkt eine Funktion, welche "main" genannt wird und
@@ -137,7 +138,7 @@ void invalidDeclaration(int a = 1, int b) // Fehler!
/////////////
// Namespaces (Namesräume)
// Namespaces (Namensräume)
/////////////
// Namespaces stellen einen getrennten Gültigkeitsbereich für Variablen,
@@ -169,7 +170,7 @@ void foo()
int main()
{
// Fügt all Symbole aus dem namespace Second in den aktuellen Gültigkeitsbereich (scope).
// Fügt alle Symbole aus dem namespace Second in den aktuellen Gültigkeitsbereich (scope).
// "foo()" wird nun nicht länger funktionieren, da es nun doppeldeutig ist, ob foo aus
// dem namespace foo oder darüberliegenden aufgerufen wird.
using namespace Second;
@@ -283,7 +284,7 @@ string retVal = tempObjectFun();
// für Details). Wie in diesem Code:
foo(bar(tempObjectFun()))
// Nehmen wir an foo und bar existieren. Das Objekt wird von "tempObjectFun" zurückgegeben,
// Nehmen wir an, foo und bar existieren. Das Objekt wird von "tempObjectFun" zurückgegeben,
// wird an bar übergeben und ist zerstört bevor foo aufgerufen wird.
// Zurück zu Referenzen. Die Annahme, dass die "am Ende des Ausdrucks" Regel gültig ist,
@@ -335,7 +336,7 @@ ECarTypes GetPreferredCarType()
return ECarTypes::Hatchback;
}
// Mit C++11 existiert eine einfache Möglichkeit einem Typ dem Enum zu zuweisen. Dies
// Mit C++11 existiert eine einfache Möglichkeit einem Typ dem Enum zuzuweisen. Dies
// kann durchaus sinnvoll bei der Serialisierung von Daten sein, oder bei der Konvertierung
// zwischen Typen bzw. Konstanten.
enum ECarTypes : uint8_t
@@ -574,7 +575,7 @@ int main ()
// Templates in C++ werden in erster Linie dafür verwendet generisch zu programmieren.
// Sie unterstützen explizite und partielle Spezialisierung und darüber hinaus können
// sie für funktionale Klassen verwendet werden.
// Tatsächlich bilden templates die Turing-Vollständigkeit
// Tatsächlich bilden Templates die Turing-Vollständigkeit
// (universelle Programmierbarkeit) ab.
@@ -588,12 +589,12 @@ public:
void insert(const T&) { ... }
};
// Während der Kompilierung generiert der Compiler Kopien für jedes template, wobei
// Während der Kompilierung generiert der Compiler Kopien für jedes Template, wobei
// hierbei die Parameter substituiert werden. Somit muss bei jedem Aufruf die gesamte
// Definition der Klasse zur Verfügung stehen. Aus diesem Grund wird ein Template
// komplett im header definiert.
// Erzeugung einer Template-Klasse auf dem stack:
// Erzeugung einer Template-Klasse auf dem Stack:
Box<int> intBox;
// eine der zu erwartenden Verwendungen:
@@ -612,7 +613,7 @@ boxOfBox.insert(intBox);
// sind fast identisch hinsichtlich der Funktionalität. Weitere
// Informationen auf: http://en.wikipedia.org/wiki/Typename
// Eine template-Funktion:
// Eine Template-Funktion:
template<class T>
void barkThreeTimes(const T& input)
{
@@ -622,7 +623,7 @@ void barkThreeTimes(const T& input)
}
// Hierbei ist zu beachten, dass an dieser Stelle nichts über den Typen des Parameters
// definiert wurde. Der Kompiler wird bei jedem Aufruf bzw. jeder Erzeugung den Typen
// definiert wurde. Der Compiler wird bei jedem Aufruf bzw. jeder Erzeugung den Typen
// prüfen. Somit funktioniert die zuvor definierte Funktion für jeden Typ 'T', die die
// const Methode 'bark' implementiert hat.
@@ -637,10 +638,10 @@ void printMessage()
cout << "Learn C++ in " << Y << " minutes!" << endl;
}
// Des Weiteren können templates aus Effizienzgründen genauer spezifiziert werden.
// Selbstverständlich sind reale-Problemen, welche genauer spezifiziert werden nicht
// Des Weiteren können Templates aus Effizienzgründen genauer spezifiziert werden.
// Selbstverständlich sind reale Probleme, welche genauer spezifiziert werden, nicht
// derart trivial. Auch wenn alle Parameter explizit definiert wurden, muss die
// Funktion oder Klasse als template deklariert werden.
// Funktion oder Klasse als Template deklariert werden.
template<>
void printMessage<10>()
{
@@ -818,9 +819,9 @@ void doSomethingWithAFile(const std::string& filename)
// Container
/////////////////////
// Die Container der Standard template Bibliothek beinhaltet einige vordefinierter templates.
// Die Container der Standard template Bibliothek beinhaltet einige vordefinierte Templates.
// Diese verwalten die Speicherbereiche für die eigenen Elemente und stellen Member-Funktionen
// für den Zugriff und die Maniplulation bereit.
// für den Zugriff und die Manipulation bereit.
// Beispielhafte Container:
@@ -876,7 +877,7 @@ for(it=ST.begin();it<ST.end();it++)
// 10
// 30
// Zum leeren des gesamten Container wird die Methode
// Zum leeren des gesamten Containers wird die Methode
// Container._name.clear() verwendet.
ST.clear();
cout << ST.size(); // Ausgabe der Set-Größe
@@ -948,11 +949,11 @@ fooMap.find(Foo(1)); // Wahr
// Lambda Ausdrücke (C++11 und höher)
///////////////////////////////////////
// Lambdas sind eine gängige Methodik um anonyme Funktionen an dem
// Lambdas sind eine gängige Methodik, um anonyme Funktionen an dem
// Ort der Verwendung zu definieren. Darüber hinaus auch bei der
// Verwendung von Funktionen als Argument einer Funktion.
// Nehmen wir an es soll ein Vektor von "pairs" (Paaren) mithilfe
// Nehmen wir an, es soll ein Vektor von "pairs" (Paaren) mithilfe
// des zweiten Werts des "pairs" sortiert werden.
vector<pair<int, int> > tester;
@@ -966,7 +967,7 @@ sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int,
return lhs.second < rhs.second;
});
// Beachte den Syntax von Lambda-Ausdrücken.
// Beachte die Syntax von Lambda-Ausdrücken.
// Die [] im Lambda Ausdruck werden für die Variablen verwendet.
// Diese so genannte "capture list" definiert, was außerhalb des Lambdas,
// innerhalb der Funktion verfügbar sein soll und in welcher Form.
@@ -1025,7 +1026,7 @@ for(auto elem: arr)
// Einige Aspekte von C++ sind für Neueinsteiger häufig überraschend (aber auch für
// C++ Veteranen).
// Der nachfolgende Abschnitt ist leider nicht vollständig:
// C++ ist eine der Sprachen, bei der es ein leichtes ist sich selbst ins Bein zu schießen.
// C++ ist eine der Sprachen, bei der es ein Leichtes ist, sich selbst ins Bein zu schießen.
// Private-Methoden können überschrieben werden
class Foo
@@ -1074,10 +1075,10 @@ f1 = f2;
#include<tuple>
// Konzeptionell sind Tuple´s alten Datenstrukturen sehr ähnlich, allerdings haben diese keine
// Konzeptionell sind Tupel alten Datenstrukturen sehr ähnlich, allerdings haben diese keine
// bezeichneten Daten-Member, sondern werden durch die Reihenfolge angesprochen.
// Erstellen des Tuples und das Einfügen eines Werts.
// Erstellen des Tupels und das Einfügen eines Werts.
auto first = make_tuple(10, 'A');
const int maxN = 1e9;
const int maxL = 15;
@@ -1102,7 +1103,7 @@ tuple<int, char, double> third(11, 'A', 3.14141);
cout << tuple_size<decltype(third)>::value << "\n"; // prints: 3
// tuple_cat fügt die Elemente eines Tuples aneinander (in der selben Reihenfolge).
// tuple_cat fügt die Elemente eines Tupels aneinander (in der selben Reihenfolge).
auto concatenated_tuple = tuple_cat(first, second, third);
// concatenated_tuple wird zu = (10, 'A', 1e9, 15, 11, 'A', 3.14141)

869
de-de/c-de.html.markdown Normal file
View File

@@ -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)

View File

@@ -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/)

View File

@@ -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:

View File

@@ -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);

View File

@@ -0,0 +1,380 @@
---
language: Dhall
contributors:
- ["Gabriel Gonzalez", "http://www.haskellforall.com/"]
translators:
- ["Profpatsch", "http://profpatsch.de"]
filename: learndhall-de.py
lang: de-de
---
Dhall ist eine programmierbare Konfigurationssprache und bietet eine
nicht-repetetive Alternative zu YAML.
Man kann Dhall sehen als: JSON + Funktionen + Typen + Importsystem
Obwohl Dhall programmierbar ist, ist die Sprache nicht
turingvollständig. Viele von Dhalls Features benutzen diese
Einschränkung, um stärkere Sicherheitsgarantien zu bieten und besseres
Tooling zu ermöglichen.
```haskell
-- einzeiliger Kommentar
{- mehrzeiliger Kommentar
Unicode funktioniert 🙂
Diese Datei ist eine valide Dhall-Expression und evaluiert zu einem
großen Record, welcher die Ergebnisse jedes Schritts beinhaltet.
Das Ergebnis kann angezeigt werden, indem man die Datei evaluiert:
$ dhall --file learndhall.dhall
{- Kommentare können verschachtelt sein -}
-}
let greeting = "Hallo, Welt!"
let fruits = "🍋🍓🍍🍉🍌"
let interpolation = "Ein paar leckere Früchte: ${fruits}"
let multilineText {- Inline-Kommentare funktionieren ebenfalls -} =
''
In Multiline-Text-Literals wird Whitespace am Anfang der Zeile
entfernt.
Das bedeutet Text kann frei eingerückt oder ausgerückt werden,
ohne dass sich der Inhalt des Strings ändert.
Relative Einrückungen bleiben erhalten.
Ansonsten wird das Text-Literal verbatim erhalten, ähnlich
zu literal-Multiline-Strings in YAML.
''
let bool = True
-- Typannotationen für Bindings sind optional, aber hilfreich, also
-- benutzen wir sie hier.
let annotation : Bool = True
let renderedBool : Text = if bool then "True" else "False"
-- Natürliche Zahlen sind nicht-negativ und vorzeichenlos.
let naturalNumber : Natural = 42
-- Integer können negativ sein, brauchen aber ein explizites Vorzeichen.
let positiveInteger : Integer = +1
let negativeInteger : Integer = -12
let pi : Double = 3.14159265359
{- Identifier dürfen eine große Anzahl an verschiedenen Zeichen
beinhalten (wie z.B. Anführungszeichen oder Whitespace), wenn man
sie mit Backticks umschließt.
-}
let `Avogadro's Number` : Double = 6.0221409e+23
let origin : { x : Double, y : Double } = { x = 0.0, y = 0.0 }
let somePrimes : List Natural = [ 2, 3, 5, 7, 11 ]
{- Ein Schema ist das gleiche wie ein Typ.
Typnamen beginnen konventionell mit einem Großbuchstaben, was
jedoch nicht erzwungen wird.
-}
let Profile : Type
= { person :
{ name : Text
, age : Natural
}
, address :
{ country : Text
, state : Text
, city : Text
}
}
let bernd : Profile =
{ person =
{ name = "Bernd Lauert"
, age = 67
}
, address =
{ country = "Deutschland"
, state = "Bayern"
, city = "Augsburg"
}
}
let augsburg : Text = bernd.address.city
{- Enum-Alternativen beginnen konventionell auch mit einem
Großbuchstaben. Das wird ebenfalls nicht erzwungen.
-}
let DNA : Type = < Adenine | Cytosine | Guanine | Thymine >
let dnaSequence : List DNA = [ DNA.Thymine, DNA.Guanine, DNA.Guanine ]
let compactDNASequence : List DNA =
let a = DNA.Adenine
let c = DNA.Cytosine
let g = DNA.Guanine
let t = DNA.Thymine
in [ c, t, t, a, t, c, g, g, c ]
-- Enums werden transformiert, indem man einen Record mit einem Feld
-- pro Alternative angibt.
let theLetterG : Text =
merge
{ Adenine = "A"
, Cytosine = "C"
, Guanine = "G"
, Thymine = "T"
}
DNA.Guanine
let presentOptionalValue : Optional Natural = Some 1
let absentOptionalValue : Optional Natural = None Natural
let points : List { x : Double, y : Double } =
[ { x = 1.1, y = -4.2 }
, { x = 4.4, y = -3.0 }
, { x = 8.2, y = -5.5 }
]
{- `Natural -> List Natural` ist der Funktionstyp mit Eingabetyp
`Natural` und Ausgabetyp `List Natural`.
Alle Funktionen in Dhall sind Anonyme Funktionen (aka. „Lambdas“),
denen man optional einen Namen geben kann.
Die folgende Funktion beispielsweise ist äquivalent zu diesem
Python Code:
lambda n : [ n, n + 1 ]
... und diesem Javascript Code:
function (n) { return [ n, n + 1 ]; }
-}
let exampleFunction : Natural -> List Natural =
\(n : Natural) -> [ n, n + 1 ]
-- Dhall unterstützt auch Unicode-Syntax, aber dieses Tutorial nutzt
-- die ASCII-Syntax.
let unicodeFunction : Natural List Natural =
λ(n : Natural) [ n, n + 1 ]
-- Funktionsargumente brauchen keine Klammern.
let exampleFunctionApplication : List Natural =
exampleFunction 2
let functionOfMultipleArguments : Natural -> Natural -> List Natural =
\(x : Natural) -> \(y : Natural) -> [ x, y ]
let functionAppliedToMultipleArguments : List Natural =
functionOfMultipleArguments 2 3
{- Wie `exampleFunction`, aber wir geben dem Eingabetypen
einen Namen, `n`.
-}
let namedArgumentType : forall (n : Natural) -> List Natural =
\(n : Natural) -> [ n, n + 1 ]
{- Bekommt der Eingabetyp einen Namen, kann man ihn weiter hinten in
der gleichen Typdefinition wiederverwenden.
Das ermöglicht Funktionen, die mit mehr als einem Eingabetypen
arbeiten können (aka. „polymorphe“ Funktionen).
-}
let duplicate : forall (a : Type) -> a -> List a =
\(a : Type) -> \(x : a) -> [ x, x ]
let duplicatedNumber : List Natural =
duplicate Natural 2
let duplicatedBool : List Bool =
duplicate Bool False
{- Die Sprache hat auch eine handvoll eingebauter polymorpher
Funktionen, wie zum Beispiel:
List/head : forall (a : Type) -> List a -> Optional a
-}
let firstPrime : Optional Natural = List/head Natural somePrimes
let functionOfARecord : { x : Natural, y : Natural } -> List Natural =
\(args : { x : Natural, y : Natural }) -> [ args.x, args.y ]
let functionAppliedToARecord : List Natural =
functionOfARecord { x = 2, y = 5 }
{- Alle Typkonversionen sind explizit.
`Natural/show` ist eine eingebaute Funktion mit dem Typ:
Natural/show : Natural -> Text
... welche `Natural`s in ihre `Text`-Repräsentation konvertiert.
-}
let typeConversion : Natural -> Text =
\(age : Natural) -> "Ich bin ${Natural/show age} Jahre alt!"
-- Ein „Template“ ist einfach eine Funktion mit Ausgabetyp `Text`.
let mitLicense : { year : Natural, copyrightHolder : Text } -> Text =
\(args : { year : Natural, copyrightHolder : Text }) ->
''
Copyright ${Natural/show args.year} ${args.copyrightHolder}
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
''
-- Template-Instanziierung ist das gleiche wie Funktionsanwendung.
let templatedLicense : Text =
mitLicense { year = 2019, copyrightHolder = "Jane Smith" }
{- Expressions können via URL importiert werden.
Ähnlich wie in Bash kann man Code aus dem lokalen Dateisystem
importieren (wird nicht gezeigt).
Sicherheitsbewusste Nutzer können via URLs importierte Expressions
mit einem semantischen Integritätscheck versehen („pinnen“).
Für gepinnte Imports wird der Dhall-Interpreter jeden Versuch
vereiteln, auf der Remote-Seite die Expression zu manipulieren.
Jedoch werden Änderungen, die den Inhalt der importierten
Expression nicht verändern trotzdem akzeptiert.
Auf diese Weise gepinnte Expressions werden auch in einem
Content-Adressable Store lokal gecached (standardmäßig in
`~/.cache/dhall`).
-}
let Natural/sum : List Natural -> Natural =
https://prelude.dhall-lang.org/Natural/sum
sha256:33f7f4c3aff62e5ecf4848f964363133452d420dcde045784518fb59fa970037
let twentyEight : Natural = Natural/sum somePrimes
-- Ein „Paket“ ist einfach ein (möglicherweise verschachtelter)
-- Record, den man importiert.
let Prelude = https://prelude.dhall-lang.org/package.dhall
let false : Bool = Prelude.Bool.not True
-- Durch das Anhängen von `as Text` wird eine Datei verbatim
-- importiert und nicht als Dhall-Code interpretiert.
let sourceCode : Text = https://prelude.dhall-lang.org/Bool/not as Text
-- Environment-Variablen können auch imortiert werden.
let presentWorkingDirectory = env:PWD as Text
-- Mit `?` kann man eine “Fallback-Expression” angeben, für den Fall
-- dass ein Import fehlschlägt.
let home : Optional Text = Some env:HOME ? None Text
-- Fallback-Expressions können auch alternative Imports enthalten.
let possiblyCustomPrelude =
env:DHALL_PRELUDE
? https://prelude.dhall-lang.org/package.dhall
{- Ein ausführliches Beispiel, welches mithilfe der
`generate`-Funktion eine Konfiguration für 10 Build-User generiert:
Prelude.List.generate
: Natural -> forall (a : Type) -> (Natural -> a) -> List a
-}
let buildUsers =
let makeUser = \(user : Text) ->
let home = "/home/${user}"
let privateKey = "${home}/.ssh/id_ed25519"
let publicKey = "${privateKey}.pub"
in { home = home
, privateKey = privateKey
, publicKey = publicKey
}
let buildUser =
\(index : Natural) -> makeUser "build${Natural/show index}"
let Config =
{ home : Text
, privateKey : Text
, publicKey : Text
}
in Prelude.List.generate 10 Config buildUser
-- Alle Ergebnisse in einem großen Record
in { greeting = greeting
, fruits = fruits
, interpolation = interpolation
, multilineText = multilineText
, bool = bool
, annotation = annotation
, renderedBool = renderedBool
, naturalNumber = naturalNumber
, positiveInteger = positiveInteger
, negativeInteger = negativeInteger
, pi = pi
, `Avogadro's Number` = `Avogadro's Number`
, origin = origin
, somePrimes = somePrimes
, bernd = bernd
, augsburg = augsburg
, dnaSequence = dnaSequence
, compactDNASequence = compactDNASequence
, theLetterG = theLetterG
, presentOptionalValue = presentOptionalValue
, absentOptionalValue = absentOptionalValue
, points = points
, exampleFunction = exampleFunction
, unicodeFunction = unicodeFunction
, exampleFunctionApplication = exampleFunctionApplication
, functionOfMultipleArguments = functionOfMultipleArguments
, functionAppliedToMultipleArguments = functionAppliedToMultipleArguments
, namedArgumentType = namedArgumentType
, duplicate = duplicate
, duplicatedNumber = duplicatedNumber
, duplicatedBool = duplicatedBool
, firstPrime = firstPrime
, functionOfARecord = functionOfARecord
, functionAppliedToARecord = functionAppliedToARecord
, typeConversion = typeConversion
, mitLicense = mitLicense
, templatedLicense = templatedLicense
, twentyEight = twentyEight
, false = false
, sourceCode = sourceCode
, presentWorkingDirectory = presentWorkingDirectory
, home = home
, buildUsers = buildUsers
}
```
Mehr Infos und Lernmaterialien gibt es auf der offiziellen Website
(Englisch), auf der man Dhall auf im Browser ausprobieren kann:
* [https://dhall-lang.org](http://dhall-lang.org/)

376
de-de/elm-de.html.markdown Normal file
View File

@@ -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).

View File

@@ -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>

View File

@@ -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**

View File

@@ -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

View File

@@ -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

View File

@@ -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))

View File

@@ -8,11 +8,11 @@ translators:
lang: de-de
---
Nix ist eine simple funktionale Programmiersprache, die für den
Nix ist eine simple funktionale Programmiersprache, die für den
[Nix package manager](https://nixos.org/nix/) und
[NixOS](https://nixos.org/) entwickelt wurde.
Du kannst Nix Ausdrücke evaluieren mithilfe von
Du kannst Nix Ausdrücke evaluieren mithilfe von
[nix-instantiate](https://nixos.org/nix/manual/#sec-nix-instantiate)
oder [`nix-repl`](https://github.com/edolstra/nix-repl).
@@ -24,7 +24,7 @@ with builtins; [
# Inline Kommentare sehen so aus.
/* Multizeilen Kommentare
/* Multizeilen Kommentare
sehen so aus. */
@@ -61,7 +61,7 @@ with builtins; [
"String Literale sind in Anführungszeichen."
"
String Literale können mehrere
String Literale können mehrere
Zeilen umspannen.
"
@@ -95,7 +95,7 @@ with builtins; [
tutorials/learn.nix
#=> /the-base-path/tutorials/learn.nix
# Ein Pfad muss mindestens einen Schrägstrich enthalten. Ein Pfad für eine
# Ein Pfad muss mindestens einen Schrägstrich enthalten. Ein Pfad für eine
# Datei im selben Verzeichnis benötigt ein ./ Präfix.
./learn.nix
#=> /the-base-path/learn.nix
@@ -238,7 +238,7 @@ with builtins; [
#=> { d = 2; e = 3; }
# Die Nachkommen eines Attributs können in diesem Feld nicht zugeordnet werden, wenn
# das Attribut selbst nicht zugewiesen wurde.
# das Attribut selbst nicht zugewiesen wurde.
{
a = { b = 1; };
a.c = 2;
@@ -261,9 +261,9 @@ with builtins; [
#=> 7
# Die erste Linie diese Tutorials startet mit "with builtins;",
# weil builtins ein Set mit allen eingebauten
# weil builtins ein Set mit allen eingebauten
# Funktionen (length, head, tail, filter, etc.) umfasst.
# Das erspart uns beispielsweise "builtins.length" zu schreiben,
# Das erspart uns beispielsweise "builtins.length" zu schreiben,
# anstatt nur "length".
@@ -305,7 +305,7 @@ with builtins; [
(tryEval (abort "foo"))
#=> error: evaluation aborted with the following error message: foo
# `assert` evaluiert zu dem gegebenen Wert, wenn die Bedingung wahr ist, sonst
# `assert` evaluiert zu dem gegebenen Wert, wenn die Bedingung wahr ist, sonst
# löst es eine abfangbare Exception aus.
(assert 1 < 2; 42)
#=> 42
@@ -319,7 +319,7 @@ with builtins; [
#=========================================
# Da die Wiederholbarkeit von Builds für den Nix Packetmanager entscheidend ist,
# werden in der Nix Sprache reine funktionale Elemente betont. Es gibt aber ein paar
# werden in der Nix Sprache reine funktionale Elemente betont. Es gibt aber ein paar
# unreine Elemente.
# Du kannst auf Umgebungsvariablen verweisen.
(getEnv "HOME")
@@ -355,4 +355,4 @@ with builtins; [
(https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55)
* [Susan Potter - Nix Cookbook - Nix By Example]
(http://funops.co/nix-cookbook/nix-by-example/)
(https://ops.functionalalgebra.com/nix-by-example/)

View File

@@ -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.

View File

@@ -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)

208
de-de/pug-de.html.markdown Normal file
View File

@@ -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)

View File

@@ -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
# 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
# Eine Division kann mit "//" für positive sowie negative Werte abgerundet werden.
5 // 3 # => 1
5.0 // 3.0 # => 1.0 # funktioniert auch mit floats
-5 // 3 # => -2
-5.0 // 3.0 # => -2.0
# Benutzt man eine Gleitkommazahl, ist auch das Ergebnis eine solche
3 * 2.0 # => 6.0
# Der Rest einer Division
7 % 3 # => 1
# 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")
# 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")
# 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"
# 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
# Eine Instanz einer Klasse erstellen
i = Human(name="Ian")
print(i.say("hi")) # gibt "Ian: hi" aus
    # Damit kann die Eigenschaft gelöscht werden
@age.deleter
def age(self):
del self._age
j = Human("Joel")
print(j.say("hello")) #gibt "Joel: hello" aus
# 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 mal unsere Klassenmethode auf
i.get_species() #=> "H. sapiens"
# Rufen wir unsere Klassenmethode auf
i.say(i.get_species()) # "Ian: H. sapiens"
# Ändern wir mal das gemeinsame Attribut
Human.species = "H. neanderthalensis"
i.get_species() #=> "H. neanderthalensis"
j.get_species() #=> "H. neanderthalensis"
# Ä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*"
# Aufruf der statischen Methode
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
## 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.
# And its own method as well
def sonar(self):
return '))) ... ((('
# Wir können auch die Funktionen und Attribute eines
# Moduls herausfinden.
import math
dir(math)
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)

View File

@@ -1,655 +0,0 @@
---
language: python3
contributors:
- ["Louie Dinh", "http://ldinh.ca"]
translators:
- ["kultprok", "http:/www.kulturproktologie.de"]
- ["matthiaskern", "https://github.com/matthiaskern"]
filename: learnpython3-de.py
lang: de-de
---
Anmerkungen des ursprünglichen Autors:
Python wurde in den frühen Neunzigern von Guido van Rossum entworfen. Es ist heute eine der beliebtesten Sprachen. Ich habe mich in Python wegen seiner syntaktischen Übersichtlichkeit verliebt. Eigentlich ist es ausführbarer Pseudocode.
Feedback ist herzlich willkommen! Ihr erreicht mich unter [@louiedinh](http://twitter.com/louiedinh) oder louiedinh [at] [google's email service].
Hinweis: Dieser Beitrag bezieht sich insplizit auf Python 3. Falls du lieber Python 2.7 lernen möchtest, schau [hier](http://learnxinyminutes.com/docs/python/) weiter.
```python
# Einzeilige Kommentare beginnen mit einer Raute (Doppelkreuz)
""" Mehrzeilige Strings werden mit
drei '-Zeichen geschrieben und werden
oft als Kommentare genutzt.
"""
####################################################
## 1. Primitive Datentypen und Operatoren
####################################################
# Die Zahlen
3 #=> 3
# Mathematik funktioniert so, wie man das erwartet
1 + 1 #=> 2
8 - 1 #=> 7
10 * 2 #=> 20
# Außer Division, welche automatisch Gleitkommazahlen zurückgibt
35 / 5 # => 7.0
# Eine Division kann mit "//" für positive sowie negative Werte abgerundet werden.
5 // 3 # => 1
5.0 // 3.0 # => 1.0 # works on floats too
-5 // 3 # => -2
-5.0 // 3.0 # => -2.0
# Benutzt man eine Gleitkommazahl, ist auch das Ergebnis eine solche
3 * 2.0 # => 6.0
# Der Rest einer Division
7 % 3 # => 1
# Potenz
2**4 # => 16
# Rangfolge wird mit Klammern erzwungen
(1 + 3) * 2 #=> 8
# Boolesche Ausdrücke sind primitive Datentypen
True
False
# Mit not wird negiert
not True #=> False
not False #=> True
# Boolesche Operatoren
# Hinweis: "and" und "or" müssen klein geschrieben werden
True and False #=> False
False or True #=> True
# Für die Benutzung von Booleschen Operatoren und ganzen Zahlen
0 and 2 #=> 0
-5 or 0 #=> -5
0 == False #=> True
2 == True #=> False
1 == True #=> True
# Gleichheit ist ==
1 == 1 #=> True
2 == 1 #=> False
# Ungleichheit ist !=
1 != 1 #=> False
2 != 1 #=> True
# Ein paar weitere Vergleiche
1 < 10 #=> True
1 > 10 #=> False
2 <= 2 #=> True
2 >= 2 #=> True
# Vergleiche können verknüpft werden!
1 < 2 < 3 #=> True
2 < 3 < 2 #=> False
# Strings werden mit " oder ' gebildet
"Das ist ein String."
'Das ist auch ein String.'
# Strings können auch addiert werden! Vermeide dies aber lieber.
"Hallo " + "Welt!" #=> "Hallo Welt!"
# Strings können ohne "+" addiert werden
"Hallo " "welt!" # => "Hallo Welt!"
# Ein String kann wie eine Liste von Zeichen verwendet werden
"Das ist ein String"[0] #=> 'D'
# .format kann Strings formatieren
"{} können {} werden".format("Strings", "formatiert")
# Schneller geht das mit Wiederholungen
"{0} mag Spagetthi, {0} liebt es zu Schwimmen und ganz besonders mag {0} {1}".format("Hans", "Blattsalat")
#=> "Hans mag Spagetthi, Hans liebt es zu Schwimmen und ganz besonders mag Hans Blattsalat"
# Wir können Schlüsselwörter verwenden, wenn wir nicht abzählen wollen.
"{name} will {food} essen".format(name="Bob", food="Lasagne")
#=> "Bob will Lasagne kochen"
#Falls dein Python 3 Code auch unter Python 2.5 oder darunter laufen soll, kann das alte Format benutzt werden:
"%s können %s werden" % ("Strings", "interpoliert")
# None ist ein Objekt
None #=> None
# Verwendet nicht das Symbol für Gleichheit `==`, um Objekte mit None zu vergleichen
# Benutzt stattdessen `is`. Dieser Operator testet Objektidentität
"etc" is None #=> False
None is None #=> True
# None, 0, und leere Strings/Listen werden alle als False bewertet.
# Alle anderen Werte sind True
bool(0) # => False
bool("") # => False
bool([]) #=> False
bool({}) #=> False
####################################################
## 2. Variablen und Collections
####################################################
# Textausgabe ist sehr einfach
print("Ich bin Python. Schön, dich kennenzulernen!")
# Es gibt keinen Grund, Variablen vor der Zuweisung zu deklarieren.
some_var = 5 # kleinschreibung_mit_unterstrichen entspricht der Norm
some_var #=> 5
# Das Ansprechen einer noch nicht 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)

View File

@@ -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)

File diff suppressed because it is too large Load Diff

282
de-de/vim-de.html.markdown Normal file
View File

@@ -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)

View File

@@ -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

View File

@@ -11,7 +11,7 @@ alternative to YAML.
You can think of Dhall as: JSON + functions + types + imports
Note that while Dhall is programmable, Dhall is not Turing-complete. Many
of Dhall's features take advantage of this restriction to provider stronger
of Dhall's features take advantage of this restriction to provide stronger
safety guarantees and more powerful tooling.
```haskell
@@ -216,7 +216,7 @@ let functionAppliedToARecord : List Natural =
let typeConversion : Natural -> Text =
\(age : Natural) -> "I am ${Natural/show age} years old!"
-- A template is the same thing as a function whose output type is `Text`
-- A "template" is the same thing as a function whose output type is `Text`
let mitLicense : { year : Natural, copyrightHolder : Text } -> Text =
\(args : { year : Natural, copyrightHolder : Text }) ->
''
@@ -263,7 +263,7 @@ let Natural/sum : List Natural -> Natural =
let twentyEight : Natural = Natural/sum somePrimes
-- A package is the same thing as a (possibly nested) record that you can import
-- A "package" is the same thing as a (possibly nested) record that you can import
let Prelude = https://prelude.dhall-lang.org/package.dhall
let false : Bool = Prelude.Bool.not True

827
directx9.html.markdown Normal file
View File

@@ -0,0 +1,827 @@
---
category: tool
tool: DirectX 9
filename: learndirectx9.cpp
contributors:
- ["Simon Deitermann", "s.f.deitermann@t-online.de"]
---
**Microsoft DirectX** is a collection of application programming interfaces (APIs) for handling tasks related to
multimedia, especially game programming and video, on Microsoft platforms. Originally, the names of these APIs
all began with Direct, such as Direct3D, DirectDraw, DirectMusic, DirectPlay, DirectSound, and so forth. [...]
Direct3D (the 3D graphics API within DirectX) is widely used in the development of video games for Microsoft
Windows and the Xbox line of consoles.<sup>[1]</sup>
In this tutorial we will be focusing on DirectX 9, which is not as low-level as it's sucessors, which are aimed at programmers very familiar with how graphics hardware works. It makes a great starting point for learning Direct3D. In this tutorial I will be using the Win32-API for window handling and the DirectX 2010 SDK.
## Window creation
```cpp
#include <Windows.h>
bool _running{ false };
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
// Handle incoming message.
switch (msg) {
// Set running to false if the user tries to close the window.
case WM_DESTROY:
_running = false;
PostQuitMessage(0);
break;
}
// Return the handled event.
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) {
// Set window properties we want to use.
WNDCLASSEX wndEx{ };
wndEx.cbSize = sizeof(WNDCLASSEX); // structure size
wndEx.style = CS_VREDRAW | CS_HREDRAW; // class styles
wndEx.lpfnWndProc = WndProc; // window procedure
wndEx.cbClsExtra = 0; // extra memory (struct)
wndEx.cbWndExtra = 0; // extra memory (window)
wndEx.hInstance = hInstance; // module instance
wndEx.hIcon = LoadIcon(nullptr, IDI_APPLICATION); // icon
wndEx.hCursor = LoadCursor(nullptr, IDC_ARROW); // cursor
wndEx.hbrBackground = (HBRUSH) COLOR_WINDOW; // background color
wndEx.lpszMenuName = nullptr; // menu name
wndEx.lpszClassName = "DirectXClass"; // register class name
wndEx.hIconSm = nullptr; // small icon (taskbar)
// Register created class for window creation.
RegisterClassEx(&wndEx);
// Create a new window handle.
HWND hWnd{ nullptr };
// Create a new window handle using the registered class.
hWnd = CreateWindow("DirectXClass", // registered class
"directx window", // window title
WS_OVERLAPPEDWINDOW, // window style
50, 50, // x, y (position)
1024, 768, // width, height (size)
nullptr, // parent window
nullptr, // menu
hInstance, // module instance
nullptr); // struct for infos
// Check if a window handle has been created.
if (!hWnd)
return -1;
// Show and update the new window.
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// Start the game loop and send incoming messages to the window procedure.
_running = true;
MSG msg{ };
while (_running) {
while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
}
```
This should create a window, that can the moved, resized and closed.
## Direct3D initialization
```cpp
// Includes DirectX 9 structures and functions.
// Remember to link "d3d9.lib" and "d3dx9.lib".
// For "d3dx9.lib" the DirectX SDK (June 2010) is needed.
// Don't forget to set your subsystem to Windows.
#include <d3d9.h>
#include <d3dx9.h>
// Includes the ComPtr, a smart pointer automatically releasing COM objects.
#include <wrl.h>
using namespace Microsoft::WRL;
// Next we define some Direct3D9 interface structs we need.
ComPtr<IDirect3D9> _d3d{ };
ComPtr<IDirect3DDevice9> _device{ };
```
With all interfaces declared we can now initialize Direct3D.
```cpp
bool InitD3D(HWND hWnd) {
// Store the size of the window rectangle.
RECT clientRect{ };
GetClientRect(hWnd, &clientRect);
// Initialize Direct3D
_d3d = Direct3DCreate9(D3D_SDK_VERSION);
// Get the display mode which format will be the window format.
D3DDISPLAYMODE displayMode{ };
_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, // use default graphics card
&displayMode); // display mode pointer
// Next we have to set some presentation parameters.
D3DPRESENT_PARAMETERS pp{ };
pp.BackBufferWidth = clientRect.right; // width is window width
pp.BackBufferHeight = clientRect.bottom; // height is window height
pp.BackBufferFormat = displayMode.Format; // use adapter format
pp.BackBufferCount = 1; // 1 back buffer (default)
pp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard after presentation
pp.hDeviceWindow = hWnd; // associated window handle
pp.Windowed = true; // display in window mode
pp.Flags = 0; // no special flags
// Variable to store results of methods to check if everything succeded.
HRESULT result{ };
result = _d3d->CreateDevice(D3DADAPTER_DEFAULT, // use default graphics card
D3DDEVTYPE_HAL, // use hardware acceleration
hWnd, // the window handle
D3DCREATE_HARDWARE_VERTEXPROCESSING,
// vertices are processed by the hardware
&pp, // the present parameters
&_device); // struct to store the device
// Return false if the device creation failed.
// It is helpful to set breakpoints at the return line.
if (FAILED(result))
return false;
// Create a viewport which hold information about which region to draw to.
D3DVIEWPORT9 viewport{ };
viewport.X = 0; // start at top left corner
viewport.Y = 0; // ..
viewport.Width = clientRect.right; // use the entire window
viewport.Height = clientRect.bottom; // ..
viewport.MinZ = 0.0f; // minimun view distance
viewport.MaxZ = 100.0f; // maximum view distance
// Apply the created viewport.
result = _device->SetViewport(&viewport);
// Always check if something failed.
if (FAILED(result))
return false;
// Everything was successful, return true.
return true;
}
// ...
// Back in our WinMain function we call our initialization function.
// ...
// Check if Direct3D initialization succeded, else exit the application.
if (!InitD3D(hWnd))
return -1;
MSG msg{ };
while (_running) {
while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Clear to render target to a specified color.
_device->Clear(0, // number of rects to clear
nullptr, // indicates to clear the entire window
D3DCLEAR_TARGET, // clear all render targets
D3DXCOLOR{ 1.0f, 0.0f, 0.0f, 1.0f }, // color (red)
0.0f, // depth buffer clear value
0); // stencil buffer clear value
// ...
// Drawing operations go here.
// ...
// Flip the front- and backbuffer.
_device->Present(nullptr, // no source rectangle
nullptr, // no destination rectangle
nullptr, // don't change the current window handle
nullptr); // pretty much always nullptr
}
// ...
```
Now the window should be displayed in a bright red color.
## Vertex Buffer
Let's create a vertex buffer to store the vertices for our triangle
```cpp
// At the top of the file we need to add a include.
#include <vector>
// First we declare a new ComPtr holding a vertex buffer.
ComPtr<IDirect3DVertexBuffer9> _vertexBuffer{ };
// Lets define a funtion to calculate the byte size of a std::vector
template <typename T>
unsigned int GetByteSize(const std::vector<T>& vec) {
return sizeof(vec[0]) * vec.size();
}
// Define "flexible vertex format" describing the content of our vertex struct.
// Use the defined color as diffuse color.
const unsigned long VertexStructFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
// Define a struct representing the vertex data the buffer will hold.
struct VStruct {
float x, y, z; // store the 3D position
D3DCOLOR color; // store a color
};
// Declare a new function to create a vertex buffer.
IDirect3DVertexBuffer9* CreateBuffer(const std::vector<VStruct>& vertices) {
// Declare the buffer to be returned.
IDirect3DVertexBuffer9* buffer{ };
HRESULT result{ };
result = _device->CreateVertexBuffer(
GetByteSize(vertices), // vector size in bytes
0, // data usage
VertexStructFVF, // FVF of the struct
D3DPOOL_DEFAULT, // use default pool for the buffer
&buffer, // receiving buffer
nullptr); // special shared handle
// Check if buffer was created successfully.
if (FAILED(result))
return nullptr;
// Create a data pointer for copying the vertex data
void* data{ };
// Lock the buffer to get a buffer for data storage.
result = buffer->Lock(0, // byte offset
GetByteSize(vertices), // size to lock
&data, // receiving data pointer
0); // special lock flags
// Check if buffer was locked successfully.
if (FAILED(result))
return nullptr;
// Copy the vertex data using C standard libraries memcpy.
memcpy(data, vertices.data(), GetByteSize(vertices));
buffer->Unlock();
// Set the FVF Direct3D uses for rendering.
_device->SetFVF(VertexStructFVF);
// If everything was successful return the filled vertex buffer.
return buffer;
}
```
In our **WinMain** we can now call the new function after the Direct3D initialization.
```cpp
// ...
if (!InitD3D(hWnd))
return -1;
// Define the vertices we need to draw a triangle.
// Values are declared in a clockwise direction else Direct3D would cull them.
// If you want to diable culling just call:
// _device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
std::vector<VStruct> vertices {
// Bottom left
VStruct{ -1.0f, -1.0f, 1.0f, D3DXCOLOR{ 1.0f, 0.0f, 0.0f, 1.0f } },
// Top left
VStruct{ -1.0f, 1.0f, 1.0f, D3DXCOLOR{ 0.0f, 1.0f, 0.0f, 1.0f } },
// Top right
VStruct{ 1.0f, 1.0f, 1.0f, D3DXCOLOR{ 0.0f, 0.0f, 1.0f, 1.0f } }
};
// Try to create the vertex buffer else exit the application.
if (!(_vertexBuffer = CreateBuffer(vertices)))
return -1;
// ...
```
## Transformations
Before we can use the vertex buffer to draw our primitives, we first need to set up the matrices.
```cpp
// Lets create a new funtions for the matrix transformations.
bool SetupTransform() {
// Create a view matrix that transforms world space to
// view space.
D3DXMATRIX view{ };
// Use a left-handed coordinate system.
D3DXMatrixLookAtLH(
&view, // receiving matrix
&D3DXVECTOR3{ 0.0f, 0.0f, -20.0f }, // "camera" position
&D3DXVECTOR3{ 0.0f, 0.0f, 0.0f }, // position where to look at
&D3DXVECTOR3{ 0.0f, 1.0f, 0.0f }); // positive y-axis is up
HRESULT result{ };
result = _device->SetTransform(D3DTS_VIEW, &view); // apply the view matrix
if (FAILED(result))
return false;
// Create a projection matrix that defines the view frustrum.
// It transforms the view space to projection space.
D3DXMATRIX projection{ };
// Create a perspective projection using a left-handed coordinate system.
D3DXMatrixPerspectiveFovLH(
&projection, // receiving matrix
D3DXToRadian(60.0f), // field of view in radians
1024.0f / 768.0f, // aspect ratio (width / height)
0.0f, // minimum view distance
100.0f); // maximum view distance
result = _device->SetTransform(D3DTS_PROJECTION, &projection);
if (FAILED(result))
return false;
// Disable lighting for now so we can see what we want to render.
result = _device->SetRenderState(D3DRS_LIGHTING, false);
// View and projection matrix are successfully applied, return true.
return true;
}
// ...
// Back in the WinMain function we can now call the transformation function.
// ...
if (!(_vertexBuffer = CreateVertexBuffer(vertices)))
return -1;
// Call the transformation setup function.
if (!SetupTransform())
return -1;
// ...
```
## Rendering
Now that everything is setup we can start drawing our first 2D triangle in 3D space.
```cpp
// ...
if (!SetupTransform())
return -1;
// First we have to bind our vertex buffer to the data stream.
HRESULT result{ };
result = _device->SetStreamSource(0, // use the default stream
_vertexBuffer.Get(), // pass the vertex buffer
0, // no offset
sizeof(VStruct)); // size of vertex struct
if (FAILED(result))
return -1;
// Create a world transformation matrix and set it to an identity matrix.
D3DXMATRIX world{ };
D3DXMatrixIdentity(&world);
// Create a scalation matrix scaling our primitve by 10 in the x,
// 10 in the y and keeping the z direction.
D3DXMATRIX scaling{ };
D3DXMatrixScaling(&scaling, // matrix to scale
10, // x scaling
10, // y scaling
1); // z scaling
// Create a rotation matrix storing the current rotation of our primitive.
// We set the current rotation matrix to an identity matrix for now.
D3DXMATRIX rotation{ };
D3DXMatrixIdentity(&rotation);
// Now we multiply the scalation and rotation matrix and store the result
// in the world matrix.
D3DXMatrixMultiply(&world, // destination matrix
&scaling, // matrix 1
&rotation); // matrix 2
// Apply the current world matrix.
_device->SetTransform(D3DTS_WORLD, &world);
// Disable culling so we can see the back of our primitive when it rotates.
_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
// The default cullmode is D3DCULL_CW.
// After we used our the rotation matrix for multiplication we can set it
// to rotate a small amount.
// D3DXToRadian() function converts degree to radians.
D3DXMatrixRotationY(&rotation, // matrix to rotate
D3DXToRadian(0.5f)); // rotation angle in radians
MSG msg{ };
while (_running) {
// ...
_device->Clear(0, nullptr, D3DCLEAR_TARGET,
D3DXCOLOR{ 0.0f, 0.0f, 0.0f, 1.0f }, 0.0f, 0);
// With everything setup we can call the draw function.
_device->BeginScene();
_device->DrawPrimitive(D3DPT_TRIANGLELIST, // primitive type
0, // start vertex
1); // primitive count
_device->EndScene();
_device->Present(nullptr, nullptr, nullptr, nullptr);
// We can keep multiplying the world matrix with our rotation matrix
// to add it's rotation to the world matrix.
D3DXMatrixMultiply(&world, &world, &rotation);
// Update the modified world matrix.
_device->SetTransform(D3DTS_WORLD, &world);
// ...
```
You should now be viewing a 10x10 units colored triangle from 20 units away, rotating around its origin.<br>
You can find the complete working code here: [DirectX - 1](https://pastebin.com/YkSF2rkk)
## Indexing
To make it easier to draw primitives sharing a lot of vertices we can use indexing, so we only have to declare the unique vertices and put the order they are called in another array.
```cpp
// First we declare a new ComPtr for our index buffer.
ComPtr<IDirect3DIndexBuffer9> _indexBuffer{ };
// ...
// Declare a function creating a index buffer from a std::vector
IDirect3DIndexBuffer9* CreateIBuffer(std::vector<unsigned int>& indices) {
IDirect3DIndexBuffer9* buffer{ };
HRESULT result{ };
result = _device->CreateIndexBuffer(
GetByteSize(indices), // vector size in bytes
0, // data usage
D3DFMT_INDEX32, // format is 32 bit int
D3DPOOL_DEFAULT, // default pool
&buffer, // receiving buffer
nullptr); // special shared handle
if (FAILED(result))
return nullptr;
// Create a data pointer pointing to the buffer data.
void* data{ };
result = buffer->Lock(0, // byte offset
GetByteSize(indices), // byte size
&data, // receiving data pointer
0); // special lock flag
if (FAILED(result))
return nullptr;
// Copy the index data and unlock after copying.
memcpy(data, indices.data(), GetByteSize(indices));
buffer->Unlock();
// Return the filled index buffer.
return buffer;
}
// ...
// In our WinMain we can now change the vertex data and create new index data.
// ...
std::vector<VStruct> vertices {
VStruct{ -1.0f, -1.0f, 1.0f, D3DXCOLOR{ 1.0f, 0.0f, 0.0f, 1.0f } },
VStruct{ -1.0f, 1.0f, 1.0f, D3DXCOLOR{ 0.0f, 1.0f, 0.0f, 1.0f } },
VStruct{ 1.0f, 1.0f, 1.0f, D3DXCOLOR{ 0.0f, 0.0f, 1.0f, 1.0f } },
// Add a vertex for the bottom right.
VStruct{ 1.0f, -1.0f, 1.0f, D3DXCOLOR{ 1.0f, 1.0f, 0.0f, 1.0f } }
};
// Declare the index data, here we build a rectangle from two triangles.
std::vector<unsigned int> indices {
0, 1, 2, // the first triangle (b,left -> t,left -> t,right)
0, 2, 3 // the second triangle (b,left -> t,right -> b,right)
};
// ...
// Now we call the "CreateIBuffer" function to create a index buffer.
// ...
if (!(_indexBuffer = CreateIBuffer(indices)))
return -1;
// ...
// After binding the vertex buffer we have to bind the index buffer to
// use indexed rendering.
result = _device->SetStreamSource(0, _vertexBuffer.Get(), 0, sizeof(VStruct));
if (FAILED(result))
return -1;
// Bind the index data to the default data stream.
result = _device->SetIndices(_indexBuffer.Get())
if (FAILED(result))
return -1;
// ...
// Now we replace the "DrawPrimitive" function with an indexed version.
_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, // primitive type
0, // base vertex index
0, // minimum index
indices.size(), // amount of vertices
0, // start in index buffer
2); // primitive count
// ...
```
Now you should see a colored rectangle made up of 2 triangles. If you set the primitive count in the "DrawIndexedPrimitive" method to 1 only the first triangle should be rendered and if you set the start of the index buffer to 3 and the primitive count to 1 only the second triangle should be rendered.<br>
You can find the complete working code here: [DirectX - 2](https://pastebin.com/yWBPWPRG)
## Vertex declaration
Instead of using the old "flexible vertex format" we should use vertex declarations instead, as the FVF declarations get converted to vertex declarations internally anyway.
```cpp
// First we have to REMOVE the following lines:
const unsigned long VertexStructFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
// and
_device->SetFVF(VertexStructFVF);
// ...
// We also have to change the vertex buffer creation FVF-flag.
result = _device->CreateVertexBuffer(
GetByteSize(vertices),
0,
0, // <- 0 indicates we use vertex declarations
D3DPOOL_DEFAULT,
&buffer,
nullptr);
// Next we have to declare a new ComPtr.
ComPtr<IDirect3DVertexDeclaration9> _vertexDecl{ };
// ...
result = _device->SetIndices(_indexBuffer.Get());
if (FAILED(result))
return -1;
// Now we have to declare and apply the vertex declaration.
// Create a vector of vertex elements making up the vertex declaration.
std::vector<D3DVERTEXELEMENT9> vertexDeclDesc {
{ 0, // stream index
0, // byte offset from the struct beginning
D3DDECLTYPE_FLOAT3, // data type (3d float vector)
D3DDECLMETHOD_DEFAULT, // tessellator operation
D3DDECLUSAGE_POSTION, // usage of the data
0 }, // index (multiples usage of the same type)
{ 0,
12, // byte offset (3 * sizeof(float) bytes)
D3DDECLTYPE_D3DCOLOR,
D3DDECLMETHOD_DEFAULT,
D3DDECLUSAGE_COLOR,
0 },
D3DDECL_END() // marks the end of the vertex declaration
};
// After having defined the vector we can create a vertex declaration from it.
result = _device->CreateVertexDeclaration(
vertexDeclDesc.data(), // the vertex element array
&_vertexDecl); // receiving pointer
if (FAILED(result))
return -1;
// Apply the created vertex declaration.
_device->SetVertexDeclaration(_vertexDecl.Get());
// ...
```
## Shader
The maximum shader model for Direct3D 9 is shader model 3.0. Even though every modern graphics card should support it, it is best to check for capabilities.
```cpp
// ...
_device->SetVertexDeclaration(_vertexDecl.Get());
// First we have to request the device capabilities.
D3DCAPS9 deviceCaps{ };
_device->GetDeviceCaps(&deviceCaps);
// Now we check if shader model 3.0 is supported for the vertex shader.
if (deviceCaps.VertexShaderVersion < D3DVS_VERSION(3, 0))
return -1;
// And the same for the pixel shader.
if (deviceCaps.PixelShaderVersion < D3DPS_VERSION(3, 0))
return -1;
```
Now that we are sure shader model 3.0 is supported let's create the vertex and pixel shader files.
DirectX 9 introduced the HLSL (**High Level Shading Language**), a C-like shader language, which
simplified the shader programming a lot, as you could only write shaders in shader assembly in DirectX 8.
Let's create a simple vertex- and pixel shader.
**Vertex Shader**
```cpp
// 3 4x4 float matrices representing the matrices we set in the fixed-function
// pipeline by using the SetTransform() method.
float4x4 projectionMatrix;
float4x4 viewMatrix;
float4x4 worldMatrix;
// The input struct to the vertex shader.
// It holds a 3d float vector for the position and a 4d float vector
// for the color.
struct VS_INPUT {
float3 position : POSITION;
float4 color : COLOR;
};
// The output struct of the vertex shader, that is passed to the pixel shader.
struct VS_OUTPUT {
float4 position : POSITION;
float4 color : COLOR;
};
// The main function of the vertex shader returns the output it sends to the
// pixel shader and receives it's input as a parameter.
VS_OUTPUT main(VS_INPUT input) {
// Declare a empty struct, that the vertex shader returns.
VS_OUTPUT output;
// Set the output position to the input position and set
// the w-component to 1, as the input position is a 3d vector and
// the output position a 4d vector.
output.position = float4(input.position, 1.0f);
// Multiply the output position step by step with the world, view and
// projection matrices.
output.position = mul(output.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
// Pass the input color unchanged to the pixel shader.
output.color = input.color;
// Return the output struct to the pixel shader.
// The position value is automatically used as the vertex position.
return output;
}
```
**Pixel Shader**
```cpp
// The pixel shader input struct must be the same as the vertex shader output!
struct PS_INPUT {
float4 position : POSITION;
float4 color : COLOR;
};
// The pixel shader simply returns a 4d vector representing the vertex color.
// It receives it's input as a parameter just like the vertex shader.
// We have to declare the output semantic as color to it gets interpreted
// correctly.
float4 main(PS_INPUT input) : COLOR {
return input.color;
}
```
For more on semantics: [DirectX - Semantics](https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics#vertex-shader-semantics)
Now we have to do quite some changes to the code.
```cpp
ComPtr<IDirect3DDevice9> _device{ };
ComPtr<IDirect3DVertexBuffer9> _vertexBuffer{ };
ComPtr<IDirect3DIndexBuffer9> _indexBuffer{ };
ComPtr<IDirect3DVertexDeclaration9> _vertexDecl{ };
// We have to add a ComPtr for the vertex- and pixel shader, aswell as one
// for the constants (matrices) in our vertex shader.
ComPtr<IDirect3DVertexShader9> _vertexShader{ };
ComPtr<IDirect3DPixelShader9> _pixelShader{ };
ComPtr<ID3DXConstantTable> _vertexTable{ };
// Declare the world and rotation matrix as global, because we use them in
// WinMain and SetupTransform now.
D3DXMATRIX _worldMatrix{ };
D3DXMATRIX _rotationMatrix{ };
// ...
bool SetupTransform() {
// Set the world and rotation matrix to an identity matrix.
D3DXMatrixIdentity(&_worldMatrix);
D3DXMatrixIdentity(&_rotationMatrix);
D3DXMATRIX scaling{ };
D3DXMatrixScaling(&scaling, 10, 10, 1);
D3DXMatrixMultiply(&_worldMatrix, &scaling, &_rotationMatrix);
// After multiplying the scalation and rotation matrix the have to pass
// them to the shader, by using a method from the constant table
// of the vertex shader.
HRESULT result{ };
result = _vertexTable->SetMatrix(
_device.Get(), // direct3d device
"worldMatrix", // matrix name in the shader
&_worldMatrix); // pointer to the matrix
if (FAILED(result))
return false;
D3DXMATRIX view{ };
D3DXMatrixLookAtLH(&view, &D3DXVECTOR3{ 0.0f, 0.0f, -20.0f },
&D3DXVECTOR3{ 0.0f, 0.0f, 0.0f }, &D3DXVECTOR3{ 0.0f, 1.0f, 0.0f });
// Do the same for the view matrix.
result = _vertexTable->SetMatrix(
_device.Get(), // direct 3d device
"viewMatrix", // matrix name
&view); // matrix
if (FAILED(result))
return false;
D3DXMATRIX projection{ };
D3DXMatrixPerspectiveFovLH(&projection, D3DXToRadian(60.0f),
1024.0f / 768.0f, 0.0f, 100.0f);
// And also for the projection matrix.
result = _vertexTable->SetMatrix(
_device.Get(),
"projectionMatrix",
&projection);
if (FAILED(result))
return false;
D3DXMatrixRotationY(&_rotationMatrix, D3DXToRadian(0.5f));
return true;
}
// ...
// Vertex and index buffer creation aswell as initialization stay unchanged.
// ...
// After checking that shader model 3.0 is available we have to compile and
// create the shaders.
// Declare two temporary buffers storing the compiled shader code.
ID3DXBuffer* vertexShaderBuffer{ };
ID3DXBuffer* pixelShaderBuffer{ };
result = D3DXCompileShaderFromFile("vertex.hlsl", // shader name
nullptr, // macro definitions
nullptr, // special includes
"main", // entry point name
"vs_3_0", // shader model version
0, // special flags
&vertexShaderBuffer, // code buffer
nullptr, // error message
&_vertexTable); // constant table
if (FAILED(result))
return -1;
// After the vertex shader compile the pixel shader.
result = D3DXCompileShaderFromFile("pixel.hlsl",
nullptr,
nullptr,
"main",
"ps_3_0", // pixel shader model 3.0
0,
&pixelShaderBuffer,
nullptr,
nullptr); // no need for a constant table
if (FAILED(result))
return -1;
// Create the vertex shader from the code buffer.
result = _device->CreateVertexShader(
(DWORD*)vertexShaderBuffer->GetBufferPointer(), // code buffer
&_vertexShader); // vertex shader pointer
if (FAILED(result))
return -1;
result = _device->CreatePixelShader(
(DWORD*)pixelShaderBuffer->GetBufferPointer(),
&_pixelShader);
if (FAILED(result))
return -1;
// Release the temporary code buffers after the shaders are created.
vertexShaderBuffer->Release();
pixelShaderBuffer->Release();
// Apply the vertex- and pixel shader.
_device->SetVertexShader(_vertexShader.Get());
_device->SetPixelShader(_pixelShader.Get());
// Apply the transform after the shaders have been set.
if (!SetupTransform())
return -1;
// You can also REMOVE the call so set the lighting render state.
_device->SetRenderState(D3DRS_LIGHTING, false);
```
You can find the complete code here: [DirectX - 3](https://pastebin.com/y4NrvawY)
## Texturing
```cpp
// First we need to declare a ComPtr for the texture.
ComPtr<IDirect3DTexture9> _texture{ };
// Then we have to change the vertex struct.
struct VStruct {
float x, y, z;
float u, v; // Add texture u and v coordinates
D3DCOLOR color;
};
// In the vertex declaration we have to add the texture coordinates.
// the top left of the texture is u: 0, v: 0.
std::vector<VStruct> vertices {
VStruct{ -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, ... }, // bottom left
VStruct{ -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, ... }, // top left
VStruct{ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, ... }, // top right
VStruct{ 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, ... } // bottom right
};
// Next is the vertex declaration.
std::vector<D3DVERTEXELEMENT9> vertexDecl{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
// Add a 2d float vector used for texture coordinates.
{0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
// The color offset is not (3 + 2) * sizeof(float) = 20 bytes
{0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
D3DDECL_END()
};
// Now we have to load the texture and pass its to the shader.
// ...
_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
// Create a Direct3D texture from a png file.
result = D3DXCreateTextureFromFile(_device.Get(), // direct3d device
"texture.png", // texture path
&_texture); // receiving texture pointer
if (FAILED(result))
return -1;
// Attach the texture to shader stage 0, which is equal to texture register 0
// in the pixel shader.
_device->SetTexture(0, _texture.Get());
```
With the main code ready we now have to adjust the shaders to these changes.
**Vertex Shader**
```cpp
float4x4 projectionMatrix;
float4x4 viewMatrix;
float4x4 worldMatrix;
// Add the texture coordinates to the vertex shader in- and output.
struct VS_INPUT {
float3 position : POSITION;
float2 texcoord : TEXCOORD;
float4 color : COLOR;
};
struct VS_OUTPUT {
float4 position : POSITION;
float2 texcoord : TEXCOORD;
float4 color : COLOR;
};
VS_OUTPUT main(VS_INPUT input) {
VS_OUTPUT output;
output.position = float4(input.position, 1.0f);
output.position = mul(output.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
output.color = input.color;
// Set the texcoord output to the input.
output.texcoord = input.texcoord;
return output;
}
```
**Pixel Shader**
```cpp
// Create a sampler called "sam0" using sampler register 0, which is equal
// to the texture stage 0, to which we passed the texture.
sampler sam0 : register(s0);
struct PS_INPUT {
float4 position : POSITION;
float2 texcoord : TEXCOORD;
float4 color : COLOR;
};
float4 main(PS_INPUT input) : COLOR{
// Do a linear interpolation between the texture color and the input color
// using 75% of the input color.
// tex2D returns the texture data at the specified texture coordinate.
return lerp(tex2D(sam0, input.texcoord), input.color, 0.75f);
}
```
## Quotes
<sup>[1]</sup>[DirectX - Wikipedia](https://en.wikipedia.org/wiki/DirectX)

146
docker.html.markdown Normal file
View File

@@ -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
```

View File

@@ -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.

File diff suppressed because it is too large Load Diff

267
el-gr/vim-gr.html.markdown Normal file
View File

@@ -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)

View File

@@ -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/)

View File

@@ -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).

View File

@@ -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 (, 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 (, de verdad) tiene un buen número de artículos con los que
iniciarse en Clojure: [http://clojure-doc.org](http://clojure-doc.org)

View File

@@ -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)

View File

@@ -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)

176
es-es/hy-es.html.markdown Normal file
View File

@@ -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

View File

@@ -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.

View File

@@ -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

View File

@@ -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>;

View File

@@ -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
# Matemática es lo que esperarías
1 + 1 #=> 2
8 - 1 #=> 7
10 * 2 #=> 20
# 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
# 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

View File

@@ -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]
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
# 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
# La división es un poco complicada. Es división entera y toma la parte entera
# de los resultados automáticamente.
5 / 2 #=> 2
# Cuando usas un float, los resultados son floats
3 * 2.0 # => 6.0
# 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
# 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

File diff suppressed because it is too large Load Diff

View File

@@ -139,7 +139,7 @@ status == :pendiente #=> true
status == 'pendiente' #=> false
status == :aprovado #=> false
status == :aprobado #=> false
# Arreglos

115
es-es/sql-es.html.markdown Normal file
View File

@@ -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;
```

View File

@@ -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"]

View File

@@ -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 هستند. توضیحات یک خطی با دو خط مورب شروع میشوند.,

View File

@@ -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 '{'

View File

@@ -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

View File

@@ -0,0 +1,479 @@
---
language: elixir
contributors:
- ["Joao Marques", "http://github.com/mrshankly"]
- ["Dzianis Dashkevich", "https://github.com/dskecse"]
- ["Ryan Plant", "https://github.com/ryanplant-au"]
- ["Ev Bogdanov", "https://github.com/evbogdanov"]
translator:
- ["Timothé Pardieu", "https://github.com/timprd"]
filename: learnelixir-fr.ex
lang: fr-fr
---
Elixir est un langage de programmation fonctionnel moderne reposant sur la machine virtuelle BEAM, qui héberge aussi Erlang.
Il est totalement compatible avec Erlang mais dispose d'une syntaxe plus agréable et apporte de nouvelles fonctionnalités.
```elixir
# Un commentaire simple sur une seule ligne commence par un dièse.
# Il n'y a pas de commentaire multi-ligne,
# Mais il est possible de les empiler comme ici.
# La commande `iex` permet de lancer le shell Elixir.
# La commande `elixirc` permet de compiler vos modules.
# Les deux devraient être dans votre path si vous avez installé Elixir correctement.
## ---------------------------
## -- Types basiques
## ---------------------------
# Il y a les nombres
3 # Integer
0x1F # Integer
3.0 # Float
# Les atomes, des littéraux, qui sont des constantes avec comme valeur leur nom.
# Ils commencent par `:`.
:hello # atom
# Il existe également des n-uplets dont les valeurs sont stockés de manière contiguë
# en mémoire.
{1,2,3} # tuple
# Il est possible d'accéder à un element d'un tuple avec la fonction
# `elem`:
elem({1, 2, 3}, 0) #=> 1
# Les listes sont implémentées sous forme de listes chainées.
[1,2,3] # list
# La tête et le reste d'une liste peuvent être récupérés comme cela :
[head | tail] = [1,2,3]
head #=> 1
tail #=> [2,3]
# En Elixir, comme en Erlang, le `=` dénote un 'pattern matching'
# (Filtrage par motif) et non une affectation.
# Cela signifie que la partie de gauche (pattern) est comparé (match) à
# la partie de droite.
# Une erreur sera lancée si aucun model (match) est trouvé.
# Dans cet exemple les tuples ont des tailles différentes
# {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
# Il y a aussi les binaires
<<1,2,3>> # binary
# Chaine de caractères et liste de caractères
"hello" # string
'hello' # char list
# Chaine de caractères sur plusieurs lignes
"""
Je suis une chaine de caractères
sur plusieurs lignes.
"""
#=> "Je suis une chaine de caractères\nsur plusieurs lignes.\n"
# Les chaines de caractères sont encodées en UTF-8 :
"héllò" #=> "héllò"
# Les chaines de caractères sont des binaires tandis que
# les listes de caractères sont des listes.
<<?a, ?b, ?c>> #=> "abc"
[?a, ?b, ?c] #=> 'abc'
# `?a` en Elixir retourne le code ASCII (Integer) de la lettre `a`
?a #=> 97
# Pour concaténer des listes il faut utiliser `++`, et `<>` pour les
# binaires
[1,2,3] ++ [4,5] #=> [1,2,3,4,5]
'hello ' ++ 'world' #=> 'hello world'
<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>>
"hello " <> "world" #=> "hello world"
# Les intervalles sont représentés de cette sorte `début..fin`
# (tout deux inclusifs)
1..10 #=> 1..10
bas..haut = 1..10 # Possibilité d'utiliser le pattern matching sur les intervalles aussi.
[bas, haut] #=> [1, 10]
# Les Maps (Tableau associatif) sont des paires clée - valeur
genders = %{"david" => "male", "gillian" => "female"}
genders["david"] #=> "male"
# Les maps avec des atomes peuvent être utilisés comme cela
genders = %{david: "male", gillian: "female"}
genders.gillian #=> "female"
## ---------------------------
## -- Operateurs
## ---------------------------
# Mathématiques
1 + 1 #=> 2
10 - 5 #=> 5
5 * 2 #=> 10
10 / 2 #=> 5.0
# En Elixir l'opérateur `/` retourne toujours un Float (virgule flottante).
# Pour faire une division avec entier il faut utiliser `div`
div(10, 2) #=> 5
# Pour obtenir le reste de la division il faut utiliser `rem`
rem(10, 3) #=> 1
# Il y a aussi les opérateurs booléen: `or`, `and` et `not`.
# Ces opérateurs attendent un booléen en premier argument.
true and true #=> true
false or true #=> true
# 1 and true
#=> ** (BadBooleanError) expected a booléens on left-side of "and", got: 1
# Elixir fournit aussi `||`, `&&` et `!` qui acceptent des arguments de
# tout type.
# Chaque valeur sauf `false` et `nil` seront évalués à vrai (true).
1 || true #=> 1
false && 1 #=> false
nil && 20 #=> nil
!true #=> false
# Pour les comparaisons il y a : `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` et `>`
1 == 1 #=> true
1 != 1 #=> false
1 < 2 #=> true
# `===` et `!==` sont plus stricts en comparant les Integers (entiers)
# et les Floats (nombres à virgules) :
1 == 1.0 #=> true
1 === 1.0 #=> false
# On peut aussi comparer deux types de données différents :
1 < :hello #=> true
# L'ordre est défini de la sorte :
# number < atom < reference < functions < port < pid < tuple < list < bit string
# Pour citer Joe Armstrong : "The actual order is not important,
# but that a total ordering is well defined is important."
## ---------------------------
## -- Structure de contrôle
## ---------------------------
# Condition avec `if` (si)
if false do
"Cela ne sera pas vu"
else
"Cela le sera"
end
# Condition avec `unless` (sauf).
# Il correspond à la négation d'un `if` (si)
unless true do
"Cela ne sera pas vu"
else
"Cela le sera"
end
# Beaucoup de structures en Elixir se basent sur le pattern matching.
# `case` permet de comparer une valeur à plusieurs modèles:
case {:one, :two} do
{:four, :five} ->
"Ne match pas"
{:one, x} ->
"Match et lie `x` à `:two` dans ce cas"
_ ->
"Match toutes les valeurs"
end
# Il est commun de lier la valeur à `_` si on ne l'utilise pas.
# Par exemple, si seulement la tête d'une liste nous intéresse:
[head | _] = [1,2,3]
head #=> 1
# Pour plus de lisibilité, ce procédé est utilisé:
[head | _tail] = [:a, :b, :c]
head #=> :a
# `cond` permet de vérifier plusieurs conditions à la fois.
# Il est conseillé d'utiliser `cond` plutôt que des `if` imbriqués.
cond do
1 + 1 == 3 ->
"Je ne serai pas vu"
2 * 5 == 12 ->
"Moi non plus"
1 + 2 == 3 ->
"Mais moi oui"
end
# Il est commun d'attribuer la dernière condition à true (vrai), qui
# matchera toujours.
cond do
1 + 1 == 3 ->
"Je ne serai pas vu"
2 * 5 == 12 ->
"Moi non plus"
true ->
"Mais moi oui (représente un else)"
end
# `try/catch` est utilisé pour attraper les valeurs rejetées.
# Il supporte aussi un
# `after` qui est appelé autant si une valeur est jetée ou non.
try do
throw(:hello)
catch
message -> "Message : #{message}."
after
IO.puts("Je suis la clause after (après).")
end
#=> Je suis la clause after (après).
# "Message : :hello"
## ---------------------------
## -- Modules et Fonctions
## ---------------------------
# Fonctions anonymes (notez le point).
square = fn(x) -> x * x end
square.(5) #=> 25
# Les fonctions anonymes acceptent aussi de nombreuses clauses et guards (gardes).
# Les guards permettent d'affiner le pattern matching,
# ils sont indiqués par le mot-clef `when` :
f = fn
x, y when x > 0 -> x + y
x, y -> x * y
end
f.(1, 3) #=> 4
f.(-1, 3) #=> -3
# Elixir propose aussi de nombreuses fonctions internes.
is_number(10) #=> true
is_list("hello") #=> false
elem({1,2,3}, 0) #=> 1
# Il est possible de grouper plusieurs fonctions dans un module.
# Dans un module, les fonctions sont définies par `def`
defmodule Math do
def sum(a, b) do
a + b
end
def square(x) do
x * x
end
end
Math.sum(1, 2) #=> 3
Math.square(3) #=> 9
# Pour compiler notre module `Math`,
# il faut le sauvegarder en tant que `math.ex` et utiliser `elixirc`.
# Executez ainsi `elixirc math.ex` dans le terminal.
# Au sein d'un module, nous pouvons définir les fonctions avec `def`
# et `defp` pour les fonctions privées.
# Une fonction définie par `def` est disponible dans les autres
# modules. Une fonction privée est disponible localement seulement.
defmodule PrivateMath do
def sum(a, b) do
do_sum(a, b)
end
defp do_sum(a, b) do
a + b
end
end
PrivateMath.sum(1, 2) #=> 3
# PrivateMath.do_sum(1, 2) #=> ** (UndefinedFunctionError)
# La déclaration de fonction supporte également les guards (gardes)
# et les clauses.
# Quand une fonction avec plusieurs clauses est appelée,
# la première fonction dont la clause est satisfaite par les arguments sera appelée.
# Exemple: le code `area({:circle, 3})` appelle la deuxième fonction definie plus bas,
# et non la première car ses arguments correspondent à la signature de cette dernière:
defmodule Geometry do
def area({:rectangle, w, h}) do
w * h
end
def area({:circle, r}) when is_number(r) do
3.14 * r * r
end
end
Geometry.area({:rectangle, 2, 3}) #=> 6
Geometry.area({:circle, 3}) #=> 28.25999999999999801048
# Geometry.area({:circle, "not_a_number"})
#=> ** (FunctionClauseError) no function clause matching in Geometry.area/1
# En raison de l'immutabilité, la récursivité est une grande partie
# d'Elixir
defmodule Recursion do
def sum_list([head | tail], acc) do
sum_list(tail, acc + head)
end
def sum_list([], acc) do
acc
end
end
Recursion.sum_list([1,2,3], 0) #=> 6
# Les modules Elixir supportent des attributs internes,
# ceux-ci peuvent aussi être personnalisés.
defmodule MyMod do
@moduledoc """
This is a built-in attribute on a example module.
"""
@my_data 100 # Attribut personnel.
IO.inspect(@my_data) #=> 100
end
# L'opérateur pipe (|>) permet de passer la sortie d'une expression
# en premier paramètre d'une fonction.
Range.new(1,10)
|> Enum.map(fn x -> x * x end)
|> Enum.filter(fn x -> rem(x, 2) == 0 end)
#=> [4, 16, 36, 64, 100]
## ---------------------------
## -- Structs et Exceptions
## ---------------------------
# Les Structs sont des extensions des Maps.
# Apportant en plus les valeurs par defaut, le polymorphisme et
# la vérification à la compilation dans Elixir.
defmodule Person do
defstruct name: nil, age: 0, height: 0
end
jean_info = %Person{ name: "Jean", age: 30, height: 180 }
#=> %Person{age: 30, height: 180, name: "Jean"}
# Access the value of name
jean_info.name #=> "Jean"
# Update the value of age
older_jean_info = %{ jean_info | age: 31 }
#=> %Person{age: 31, height: 180, name: "Jean"}
# Le bloc `try` avec le mot-clef `rescue` est utilisé pour gérer les exceptions
try do
raise "some error"
rescue
RuntimeError -> "rescued a runtime error"
_error -> "this will rescue any error"
end
#=> "rescued a runtime error"
# Chaque exception possède un message
try do
raise "some error"
rescue
x in [RuntimeError] ->
x.message
end
#=> "some error"
## ---------------------------
## -- Concurrence
## ---------------------------
# Elixir se repose sur le modèle d'acteur pour gérer la concurrence.
# Pour écrire un programme concurrent en Elixir il faut trois
# primitives: spawning processes (création), sending messages (envoi)
# et receiving messages (réception).
# Pour débuter un nouveau processus, il faut utiliser
# la fonction `spawn` qui prend en argument une fonction.
f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
spawn(f) #=> #PID<0.40.0>
# `spawn` retourn un pid (identifiant de processus), il est possible
# d'utiliser ce pid pour envoyer un message au processus.
# Pour faire parvenir le message il faut utiliser l'opérateur `send`.
# Pour que cela soit utile il faut être capable de recevoir les
# messages.
# Cela est possible grâce au mechanisme de `receive`:
# Le bloc `receive do` est utilisé pour écouter les messages et les traiter
# au moment de la réception. Un bloc `receive do` pourra traiter un seul
# message reçu.
# Pour traiter plusieurs messages, une fonction avec un bloc `receive do`
# doit s'appeler elle-même récursivement.
defmodule Geometry do
def area_loop do
receive do
{:rectangle, w, h} ->
IO.puts("Area = #{w * h}")
area_loop()
{:circle, r} ->
IO.puts("Area = #{3.14 * r * r}")
area_loop()
end
end
end
# Ceci compile le module et créer un processus qui évalue dans le terminal `area_loop`
pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
# Alternativement
pid = spawn(Geometry, :area_loop, [])
# On envoi un message au `pid` qui correspond à la régle de réception.
send pid, {:rectangle, 2, 3}
#=> Area = 6
# {:rectangle,2,3}
send pid, {:circle, 2}
#=> Area = 12.56000000000000049738
# {:circle,2}
# Le shell est aussi un processus, il est possible d'utiliser `self`
# pour obtenir le pid du processus courant.
self() #=> #PID<0.27.0>
## ---------------------------
## -- Agents
## ---------------------------
# Un agent est un processus qui garde les traces des valeurs modifiées.
# Pour créer un agent on utilise `Agent.start_link` avec une fonction.
# L'état initial de l'agent sera ce que la fonction retourne
{ok, my_agent} = Agent.start_link(fn -> ["red", "green"] end)
# `Agent.get` prend un nom d'agent et une fonction (`fn`).
# Qu'importe ce que cette `fn` retourne, l'état sera ce qui est retourné.
Agent.get(my_agent, fn colors -> colors end) #=> ["red", "green"]
# Modification de l'état de l'agent
Agent.update(my_agent, fn colors -> ["blue" | colors] end)
```
## Références
* [Guide de debut](http://elixir-lang.org/getting-started/introduction.html) depuis le site [Elixir](http://elixir-lang.org)
* [Documentation Elixir ](https://elixir-lang.org/docs.html)
* ["Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) de Dave Thomas
* [Elixir Cheat Sheet](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf)
* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) de Fred Hebert
* ["Programming Erlang: Software for a Concurrent World"](https://pragprog.com/book/jaerlang2/programming-erlang) de Joe Armstrong

View File

@@ -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

View File

@@ -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'){

View File

@@ -178,8 +178,8 @@ Vous pouvez également utiliser des sous-listes.
1. Item un
2. Item deux
3. Item trois
* Sub-item
* Sub-item
* Sub-item
* Sub-item
4. Item quatre
```
@@ -230,7 +230,7 @@ En Markdown GitHub, vous pouvez utiliser des syntaxes spécifiques.
```
Pas besoin d'indentation pour le code juste au-dessus, de plus, GitHub
va utiliser une coloration syntaxique pour le langage indiqué après les ```.
va utiliser une coloration syntaxique pour le langage indiqué après les <code>```</code>.
## Ligne Horizontale
@@ -267,13 +267,13 @@ Markdown supporte aussi les liens relatifs.
Les liens de références sont eux aussi disponibles en Markdown.
```md
[Cliquez ici][link1] pour plus d'information!
[Regardez aussi par ici][foobar] si vous voulez.
<div class="highlight"><code><pre>
[<span class="nv">Cliquez ici</span>][<span class="ss">link1</span>] pour plus d'information!
[<span class="nv">Regardez aussi par ici</span>][<span class="ss">foobar</span>] si vous voulez.
[link1]: http://test.com/ "Cool!"
[foobar]: http://foobar.biz/ "Génial!"
```
[<span class="nv">link1</span>]: <span class="sx">http://test.com/</span> <span class="nn">"Cool!"</span>
[<span class="nv">foobar</span>]: <span class="sx">http://foobar.biz/</span> <span class="nn">"Génial!"</span>
</pre></code></div>
Le titre peut aussi être entouré de guillemets simples, ou de parenthèses, ou
absent. Les références peuvent être placées où vous voulez dans le document et
@@ -282,11 +282,11 @@ les identifiants peuvent être n'importe quoi tant qu'ils sont uniques.
Il y a également le nommage implicite qui transforme le texte du lien en
identifiant.
```md
[Ceci][] est un lien.
<div class="highlight"><code><pre>
[<span class="nv">Ceci</span>][] est un lien.
[ceci]: http://ceciestunlien.com/
```
[<span class="nv">Ceci</span>]:<span class="sx">http://ceciestunlien.com/</span>
</pre></code></div>
Mais ce n'est pas beaucoup utilisé.
@@ -302,11 +302,11 @@ d'un point d'exclamation!
Là aussi, on peut utiliser le mode "références".
```md
![Ceci est l'attribut ALT de l'image][monimage]
<div class="highlight"><code><pre>
![<span class="nv">Ceci est l'attribut ALT de l'image</span>][<span class="ss">monimage</span>]
[monimage]: relative/urls/cool/image.jpg "si vous voulez un titre, c'est ici."
```
[<span class="nv">monimage</span>]: <span class="sx">relative/urls/cool/image.jpg</span> <span class="nn">"si vous voulez un titre, c'est ici."</span>
</pre></code></div>
## Divers

View File

@@ -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

View File

@@ -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
# On a des 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
# Les calculs sont ce à quoi on s'attend
1 + 1 # => 2
8 - 1 # => 7
10 * 2 # => 20
# 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
# Sauf pour la division qui retourne un float (nombre à virgule flottante)
35 / 5 # => 7.0
# Pour corriger ce problème, on utilise les float.
2.0 # Voici un float
11.0 / 4.0 #=> 2.75 ahhh... beaucoup mieux
# 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
# Forcer la priorité avec les parenthèses
(1 + 3) * 2 #=> 8
# Quand on utilise un float, le résultat est un float
3 * 2.0 # => 6.0
# Les valeurs booléenes sont de type primitif
# 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
# Pour la négation, on utilise "not"
not True #=> False
not False #=> True
# Négation avec not
not True # => False
not False # => True
# Pour l'égalité, ==
1 == 1 #=> True
2 == 1 #=> False
# Opérateurs booléens
# On note que "and" et "or" sont sensibles à la casse
True and False #=> False
False or True #=> True
# L'inégalité est symbolisée par !=
1 != 1 #=> False
2 != 1 #=> 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
# D'autres comparateurs
1 < 10 #=> True
1 > 10 #=> False
2 <= 2 #=> True
2 >= 2 #=> True
# On vérifie une égalité avec ==
1 == 1 # => True
2 == 1 # => False
# On peut enchaîner les comparateurs !
1 < 2 < 3 #=> True
2 < 3 < 2 #=> False
# On vérifie une inégalité avec !=
1 != 1 # => False
2 != 1 # => True
# Les chaînes de caractères sont créées avec " ou '
"C'est une chaîne."
'C\'est aussi une chaîne.'
# Autres opérateurs de comparaison
1 < 10 # => True
1 > 10 # => False
2 <= 2 # => True
2 >= 2 # => True
# On peut aussi les "additioner" !
"Hello " + "world!" #=> "Hello world!"
# On peut enchaîner les comparaisons
1 < 2 < 3 # => True
2 < 3 < 2 # => False
# Une chaîne peut être traitée comme une liste de caractères
"C'est une chaîne"[0] #=> 'C'
# (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
# % peut être utilisé pour formatter des chaîne, comme ceci:
"%s can be %s" % ("strings", "interpolated")
# 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!")
# 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!
# 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
# 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
# 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
# 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
# 'if' peut être utilisé comme expression
"yahoo!" if 3 > 2 else 2 #=> "yahoo!"
# 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]
# 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]
# 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.
# Accès à un élément d'une liste :
li[0] # => 1
# Accès au dernier élément :
li[-1] # => 3
# 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 à un élément en dehors des limites lève une IndexError
li[4] # Lève une IndexError
# Accèder aux indices hors limite lève une exception
li[4] # Lève un '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]
# 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]
# Faire une copie d'une profondeur de un avec les "slices"
li2 = li[:] # => li2 = [1, 2, 4, 3] mais (li2 is li) vaut False.
# Retirer un élément spécifique dee la liste avec "del"
del li[2] # li contient [1, 2, 3]
# Enlever des éléments arbitrairement d'une liste
del li[2] # li is now [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 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'
tup[0] # => 1
tup[0] = 3 # Lève une 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
# 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'>
# 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
# 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.
# 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.
# On trouve une valeur avec []
filled_dict["one"] # => 1
# 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
# 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"]
# Les sets stockent ... des sets
# 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()
# 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}
# Depuis Python 2.7, {} peut être utilisé pour déclarer un 'set'
filled_set = {1, 2, 2, 3, 4} # => {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}
# Ajouter plus d'éléments au set
filled_set.add(5) # filled_set contient maintenant {1, 2, 3, 4, 5}
# On peut changer un set :
filled_set = some_set
# Intersection de sets avec &
# 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}
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)
"""
Les boucles "while" boucle jusqu'à ce que leur condition ne soit plus vraie
"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
@@ -307,66 +415,135 @@ Affiche:
"""
x = 0
while x < 4:
print x
print(x)
x += 1 # Raccourci pour x = x + 1
# 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/)
### Format papier
### 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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -14,7 +14,7 @@ The syntax of F# is different from C-style languages:
* Curly braces are not used to delimit blocks of code. Instead, indentation is used (like Python).
* Whitespace is used to separate parameters rather than commas.
If you want to try out the code below, you can go to [tryfsharp.org](http://www.tryfsharp.org/Create) and paste it into an interactive REPL.
If you want to try out the code below, you can go to [https://try.fsharp.org](https://try.fsharp.org) and paste it into an interactive REPL.
```csharp
@@ -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).

View File

@@ -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)

View File

@@ -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.

View File

@@ -180,6 +180,21 @@ class Foo {
def lastName
}
/*
Methods with optional parameters
*/
// A method can have default values for parameters
def say(msg = 'Hello', name = 'world') {
"$msg $name!"
}
// It can be called in 3 different ways
assert 'Hello world!' == say()
// Right most parameter with default value is eliminated first.
assert 'Hi world!' == say('Hi')
assert 'learn groovy' == say('learn', 'groovy')
/*
Logical Branching and Looping
*/

View File

@@ -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. Haskell IO
-- 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
----------------------------------------------------
-- 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`.

View File

@@ -6,8 +6,8 @@ contributors:
- ["Dan Korostelev", "https://github.com/nadako/"]
---
Haxe is a web-oriented language that provides platform support for C++, C#,
Swf/ActionScript, Javascript, Java, PHP, Python, Lua, HashLink, and Neko byte code
[Haxe](https://haxe.org/) is a general-purpose language that provides platform support for C++, C#,
Swf/ActionScript, JavaScript, Java, PHP, Python, Lua, HashLink, and Neko bytecode
(the latter two being also written by the Haxe author). Note that this guide is for
Haxe version 3. Some of the guide may be applicable to older versions, but it is
recommended to use other references.
@@ -189,7 +189,7 @@ class LearnHaxe3 {
trace(m.get('bar') + " is the value for m.get('bar')");
trace(m['bar'] + " is the value for m['bar']");
var m2 = ['foo' => 4, 'baz' => 6]; // Alternative map syntax
var m2 = ['foo' => 4, 'baz' => 6]; // Alternative map syntax
trace(m2 + " is the value for m2");
// Remember, you can use type inference. The Haxe compiler will
@@ -234,10 +234,9 @@ class LearnHaxe3 {
^ Bitwise exclusive OR
| Bitwise inclusive OR
*/
// increments
var i = 0;
trace("Increments and decrements");
trace("Pre-/Post- Increments and Decrements");
trace(i++); // i = 1. Post-Increment
trace(++i); // i = 2. Pre-Increment
trace(i--); // i = 1. Post-Decrement
@@ -287,7 +286,7 @@ class LearnHaxe3 {
}
// do-while loop
var l = 0;
var l = 0;
do {
trace("do statement always runs at least once");
} while (l > 0);
@@ -338,7 +337,7 @@ class LearnHaxe3 {
*/
var my_dog_name = "fido";
var favorite_thing = "";
switch(my_dog_name) {
switch (my_dog_name) {
case "fido" : favorite_thing = "bone";
case "rex" : favorite_thing = "shoe";
case "spot" : favorite_thing = "tennis ball";
@@ -366,7 +365,7 @@ class LearnHaxe3 {
trace("k equals ", k); // outputs 10
var other_favorite_thing = switch(my_dog_name) {
var other_favorite_thing = switch (my_dog_name) {
case "fido" : "teddy";
case "rex" : "stick";
case "spot" : "football";
@@ -559,7 +558,7 @@ class SimpleEnumTest {
// You can specify the "full" name,
var e_explicit:SimpleEnum = SimpleEnum.Foo;
var e = Foo; // but inference will work as well.
switch(e) {
switch (e) {
case Foo: trace("e was Foo");
case Bar: trace("e was Bar");
case Baz: trace("e was Baz"); // comment this line to throw an error.
@@ -572,7 +571,7 @@ class SimpleEnumTest {
You can also specify a default for enum switches as well:
*/
switch(e) {
switch (e) {
case Foo: trace("e was Foo again");
default : trace("default works here too");
}
@@ -595,21 +594,21 @@ class ComplexEnumTest {
var e1:ComplexEnum = IntEnum(4); // specifying the enum parameter
// Now we can switch on the enum, as well as extract any parameters
// it might have had.
switch(e1) {
switch (e1) {
case IntEnum(x) : trace('$x was the parameter passed to e1');
default: trace("Shouldn't be printed");
}
// another parameter here that is itself an enum... an enum enum?
var e2 = SimpleEnumEnum(Foo);
switch(e2){
switch (e2){
case SimpleEnumEnum(s): trace('$s was the parameter passed to e2');
default: trace("Shouldn't be printed");
}
// enums all the way down
var e3 = ComplexEnumEnum(ComplexEnumEnum(MultiEnum(4, 'hi', 4.3)));
switch(e3) {
switch (e3) {
// You can look for certain nested enums by specifying them
// explicitly:
case ComplexEnumEnum(ComplexEnumEnum(MultiEnum(i,j,k))) : {
@@ -668,7 +667,7 @@ class TypedefsAndStructuralTypes {
That would give us a single "Surface" type to work with across
all of those platforms.
*/
*/
}
}
@@ -700,8 +699,7 @@ class UsingExample {
instance, and the compiler still generates code equivalent to a
static method.
*/
}
}
}
```

231
hdl.html.markdown Normal file
View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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 ))

View File

@@ -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

View File

@@ -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"]

View File

@@ -11,7 +11,7 @@ lang: it-it
Un'espressione regolare (regex o regexp in breve) è una speciale stringa
utilizzata per definire un pattern, ad esempio per cercare una sequenza di
caratteri; ad esempio, `/^[a-z]+:/` può essere usato per estrarre `http:`
dall'URL `http://github.com/`.
dall'URL `http://github.com/`.
PCRE (Perl Compatible Regular Expressions) è una libreria per i regex in C.
La sintassi utilizzata per le espressioni è molto simile a quella di Perl, da
@@ -19,7 +19,9 @@ cui il nome. Si tratta di una delle sintassi più diffuse per la scrittura di
regex.
Esistono due tipi di metacaratteri (caratteri con una funzione speciale):
* Caratteri riconosciuti ovunque tranne che nelle parentesi quadre
```
\ carattere di escape
^ cerca all'inizio della stringa (o della riga, in modalità multiline)
@@ -36,16 +38,17 @@ Esistono due tipi di metacaratteri (caratteri con una funzione speciale):
```
* Caratteri riconosciuti nelle parentesi quadre
```
\ carattere di escape
^ nega la classe se è il primo carattere
- indica una serie di caratteri
[ classe caratteri POSIX (se seguita dalla sintassi POSIX)
] termina la classe caratteri
```
```
PCRE fornisce inoltre delle classi di caratteri predefinite:
PCRE fornisce inoltre delle classi di caratteri predefinite:
```
\d cifra decimale
\D NON cifra decimale
@@ -62,9 +65,11 @@ PCRE fornisce inoltre delle classi di caratteri predefinite:
## Esempi
Utilizzeremo la seguente stringa per i nostri test:
```
66.249.64.13 - - [18/Sep/2004:11:07:48 +1000] "GET /robots.txt HTTP/1.0" 200 468 "-" "Googlebot/2.1"
```
Si tratta di una riga di log del web server Apache.
| Regex | Risultato | Commento |

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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)

112
it-it/sql-it.html.markdown Normal file
View File

@@ -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;
```

361
it-it/zfs-it.html.markdown Normal file
View File

@@ -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)

View File

@@ -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"キーワードのみを書くだけで良いです。

328
janet.html.markdown Normal file
View File

@@ -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.

View File

@@ -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/)

Some files were not shown because too many files have changed in this diff Show More