Merge branch 'adambard:master' into OKEAMAH-patch-1

This commit is contained in:
DAVID OKEAMAH 2024-10-13 16:02:00 +01:00 committed by GitHub
commit 30b2cc8c19
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
702 changed files with 35018 additions and 19160 deletions

67
.gitattributes vendored
View File

@ -1,65 +1,2 @@
asciidoc*.html.markdown linguist-language=AsciiDoc
angularjs*.html.markdown linguist-language=JavaScript
bash*.html.markdown linguist-language=bash
bf.html.markdown linguist-language=Brainfuck
bf-*.html.markdown linguist-language=Brainfuck
c-*.html.markdown linguist-language=C
c.html.markdown linguist-language=C
c++*.html.markdown linguist-language=C++
chapel*.html.markdown linguist-language=Chapel
clojure*.html.markdown linguist-language=Clojure
cmake*.html.markdown linguist-language=CMake
coffeescript*.html.markdown linguist-language=CoffeeScript
coldfusion*.html.markdown linguist-language=ColdFusion
common-lisp*.html.markdown linguist-language=lisp
compojure*.html.markdown linguist-language=Clojure
csharp*.html.markdown linguist-language=C#
css*.html.markdown linguist-language=CSS
d.html.markdown linguist-language=D
d-*.html.markdown linguist-language=D
dart*.html.markdown linguist-language=Dart
edn*.html.markdown linguist-language=edn
elisp*.html.markdown linguist-language=elisp
elixir*.html.markdown linguist-language=Elixir
elm*.html.markdown linguist-language=Elm
erlang*.html.markdown linguist-language=Erlang
factor*.html.markdown linguist-language=Factor
forth*.html.markdown linguist-language=Forth
fortran*.html.markdown linguist-language=FORTRAN
fsharp*.html.markdown linguist-language=fsharp
go.html.markdown linguist-language=Go
go-*.html.markdown linguist-language=Go
groovy*.html.markdown linguist-language=Groovy
hack*.html.markdown linguist-language=Hack
haml*.html.markdown linguist-language=Haml
haskell*.html.markdown linguist-language=Haskell
haxe*.html.markdown linguist-language=Haxe
html*.html.markdown linguist-language=HTML
hy.html.markdown linguist-language=Hy
hy-*.html.markdown linguist-language=Hy
inform7*.html.markdown linguist-language=inform7
java.html.markdown linguist-language=Java
java-*.html.markdown linguist-language=Java
javascript*.html.markdown linguist-language=JavaScript
jquery*.html.markdown linguist-language=JavaScript
json*.html.markdown linguist-language=JSON
julia*.html.markdown linguist-language=Julia
kotlin*.html.markdown linguist-language=Kotlin
latex*.html.markdown linguist-language=latex
less*.html.markdown linguist-language=Less
livescript*.html.markdown linguist-language=LiveScript
logtalk*.html.markdown linguist-language=Logtalk
lua*.html.markdown linguist-language=Lua
make*.html.markdown linguist-language=Makefile
markdown*.html.markdown linguist-language=Markdown
matlab*.html.markdown linguist-language=MATLAB
nim*.html.markdown linguist-language=Nimrod
nix*.html.markdown linguist-language=Nix
objective-c*.html.markdown linguist-language=Objective-C
ocaml*.html.markdown linguist-language=OCaml
paren*.html.markdown linguist-language=lisp
pcre*.html.markdown linguist-language=Perl
perl.html.markdown linguist-language=Perl
perl-*.html.markdown linguist-language=Perl
raku*.html.markdown linguist-language=Perl6
ruby*.html.markdown linguist-language=Ruby
*.html.markdown linguist-language=Markdown linguist-detectable
file.html.erb linguist-vendored

17
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: Trigger site build
on:
push:
branches: [main, master]
jobs:
deploy:
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.repository_owner == 'adambard'
steps:
- name: Trigger site build
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.PAT_LEARNXINYMINUTES_SITE }}
repository: adambard/learnxinyminutes-site
event-type: doc-update

18
.github/workflows/lint.yml vendored Normal file
View File

@ -0,0 +1,18 @@
name: CI
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.2'
- run: gem install mdl
- run: mdl . --ignore-front-matter -r MD003,MD011,MD023,MD027,MD028,MD035,MD037,MD038,MD039,MD047

View File

@ -1,3 +0,0 @@
language: ruby
rvm:
- 2.2

View File

@ -34,7 +34,7 @@ review them more effectively and/or individually.
* **Use UTF-8**
* For translations (or EN articles with non-ASCII characters) please ensure
your file is UTF-8 encoded.
* Try to leave out the byte-order-mark at the start of the file (in Vim, use
* Leave out the byte-order-mark (BOM) at the start of the file (in Vim, use
`:set nobomb`).
* You can check if the file contains a BOM on Linux/Unix systems by running
`file language.html.markdown` You will see this if it uses a BOM:
@ -58,7 +58,7 @@ Other fields:
*tool* or *Algorithms & Data Structures*. Defaults to *language* if omitted.
* **filename**: The filename for this article's code. It will be fetched, mashed
together, and made downloadable.
* For non-English articles, *filename* should have a language-specific
* For non-English articles, *filename* should have a language-specific
suffix.
* **lang**: For translations, the human language this article is in. For
categorization, mostly.
@ -76,7 +76,12 @@ lang: ep-ep
*--
```
### Should I add myself as a Contributor?
### Syntax highlighter
[Pygments](https://pygments.org/languages/) is used for syntax highlighting through
[pygments.rb](https://github.com/pygments/pygments.rb).
### Should I add myself as a contributor?
If you want to add yourself to contributors, keep in mind that contributors get
equal billing, and the first contributor usually wrote the whole article. Please

View File

@ -1,5 +0,0 @@
source 'http://rubygems.org'
group :test do
gem 'rake'
gem 'charlock_holmes'
end

View File

@ -1,15 +0,0 @@
GEM
remote: http://rubygems.org/
specs:
charlock_holmes (0.7.3)
rake (12.0.0)
PLATFORMS
ruby
DEPENDENCIES
charlock_holmes
rake
BUNDLED WITH
1.13.7

View File

@ -1,7 +1,5 @@
# [Learn X in Y minutes][1]
[![Build Status](https://travis-ci.org/adambard/learnxinyminutes-docs.svg?branch=master)](https://travis-ci.org/adambard/learnxinyminutes-docs)
Whirlwind tours of (several, hopefully many someday) popular and
ought-to-be-more-popular programming languages, presented as valid, commented
code and explained as they go.

View File

@ -1,23 +0,0 @@
task default: %w[encoding yaml return_code]
$failure = 0
task :encoding do
begin
ruby 'tests/encoding.rb'
rescue Exception => msg
puts msg
$failure += 1
end
end
task :yaml do
begin
ruby 'tests/yaml.rb'
rescue Exception => msg
puts msg
$failure += 1
end
end
task :return_code do
if $failure != 0
raise "Failed #{$failure} tests!!"
end
end

View File

@ -2,10 +2,10 @@
language: Ada
filename: learn.ada
contributors:
["Luke A. Guest", "https://github.com/Lucretia"]
["Fernando Oleo Blanco", "https://github.com/Irvise"]
["Fabien Chouteau", "https://github.com/Fabien-Chouteau"]
["Manuel", "https://github.com/mgrojo"]
- ["Luke A. Guest", "https://github.com/Lucretia"]
- ["Fernando Oleo Blanco", "https://github.com/Irvise"]
- ["Fabien Chouteau", "https://github.com/Fabien-Chouteau"]
- ["Manuel", "https://github.com/mgrojo"]
---
Ada is a strong statically typed imperative, [object-oriented](https://ada-lang.io/docs/arm/AA-3/AA-3.9), [real-time](https://ada-lang.io/docs/arm/AA-D), [parallel](https://ada-lang.io/docs/arm/AA-9) and [distributed](https://ada-lang.io/docs/arm/AA-9) programming language from the Pascal/Algol family of languages, but nowadays, it only has a passing resemblance to Pascal, with the only remnants left being the ```begin/end``` keyword pair, the ```:=``` assignment symbol, records and ```if/case``` control statement structures.

View File

@ -1,212 +1,219 @@
---
category: tool
tool: amd
contributors:
- ["Frederik Ring", "https://github.com/m90"]
filename: learnamd.js
---
## Getting Started with AMD
The **Asynchronous Module Definition** API specifies a mechanism for defining
JavaScript modules such that the module and its dependencies can be asynchronously
loaded. This is particularly well suited for the browser environment where
synchronous loading of modules incurs performance, usability, debugging, and
cross-domain access problems.
### Basic concept
```javascript
// The basic AMD API consists of nothing but two methods: `define` and `require`
// and is all about module definition and consumption:
// `define(id?, dependencies?, factory)` defines a module
// `require(dependencies, callback)` imports a set of dependencies and
// consumes them in the passed callback
// Let's start by using define to define a new named module
// that has no dependencies. We'll do so by passing a name
// and a factory function to define:
define('awesomeAMD', function(){
var isAMDAwesome = function(){
return true;
};
// The return value of a module's factory function is
// what other modules or require calls will receive when
// requiring our `awesomeAMD` module.
// The exported value can be anything, (constructor) functions,
// objects, primitives, even undefined (although that won't help too much).
return isAMDAwesome;
});
// Now, let's define another module that depends upon our `awesomeAMD` module.
// Notice that there's an additional argument defining our
// module's dependencies now:
define('loudmouth', ['awesomeAMD'], function(awesomeAMD){
// dependencies will be passed to the factory's arguments
// in the order they are specified
var tellEveryone = function(){
if (awesomeAMD()){
alert('This is sOoOo rad!');
} else {
alert('Pretty dull, isn\'t it?');
}
};
return tellEveryone;
});
// As we do know how to use define now, let's use `require` to
// kick off our program. `require`'s signature is `(arrayOfDependencies, callback)`.
require(['loudmouth'], function(loudmouth){
loudmouth();
});
// To make this tutorial run code, let's implement a very basic
// (non-asynchronous) version of AMD right here on the spot:
function define(name, deps, factory){
// notice how modules without dependencies are handled
define[name] = require(factory ? deps : [], factory || deps);
}
function require(deps, callback){
var args = [];
// first let's retrieve all the dependencies needed
// by the require call
for (var i = 0; i < deps.length; i++){
args[i] = define[deps[i]];
}
// satisfy all the callback's dependencies
return callback.apply(null, args);
}
// you can see this code in action here: http://jsfiddle.net/qap949pd/
```
### Real-world usage with require.js
In contrast to the introductory example, `require.js` (the most popular AMD library) actually implements the **A** in **AMD**, enabling you to load modules and their dependencies asynchronously via XHR:
```javascript
/* file: app/main.js */
require(['modules/someClass'], function(SomeClass){
// the callback is deferred until the dependency is loaded
var thing = new SomeClass();
});
console.log('So here we are, waiting!'); // this will run first
```
By convention, you usually store one module in one file. `require.js` can resolve module names based on file paths, so you don't have to name your modules, but can simply reference them using their location. In the example `someClass` is assumed to be in the `modules` folder, relative to your configuration's `baseUrl`:
* app/
* main.js
* modules/
* someClass.js
* someHelpers.js
* ...
* daos/
* things.js
* ...
This means we can define `someClass` without specifying a module id:
```javascript
/* file: app/modules/someClass.js */
define(['daos/things', 'modules/someHelpers'], function(thingsDao, helpers){
// module definition, of course, will also happen asynchronously
function SomeClass(){
this.method = function(){/**/};
// ...
}
return SomeClass;
});
```
To alter the default path mapping behavior use `requirejs.config(configObj)` in your `main.js`:
```javascript
/* file: main.js */
requirejs.config({
baseUrl : 'app',
paths : {
// you can also load modules from other locations
jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min',
coolLibFromBower : '../bower_components/cool-lib/coollib'
}
});
require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolLib, helpers){
// a `main` file needs to call require at least once,
// otherwise no code will ever run
coolLib.doFancyStuffWith(helpers.transform($('#foo')));
});
```
`require.js`-based apps will usually have a single entry point (`main.js`) that is passed to the `require.js` script tag as a data-attribute. It will be automatically loaded and executed on pageload:
```html
<!DOCTYPE html>
<html>
<head>
<title>A hundred script tags? Never again!</title>
</head>
<body>
<script src="require.js" data-main="app/main"></script>
</body>
</html>
```
### Optimizing a whole project using r.js
Many people prefer using AMD for sane code organization during development, but still want to ship a single script file in production instead of performing hundreds of XHRs on page load.
`require.js` comes with a script called `r.js` (that you will probably run in node.js, although Rhino is supported too) that can analyse your project's dependency graph, and build a single file containing all your modules (properly named), minified and ready for consumption.
Install it using `npm`:
```shell
$ npm install requirejs -g
```
Now you can feed it with a configuration file:
```shell
$ r.js -o app.build.js
```
For our above example the configuration might look like:
```javascript
/* file : app.build.js */
({
name : 'main', // name of the entry point
out : 'main-built.js', // name of the file to write the output to
baseUrl : 'app',
paths : {
// `empty:` tells r.js that this should still be loaded from the CDN, using
// the location specified in `main.js`
jquery : 'empty:',
coolLibFromBower : '../bower_components/cool-lib/coollib'
}
})
```
To use the built file in production, simply swap `data-main`:
```html
<script src="require.js" data-main="app/main-built"></script>
```
An incredibly detailed [overview of build options](https://github.com/jrburke/r.js/blob/master/build/example.build.js) is available in the GitHub repo.
### Topics not covered in this tutorial
* [Loader plugins / transforms](http://requirejs.org/docs/plugins.html)
* [CommonJS style loading and exporting](http://requirejs.org/docs/commonjs.html)
* [Advanced configuration](http://requirejs.org/docs/api.html#config)
* [Shim configuration (loading non-AMD modules)](http://requirejs.org/docs/api.html#config-shim)
* [CSS loading and optimizing with require.js](http://requirejs.org/docs/optimization.html#onecss)
* [Using almond.js for builds](https://github.com/jrburke/almond)
### Further reading:
* [Official Spec](https://github.com/amdjs/amdjs-api/wiki/AMD)
* [Why AMD?](http://requirejs.org/docs/whyamd.html)
* [Universal Module Definition](https://github.com/umdjs/umd)
### Implementations:
* [require.js](http://requirejs.org)
* [dojo toolkit](http://dojotoolkit.org/documentation/tutorials/1.9/modules/)
* [cujo.js](http://cujojs.com/)
* [curl.js](https://github.com/cujojs/curl)
* [lsjs](https://github.com/zazl/lsjs)
* [mmd](https://github.com/alexlawrence/mmd)
---
category: tool
tool: amd
contributors:
- ["Frederik Ring", "https://github.com/m90"]
filename: learnamd.js
---
## Getting Started with AMD
The **Asynchronous Module Definition** API specifies a mechanism for defining
JavaScript modules such that the module and its dependencies can be asynchronously
loaded. This is particularly well suited for the browser environment where
synchronous loading of modules incurs performance, usability, debugging, and
cross-domain access problems.
### Basic concept
```javascript
// The basic AMD API consists of nothing but two methods: `define` and `require`
// and is all about module definition and consumption:
// `define(id?, dependencies?, factory)` defines a module
// `require(dependencies, callback)` imports a set of dependencies and
// consumes them in the passed callback
// Let's start by using define to define a new named module
// that has no dependencies. We'll do so by passing a name
// and a factory function to define:
define('awesomeAMD', function(){
var isAMDAwesome = function(){
return true;
};
// The return value of a module's factory function is
// what other modules or require calls will receive when
// requiring our `awesomeAMD` module.
// The exported value can be anything, (constructor) functions,
// objects, primitives, even undefined (although that won't help too much).
return isAMDAwesome;
});
// Now, let's define another module that depends upon our `awesomeAMD` module.
// Notice that there's an additional argument defining our
// module's dependencies now:
define('loudmouth', ['awesomeAMD'], function(awesomeAMD){
// dependencies will be passed to the factory's arguments
// in the order they are specified
var tellEveryone = function(){
if (awesomeAMD()){
alert('This is sOoOo rad!');
} else {
alert('Pretty dull, isn\'t it?');
}
};
return tellEveryone;
});
// As we do know how to use define now, let's use `require` to
// kick off our program. `require`'s signature is `(arrayOfDependencies, callback)`.
require(['loudmouth'], function(loudmouth){
loudmouth();
});
// To make this tutorial run code, let's implement a very basic
// (non-asynchronous) version of AMD right here on the spot:
function define(name, deps, factory){
// notice how modules without dependencies are handled
define[name] = require(factory ? deps : [], factory || deps);
}
function require(deps, callback){
var args = [];
// first let's retrieve all the dependencies needed
// by the require call
for (var i = 0; i < deps.length; i++){
args[i] = define[deps[i]];
}
// satisfy all the callback's dependencies
return callback.apply(null, args);
}
// you can see this code in action here: http://jsfiddle.net/qap949pd/
```
### Real-world usage with require.js
In contrast to the introductory example, `require.js` (the most popular AMD library) actually implements the **A** in **AMD**, enabling you to load modules and their dependencies asynchronously via XHR:
```javascript
/* file: app/main.js */
require(['modules/someClass'], function(SomeClass){
// the callback is deferred until the dependency is loaded
var thing = new SomeClass();
});
console.log('So here we are, waiting!'); // this will run first
```
By convention, you usually store one module in one file. `require.js` can resolve module names based on file paths, so you don't have to name your modules, but can simply reference them using their location. In the example `someClass` is assumed to be in the `modules` folder, relative to your configuration's `baseUrl`:
* app/
* main.js
* modules/
* someClass.js
* someHelpers.js
* ...
* daos/
* things.js
* ...
This means we can define `someClass` without specifying a module id:
```javascript
/* file: app/modules/someClass.js */
define(['daos/things', 'modules/someHelpers'], function(thingsDao, helpers){
// module definition, of course, will also happen asynchronously
function SomeClass(){
this.method = function(){/**/};
// ...
}
return SomeClass;
});
```
To alter the default path mapping behavior use `requirejs.config(configObj)` in your `main.js`:
```javascript
/* file: main.js */
requirejs.config({
baseUrl : 'app',
paths : {
// you can also load modules from other locations
jquery : '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min',
coolLibFromBower : '../bower_components/cool-lib/coollib'
}
});
require(['jquery', 'coolLibFromBower', 'modules/someHelpers'], function($, coolLib, helpers){
// a `main` file needs to call require at least once,
// otherwise no code will ever run
coolLib.doFancyStuffWith(helpers.transform($('#foo')));
});
```
`require.js`-based apps will usually have a single entry point (`main.js`) that is passed to the `require.js` script tag as a data-attribute. It will be automatically loaded and executed on pageload:
```html
<!DOCTYPE html>
<html>
<head>
<title>A hundred script tags? Never again!</title>
</head>
<body>
<script src="require.js" data-main="app/main"></script>
</body>
</html>
```
### Optimizing a whole project using r.js
Many people prefer using AMD for sane code organization during development, but still want to ship a single script file in production instead of performing hundreds of XHRs on page load.
`require.js` comes with a script called `r.js` (that you will probably run in node.js, although Rhino is supported too) that can analyse your project's dependency graph, and build a single file containing all your modules (properly named), minified and ready for consumption.
Install it using `npm`:
```shell
$ npm install requirejs -g
```
Now you can feed it with a configuration file:
```shell
$ r.js -o app.build.js
```
For our above example the configuration might look like:
```javascript
/* file : app.build.js */
({
name : 'main', // name of the entry point
out : 'main-built.js', // name of the file to write the output to
baseUrl : 'app',
paths : {
// `empty:` tells r.js that this should still be loaded from the CDN, using
// the location specified in `main.js`
jquery : 'empty:',
coolLibFromBower : '../bower_components/cool-lib/coollib'
}
})
```
To use the built file in production, simply swap `data-main`:
```html
<script src="require.js" data-main="app/main-built"></script>
```
An incredibly detailed [overview of build options](https://github.com/jrburke/r.js/blob/master/build/example.build.js) is available in the GitHub repo.
### Topics not covered in this tutorial
* [Loader plugins / transforms](http://requirejs.org/docs/plugins.html)
* [CommonJS style loading and exporting](http://requirejs.org/docs/commonjs.html)
* [Advanced configuration](http://requirejs.org/docs/api.html#config)
* [Shim configuration (loading non-AMD modules)](http://requirejs.org/docs/api.html#config-shim)
* [CSS loading and optimizing with require.js](http://requirejs.org/docs/optimization.html#onecss)
* [Using almond.js for builds](https://github.com/jrburke/almond)
### Further reading:
* [Official Spec](https://github.com/amdjs/amdjs-api/wiki/AMD)
* [Why AMD?](http://requirejs.org/docs/whyamd.html)
* [Universal Module Definition](https://github.com/umdjs/umd)
### Implementations:
* [require.js](http://requirejs.org)
* [dojo toolkit](http://dojotoolkit.org/documentation/tutorials/1.9/modules/)
* [cujo.js](http://cujojs.com/)
* [curl.js](https://github.com/cujojs/curl)
* [lsjs](https://github.com/zazl/lsjs)
* [mmd](https://github.com/alexlawrence/mmd)

View File

@ -1,6 +1,6 @@
---
category: tool
tool: AngularJS
category: framework
framework: AngularJS
contributors:
- ["Walter Cordero", "http://waltercordero.com"]
filename: learnangular.html

View File

@ -632,7 +632,7 @@ fact_caching_timeout = 86400
```
I like to use `jsonfile` as my backend. It allows to use another project
`ansible-cmdb` [(project on github)](https://github.com/fboender/ansible-cmdb) that generates a HTML page of your inventory
`ansible-cmdb` [(project on GitHub)](https://github.com/fboender/ansible-cmdb) that generates a HTML page of your inventory
resources. A nice 'free' addition!
### Debugging ansible [chapter in progress]

69
apl.html.markdown Normal file
View File

@ -0,0 +1,69 @@
---
language: APL
contributors:
- ["nooodl", "https://github.com/nooodl"]
filename: learnapl.apl
---
```apl
⍝ Comments in APL are prefixed by ⍝.
⍝ A list of numbers. (¯ is negative)
2 3e7 ¯4 50.3
⍝ An expression, showing some functions. In APL, there's
⍝ no order of operations: everything is parsed right-to-
⍝ left. This is equal to 5 + (4 × (2 ÷ (5 - 3))) = 9:
5 + 4 × 2 ÷ 5 - 3 ⍝ 9
⍝ These functions work on lists, too:
1 2 3 4 × 5 ⍝ 5 10 15 20
1 2 3 4 × 5 6 7 8 ⍝ 5 12 21 32
⍝ All functions have single-argument and dual-argument
⍝ meanings. For example, "×" applied to two arguments
⍝ means multiply, but when applied to only a right-hand
⍝ side, it returns the sign:
× ¯4 ¯2 0 2 4 ⍝ ¯1 ¯1 0 1 1
⍝ Values can be compared using these operators (1 means
⍝ "true", 0 means "false"):
10 20 30 = 10 20 99 ⍝ 1 1 0
10 20 30 < 10 20 99 0 0 1
⍝ "n" returns a vector containing the first n naturals.
⍝ Matrices can be constructed using (reshape):
4 3 5 ⍝ 0 1 2
⍝ 3 4 0
⍝ 1 2 3
⍝ 4 0 1
⍝ Single-argument gives you the dimensions back:
4 3 5 ⍝ 4 3
⍝ Values can be stored using ←. Let's calculate the mean
⍝ value of a vector of numbers:
A ← 10 60 55 23
⍝ Sum of elements of A (/ is reduce):
+/A ⍝ 148
⍝ Length of A:
A ⍝ 4
⍝ Mean:
(+/A) ÷ (A) ⍝ 37
⍝ We can define this as a function using {} and ⍵:
mean ← {(+/⍵)÷⍴⍵}
mean A ⍝ 37
```
## Further Reading
- [APL Wiki](https://aplwiki.com/)
- An older version of APL book by the creator: [Kenneth Iverson - A Programming Language](https://www.softwarepreservation.org/projects/apl/Books/APROGRAMMING%20LANGUAGE/view)
- Additional Books: [APL Books](https://aplwiki.com/wiki/Books)

View File

@ -107,7 +107,6 @@ HTML اختصار ل HyperText Markup Language، أي "لغة ترميز الن
<td>الصف الثاني، العمود الأول</td>
</tr>
</table>
```
## الاستعمال

View File

@ -17,12 +17,9 @@ filename: learnpython-ar.py
لقد أُنشئت لغة البايثون بواسطة جايدو ڤان روسم في بداية التسعينات. هي الأن أحد أشهر اللغات الموجودة.
لقد أحببت لغة البايثون بسبب وضوحها. هي في الأساس عبارة عن سودوكود قابل للتنفيذ.
ردود أفعالكم عن المقال مُقدرة بشدة. يمكنكم التواصل مع الكاتب الاساسي من خلال [@louiedinh](http://twitter.com/louiedinh) أو louiedinh [at] [google's email service]
ملحوظة: هذا المقال يُطبق على بايثون 3 فقط. راجع المقال [هنا](http://learnxinyminutes.com/docs/pythonlegacy/) إذا أردت تعلم لغة البايثون نسخة 2.7 الأقدم
```python
# تعليق من سطر واحد يبدأ برمز الرقم.
""" يمكن كتابة تعليق يتكون من أكثر من سطر
@ -1006,14 +1003,11 @@ print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
### مجانا عبر الانترنت
* [أتمتتة المهمات المُملة عبر بايثون](https://automatetheboringstuff.com)
* [أفكار لمشروعات بلغة البايثون](http://pythonpracticeprojects.com)
* [التوثيقات الرسمية](http://docs.python.org/3/)
* [دليل المُسافر لبايثون](http://docs.python-guide.org/en/latest/)
* [دورة بايثون](http://www.python-course.eu/index.php)
* [أولى الخطوات مع بايثون](https://realpython.com/learn/python-first-steps/)
* [قائمة مُختارة من إطارات عمل بايثون الرائعة, المكتبات والبرمجيات](https://github.com/vinta/awesome-python)
* [ثلاثون خاصية وخدعة للغة البايثون ربما لم تعرف بها](http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html)
* [الدليل الرسمي لنمط البايثون](https://www.python.org/dev/peps/pep-0008/)
* [الدليل الرسمي لنمط البايثون](https://peps.python.org/pep-0008/)
* [بايثون 3 دوائر علوم الحاسب](http://cscircles.cemc.uwaterloo.ca/)
* [غُص في بايثون 3](http://www.diveintopython3.net/index.html)
* [دورة سريعة في البايثون للعلماء](http://nbviewer.jupyter.org/gist/anonymous/5924718)

View File

@ -27,9 +27,9 @@ QUIT , EXIT
في الامثلة بالأسفل تعتمدالعديد من الأوامرأن قاعدة بيانات الموظفين
[MySQL employee sample database](https://dev.mysql.com/doc/employee/en/)
الموجودة على
[github](https://github.com/datacharmer/test_db)
[GitHub](https://github.com/datacharmer/test_db)
قد تم تحميلها مسبقا. الملفات على
github
GitHub
هي مجموعة من الاوامر تشبه الموجودة بالاسفل و تقوم الأوامر بإنشاء الجدوال وإدخال بيانات مجموعة من الموظفين المتخيلين في شركة. تعتمد الأوامر المستخدمة في هذا البرنامج على نسخة
SQL
التي تستخدمها،
@ -125,6 +125,7 @@ DELETE FROM tablename1;
-- تماما tablename1 إزالة جدول
DROP TABLE tablename1;
```
<div dir="rtl">
## اقرأ أكثر

View File

@ -81,7 +81,6 @@ Section Titles
==== Level 3 <h4>
===== Level 4 <h5>
```
Lists

View File

@ -1,5 +1,5 @@
---
language: Assemblyscript
language: AssemblyScript
contributors:
- ["Philippe Vlérick", "https://github.com/pvlerick"]
- ["Steve Huguenin-Elie", "https://github.com/StEvUgnIn"]
@ -13,7 +13,7 @@ __AssemblyScript__ compiles a variant of __TypeScript__ (basically JavaScript wi
This article will focus only on AssemblyScript extra syntax, as opposed to [TypeScript](/docs/typescript) and [JavaScript](/docs/javascript).
To test AssemblyScript's compiler, head to the
[Playground](https://bit.ly/asplayground) where you will be able
[Playground](https://www.assemblyscript.org/editor.html#IyFydW50aW1lPXN0dWIKLyoqIENhbGN1bGF0ZXMgdGhlIG4tdGggRmlib25hY2NpIG51bWJlci4gKi8KZXhwb3J0IGZ1bmN0aW9uIGZpYihuOiBpMzIpOiBpMzIgewogIHZhciBhID0gMCwgYiA9IDEKICBpZiAobiA+IDApIHsKICAgIHdoaWxlICgtLW4pIHsKICAgICAgbGV0IHQgPSBhICsgYgogICAgICBhID0gYgogICAgICBiID0gdAogICAgfQogICAgcmV0dXJuIGIKICB9CiAgcmV0dXJuIGEKfQoKIyFodG1sCjx0ZXh0YXJlYSBpZD0ib3V0cHV0IiBzdHlsZT0iaGVpZ2h0OiAxMDAlOyB3aWR0aDogMTAwJSIgcmVhZG9ubHk+PC90ZXh0YXJlYT4KPHNjcmlwdD4KbG9hZGVyLmluc3RhbnRpYXRlKG1vZHVsZV93YXNtLCB7IC8qIGltcG9ydHMgKi8gfSkKICAudGhlbigoeyBleHBvcnRzIH0pID0+IHsKICAgIGNvbnN0IG91dHB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdvdXRwdXQnKQogICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gMTA7ICsraSkgewogICAgICBvdXRwdXQudmFsdWUgKz0gYGZpYigke2l9KSA9ICR7ZXhwb3J0cy5maWIoaSl9XG5gCiAgICB9CiAgfSkKPC9zY3JpcHQ+Cg==) where you will be able
to type code, have auto completion and directly see the emitted WebAssembly.
```ts
@ -144,11 +144,11 @@ export namespace Geometry {
let s1 = new Geometry.Square(5);
// Generics
// AssemblyScript compiles generics to one concrete method or function per set
// of unique contextual type arguments, also known as [monomorphisation].
// Implications are that a module only includes and exports concrete functions
// for sets of type arguments actually used and that concrete functions can be
// shortcutted with [static type checks] at compile time, which turned out to
// AssemblyScript compiles generics to one concrete method or function per set
// of unique contextual type arguments, also known as [monomorphisation].
// Implications are that a module only includes and exports concrete functions
// for sets of type arguments actually used and that concrete functions can be
// shortcutted with [static type checks] at compile time, which turned out to
// be quite useful.
// Classes
export class Tuple<T1, T2> {
@ -193,10 +193,10 @@ let doubles = [0.0, 1.0, 2, 3, 4] // will infer as Array<f64>
let bytes1 = [0 as u8, 1, 2, 3, 4] // will infer as Array<u8>
let bytes2 = [0, 1, 2, 3, 4] as u8[] // will infer as Array<u8>
let bytes3: u8[] = [0, 1, 2, 3, 4] // will infer as Array<u8>
```
## Further Reading
* [AssemblyScript Official website] (https://www.assemblyscript.org/)
* [AssemblyScript source documentation] https://github.com/AssemblyScript/website/tree/main/src)
* [Source Code on GitHub] (https://github.com/AssemblyScript/assemblyscript)
* [AssemblyScript Official website](https://www.assemblyscript.org/)
* [AssemblyScript source documentation](https://github.com/AssemblyScript/website/tree/main/src)
* [Source Code on GitHub](https://github.com/AssemblyScript/assemblyscript)

View File

@ -375,7 +375,6 @@ END {
if (nlines)
print "The average age for " name " is " sum / nlines;
}
```
Further Reading:

View File

@ -4,7 +4,7 @@ contributors:
- ["Btup"]
filename: learnbc.bc
---
```c
```bc
/*This is a multi-
line comment.*/
# This is also a (one-line) comment! (in GNU bc).
@ -29,27 +29,23 @@ hour = read() /*Input a number*/
if(hour < 12) { /*Operators are exactly like C.*/
print "Good morning\n" /*"print" outputs strings or variables
separated by commas.*/
separated by commas.*/
} else if(hour == 12) {
print "Hello\n"
/*Escaping sequences start with a \ in a string.
In order to make the escaping sequences clearer, here
is a simplified list of them that will work in bc:
is a simplified list of them that will work in bc:
\b: backspace
\c: carriage return
\n: newline
\t: tab
\\: backslash*/
} else {
/*Variables are global by default.*/
thisIsGlobal = 5
/*You can make a variable local. Use the "auto" keyword in a function.*/
print "Good afternoon\n"
}
/*Every variable is pre-set to 0.*/
num = blankVariable /*num is set to 0.*/
/*Like C, only 0 is falsy.*/
num = 0
if(!num) {print "false\n"}
/*Unlike C, bc does not have the ?: operators. For example,
@ -93,6 +89,7 @@ print a[0], " ", a[1], " ", a[2], " ", a[3], "\n"
quit /*Add this line of code to make sure
that your program exits. This line of code is optional.*/
```
Enjoy this simple calculator! (Or this programming language, to be exact.)
This whole program is written in GNU bc. To run it, use ```bc learnbc.bc```.

File diff suppressed because it is too large Load Diff

288
bqn.html.markdown Normal file
View File

@ -0,0 +1,288 @@
---
language: BQN
filename: learnbqn.bqn
contributors:
- ["Raghu Ranganathan", "https://github.com/razetime"]
---
BQN is a modern array language (similar to APL) that aims to eliminate burdensome aspects of the APL tradition.
It is recommended to try these code examples out in a REPL. The [online REPL](https://mlochbaum.github.io/BQN/try.html) is
recommended for quick start, since it comes with keyboard and easy to access help. You can try building
[CBQN](https://github.com/dzaima/CBQN) for a local install, but it will need keyboard setup.
```bqn
# This is a comment.
# The characters ',' and `⋄` are statement separators.
##################
# Main datatypes #
##################
# Numbers
1,2,3,4
¯1,¯2,¯3 # Negative numbers are written with a high minus
π,∞,¯π,¯∞ # Pi and Infinity are defined constants
1_234_456 # You can add underscores in between numbers
# This does not change their value
1.3E4 # Scientific notation is supported
# Characters
'a','⥊'
'
' # Yes, you can put *any* character in a character literal
@ # Null character ('\0' in C)
# Arrays
1‿2‿3 # Stranding, good for simple lists
⟨1,2,3⟩ # General list notation
⟨1‿2,2‿3⟩ # Both can be mixed
[1‿2,2‿3] # Array notation
# An array is multidimensional, as opposed to containing sublists.
# It must be rectangular in shape (a grid structure rather than a tree structure)
[1‿2‿3,4‿5] # This is hence invalid
# May be familiar coming from Numpy, MATLAB and similar languages.
"asdf" # Character array (String)
"newline
separated" # Allows newlines
"quo""tes" # Escape a double quote by typing it twice
# Functions
1{𝕨+𝕩}3 # All functions are infix
# 𝕨 is left argument, 𝕩 is right argument
{-𝕩}5 # 𝕨 can be omitted
1+3 # Same as the above
{𝕊𝕩} # 𝕊 is a recursive call
# (this function will loop forever)
{𝕨 𝕊 𝕩: 𝕨+𝕩} # Functions can have headers (too many cases to discuss here)
# Headers can define arity
{𝕊 a‿b: a}1‿2 # and also do basic pattern matching
# (returns 1)
# Modifiers (higher order functions)
{𝕗,𝔽,𝕘,𝔾} # 𝔽 and 𝔾 are the operands as callable functions
# 𝕗 and 𝕘 are the operands as values
{𝔽𝕩} # 1-modifiers use 𝔽/𝕗 ONLY
˜,˘,¨,⁼,⌜ # primitive 1-modifiers are superscripts
{𝕨𝔽𝔾𝕩} # 2-modifiers MUST use both 𝔽/𝕗 and 𝔾/𝕘 in body or header
⊸,∘,○,⟜ # primitive 2-modifiers all have circles
+{⟨𝕗⟩} # returns ⟨ + ⟩
1-{𝔽 𝕨 𝔾 𝕩 }×2 # returns ¯2 (operators are *also* infix)
# (same as 1 -○× 2)
# Trains (Special form of function composition)
(+´÷≠) # Average (but how?)
# The above train is an F G H train, where
# (F G H) 𝕩 → (F 𝕩) G (H 𝕩)
# F ← +´, G ← ÷, H ← ≠
# In explicit form, this is
{(+´𝕩)÷≠𝕩}
# The second pattern is (f g) 𝕩 → f g 𝕩.
# longer trains are complex arrangements of these patterns, involving constants and Nothing (·).
# Read more about trains at https://mlochbaum.github.io/BQN/doc/train.html
# Evaluation order:
# BQN evaluates functions right to left with no precedence rules governing *functions*. Functions are what
# one would call operators in a mainstream language.
1÷2+3 # 1÷(2+3) = 0.2
(1÷2)+3 # ((1÷2)+3) = 1.5
# Modifiers:
# Modifiers are higher order functions, and bind tighter than functions. Modifiers execute left to right.
# Modifiers can take non-function arguments e.g. Constant (`˙`)
+
1+˜2+○-∘×3 # 1(+˜)(2((+○-)∘×)3)
# Variables
# Since the case of a variable matters to determine what it means, BQN variables are *case insensitive*
# The case that a variable is written in can change the way it is interpreted by BQN.
# Eg. `F` refers to a value as a callable function, whereas `f` refers to the same variable as just a value.
# Variable assignment is done with `←`. Variables have naming conventions based on their value:
subject ← 1‿2‿3 # Arrays, single values, namespaces come under this
# name must start with with a lowercase letter
Function ← {𝕨+𝕩} # Primitive and user defined functions come under this, both monadic and dyadic
# Starts with an uppercase letter
_1modifier ← {𝕨𝔽𝕩} # Starts with an underscore
_2modifier_ ← {𝔽𝕨𝔾𝕩} # Starts and ends with an underscore
# Variable modification is done with `↩`. An existing name cannot be reassigned with `←`.
Func ↩ {"Hello"∾𝕩}
array_or_atom +↩ 2 # You can use a dyadic function for modification
#≡ 3‿4‿5
array_or_atom -↩ # Or a monadic function.
#≡ ¯3‿¯4‿¯5
# Due to all functions being infix, you can use your own functions for modification as well:
array_or_atom {2⋆𝕩}↩ #≡ ⟨ 0.125, 0.0625, 0.03125 ⟩
##################
# BQN Primitives #
##################
# All of BQN's base primitives are a single character long. Refer to https://mlochbaum.github.io/BQN/help/index.html for
# examples.
# Here we will look at a few primitives from each section. You will want to consult the docs for detailed explanations.
# Primitive Functions
# All BQN functions are variadic, and can take one or two arguments. The base functions have both monadic and dyadic overloads.
# Usually the two overloads for a function are related.
## Arithmetic Functions
+, -, ×, ÷ # Add, Subtract, Signum/Multiply, Reciprocal/Divide , '*' does NOT do multiplication
# ⌊∘÷ does floor division
√, ⋆ # Square root/Nth root, e^x/Power
# All Arithmetic functions vectorize:
1 + 2‿3‿4 #≡ 3‿4‿5
1‿2‿3 + 2‿3‿4 #≡ 3‿5‿7
# Character arithmetic(+ and - only):
"abc"+3 #≡ "def"
'a'-'d' #≡ ¯3
## Logic Functions
∧, , ¬ # For Booleans, return 1 or 0
≤, <, >, ≥, = # Vectorizing comparisons
≡, ≢ # Nonvectorizing comparisons
## Array manipulation Functions
↕ # Make a range
∾, ≍, ⋈ # Joining arrays together
a←1‿2‿3,b←4‿5 # Let us take a and b.
a∾b #≡ 1‿2‿3‿4‿5
a≍b # Same as previous, since a and b are not multidimensional
# Adds an extra dimension, similar to a ⋈ for multidimensional arrays.
a⋈b #≡ ⟨1‿2‿3, 4‿5⟩
⊑, ⊏ # Indexing
1⊑1‿2‿3 #≡ 2 (BQN is 0-indexed)
1‿2⊏1‿2‿3 #≡ 2‿3 (for multiple indices)
↑, ↓ # Getting a prefix, suffix of an array.
# together they can be used for slicing
⥊ # Reshape/repeat items to create a new array
# Primitive 1-Modifiers
## Looping combinators
¨, ˘, ⌜ # Mapping/Zipping
´, ˝ # Fold from right
` # Scan from left
## General combinators
˜ # duplicate argument/swap args - Very useful!
˙ # Create constant function
1 -˜ 2 #≡ 2 - 1
+˜ 2 #≡ 2 + 2
# Primitive 2-modifiers
## Control Flow
◶ # Choose from a list of funcs
⍟ # Repeat n times
## General Combinators
⊸, ⟜ # hook, hookf
∘, ○ # simple function composition
##########
# Blocks #
##########
# Code delimited by {}
# Lexically scoped
# For more info: https://mlochbaum.github.io/BQN/doc/block.html
# Can have headers, which are ways to explicitly define what a block should be.
# A block without headers is automatically inferred from its special variables (𝕨, 𝕩, ...).
# Function blocks
# Implicit variables(Capitals are functions):
# - 𝕨, 𝕎 left argument
# - 𝕩, 𝕏 right argument
# - 𝕤, 𝕊 represent the block itself
# Optional: one or more headers that trigger based on
# - pattern match (':') o
# - condition ('?') (similar to if-then-else)
{ # A factorial using headers:
𝕊 0: 1;
𝕊 𝕩: 𝕩×𝕊 𝕩-1
}
{ # Factorial with predicates
𝕩<2 ? 1; # Similar to an if-else pattern.
𝕩×𝕊 𝕩-1
}
# Modifier blocks
# create 1-modifiers and 2-modifiers, which have separate types
# Implicit variables(Capitals are functions):
# - has 𝕨 and 𝕩 if needed
# - 𝕗, 𝔽 left operand
# - 𝕘, 𝔾 right operand (only in 2-modifiers)
# - 𝕣 represents the block itself* (requires underscores as per convention)
# Same header rules as functions.
{ 𝕨=0 ? 𝔽 𝕩; 𝔾 𝕩 } # execute 𝔽 or 𝔾 based on whether left argument is 0.
# Namespace blocks
# Create immutable namespaces with fields
# Require exports (`⇐`) for accessible fields.
# Use '.' for field access
n←{
A←+
b⇐4
}
n.b #≡ 4
n.a # ERROR
# Immediate Blocks
# No arguments taken
# Run the code inside and return the last statement
# Often responsible for strange errors.
# Can be mistaken for other blocks easily
# Good for avoiding scoping issues
{
1‿2‿3
}
{+} # Trick for returning a function as a value
####################
# Basic constructs #
####################
# Functional programming
# `¨` is used for mapping, as discussed before:
{𝕩∾2}¨1‿2‿3 #≡ ⟨1‿2,2‿2,3‿2⟩
# ⋈¨ is a plain zip, which produces pairs.
# `¨` acts as a zipWith when used with two arguments:
1‿2‿3 {⟨𝕩+2,2⥊𝕨⟩} 4‿5‿6 #≡ ⟨⟨6,1‿1⟩,⟨7,2‿2⟩,⟨8,3‿3⟩⟩
# `/` is replicate, which serves several purposes *including* filtering.
# elements in 𝕩 are repeated by the corresponding number in 𝕨.
1‿2‿3‿0/4‿5‿6‿7 #≡ 4‿5‿5‿6‿6‿6
# a simple filter idiom is F⊸/:
{2|𝕩}⊸/67‿42‿83 # keep the odd elements
#≡ 67‿83
# Conditionals
# There are two main ways to define a conditional.
## Predicate headers
{
𝕩 > 2: "greater than 2";
𝕩 < 2: "lesser than 2";
"equal to 2"
}
## Choose (function-based)
# - 2-modifier
# - 𝔾: list of functions that serve as bodies
# - 𝔽: condition function that specifies which function from 𝔾 to select
# The same conditional as above would be:
{⊑/⟨𝕩>2, 𝕩<2, 𝕩=2⟩}◶⟨
{𝕊: "greater than 2"}
{𝕊: "lesser than 2"}
{𝕊: "equal to 2"}
## Some helpers for conditionals
If ← {𝕏⍟𝕎@}´ # Used as If ⟨Condition, Block⟩
IfElse ← {c‿T‿F: c◶F‿T@} # Used as IfElse ⟨Condition, Block, ElseBlock⟩
# Looping
# The primary form of unbounded looping is recursion (performed with 𝕊).
# BQN does not eliminate tail calls, but the while idiom can be used to work around this:
While ← {𝕩{𝔽𝔾𝔽_𝕣_𝔾𝔽𝔾𝕩}𝕨@}´ # While 1‿{... to run forever
DoWhile ← {𝕏@ ⋄ While 𝕨‿𝕩}´
# A For loop can be done with ¨, functions need not be pure.
```
## Ready for more?
- [Quickstart guide](https://mlochbaum.github.io/BQN/doc/quick.html)
- [Full length, explained documentation](https://mlochbaum.github.io/BQN/doc/index.html)
- [Short docs](https://mlochbaum.github.io/BQN/help/index.html)
- [BQN community!](https://mlochbaum.github.io/BQN/community/index.html)

View File

@ -31,7 +31,7 @@ one of the most widely-used programming languages.
// Comparison to C
//////////////////
// C++ is _almost_ a superset of C and shares its basic syntax for
// C++ is almost a superset of C and shares its basic syntax for
// variable declarations, primitive types, and functions.
// Just like in C, your program's entry point is a function called
@ -55,24 +55,26 @@ int main(int argc, char** argv)
// However, C++ varies in some of the following ways:
// In C++, character literals are chars
sizeof('c') == sizeof(char) == 1
// In C++, character literals are chars, therefore the size is 1
sizeof('c') == sizeof(char)
// In C, character literals are ints
// In C, character literals are ints, therefore the size is 4
sizeof('c') == sizeof(int)
// C++ has strict prototyping
void func(); // function which accepts no arguments
void func(void); // same as earlier
// In C
void func(); // function which may accept any number of arguments
void func(); // function which may accept any number of arguments with unknown type
void func(void); // function which accepts no arguments
// Use nullptr instead of NULL in C++
int* ip = nullptr;
// C standard headers are available in C++.
// C headers end in .h, while
// Most C standard headers are available in C++.
// C headers generally end with .h, while
// C++ headers are prefixed with "c" and have no ".h" suffix.
// The C++ standard version:
@ -101,7 +103,7 @@ void print(char const* myString)
void print(int myInt)
{
printf("My int is %d", myInt);
printf("My int is %d\n", myInt);
}
int main()
@ -160,7 +162,7 @@ namespace Second {
}
void bar()
{
printf("This is Second::bar\n");
printf("This is Second::bar\n");
}
}
@ -193,22 +195,24 @@ int main()
#include <iostream> // Include for I/O streams
using namespace std; // Streams are in the std namespace (standard library)
int main()
{
int myInt;
int myInt;
// Prints to stdout (or terminal/screen)
cout << "Enter your favorite number:\n";
// Takes in input
cin >> myInt;
// Prints to stdout (or terminal/screen)
// std::cout referring the access to the std namespace
std::cout << "Enter your favorite number:\n";
// Takes in input
std::cin >> myInt;
// cout can also be formatted
cout << "Your favorite number is " << myInt << '\n';
// prints "Your favorite number is <myInt>"
// cout can also be formatted
std::cout << "Your favorite number is " << myInt << '\n';
// prints "Your favorite number is <myInt>"
cerr << "Used for error messages";
std::cerr << "Used for error messages";
// flush string stream buffer with new line
std::cout << "I flushed it away" << std::endl;
}
//////////
@ -218,20 +222,27 @@ int main()
// Strings in C++ are objects and have many member functions
#include <string>
using namespace std; // Strings are also in the namespace std (standard library)
string myString = "Hello";
string myOtherString = " World";
std::string myString = "Hello";
std::string myOtherString = " World";
// + is used for concatenation.
cout << myString + myOtherString; // "Hello World"
std::cout << myString + myOtherString; // "Hello World"
cout << myString + " You"; // "Hello You"
std::cout << myString + " You"; // "Hello You"
// C++ string length can be found from either string::length() or string::size()
cout << myString.length() + myOtherString.size(); // Outputs 11 (= 5 + 6).
// C++ strings are mutable.
myString.append(" Dog");
cout << myString; // "Hello Dog"
std::cout << myString; // "Hello Dog"
// C++ can handle C-style strings with related functions using cstrings
#include <cstring>
char myOldString[10] = "Hello CPP";
cout << myOldString;
cout << "Length = " << strlen(myOldString); // Length = 9
/////////////
// References
@ -245,35 +256,32 @@ cout << myString; // "Hello Dog"
// No * is needed for dereferencing and
// & (address of) is not used for assignment.
using namespace std;
std::string foo = "I am foo";
std::string bar = "I am bar";
string foo = "I am foo";
string bar = "I am bar";
string& fooRef = foo; // This creates a reference to foo.
std::string& fooRef = foo; // This creates a reference to foo.
fooRef += ". Hi!"; // Modifies foo through the reference
cout << fooRef; // Prints "I am foo. Hi!"
std::cout << fooRef; // Prints "I am foo. Hi!"
std::cout << &fooRef << '\n'; // Prints the address of foo
// Doesn't reassign "fooRef". This is the same as "foo = bar", and
// foo == "I am bar"
// after this line.
cout << &fooRef << endl; //Prints the address of foo
fooRef = bar;
cout << &fooRef << endl; //Still prints the address of foo
cout << fooRef; // Prints "I am bar"
std::cout << &fooRef << '\n'; // Still prints the address of foo
std::cout << fooRef << '\n'; // Prints "I am bar"
// The address of fooRef remains the same, i.e. it is still referring to foo.
const string& barRef = bar; // Create a const reference to bar.
const std::string& barRef = bar; // Create a const reference to bar.
// Like C, const values (and pointers and references) cannot be modified.
barRef += ". Hi!"; // Error, const references cannot be modified.
// Sidetrack: Before we talk more about references, we must introduce a concept
// called a temporary object. Suppose we have the following code:
string tempObjectFun() { ... }
string retVal = tempObjectFun();
std::string tempObjectFun() { ... }
std::string retVal = tempObjectFun();
// What happens in the second line is actually:
// - a string object is returned from tempObjectFun
@ -296,27 +304,27 @@ foo(bar(tempObjectFun()))
// which case its life gets extended to the current scope:
void constReferenceTempObjectFun() {
// constRef gets the temporary object, and it is valid until the end of this
// function.
const string& constRef = tempObjectFun();
...
// constRef gets the temporary object, and it is valid until the end of this
// function.
const std::string& constRef = tempObjectFun();
...
}
// Another kind of reference introduced in C++11 is specifically for temporary
// objects. You cannot have a variable of its type, but it takes precedence in
// overload resolution:
void someFun(string& s) { ... } // Regular reference
void someFun(string&& s) { ... } // Reference to temporary object
void someFun(std::string& s) { ... } // Regular reference
void someFun(std::string&& s) { ... } // Reference to temporary object
string foo;
std::string foo;
someFun(foo); // Calls the version with regular reference
someFun(tempObjectFun()); // Calls the version with temporary reference
// For example, you will see these two versions of constructors for
// std::basic_string:
basic_string(const basic_string& other);
basic_string(basic_string&& other);
std::basic_string(const basic_string& other);
std::basic_string(basic_string&& other);
// Idea being if we are constructing a new string from a temporary object (which
// is going to be destroyed soon anyway), we can have a more efficient
@ -331,15 +339,15 @@ basic_string(basic_string&& other);
// easier visualization and reading of code
enum ECarTypes
{
Sedan,
Hatchback,
SUV,
Wagon
Sedan,
Hatchback,
SUV,
Wagon
};
ECarTypes GetPreferredCarType()
{
return ECarTypes::Hatchback;
return ECarTypes::Hatchback;
}
// As of C++11 there is an easy way to assign a type to the enum which can be
@ -347,21 +355,21 @@ ECarTypes GetPreferredCarType()
// the desired type and their respective constants
enum ECarTypes : uint8_t
{
Sedan, // 0
Hatchback, // 1
SUV = 254, // 254
Hybrid // 255
Sedan, // 0
Hatchback, // 1
SUV = 254, // 254
Hybrid // 255
};
void WriteByteToFile(uint8_t InputValue)
{
// Serialize the InputValue to a file
// Serialize the InputValue to a file
}
void WritePreferredCarTypeToFile(ECarTypes InputCarType)
{
// The enum is implicitly converted to a uint8_t due to its declared enum type
WriteByteToFile(InputCarType);
// The enum is implicitly converted to a uint8_t due to its declared enum type
WriteByteToFile(InputCarType);
}
// On the other hand you may not want enums to be accidentally cast to an integer
@ -369,22 +377,22 @@ void WritePreferredCarTypeToFile(ECarTypes InputCarType)
// won't be implicitly converted
enum class ECarTypes : uint8_t
{
Sedan, // 0
Hatchback, // 1
SUV = 254, // 254
Hybrid // 255
Sedan, // 0
Hatchback, // 1
SUV = 254, // 254
Hybrid // 255
};
void WriteByteToFile(uint8_t InputValue)
{
// Serialize the InputValue to a file
// Serialize the InputValue to a file
}
void WritePreferredCarTypeToFile(ECarTypes InputCarType)
{
// Won't compile even though ECarTypes is a uint8_t due to the enum
// being declared as an "enum class"!
WriteByteToFile(InputCarType);
// Won't compile even though ECarTypes is a uint8_t due to the enum
// being declared as an "enum class"!
WriteByteToFile(InputCarType);
}
//////////////////////////////////////////
@ -565,7 +573,7 @@ Point& Point::operator+=(const Point& rhs)
{
x += rhs.x;
y += rhs.y;
// `this` is a pointer to the object, on which a method is called.
return *this;
}
@ -577,7 +585,7 @@ int main () {
// Point up calls the + (function) with right as its parameter
Point result = up + right;
// Prints "Result is upright (1,1)"
cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
std::cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
return 0;
}
@ -645,7 +653,7 @@ barkThreeTimes(fluffy); // Prints "Fluffy barks" three times.
// Template parameters don't have to be classes:
template<int Y>
void printMessage() {
cout << "Learn C++ in " << Y << " minutes!" << endl;
std::cout << "Learn C++ in " << Y << " minutes!\n";
}
// And you can explicitly specialize templates for more efficient code. Of
@ -654,7 +662,7 @@ void printMessage() {
// even if you explicitly specified all parameters.
template<>
void printMessage<10>() {
cout << "Learn C++ faster in only 10 minutes!" << endl;
std::cout << "Learn C++ faster in only 10 minutes!\n";
}
printMessage<20>(); // Prints "Learn C++ in 20 minutes!"
@ -707,6 +715,9 @@ void doSomethingWithAFile(const char* filename)
// To begin with, assume nothing can fail.
FILE* fh = fopen(filename, "r"); // Open the file in read mode.
if (fh == NULL) {
// Handle possible error
}
doSomethingWithTheFile(fh);
doSomethingElseWithIt(fh);
@ -826,10 +837,10 @@ void doSomethingWithAFile(const std::string& filename)
// Generally a smart pointer is a class which wraps a "raw pointer" (usage of "new"
// respectively malloc/calloc in C). The goal is to be able to
// manage the lifetime of the object being pointed to without ever needing to explicitly delete
// manage the lifetime of the object being pointed to without ever needing to explicitly delete
// the object. The term itself simply describes a set of pointers with the
// mentioned abstraction.
// Smart pointers should preferred over raw pointers, to prevent
// Smart pointers should be preferred over raw pointers, to prevent
// risky memory leaks, which happen if you forget to delete an object.
// Usage of a raw pointer:
@ -846,9 +857,9 @@ delete ptr;
// Usage of "std::shared_ptr":
void foo()
{
// It's no longer necessary to delete the Dog.
std::shared_ptr<Dog> doggo(new Dog());
doggo->bark();
// It's no longer necessary to delete the Dog.
std::shared_ptr<Dog> doggo(new Dog());
doggo->bark();
}
// Beware of possible circular references!!!
@ -858,7 +869,7 @@ std::shared_ptr<Dog> doggo_two(new Dog());
doggo_one = doggo_two; // p1 references p2
doggo_two = doggo_one; // p2 references p1
// There are several kinds of smart pointers.
// 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
@ -884,22 +895,23 @@ doggo_two = doggo_one; // p2 references p1
// Vector (Dynamic array)
// Allow us to Define the Array or list of objects at run time
#include <vector>
string val;
vector<string> my_vector; // initialize the vector
cin >> val;
std::string val;
std::vector<string> my_vector; // initialize the vector
std::cin >> val;
my_vector.push_back(val); // will push the value of 'val' into vector ("array") my_vector
my_vector.push_back(val); // will push the value into the vector again (now having two elements)
// To iterate through a vector we have 2 choices:
// Either classic looping (iterating through the vector from index 0 to its last index):
for (int i = 0; i < my_vector.size(); i++) {
cout << my_vector[i] << endl; // for accessing a vector's element we can use the operator []
std::cout << my_vector[i] << '\n'; // for accessing a vector's element we can use the operator []
}
// or using an iterator:
vector<string>::iterator it; // initialize the iterator for vector
for (it = my_vector.begin(); it != my_vector.end(); ++it) {
cout << *it << endl;
std::cout << *it << '\n';
}
// Set
@ -908,7 +920,7 @@ for (it = my_vector.begin(); it != my_vector.end(); ++it) {
// without any other functions or code.
#include<set>
set<int> ST; // Will initialize the set of int data type
std::set<int> ST; // Will initialize the set of int data type
ST.insert(30); // Will insert the value 30 in set ST
ST.insert(10); // Will insert the value 10 in set ST
ST.insert(20); // Will insert the value 20 in set ST
@ -920,9 +932,9 @@ ST.insert(30); // Will insert the value 30 in set ST
ST.erase(20); // Will erase element with value 20
// Set ST: 10 30
// To iterate through Set we use iterators
set<int>::iterator it;
for(it=ST.begin();it!=ST.end();it++) {
cout << *it << endl;
std::set<int>::iterator it;
for (it = ST.begin(); it != ST.end(); it++) {
std::cout << *it << '\n';
}
// Output:
// 10
@ -930,7 +942,7 @@ for(it=ST.begin();it!=ST.end();it++) {
// To clear the complete container we use Container_name.clear()
ST.clear();
cout << ST.size(); // will print the size of set ST
std::cout << ST.size(); // will print the size of set ST
// Output: 0
// NOTE: for duplicate elements we can use multiset
@ -942,7 +954,7 @@ cout << ST.size(); // will print the size of set ST
// and a mapped value, following a specific order.
#include<map>
map<char, int> mymap; // Will initialize the map with key as char and value as int
std::map<char, int> mymap; // Will initialize the map with key as char and value as int
mymap.insert(pair<char,int>('A',1));
// Will insert value 1 for key A
@ -950,16 +962,16 @@ mymap.insert(pair<char,int>('Z',26));
// Will insert value 26 for key Z
// To iterate
map<char,int>::iterator it;
for (it=mymap.begin(); it!=mymap.end(); ++it)
std::cout << it->first << "->" << it->second << std::endl;
std::map<char,int>::iterator it;
for (it = mymap.begin(); it != mymap.end(); ++it)
std::cout << it->first << "->" << it->second << '\n';
// Output:
// A->1
// Z->26
// To find the value corresponding to a key
it = mymap.find('Z');
cout << it->second;
std::cout << it->second;
// Output: 26
@ -997,7 +1009,7 @@ fooMap.find(Foo(1)); //true
// For example, consider sorting a vector of pairs using the second
// value of the pair
vector<pair<int, int> > tester;
std::vector<pair<int, int> > tester;
tester.push_back(make_pair(3, 6));
tester.push_back(make_pair(1, 9));
tester.push_back(make_pair(5, 0));
@ -1005,7 +1017,7 @@ tester.push_back(make_pair(5, 0));
// Pass a lambda expression as third argument to the sort function
// sort is from the <algorithm> header
sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs) {
std::sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs) {
return lhs.second < rhs.second;
});
@ -1019,10 +1031,10 @@ sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int,
// 4. same as 3, but by value [=]
// Example:
vector<int> dog_ids;
std::vector<int> dog_ids;
// number_of_dogs = 3;
for(int i = 0; i < 3; i++) {
dog_ids.push_back(i);
for (int i = 0; i < 3; i++) {
dog_ids.push_back(i);
}
int weight[3] = {30, 50, 10};
@ -1045,15 +1057,15 @@ sort(dog_ids.begin(), dog_ids.end(), [&weight](const int &lhs, const int &rhs) {
// You can use a range for loop to iterate over a container
int arr[] = {1, 10, 3};
for(int elem: arr){
cout << elem << endl;
for (int elem: arr) {
cout << elem << endl;
}
// You can use "auto" and not worry about the type of the elements of the container
// For example:
for(auto elem: arr) {
// Do something with each element of arr
for (auto elem: arr) {
// Do something with each element of arr
}
/////////////////////
@ -1066,10 +1078,10 @@ for(auto elem: arr) {
// You can override private methods!
class Foo {
virtual void bar();
virtual void bar();
};
class FooSub : public Foo {
virtual void bar(); // Overrides Foo::bar!
virtual void bar(); // Overrides Foo::bar!
};
@ -1124,33 +1136,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
std::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
std::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
std::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
std::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'
std::cout << get<0>(concatenated_tuple) << '\n'; // prints: 10
std::cout << get<3>(concatenated_tuple) << '\n'; // prints: 15
std::cout << get<5>(concatenated_tuple) << '\n'; // prints: 'A'
///////////////////////////////////
@ -1196,12 +1208,11 @@ compl 4 // Performs a bitwise not
4 bitor 3 // Performs bitwise or
4 bitand 3 // Performs bitwise and
4 xor 3 // Performs bitwise xor
```
Further Reading:
* An up-to-date language reference can be found at [CPP Reference](http://cppreference.com/w/cpp).
* A tutorial for beginners or experts, covering many modern features and good practices: [LearnCpp.com](https://www.learncpp.com/)
* A tutorial covering basics of language and setting up coding environment is available at [TheChernoProject - C++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb).
* Additional resources may be found at [CPlusPlus](http://cplusplus.com).
## Further Reading:
- An up-to-date language reference can be found at [CPP Reference](http://cppreference.com/w/cpp).
- A tutorial for beginners or experts, covering many modern features and good practices: [LearnCpp.com](https://www.learncpp.com/)
- A tutorial covering basics of language and setting up coding environment is available at [TheChernoProject - C++](https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb).
- Additional resources may be found at [CPlusPlus](http://cplusplus.com).

View File

@ -905,13 +905,11 @@ Node createLinkedList(int *vals, int len);
/* a header file but instead put into separate headers or a C file. */
#endif /* End of the if precompiler directive. */
```
## Further Reading
Best to find yourself a copy of [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language)
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
Best to find yourself a copy of [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language). 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://learncodethehardway.org/c/) (not free).
@ -922,6 +920,4 @@ It's very important to use proper spacing, indentation and to be consistent with
Readable code is better than clever code and fast code. For a good, sane coding style to adopt, see the
[Linux kernel coding style](https://www.kernel.org/doc/Documentation/process/coding-style.rst).
Other than that, Google is your friend.
[1] [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](https://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member)

View File

@ -95,7 +95,7 @@ salts de línia.` // El mateix tipus
// literals Non-ASCII literal. El tipus de Go és UTF-8.
g := 'Σ' // El tipus rune, és un àlies de int32 conté un caràcter unicode.
f := 3.14195 // float64, un número de 64 bits amb coma flotant IEEE-754.
f := 3.14159 // float64, un número de 64 bits amb coma flotant IEEE-754.
c := 3 + 4i // complex128, representat internament amb dos float64.
// Sintaxi amb var i inicialitzadors.
@ -432,26 +432,26 @@ func requestServer() {
## Més informació
L'arrel de tot en Go és la web oficial [official Go web site]
(http://golang.org/). Allà es pot seguir el tutorial, jugar interactivament
L'arrel de tot en Go és la web oficial [official Go web site](https://go.dev/).
Allà es pot seguir el tutorial, jugar interactivament
i llegir molt més del que hem vist aquí.En el "tour",
[the docs](https://golang.org/doc/) conté informació sobre com escriure codi
[the docs](https://go.dev/doc/) conté informació sobre com escriure codi
net i efectiu en Go, comandes per empaquetar i generar documentació, i
història de les versions.
És altament recomanable llegir La definició del llenguatge. És fàcil de llegir
i sorprenentment curta (com la definició del llenguatge en aquests dies).
Es pot jugar amb codi a [Go playground](https://play.golang.org/p/tnWMjr16Mm).
Es pot jugar amb codi a [Go playground](https://go.dev/play/p/tnWMjr16Mm).
Prova de fer canvis en el codi i executar-lo des del navegador! Es pot fer
servir [https://play.golang.org](https://play.golang.org) com a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) per provar coses i codi
servir [https://go.dev/play/](https://go.dev/play/) com a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) per provar coses i codi
en el navegador sense haver d'instal·lar Go.
En la llista de lectures pels estudiants de Go hi ha
[el codi font de la llibreria estàndard](http://golang.org/src/pkg/).
[el codi font de la llibreria estàndard](https://go.dev/src/).
Ampliament comentada, que demostra el fàcil que és de llegir i entendre els
programes en Go, l'estil de programació, i les formes de treballar-hi. O es
pot clicar en un nom de funció en [la documentació](http://golang.org/pkg/)
pot clicar en un nom de funció en [la documentació](https://go.dev/pkg/)
i veure'n el codi!
Un altre gran recurs per aprendre Go és
@ -460,5 +460,5 @@ Un altre gran recurs per aprendre Go és
Go Mobile afegeix suport per plataformes mòbils (Android i iOS). Es poden
escriure aplicacions mòbils o escriure llibreries de paquets de Go, que es
poden cridar des de Java (android) i Objective-C (iOS).
Comproveu la [Go Mobile page](https://github.com/golang/go/wiki/Mobile) per
Comproveu la [Go Mobile page](https://go.dev/wiki/Mobile) per
més informació.

View File

@ -10,10 +10,9 @@ translations:
- ["Xavier Sala Pujolar", "http://github.com/utrescu"]
---
Groovy - Un llenguatge dinàmic per la plataforma Java [Llegir-ne més.](http://www.groovy-lang.org/)
Groovy - Un llenguatge dinàmic per la plataforma Java [Llegir-ne més](http://www.groovy-lang.org/).
```groovy
/*
Posa'l en marxa tu mateix:
@ -286,7 +285,7 @@ def clos = { print it }
clos( "hi" )
/*
Groovy pot recordar els resultats dels Closures [1][2][3]
Groovy pot recordar els resultats dels Closures
*/
def cl = {a, b ->
sleep(3000) // simula un procés llarg
@ -413,8 +412,6 @@ int sum(int x, int y) {
}
assert sum(2,5) == 7
```
## Per aprendre'n més
@ -423,17 +420,10 @@ assert sum(2,5) == 7
[Cònsola de Groovy](http://groovyconsole.appspot.com/)
Uneix-te a un [grup d'usuaris Groovy]
(http://www.groovy-lang.org/usergroups.html)
Uneix-te a un [grup d'usuaris Groovy](http://www.groovy-lang.org/usergroups.html)
## Llibres
* [Groovy Goodness] (https://leanpub.com/groovy-goodness-notebook)
* [Groovy in Action] (http://manning.com/koenig2/)
* [Programming Groovy 2: Dynamic Productivity for the Java Developer] (http://shop.oreilly.com/product/9781937785307.do)
[1] http://roshandawrani.wordpress.com/2010/10/18/groovy-new-feature-closures-can-now-memorize-their-results/
[2] http://www.solutionsiq.com/resources/agileiq-blog/bid/72880/Programming-with-Groovy-Trampoline-and-Memoize
[3] http://mrhaki.blogspot.mx/2011/05/groovy-goodness-cache-closure-results.html
* [Groovy Goodness](https://leanpub.com/groovy-goodness-notebook)
* [Groovy in Action](http://manning.com/koenig2/)
* [Programming Groovy 2: Dynamic Productivity for the Java Developer](http://shop.oreilly.com/product/9781937785307.do)

View File

@ -160,7 +160,6 @@ article tracta principalment la sintaxi de l'HTML i alguns consells útils.
<td>Segona fila, segona columna</td>
</tr>
</table>
```
## Ús

View File

@ -379,7 +379,6 @@ fun useObject() {
ObjectExample.hello()
val someRef: Any = ObjectExample // podem fer servir el nom de l'objecte
}
```
### Per llegir més

View File

@ -1,864 +0,0 @@
---
language: Cairo
filename: learnCairo.sol
contributors:
- ["Darlington Nnam", "https://github.com/Darlington02"]
---
# Cairo
Cairo is a Turing-complete language that allows you write provable programs
(where one party can prove to another that a certain computation was executed
correctly) on StarkNet.
## StarkNet
StarkNet is a decentralized ZK-rollup that operates as an Ethereum layer 2
chain.
In this document, we are going to be going in-depth into understanding Cairo's
syntax and how you could create and deploy a Cairo smart contract on StarkNet.
**NB: As at the time of this writing, StarkNet is still at v0.10.3, with Cairo
1.0 coming soon. The ecosystem is young and evolving very fast, so you might
want to check the [official docs](https://www.cairo-lang.org/docs) to confirm
this document is still up-to-date. Pull requests are welcome!**
## Setting Up A Development Environment
Before we get started writing codes, we will need to setup a Cairo development
environment, for writing, compiling and deploying our contracts to StarkNet.
For the purpose of this tutorial we are going to be using the
[Protostar Framework](https://github.com/software-mansion/protostar).
Installation steps can be found in the docs
[here](https://docs.swmansion.com/protostar/docs/tutorials/installation).
Note that Protostar supports just Mac and Linux OS, Windows users might need to
use WSL, or go for other alternatives such as the Official
[StarkNet CLI](https://www.cairo-lang.org/docs/quickstart.html) or
[Nile from Openzeppelin](https://github.com/OpenZeppelin/nile)
Once you're done with the installations, run the command `protostar -v` to
confirm your installation was successful. If successful, you should see your
Protostar version displayed on the screen.
## Initializing a new project
Protostar similar to Truffle for solidity development can be installed once and
used for multiple projects. To initialize a new Protostar project, run the
following command:
```
protostar init
```
It would then request the project's name and the library's directory name,
you'd need to fill in this, and a new project will be initialized successfully.
## Compiling, Declaring, Deploying and Interacting with StarkNet Contracts
Within the `src` folder you'll find a boilerplate contract that comes with
initializing a new Protostar project, `main.cairo`. We are going to be
compiling, declaring and deploying this contract.
### Compiling Contracts
To compile a Cairo contract using Protostar, ensure a path to the contract is
specified in the `[contracts]` section of the `protostar.toml` file. Once
you've done that, open your terminal and run the command:
```
protostar build
```
And you should get an output similar to what you see below, with a `main.json`
and `main_abi.json` files created in the `build` folder.
<img src="./images/cairo/build.png" alt="building your contract">
### Declaring Contracts
With the recent StarkNet update to 0.10.3, the DEPLOY transaction was
deprecated and no longer works. To deploy a transaction, you must first declare
a Contract to obtain the class hash, then deploy the declared contract using the
[Universal Deployer Contract](https://community.starknet.io/t/universal-deployer-contract-proposal/1864).
Before declaring or deploying your contract using Protostar, you should set the
private key associated with the specified account address in a file, or in the
terminal. To set your private key in the terminal, run the command:
```
export PROTOSTAR_ACCOUNT_PRIVATE_KEY=[YOUR PRIVATE KEY HERE]
```
Then to declare our contract using Protostar run the following command (for
visual clarity, the backslash sign symbolizes the continuing line):
```
protostar declare ./build/main.json \
--network testnet \
--account 0x0691622bBFD29e835bA4004e7425A4e9630840EbD11c5269DE51C16774585b16 \
--max-fee auto
```
where `network` specifies the network we are deploying to, `account` specifies
account whose private key we are using, `max-fee` specifies the maximum fee to
be paid for the transaction. You should get the class hash outputted as seen
below:
<img src="./images/cairo/declare.png" alt="declaring your contract">
### Deploying Contracts
After obtaining our class hash from declaring, we can now deploy using the
command below:
```
protostar \
deploy 0x02a5de1b145e18dfeb31c7cd7ff403714ededf5f3fdf75f8b0ac96f2017541bc \
--network testnet \
--account 0x0691622bBFD29e835bA4004e7425A4e9630840EbD11c5269DE51C16774585b16 \
--max-fee auto
```
where `0x02a5de1b145e18dfeb31c7cd7ff403714ededf5f3fdf75f8b0ac96f2017541bc` is
the class hash of our contract.
<img src="./images/cairo/deploy.png" alt="deploying your contract">
### Interacting with Contracts
To interact with your deployed contract, we will be using `Argent X`
(alternative: `Braavos`), and `Starkscan` (alternative: `Voyager`). To install
and setup `Argent X`, see this
[guide](https://www.argent.xyz/learn/how-to-create-an-argent-x-wallet/).
Copy your contract address, displayed on screen from the previous step, and
head over to [Starkscan](https://testnet.starkscan.co/) to search for the
contract. Once found, you can make write calls to the contract in the following
sequence:
+ click on the "connect wallet" button,
<img src="./images/cairo/connect.png" alt="connect wallet">
+ select `Argent X` and approve the connection
<img src="./images/cairo/connect2.png" alt="connect to argentX">
+ you can now make read and write calls easily.
## Let's learn Cairo
First let's look at a default contract that comes with Protostar which allows
you to set balance on deployment, increase, and get the balance.
```
// Language directive - instructs compiler its a StarkNet contract
%lang starknet
// Library imports from the Cairo-lang library
from starkware.cairo.common.math import assert_nn
from starkware.cairo.common.cairo_builtins import HashBuiltin
// @dev Storage variable that stores the balance of a user.
// @storage_var is a decorator that instructs the compiler the function
// below it is a storage variable.
@storage_var
func balance() -> (res: felt) {}
// @dev Constructor writes the balance variable to 0 on deployment
// Constructors sets storage variables on deployment. Can accept arguments too.
@constructor
func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}() {
balance.write(0);
return();
}
// @dev increase_balance updates the balance variable
// @param amount the amount you want to add to balance
// @external is a decorator that specifies the func below it is an external
// function.
@external
func increase_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}(amount: felt){
with_attr error_message("Amount must be positive. Got: {amount}.") {
assert_nn(amount);
}
let (res) = balance.read();
balance.write(res + amount);
return ();
}
// @dev returns the balance variable
// @view is a decorator that specifies the func below it is a view function.
@view
func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}() -> (res: felt) {
let (res) = balance.read();
return (res,);
}
```
Before proceeding to the main lessons, try to build, deploy and interact with
this contract.
NB: You should be at `main.cairo` if you are using Protostar.
### 1. The Felt data type
Unlike solidity, where you have access to various data types, Cairo comes with
just a single data type `..felts`. Felts stands for Field elements, and are a
252 bit integer in the range `0<=x<=P` where `P` is a prime number. You can
create a `Uint256` in Cairo by utlizing a struct of two 128 bits felts.
```
struct Uint256 {
low: felt, // The low 128 bits of the value.
high: felt, // The high 128 bits of the value.
}
```
To avoid running into issues with divisions, it's safer to work with the
`unsigned_div_rem` method from Cairo-lang's library.
### 2. Lang Directive and Imports
To get started with writing a StarkNet contract, you must specify the directive:
```
%lang starknet
```
This directive informs the compiler you are writing a contract and not a
program. The difference between both is contracts have access to StarkNet's
storage, programs don't and as such are stateless.
There are important functions you might need to import from the official
Cairo-lang library or Openzeppelin's, e.g.
```
from starkware.cairo.common.cairo_builtins import HashBuiltin
from cairo_contracts.src.openzeppelin.token.erc20.library import ERC20
from starkware.cairo.common.uint256 import Uint256
from starkware.cairo.common.bool import TRUE
```
### 3. Data Structures
+ Storage variables: Cairo's storage is a map with `2^251` slots, where each
slot is a felt which is initialized to `0`. You create one using the
`@storage_var` decorator.
```
@storage_var
func names() -> (name: felt) {}
```
+ Storage mappings: Unlike Solidity where mappings have a separate keyword, in
Cairo you create mappings using storage variables.
```
@storage_var
func names(address: felt) -> (name: felt) {}
```
+ Structs: are a means to create custom data types in Cairo. A `struct` has a
size, which is the sum of the sizes of its members. The size can be
retrieved using `MyStruct.SIZE`. You create a struct in Cairo using the
`struct` keyword.
```
struct Person {
name: felt,
age: felt,
address: felt,
}
```
+ Constants: Constants are fixed and as such can't be altered after being set.
They evaluate to an integer (field element) at compile time. To create a
constant in Cairo, you use the `const` keyword. It's proper practice to
capitalize constant names.
```
const USER = 0x01C6cfC1DB2ae90dACEA243F0a8C2F4e32560F7cDD398e4dA2Cc56B733774E9b
```
+ Arrays: Arrays can be defined as a `pointer(felt*)` to the first element of
the array. As an array is populated, its elements take up contigous memory
cells. The `alloc` keyword can be used to dynamically allocate a new memory
segment, which can be used to store an array:
```
let (myArray: felt*) = alloc ();
assert myArray[0] = 1;
assert myArray[1] = 2;
assert myArray[3] = 3;
```
You can also use the `new` operator to create fixed-size arrays using
tuples. The new operator is useful as it enables you allocate memory and
initialize the object in one instruction
```
func foo() {
tempvar arr: felt* = new (1, 1, 2, 3, 5);
assert arr[4] = 5;
return ();
}
```
+ Tuples: A tuple is a finite, ordered, unchangeable list of elements. It is
represented as a comma-separated list of elements enclosed by parentheses.
Their elements may be of any combination of valid types.
```
local tuple0: (felt, felt, felt) = (7, 9, 13);
```
+ Events: Events allows a contract emit information during the course of its
execution, that can be used outside of StarkNet. An event can be created,
subsequently emitted:
```
@event
func name_stored(address, name) {}
name_stored.emit(address, name);
```
### 4. Constructors, External and View functions
+ Constructors: Constructors are a way to intialize state variables on
contract deployment. You create a constructor using the `@constructor`
decorator.
```
@constructor
func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}(_name: felt) {
let (caller) = get_caller_address();
names.write(caller, _name);
return ();
}
```
+ External functions: External functions are functions that modifies the state
of the network. You create an external function using the `@external`
decorator:
```
@external
func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}(_name: felt){
let (caller) = get_caller_address();
names.write(caller, _name);
stored_name.emit(caller, _name);
return ();
}
```
+ View functions: View functions do not modify the state of the blockchain.
You can create a view function using the `@view` decorator.
```
@view
func get_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}(_address: felt) -> (name: felt){
let (name) = names.read(_address);
return (name,);
}
```
NB: Unlike Solidity, Cairo supports just External and View function types.
You can alternatively also create an internal function by not adding any
decorator to the function.
### 5. Decorators
All functions in Cairo are specified by the `func` keyword, which can be
confusing. Decorators are used by the compiler to distinguish between these
functions.
Here are the most common decorators you'll encounter in Cairo:
+ `@storage_var` — used for specifying state variables.
+ `@constructor` — used for specifying constructors.
+ `@external` — used for specifying functions that write to a state variable.
+ `@event` — used for specifying events
+ `@view` — used to specify functions reading from a state variable
+ `@contract_interface` — used for specifying function interfaces.
+ `@l1_handler` — used for specifying functions that processes message sent from
an L1 contract in a messaging bridge.
### 6. BUILTINS, HINTS & IMPLICIT Arguments
+ `BUILTINS` are predefined optimized low-level execution units, which are
added to Cairos CPU board. They help perform predefined computations like
pedersen hashing, bitwise operations etc, which are expensive to perform in
Vanilla Cairo. Each builtin in Cairo is assigned a separate memory location,
accessible through regular Cairo memory calls using implicit parameters. You
specify them using the `%builtins` directive
Here is a list of available builtins in Cairo:
+ `output` — the output builtin is used for writing program outputs
+ `pedersen` — the pedersen builtin is used for pedersen hashing
computations
+ `range_check` — This builtin is mostly used for integer comparisons,
and facilitates check to confirm that a field element is within a range
`[0, 2^128)`
+ `ecdsa` — the ecdsa builtin is used for verifying ECDSA signatures
+ `bitwise` — the bitwise builtin is used for carrying out bitwise
operations on felts
+ `HINTS` are pieces of Python codes, which contains instructions that only
the prover sees and executes. From the point of view of the verifier these
hints do not exist. To specify a hint in Cairo, you need to encapsulate it
within `%{` and `%}`. It is good practice to avoid using hints as much as
you can in your contracts, as hints are not added to the bytecode, and thus
do not count in the total number of execution steps.
```
%{
# Python hint goes here
%}
```
+ `IMPLICIT ARGUMENTS` are not restricted to the function body, but can be
inherited by other functions calls that require them. Implicit arguments are
passed in between curly bracelets, like you can see below:
```
func store_name{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}(_name: felt){
let (caller) = get_caller_address();
names.write(caller, _name);
stored_name.emit(caller, _name);
return ();
}
```
### 7. Error Messages and Access Controls
You can create custom errors in Cairo which is outputted to the user upon failed
execution. This can be very useful for implementing checks and proper access
control mechanisms. An example is preventing a user to call a function except
user is `admin`.
```
// imports
from starkware.starknet.common.syscalls import get_caller_address
// create an admin constant
const ADMIN = 0x01C6cfC1DB2ae90dACEA243F0a8C2F4e32560F7cDD398e4dA2Cc56B733774E9b
// implement access control
with_attr error_message("You do not have access to make this action!"){
let (caller) = get_caller_address();
assert ADMIN = caller;
}
// using an assert statement throws if condition is not true, thus
// returning the specified error.
```
### 8. Contract Interfaces
Contract interfaces provide a means for one contract to invoke or call the
external function of another contract. To create a contract interface, you use
the `@contract_interface` keyword:
```
@contract_interface
namespace IENS {
func store_name(_name: felt) {
}
func get_name(_address: felt) -> (name: felt) {
}
}
```
Once a contract interface is specified, any contract can make calls to that
contract passing in the contract address as the first parameter like this:
```
IENS.store_name(contract_address, _name);
```
Note that Interfaces exclude the function body/logic and the implicit
arguments.
### 9. Recursions
Due to the unavailability of loops, Recursion is the go-to for similar
operations. In simple terms, a recursive function is one which calls itself
repeatedly.
A good example to demonstrate this is writing a function for getting the nth
fibonacci number:
```
@external
func fibonacci{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}(n : felt) -> (result : felt){
alloc_locals;
if (n == 0){
return (0);
}
if (n == 1){
return (1);
}
let (local x) = fibonacci(n - 1);
let (local y) = fibonacci(n - 2);
return (result=(x + y));
}
```
The nth fibonacci term is the sum of the `nth - 1` and the `nth - 2` numbers,
that's why we get these two as `(x,y)` using recursion.
NB: when implementing recursive functions, always remember to implement a base
case (`n==0`, `n==1` in our case), to prevent stack overflows.
### 10. Registers
Registers holds values that may change over time. There are 3 major types of
registers:
+ `ap` (allocation pointer) points to a yet unused memory. Temporary variables
created using `let`, `tempvar` are held here, and thus susceptible to being
revoked.
+ `fp` (frame pointer) points to the frame of the current function. The address
of all the function arguments and local variables are relative to this
register and as such can never be revoked.
+ `pc` (program counter) points to the current instruction.
### 11. Revoked References
Revoked references occur when there is a call instruction to another function,
between the definition of a reference variable that depends on `ap` (temp
variables) and its usage. This occurs as the compiler may not be able to compute
the change of `ap` (as one may jump to the label from another place in the
program, or call a function that might change ap in an unknown way).
Here is an example to demonstrate what I mean:
```
@external
func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}() -> (res: felt) {
return (res=100);
}
@external
func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}() -> (res: felt) {
let multiplier = 2;
let (balance) = get_balance();
let new_balance = balance * multiplier;
return (res=new_balance);
}
```
If you run that code, you'll run into the revoked reference error as we are
trying to access the `multiplier` variable after calling the `get_balance`
function.
In simple cases you can resolve revoked references by adding the keyword
`alloc_locals` within function scopes. In more complex cases you might need to
create a local variable to resolve it.
```
// resolving the `double_balance` function:
@external
func double_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}() -> (res: felt) {
alloc_locals;
let multiplier = 2;
let (balance) = get_balance();
let new_balance = balance * multiplier;
return (res=new_balance);
}
```
### 12. Understanding Cairo's Punctuations
+ `;` (semicolon). Used at the end of each instruction
+ `()` (parentheses). Used in a function declaration, if statements, and in a
tuple declaration
+ `{}` (curly braces). Used in a declaration of implicit arguments and to define
code blocks.
+ `[]` (square brackets). Standalone brackets represent the value at a
particular address location (such as the allocation pointer, `[ap]`). Brackets
following a pointer or a tuple act as a subscript operator, where `x[2]`
represents the element with index `2` in `x`.
+ `*` (single asterisk). Refers to the pointer of an expression.
+ `%` (percent sign). Appears at the start of a directive, such as `%builtins`
or `%lang`.
+ `%{` and `%}` represent Python hints.
+ `_` (underscore). A placeholder to handle values that are not used, such as an
unused function return value.
## Full Contract Example
Below is a simple automated market maker contract example that implements most
of what we just learnt! Re-write, deploy, have fun!
```
%lang starknet
from starkware.cairo.common.cairo_builtins import HashBuiltin
from starkware.cairo.common.hash import hash2
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.math import (assert_le, assert_nn_le,
unsigned_div_rem)
from starkware.starknet.common.syscalls import (get_caller_address,
storage_read, storage_write)
// CONSTANTS
//
// @dev the maximum amount of each token that belongs to the AMM
const BALANCE_UPPER_BOUND = 2 ** 64;
const TOKEN_TYPE_A = 1;
const TOKEN_TYPE_B = 2;
// @dev Ensure the user's balances are much smaller than the pool's balance
const POOL_UPPER_BOUND = 2 ** 30;
const ACCOUNT_BALANCE_BOUND = 1073741; // (2 ** 30 / 1000)
// STORAGE VARIABLES
//
// @dev A map from account and token type to corresponding balance
@storage_var
func account_balance(account_id: felt, token_type: felt) -> (balance: felt) {}
// @dev a map from token type to corresponding pool balance
@storage_var
func pool_balance(token_type: felt) -> (balance: felt) {}
// GETTERS
//
// @dev returns account balance for a given token
// @param account_id Account to be queried
// @param token_type Token to be queried
@view
func get_account_token_balance{syscall_ptr: felt*, pedersen_ptr:
HashBuiltin*, range_check_ptr}(
account_id: felt, token_type: felt
) -> (balance: felt) {
return account_balance.read(account_id, token_type);
}
// @dev return the pool's balance
// @param token_type Token type to get pool balance
@view
func get_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}(
token_type: felt
) -> (balance: felt) {
return pool_balance.read(token_type);
}
// EXTERNALS
//
// @dev set pool balance for a given token
// @param token_type Token whose balance is to be set
// @param balance Amount to be set as balance
@external
func set_pool_token_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}(
token_type: felt, balance: felt
) {
with_attr error_message("exceeds maximum allowed tokens!"){
assert_nn_le(balance, BALANCE_UPPER_BOUND - 1);
}
pool_balance.write(token_type, balance);
return ();
}
// @dev add demo token to the given account
// @param token_a_amount amount of token a to be added
// @param token_b_amount amount of token b to be added
@external
func add_demo_token{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}(
token_a_amount: felt, token_b_amount: felt
) {
alloc_locals;
let (account_id) = get_caller_address();
modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_A,
amount=token_a_amount);
modify_account_balance(account_id=account_id, token_type=TOKEN_TYPE_B,
amount=token_b_amount);
return ();
}
// @dev intialize AMM
// @param token_a amount of token a to be set in pool
// @param token_b amount of token b to be set in pool
@external
func init_pool{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}(
token_a: felt, token_b: felt
) {
with_attr error_message("exceeds maximum allowed tokens!"){
assert_nn_le(token_a, POOL_UPPER_BOUND - 1);
assert_nn_le(token_b, POOL_UPPER_BOUND - 1);
}
set_pool_token_balance(token_type=TOKEN_TYPE_A, balance=token_a);
set_pool_token_balance(token_type=TOKEN_TYPE_B, balance=token_b);
return ();
}
// @dev swaps token between the given account and the pool
// @param token_from token to be swapped
// @param amount_from amount of token to be swapped
// @return amount_to the token swapped to
@external
func swap{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
token_from: felt, amount_from: felt
) -> (amount_to: felt) {
alloc_locals;
let (account_id) = get_caller_address();
// verify token_from is TOKEN_TYPE_A or TOKEN_TYPE_B
with_attr error_message("token not allowed in pool!"){
assert (token_from - TOKEN_TYPE_A) * (token_from - TOKEN_TYPE_B) = 0;
}
// check requested amount_from is valid
with_attr error_message("exceeds maximum allowed tokens!"){
assert_nn_le(amount_from, BALANCE_UPPER_BOUND - 1);
}
// check user has enough funds
let (account_from_balance) =
get_account_token_balance(account_id=account_id, token_type=token_from);
with_attr error_message("insufficient balance!"){
assert_le(amount_from, account_from_balance);
}
let (token_to) = get_opposite_token(token_type=token_from);
let (amount_to) = do_swap(account_id=account_id, token_from=token_from,
token_to=token_to, amount_from=amount_from);
return (amount_to=amount_to);
}
// INTERNALS
//
// @dev internal function that updates account balance for a given token
// @param account_id Account whose balance is to be modified
// @param token_type Token type to be modified
// @param amount Amount Amount to be added
func modify_account_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}(
account_id: felt, token_type: felt, amount: felt
) {
let (current_balance) = account_balance.read(account_id, token_type);
tempvar new_balance = current_balance + amount;
with_attr error_message("exceeds maximum allowed tokens!"){
assert_nn_le(new_balance, BALANCE_UPPER_BOUND - 1);
}
account_balance.write(account_id=account_id, token_type=token_type,
value=new_balance);
return ();
}
// @dev internal function that swaps tokens between the given account and
// the pool
// @param account_id Account whose tokens are to be swapped
// @param token_from Token type to be swapped from
// @param token_to Token type to be swapped to
// @param amount_from Amount to be swapped
func do_swap{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
range_check_ptr}(
account_id: felt, token_from: felt, token_to: felt, amount_from: felt
) -> (amount_to: felt) {
alloc_locals;
// get pool balance
let (local amm_from_balance) = get_pool_token_balance(token_type =
token_from);
let (local amm_to_balance) = get_pool_token_balance(token_type=token_to);
// calculate swap amount
let (local amount_to, _) = unsigned_div_rem((amm_to_balance *
amount_from), (amm_from_balance + amount_from));
// update token_from balances
modify_account_balance(account_id=account_id, token_type=token_from,
amount=-amount_from);
set_pool_token_balance(token_type=token_from, balance=(amm_from_balance
+ amount_from));
// update token_to balances
modify_account_balance(account_id=account_id, token_type=token_to,
amount=amount_to);
set_pool_token_balance(token_type=token_to, balance=(amm_to_balance -
amount_to));
return (amount_to=amount_to);
}
// @dev internal function to get the opposite token type
// @param token_type Token whose opposite pair needs to be gotten
func get_opposite_token(token_type: felt) -> (t: felt) {
if(token_type == TOKEN_TYPE_A) {
return (t=TOKEN_TYPE_B);
} else {
return (t=TOKEN_TYPE_A);
}
}
```
## Additional Resources
+ [Official documentation](https://www.cairo-lang.org/docs/)
+ [Starknet EDU](https://medium.com/starknet-edu)
+ [Journey through Cairo](https://medium.com/@darlingtonnnam/journey-through-cairo-i-setting-up-protostar-and-argentx-for-local-development-ba40ae6c5524)
+ [Demystifying Cairo whitepaper](https://medium.com/@pban/demystifying-cairo-white-paper-part-i-b71976ad0108)
+ [Learn about StarkNet with Argent](https://www.argent.xyz/learn/tag/starknet/)
## Development Frameworks
+ [Protostar](https://docs.swmansion.com/protostar/docs/tutorials/installation)
+ [Nile](https://github.com/OpenZeppelin/nile)
+ [StarkNet CLI](https://www.cairo-lang.org/docs/quickstart.html)
## Helpful Libraries
+ [Cairo-lang](https://github.com/starkware-libs/cairo-lang)
+ [Openzeppelin](https://github.com/OpenZeppelin/cairo-contracts)
## Educational Repos
+ [StarkNet Cairo 101](https://github.com/starknet-edu/starknet-cairo-101)
+ [StarkNet ERC721](https://github.com/starknet-edu/starknet-erc721)
+ [StarkNet ERC20](https://github.com/starknet-edu/starknet-erc20)
+ [L1 -> L2 Messaging](https://github.com/starknet-edu/starknet-messaging-bridge)
+ [StarkNet Debug](https://github.com/starknet-edu/starknet-debug)
+ [StarkNet Accounts](https://github.com/starknet-edu/starknet-accounts)
+ [Min-Starknet](https://github.com/Darlington02/min-starknet)
## Security
+ [Amarna static analysis for Cairo programs](https://blog.trailofbits.com/2022/04/20/amarna-static-analysis-for-cairo-programs/)
+ [Cairo and StarkNet security by Ctrl03](https://ctrlc03.github.io/)
+ [How to hack almost any Cairo smart contract](https://medium.com/ginger-security/how-to-hack-almost-any-starknet-cairo-smart-contract-67b4681ac0f6)
+ [Analyzing Cairo code using Armana](https://dic0de.substack.com/p/analyzing-cairo-code-using-amarna?sd=pf)
## Future TO-DOs
Update tutorial to fit Cairo 1.0

View File

@ -13,42 +13,60 @@ as well as multi-kilocore supercomputers.
More information and support can be found at the bottom of this document.
You can refer to the official site for [latest version](https://chapel-lang.org/docs/master/primers/learnChapelInYMinutes.html) of this document.
```chapel
/*
Learn Chapel in Y Minutes
This primer will go over basic syntax and concepts in Chapel.
Last sync with official page: Sun, 08 Mar 2020 08:05:53 +0000
*/
// Comments are C-family style
// one line comment
/*
multi-line comment
multi-line comment
*/
// Basic printing
/*
Basic printing
*/
write("Hello, ");
writeln("World!");
// write and writeln can take a list of things to print.
// ``write`` and ``writeln`` can take a list of things to print.
// Each thing is printed right next to the others, so include your spacing!
writeln("There are ", 3, " commas (\",\") in this line of code");
// Different output channels:
use IO; // Required for accessing the alternative output channels
stdout.writeln("This goes to standard output, just like plain writeln() does");
stderr.writeln("This goes to standard error");
/*
Variables
*/
// Variables don't have to be explicitly typed as long as
// the compiler can figure out the type that it will hold.
// 10 is an int, so myVar is implicitly an int
// 10 is an ``int``, so ``myVar`` is implicitly an ``int``
var myVar = 10;
myVar = -10;
var mySecondVar = myVar;
// var anError; would be a compile-time error.
// ``var anError;`` would be a compile-time error.
// We can (and should) explicitly type things.
var myThirdVar: real;
var myFourthVar: real = -1.234;
myThirdVar = myFourthVar;
// Types
/*
Types
*/
// There are a number of basic types.
var myInt: int = -1000; // Signed ints
@ -75,39 +93,45 @@ type RGBColor = 3*chroma; // Type representing a full color
var black: RGBColor = (0,0,0);
var white: RGBColor = (255, 255, 255);
// Constants and Parameters
/*
Constants and Parameters
*/
// A const is a constant, and cannot be changed after set in runtime.
// A ``const`` is a constant, and cannot be changed after set in runtime.
const almostPi: real = 22.0/7.0;
// A param is a constant whose value must be known statically at
// A ``param`` is a constant whose value must be known statically at
// compile-time.
param compileTimeConst: int = 16;
// The config modifier allows values to be set at the command line.
// Set with --varCmdLineArg=Value or --varCmdLineArg Value at runtime.
// The ``config`` modifier allows values to be set at the command line.
// Set with ``--varCmdLineArg=Value`` or ``--varCmdLineArg Value`` at runtime.
config var varCmdLineArg: int = -123;
config const constCmdLineArg: int = 777;
// config param can be set at compile-time.
// Set with --set paramCmdLineArg=value at compile-time.
// ``config param`` can be set at compile-time.
// Set with ``--set paramCmdLineArg=value`` at compile-time.
config param paramCmdLineArg: bool = false;
writeln(varCmdLineArg, ", ", constCmdLineArg, ", ", paramCmdLineArg);
// References
/*
References
*/
// ref operates much like a reference in C++. In Chapel, a ref cannot
// ``ref`` operates much like a reference in C++. In Chapel, a ``ref`` cannot
// be made to alias a variable other than the variable it is initialized with.
// Here, refToActual refers to actual.
// Here, ``refToActual`` refers to ``actual``.
var actual = 10;
ref refToActual = actual;
ref refToActual = actual;
writeln(actual, " == ", refToActual); // prints the same value
actual = -123; // modify actual (which refToActual refers to)
writeln(actual, " == ", refToActual); // prints the same value
refToActual = 99999999; // modify what refToActual refers to (which is actual)
writeln(actual, " == ", refToActual); // prints the same value
// Operators
/*
Operators
*/
// Math operators:
var a: int, thisInt = 1234, thatInt = 5678;
@ -146,7 +170,7 @@ a <<= 3; // Left-bit-shift-equals (a = a << 10;)
// Unlike other C family languages, there are no
// pre/post-increment/decrement operators, such as:
//
// ++j, --j, j++, j--
// ``++j``, ``--j``, ``j++``, ``j--``
// Swap operator:
var old_this = thisInt;
@ -156,7 +180,9 @@ writeln((old_this == thatInt) && (old_that == thisInt));
// Operator overloads can also be defined, as we'll see with procedures.
// Tuples
/*
Tuples
*/
// Tuples can be of the same type or different types.
var sameTup: 2*int = (10, -1);
@ -179,16 +205,18 @@ writeln(diffTup == (tupInt, tupReal, tupCplx));
// They are also useful for writing a list of variables, as is common in debugging.
writeln((a,b,thisInt,thatInt,thisBool,thatBool));
// Control Flow
/*
Control Flow
*/
// if - then - else works just like any other C-family language.
// ``if`` - ``then`` - ``else`` works just like any other C-family language.
if 10 < 100 then
writeln("All is well");
if -1 < 1 then
writeln("Continuing to believe reality");
else
writeln("Send mathematician, something is wrong");
writeln("Send mathematician, something's wrong");
// You can use parentheses if you prefer.
if (10 > 100) {
@ -209,11 +237,11 @@ if a % 3 == 0 {
writeln(b, " is divided by 3 with a remainder of 2.");
}
// Ternary: if - then - else in a statement.
// Ternary: ``if`` - ``then`` - ``else`` in a statement.
var maximum = if thisInt < thatInt then thatInt else thisInt;
// select statements are much like switch statements in other languages.
// However, select statements do not cascade like in C or Java.
// ``select`` statements are much like switch statements in other languages.
// However, ``select`` statements don't cascade like in C or Java.
var inputOption = "anOption";
select inputOption {
when "anOption" do writeln("Chose 'anOption'");
@ -223,11 +251,11 @@ select inputOption {
}
otherwise {
writeln("Any other Input");
writeln("the otherwise case does not need a do if the body is one line");
writeln("the otherwise case doesn't need a do if the body is one line");
}
}
// while and do-while loops also behave like their C counterparts.
// ``while`` and ``do``-``while`` loops also behave like their C counterparts.
var j: int = 1;
var jSum: int = 0;
while (j <= 1000) {
@ -242,8 +270,8 @@ do {
} while (j <= 10000);
writeln(jSum);
// for loops are much like those in Python in that they iterate over a
// range. Ranges (like the 1..10 expression below) are a first-class object
// ``for`` loops are much like those in python in that they iterate over a
// range. Ranges (like the ``1..10`` expression below) are a first-class object
// in Chapel, and as such can be stored in variables.
for i in 1..10 do write(i, ", ");
writeln();
@ -261,7 +289,9 @@ for x in 1..10 {
writeln();
}
// Ranges and Domains
/*
Ranges and Domains
*/
// For-loops and arrays both use ranges and domains to define an index set that
// can be iterated over. Ranges are single dimensional integer indices, while
@ -277,17 +307,18 @@ var rangeEmpty: range = 100..-100; // this is valid but contains no indices
var range1toInf: range(boundedType=BoundedRangeType.boundedLow) = 1.. ; // 1, 2, 3, 4, 5, ...
var rangeNegInfTo1 = ..1; // ..., -4, -3, -2, -1, 0, 1
// Ranges can be strided (and reversed) using the by operator.
// Ranges can be strided (and reversed) using the ``by`` operator.
var range2to10by2: range(stridable=true) = 2..10 by 2; // 2, 4, 6, 8, 10
var reverse2to10by2 = 2..10 by -2; // 10, 8, 6, 4, 2
var trapRange = 10..1 by -1; // Do not be fooled, this is still an empty range
writeln("Size of range ", trapRange, " = ", trapRange.length);
writeln("Size of range '", trapRange, "' = ", trapRange.size);
// Note: range(boundedType= ...) and range(stridable= ...) are only
// Note: ``range(boundedType= ...)`` and ``range(stridable= ...)`` are only
// necessary if we explicitly type the variable.
// The end point of a range can be determined using the count (#) operator.
// The end point of a range can be computed by specifying the total size
// of the range using the count (``#``) operator.
var rangeCount: range = -5..#12; // range from -5 to 6
// Operators can be mixed.
@ -297,8 +328,8 @@ writeln(rangeCountBy);
// Properties of the range can be queried.
// In this example, printing the first index, last index, number of indices,
// stride, and if 2 is include in the range.
writeln((rangeCountBy.first, rangeCountBy.last, rangeCountBy.length,
rangeCountBy.stride, rangeCountBy.member(2)));
writeln((rangeCountBy.first, rangeCountBy.last, rangeCountBy.size,
rangeCountBy.stride, rangeCountBy.contains(2)));
for i in rangeCountBy {
write(i, if i == rangeCountBy.last then "\n" else ", ");
@ -322,7 +353,7 @@ for idx in twoDimensions do
write(idx, ", ");
writeln();
// These tuples can also be deconstructed.
// These tuples can also be destructured.
for (x,y) in twoDimensions {
write("(", x, ", ", y, ")", ", ");
}
@ -352,7 +383,9 @@ var domainB = {-5..5, 1..10};
var domainC = domainA[domainB];
writeln((domainA, domainB, domainC));
// Arrays
/*
Arrays
*/
// Arrays are similar to those of other languages.
// Their sizes are defined using domains that represent their indices.
@ -364,9 +397,9 @@ for i in 1..10 do
intArray[i] = -i;
writeln(intArray);
// We cannot access intArray[0] because it exists outside
// of the index set, {1..10}, we defined it to have.
// intArray[11] is illegal for the same reason.
// We cannot access ``intArray[0]`` because it exists outside
// of the index set, ``{1..10}``, we defined it to have.
// ``intArray[11]`` is illegal for the same reason.
var realDomain: domain(2) = {1..5,1..7};
var realArray: [realDomain] real;
var realArray2: [1..5,1..7] real; // equivalent
@ -396,9 +429,9 @@ for value in realArray {
writeln(rSum, "\n", realArray);
// Associative arrays (dictionaries) can be created using associative domains.
var dictDomain: domain(string) = { "one", "two" };
var dict: [dictDomain] int = ["one" => 1, "two" => 2];
dict["three"] = 3; // Adds 'three' to 'dictDomain' implicitly
var dictDomain: domain(string) = { "one", "two", "three"};
var dict: [dictDomain] int = ["one" => 1, "two" => 2, "three" => 3];
for key in dictDomain.sorted() do
writeln(dict[key]);
@ -407,9 +440,9 @@ for key in dictDomain.sorted() do
var thisArray : [0..5] int = [0,1,2,3,4,5];
var thatArray : [0..5] int;
// First, simply assign one to the other. This copies thisArray into
// thatArray, instead of just creating a reference. Therefore, modifying
// thisArray does not also modify thatArray.
// First, simply assign one to the other. This copies ``thisArray`` into
// ``thatArray``, instead of just creating a reference. Therefore, modifying
// ``thisArray`` does not also modify ``thatArray``.
thatArray = thisArray;
thatArray[1] = -1;
@ -425,7 +458,7 @@ var thisPlusThat = thisArray + thatArray;
writeln(thisPlusThat);
// Moving on, arrays and loops can also be expressions, where the loop
// body expression is the result of each iteration.
// body's expression is the result of each iteration.
var arrayFromLoop = for i in 1..10 do i;
writeln(arrayFromLoop);
@ -435,16 +468,18 @@ var evensOrFives = for i in 1..10 do if (i % 2 == 0 || i % 5 == 0) then i;
writeln(arrayFromLoop);
// Array expressions can also be written with a bracket notation.
// Note: this syntax uses the forall parallel concept discussed later.
// Note: this syntax uses the ``forall`` parallel concept discussed later.
var evensOrFivesAgain = [i in 1..10] if (i % 2 == 0 || i % 5 == 0) then i;
// They can also be written over the values of the array.
arrayFromLoop = [value in arrayFromLoop] value + 1;
// Procedures
/*
Procedures
*/
// Chapel procedures have similar syntax functions in other languages.
// Chapel procedures have similar syntax functions in other languages.
proc fibonacci(n : int) : int {
if n <= 1 then return n;
return fibonacci(n-1) + fibonacci(n-2);
@ -482,10 +517,10 @@ writeln(defaultsProc(x=11));
writeln(defaultsProc(x=12, y=5.432));
writeln(defaultsProc(y=9.876, x=13));
// The ? operator is called the query operator, and is used to take
// The ``?`` operator is called the query operator, and is used to take
// undetermined values like tuple or array sizes and generic types.
// For example, taking arrays as parameters. The query operator is used to
// determine the domain of A. This is uesful for defining the return type,
// determine the domain of ``A``. This is useful for defining the return type,
// though it's not required.
proc invertArray(A: [?D] int): [D] int{
for a in A do a = -a;
@ -509,7 +544,7 @@ genericProc(1, 2);
genericProc(1.2, 2.3);
genericProc(1.0+2.0i, 3.0+4.0i);
// We can also enforce a form of polymorphism with the where clause
// We can also enforce a form of polymorphism with the ``where`` clause
// This allows the compiler to decide which function to use.
// Note: That means that all information needs to be known at compile-time.
// The param modifier on the arg is used to enforce this constraint.
@ -526,13 +561,13 @@ proc whereProc(param N : int): void
whereProc(10);
whereProc(-1);
// whereProc(0) would result in a compiler error because there
// are no functions that satisfy the where clause's condition.
// We could have defined a whereProc without a where clause
// ``whereProc(0)`` would result in a compiler error because there
// are no functions that satisfy the ``where`` clause's condition.
// We could have defined a ``whereProc`` without a ``where`` clause
// that would then have served as a catch all for all the other cases
// (of which there is only one).
// where clauses can also be used to constrain based on argument type.
// ``where`` clauses can also be used to constrain based on argument type.
proc whereType(x: ?t) where t == int {
writeln("Inside 'int' version of 'whereType': ", x);
}
@ -544,7 +579,9 @@ proc whereType(x: ?t) {
whereType(42);
whereType("hello");
// Intents
/*
Intents
*/
/* Intent modifiers on the arguments convey how those arguments are passed to the procedure.
@ -571,7 +608,7 @@ intentsProc(inVar, outVar, inoutVar, refVar);
writeln("Outside After: ", (inVar, outVar, inoutVar, refVar));
// Similarly, we can define intents on the return type.
// refElement returns a reference to an element of array.
// ``refElement`` returns a reference to an element of array.
// This makes more practical sense for class methods where references to
// elements in a data-structure are returned via a method or iterator.
proc refElement(array : [?D] ?T, idx) ref : T {
@ -586,14 +623,16 @@ refToElem = -2; // modify reference which modifies actual value in array
writeln(refToElem);
writeln(myChangingArray);
// Operator Definitions
/*
Operator Definitions
*/
// Chapel allows for operators to be overloaded.
// We can define the unary operators:
// + - ! ~
// ``+ - ! ~``
// and the binary operators:
// + - * / % ** == <= >= < > << >> & | ˆ by
// += -= *= /= %= **= &= |= ˆ= <<= >>= <=>
// ``+ - * / % ** == <= >= < > << >> & | ˆ by``
// ``+= -= *= /= %= **= &= |= ˆ= <<= >>= <=>``
// Boolean exclusive or operator.
proc ^(left : bool, right : bool): bool {
@ -605,25 +644,28 @@ writeln(false ^ true);
writeln(true ^ false);
writeln(false ^ false);
// Define a * operator on any two types that returns a tuple of those types.
// Define a ``*`` operator on any two types that returns a tuple of those types.
proc *(left : ?ltype, right : ?rtype): (ltype, rtype) {
writeln("\tIn our '*' overload!");
return (left, right);
}
writeln(1 * "a"); // Uses our * operator.
writeln(1 * 2); // Uses the default * operator.
writeln(1 * "a"); // Uses our ``*`` operator.
writeln(1 * 2); // Uses the default ``*`` operator.
// Note: You could break everything if you get careless with your overloads.
// This here will break everything. Don't do it.
/*
proc +(left: int, right: int): int {
return left - right;
}
/*
proc +(left: int, right: int): int {
return left - right;
}
*/
// Iterators
/*
Iterators
*/
// Iterators are sisters to the procedure, and almost everything about
// procedures also applies to iterators. However, instead of returning a single
@ -656,7 +698,7 @@ for i in absolutelyNothing(10) {
}
// We can zipper together two or more iterators (who have the same number
// of iterations) using zip() to create a single zipped iterator, where each
// of iterations) using ``zip()`` to create a single zipped iterator, where each
// iteration of the zipped iterator yields a tuple of one value yielded
// from each iterator.
for (positive, negative) in zip(1..5, -5..-1) do
@ -683,11 +725,10 @@ for (i, j) in zip(toThisArray.domain, -100..#5) {
}
writeln(toThisArray);
// This is very important in understanding why this statement exhibits a
// runtime error.
// This is very important in understanding why this statement exhibits a runtime error.
/*
var iterArray : [1..10] int = [i in 1..10] if (i % 2 == 1) then i;
/*
var iterArray : [1..10] int = [i in 1..10] if (i % 2 == 1) then i;
*/
// Even though the domain of the array and the loop-expression are
@ -695,8 +736,9 @@ writeln(toThisArray);
// Because iterators can yield nothing, that iterator yields a different number
// of things than the domain of the array or loop, which is not allowed.
// Classes
/*
Classes
*/
// Classes are similar to those in C++ and Java, allocated on the heap.
class MyClass {
@ -704,13 +746,16 @@ class MyClass {
var memberInt : int;
var memberBool : bool = true;
// Explicitly defined initializer.
// We also get the compiler-generated initializer, with one argument per field.
// Note that soon there will be no compiler-generated initializer when we
// define any initializer(s) explicitly.
proc init(val : real) {
this.memberInt = ceil(val): int;
}
// By default, any class that doesn't define an initializer gets a
// compiler-generated initializer, with one argument per field and
// the field's initial value as the argument's default value.
// Alternatively, the user can define initializers manually as shown
// in the following commented-out routine:
//
/* // proc init(val : real) {
// this.memberInt = ceil(val): int;
// }
*/
// Explicitly defined deinitializer.
// If we did not write one, we would get the compiler-generated deinitializer,
@ -738,37 +783,45 @@ class MyClass {
} // end MyClass
// Call compiler-generated initializer, using default value for memberBool.
var myObject = new MyClass(10);
myObject = new MyClass(memberInt = 10); // Equivalent
writeln(myObject.getMemberInt());
{
var myObject = new owned MyClass(10);
myObject = new owned MyClass(memberInt = 10); // Equivalent
writeln(myObject.getMemberInt());
// Same, but provide a memberBool value explicitly.
var myDiffObject = new MyClass(-1, true);
myDiffObject = new MyClass(memberInt = -1,
memberBool = true); // Equivalent
writeln(myDiffObject);
// Same, but provide a memberBool value explicitly.
var myDiffObject = new owned MyClass(-1, true);
myDiffObject = new owned MyClass(memberInt = -1,
memberBool = true); // Equivalent
writeln(myDiffObject);
// Call the initializer we wrote.
var myOtherObject = new MyClass(1.95);
myOtherObject = new MyClass(val = 1.95); // Equivalent
writeln(myOtherObject.getMemberInt());
// Similar, but rely on the default value of memberInt, passing in memberBool.
var myThirdObject = new owned MyClass(memberBool = true);
writeln(myThirdObject);
// We can define an operator on our class as well, but
// the definition has to be outside the class definition.
proc +(A : MyClass, B : MyClass) : MyClass {
return new MyClass(memberInt = A.getMemberInt() + B.getMemberInt(),
memberBool = A.getMemberBool() || B.getMemberBool());
// If the user-defined initializer above had been uncommented, we could
// make the following calls:
//
/* // var myOtherObject = new MyClass(1.95);
// myOtherObject = new MyClass(val = 1.95);
// writeln(myOtherObject.getMemberInt());
*/
// We can define an operator on our class as well, but
// the definition has to be outside the class definition.
proc +(A : MyClass, B : MyClass) : owned MyClass {
return
new owned MyClass(memberInt = A.getMemberInt() + B.getMemberInt(),
memberBool = A.getMemberBool() || B.getMemberBool());
}
var plusObject = myObject + myDiffObject;
writeln(plusObject);
// Destruction of an object: calls the deinit() routine and frees its memory.
// ``unmanaged`` variables should have ``delete`` called on them.
// ``owned`` variables are destroyed when they go out of scope.
}
var plusObject = myObject + myDiffObject;
writeln(plusObject);
// Destruction.
delete myObject;
delete myDiffObject;
delete myOtherObject;
delete plusObject;
// Classes can inherit from one or more parent classes
class MyChildClass : MyClass {
var memberComplex: complex;
@ -780,42 +833,46 @@ class GenericClass {
var classDomain: domain(1);
var classArray: [classDomain] classType;
// Explicit constructor.
proc GenericClass(type classType, elements : int) {
this.classDomain = {1..#elements};
// Explicit initializer.
proc init(type classType, elements : int) {
this.classType = classType;
this.classDomain = {1..elements};
// all generic and const fields must be initialized in "phase 1" prior
// to a call to the superclass initializer.
}
// Copy constructor.
// Note: We still have to put the type as an argument, but we can
// default to the type of the other object using the query (?) operator.
// Further, we can take advantage of this to allow our copy constructor
// to copy classes of different types and cast on the fly.
proc GenericClass(other : GenericClass(?otherType),
type classType = otherType) {
// Copy-style initializer.
// Note: We include a type argument whose default is the type of the first
// argument. This lets our initializer copy classes of different
// types and cast on the fly.
proc init(other : GenericClass(?),
type classType = other.classType) {
this.classType = classType;
this.classDomain = other.classDomain;
// Copy and cast
for idx in this.classDomain do this[idx] = other[idx] : classType;
this.classArray = for o in other do o: classType; // copy and cast
}
// Define bracket notation on a GenericClass
// object so it can behave like a normal array
// i.e. objVar[i] or objVar(i)
// i.e. ``objVar[i]`` or ``objVar(i)``
proc this(i : int) ref : classType {
return this.classArray[i];
}
// Define an implicit iterator for the class
// to yield values from the array to a loop
// i.e. for i in objVar do ...
// i.e. ``for i in objVar do ...``
iter these() ref : classType {
for i in this.classDomain do
yield this[i];
}
} // end GenericClass
// Allocate an owned instance of our class
var realList = new owned GenericClass(real, 10);
// We can assign to the member array of the object using the bracket
// notation that we defined.
var realList = new GenericClass(real, 10);
for i in realList.classDomain do realList[i] = i + 1.0;
// We can iterate over the values in our list with the iterator
@ -823,23 +880,25 @@ for i in realList.classDomain do realList[i] = i + 1.0;
for value in realList do write(value, ", ");
writeln();
// Make a copy of realList using the copy constructor.
var copyList = new GenericClass(realList);
// Make a copy of realList using the copy initializer.
var copyList = new owned GenericClass(realList);
for value in copyList do write(value, ", ");
writeln();
// Make a copy of realList and change the type, also using the copy constructor.
var copyNewTypeList = new GenericClass(realList, int);
// Make a copy of realList and change the type, also using the copy initializer.
var copyNewTypeList = new owned GenericClass(realList, int);
for value in copyNewTypeList do write(value, ", ");
writeln();
// Modules
/*
Modules
*/
// Modules are Chapel's way of managing name spaces.
// The files containing these modules do not need to be named after the modules
// (as in Java), but files implicitly name modules.
// For example, this file implicitly names the learnChapelInYMinutes module
// For example, this file implicitly names the ``learnChapelInYMinutes`` module
module OurModule {
@ -870,21 +929,23 @@ module OurModule {
}
} // end OurModule
// Using OurModule also uses all the modules it uses.
// Since OurModule uses Time, we also use Time.
// Using ``OurModule`` also uses all the modules it uses.
// Since ``OurModule`` uses ``Time``, we also use ``Time``.
use OurModule;
// At this point we have not used ChildModule or SiblingModule so
// their symbols (i.e. foo) are not available to us. However, the module
// names are available, and we can explicitly call foo() through them.
// At this point we have not used ``ChildModule`` or ``SiblingModule`` so
// their symbols (i.e. ``foo``) are not available to us. However, the module
// names are available, and we can explicitly call ``foo()`` through them.
SiblingModule.foo();
OurModule.ChildModule.foo();
// Now we use ChildModule, enabling unqualified calls.
// Now we use ``ChildModule``, enabling unqualified calls.
use ChildModule;
foo();
// Parallelism
/*
Parallelism
*/
// In other languages, parallelism is typically done with
// complicated libraries and strange class structure hierarchies.
@ -894,9 +955,9 @@ foo();
// executed.
proc main() {
// A begin statement will spin the body of that statement off
// A ``begin`` statement will spin the body of that statement off
// into one new task.
// A sync statement will ensure that the progress of the main
// A ``sync`` statement will ensure that the progress of the main
// task will not progress until the children have synced back up.
sync {
@ -913,7 +974,7 @@ proc main() {
writeln("fibonacci(",n,") = ", fibonacci(n));
}
// A cobegin statement will spin each statement of the body into one new
// A ``cobegin`` statement will spin each statement of the body into one new
// task. Notice here that the prints from each statement may happen in any
// order.
cobegin {
@ -929,17 +990,17 @@ proc main() {
}
}
// A coforall loop will create a new task for EACH iteration.
// A ``coforall`` loop will create a new task for EACH iteration.
// Again we see that prints happen in any order.
// NOTE: coforall should be used only for creating tasks!
// NOTE: ``coforall`` should be used only for creating tasks!
// Using it to iterating over a structure is very a bad idea!
var num_tasks = 10; // Number of tasks we want
coforall taskID in 1..#num_tasks {
coforall taskID in 1..num_tasks {
writeln("Hello from task# ", taskID);
}
// forall loops are another parallel loop, but only create a smaller number
// of tasks, specifically --dataParTasksPerLocale= number of tasks.
// ``forall`` loops are another parallel loop, but only create a smaller number
// of tasks, specifically ``--dataParTasksPerLocale=`` number of tasks.
forall i in 1..100 {
write(i, ", ");
}
@ -951,10 +1012,10 @@ proc main() {
// (1..3, 4..6, or 7..9) doing that chunk serially, but each task happens
// in parallel. Your results may depend on your machine and configuration
// For both the forall and coforall loops, the execution of the
// For both the ``forall`` and ``coforall`` loops, the execution of the
// parent task will not continue until all the children sync up.
// forall loops are particularly useful for parallel iteration over arrays.
// ``forall`` loops are particularly useful for parallel iteration over arrays.
// Lets run an experiment to see how much faster a parallel loop is
use Time; // Import the Time module to use Timer objects
var timer: Timer;
@ -982,14 +1043,14 @@ proc main() {
// the parallel loop went faster than the serial loop.
// The bracket style loop-expression described
// much earlier implicitly uses a forall loop.
// much earlier implicitly uses a ``forall`` loop.
[val in myBigArray] val = 1 / val; // Parallel operation
// Atomic variables, common to many languages, are ones whose operations
// occur uninterrupted. Multiple threads can therefore modify atomic
// variables and can know that their values are safe.
// Chapel atomic variables can be of type bool, int,
// uint, and real.
// Chapel atomic variables can be of type ``bool``, ``int``,
// ``uint``, and ``real``.
var uranium: atomic int;
uranium.write(238); // atomically write a variable
writeln(uranium.read()); // atomically read a variable
@ -1003,7 +1064,7 @@ proc main() {
writeln("uranium was ", was, " but is now ", replaceWith);
var isEqualTo = 235;
if uranium.compareExchange(isEqualTo, replaceWith) {
if uranium.compareAndSwap(isEqualTo, replaceWith) {
writeln("uranium was equal to ", isEqualTo,
" so replaced value with ", replaceWith);
} else {
@ -1025,7 +1086,7 @@ proc main() {
}
}
// sync variables have two states: empty and full.
// ``sync`` variables have two states: empty and full.
// If you read an empty variable or write a full variable, you are waited
// until the variable is full or empty again.
var someSyncVar$: sync int; // varName$ is a convention not a law.
@ -1043,9 +1104,8 @@ proc main() {
}
}
// single vars can only be written once. A read on an unwritten single
// results in a wait, but when the variable has a value it can be read
// indefinitely.
// ``single`` vars can only be written once. A read on an unwritten ``single``
// results in a wait, but when the variable has a value it can be read indefinitely.
var someSingleVar$: single int; // varName$ is a convention not a law.
sync {
begin { // Reader task
@ -1063,7 +1123,7 @@ proc main() {
}
}
// Here's an example using atomics and a sync variable to create a
// Here's an example using atomics and a ``sync`` variable to create a
// count-down mutex (also known as a multiplexer).
var count: atomic int; // our counter
var lock$: sync bool; // the mutex lock
@ -1074,7 +1134,7 @@ proc main() {
// (full:unlocked / empty:locked)
// Also, writeXF() fills (F) the sync var regardless of its state (X)
coforall task in 1..#5 { // Generate tasks
coforall task in 1..5 { // Generate tasks
// Create a barrier
do {
lock$; // Read lock$ (wait)
@ -1091,7 +1151,7 @@ proc main() {
lock$.writeXF(true); // Set lock$ to full (signal)
}
// We can define the operations + * & | ^ && || min max minloc maxloc
// We can define the operations ``+ * & | ^ && || min max minloc maxloc``
// over an entire array using scans and reductions.
// Reductions apply the operation over the entire array and
// result in a scalar value.
@ -1099,7 +1159,7 @@ proc main() {
var sumOfValues = + reduce listOfValues;
var maxValue = max reduce listOfValues; // 'max' give just max value
// maxloc gives max value and index of the max value.
// ``maxloc`` gives max value and index of the max value.
// Note: We have to zip the array and domain together with the zip iterator.
var (theMaxValue, idxOfMax) = maxloc reduce zip(listOfValues,
listOfValues.domain);
@ -1108,7 +1168,7 @@ proc main() {
// Scans apply the operation incrementally and return an array with the
// values of the operation at that index as it progressed through the
// array from array.domain.low to array.domain.high.
// array from ``array.domain.low`` to ``array.domain.high``.
var runningSumOfValues = + scan listOfValues;
var maxScan = max scan listOfValues;
writeln(runningSumOfValues);
@ -1116,8 +1176,7 @@ proc main() {
} // end main()
```
Who is this tutorial for?
-------------------------
## Who is this tutorial for?
This tutorial is for people who want to learn the ropes of chapel without
having to hear about what fiber mixture the ropes are, or how they were
@ -1132,28 +1191,27 @@ to see if more topics have been added or more tutorials created.
### What this tutorial is lacking:
* Exposition of the [standard modules](https://chapel-lang.org/docs/latest/modules/standard.html)
* Multiple Locales (distributed memory system)
* Records
* Parallel iterators
* Exposition of the [standard modules](https://chapel-lang.org/docs/latest/modules/standard.html)
* Multiple Locales (distributed memory system)
* Records
* Parallel iterators
Your input, questions, and discoveries are important to the developers!
-----------------------------------------------------------------------
## Your input, questions, and discoveries are important to the developers!
The Chapel language is still in active development, so there are
occasional hiccups with performance and language features. The more information
you give the Chapel development team about issues you encounter or features you
would like to see, the better the language becomes.
There are several ways to interact with the developers:
+ [Gitter chat](https://gitter.im/chapel-lang/chapel)
+ [sourceforge email lists](https://sourceforge.net/p/chapel/mailman)
* [Gitter chat](https://gitter.im/chapel-lang/chapel)
* [sourceforge email lists](https://sourceforge.net/p/chapel/mailman)
If you're really interested in the development of the compiler or contributing
to the project, [check out the master GitHub repository](https://github.com/chapel-lang/chapel).
It is under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0).
Installing the Compiler
-----------------------
## Installing the Compiler
[The Official Chapel documentation details how to download and compile the Chapel compiler.](https://chapel-lang.org/docs/usingchapel/QUICKSTART.html)
@ -1161,23 +1219,22 @@ Chapel can be built and installed on your average 'nix machine (and cygwin).
[Download the latest release version](https://github.com/chapel-lang/chapel/releases/)
and it's as easy as
1. `tar -xvf chapel-<VERSION>.tar.gz`
2. `cd chapel-<VERSION>`
3. `source util/setchplenv.bash # or .sh or .csh or .fish`
4. `make`
5. `make check # optional`
1. `tar -xvf chapel-<VERSION>.tar.gz`
2. `cd chapel-<VERSION>`
3. `source util/setchplenv.bash # or .sh or .csh or .fish`
4. `make`
5. `make check # optional`
You will need to `source util/setchplenv.EXT` from within the Chapel directory
(`$CHPL_HOME`) every time your terminal starts so it's suggested that you drop
that command in a script that will get executed on startup (like .bashrc).
Chapel is easily installed with Brew for macOS
Chapel is easily installed on macOS with Homebrew
1. `brew update`
2. `brew install chapel`
1. `brew update`
2. `brew install chapel`
Compiling Code
--------------
## Compiling Code
Builds like other compilers:
@ -1185,10 +1242,10 @@ Builds like other compilers:
Notable arguments:
* `--fast`: enables a number of optimizations and disables array bounds
checks. Should only enable when application is stable.
* `--set <Symbol Name>=<Value>`: set config param `<Symbol Name>` to `<Value>`
at compile-time.
* `--main-module <Module Name>`: use the main() procedure found in the module
`<Module Name>` as the executable's main.
* `--module-dir <Directory>`: includes `<Directory>` in the module search path.
* `--fast`: enables a number of optimizations and disables array bounds
checks. Should only enable when application is stable.
* `--set <Symbol Name>=<Value>`: set config param `<Symbol Name>` to `<Value>`
at compile-time.
* `--main-module <Module Name>`: use the main() procedure found in the module
`<Module Name>` as the executable's main.
* `--module-dir <Directory>`: includes `<Directory>` in the module search path.

View File

@ -504,8 +504,8 @@ sqr ;; => #<procedure (sqr x)>
(import star-squarer)
(square 3) ;; => ((* * *)(* * *)(* * *))
```
## Further Reading
* [CHICKEN User's Manual](https://wiki.call-cc.org/manual).
* [R5RS standards](http://www.schemers.org/Documents/Standards/R5RS)

View File

@ -184,12 +184,6 @@ organizations.
*and then re-run the program. This time the output is:
THE FULL NAME IS: BOB GIBBERISH COBB
```
##Ready For More?

View File

@ -233,6 +233,7 @@ ColdFusion started as a tag-based language. Almost all functionality is availabl
<em>Code for reference (Functions must return something to support IE)</em>
```
```cfs
<cfcomponent>
<cfset this.hello = "Hello" />

View File

@ -17,7 +17,6 @@ popular and recent book is [Land of Lisp](http://landoflisp.com/). A new book ab
```lisp
;;;-----------------------------------------------------------------------------
;;; 0. Syntax
;;;-----------------------------------------------------------------------------

View File

@ -9,7 +9,6 @@ contributors:
---
```crystal
# This is a comment
# Everything is an object
@ -556,7 +555,6 @@ rescue ex4 # catch any kind of exception
end
ex #=> "ex2"
```
## Additional resources

View File

@ -1,5 +1,5 @@
---
language: brainfuck
language: bf
contributors:
- ["Prajit Ramachandran", "http://prajitr.github.io/"]
- ["Mathias Bynens", "http://mathiasbynens.be/"]

View File

@ -220,9 +220,11 @@ p { vlastnost: hodnota !important; }
```
a tento element
```xml
<p style='/*F*/ vlastnost:hodnota;' trida='trida1 trida2' attr='hodnota' />
```
Priorita stylu je následující. Pamatujte, priorita pro každou **vlastnost**, ne pro celý blok.
* `E` má nejvyšší prioritu kvůli slůvku `!important`. Je doporučováno se úplně vyhnout jeho použití.

View File

@ -90,7 +90,7 @@ může obsahovat nové řádky` // Opět typ řetězec.
// Můžeme použít ne ASCII znaky, Go používá UTF-8.
g := 'Σ' // type runa, což je alias na int32 a ukládá se do něj znak UTF-8
f := 3.14195 // float64, je IEEE-754 64-bit číslem s plovoucí čárkou.
f := 3.14159 // float64, je IEEE-754 64-bit číslem s plovoucí čárkou.
c := 3 + 4i // complex128, interně uložené jako dva float64.
// takhle vypadá var s inicializací
@ -408,24 +408,24 @@ func requestServer() {
## Kam dále
Vše hlavní o Go se nachází na [oficiálních stránkách go](http://golang.org/).
Vše hlavní o Go se nachází na [oficiálních stránkách go](https://go.dev/).
Tam najdete tutoriály, interaktivní konzolu a mnoho materiálu ke čtení.
Kromě úvodu, [dokumenty](https://golang.org/doc/) tam obsahují jak psát čistý kód v Go
Kromě úvodu, [dokumenty](https://go.dev/doc/) tam obsahují jak psát čistý kód v Go
popis balíčků (package), dokumentaci příkazové řádky a historii releasů.
Také doporučujeme přečíst si definici jazyka. Je čtivá a překvapivě krátká. Tedy alespoň proti
jiným současným jazyků.
Pokud si chcete pohrát s Go, tak navštivte [hřiště Go](https://play.golang.org/p/r46YvCu-XX).
Můžete tam spouštět programy s prohlížeče. Také můžete [https://play.golang.org](https://play.golang.org) použít jako
Pokud si chcete pohrát s Go, tak navštivte [hřiště Go](https://go.dev/play/p/r46YvCu-XX).
Můžete tam spouštět programy s prohlížeče. Také můžete [https://go.dev/play/](https://go.dev/play/) použít jako
[REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop), kde si v rychlosti vyzkoušíte věci, bez instalace Go.
Na vašem knižním seznamu, by neměly chybět [zdrojáky stadardní knihovny](http://golang.org/src/pkg/).
Důkladně popisuje a dokumentuje Go, styl zápisu Go a Go idiomy. Pokud kliknete na [dokumentaci](http://golang.org/pkg/)
Na vašem knižním seznamu, by neměly chybět [zdrojáky stadardní knihovny](https://go.dev/src/).
Důkladně popisuje a dokumentuje Go, styl zápisu Go a Go idiomy. Pokud kliknete na [dokumentaci](https://go.dev/pkg/)
tak se podíváte na dokumentaci.
Dalším dobrým zdrojem informací je [Go v ukázkách](https://gobyexample.com/).
Go mobile přidává podporu pro Android a iOS. Můžete s ním psát nativní mobilní aplikace nebo knihovny, které půjdou
spustit přes Javu (pro Android), nebo Objective-C (pro iOS). Navštivte [web Go Mobile](https://github.com/golang/go/wiki/Mobile)
spustit přes Javu (pro Android), nebo Objective-C (pro iOS). Navštivte [web Go Mobile](https://go.dev/wiki/Mobile)
pro více informací.

View File

@ -295,7 +295,6 @@ class Samuel
$cat = new Samuel();
$cat instanceof KittenInterface === true; // True
```
## Více informací

View File

@ -620,7 +620,7 @@ na stránkách Mozilla Developer Network.
[2]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
[3]: https://developer.mozilla.org/en-US/docs/Using_the_W3C_DOM_Level_1_Core
[4]: http://www.learneroo.com/modules/64/nodes/350
[5]: http://bonsaiden.github.io/JavaScript-Garden/
[5]: https://shamansir.github.io/JavaScript-Garden/
[6]: http://www.amazon.com/gp/product/0596805527/
[7]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript
[8]: http://eloquentjavascript.net/

View File

@ -19,41 +19,18 @@ které markdown dále zpracovávají) mírně odlišuje. V této příručce se
upozorňovat, kdy se jedná o obecnou vlastnost markdownu a kdy se jedná o
specifickou vlastnost daného parseru.
## Obsah
- [Obsah](#obsah)
- [HTML Elementy](#html-elementy)
- [Nadpisy](#nadpisy)
- [Jednoduché stylování textu](#jednoduché-stylování-textu)
- [Odstavce](#odstavce)
- [Blokové citace](#blokové-citace)
- [Seznamy](#seznamy)
- [Bloky kódu](#bloky-kódu)
- [Vodorovná čára (`<hr />`)](#vodorovná-čára-hr-)
- [Odkazy](#odkazy)
- [Obsahy](#obsahy)
- [Obrázky](#obrázky)
- [Ostatní](#ostatní)
- [Automatické odkazy](#automatické-odkazy)
- [Automatické odkazy z emailů](#automatické-odkazy-z-emailů)
- [Escapování znaků](#escapování-znaků)
- [Klávesové zkratky](#klávesové-zkratky)
- [Tabulky](#tabulky)
- [Markdownlint](#markdownlint)
- [Reference](#reference)
## HTML Elementy
Markdown je nadstavba HTML. To znamená, že každý HTML kód je zároveň validním
kódem v Markdownu.
```md
<!-- To znamená, že v Markdownu můžeme používat HTML elementy jako například
komentáře, které nebudou ovlivněny parserem Markdownu. Na druhou stranu to také
znamená, že pokud ve svém Markdown kódu vytvoříte HTML element, už v rámci
tohoto elementu nelze použít Markdown.
<!-- To znamená, že v Markdownu můžeme používat HTML elementy jako například
komentáře, které nebudou ovlivněny parserem Markdownu. Na druhou stranu to také
znamená, že pokud ve svém Markdown kódu vytvoříte HTML element, už v rámci
tohoto elementu nelze použít Markdown.
Markdown využívá i tato stránka, a tak by tento text, kdyby nebyl obalen v bloku
Markdown využívá i tato stránka, a tak by tento text, kdyby nebyl obalen v bloku
kódu (viz níže), jako validní HTML komentář vůbec nebyl vidět. -->
```
@ -132,7 +109,7 @@ Blokové citace se dělají jednoduše uvozením řádku znakem >.
```md
> Toto je bloková citace. Můžete dokonce
> manuálně rozdělit řádky, a před každý vložit >, nebo nechat vaše řádky
> manuálně rozdělit řádky, a před každý vložit >, nebo nechat vaše řádky
> jakkoli dlouhé, ať se zarovnají samy.
> Je to jedno, pokud vždy začínají symbolem `>`.
@ -170,7 +147,7 @@ nebo
2. Položka dvě
3. Položka tři
<!-- Čísla ani nemusíte psát popořadě. Markdown je umí zobrazit správně, jenom
<!-- Čísla ani nemusíte psát popořadě. Markdown je umí zobrazit správně, jenom
je třeba vždy překontrolovat, že číslování funguje správně. -->
1. Položka jedna
@ -215,7 +192,7 @@ Pro ještě hlubší odsazení můžete přidat další 4 mezery nebo další ta
```md
moje_pole.each do |i|
puts i
puts i
end
```
@ -228,11 +205,13 @@ Honza neměl tušení, co dělá funkce `go_to()`!
V Markdownu od GitHubu, můžete použít speciální syntaxi pro kód:
<pre><code class="highlight">&#x60;&#x60;&#x60;ruby
````md
```ruby
def neco
puts "Ahoj světe!"
puts "Ahoj světe!"
end
&#x60;&#x60;&#x60;</code></pre>
```
````
Text výše nepotřebuje čtyřmezerové odsazení a parser navíc použije zvýraznění
syntaxe pro zvolený jazyk.
@ -252,8 +231,8 @@ pomlček), a to buď s mezerami mezi jednotlivými znaky, nebo bez nich.
## Odkazy
```md
<!-- Jedna z nejlepších vlastností Markdownu je, jak snadno lze s jeho pomocí
vytvářet odkazy. Text odkazu, který chcete zobrazit vložte do [] a hned za něj
<!-- Jedna z nejlepších vlastností Markdownu je, jak snadno lze s jeho pomocí
vytvářet odkazy. Text odkazu, který chcete zobrazit vložte do [] a hned za něj
v kulatých závorkách () připojte url adresu. -->
[Klikni na mě!](http://test.com/)
@ -277,12 +256,12 @@ v kulatých závorkách () připojte url adresu. -->
[link1]: http://test.com/ "Cool!"
[neco]: http://neco.czz/ "Dobře!"
<!-- Titulek v tomto případě může být v jednoduchých uvozovkách, závorkách, nebo
zcela vynechaný. Reference může být kdekoliv ve vašem dokumentu a identifikátory
<!-- Titulek v tomto případě může být v jednoduchých uvozovkách, závorkách, nebo
zcela vynechaný. Reference může být kdekoliv ve vašem dokumentu a identifikátory
mohou být jakékoli, pokud jsou unikátní. -->
<!-- V markdownu existuje rovněž "implicitní pojmenování", které použije text
<!-- V markdownu existuje rovněž "implicitní pojmenování", které použije text
odkazu jako své id -->
[Toto][] je odkaz..
@ -329,7 +308,7 @@ fungovat stejně.
### Automatické odkazy
```md
<http://stranka.cz/>
<http://stranka.cz/>
je stejné jako
@ -345,14 +324,14 @@ je stejné jako
### Escapování znaků
```md
Chci napsat *tento text obklopený hvězdičkami*, ale protože nechci, aby to bylo
Chci napsat *tento text obklopený hvězdičkami*, ale protože nechci, aby to bylo
kurzívou, tak hvězdičky vyescapuji `\`: \*tento text bude obklopený hvězdičkami\*.
```
### Klávesové zkratky
```md
<!-- V Markdownu od GitHubu můžete použít tag <kbd> k označení kláves na
<!-- V Markdownu od GitHubu můžete použít tag <kbd> k označení kláves na
počítači -->
Váš počítač přestal pracovat? Zkuste

View File

@ -14,13 +14,9 @@ lang: cs-cz
Python byl vytvořen Guidem Van Rossum v raných 90. letech. Nyní je jedním z nejpopulárnějších jazyků.
Zamiloval jsem si Python pro jeho syntaktickou čistotu - je to vlastně spustitelný pseudokód.
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/pythonlegacy/).
```python
# Jednořádkový komentář začíná křížkem
""" Víceřádkové komentáře používají tři uvozovky nebo apostrofy
@ -78,9 +74,9 @@ False or True # => True
0 and 2 # => 0
-5 or 0 # => -5
# Při porovnání s boolean hodnotou nepoužívejte operátor rovnosti "==".
# Při porovnání s boolean hodnotou nepoužívejte operátor rovnosti "==".
# Stejně jako u hodnoty None.
# Viz PEP8: https://www.python.org/dev/peps/pep-0008/
# Viz PEP8: https://www.python.org/dev/peps/pep-0008/
0 is False # => True
2 is True # => False
1 is True # => True
@ -160,7 +156,7 @@ print("Jsem 3. Python 3.")
nazev_promenne = 5
nazev_promenne # => 5
# Názvy proměnných mohou obsahovat i unicode znaky, ale nedělejte to.
# Viz PEP 3131 -- Supporting Non-ASCII Identifiers:
# Viz PEP 3131 -- Supporting Non-ASCII Identifiers:
# https://www.python.org/dev/peps/pep-3131/
název_proměnné = 5
@ -644,5 +640,6 @@ pozdrav("Pepo") # Vypíše 3x: "Měj se Pepo!"
## Co dál?
Spoustu odkazů na české i anglické materiály najdete na [webu české Python komunity]
(http://python.cz/). Můžete také přijít na Pyvo, kde to společně probereme.
Spoustu odkazů na české i anglické materiály najdete na
[webu české Python komunity](http://python.cz/). Můžete
také přijít na Pyvo, kde to společně probereme.

View File

@ -19,8 +19,6 @@ Tento tutoriál bude používat syntaxi CSS.
Pokud jste již obeznámeni s CSS3, budete schopni používat Sass relativně rychle. Nezprostředkovává nějaké úplně nové stylové možnosti, spíše nátroje, jak psát Vás CSS kód více efektivně, udržitelně a jednoduše.
```scss
//Jednořádkové komentáře jsou ze Sassu při kompilaci vymazány
/*Víceřádkové komentáře jsou naopak zachovány */
@ -411,8 +409,6 @@ body {
.gutter {
width: 6.25%;
}
```

View File

@ -867,7 +867,7 @@ on a new line! ""Wow!"", the masses cried";
}
// It's also possible to define custom Indexers on objects.
// All though this is not entirely useful in this example, you
// Although this is not entirely useful in this example, you
// could do bicycle[0] which returns "chris" to get the first passenger or
// bicycle[1] = "lisa" to set the passenger. (of this apparent quattrocycle)
private string[] passengers = { "chris", "phil", "darren", "regina" };
@ -1311,7 +1311,6 @@ namespace Csharp7
}
}
}
```
## Topics Not Covered

View File

@ -69,6 +69,9 @@ div { }
/* or ends with a value (CSS 3) */
[attr$='ue'] { font-size:smaller; }
/* or contains a value (CSS 3) */
[attr*='foo'] { }
/* or contains a value in a space-separated list */
[otherAttr~='foo'] { }
[otherAttr~='bar'] { }
@ -125,6 +128,9 @@ selector:first-child {}
/* any element that is the last child of its parent */
selector:last-child {}
/* Select the nth child of selector parent (CSS 3) */
selector:nth-child(n) { }
/* Just like pseudo classes, pseudo elements allow you to style certain parts of
a document */
@ -144,6 +150,12 @@ selector::after {}
in the group */
selector1, selector2 { }
/* Select elements that do not have a certain state (CSS 3) */
/* Here, we select div with no id attribute. */
div:not([id]) {
background-color: red;
}
/* ####################
## PROPERTIES
#################### */
@ -196,6 +208,41 @@ selector {
/* if the first one is not found, the browser uses the next, and so on */
font-family: "Courier New", Trebuchet, Arial, sans-serif;
}
/* Custom CSS properties using variables (CSS 3) */
:root {
--main-bg-color: whitesmoke;
}
body {
background-color: var(--main-bg-color)
}
/* Perfom a calculation (CSS 3) */
body {
width: calc(100vw - 100px)
}
/* Nest style rule inside another (CSS 3) */
.main {
.bgred { /* same as: .main .bgred { } */
background: red;
}
& .bggreen { /* same as: .main .bggreen { } */
background: green;
}
&.bgblue { /* (without space) same as: .main.bgblue { } */
background: blue;
}
}
/* Design responsive layout using flexbox (CSS 3) */
.container {
display: flex;
flex-direction: row; /* in which direction stack the flex items */
flex-wrap: wrap; /* whether or not flex items should wrap */
justify-content: center; /* how to align flex items horizontally */
align-items: center; /* how to align flex items vertically */
}
```
## Usage

View File

@ -1,7 +1,7 @@
---
name: CUE
category: language
language: cue
language: CUE
filename: learncue.cue
contributors:
- ["Daniel Cox", "https://github.com/danielpcox"]
@ -23,8 +23,9 @@ disposition: "oblivious"
```
Now we can unify and export to JSON:
```bash
% cue export name.cue disposition.cue
% cue export name.cue disposition.cue
{
"name": "Daniel",
"disposition": "oblivious"
@ -32,8 +33,9 @@ Now we can unify and export to JSON:
```
Or YAML:
```bash
% cue export --out yaml name.cue disposition.cue
% cue export --out yaml name.cue disposition.cue
name: Daniel
disposition: oblivious
```
@ -58,7 +60,7 @@ foo: 100
```
```bash
% cue export string_value.cue integer_value.cue
% cue export string_value.cue integer_value.cue
foo: conflicting values "baz" and 100 (mismatched types string and int):
integer_value.cue:1:6
string_value.cue:1:6
@ -220,7 +222,7 @@ vatican_city: #Country & {
}
```
CUE may save you quite a bit of time with all the sugar it provides on top of mere JSON. Here we're defining, "modifying", and validating a nested structure in three lines: (Notice the `[]` syntax used around `string` to signal to the engine that `string` is a constraint, not a string in this case.)
CUE may save you quite a bit of time with all the sugar it provides on top of mere JSON. Here we're defining, "modifying", and validating a nested structure in three lines: (Notice the `[]` syntax used around `string` to signal to the engine that `string` is a constraint, not a string in this case.)
```yaml
//paths.cue
@ -386,7 +388,7 @@ j: 8 < 10 // and supports boolean ops
price: number
// Require a justification if price is too high
if price > 100 {
justification: string
justification: string
}
price: 200
justification: "impulse buy"
@ -398,11 +400,11 @@ comp: [ for x in #items if x rem 2 == 0 {x*x}]
// and... well you can do this too
#a: [ "Apple", "Google", "SpaceX"]
for k, v in #a {
"\( strings.ToLower(v) )": {
pos: k + 1
name: v
nameLen: len(v)
}
"\( strings.ToLower(v) )": {
pos: k + 1
name: v
nameLen: len(v)
}
}
```
@ -479,7 +481,7 @@ This creates a `cue.mod/` subdirectory within that `mymodule` directory, and `cu
- gen/
- usr/
For a different perspective on this and details about what's in there, see https://cuelang.org/docs/concepts/packages/. For my purposes here, I'll say you don't need to think about the contents of this directory *at all*, except that your module name will be the prefix for all imports within your module.
For a different perspective on this and details about what's in there, see [cuelang.org/docs/concepts/packages/](https://cuelang.org/docs/concepts/packages/). For my purposes here, I'll say you don't need to think about the contents of this directory *at all*, except that your module name will be the prefix for all imports within your module.
Where will your module file hierarchy go? All files and directories for your module are rooted in `mymodule/`, the directory that also contains `cue.mod/`. If you want to import a package, you'll prefix it with `example.com/mymodule`, followed by a relative path rooted in `mymodule/`.
@ -546,6 +548,6 @@ configuredBar: conflicting values string and 200 (mismatched types string and in
That's it for now. I understand there are more package management features coming in the future and the design decisions around `cue.mod` are looking ahead to that.
Finally, CUE has built-in modules with powerful functionality. We saw one of these earlier, when we imported "strings" and used `strings.ToLower`. Imports without fully-qualified module names are assumed to be built-ins. The full list and documentation for each is here: https://pkg.go.dev/cuelang.org/go/pkg
Finally, CUE has built-in modules with powerful functionality. We saw one of these earlier, when we imported "strings" and used `strings.ToLower`. Imports without fully-qualified module names are assumed to be built-ins. The full list and documentation for each is here: [pkg.go.dev/cuelang.org/go/pkg](https://pkg.go.dev/cuelang.org/go/pkg)
This has been a condensation of the official docs and tutorials, so go give the source material some love: https://cuelang.org/docs/tutorials/
This has been a condensation of the official docs and tutorials, so go give the source material some love: [cuelang.org/docs/tutorials/](https://cuelang.org/docs/tutorials/)

View File

@ -5,84 +5,57 @@ contributors:
- ["Théo Gauchoux", "https://github.com/TheoGauchoux"]
---
Cypher is the Neo4js query language to manipulate graphs easily. It reuses syntax from SQL and mixes it with kind of ascii-art to represent graphs.
Cypher is Neo4j's query language for easily manipulating graphs.
It reuses syntax from SQL and mixes it with kind of an ASCII-art to represent graphs.
This tutorial assumes that you already know graph concepts like nodes and relationships.
[Read more here.](https://neo4j.com/developer/cypher-query-language/)
## Nodes represent a record in a graph
`()` is an empty *node*, to indicate that there is a *node*, but it's not relevant for the query.
Nodes
---
`(n)` is a *node* referred by the variable `n`, reusable in the query. It begins with lowercase and uses camelCase.
**Represents a record in a graph.**
`(p:Person)` - you can add a *label* to your node, here `Person`. It's like a type/class/category. It begins with uppercase and uses camelCase.
`()`
It's an empty *node*, to indicate that there is a *node*, but it's not relevant for the query.
`(p:Person:Manager)` - a node can have many *labels*.
`(n)`
It's a *node* referred by the variable **n**, reusable in the query. It begins with lowercase and uses camelCase.
`(p:Person {name : 'Théo Gauchoux', age : 22})` - a node can have some *properties*, here `name` and `age`. It begins with lowercase and uses camelCase.
`(p:Person)`
You can add a *label* to your node, here **Person**. It's like a type / a class / a category. It begins with uppercase and uses camelCase.
The types allowed in properties:
`(p:Person:Manager)`
A node can have many *labels*.
- Numeric
- Boolean
- String
- List of previous primitive types
`(p:Person {name : 'Théo Gauchoux', age : 22})`
A node can have some *properties*, here **name** and **age**. It begins with lowercase and uses camelCase.
*Warning: there's no datetime properties in Cypher! You can use a String with a specific pattern or a Numeric from a specific date.*
The types allowed in properties :
`p.name` - you can access a property with the dot style.
- Numeric
- Boolean
- String
- List of previous primitive types
## Relationships (or Edges) connect two nodes
*Warning : there isn't datetime property in Cypher ! You can use String with a specific pattern or a Numeric from a specific date.*
`[:KNOWS]` is a *relationship* with the *label* `KNOWS`. It's a *label* as the node's label. It uses UPPER\_SNAKE\_CASE.
`p.name`
You can access to a property with the dot style.
`[k:KNOWS]` - the same *relationship*, referred by the variable `k`, reusable in the query, but it's not necessary.
`[k:KNOWS {since:2017}]` - the same *relationship*, with *properties* (like *node*), here `since`.
Relationships (or Edges)
---
`[k:KNOWS*..4]` is structural information to use in a *path* (seen later). Here, `\*..4` says "Match the pattern, with the relationship `k` which can be repeated between 1 and 4 times.
**Connects two nodes**
## Paths - the way to mix nodes and relationships.
`[:KNOWS]`
It's a *relationship* with the *label* **KNOWS**. It's a *label* as the node's label. It begins with uppercase and use UPPER\_SNAKE\_CASE.
`(a:Person)-[:KNOWS]-(b:Person)` - a path describing that `a` and `b` know each other.
`[k:KNOWS]`
The same *relationship*, referred by the variable **k**, reusable in the query, but it's not necessary.
`(a:Person)-[:MANAGES]->(b:Person)` - a path can be directed. This path describes that `a` is the manager of `b`.
`[k:KNOWS {since:2017}]`
The same *relationship*, with *properties* (like *node*), here **since**.
`(a:Person)-[:KNOWS]-(b:Person)-[:KNOWS]-(c:Person)` - you can chain multiple relationships. This path describes the friend of a friend.
`[k:KNOWS*..4]`
It's a structural information to use in a *path* (seen later). Here, **\*..4** says "Match the pattern, with the relationship **k** which be repeated between 1 and 4 times.
`(a:Person)-[:MANAGES]->(b:Person)-[:MANAGES]->(c:Person)` - a chain can also be directed. This path describes that `a` is the boss of `b` and the big boss of `c`.
Commonly used patterns (from Neo4j documentation):
Paths
---
**The way to mix nodes and relationships.**
`(a:Person)-[:KNOWS]-(b:Person)`
A path describing that **a** and **b** know each other.
`(a:Person)-[:MANAGES]->(b:Person)`
A path can be directed. This path describes that **a** is the manager of **b**.
`(a:Person)-[:KNOWS]-(b:Person)-[:KNOWS]-(c:Person)`
You can chain multiple relationships. This path describes the friend of a friend.
`(a:Person)-[:MANAGES]->(b:Person)-[:MANAGES]->(c:Person)`
A chain can also be directed. This path describes that **a** is the boss of **b** and the big boss of **c**.
Patterns often used (from Neo4j doc) :
```
// Friend-of-a-friend
```cypher
// Friend-of-a-friend
(user)-[:KNOWS]-(friend)-[:KNOWS]-(foaf)
// Shortest path
@ -91,159 +64,167 @@ path = shortestPath( (user)-[:KNOWS*..5]-(other) )
// Collaborative filtering
(user)-[:PURCHASED]->(product)<-[:PURCHASED]-()-[:PURCHASED]->(otherProduct)
// Tree navigation
// Tree navigation
(root)<-[:PARENT*]-(leaf:Category)-[:ITEM]->(data:Product)
```
Create queries
---
## Create queries
Create a new node
```
```cypher
CREATE (a:Person {name:"Théo Gauchoux"})
RETURN a
```
*`RETURN` allows to have a result after the query. It can be multiple, as `RETURN a, b`.*
Create a new relationship (with 2 new nodes)
```
```cypher
CREATE (a:Person)-[k:KNOWS]-(b:Person)
RETURN a,k,b
```
Match queries
---
## Match queries
Match all nodes
```
```cypher
MATCH (n)
RETURN n
```
Match nodes by label
```
```cypher
MATCH (a:Person)
RETURN a
```
Match nodes by label and property
```
```cypher
MATCH (a:Person {name:"Théo Gauchoux"})
RETURN a
```
Match nodes according to relationships (undirected)
```
```cypher
MATCH (a)-[:KNOWS]-(b)
RETURN a,b
```
Match nodes according to relationships (directed)
```
```cypher
MATCH (a)-[:MANAGES]->(b)
RETURN a,b
```
Match nodes with a `WHERE` clause
```
```cypher
MATCH (p:Person {name:"Théo Gauchoux"})-[s:LIVES_IN]->(city:City)
WHERE s.since = 2015
RETURN p,state
```
You can use `MATCH WHERE` clause with `CREATE` clause
```
```cypher
MATCH (a), (b)
WHERE a.name = "Jacquie" AND b.name = "Michel"
CREATE (a)-[:KNOWS]-(b)
```
Update queries
---
## Update queries
Update a specific property of a node
```
```cypher
MATCH (p:Person)
WHERE p.name = "Théo Gauchoux"
SET p.age = 23
```
Replace all properties of a node
```
```cypher
MATCH (p:Person)
WHERE p.name = "Théo Gauchoux"
SET p = {name: "Michel", age: 23}
```
Add new property to a node
```
```cypher
MATCH (p:Person)
WHERE p.name = "Théo Gauchoux"
SET p + = {studies: "IT Engineering"}
SET p += {studies: "IT Engineering"}
```
Add a label to a node
```
```cypher
MATCH (p:Person)
WHERE p.name = "Théo Gauchoux"
SET p:Internship
```
Delete queries
---
## Delete queries
Delete a specific node (linked relationships must be deleted before)
```
```cypher
MATCH (p:Person)-[relationship]-()
WHERE p.name = "Théo Gauchoux"
DELETE relationship, p
```
Remove a property in a specific node
```
```cypher
MATCH (p:Person)
WHERE p.name = "Théo Gauchoux"
REMOVE p.age
```
*Pay attention to the `REMOVE`keyword, it's not `DELETE` !*
*Pay attention to the `REMOVE` keyword, it's not `DELETE`!*
Remove a label from a specific node
```
```cypher
MATCH (p:Person)
WHERE p.name = "Théo Gauchoux"
DELETE p:Person
```
Delete entire database
```
```cypher
MATCH (n)
OPTIONAL MATCH (n)-[r]-()
DELETE n, r
```
*Seriously, it's the `rm -rf /` of Cypher !*
*Seriously, it's the `rm -rf /` of Cypher!*
Other useful clauses
---
## Other useful clauses
`PROFILE`
Before a query, show the execution plan of it.
`PROFILE` - before a query, show its execution plan.
`COUNT(e)`
Count entities (nodes or relationships) matching **e**.
`COUNT(e)` - count entities (nodes or relationships) matching `e`.
`LIMIT x`
Limit the result to the x first results.
`LIMIT x` - limit the result to the first `x` results.
## Special hints
Special hints
---
- There is just single-line comments in Cypher, with double-slash : // Comments
- You can execute a Cypher script stored in a **.cql** file directly in Neo4j (it's an import). However, you can't have multiple statements in this file (separated by **;**).
- Cypher only has single-line comments, using double-slashes: `// comment`
- You can execute a Cypher script stored in a .cql file directly in Neo4j (it's an import). However, you can't have multiple statements in this file (separated by `;`).
- Use the Neo4j shell to write Cypher, it's really awesome.
- The Cypher will be the standard query language for all graph databases (known as **OpenCypher**).
- Cypher will be the standard query language for all graph databases (known as [openCypher](https://opencypher.org/)).
Read more [here](https://neo4j.com/developer/cypher-query-language/).

View File

@ -3,7 +3,6 @@ language: D
filename: learnd.d
contributors:
- ["Nick Papanastasiou", "www.nickpapanastasiou.github.io"]
---
```d
@ -128,7 +127,6 @@ class Matrix(uint m, uint n, T = int) {
}
auto mat = new Matrix!(3, 3); // We've defaulted type 'T' to 'int'.
```
Speaking of classes, let's talk about properties for a second. A property

View File

@ -32,7 +32,7 @@ import "dart:math" as math;
// Single line comment
/**
* Multi-line comment
* Can comment more than 2 lines
* Can comment several lines
*/
/// Code doc comment
/// It uses markdown syntax to generate code docs when making an API.
@ -254,25 +254,29 @@ example10() {
/// `int` and `double` are children of type `num`
example11() {
var i = 1 + 320, d = 3.2 + 0.01;
final num myFinalNumDouble = 2.2;
final num myFinalNumInt = 2;
final int myFinalInt = 1;
final double myFinalDouble = 0.1;
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
myNumDouble = myFinalInt; // valid
myNumDouble = myFinalDouble; // valid
myNumDouble = myFinalNumInt; // valid
myNumInt = myInt; // valid
myNumInt = myDouble; // valid
myNumInt = myNumDouble; // valid
myNumInt = myFinalInt; // valid
myNumInt = myFinalDouble; // valid
myNumInt = myFinalNumDouble; // valid
myInt = myNumDouble; //Error
myInt = myDouble; //Error
myInt = myNumInt; //valid
myInt = myNumDouble; // error
myInt = myFinalDouble; // error
myInt = myFinalNumInt; // valid
myDouble = myInt; //error
myDouble = myNumInt; //valid
myDouble = myNumDouble; //valid
myDouble = myFinalInt; // error
myDouble = myFinalNumInt; // error
myDouble = myFinalNumDouble; // valid
print("Example11 int ${i}");
print("Example11 double ${d}");
@ -308,15 +312,15 @@ example14() {
if (a) {
print("true, a is $a");
}
a = null;
a = false;
if (a) {
print("true, a is $a");
print("true, a is $a");
} else {
print("false, a is $a"); /// runs here
}
/// dynamic typed null can be convert to bool
var b;/// b is dynamic type
/// dynamic typed null can not be convert to bool
var b; /// b is dynamic type
b = "abc";
try {
if (b) {
@ -327,17 +331,17 @@ example14() {
} catch (e) {
print("error, b is $b"); /// this could be run but got error
}
b = null;
if (b) {
b = null;
if (b) { /// Failed assertion: boolean expression must not be null)
print("true, b is $b");
} else {
print("false, b is $b"); /// runs here
print("false, b is $b");
}
/// statically typed null can not be convert to bool
var c = "abc";
c = null;
/// complie failed
/// compilation failed
/// if (c) {
/// print("true, c is $c");
/// } else {
@ -710,7 +714,6 @@ main() {
example30 // Adding this comment stops the dart formatter from putting all items on a new line
].forEach((ef) => ef());
}
```
## Further Reading

View File

@ -8,9 +8,9 @@ filename: asciidoc-de.adoc
lang: de-de
---
AsciiDoc ist eine Auszeichnungssprache ähnlich zu Markdown. Sie kann für alles
verwendet werden von Büchern zu Blogs. Erfunden wurde sie 2002 von Stuart
Rackham. Die Sprache ist simpel aber sie ermöglicht eine große Anzahl an
AsciiDoc ist eine Auszeichnungssprache, ähnlich wie Markdown. Sie kann für alles
verwendet werden von Büchern bis zu Blogs. Erfunden wurde sie 2002 von Stuart
Rackham. Die Sprache ist simpel, aber sie ermöglicht eine große Anzahl an
Anpassungen.
Kopfzeile des Dokuments
@ -57,12 +57,12 @@ Dieser Artikel über Chips wird Spaß machen.
Absätze
```
Du musst nichts besonderes machen für Absätze.
Du musst nichts Besonderes machen für Absätze.
Füge eine Leerzeile zwischen zwei Absätze, um sie zu trennen.
Um eine Leerzeile zu erhalten musst du ein +
ergänzen und du erhälst einen Umbruch!
ergänzen und du erhältst einen Umbruch!
```
Textformatierung
@ -87,7 +87,6 @@ Abteilungstitel
==== Level 3 <h4>
===== Level 4 <h5>
```
Listen

View File

@ -160,7 +160,7 @@ echo "#helloworld" | tee output.out >/dev/null
# (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:
# Die Ausgabe von Befehlen kann mithilfe von $( ) in anderen Befehlen verwendet werden:
# Der folgende Befehl zeigt die Anzahl aller Dateien und Unterverzeichnisse
# im aktuellen Verzeichnis an.
echo "Dieser Ordner beinhaltet $(ls | wc -l) Dateien und Verzeichnisse."

View File

@ -5,8 +5,9 @@ contributors:
filename: learnbc-de.bc
lang: de-de
---
```c
/* Das is ein mehr-
```bc
/* Das ist ein mehr-
zeiliger Kommentar */
# Das ist ein (einzeiliger) Kommentar (in GNU bc).
@ -14,11 +15,11 @@ zeiliger Kommentar */
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 */
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*/
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:
@ -30,21 +31,21 @@ 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.*/
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.:
/* Escape-Sequenzen starten mit einem \ in einem String.
Um Escape-Sequenzen klarer zu machen, ist hier eine vereinfachte
Liste, welche in bc funktionieren:
\b: Backspace
\c: carriage return
\n: Zeilenumbruch
\t: Tab
\\: Backslash*/
} else {
/* Standardmässig sind Variablen global. */
/* Standardmässig sind Variablen global. */
thisIsGlobal = 5
/*Variablen können lokal gemacht werden. Benutze das Schlüsselwort "auto"
/*Variablen können lokal gemacht werden. Benutze das Schlüsselwort "auto"
in einer Funktion.*/
}
@ -55,7 +56,7 @@ num = blankVariable /*num wurde auf 0 gesetzt.*/
if(!num) {print "false\n"}
/*Im Gegensatz zu C hat bc den Ternäroperator ?: nicht. Zum Beispiel
führt dieser Codeblok zu einem Fehler:
führt dieser Codeblock zu einem Fehler:
a = (num) ? 1 : 0
Jedoch kann dies simuliert werden:*/
a = (num) && (1) || (0) /*&& ist das UND, || ist das ODER*/
@ -78,7 +79,7 @@ define fac(n) { /*Definiere eine Funktion mit define*/
num = fac(4) /*24*/
/*Dies ist ein Beispiel von lokalen Variabeln.*/
/*Dies ist ein Beispiel von lokalen Variablen.*/
define x(n) {
auto x
x = 1
@ -96,7 +97,7 @@ 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

@ -19,7 +19,7 @@ Brainfuck im Browser ausprobiert werden.
```
Alle Zeichen außer "><+-.,[]" (ohne die Klammern) werden ignoriert.
Brainfuck besteht aus einem Array mit unendlich vielen Elementen, die alle mit Null initalisiert
Brainfuck besteht aus einem Array mit unendlich vielen Elementen, die alle mit Null initialisiert
sind und einem Datenzeiger auf das aktuelle Element.
Es gibt acht Befehle:
@ -29,10 +29,10 @@ Es gibt acht Befehle:
< : Bewegt den Zeiger um eine Stelle zurück.
. : Gibt den Wert der aktuellen Zelle als ASCII Wert aus (z.B. 65 = 'A').
, : Liest ein einzelnes Zeichen von der Standardeingabe und speichert dessen ASCII Wert in der aktuellen Zelle.
[ : Wenn der Wert des aktuellen Elements Null ist, bewege des Zeiger hinter den
[ : Wenn der Wert des aktuellen Elements Null ist, bewege den Zeiger hinter den
zugehörigen ]-Befehl.
Ansonsten, bewege den Zeiger ein Element weiter.
] : Wenn der Wert des aktuellen Elements Null ist, bewege des Zeiger um eine Stelle
] : Wenn der Wert des aktuellen Elements Null ist, bewege den Zeiger um eine Stelle
weiter.
Ansonsten, bewege den Zeiger hinter den zugehörigen [-Befehl.
@ -51,7 +51,7 @@ und das Programm hinter dem korrespondierenden ] fortgesetzt).
An dieser Stelle befinden wir uns an Zelle #1, die jetzt den Wert 0 hat, während Zelle #2
den Wert 60 hat. Wir gehen vor zu Zelle #2, inkrementieren 5 Mal, bis zum Wert 65,
und geben dann den Wert der Zelle #2 aus. 65 ist ein 'A' im ASCII Zeichensatz,
und geben dann den Wert der Zelle #2 aus. 65 ist ein 'A' im ASCII-Zeichensatz,
daher wird 'A' am Terminal ausgegeben..
@ -59,11 +59,11 @@ daher wird 'A' am Terminal ausgegeben..
Dieses Programm liest ein Zeichen von der Benutzereingabe und schreibt dessen Wert
in Zelle #1. Danach beginnt eine Schleife. Rücke vor auf Zelle #2, erhöhe den Wert der Zelle #2,
gehe zurück auf Zelle #1, verringere den Wert der Zelle #1. Dies geht solange bis
gehe zurück auf Zelle #1, verringere den Wert der Zelle #1. Dies geht so lange bis
Zelle #1 den Wert 0 und Zelle #2 den alten Wert aus #1 hat. Da wir am Ende der Schleife
bie Zelle #1 sind, gehe vor zu Zelle #2 und gibt denb Wert als ASCII Zeichen aus.
bei Zelle #1 sind, gehe vor zu Zelle #2 und gibt den Wert als ASCII Zeichen aus.
Beachte biite, dass die Leerzeichen nur aus Gründen der Lesbarkeit geschrieben werden.
Beachte bitte, dass die Leerzeichen nur aus Gründen der Lesbarkeit geschrieben werden.
Man könnte genauso schreiben:
,[>+<-]>.
@ -84,6 +84,6 @@ Am Ende steht in Zelle #3 das Ergebnis.
```
Das ist Brainfuck. Nicht so schwierig, oder? Zum Spaß kannst du dein eigenes Brainfuck
Programm schreiben oder du schreibst einen Brainfuck Interpreter in einer anderen
Programm schreiben oder du schreibst einen Brainfuck-Interpreter in einer anderen
Programmiersprache. Der Interpreter lässt sich ziemlich einfach implementieren.
Falls du Masochist bist, kannst du auch versuchen, einen Brainfuck Interpreter in Brainfuck zu implementieren.
Falls du Masochist bist, kannst du auch versuchen, einen Brainfuck-Interpreter in Brainfuck zu implementieren.

View File

@ -278,7 +278,7 @@ string retVal = tempObjectFun();
// - ein String Objekt wird von "tempObjectFun" zurückgegeben
// - ein neuer String wird mit dem zurückgegebenen Objekt als Argument für den Konstruktor erzeugt.
// - das zurückgegebene Objekt wird zerstört
// Das zurückgegbene Objekt wird temporäres Objekt genannt. Temporäre Objekte werden erzeugt
// Das zurückgegebene Objekt wird temporäres Objekt genannt. Temporäre Objekte werden erzeugt
// wann immer eine Funktion ein Objekt zurückgibt. Zerstört werden diese am Ende der Auswertung des Ausdrucks
// (dies schreibt der Standard vor, aber Compiler sind berechtigt dieses Verhalten zu ändern. Siehe "return value optimization"
// für Details). Wie in diesem Code:
@ -530,7 +530,7 @@ public:
Point (double a, double b) :
x(a),
y(b)
{ /* Außschließliche Initialisierung der Werte */ }
{ /* Ausschließliche Initialisierung der Werte */ }
// Überladung des "+" Operator.
Point operator+(const Point& rhs) const;
@ -842,7 +842,7 @@ for (int i = 0; i < my_vector.size(); i++)
}
// Oder die Verwendung von Iteratoren:
vector<string>::iterator it; // Initialisierng des Iterators.
vector<string>::iterator it; // Initialisierung des Iterators.
for (it = my_vector.begin(); it != my_vector.end(); ++it)
{
cout << *it << endl;
@ -913,7 +913,7 @@ for (it=mymap.begin(); it!=mymap.end(); ++it)
it = mymap.find('Z');
cout << it->second;
// Ausabe: 26
// Ausgabe: 26
// Bemerkung: für "hash maps" sollten die "unordered_map´s" verwendet werden. Diese
// sind effizienter und benötigen keine Reihenfolge. "unordered_maps" sind ab
@ -1148,9 +1148,8 @@ compl 4 // Führt bitweises nicht aus.
4 bitor 3 // Führt bitweises oder aus.
4 bitand 3 // Führt bitweises und aus.
4 xor 3 // Führt bitweises xor aus.
```
Weiterführende Literatur:
* Aktuelle Sprachen-Referenz [CPP Reference](http://cppreference.com/w/cpp).

View File

@ -8,7 +8,7 @@ lang: de-de
Ach, C. Immer noch **die** Sprache für modernes High-Performance Computing.
C ist wahrscheinlich die Programmiersprache mit dem niedrigsten Abstraktionsnvieau,
C ist wahrscheinlich die Programmiersprache mit dem niedrigsten Abstraktionsniveau,
welche die meisten Programmierer je brauchen werden.
Die Geschwindigkeit von C ist enorm, allerdings muss man sich stets der
manuellen Speicherverwaltung bewusst sein.
@ -22,7 +22,7 @@ manuellen Speicherverwaltung bewusst sein.
> Standards:
> `-Wall -Wextra -Werror -O2 -std=c99 -pedantic`
>
> Da gewisse Optionen (inbesondere der C-Standard) sehr stark vom Projekt
> Da gewisse Optionen (insbesondere 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.
@ -64,12 +64,12 @@ enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT};
// Funktionssignaturen werden entweder vorher in einer .h-Datei deklariert oder
// am Anfang der .c-Datei.
void function_1();
int funkcion_2(void);
int function_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,
// Auch wenn der Ausdruck `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.
@ -227,7 +227,7 @@ int main (int argc, char** argv) {
// 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.
// Kompilierzeit.
int a = 1;
//size_t ist ein vorzeichenloser Integer Typ mit mindestens 2 Byte um die
@ -283,7 +283,7 @@ int main (int argc, char** argv) {
// 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("%s\n", a_string); // %s formatiert einen String
printf("%d\n", a_string[18]); // => 0
// Hier ist das Byte #19 0 (wie auch Byte #20)
@ -394,7 +394,7 @@ int main (int argc, char** argv) {
// 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", (double) 100); // %f formatiert immer zu einem `double`...
printf("%f\n", (flaot) 100); // ... auch mit einem `float`
printf("%d\n", (char)100.0);
@ -414,7 +414,7 @@ int main (int argc, char** argv) {
int x = 0;
printf("%p\n", (void *)&x); // verwende & um die Adresse der Variable
// zu erhalten
// %p formattiert einen Objektpointer des Typen void*)
// %p formatiert einen Objektpointer des Typen void*)
// => Gibt eine Adresse im Speicher aus
// Pointer starten mit einem * zu Beginn der Deklaration.
@ -437,7 +437,7 @@ int main (int argc, char** argv) {
printf("%d\n", *px); // => 1
printf("%d\n", x); // => 1
// Arrays sind eine gute Möglichekit, einen zusammenhängenden Block von
// Arrays sind eine gute Möglichkeit, 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.)
@ -446,7 +446,7 @@ int main (int argc, char** argv) {
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`
// Deklariere ein Pointer des Typs int und initialisiere 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)
@ -457,7 +457,7 @@ int main (int argc, char** argv) {
// 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)
// Es ist vom Typen "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";
@ -631,7 +631,7 @@ void test_function() {
// 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.
// `private` sind. Privat heißt, dass sie nur in diesem Kontext sichtbar sind.
////////////////////////////////////////////////
@ -707,12 +707,12 @@ void str_reverse_through_pointer(char *str_in) {
// 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.
// aufzurufen.
}
/*
Solange die Signaturen der Funktionen übereinstimmen, kann man sämtliche Funktionen
demselben Pointer zuweisen. Funktionspointer sind auf Grund der Einfacheit und
demselben Pointer zuweisen. Funktionspointer sind auf Grund der Einfachheit und
Leserlichkeit normalerweise wie folgt `typedef`d
*/
typedef void (*my_fnp_type)(char *);
@ -722,7 +722,7 @@ typedef void (*my_fnp_type)(char *);
// Spezialzeichen
// Im folgenden sin die englischen Begriffe jeweils in Klammern geschrieben,
// da diese Begriffe auch im deutschten Sprachgebrauch verwendet werden.
// da diese Begriffe auch im deutschen Sprachgebrauch verwendet werden.
'\a'; // Alarmzeichen (alert (bell) character)
'\n'; // Zeichen für neue Linie (newline character)
'\t'; // Tab (tab character (left justifies text))
@ -804,7 +804,7 @@ befindet wie die C-Quelldatei.
#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
// Es können 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>
@ -832,7 +832,7 @@ typedef struct 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
// Funktionsprototypen können 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);
@ -844,6 +844,7 @@ Node create_linked_list(int *value, int length);
#endif /* Ende der Präprozessordirektive */
```
## Weiterführende Literatur
Das Beste wird es sein, wenn man sich ein Exemplar des Buches

View File

@ -0,0 +1,422 @@
---
language: clojure
filename: learnclojure-de.clj
contributors:
- ["Adam Bard", "http://adambard.com/"]
translators:
- ["Dennis Keller", "https://github.com/denniskeller"]
lang: de-de
---
Clojure ist ein Lispdialekt, der für die Java Virtual Maschine entwickelt worden ist. Sie hat eine stärkere Betonung auf reine [funktionale Programmierung](https://en.wikipedia.org/wiki/Functional_programming) als Common Lisp. Jedoch besitzt sie je nach Bedarf mehrere [STM](https://en.wikipedia.org/wiki/Software_transactional_memory) Werkzeuge zur Handhabung von Zustand.
Diese Verknüpfung erlaubt es, parallele Verarbeitung sehr einfach und häufig automatisch zu verarbeiten.
(Du brauchst die Clojure Version 1.2 oder neuer)
```clojure
; Kommentare starten mit einem Semikolon.
; Clojure wird in "Forms" geschrieben, was nur Listen von Dingen
; in Klammern sind, getrennt durch Leerzeichen.
;
; Der Clojure Leser nimmt an, dass das Erste, was aufgerufen wird
; eine Funktion oder ein Makro ist, der Rest sind Argumente.
; Der erste Aufruf in einer Datei sollte ns sein, um den Namespace zu setzen.
(ns learnclojure)
; Weitere einfache Beispiele:
; str erstellt einen String aus allen Argumenten
(str "Hallo" " " "Welt") ; => "Hallo Welt"
; Mathe ist einfach
(+ 1 1) ; => 2
(- 2 1) ; => 1
(* 1 2) ; => 2
(/ 2 1) ; => 2
; Gleichheit ist =
(= 1 1) ; => true
(= 2 1) ; => false
; Du brauchst auch not für Logik
(not true) ; => false
; Verschachtelte Forms funktionieren, wie erwartet
(+ 1 (- 3 2)) ; = 1 + (3 - 2) => 2
; Typen
;;;;;;;;;;;;;
; Clojure verwendet Javas Objekt Typen für Booleans, Strings und Zahlen.
; Verwende `class` um sie zu inspizieren.
(class 1) ; Integer-Literale sind standardmäßig java.lang.Long
(class 1.); Float-Literale sind java.lang.Double
(class ""); Strings sind immer in doppelten Anführungszeichen notiert und sind java.lang.String
(class false) ; Booleans sind java.lang.Boolean
(class nil); Der "null" Wert heißt nil
; Wenn du ein literale Liste aus Daten erzeugen willst, verwendest du ' um
; zu verhindern dass es evaluiert wird
'(+ 1 2) ; => (+ 1 2)
; (Kurzform für (quote (+ 1 2)))
; Du kannst eine zitierte Liste evaluieren
(eval '(+ 1 2)) ; => 3
; Kollektionen & Sequenzen
;;;;;;;;;;;;;;;;;;;
; Listen sind Linked-Lists Datenstrukturen, während Vektoren arraybasierend sind.
; Vektoren und Listen sind auch Java Klassen!
(class [1 2 3]); => clojure.lang.PersistentVector
(class '(1 2 3)); => clojure.lang.PersistentList
; Eine Liste würde nur als (1 2 3) geschrieben, aber wir müssen es zitieren
; damit der Leser aufhört zu denken, es sei eine Funktion.
; Außerdem ist (list 1 2 3) dasselbe, wie '(1 2 3)
; "Kollektionen" sind nur Gruppen von Daten
; Listen und Vektoren sind Kollektionen:
(coll? '(1 2 3)) ; => true
(coll? [1 2 3]) ; => true
; "Sequenzen" (seqs) sind abstrakte Beschreibungen von Listen von Daten.
; Nur Listen sind seqs.
(seq? '(1 2 3)) ; => true
(seq? [1 2 3]) ; => false
; Ein seq muss nur einen Eintrittspunkt bereitstellen, wenn auf ihm zugegriffen wird.
; Das heißt, dass seqs faul sein können -- Mit ihnen kann man unendliche Serien beschreiben.
(range 4) ; => (0 1 2 3)
(range) ; => (0 1 2 3 4 ...) (eine unendliche Serie)
(take 4 (range)) ; (0 1 2 3)
; Verwende cons um ein Item zum Anfang einer Liste oder eines Vektors hinzuzufügen.
(cons 4 [1 2 3]) ; => (4 1 2 3)
(cons 4 '(1 2 3)) ; => (4 1 2 3)
; Conj fügt ein Item auf die effizienteste Weise zu einer Kollektion hinzu.
; Für Listen fügt er sie an den Anfang hinzu. Für Vektoren fügt er sie an das Ende hinzu.
(conj [1 2 3] 4) ; => [1 2 3 4]
(conj '(1 2 3) 4) ; => (4 1 2 3)
; Verwende concat um Listen und Vektoren miteinander zu verbinden
(concat [1 2] '(3 4)) ; => (1 2 3 4)
; Verwende filter, map um mit Kollektionen zu interagieren
(map inc [1 2 3]) ; => (2 3 4)
(filter even? [1 2 3]) ; => (2)
; Verwende reduce um sie zu reduzieren
(reduce + [1 2 3 4])
; = (+ (+ (+ 1 2) 3) 4)
; => 10
; Reduce kann auch einen Initialwert als Argument verwenden
(reduce conj [] '(3 2 1))
; = (conj (conj (conj [] 3) 2) 1)
; => [3 2 1]
; Funktionen
;;;;;;;;;;;;;;;;;;;;;
; Verwende fn um neue Funktionen zu erstellen. Eine Funktion gibt immer ihr
; letztes Statement zurück.
(fn [] "Hallo Welt") ; => fn
; (Du brauchst exta Klammern um sie aufzurufen)
((fn [] "Hallo Welt")) ; => "Hallo Welt"
; Du kannst eine Variable mit def erstellen
(def x 1)
x ; => 1
; Weise eine Funktion einer Variable zu
(def hello-world (fn [] "Hallo Welt"))
(hello-world) ; => "Hallo Welt"
; Du kannst den Prozess verkürzen indem du defn verwendest
(defn hello-world [] "Hallo Welt")
; [] ist die Liste der Argumente für die Funktion
; The [] is the list of arguments for the function.
(defn hello [name]
(str "Hallo " name))
(hello "Steve") ; => "Hallo Steve"
; Du kannst diese Kurzschreibweise verwenden um Funktionen zu erstellen:
(def hello2 #(str "Hallo " %1))
(hello2 "Julie") ; => "Hallo Julie"
; Du kannst auch multi-variadische Funktionen haben
(defn hello3
([] "Hallo Welt")
([name] (str "Hallo " name)))
(hello3 "Jake") ; => "Hallo Jake"
(hello3) ; => "Hallo Welt"
; Funktionen können auch extra Argumente in einem seq für dich speichern
(defn count-args [& args]
(str "Du hast " (count args) " Argumente übergeben: " args))
(count-args 1 2 3) ; => "Du hast 3 Argumente übergeben: (1 2 3)"
; Du kannst reguläre und gepackte Argumente mischen
(defn hello-count [name & args]
(str "Hallo " name ", Du hast " (count args) " extra Argumente übergeben"))
(hello-count "Finn" 1 2 3)
; => "Hallo Finn, Du hast 3 extra Argumente übergeben"
; Maps
;;;;;;;;;;
; Hash maps und Array maps teilen sich ein Interface. Hash maps haben eine schnellere Zugriffszeit,
; aber behalten keine Schlüsselreihenfolge.
(class {:a 1 :b 2 :c 3}) ; => clojure.lang.PersistentArrayMap
(class (hash-map :a 1 :b 2 :c 3)) ; => clojure.lang.PersistentHashMap
; Arraymaps werden durch die meisten Operationen automatisch zu Hashmaps,
; sobald sie groß genug werden. Das heißt du musst dich nicht darum sorgen.
; Maps können einen beliebigen Hash-Typ als Schlüssel verwenden, in der Regel
; sind jedoch Keywords am besten. Keywords sind wie Strings, jedoch besitzen sie
; Performance-Vorteile
(class :a) ; => clojure.lang.Keyword
(def stringmap {"a" 1, "b" 2, "c" 3})
stringmap ; => {"a" 1, "b" 2, "c" 3}
(def keymap {:a 1, :b 2, :c 3})
keymap ; => {:a 1, :c 3, :b 2}
; Übrigens werden Kommas als Leerzeichen behandelt und machen nichts.
; Rufe einen Wert von einer Map ab, indem du sie als Funktion aufrufst
(stringmap "a") ; => 1
(keymap :a) ; => 1
; Keywords können auch verwendet werden um ihren Wert aus der Map zu bekommen!
(:b keymap) ; => 2
; Versuche es nicht mit Strings.
;("a" stringmap)
; => Exception: java.lang.String cannot be cast to clojure.lang.IFn
; Das Abrufen eines nicht vorhandenen Keys gibt nil zurück
(stringmap "d") ; => nil
; Verwende assoc um einen neuen Key zu einer Hash-map hinzuzufügen
(def newkeymap (assoc keymap :d 4))
newkeymap ; => {:a 1, :b 2, :c 3, :d 4}
; Aber denk daran, Clojure Typen sind unveränderlich!
keymap ; => {:a 1, :b 2, :c 3}
; Verwende dissoc um Keys zu entfernen
(dissoc keymap :a :b) ; => {:c 3}
; Sets
;;;;;;
(class #{1 2 3}) ; => clojure.lang.PersistentHashSet
(set [1 2 3 1 2 3 3 2 1 3 2 1]) ; => #{1 2 3}
; Füge ein Element mit conj hinzu
(conj #{1 2 3} 4) ; => #{1 2 3 4}
; Entferne ein Element mit disj
(disj #{1 2 3} 1) ; => #{2 3}
; Teste auf Existenz, indem du das Set als Funktion verwendest:
(#{1 2 3} 1) ; => 1
(#{1 2 3} 4) ; => nil
; Es gibt mehr Funktionen in dem clojure.sets Namespace.
; Nützliche Forms
;;;;;;;;;;;;;;;;;
; Logische Konstrukte in Clojure sind nur Makros und sie sehen, wie alles
; andere aus
(if false "a" "b") ; => "b"
(if false "a") ; => nil
; Verwende let um temporäre Bindungen aufzubauen
(let [a 1 b 2]
(> a b)) ; => false
; Gruppiere Statements mit do zusammen
; Group statements together with do
(do
(print "Hallo")
"Welt") ; => "Welt" (prints "Hallo")
; Funktionen haben ein implizites do
(defn print-and-say-hello [name]
(print "Sage Hallo zu " name)
(str "Hallo " name))
(print-and-say-hello "Jeff") ;=> "Hallo Jeff" (prints "Sage Hallo zu Jeff")
; let macht das auch
(let [name "Urkel"]
(print "Sage Hallo zu " name)
(str "Hallo " name)) ; => "Hallo Urkel" (prints "Sage Hallo zu Urkel")
; Verwende die Threading Makros (-> and ->>) um Transformationen von
; Daten deutlicher auszudrücken.
; Das "Thread-zuerst" Makro (->) fügt in jede Form das Ergebnis des
; Vorherigen als erstes Argument (zweites Element) ein.
(->
{: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)
; Dieser Ausdruck kann auch als so geschrieben werden:
; (dissoc (assoc {:a 1 :b 2} :c 3) :b)
; and evaluates to {:a 1 :c 3}
; Der Doppelpfeil macht das Selbe, aber er fügt das Ergebnis von jeder
; Zeile an das Ende der Form, Das ist vor allem für Operationen auf
; Kollektionen nützlich:
(->>
(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]
; Wenn du in einer Situation bist, in der du mehr Freiheit willst,
; wohin du das Ergebnis vorheriger Datentransformationen in einem Ausdruck
; platzieren möchtest, kannst du das as-> Macro verwenden. Mit diesem Macro
; kannst du einen speziellen Namen auf die Ausgabe einer Transformationen geben.
; Du kannst es als Platzhalter in verketteten Ausdrücken verwenden:
(as-> [1 2 3] input
(map inc input);=> Du kannst die letzte Ausgabe der Transformation in der letzten Position verwenden
(nth input 2) ;=> und auch in der zweiten Position, im selben Ausdruck verwenden
(conj [4 5 6] input [8 9 10])) ;=> oder auch in der Mitte!
; Module
;;;;;;;;;;;;;;;
; Verwende "use" um alle Funktionen aus einem Modul zu bekommen
(use 'clojure.set)
; Nun können wir set Operationen verwenden
(intersection #{1 2 3} #{2 3 4}) ; => #{2 3}
(difference #{1 2 3} #{2 3 4}) ; => #{1}
; Du kannst auch auswählen nur ein Subset von Funktionen zu importieren
(use '[clojure.set :only [intersection]])
; Verwende require um ein Modul zu importieren
(require 'clojure.string)
; Verwende / um eine Funktion aus einem Modul aufzurufen
; Hier verwenden wir das Modul clojure.string und die Funktion blank?
(clojure.string/blank? "") ; => true
; Du kannst auch einem Modul einen kürzeren Namen beim Import geben
(require '[clojure.string :as str])
(str/replace "Das ist ein Test." #"[a-o]" str/upper-case) ; => "DAs IsT EIN TEsT."
; (#"" bezeichnet einen regulären literalen Ausdruck)
; Du kannst require aus einem Namespace verwenden (auch use ist möglich, aber nicht zu empfehlen)
; indem du :require verwendest.
; Du brauchst keine Zitierzeichen für deine Module verwenden, wenn du
; es auf diese Weise machst.
(ns test
(:require
[clojure.string :as str]
[clojure.set :as set]))
; Java
;;;;;;;;;;;;;;;;;
; Java hat eine riesige und nützliche Standardbibliothek,
; du möchtest lernen wie man sie verwendet.
; Verwende import um ein Java modul zu laden.
(import java.util.Date)
; Du kannst auch von einem ns importieren.
(ns test
(:import java.util.Date
java.util.Calendar))
; Verwende den Klassennamen mit einem "." am Ende, um eine neue Instanz zu erstellen
(Date.) ; <a date object>
; Verwende . um Methoden aufzurufen oder verwende die ".method" Abkürzung
(. (Date.) getTime) ; <a timestamp>
(.getTime (Date.)) ; Genau das Selbe
; Verwende / um statische Methoden aufzurufen
(System/currentTimeMillis) ; <a timestamp> (system ist immer da)
; Verwende doto um mit veränderliche Klassen besser umzugehen
(import java.util.Calendar)
(doto (Calendar/getInstance)
(.set 2000 1 1 0 0 0)
.getTime) ; => A Date. set to 2000-01-01 00:00:00
; STM
;;;;;;;;;;;;;;;;;
; Software Transactional Memory ist der Mechanismus, den Clojure verwendet
; um mit persistenten Zuständen umzugehen. Es gibt ein Paar Konstrukte in
; Clojure die es verwenden.
; Ein Atom ist das Einfachste. Gebe es einen Initialwert
(def my-atom (atom {}))
; Update ein Atom mit swap!.
; swap! nimmt eine Funktion und ruft sie mit dem aktuellen Zustand des
; Atoms auf und alle nachfolgenden Argumente als das Zweite
(swap! my-atom assoc :a 1) ; Setzt my-atom zu dem Ergebnis von (assoc {} :a 1)
(swap! my-atom assoc :b 2) ; Setzt my-atom zu dem Ergebnis von (assoc {:a 1} :b 2)
; Verwende '@' um das Atom zu dereferenzieren und den Wert zu bekommen
my-atom ;=> Atom<#...> (Gibt das Atom Objekt zurück
@my-atom ; => {:a 1 :b 2}
; Hier ist ein einfacher Zähler mit einem Atom
(def counter (atom 0))
(defn inc-counter []
(swap! counter inc))
(inc-counter)
(inc-counter)
(inc-counter)
(inc-counter)
(inc-counter)
@counter ; => 5
; Andere STM Konstrukte sind refs und agents.
; Refs: http://clojure.org/refs
; Agents: http://clojure.org/agents
```
### Weiterführende Literatur
Das ist alles andere als erschöpfend, aber hoffentlich ist es genug, um dich auf die Beine zu stellen.
Clojure.org hat eine Menge von Artikeln:
[http://clojure.org/](http://clojure.org/)
Clojuredocs.org hat eine Dokumentation mit Beispielen für die meisten Kernfunktionen
[http://clojuredocs.org/quickref/Clojure%20Core](http://clojuredocs.org/quickref/Clojure%20Core)
4Clojure ist eine gute Möglichkeit um deine clojure/FP zu verbessern:
[http://www.4clojure.com/](http://www.4clojure.com/)
Clojure-doc.org (ja, wirklich) hat eine Reihe von Artikeln zum Starten:
[http://clojure-doc.org/](http://clojure-doc.org/)

View File

@ -11,11 +11,11 @@ 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
Macros geben dir eine leistungsstarke 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.
ein Macro schreibst, obwohl eine Funktion genauso gut 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.
@ -59,7 +59,7 @@ Wenn du mit Clojure vertraut sein möchtest, stelle sicher, dass du alles in [Cl
;; 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: `
;; Um dies zu umgehen, bietet Clojure eine Art und Weise Macros zu zitieren: `
;; In ` kannst du ~ verwenden um in den äußeren Bereich zu kommen.
(defmacro inc2-quoted [arg]
`(+ 2 ~arg))
@ -156,6 +156,6 @@ Wenn du mit Clojure vertraut sein möchtest, stelle sicher, dass du alles in [Cl
[Macros schreiben](http://www.braveclojure.com/writing-macros/)
[Offiziele Docs](http://clojure.org/macros)
[Offizielle Docs](http://clojure.org/macros)
[Wann verwendet man Macros?](https://lispcast.com/when-to-use-a-macro/)

View File

@ -10,7 +10,6 @@ lang: de-de
---
```crystal
# Das ist ein Kommentar
# Alles ist ein Objekt
@ -83,7 +82,7 @@ true.class # => Bool
"s".class # => String
# Strings sind unveränderlich
s = 'hello, " # => "hello, " : String
s = "hello, " # => "hello, " : String
s.object_id # => 1234667712 : UInt64
s += "Crystal" # => "hello, Crystal" : String
s.object_id # => 142528472 : UInt64
@ -171,7 +170,7 @@ set << 3
{1 => 2, 3 => 4}.class # => Hash(Int32, Int32)
{1 => 2, 'a' => 3}.class # => Hash (Int32 | Char, Int32)
# Leere Hashes sollten einen Typen spezifieren
# Leere Hashes sollten einen Typen spezifizieren
{} # Syntaxfehler
{} of Int32 => Int32 # {}
Hash(Int32, Int32).new # {}
@ -446,7 +445,7 @@ class Human
end
# Eine Klasse instanzieren
# Eine Klasse instanziieren
jim = Human.new("Jim Halpert")
dwight = Human.new("Dwight K. Schrute")

File diff suppressed because it is too large Load Diff

View File

@ -139,12 +139,11 @@ selector {
/* Schriften */
font-family: Arial;
font-family: "Courier New"; /* wenn der Name ein Leerzeichen beinhält, kommt er in
font-family: "Courier New"; /* wenn der Name ein Leerzeichen enthält, kommt er in
Anführungszeichen */
font-family: "Courier New", Trebuchet, Arial; /* wird die erste Schriftart
nicht gefunden, wird die zweite benutzt, usw. */
}
```
## Benutzung
@ -164,7 +163,6 @@ empfohlen ist -->
<!-- Oder direkt auf einem Element (sollte aber vermieden werden) -->
<div style='property:value;'>
</div>
```
## Spezifität
@ -190,7 +188,6 @@ p {}
/*E*/
p { property: wert !important; }
```
und das folgende Markup:

View File

@ -1,6 +1,6 @@
---
language: D
filename: learnd-de.d
language: D
filename: learnd-de.d
contributors:
- ["Nick Papanastasiou", "www.nickpapanastasiou.github.io"]
translators:
@ -8,13 +8,13 @@ translators:
lang: de-de
---
```c
```d
// Es war klar, dass das kommt...
module hello;
import std.stdio;
// argumente sind optional
// Argumente sind optional
void main(string[] args) {
writeln("Hello, World!");
}
@ -22,13 +22,13 @@ void main(string[] args) {
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
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
```d
import std.stdio;
void main() {
@ -39,8 +39,8 @@ void main() {
}
auto n = 1; // auto um den Typ vom Compiler bestimmen zu lassen
// Zahlenliterale können _ verwenden für lesbarkeit
// Zahlenliterale können _ verwenden für Lesbarkeit
while(n < 10_000) {
n += n;
}
@ -69,11 +69,11 @@ 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
Structs und unions werden as-value (kopiert) an Methoden übergeben wogegen
Klassen als Referenz übergeben werden. Templates können verwendet werden um
alle Typen zu parameterisieren.
alle Typen zu parametrisieren.
```c
```d
// Hier, T ist ein Type-Parameter, Er funktioniert wie Generics in C#/Java/C++
struct LinkedList(T) {
T data = null;
@ -82,7 +82,7 @@ struct LinkedList(T) {
class BinTree(T) {
T data = null;
// Wenn es nur einen T Parameter gibt, können die Klammern um ihn weggelassen werden
BinTree!T left;
BinTree!T right;
@ -121,22 +121,21 @@ void swap(T)(ref T a, ref T b) {
b = temp;
}
// Templates können ebenso Werte parameterisieren.
// Templates können ebenso Werte parametrisieren.
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
```
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
im Stil von `structure.x = 7` was gleichgültig wäre zu `structure.setX(7)`
```c
// Diese Klasse ist parameterisiert mit T, U
```d
// Diese Klasse ist parametrisiert mit T, U
class MyClass(T, U) {
T _data;
@ -148,13 +147,13 @@ class MyClass(T, U) {
class MyClass(T, U) {
T _data;
U _other;
// Konstruktoren heißen immer `this`
this(T t, U u) {
data = t;
other = u;
}
// getters
@property T data() {
return _data;
@ -164,8 +163,8 @@ class MyClass(T, U) {
return _other;
}
// setters
// @property kann genauso gut am ende der Methodensignatur stehen
// setters
// @property kann genauso gut am ende der Methodensignatur stehen
void data(T t) @property {
_data = t;
}
@ -181,13 +180,13 @@ void main() {
mc.data = 7;
mc.other = "seven";
writeln(mc.data);
writeln(mc.other);
}
```
Mit properties können wir sehr viel logik hinter unseren gettern
Mit properties können wir sehr viel Logik hinter unseren gettern
und settern hinter einer schönen Syntax verstecken
Andere Objektorientierte features sind beispielsweise
@ -202,17 +201,17 @@ 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!
```c
```d
import std.algorithm : map, filter, reduce;
import std.range : iota; // builds an end-exclusive range
void main() {
// 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
// Lambdas bieten sich hier aber an.
// Lambdas bieten sich hier aber an.
auto num = iota(1, 101).filter!(x => x % 2 == 0)
.map!(y => y ^^ 2)
.reduce!((a, b) => a + b);
@ -225,21 +224,21 @@ 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
als freie Funktion aufrufen. Walters artikel dazu findet ihr
[hier.](http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394)
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
Methode auf A anwenden.
Parrallel Computing ist eine Tolle sache, findest du nicht auch?
Parallel Computing ist eine tolle Sache, findest du nicht auch?
```c
```d
import std.stdio;
import std.parallelism : parallel;
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
@ -248,5 +247,4 @@ void main() {
ref = sqrt(i + 1.0);
}
}
```

View File

@ -288,7 +288,7 @@ let false : Bool = Prelude.Bool.not True
-- 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.
-- Environment-Variablen können auch importiert werden.
let presentWorkingDirectory = env:PWD as Text
-- Mit `?` kann man eine “Fallback-Expression” angeben, für den Fall

View File

@ -40,13 +40,13 @@ Dies wird als Dynamische Programmierung bezeichnet.
Das Problem mit der längsten ansteigenden Subsequenz besteht darin,
die längste ansteigende Subsequenz einer gegebenen Sequenz zu finden.
Gegeben die Sequenz `S= {a1, a2, a3, a3, a4,..............., an-1, an }`,
müssen wir die größte Teilmenge finden, so daß für alle `j` und `i`, `j<i`
müssen wir die größte Teilmenge finden, sodass für alle `j` und `i`, `j<i`
in der Teilmenge `aj<ai` gilt.
Zuerst müssen wir bei jedem Index i den Wert der längsten Subsequenzen (LSi)
finden, wobei das letzte Element der Sequenz ai ist. Dann wäre die größte LSi
die längste Subsequenz in der gegebenen Sequenz. Am Anfang wird der LSi mit
eins belegt, da ai ein Element der Sequenz (Letztes Element) ist.
Dann ist für alle `j` mit `j<i` und `aj<ai`, so dass wir den größten LSj finden
Dann ist für alle `j` mit `j<i` und `aj<ai`, sodass wir den größten LSj finden
und zum LSi hinzufügen. Der Algorithmus hat eine Laufzeit von *O(n2)*.
Pseudocode zur Bestimmung der Länge der am längsten ansteigenden Subsequenz:
@ -56,6 +56,7 @@ wie `largest_sequences_so_far` und dessen Index würde eine Menge Zeit sparen.
Ein ähnliches Konzept könnte auch bei der Suche nach dem längsten Weg
in gerichteten azyklischen Graphen angewandt werden.
```python
for i=0 to n-1
LS[i]=1

View File

@ -82,7 +82,7 @@ false
;;; markierte Elemente ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
; EDN kann erweitert werden, indem Elemente mit # Symbolen makiert werden.
; EDN kann erweitert werden, indem Elemente mit # Symbolen markiert werden.
#MyYelpClone/MenuItem {:name "eggs-benedict" :rating 10}
@ -102,11 +102,10 @@ false
(edn/read-string {:readers {'MyYelpClone/MenuItem map->menu-item}}
"#MyYelpClone/MenuItem {:name \"eggs-benedict\" :rating 10}")
; -> #user.MenuItem{:name "eggs-benedict", :rating 10}
```
# Referenzen
- [EDN spec](https://github.com/edn-format/edn)
- [Implementationen](https://github.com/edn-format/edn/wiki/Implementations)
- [makierte Elemente](http://www.compoundtheory.com/clojure-edn-walkthrough/)
- [markierte Elemente](http://www.compoundtheory.com/clojure-edn-walkthrough/)

View File

@ -1,423 +1,421 @@
---
language: elixir
contributors:
- ["Joao Marques", "http://github.com/mrshankly"]
translators:
- ["Gregor Große-Bölting", "http://www.ideen-und-soehne.de"]
filename: learnelixir-de.ex
lang: de-de
---
Elixir ist eine moderne, funktionale Sprache für die Erlang VM. Sie ist voll
kompatibel mit Erlang, verfügt aber über eine freundlichere Syntax und bringt
viele Features mit.
```ruby
# Einzeilige Kommentare werden mit der Raute gesetzt.
# Es gibt keine mehrzeiligen Kommentare;
# es ist aber problemlos möglich mehrere einzeilige Kommentare hintereinander
# zu setzen (so wie hier).
# Mit 'iex' ruft man die Elixir-Shell auf.
# Zum kompilieren von Modulen dient der Befehl 'elixirc'.
# Beide Befehle sollten als Umgebungsvariable gesetzt sein, wenn Elixir korrekt
# installiert wurde.
## ---------------------------
## -- Basistypen
## ---------------------------
# Es gibt Nummern:
3 # Integer
0x1F # Integer
3.0 # Float
# Für bessere Lesbarkeit des Codes können Unterstriche "_" als Trennzeichen verwendet werden
1_000_000 == 1000000 # Integer
1_000.567 == 1000.567 # Float
# Atome, das sind Literale, sind Konstanten mit Namen. Sie starten mit einem
# ':'.
:hello # Atom
# Außerdem gibt es Tupel, deren Werte im Arbeitsspeicher vorgehalten werden.
{1,2,3} # Tupel
# Die Werte innerhalb eines Tupels können mit der 'elem'-Funktion ausgelesen
# werden:
elem({1, 2, 3}, 0) # => 1
# Listen sind als verkettete Listen implementiert.
[1, 2, 3] # list
# Auf Kopf und Rest einer Liste kann wie folgt zugegriffen werden:
[ kopf | rest ] = [1,2,3]
kopf # => 1
rest # => [2, 3]
# In Elixir, wie auch in Erlang, kennzeichnet '=' ein 'pattern matching'
# (Musterabgleich) und keine Zuweisung.
# Das heißt, dass die linke Seite auf die rechte Seite 'abgeglichen' wird.
# Auf diese Weise kann im Beispiel oben auf Kopf und Rest der Liste zugegriffen
# werden.
# Ein Musterabgleich wird einen Fehler werfen, wenn die beiden Seiten nicht
# zusammenpassen.
# Im folgenden Beispiel haben die Tupel eine unterschiedliche Anzahl an
# Elementen:
{a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
# Es gibt außerdem 'binaries',
<<1,2,3>> # binary.
# Strings und 'char lists'
"hello" # String
'hello' # Char-Liste
# ... und mehrzeilige Strings
"""
Ich bin ein
mehrzeiliger String.
"""
#=> "Ich bin ein\nmehrzeiliger String.\n"
# Alles Strings werden in UTF-8 enkodiert:
"héllò" #=> "héllò"
# Eigentlich sind Strings in Wahrheit nur binaries und 'char lists' einfach
# Listen.
<<?a, ?b, ?c>> #=> "abc"
[?a, ?b, ?c] #=> 'abc'
# In Elixir gibt `?a` den ASCII-Integer für den Buchstaben zurück.
?a #=> 97
# Um Listen zu verbinden gibt es den Operator '++', für binaries nutzt man '<>'
[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"
## ---------------------------
## -- Operatoren
## ---------------------------
# Einfache Arithmetik
1 + 1 #=> 2
10 - 5 #=> 5
5 * 2 #=> 10
10 / 2 #=> 5.0
# In Elixir gibt der Operator '/' immer einen Float-Wert zurück.
# Für Division mit ganzzahligen Ergebnis gibt es 'div'
div(10, 2) #=> 5
# Um den Rest der ganzzahligen Division zu erhalten gibt es 'rem'
rem(10, 3) #=> 1
# Natürlich gibt es auch Operatoren für Booleans: 'or', 'and' und 'not'. Diese
# Operatoren erwarten einen Boolean als erstes Argument.
true and true #=> true
false or true #=> true
# 1 and true #=> ** (ArgumentError) argument error
# Elixir bietet auch '||', '&&' und '!', die Argumente jedweden Typs
# akzeptieren. Alle Werte außer 'false' und 'nil' werden zu wahr evaluiert.
1 || true #=> 1
false && 1 #=> false
nil && 20 #=> nil
!true #=> false
# Für Vergleiche gibt es die Operatoren `==`, `!=`, `===`, `!==`, `<=`, `>=`,
# `<` und `>`
1 == 1 #=> true
1 != 1 #=> false
1 < 2 #=> true
# '===' und '!==' sind strikter beim Vergleich von Integern und Floats:
1 == 1.0 #=> true
1 === 1.0 #=> false
# Es ist außerdem möglich zwei verschiedene Datentypen zu vergleichen:
1 < :hello #=> true
# Die gesamte Ordnung über die Datentypen ist wie folgt definiert:
# number < atom < reference < functions < port < pid < tuple < list < bitstring
# Um Joe Armstrong zu zitieren: "The actual order is not important, but that a
# total ordering is well defined is important."
## ---------------------------
## -- Kontrollstrukturen
## ---------------------------
# Es gibt die `if`-Verzweigung
if false do
"Dies wird nie jemand sehen..."
else
"...aber dies!"
end
# ...und ebenso `unless`
unless true do
"Dies wird nie jemand sehen..."
else
"...aber dies!"
end
# Du erinnerst dich an 'pattern matching'? Viele Kontrollstrukturen in Elixir
# arbeiten damit.
# 'case' erlaubt es uns Werte mit vielerlei Mustern zu vergleichen.
case {:one, :two} do
{:four, :five} ->
"Das wird nicht passen"
{:one, x} ->
"Das schon und außerdem wird es ':two' dem Wert 'x' zuweisen."
_ ->
"Dieser Fall greift immer."
end
# Es ist eine übliche Praxis '_' einen Wert zuzuweisen, sofern dieser Wert
# nicht weiter verwendet wird.
# Wenn wir uns zum Beispiel nur für den Kopf einer Liste interessieren:
[kopf | _] = [1,2,3]
kopf #=> 1
# Für bessere Lesbarkeit können wir auch das Folgende machen:
[kopf | _rest] = [:a, :b, :c]
kopf #=> :a
# Mit 'cond' können diverse Bedingungen zur selben Zeit überprüft werden. Man
# benutzt 'cond' statt viele if-Verzweigungen zu verschachteln.
cond do
1 + 1 == 3 ->
"Ich werde nie aufgerufen."
2 * 5 == 12 ->
"Ich auch nicht."
1 + 2 == 3 ->
"Aber ich!"
end
# Es ist üblich eine letzte Bedingung einzufügen, die immer zu wahr evaluiert.
cond do
1 + 1 == 3 ->
"Ich werde nie aufgerufen."
2 * 5 == 12 ->
"Ich auch nicht."
true ->
"Aber ich! (dies ist im Grunde ein 'else')"
end
# 'try/catch' wird verwendet um Werte zu fangen, die zuvor 'geworfen' wurden.
# Das Konstrukt unterstützt außerdem eine 'after'-Klausel die aufgerufen wird,
# egal ob zuvor ein Wert gefangen wurde.
try do
throw(:hello)
catch
nachricht -> "#{nachricht} gefangen."
after
IO.puts("Ich bin die 'after'-Klausel.")
end
#=> Ich bin die 'after'-Klausel.
# ":hello gefangen"
## ---------------------------
## -- Module und Funktionen
## ---------------------------
# Anonyme Funktionen (man beachte den Punkt)
square = fn(x) -> x * x end
square.(5) #=> 25
# Anonyme Funktionen unterstützen auch 'pattern' und 'guards'. Guards erlauben
# es die Mustererkennung zu justieren und werden mit dem Schlüsselwort 'when'
# eingeführt:
f = fn
x, y when x > 0 -> x + y
x, y -> x * y
end
f.(1, 3) #=> 4
f.(-1, 3) #=> -3
# Elixir bietet zahlreiche eingebaute Funktionen. Diese sind im gleichen
# Geltungsbereich ('scope') verfügbar.
is_number(10) #=> true
is_list("hello") #=> false
elem({1,2,3}, 0) #=> 1
# Mehrere Funktionen können in einem Modul gruppiert werden. Innerhalb eines
# Moduls ist es möglich mit dem Schlüsselwort 'def' eine Funktion zu
# definieren.
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
# Um unser einfaches Mathe-Modul zu kompilieren muss es unter 'math.ex'
# gesichert werden. Anschließend kann es mit 'elixirc' im Terminal aufgerufen
# werden: elixirc math.ex
# Innerhalb eines Moduls definieren wir private Funktionen mit 'defp'. Eine
# Funktion, die mit 'def' erstellt wurde, kann von anderen Modulen aufgerufen
# werden; eine private Funktion kann nur lokal angesprochen werden.
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)
# Auch Funktionsdeklarationen unterstützen 'guards' und Mustererkennung:
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
# Wegen der Unveränderlichkeit von Variablen ist Rekursion ein wichtiger
# Bestandteil von Elixir.
defmodule Recursion do
def sum_list([head | tail], acc) do
sum_list(tail, acc + head)
end
def sum_list([], acc) do
acc
end
end
Recursion.sum_list([1,2,3], 0) #=> 6
# Elixir-Module unterstützen Attribute. Es gibt eingebaute Attribute, ebenso
# ist es möglich eigene Attribute hinzuzufügen.
defmodule MyMod do
@moduledoc """
Dies ist ein eingebautes Attribut in einem Beispiel-Modul
"""
@my_data 100 # Dies ist ein selbst-definiertes Attribut.
IO.inspect(@my_data) #=> 100
end
## ---------------------------
## -- 'Records' und Ausnahmebehandlung
## ---------------------------
# 'Records' sind im Grunde Strukturen, die es erlauben einem Wert einen eigenen
# Namen zuzuweisen.
defrecord Person, name: nil, age: 0, height: 0
joe_info = Person.new(name: "Joe", age: 30, height: 180)
#=> Person[name: "Joe", age: 30, height: 180]
# Zugriff auf den Wert von 'name'
joe_info.name #=> "Joe"
# Den Wert von 'age' überschreiben
joe_info = joe_info.age(31) #=> Person[name: "Joe", age: 31, height: 180]
# Der 'try'-Block wird zusammen mit dem 'rescue'-Schlüsselwort dazu verwendet,
# um Ausnahmen beziehungsweise Fehler zu behandeln.
try do
raise "Irgendein Fehler."
rescue
RuntimeError -> "Laufzeit-Fehler gefangen."
_error -> "Und dies fängt jeden Fehler."
end
# Alle Ausnahmen haben das Attribut 'message'
try do
raise "ein Fehler"
rescue
x in [RuntimeError] ->
x.message
end
## ---------------------------
## -- Nebenläufigkeit
## ---------------------------
# Elixir beruht auf dem Aktoren-Model zur Behandlung der Nebenläufigkeit. Alles
# was man braucht um in Elixir nebenläufige Programme zu schreiben sind drei
# Primitive: Prozesse erzeugen, Nachrichten senden und Nachrichten empfangen.
# Um einen neuen Prozess zu erzeugen nutzen wir die 'spawn'-Funktion, die
# wiederum eine Funktion als Argument entgegen nimmt.
f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
spawn(f) #=> #PID<0.40.0>
# 'spawn' gibt eine pid (einen Identifikator des Prozesses) zurück. Diese kann
# nun verwendet werden, um Nachrichten an den Prozess zu senden. Um
# zu senden nutzen wir den '<-' Operator. Damit das alles Sinn macht müssen wir
# in der Lage sein Nachrichten zu empfangen. Dies wird mit dem
# 'receive'-Mechanismus sichergestellt:
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
# Kompiliere das Modul, starte einen Prozess und gib die 'area_loop' Funktion
# in der Shell mit, etwa so:
pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
# Sende eine Nachricht an die 'pid', die ein Muster im 'receive'-Ausdruck
# erfüllt:
pid <- {:rectangle, 2, 3}
#=> Area = 6
# {:rectangle,2,3}
pid <- {:circle, 2}
#=> Area = 12.56000000000000049738
# {:circle,2}
# Die Shell selbst ist ein Prozess und mit dem Schlüsselwort 'self' kann man
# die aktuelle pid herausfinden.
self() #=> #PID<0.27.0>
```
## Referenzen und weitere Lektüre
* [Getting started guide](http://elixir-lang.org/getting_started/1.html) auf der [elixir Website](http://elixir-lang.org)
* [Elixir Documentation](http://elixir-lang.org/docs/master/)
* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) von Fred Hebert
* "Programming Erlang: Software for a Concurrent World" von Joe Armstrong
---
language: Elixir
contributors:
- ["Joao Marques", "http://github.com/mrshankly"]
translators:
- ["Gregor Große-Bölting", "http://www.ideen-und-soehne.de"]
filename: learnelixir-de.ex
lang: de-de
---
Elixir ist eine moderne, funktionale Sprache für die Erlang VM. Sie ist voll
kompatibel mit Erlang, verfügt aber über eine freundlichere Syntax und bringt
viele Features mit.
```ruby
# Einzeilige Kommentare werden mit der Raute gesetzt.
# Es gibt keine mehrzeiligen Kommentare;
# es ist aber problemlos möglich mehrere einzeilige Kommentare hintereinander
# zu setzen (so wie hier).
# Mit 'iex' ruft man die Elixir-Shell auf.
# Zum kompilieren von Modulen dient der Befehl 'elixirc'.
# Beide Befehle sollten als Umgebungsvariable gesetzt sein, wenn Elixir korrekt
# installiert wurde.
## ---------------------------
## -- Basistypen
## ---------------------------
# Es gibt Nummern:
3 # Integer
0x1F # Integer
3.0 # Float
# Für bessere Lesbarkeit des Codes können Unterstriche "_" als Trennzeichen verwendet werden
1_000_000 == 1000000 # Integer
1_000.567 == 1000.567 # Float
# Atome, das sind Literale, sind Konstanten mit Namen. Sie starten mit einem
# ':'.
:hello # Atom
# Außerdem gibt es Tupel, deren Werte im Arbeitsspeicher vorgehalten werden.
{1,2,3} # Tupel
# Die Werte innerhalb eines Tupels können mit der 'elem'-Funktion ausgelesen
# werden:
elem({1, 2, 3}, 0) # => 1
# Listen sind als verkettete Listen implementiert.
[1, 2, 3] # list
# Auf Kopf und Rest einer Liste kann wie folgt zugegriffen werden:
[ kopf | rest ] = [1,2,3]
kopf # => 1
rest # => [2, 3]
# In Elixir, wie auch in Erlang, kennzeichnet '=' ein 'pattern matching'
# (Musterabgleich) und keine Zuweisung.
# Das heißt, dass die linke Seite auf die rechte Seite 'abgeglichen' wird.
# Auf diese Weise kann im Beispiel oben auf Kopf und Rest der Liste zugegriffen
# werden.
# Ein Musterabgleich wird einen Fehler werfen, wenn die beiden Seiten nicht
# zusammenpassen.
# Im folgenden Beispiel haben die Tupel eine unterschiedliche Anzahl an
# Elementen:
{a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2}
# Es gibt außerdem 'binaries',
<<1,2,3>> # binary.
# Strings und 'char lists'
"hello" # String
'hello' # Char-Liste
# ... und mehrzeilige Strings
"""
Ich bin ein
mehrzeiliger String.
"""
#=> "Ich bin ein\nmehrzeiliger String.\n"
# Alles Strings werden in UTF-8 enkodiert:
"héllò" #=> "héllò"
# Eigentlich sind Strings in Wahrheit nur binaries und 'char lists' einfach
# Listen.
<<?a, ?b, ?c>> #=> "abc"
[?a, ?b, ?c] #=> 'abc'
# In Elixir gibt `?a` den ASCII-Integer für den Buchstaben zurück.
?a #=> 97
# Um Listen zu verbinden gibt es den Operator '++', für binaries nutzt man '<>'
[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"
## ---------------------------
## -- Operatoren
## ---------------------------
# Einfache Arithmetik
1 + 1 #=> 2
10 - 5 #=> 5
5 * 2 #=> 10
10 / 2 #=> 5.0
# In Elixir gibt der Operator '/' immer einen Float-Wert zurück.
# Für Division mit ganzzahligen Ergebnis gibt es 'div'
div(10, 2) #=> 5
# Um den Rest der ganzzahligen Division zu erhalten gibt es 'rem'
rem(10, 3) #=> 1
# Natürlich gibt es auch Operatoren für Booleans: 'or', 'and' und 'not'. Diese
# Operatoren erwarten einen Boolean als erstes Argument.
true and true #=> true
false or true #=> true
# 1 and true #=> ** (ArgumentError) argument error
# Elixir bietet auch '||', '&&' und '!', die Argumente jedweden Typs
# akzeptieren. Alle Werte außer 'false' und 'nil' werden zu wahr evaluiert.
1 || true #=> 1
false && 1 #=> false
nil && 20 #=> nil
!true #=> false
# Für Vergleiche gibt es die Operatoren `==`, `!=`, `===`, `!==`, `<=`, `>=`,
# `<` und `>`
1 == 1 #=> true
1 != 1 #=> false
1 < 2 #=> true
# '===' und '!==' sind strikter beim Vergleich von Integern und Floats:
1 == 1.0 #=> true
1 === 1.0 #=> false
# Es ist außerdem möglich zwei verschiedene Datentypen zu vergleichen:
1 < :hello #=> true
# Die gesamte Ordnung über die Datentypen ist wie folgt definiert:
# number < atom < reference < functions < port < pid < tuple < list < bitstring
# Um Joe Armstrong zu zitieren: "The actual order is not important, but that a
# total ordering is well defined is important."
## ---------------------------
## -- Kontrollstrukturen
## ---------------------------
# Es gibt die `if`-Verzweigung
if false do
"Dies wird nie jemand sehen..."
else
"...aber dies!"
end
# ...und ebenso `unless`
unless true do
"Dies wird nie jemand sehen..."
else
"...aber dies!"
end
# Du erinnerst dich an 'pattern matching'? Viele Kontrollstrukturen in Elixir
# arbeiten damit.
# 'case' erlaubt es uns Werte mit vielerlei Mustern zu vergleichen.
case {:one, :two} do
{:four, :five} ->
"Das wird nicht passen"
{:one, x} ->
"Das schon und außerdem wird es ':two' dem Wert 'x' zuweisen."
_ ->
"Dieser Fall greift immer."
end
# Es ist eine übliche Praxis '_' einen Wert zuzuweisen, sofern dieser Wert
# nicht weiter verwendet wird.
# Wenn wir uns zum Beispiel nur für den Kopf einer Liste interessieren:
[kopf | _] = [1,2,3]
kopf #=> 1
# Für bessere Lesbarkeit können wir auch das Folgende machen:
[kopf | _rest] = [:a, :b, :c]
kopf #=> :a
# Mit 'cond' können diverse Bedingungen zur selben Zeit überprüft werden. Man
# benutzt 'cond' statt viele if-Verzweigungen zu verschachteln.
cond do
1 + 1 == 3 ->
"Ich werde nie aufgerufen."
2 * 5 == 12 ->
"Ich auch nicht."
1 + 2 == 3 ->
"Aber ich!"
end
# Es ist üblich eine letzte Bedingung einzufügen, die immer zu wahr evaluiert.
cond do
1 + 1 == 3 ->
"Ich werde nie aufgerufen."
2 * 5 == 12 ->
"Ich auch nicht."
true ->
"Aber ich! (dies ist im Grunde ein 'else')"
end
# 'try/catch' wird verwendet um Werte zu fangen, die zuvor 'geworfen' wurden.
# Das Konstrukt unterstützt außerdem eine 'after'-Klausel die aufgerufen wird,
# egal ob zuvor ein Wert gefangen wurde.
try do
throw(:hello)
catch
nachricht -> "#{nachricht} gefangen."
after
IO.puts("Ich bin die 'after'-Klausel.")
end
#=> Ich bin die 'after'-Klausel.
# ":hello gefangen"
## ---------------------------
## -- Module und Funktionen
## ---------------------------
# Anonyme Funktionen (man beachte den Punkt)
square = fn(x) -> x * x end
square.(5) #=> 25
# Anonyme Funktionen unterstützen auch 'pattern' und 'guards'. Guards erlauben
# es die Mustererkennung zu justieren und werden mit dem Schlüsselwort 'when'
# eingeführt:
f = fn
x, y when x > 0 -> x + y
x, y -> x * y
end
f.(1, 3) #=> 4
f.(-1, 3) #=> -3
# Elixir bietet zahlreiche eingebaute Funktionen. Diese sind im gleichen
# Geltungsbereich ('scope') verfügbar.
is_number(10) #=> true
is_list("hello") #=> false
elem({1,2,3}, 0) #=> 1
# Mehrere Funktionen können in einem Modul gruppiert werden. Innerhalb eines
# Moduls ist es möglich mit dem Schlüsselwort 'def' eine Funktion zu
# definieren.
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
# Um unser einfaches Mathe-Modul zu kompilieren muss es unter 'math.ex'
# gesichert werden. Anschließend kann es mit 'elixirc' im Terminal aufgerufen
# werden: elixirc math.ex
# Innerhalb eines Moduls definieren wir private Funktionen mit 'defp'. Eine
# Funktion, die mit 'def' erstellt wurde, kann von anderen Modulen aufgerufen
# werden; eine private Funktion kann nur lokal angesprochen werden.
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)
# Auch Funktionsdeklarationen unterstützen 'guards' und Mustererkennung:
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
# Wegen der Unveränderlichkeit von Variablen ist Rekursion ein wichtiger
# Bestandteil von Elixir.
defmodule Recursion do
def sum_list([head | tail], acc) do
sum_list(tail, acc + head)
end
def sum_list([], acc) do
acc
end
end
Recursion.sum_list([1,2,3], 0) #=> 6
# Elixir-Module unterstützen Attribute. Es gibt eingebaute Attribute, ebenso
# ist es möglich eigene Attribute hinzuzufügen.
defmodule MyMod do
@moduledoc """
Dies ist ein eingebautes Attribut in einem Beispiel-Modul
"""
@my_data 100 # Dies ist ein selbst-definiertes Attribut.
IO.inspect(@my_data) #=> 100
end
## ---------------------------
## -- 'Records' und Ausnahmebehandlung
## ---------------------------
# 'Records' sind im Grunde Strukturen, die es erlauben einem Wert einen eigenen
# Namen zuzuweisen.
defrecord Person, name: nil, age: 0, height: 0
joe_info = Person.new(name: "Joe", age: 30, height: 180)
#=> Person[name: "Joe", age: 30, height: 180]
# Zugriff auf den Wert von 'name'
joe_info.name #=> "Joe"
# Den Wert von 'age' überschreiben
joe_info = joe_info.age(31) #=> Person[name: "Joe", age: 31, height: 180]
# Der 'try'-Block wird zusammen mit dem 'rescue'-Schlüsselwort dazu verwendet,
# um Ausnahmen beziehungsweise Fehler zu behandeln.
try do
raise "Irgendein Fehler."
rescue
RuntimeError -> "Laufzeit-Fehler gefangen."
_error -> "Und dies fängt jeden Fehler."
end
# Alle Ausnahmen haben das Attribut 'message'
try do
raise "ein Fehler"
rescue
x in [RuntimeError] ->
x.message
end
## ---------------------------
## -- Nebenläufigkeit
## ---------------------------
# Elixir beruht auf dem Aktoren-Model zur Behandlung der Nebenläufigkeit. Alles
# was man braucht um in Elixir nebenläufige Programme zu schreiben sind drei
# Primitive: Prozesse erzeugen, Nachrichten senden und Nachrichten empfangen.
# Um einen neuen Prozess zu erzeugen nutzen wir die 'spawn'-Funktion, die
# wiederum eine Funktion als Argument entgegen nimmt.
f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245>
spawn(f) #=> #PID<0.40.0>
# 'spawn' gibt eine pid (einen Identifikator des Prozesses) zurück. Diese kann
# nun verwendet werden, um Nachrichten an den Prozess zu senden. Um
# zu senden nutzen wir den '<-' Operator. Damit das alles Sinn macht müssen wir
# in der Lage sein Nachrichten zu empfangen. Dies wird mit dem
# 'receive'-Mechanismus sichergestellt:
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
# Kompiliere das Modul, starte einen Prozess und gib die 'area_loop' Funktion
# in der Shell mit, etwa so:
pid = spawn(fn -> Geometry.area_loop() end) #=> #PID<0.40.0>
# Sende eine Nachricht an die 'pid', die ein Muster im 'receive'-Ausdruck
# erfüllt:
pid <- {:rectangle, 2, 3}
#=> Area = 6
# {:rectangle,2,3}
pid <- {:circle, 2}
#=> Area = 12.56000000000000049738
# {:circle,2}
# Die Shell selbst ist ein Prozess und mit dem Schlüsselwort 'self' kann man
# die aktuelle pid herausfinden.
self() #=> #PID<0.27.0>
```
## Referenzen und weitere Lektüre
* [Getting started guide](http://elixir-lang.org/getting_started/1.html) auf der [elixir Website](http://elixir-lang.org)
* [Elixir Documentation](http://elixir-lang.org/docs/master/)
* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) von Fred Hebert
* "Programming Erlang: Software for a Concurrent World" von Joe Armstrong

View File

@ -33,7 +33,7 @@ Hauptmerkmal von Elm sind die ausführlichen und gut erklärten Fehlermeldungen.
-- Exponenten
5 ^ 2 -- 25
-- Boolsche Werte
-- Boolesche Werte
not True -- False
not False -- True
1 == 1 -- True
@ -189,7 +189,7 @@ listLength aList =
-- 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.
-- Danach wird das Ergebnis davon den Funktionen "cos", bzw. "sin" übergeben.
-- Dann wird das Ergebnis davon mit 2 quadriert und als letztes werden diese
-- beiden Werte dann addiert.
@ -238,7 +238,7 @@ 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.
-- Ein "Record" ist ähnlich wie ein Tupel, nur das jedes Feld einen Namen hat.
-- Dabei spielt die Reihenfolge keine Rolle.
{ x = 3, y = 7 }
@ -253,7 +253,7 @@ append [1,1,2] [3,5,8] -- [1,1,2,3,5,8]
{ person |
name = "George" }
-- Mehrere Felder aufeinmal ändern unter Verwendung des alten Wertes.
-- Mehrere Felder auf einmal ändern unter Verwendung des alten Wertes.
{ particle |
position = particle.position + particle.velocity,
velocity = particle.velocity + particle.acceleration }
@ -274,7 +274,7 @@ otherOrigin : Point3D
otherOrigin =
Point3D 0 0 0
-- Aber es ist immernoch der selbe Typ, da es nur ein Alias ist!
-- Aber es ist immer noch derselbe Typ, da es nur ein Alias ist!
origin == otherOrigin -- True
-- Neben den Records gibt es auch noch so genannte Summentypen.
@ -309,7 +309,7 @@ leftmostElement tree =
-- 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
-- Eine Modul beginnt ganz oben. Ohne diese Angabe befindet man sich
-- automatisch im Modul "Main".
module Name where
@ -337,13 +337,13 @@ $ elm make MyFile.elm
-- "elm-package.json"-Datei anlegen, die alle Informationen des Projektes
-- speichert.
-- Der Reactor ist ein Server, welche alle Dateinen kompiliert und ausführt.
-- Der Reactor ist ein Server, welcher alle Dateien 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.
-- 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.
@ -360,7 +360,7 @@ 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)
- [Anleitung zur Installation 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)

View File

@ -82,10 +82,10 @@ Zeilenumbrüche beinhalten.` // Selber Zeichenketten-Typ
// nicht-ASCII Literal. Go Quelltext ist UTF-8 kompatibel.
g := 'Σ' // Ein Runen-Typ, alias int32, gebraucht für unicode code points.
f := 3.14195 // float64, eine IEEE-754 64-bit Dezimalzahl
f := 3.14159 // float64, eine IEEE-754 64-bit Dezimalzahl
c := 3 + 4i // complex128, besteht intern aus zwei float64-er
// "var"-Syntax mit Initalwert
// "var"-Syntax mit Initialwert
var u uint = 7 // Vorzeichenlos, aber die Größe ist implementationsabhängig
var pi float32 = 22. / 7
@ -124,13 +124,13 @@ Zeilenumbrüche beinhalten.` // Selber Zeichenketten-Typ
// keine Zeiger-Rechnungen. Fehler können sich durch "nil" einschleichen, jedoch
// nicht durch erhöhen eines Zeigers.
func learnMemory() (p, q *int) {
// Die bennanten Rückgabewerte p & q sind vom Typ *int
// Die benannten Rückgabewerte p & q sind vom Typ *int
p = new(int) // Eingebaute Funktion "new" weist neuen Speicherplatz zu
// Der zugewiesene Speicher ist mit 0 initialisiert, p ist nicht länger nil
s := make([]int, 20) // So weist man 20 ints nebeneinander (im Speicher) zu
s[3] = 7 // Einer von ihnen wird ein Wert zugewiesen
r := -2 // Deklaration einer weiteren lokalen Variable
return &s[3], &r // & gibt die Addresse einer Variable
return &s[3], &r // & gibt die Adresse einer Variable
}
func expensiveComputation() int {
@ -292,7 +292,7 @@ func learnConcurrency() {
// Eine einzige Funktion aus dem http-Paket kann einen Webserver starten.
func learnWebProgramming() {
// Der erste Parameter von "ListenAndServe" ist eine TCP Addresse, an die
// Der erste Parameter von "ListenAndServe" ist eine TCP Adresse, an die
// sich angeschlossen werden soll.
// Der zweite Parameter ist ein Interface, speziell: ein http.Handler
err := http.ListenAndServe(":8080", pair{})
@ -308,13 +308,13 @@ func (p pair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
```
## Weitere Resourcen
Informationen zu Go findet man auf der [offiziellen Go Webseite](http://golang.org/).
Informationen zu Go findet man auf der [offiziellen Go Webseite](https://go.dev/).
Dort gibt es unter anderem ein Tutorial und interaktive Quelltext-Beispiele, vor
allem aber Dokumentation zur Sprache und den Paketen.
Auch zu empfehlen ist die Spezifikation von Go, die nach heutigen Standards sehr
kurz und gut verständlich formuliert ist. Auf der Leseliste von Go-Neulingen
ist außerdem der Quelltext der [Go standard Bibliothek](http://golang.org/src/pkg/)
ist außerdem der Quelltext der [Go standard Bibliothek](https://go.dev/src/)
einzusehen. Dieser kann als Referenz für leicht zu verstehendes und im idiomatischen Stil
verfasstes Go dienen. Erreichbar ist der Quelltext auch durch das Klicken der Funktionsnamen
in der [offiziellen Dokumentation von Go](http://golang.org/pkg/).
in der [offiziellen Dokumentation von Go](https://go.dev/pkg/).

View File

@ -305,7 +305,6 @@ class Samuel
$cat = new Samuel();
$cat instanceof KittenInterface === true; // True
```
## Weitere Informationen
@ -318,5 +317,5 @@ besuchen.
Die offizielle Webseite [hhvm.com](http://hhvm.com/) bietet Infos zum Download
und zur Installation der HHVM.
Hack's [nicht-untersützte PHP Syntax-Elemente](http://docs.hhvm.com/manual/en/hack.unsupported.php)
Hack's [nicht-unterstützte PHP Syntax-Elemente](http://docs.hhvm.com/manual/en/hack.unsupported.php)
werden im offiziellen Handbuch beschrieben.

View File

@ -93,7 +93,7 @@ $ haml input_file.haml output_file.html
/ andere Attribute können über den Hash angegeben werden:
%a{:href => '#', :class => 'bar', :title => 'Bar'}
/ Booleesche Attribute können mit 'true' gesetzt werden:
/ Boolesche Attribute können mit 'true' gesetzt werden:
%input{:selected => true}
/ data-Attribute können in einem eigenen Hash im :data key angegeben werden:
@ -141,13 +141,12 @@ $ haml input_file.haml output_file.html
/ -------------------------------------------
/
Mit dem Doppelpinkt können Haml Filter benutzt werden.
Mit dem Doppelpunkt können Haml Filter benutzt werden.
Zum Beispiel gibt es den :javascript Filter, mit dem inline JS
geschrieben werden kann:
:javascript
console.log('Dies ist ein <script>');
```
## Weitere Resourcen

View File

@ -50,7 +50,7 @@ not False -- True
1 /= 1 -- False
1 < 10 -- True
-- `not` ist eine Funktion die ein Argument entgegenimmt.
-- `not` ist eine Funktion die ein Argument entgegennimmt.
-- Haskell benötigt keine Klammern um Argumente.
-- Sie werden einfach aufgelistet: func arg1 arg2 arg3...
-- Wie man Funktionen definiert kommt weiter unten.
@ -66,6 +66,8 @@ not False -- True
-- Ein String ist eine Liste von Zeichen.
['H', 'a', 'l', 'l', 'o', '!'] -- "Hallo!"
-- Der "!!"-Operator extrahiert das Element an einem bestimmten Index
"Das ist eine String" !! 0 -- 'D'
@ -87,7 +89,7 @@ not False -- True
[5..1] -- [], da Haskell standardmässig inkrementiert.
[5,4..1] -- [5,4,3,2,1]
-- Der "!!"-Operator extrahiert das Element an einem bestimmten Index:
-- Ein Element per Index extrahieren:
[1..10] !! 3 -- 4
-- Haskell unterstützt unendliche Listen!
@ -282,7 +284,7 @@ for [0..5] $ \i -> show i
-- wir hätten sie auch so benutzen können:
for [0..5] show
-- foldl oder foldr reduziren Listen auf einen Wert.
-- foldl oder foldr reduzieren Listen auf einen Wert.
-- foldl <Funktion> <initialer Wert> <Liste>
foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
@ -345,7 +347,7 @@ main' = interact countLines
-- Man kann den Typ `IO ()` als Repräsentation einer Sequenz von
-- Aktionen sehen, die der Computer abarbeiten muss.
-- Wie bei einem Programm das in einer Imperativen Sprache geschreiben wurde.
-- Wie bei einem Programm das in einer Imperativen Sprache geschrieben wurde.
-- Mit der `do` Notation können Aktionen verbunden werden.
sayHello :: IO ()
@ -419,7 +421,6 @@ foo :: Integer
What is your name?
Friend!
Hello, Friend!
```
Es gibt noch viel mehr in Haskell, wie zum Beispiel Typklassen und Monaden.

View File

@ -10,7 +10,7 @@ lang: de-de
HTML steht für HyperText Markup Language (Hypertext-Auszeichnungssprache).
Sie ist eine Sprache, um Seiten für das World Wide Web zu schreiben.
Es ist eine Auszeichnugssprache, die es uns ermöglicht Webseiten mithilfe des Codes zu schreiben, der kennzeichnet wie Text und Daten angezeigt werden sollen. Eigentlich sind HTML Dateien nur einfache Textdateien.
Es ist eine Auszeichnungssprache, die es uns ermöglicht Webseiten mithilfe des Codes zu schreiben, der kennzeichnet wie Text und Daten angezeigt werden sollen. Eigentlich sind HTML Dateien nur einfache Textdateien.
Was sind das für Auszeichnungen? Es ist eine Methode, um die Daten der Website zu organisieren mithilfe von Start- und Endtags.
Diese Auszeichnung dient dazu dem Text Bedeutung zu geben, welchen sie umschließt.
Wie viele andere Computersprachen auch, besitzt HTML viele Versionen. Wir werden hier über HTML5 reden.
@ -65,7 +65,7 @@ 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 diesem Punkt wird nichts im Browerfenster angezeigt. -->
<!-- Bis zu diesem Punkt wird nichts im Browserfenster angezeigt. -->
<!-- Wir müssen den Body mit dem Inhalt füllen, der angezeigt werden soll. -->
<body>
@ -95,7 +95,7 @@ Dieser Artikel ist bedacht darauf, nur HTML Syntax und nützliche Tipps zu geben
<table> <!-- Wir öffnen ein <table> Element. -->
<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>
<th>Zweiter Tabellenkopf</th>
</tr>
<tr>
<td>Erste Zeile, erste Spalte</td> <!-- <td> erlaubt es, eine Tabellenzelle zu erstellen. -->
@ -106,7 +106,6 @@ Dieser Artikel ist bedacht darauf, nur HTML Syntax und nützliche Tipps zu geben
<td>Zweite Zeile, zweite Spalte</td>
</tr>
</table>
```
## Verwendung

View File

@ -125,9 +125,9 @@ public class LearnJavaDe {
// Weitere nennenswerte Typen
// ArrayLists - Ähnlich Arrays, allerdings werden mehr Funktionen geboten,
// ebenso ist die Arraygröße verwänderbar
// ebenso ist die Arraygröße veränderbar
// LinkedLists - Implementierung einer doppelt verlinkten Liste.
// Alle Operationen funktioneren so, wie es von einer doppelt verlinkten Liste erwartet wird.
// Alle Operationen funktionieren so, wie es von einer doppelt verlinkten Liste erwartet wird.
// Weitere Informationen: https://de.wikipedia.org/wiki/Liste_(Datenstruktur)#Doppelt_.28mehrfach.29_verkettete_Liste
// Maps - Eine Sammlung von Objekten, welche eine Verknüpfung von Schlüsseln zu Werten (key => value) vornimmt.
// Eine Map kann keine Duplikate enthalten; Jeder Schlüssel kann genau einen Wert beinhalten.
@ -173,7 +173,7 @@ public class LearnJavaDe {
// Inkrementierungen
int i = 0;
System.out.println("\n->Inc/Dec-rementierung");
// Die ++ und -- operatoren inkrementieren und dekrementieren jeweils um 1.
// Die ++ und -- Operatoren inkrementieren und dekrementieren jeweils um 1.
// Werden sie vor die Variable gesetzt, ink-/dekrementieren sie und geben anschließend ihren Wert zurück.
// Hinter der Variable geben sie ihren Wert zurück und ändern ihn anschließend.
System.out.println(i++); // i = 1, schreibt 0 (post-increment)
@ -284,7 +284,7 @@ public class LearnJavaDe {
// String
// Tpe-Casting
// Java Objekte können benfalls konvertiert werden, hierbei gibt es vielfältige Konzepte.
// Java Objekte können ebenfalls konvertiert werden, hierbei gibt es vielfältige Konzepte.
// Weitere Informationen finden sich hier (englisch):
// http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
@ -311,7 +311,7 @@ public class LearnJavaDe {
} // Ende der LearnJavaDe Klasse
// In einer .java-Datei können zusätzliche nicht öffentliche (non-public) äüßere Klassen vorhanden sein.
// In einer .java-Datei können zusätzliche nicht öffentliche (non-public) äußere Klassen vorhanden sein.
// Syntax der Klassendeklaration:
@ -490,7 +490,7 @@ Für tiefergreifende Fragen ist Google der beste Startpunkt.
* [Head First Java](http://www.headfirstlabs.com/books/hfjava/)
* [Thinking in Java](http://www.mindview.net/Books/TIJ/)
* [Thinking in Java](https://www.amazon.com/Thinking-Java-4th-Bruce-Eckel/dp/0131872486/)
* [Objects First with Java](http://www.amazon.com/Objects-First-Java-Practical-Introduction/dp/0132492660)

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@ Dokument das vermutlich einfachste "Learn X in Y Minutes" werden.
In seiner grundlegenden Form hat JSON keine eigentlichen Kommentare. Dennoch
akzeptieren die meisten Parser Kommentare in C-Syntax (`//`, `/* */`). Dennoch
soll für dieses Dokument nur 100% gültiges JSON verwendet werden, weshalbt keine
soll für dieses Dokument nur 100 % gültiges JSON verwendet werden, weshalb keine
Kommentare verwendet werden. Glücklicherweise ist das nachfolgende Dokument
selbsterklärend.

View File

@ -57,7 +57,7 @@ filename: latex-de.tex
% LaTeX für uns eine Titelseite generieren
\maketitle
% Die meisten Paper haben ein Abstract. LaTeX bietet dafür einen vorgefertigen Befehl an.
% Die meisten Paper haben ein Abstract. LaTeX bietet dafür einen vorgefertigten Befehl an.
% Das Abstract sollte in der logischen Reihenfolge, also nach dem Titel, aber vor dem
% Inhalt erscheinen.
% Dieser Befehl ist in den Dokumentenklassen article und report verfügbar.
@ -240,6 +240,7 @@ Das war's erst mal!
% Dokument beenden
\end{document}
```
## Mehr Informationen über LateX
* Das tolle LaTeX wikibook: [https://de.wikibooks.org/wiki/LaTeX-Kompendium](https://de.wikibooks.org/wiki/LaTeX-Kompendium)

View File

@ -21,7 +21,7 @@ lang: de-de
num = 42 -- Alle Nummern sind vom Typ: Double.
-- Werd nicht nervös, 64-Bit Double haben 52 Bits zum Speichern von exakten
-- Ganzzahlen; Maschinen-Genauigkeit ist kein Problem für Ganzzahlen kleiner als
-- Ganzzahlen; Maschinen-Genauigkeit ist kein Problem für Ganzzahlen kleiner als
-- 52 Bit.
s = 'walternate' -- Zeichenketten sind unveränderlich, wie bei Python.
@ -29,11 +29,11 @@ t = "Doppelte Anführungszeichen sind auch OK"
u = [[ Doppelte eckige Klammern
beginnen und beenden
mehrzeilige Zeichenketten.]]
t = nil -- Undefineren von t; Lua hat einen Garbage Collection.
t = nil -- Undefinieren von t; Lua hat einen Garbage Collection.
-- Blöcke werden durch Schlüsselwörter wie do/end markiert:
while num < 50 do
num = num + 1 -- Es gibt Keine Operatoren wie ++ oder +=
num = num + 1 -- Es gibt keine Operatoren wie ++ oder +=
end
-- If Bedingungen:
@ -72,7 +72,7 @@ for i = 1, 100 do -- Ein Bereich inkludiert beide Enden.
karlSum = karlSum + i
end
-- Verwende "100, 1, -1" als Breich für Countdowns:
-- Verwende "100, 1, -1" als Bereich für Countdowns:
fredSum = 0
for j = 100, 1, -1 do fredSum = fredSum + j end
@ -161,7 +161,7 @@ print(t.key1) -- Ausgabe 'value1'.
t.newKey = {} -- Neues Schlüssel/Wert-Paar hinzufügen.
t.key2 = nil -- key2 aus der Tabelle entfernen.
-- Literale notation für jeden (nicht-nil) Wert als Schlüssel:
-- Literale Notation für jeden (nicht-nil) Wert als Schlüssel:
u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
print(u[6.28]) -- Ausgabe "tau"
@ -171,7 +171,7 @@ a = u['@!#'] -- Nun ist a = 'qbert'.
b = u[{}] -- Wir würden 1729 erwarten, aber es ist nil:
-- b = nil weil der Lookup fehlschlägt. Er schlägt Fehl, weil der Schlüssel
-- den wir verwendet haben nicht das gleiche Objekt ist das wir verwendet
-- haben um den original Wert zu speichern. Zahlen und Zeichnkette sind daher
-- haben um den original Wert zu speichern. Zahlen und Zeichenkette sind daher
-- die praktischeren Schlüssel.
-- Eine Funktion mit nur einem Tabellen-Parameter benötigt keine Klammern.
@ -230,7 +230,7 @@ s = f1 + f2 -- Rufe __add(f1, f2) vom der Metatabelle von f1 auf.
-- Die nächste Zeile schlägt fehl weil s keine Metatabelle hat:
-- t = s + s
-- Mihilfe von Klassen ähnlichen Mustern kann das gelöst werden.
-- Mithilfe von Klassen ähnlichen Mustern kann das gelöst werden.
-- Siehe weiter unten.
-- Ein __index einer Metatabelle überlädt Punkt-Lookups:
@ -269,10 +269,10 @@ eatenBy = myFavs.animal -- Funktioniert dank Metatabelle!
-- 3.2 Klassen-Artige Tabellen und Vererbung.
--------------------------------------------------------------------------------
-- Klassen sind in Lua nicht eingebaut. Es gibt verschieden Wege sie mithilfe
-- Klassen sind in Lua nicht eingebaut. Es gibt verschiedene Wege sie mithilfe
-- von Tabellen und Metatabellen zu erzeugen.
-- Die Erklärund des Beispiels erfolgt unterhalb.
-- Die Erklärung des Beispiels erfolgt unterhalb.
Dog = {} -- 1.
@ -294,7 +294,7 @@ mrDog:makeSound() -- 'I say woof' -- 8.
-- "function tablename.fn(self, ...)", Der : fügt nur ein Argument namens
-- self hinzu. Siehe 7 & 8 um zu sehen wie self seinen Wert bekommt.
-- 3. newObj wird eine Instanz von Dog.
-- 4. "self" ist die zu Instanzierende Klasse. Meistern ist self = Dog, aber
-- 4. "self" ist die zu instanziierende Klasse. Meistern ist self = Dog, aber
-- dies kann durch Vererbung geändert werden. newObj bekommt die Funktionen
-- von self wenn wir die Metatabelle von newObj und __index von self auf
-- self setzen.
@ -400,27 +400,26 @@ g = loadstring('print(343)') -- Gibt eine Funktion zurück..
g() -- Ausgabe 343; Vorher kam keine Ausgabe.
--]]
```
## Referenzen
Ich war so begeistert Lua zu lernen, damit ich Spiele mit <a href="http://love2d.org/">Love 2D game engine</a> programmieren konnte.
Ich war so begeistert Lua zu lernen, damit ich Spiele mit [LÖVE game engine](http://love2d.org/) programmieren konnte.
Ich habe angefangen mit <a href="http://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/">BlackBulletIV's Lua for programmers</a>.
Danach habe ich das offizielle Lua Buch gelesen: <a href="http://www.lua.org/pil/contents.html">Programming in Lua</a>
Ich habe angefangen mit [BlackBulletIV's Lua for programmers](http://nova-fusion.com/2012/08/27/lua-for-programmers-part-1/).
Danach habe ich das offizielle Lua Buch gelesen: [Programming in Lua](http://www.lua.org/pil/contents.html)
Es kann auch hilfreich sein hier vorbeizuschauen: <a href="http://lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf">Lua short
reference</a>
Es kann auch hilfreich sein hier vorbeizuschauen: [Lua short reference](http://lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf)
Wichtige Themen die hier nicht angesprochen wurden; die Standard-Bibliotheken:
* <a href="http://lua-users.org/wiki/StringLibraryTutorial">string library</a>
* <a href="http://lua-users.org/wiki/TableLibraryTutorial">table library</a>
* <a href="http://lua-users.org/wiki/MathLibraryTutorial">math library</a>
* <a href="http://lua-users.org/wiki/IoLibraryTutorial">io library</a>
* <a href="http://lua-users.org/wiki/OsLibraryTutorial">os library</a>
* [`string` library](http://lua-users.org/wiki/StringLibraryTutorial)
* [`table` library](http://lua-users.org/wiki/TableLibraryTutorial)
* [`math` library](http://lua-users.org/wiki/MathLibraryTutorial)
* [`io` library](http://lua-users.org/wiki/IoLibraryTutorial)
* [`os` library](http://lua-users.org/wiki/OsLibraryTutorial)
Übrigends, die gesamte Datei ist gültiges Lua. Speichere sie als learn.lua und
starte sie als "lua learn.lua" !
Übrigens, die gesamte Datei ist gültiges Lua. Speichere sie als learn.lua und
starte sie als "`lua learn.lua`" !
Die Erstfassung ist von tylerneylon.com, und ist auch hier verfügbar: <a href="https://gist.github.com/tylerneylon/5853042">github gist</a>. Viel Spaß mit Lua!
Die Erstfassung ist von tylerneylon.com, und ist auch hier verfügbar: [GitHub gist](https://gist.github.com/tylerneylon/5853042). Viel Spaß mit Lua!

View File

@ -1,263 +1,262 @@
---
category: tool
tool: make
contributors:
- ["Robert Steed", "https://github.com/robochat"]
- ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
translators:
- ["Martin Schimandl", "https://github.com/Git-Jiro"]
filename: Makefile-de
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
von Stuart Feldman 1976 übers Wochenende geschrieben. Make ist noch immer
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äftigt sich
mit der Version GNU Make. Diese Version ist Standard auf Linux.
```make
# Kommentare können so geschrieben werden.
# Dateien sollten Makefile heißen, denn dann können sie als `make <ziel>`
# aufgerufen werden. Ansonsten muss `make -f "dateiname" <ziel>` verwendet
# werden.
# Warnung - Es sollten nur TABULATOREN zur Einrückung im Makefile verwendet
# werden. Niemals Leerzeichen!
#-----------------------------------------------------------------------
# Grundlagen
#-----------------------------------------------------------------------
# Eine Regel - Diese Regel wird nur abgearbeitet wenn die Datei file0.txt
# nicht existiert.
file0.txt:
echo "foo" > file0.txt
# Selbst Kommentare in der 'Rezept' Sektion werden an die Shell
# weitergegeben. Versuche `make file0.txt` oder einfach `make`
# die erste Regel ist die Standard-Regel.
# 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, 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.
file2.txt file3.txt: file0.txt file1.txt
touch file2.txt
touch file3.txt
# Make wird sich beschweren, wenn es mehrere Rezepte für die gleiche Regel gibt.
# Leere Rezepte zählen nicht und können dazu verwendet werden weitere
# Voraussetzungen hinzuzufügen.
#-----------------------------------------------------------------------
# Phony-Ziele
#-----------------------------------------------------------------------
# Ein Phony-Ziel ist ein Ziel, das keine Datei ist.
# Es wird nie aktuell sein, daher wird Make immer versuchen, es abzuarbeiten
all: maker process
# Es ist erlaubt Dinge ausserhalb der Reihenfolge zu deklarieren.
maker:
touch ex0.txt ex1.txt
# Um das Fehlschlagen von Phony-Regeln zu vermeiden wenn eine echte Datei den
# selben namen wie ein Phony-Ziel hat:
.PHONY: all maker process
# Das ist ein spezielles Ziel. Es gibt noch ein paar mehr davon.
# Eine Regel mit einem Phony-Ziel als Voraussetzung wird immer abgearbeitet
ex0.txt ex1.txt: maker
# Häufige Phony-Ziele sind: all make clean install ...
#-----------------------------------------------------------------------
# Automatische Variablen & Wildcards
#-----------------------------------------------------------------------
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 $+ # Alle Voraussetzungen inklusive Duplikate (nicht wie Üblich)
#@echo $| # Alle 'order only' Voraussetzungen
# Selbst wenn wir die Voraussetzungen der Regel aufteilen, $^ wird sie finden.
process: ex1.txt file0.txt
# ex1.txt wird gefunden werden, aber file0.txt wird dedupliziert.
#-----------------------------------------------------------------------
# Muster
#-----------------------------------------------------------------------
# Mit Mustern kann man make beibringen wie Dateien in andere Dateien
# umgewandelt werden.
%.png: %.svg
inkscape --export-png $^
# 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
# findet.
%.png: %.svg
@echo this rule is chosen
# 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
# Make hat bereits ein paar eingebaute Muster-Vergleichs-Regelen. Zum Beispiel
# weiß Make wie man aus *.c Dateien *.o Dateien erzeugt.
# Ältere Versionen von Make verwenden möglicherweise Suffix-Regeln anstatt
# Muster-Vergleichs-Regeln.
.png.ps:
@echo this rule is similar to a pattern rule.
# Aktivieren der Suffix-Regel
.SUFFIXES: .png
#-----------------------------------------------------------------------
# Variablen
#-----------------------------------------------------------------------
# auch Makros genannt.
# Variablen sind im Grunde genommen Zeichenketten-Typen.
name = Ted
name2="Sarah"
echo:
@echo $(name)
@echo ${name2}
@echo $name # Das funktioniert nicht, wird als $(n)ame behandelt.
@echo $(name3) # Unbekannte Variablen werden als leere Zeichenketten behandelt.
# Es git 4 Stellen um Variablen zu setzen.
# In Reihenfolge der Priorität von höchster zu niedrigster:
# 1: Befehls-Zeilen Argumente
# 2: Makefile
# 3: Shell Umbebungs-Variablen - Make importiert diese automatisch.
# 3: MAke hat einige vordefinierte Variablen.
name4 ?= Jean
# Setze die Variable nur wenn es eine gleichnamige Umgebungs-Variable noch
# nicht gibt.
override name5 = David
# Verhindert, dass Kommando-Zeilen Argumente diese Variable ändern können.
name4 +=grey
# Werte an eine Variable anhängen (inkludiert Leerzeichen).
# 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!)
# Ein paar Variablen, die von Make automatisch definiert werden.
echo_inbuilt:
echo $(CC)
echo ${CXX}
echo $(FC)
echo ${CFLAGS}
echo $(CPPFLAGS)
echo ${CXXFLAGS}
echo $(LDFLAGS)
echo ${LDLIBS}
#-----------------------------------------------------------------------
# Variablen 2
#-----------------------------------------------------------------------
# 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)
var := hello
var2 ::= $(var) hello
#:= und ::= sind äquivalent.
# Diese Variablen werden prozedural ausgwertet (in der Reihenfolge in der sie
# auftauchen), die stehen daher im wiederspruch zum Rest der Sprache!
# Das funktioniert nicht
var3 ::= $(var4) and good luck
var4 ::= good night
#-----------------------------------------------------------------------
# Funktionen
#-----------------------------------------------------------------------
# Make verfügt über eine Vielzahl von Funktionen.
sourcefiles = $(wildcard *.c */*.c)
objectfiles = $(patsubst %.c,%.o,$(sourcefiles))
# Das Format ist $(func arg0,arg1,arg2...)
# Ein paar Beispiele
ls: * src/*
@echo $(filter %.txt, $^)
@echo $(notdir $^)
@echo $(join $(dir $^),$(notdir $^))
#-----------------------------------------------------------------------
# Direktiven
#-----------------------------------------------------------------------
# Inkludiere andere Makefile, sehr praktisch für platformspezifischen Code
include foo.mk
sport = tennis
# Konditionale kompiliereung
report:
ifeq ($(sport),tennis)
@echo 'game, set, match'
else
@echo "They think it's all over; it is now"
endif
# Es gibt auch ifneq, ifdef, ifndef
foo = true
ifdef $(foo)
bar = 'hello'
endif
```
### Mehr Resourcen
+ [gnu make documentation](https://www.gnu.org/software/make/manual/)
+ [software carpentry tutorial](http://swcarpentry.github.io/make-novice/)
+ learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html)
---
category: tool
tool: make
contributors:
- ["Robert Steed", "https://github.com/robochat"]
- ["Stephan Fuhrmann", "https://github.com/sfuhrm"]
translators:
- ["Martin Schimandl", "https://github.com/Git-Jiro"]
filename: Makefile-de
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
von Stuart Feldman 1976 übers Wochenende geschrieben. Make ist noch immer
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äftigt sich
mit der Version GNU Make. Diese Version ist Standard auf Linux.
```make
# Kommentare können so geschrieben werden.
# Dateien sollten Makefile heißen, denn dann können sie als `make <ziel>`
# aufgerufen werden. Ansonsten muss `make -f "dateiname" <ziel>` verwendet
# werden.
# Warnung - Es sollten nur TABULATOREN zur Einrückung im Makefile verwendet
# werden. Niemals Leerzeichen!
#-----------------------------------------------------------------------
# Grundlagen
#-----------------------------------------------------------------------
# Eine Regel - Diese Regel wird nur abgearbeitet, wenn die Datei file0.txt
# nicht existiert.
file0.txt:
echo "foo" > file0.txt
# Selbst Kommentare in der 'Rezept' Sektion werden an die Shell
# weitergegeben. Versuche `make file0.txt` oder einfach `make`
# die erste Regel ist die Standard-Regel.
# 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, 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.
file2.txt file3.txt: file0.txt file1.txt
touch file2.txt
touch file3.txt
# Make wird sich beschweren, wenn es mehrere Rezepte für die gleiche Regel gibt.
# Leere Rezepte zählen nicht und können dazu verwendet werden weitere
# Voraussetzungen hinzuzufügen.
#-----------------------------------------------------------------------
# Phony-Ziele
#-----------------------------------------------------------------------
# Ein Phony-Ziel ist ein Ziel, das keine Datei ist.
# Es wird nie aktuell sein, daher wird Make immer versuchen, es abzuarbeiten
all: maker process
# Es ist erlaubt Dinge außerhalb der Reihenfolge zu deklarieren.
maker:
touch ex0.txt ex1.txt
# Um das Fehlschlagen von Phony-Regeln zu vermeiden wenn eine echte Datei den
# selben Namen wie ein Phony-Ziel hat:
.PHONY: all maker process
# Das ist ein spezielles Ziel. Es gibt noch ein paar mehr davon.
# Eine Regel mit einem Phony-Ziel als Voraussetzung wird immer abgearbeitet
ex0.txt ex1.txt: maker
# Häufige Phony-Ziele sind: all make clean install ...
#-----------------------------------------------------------------------
# Automatische Variablen & Wildcards
#-----------------------------------------------------------------------
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 $+ # Alle Voraussetzungen inklusive Duplikate (nicht wie üblich)
#@echo $| # Alle 'order only' Voraussetzungen
# Selbst wenn wir die Voraussetzungen der Regel aufteilen, $^ wird sie finden.
process: ex1.txt file0.txt
# ex1.txt wird gefunden werden, aber file0.txt wird dedupliziert.
#-----------------------------------------------------------------------
# Muster
#-----------------------------------------------------------------------
# Mit Mustern kann man make beibringen wie Dateien in andere Dateien
# umgewandelt werden.
%.png: %.svg
inkscape --export-png $^
# 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
# findet.
%.png: %.svg
@echo this rule is chosen
# 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
# Make hat bereits ein paar eingebaute Muster-Vergleichs-Regeln. Zum Beispiel
# weiß Make wie man aus *.c Dateien *.o Dateien erzeugt.
# Ältere Versionen von Make verwenden möglicherweise Suffix-Regeln anstatt
# Muster-Vergleichs-Regeln.
.png.ps:
@echo this rule is similar to a pattern rule.
# Aktivieren der Suffix-Regel
.SUFFIXES: .png
#-----------------------------------------------------------------------
# Variablen
#-----------------------------------------------------------------------
# auch Makros genannt.
# Variablen sind im Grunde genommen Zeichenketten-Typen.
name = Ted
name2="Sarah"
echo:
@echo $(name)
@echo ${name2}
@echo $name # Das funktioniert nicht, wird als $(n)ame behandelt.
@echo $(name3) # Unbekannte Variablen werden als leere Zeichenketten behandelt.
# Es gibt 4 Stellen um Variablen zu setzen.
# In Reihenfolge der Priorität von höchster zu niedrigster:
# 1: Befehls-Zeilen Argumente
# 2: Makefile
# 3: Shell Umgebungs-Variablen - Make importiert diese automatisch.
# 3: Make hat einige vordefinierte Variablen.
name4 ?= Jean
# Setze die Variable nur wenn es eine gleichnamige Umgebungs-Variable noch
# nicht gibt.
override name5 = David
# Verhindert, dass Kommando-Zeilen Argumente diese Variable ändern können.
name4 +=grey
# Werte an eine Variable anhängen (inkludiert Leerzeichen).
# Muster-Spezifische Variablen Werte (GNU Erweiterung).
echo: name2 = Sara # Wahr innerhalb der passenden Regel und auch innerhalb
# rekursiver Voraussetzungen (außer wenn es den Graphen zerstören
# kann, wenn es zu kompliziert wird!)
# Ein paar Variablen, die von Make automatisch definiert werden.
echo_inbuilt:
echo $(CC)
echo ${CXX}
echo $(FC)
echo ${CFLAGS}
echo $(CPPFLAGS)
echo ${CXXFLAGS}
echo $(LDFLAGS)
echo ${LDLIBS}
#-----------------------------------------------------------------------
# Variablen 2
#-----------------------------------------------------------------------
# Der erste Typ von Variablen wird bei jeder Verwendung ausgewertet.
# Das kann aufwendig sein, daher existiert ein zweiter Typ von Variablen.
# Diese werden nur einmal ausgewertet. (Das ist eine GNU make Erweiterung)
var := hello
var2 ::= $(var) hello
#:= und ::= sind äquivalent.
# Diese Variablen werden prozedural ausgewertet (in der Reihenfolge, in der sie
# auftauchen), die stehen daher im Widerspruch zum Rest der Sprache!
# Das funktioniert nicht
var3 ::= $(var4) and good luck
var4 ::= good night
#-----------------------------------------------------------------------
# Funktionen
#-----------------------------------------------------------------------
# Make verfügt über eine Vielzahl von Funktionen.
sourcefiles = $(wildcard *.c */*.c)
objectfiles = $(patsubst %.c,%.o,$(sourcefiles))
# Das Format ist $(func arg0,arg1,arg2...)
# Ein paar Beispiele
ls: * src/*
@echo $(filter %.txt, $^)
@echo $(notdir $^)
@echo $(join $(dir $^),$(notdir $^))
#-----------------------------------------------------------------------
# Direktiven
#-----------------------------------------------------------------------
# Inkludiere andere Makefile, sehr praktisch für plattformspezifischen Code
include foo.mk
sport = tennis
# Konditionale Kompilierung
report:
ifeq ($(sport),tennis)
@echo 'game, set, match'
else
@echo "They think it's all over; it is now"
endif
# Es gibt auch ifneq, ifdef, ifndef
foo = true
ifdef $(foo)
bar = 'hello'
endif
```
### Mehr Ressourcen
+ [gnu make documentation](https://www.gnu.org/software/make/manual/)
+ [software carpentry tutorial](http://swcarpentry.github.io/make-novice/)
+ learn C the hard way [ex2](http://c.learncodethehardway.org/book/ex2.html) [ex28](http://c.learncodethehardway.org/book/ex28.html)

View File

@ -115,7 +115,7 @@ oder
3. Punkt drei
<!-- Auch wenn es keine gute Idee sein mag: du müsstest die einzelnen Punkte
nicht mal korrekt numerieren -->
nicht mal korrekt nummerieren -->
1. Punkt eins
1. Punkt zwei
@ -148,7 +148,7 @@ indem du eine Zeile mit vier Leerzeichen oder einem Tabulator einrückst -->
Hermann hatte nicht die leiseste Ahnung, was dieses `go_to()` bedeuten könnte!
<!-- In "GitHub Flavored Markdown" gibt es für Code nocheinmal eine
<!-- In "GitHub Flavored Markdown" gibt es für Code noch einmal eine
besondere Syntax -->
\`\`\`ruby <!-- in "echt" musst du die Backslashes entfernen: ```ruby ! -->
@ -223,7 +223,7 @@ voranstellt! -->
<http://testwebseite.de/> ist das selbe wie
[http://testwebseite.de/](http://testwebseite.de/)
<!-- Automatische Links für E-Mail-Addressen -->
<!-- Automatische Links für E-Mail-Adressen -->
<foo@bar.com>

View File

@ -16,7 +16,7 @@ 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).
```
```nix
with builtins; [
# Kommentare
@ -222,7 +222,7 @@ with builtins; [
({ a = 1; b = 2; } // { a = 3; c = 4; })
#=> { a = 3; b = 2; c = 4; }
# Das Schlüsselwort rec bezeichenet ein "rekursives Set", in dem sich Attribute
# Das Schlüsselwort rec bezeichnet ein "rekursives Set", in dem sich Attribute
# aufeinander beziehen können.
(let a = 1; in { a = 2; b = a; }.b)
#=> 1
@ -348,14 +348,8 @@ with builtins; [
### Weitere Ressourcen
* [Nix Manual - Nix expression language]
(https://nixos.org/nix/manual/#ch-expression-language)
* [James Fisher - Nix by example - Part 1: The Nix expression language]
(https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55)
* [Susan Potter - Nix Cookbook - Nix By Example]
(https://ops.functionalalgebra.com/nix-by-example/)
* [Rommel Martinez - A Gentle Introduction to the Nix Family]
(https://web.archive.org/web/20210121042658/https://ebzzry.io/en/nix/#nix)
* [Nix Manual - Nix expression language](https://nixos.org/nix/manual/#ch-expression-language)
* [James Fisher - Nix by example - Part 1: The Nix expression language](https://medium.com/@MrJamesFisher/nix-by-example-a0063a1a4c55)
* [Susan Potter - Nix Cookbook - Nix By Example](https://ops.functionalalgebra.com/nix-by-example/)
* [Zero to Nix - Nix Tutorial](https://zero-to-nix.com/)
* [Rommel Martinez - A Gentle Introduction to the Nix Family](https://web.archive.org/web/20210121042658/https://ebzzry.io/en/nix/#nix)

View File

@ -1,6 +1,6 @@
---
category: tool
tool: OpenCV
category: framework
framework: OpenCV
filename: learnopencv-de.py
contributors:
- ["Yogesh Ojha", "http://github.com/yogeshojha"]
@ -8,21 +8,20 @@ translators:
- ["Dennis Keller", "https://github.com/denniskeller"]
lang: de-de
---
### Opencv
OpenCV (Open Source Computer Vision) ist eine Bibliothek von Programmierfunktionen,
OpenCV (Open Source Computer Vision) ist eine Bibliothek von Programmierfunktionen,
die hauptsächlich auf maschinelles Sehen in Echtzeit ausgerichtet ist.
Ursprünglich wurde OpenCV von Intel entwickelt. Später wurde es von von
Ursprünglich wurde OpenCV von Intel entwickelt. Später wurde es von
Willow Garage und dann Itseez (das später von Intel übernommen wurde) unterstützt.
OpenCV unterstützt derzeit eine Vielzahl von Sprachen, wie C++, Python, Java uvm.
#### Installation
Bitte lese diese Artikel für die Installation von OpenCV auf deinen Computer.
Bitte lies diesen Artikel für die Installation von OpenCV auf deinem Computer.
* Windows Installationsanleitung: [https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.html#install-opencv-python-in-windows]()
* Mac Installationsanleitung (High Sierra): [https://medium.com/@nuwanprabhath/installing-opencv-in-macos-high-sierra-for-python-3-89c79f0a246a]()
* Linux Installationsanleitung (Ubuntu 18.04): [https://www.pyimagesearch.com/2018/05/28/ubuntu-18-04-how-to-install-opencv]()
* [Windows Installationsanleitung](https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_setup/py_setup_in_windows/py_setup_in_windows.html#install-opencv-python-in-windows)
* [Mac Installationsanleitung](https://medium.com/@nuwanprabhath/installing-opencv-in-macos-high-sierra-for-python-3-89c79f0a246a) (High Sierra)
* [Linux Installationsanleitung](https://www.pyimagesearch.com/2018/05/28/ubuntu-18-04-how-to-install-opencv) (Ubuntu 18.04)
### Hier werden wir uns auf die Pythonimplementierung von OpenCV konzentrieren.
@ -33,28 +32,28 @@ img = cv2.imread('Katze.jpg')
# Bild darstellen
# Die imshow() Funktion wird verwendet um das Display darzustellen.
cv2.imshow('Image',img)
cv2.imshow('Image', img)
# Das erste Argument ist der Titel des Fensters und der zweite Parameter ist das Bild
# Wenn du den Fehler Object Type None bekommst ist eventuell dein Bildpfad falsch.
# Wenn du den Fehler Object Type None bekommst, ist eventuell dein Bildpfad falsch.
# Bitte überprüfe dann den Pfad des Bildes erneut.
cv2.waitKey(0)
# waitKey() ist eine Tastaturbindungsfunktion, sie nimmt Argumente in
# waitKey() ist eine Tastaturbindungsfunktion, sie nimmt Argumente in
# Millisekunden an. Für GUI Ereignisse MUSST du die waitKey() Funktion verwenden.
# Ein Bild schreiben
cv2.imwrite('graueKatze.png',img)
# Das erste Arkument ist der Dateiname und das Zweite ist das Bild
cv2.imwrite('graueKatze.png', img)
# Das erste Argument ist der Dateiname und das zweite ist das Bild
# Konveriere das Bild zu Graustufen
# Konvertiert das Bild zu Graustufen
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Videoaufnahme von der Webcam
cap = cv2.VideoCapture(0)
# 0 ist deine Kamera, wenn du mehrere Kameras hast musst du deren Id eingeben
while(True):
while True:
# Erfassen von Einzelbildern
_, frame = cap.read()
cv2.imshow('Frame',frame)
cv2.imshow('Frame', frame)
# Wenn der Benutzer q drückt -> beenden
if cv2.waitKey(1) & 0xFF == ord('q'):
break
@ -63,59 +62,60 @@ cap.release()
# Wiedergabe von Videos aus einer Datei
cap = cv2.VideoCapture('film.mp4')
while(cap.isOpened()):
while cap.isOpened():
_, frame = cap.read()
# Das Video in Graustufen abspielen
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame',gray)
cv2.imshow('frame', gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
# Zeichne eine Linie in OpenCV
# cv2.line(img,(x,y),(x1,y1),(color->r,g,b->0 to 255),thickness)
cv2.line(img,(0,0),(511,511),(255,0,0),5)
# cv2.line(img, (x,y), (x1,y1), (color->r,g,b->0 to 255), thickness)
cv2.line(img, (0, 0), (511, 511), (255, 0, 0), 5)
# Zeichne ein Rechteck
# cv2.rectangle(img,(x,y),(x1,y1),(color->r,g,b->0 to 255),thickness)
# cv2.rectangle(img, (x,y), (x1,y1), (color->r,g,b->0 to 255), thickness)
# thickness = -1 wird zum Füllen des Rechtecks verwendet
cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)
cv2.rectangle(img, (384, 0), (510, 128), (0, 255, 0), 3)
# Zeichne ein Kreis
cv2.circle(img,(xCenter,yCenter), radius, (color->r,g,b->0 to 255), thickness)
cv2.circle(img,(200,90), 100, (0,0,255), -1)
# cv2.circle(img, (xCenter,yCenter), radius, (color->r,g,b->0 to 255), thickness)
cv2.circle(img, (200, 90), 100, (0, 0, 255), -1)
# Zeichne eine Ellipse
cv2.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
cv2.ellipse(img, (256, 256), (100, 50), 0, 0, 180, 255, -1)
# Text auf Bildern hinzufügen
cv2.putText(img,"Hello World!!!", (x,y), cv2.FONT_HERSHEY_SIMPLEX, 2, 255)
cv2.putText(img, "Hello World!!!", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 2, 255)
# Bilder zusammenfüggen
# Bilder zusammenfügen
img1 = cv2.imread('Katze.png')
img2 = cv2.imread('openCV.jpg')
dst = cv2.addWeighted(img1,0.5,img2,0.5,0)
dst = cv2.addWeighted(img1, 0.5, img2, 0.5, 0)
# Schwellwertbild
# Binäre Schwellenwerte
_,thresImg = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
# Anpassbare Schwellenwerte
adapThres = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,2)
_, thresImg = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# Anpassbare Schwellenwerte
adapThres = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
# Weichzeichnung von einem Bild
# Gausßscher Weichzeichner
blur = cv2.GaussianBlur(img,(5,5),0)
# Gaußscher Weichzeichner
blur = cv2.GaussianBlur(img, (5, 5), 0)
# Rangordnungsfilter
medianBlur = cv2.medianBlur(img,5)
medianBlur = cv2.medianBlur(img, 5)
# Canny-Algorithmus
img = cv2.imread('Katze.jpg',0)
edges = cv2.Canny(img,100,200)
img = cv2.imread('Katze.jpg', 0)
edges = cv2.Canny(img, 100, 200)
# Gesichtserkennung mit Haarkaskaden
# Lade die Haarkaskaden von https://github.com/opencv/opencv/blob/master/data/haarcascades/ herunter
import cv2
import numpy as np
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
@ -123,31 +123,32 @@ img = cv2.imread('Mensch.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
aces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]
for x, y, w, h in faces:
cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
roi_gray = gray[y : y + h, x : x + w]
roi_color = img[y : y + h, x : x + w]
eyes = eye_cascade.detectMultiScale(roi_gray)
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
for ex, ey, ew, eh in eyes:
cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)
cv2.imshow('img',img)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# destroyAllWindows() zerstört alle Fenster
# Wenn du ein bestimmtes Fenter zerstören möchtest musst du den genauen Namen des
# Wenn du ein bestimmtes Fenster zerstören möchtest, musst du den genauen Namen des
# von dir erstellten Fensters übergeben.
```
### Weiterführende Literatur:
* Lade Kaskade hier herunter [https://github.com/opencv/opencv/blob/master/data/haarcascades]()
* OpenCV Zeichenfunktionen [https://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html]()
* Eine aktuelle Sprachenreferenz kann hier gefunden werden [https://opencv.org]()
* Zusätzliche Ressourcen können hier gefunden werden [https://en.wikipedia.org/wiki/OpenCV]()
* Lade Kaskade hier herunter [https://github.com/opencv/opencv/blob/master/data/haarcascades](https://github.com/opencv/opencv/blob/master/data/haarcascades)
* OpenCV Zeichenfunktionen [https://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html](https://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html)
* Eine aktuelle Sprachenreferenz kann hier gefunden werden [https://opencv.org](https://opencv.org)
* Zusätzliche Ressourcen können hier gefunden werden [https://en.wikipedia.org/wiki/OpenCV](https://en.wikipedia.org/wiki/OpenCV)
* Gute OpenCV Tutorials
* [https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html]()
* [https://realpython.com/python-opencv-color-spaces]()
* [https://pyimagesearch.com]()
* [https://www.learnopencv.com]()
* [https://docs.opencv.org/master/]()
* [https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html](https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html)
* [https://realpython.com/python-opencv-color-spaces](https://realpython.com/python-opencv-color-spaces)
* [https://pyimagesearch.com](https://pyimagesearch.com)
* [https://www.learnopencv.com](https://www.learnopencv.com)
* [https://docs.opencv.org/master/](https://docs.opencv.org/master/)

View File

@ -34,7 +34,7 @@ Manche Beispiele sind von <http://learnxinyminutes.com/docs/racket/>.
;; Funktionsapplikationen werden so geschrieben: (f x y z ...)
;; Dabei ist f eine Funktion und x, y, z sind die Operatoren.
;; Wenn du eine Literalliste von Daten erstelllen möchtest,
;; Wenn du eine Literalliste von Daten erstellen möchtest,
;; verwende (quote) um zu verhindern, dass sie ausgewertet zu werden.
(quote (+ 1 2)) ; => (+ 1 2)
;; Nun einige arithmetische Operationen
@ -74,7 +74,7 @@ false ; for Falsch
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 2. Variablen
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Du kannst Variablen setzen indem du (set) verwedest
;; Du kannst Variablen setzen indem du (set) verwendest
;; eine Variable kann alle Zeichen besitzen außer: ();#"
(set some-var 5) ; => 5
some-var ; => 5
@ -92,7 +92,7 @@ some-var ; => 5
;;; Listen
;; Listen sind Vektrorartige Datenstrukturen. (Zufälliger Zugriff ist O(1).
;; Listen sind Vektorartige Datenstrukturen. (Zufälliger Zugriff ist O(1).
(cons 1 (cons 2 (cons 3 (list)))) ; => (1 2 3)
;; 'list' ist ein komfortabler variadischer Konstruktor für Listen
(list 1 2 3) ; => (1 2 3)
@ -196,5 +196,5 @@ a ; => (3 2)
(infix 1 + 2 (infix 3 * 4)) ; => 15
;; Makros sind nicht hygenisch, Du kannst bestehende Variablen überschreiben!
;; Sie sind Codetransformationenen.
;; Sie sind Codetransformationen.
```

View File

@ -10,7 +10,7 @@ lang: de-de
Perl ist eine sehr mächtige, funktionsreiche Programmiersprache mit über 25 Jahren Entwicklungsgeschichte.
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 läuft auf über 100 Plattformen 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.
@ -30,8 +30,8 @@ Perl läuft auf über 100 Platformen von portablen Geräten bis hin zu Mainframe
my $animal = "camel";
my $answer = 42;
# Scalare Werte könnne Zeichenketten, Ganzzahlen und Gleitkomma-Zahlen sein.
# Perl convertiert automatisch zwischen diesen Werten wenn nötig.
# Scalare Werte können Zeichenketten, Ganzzahlen und Gleitkomma-Zahlen sein.
# Perl konvertiert automatisch zwischen diesen Werten wenn nötig.
## Arrays
# Ein Array repräsentiert eine Liste von Werten:
@ -42,7 +42,7 @@ my @mixed = ("camel", 42, 1.23);
## Hashes
# Ein Hash representiert ein Set von Schlüssel/Wert Paaren:
# Ein Hash repräsentiert ein Set von Schlüssel/Wert Paaren:
my %fruit_color = ("apple", "red", "banana", "yellow");
@ -55,7 +55,7 @@ my %fruit_color = (
# Scalare, Arrays und Hashes sind in perldata sehr genau dokumentiert.
# (perldoc perldata)
# Komplexere Daten-Typen können mit hilfe von Referenzen konstruiert werden.
# Komplexere Daten-Typen können mithilfe von Referenzen konstruiert werden.
# Dies erlaubt das erstellen von Listen und Hashes in Listen und Hashes.
#### Bedingte Ausführungs- und Schleifen-Konstrukte.
@ -157,7 +157,7 @@ logger("We have a logger subroutine!");
#### Verwenden von Perl Modulen
Perl Module liefern eine Menge an Funktionen die dabei Helfen das Rad nicht neu erfinden zu müssen. Perl Module können von CPAN (http://www.cpan.org/) heruntergeladen werden. Einige populäre Module sind in der Perl Distribution selbst bereits enthalten.
Perl Module liefern eine Menge an Funktionen die dabei Helfen das Rad nicht neu erfinden zu müssen. Perl Module können von [CPAN](http://www.cpan.org/) heruntergeladen werden. Einige populäre Module sind in der Perl Distribution selbst bereits enthalten.
Perlfaq enthält Fragen und Antworten zu häufig vorkommenden Aufgaben. Sehr oft sind auch Vorschläge enthalten welches CPAN module am besten geeignet ist.

View File

@ -34,7 +34,7 @@ offiziellen IDE, damit die Programme kompiliert und ausgeführt werden können.
/*
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.
Mehrzeilige Kommentare werden wie hier umschlossen.
*/
/* -------------------------------------------------
@ -59,7 +59,7 @@ size(width, height, [renderer]); // bestimme die Canvasgröße mit dem optionale
// 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
// Wenn du möchtest, dass der 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.
@ -107,7 +107,7 @@ double doubleValue = 1.12345D // Double (64-Bit Gleitkommazahl)
// lediglich die wichtigsten durch.
// String
// Während der Datentyp `char` einfache Anzührungszeichen (' ') braucht, haben
// Während der Datentyp `char` einfache Anführungszeichen (' ') braucht, haben
// Strings doppelte Anführungszeichen (" ").
String sampleString = "Hallo, Processing!";
// Strings können auch durch ein Array von `char`s erstellt werden.
@ -137,11 +137,11 @@ ArrayList<Integer> intArrayList = new ArrayList<Integer>();
// 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.
// Selbstverständlich muss eine Klasse definiert werden, bevor du ein Objekt
// davon instanziieren kannst.
// Format: ClassName InstanceName
SomeRandomClass myObject // hier musst du das Objekt später instazieren
// Hier wird das Objekt direkt instanziert:
SomeRandomClass myObject // hier musst du das Objekt später instanziieren
// Hier wird das Objekt direkt instanziiert:
SomeRandomClass myObjectInstantiated = new SomeRandomClass();
// Processing hat noch weitere Collections (wie zum Beispiel Dictionaries und
@ -255,7 +255,6 @@ Da du nun die Grundsätze der Programmiersprache verstanden hast, schauen wir
uns nun das Beste an Processing an - Das Zeichnen!
```
/* -------------------------------------------------
Figuren
-------------------------------------------------
@ -349,7 +348,7 @@ sphere(radius); // Die Größe wird definiert durch den Parameter `radius`
-------------------------------------------------
*/
// Tranformationen sind nützlich, um ständig zu wissen, wo die Koordinaten und
// Transformationen 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
@ -363,7 +362,7 @@ 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.
rotate(angle); // Rotiere, um den Betrag, welcher spezifiziert wurde.
// Es gibt drei Pendants im dreidimensionalen Raum.
// Namentlich sind dies: `rotateX(angle)`, `rotateY(angle)` und `rotateZ(angle)`
@ -406,7 +405,7 @@ Wenn du weitere Dinge mit Processing kennenlernen willst, dann gibt es unzählig
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.
Dokumentation.
```
// Bevor wir weiterfahren, werde ich einige Aspekte zum Importieren von
@ -432,7 +431,7 @@ 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
// Disclaimer: Ich habe das Programm nicht selbst geschrieben. 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)
@ -483,7 +482,7 @@ void branch(float len) {
}
```
Processing ist einfach zu erlernen und ist vorallem nützlich, um Multimedia-
Processing ist einfach zu erlernen und ist vor allem 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.

View File

@ -8,16 +8,12 @@ translators:
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
@ -88,10 +84,10 @@ div(class=meineKlasse)
//- 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>
div(style=meineStile)
//- <div style="color:white;background-color:blue;"></div>
//- JS Attributte
//- JS Attribute
- const meineAttribute = {"src": "foto.png", "alt": "meine Bilder"}
img&attributes(meineAttribute)
//- <img src="foto.png" alt="meine Bilder">
@ -162,13 +158,13 @@ case bestellungsStatus
//- <p class="warn">Deine Bestellung steht noch aus</p>
//- --INCLUDE--
//- File path -> "includes/nav.png"
//- File path -> "includes/nav.pug"
h1 Firmenname
nav
a(href="index.html") Home
a(href="about.html") Über uns
//- Dateipfad -> "index.png"
//- Dateipfad -> "index.pug"
html
body
include includes/nav.pug
@ -198,11 +194,10 @@ mixin comment(name, kommentar)
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)
- [GitHub Repo](https://github.com/pugjs/pug)

View File

@ -1,6 +1,6 @@
---
category: tool
tool: PyQT
category: framework
framework: PyQT
filename: learnpyqt-de.py
contributors:
- ["Nathan Hughes", "https://github.com/sirsharpest"]
@ -9,19 +9,19 @@ translators:
lang: de-de
---
**Qt** ist eine weit bekanntes Framework mit den man plattformunabhängige Programme schreiben kann,
die auf verschiedenen Sotfware und Hardware Plattformen laufen mit kleinen oder keinen Änderungen im Code.
Dabei besitzen sie trozdem die Power und Geschwindigkeit von nativen Anwendungen.
**Qt** ist ein weit bekanntes Framework, mit dem man plattformunabhängige Programme schreiben kann,
die auf verschiedenen Software- und Hardwareplattformen laufen, mit kleinen oder keinen Änderungen im Code.
Dabei besitzen sie trotzdem die Power und Geschwindigkeit von nativen Anwendungen.
**Qt** wurde ursprünglich in *C++** geschrieben.
Das ist eine Adaption von dem C++ Intro für QT von [Aleksey Kholovchuk](https://github.com/vortexxx192),
manche der Codebeispiele sollte in der selben Funktionalität resultieren.
manche der Codebeispiele sollten in derselben Funktionalität resultieren.
Diese Version wurde in pyqt erstellt.
```python
import sys
from PyQt4 import QtGui
def window():
# Erschafft ein Anwendungsobjekt.
app = QtGui.QApplication(sys.argv)
@ -31,7 +31,7 @@ def window():
b = QtGui.QLabel(w)
# Setzt einen Text für das Label.
b.setText("Hello World!")
# Setzt die Größe und die Platzierungsinfomationen.
# Setzt die Größe und die Platzierungsinformationen.
w.setGeometry(100, 100, 200, 50)
b.move(50, 20)
# Setzt unserem Fenster einen schönen Titel.
@ -43,15 +43,14 @@ def window():
if __name__ == '__main__':
window()
```
Damit wir weitere fortgeschrittene Funktionen in **pyqt** verwenden können,
müssen wir anfangen zusätzliche Elemente zu bauen.
Hier zeigen wir wie man eine Dialog Popup Box einführt.
Diese ist nützlich, um den Benutzer eine Entscheidung zu bestätigen oder um Informationen anzuzeigen.
Hier zeigen wir wie man eine Dialog Popup Box einführt.
Diese ist nützlich, um dem Benutzer eine Entscheidung zu bestätigen oder Informationen anzuzeigen.
```Python
```python
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
@ -70,9 +69,9 @@ def window():
w.setWindowTitle("PyQt Dialog")
w.show()
sys.exit(app.exec_())
# Diese Funktion soll ein Dialogfenster mit einem Knopf erschaffen.
# Der Knopf wartet bis er geklickt wird und beendet das Programm
# Der Knopf wartet, bis er geklickt wird, und beendet das Programm.
def showdialog():
d = QDialog()
b1 = QPushButton("ok", d)
@ -80,7 +79,7 @@ def showdialog():
d.setWindowTitle("Dialog")
# Diese Modalität sagt dem Popup, dass es den Parent blocken soll, solange es aktiv ist.
d.setWindowModality(Qt.ApplicationModal)
# Beim klicken möchte ich, dass der gesamte Prozess beendet wird.
# Beim Klicken möchte ich, dass der gesamte Prozess beendet wird.
b1.clicked.connect(sys.exit)
d.exec_()

View File

@ -12,13 +12,10 @@ lang: de-de
Anmerkungen des ursprünglichen Autors:
Python wurde in den frühen Neunzigern von Guido van Rossum entworfen. Es ist heute eine der beliebtesten Sprachen. Ich habe mich in Python wegen seiner syntaktischen Übersichtlichkeit verliebt. Eigentlich ist es ausführbarer Pseudocode.
Feedback ist herzlich willkommen! Ihr erreicht mich unter [@louiedinh](http://twitter.com/louiedinh) oder louiedinh [at] [google's email service].
Hinweis: Dieser Beitrag bezieht sich implizit auf Python 3. Falls du lieber Python 2.7 lernen möchtest, schau [hier](http://learnxinyminutes.com/docs/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
@ -104,7 +101,7 @@ False or True #=> True
# Strings können auch addiert werden! Vermeide dies aber lieber.
"Hallo " + "Welt!" #=> "Hallo Welt!"
# Strings können ohne "+" addiert werden
"Hallo " "welt!" # => "Hallo Welt!"
"Hallo " "Welt!" # => "Hallo Welt!"
# Ein String kann wie eine Liste von Zeichen verwendet werden
"Das ist ein String"[0] #=> 'D'
@ -113,13 +110,13 @@ False or True #=> True
"{} 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"
"{0} mag Spaghetti, {0} liebt es zu Schwimmen und ganz besonders mag {0} {1}".format("Hans", "Blattsalat")
#=> "Hans mag Spaghetti, Hans liebt es zu Schwimmen und ganz besonders mag Hans Blattsalat"
# Die Formatierung kann auch mit `f-strings` oder formattierten Strings gemacht
# Die Formatierung kann auch mit `f-strings` oder formatierten Strings gemacht
# werden (ab Python 3.6+)
name = "Sandra"
f"Sie hat gesagt, ihr name sei {name}." # => Sie hat gesagt, ihr Name sei 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.
@ -224,7 +221,7 @@ 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
# Dictionarys (Wörterbücher) speichern Schlüssel-Werte-Paare
empty_dict = {}
# Hier ein gefülltes Wörterbuch
filled_dict = {"one": 1, "two": 2, "three": 3}
@ -245,7 +242,7 @@ list(filled_dict.values()) #=> [3, 2, 1]
"one" in filled_dict #=> True
1 in filled_dict #=> False
# Einen nicht vorhandenenen Schlüssel zu suchen, löst einen KeyError aus
# Einen nicht vorhandenen Schlüssel zu suchen, löst einen KeyError aus
filled_dict["four"] # KeyError
# Mit der get-Methode verhindern wir das
@ -264,7 +261,7 @@ 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"
del filled_dict["one"] # Entfernt den Schlüssel "one"
# Sets speichern Mengen
empty_set = set()
@ -623,7 +620,6 @@ def say(say_please=False):
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?
@ -635,8 +631,7 @@ print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(
* [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)
* [Hitchhiker's Guide to Python](http://docs.python-guide.org/)
* [Python Course](http://www.python-course.eu/index.php)
* [First Steps With Python](https://realpython.com/learn/python-first-steps/)

View File

@ -11,8 +11,6 @@ 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
@ -194,7 +192,7 @@ d, e, f = 4, 5, 6
e, d = d, e # d is now 5 and e is now 4
# Dictionarys (Wörterbucher) speichern Key-Value-Paare
# Dictionarys (Wörterbücher) speichern Key-Value-Paare
empty_dict = {}
# Hier ein gefülltes Wörterbuch
filled_dict = {"one": 1, "two": 2, "three": 3}
@ -215,7 +213,7 @@ filled_dict.values() #=> [3, 2, 1]
"one" in filled_dict #=> True
1 in filled_dict #=> False
# Einen nicht vorhandenenen Schlüssel zu suchen, löst einen KeyError aus
# Einen nicht vorhandenen Schlüssel zu suchen, löst einen KeyError aus
filled_dict["four"] # KeyError
# Mit der get-Methode verhindern wir das
@ -745,7 +743,6 @@ def say(say_please=False):
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?

View File

@ -1,6 +1,6 @@
---
category: tool
tool: Qt Framework
category: framework
framework: Qt Framework
language: C++
filename: learnqt-de.cpp
contributors:
@ -10,9 +10,9 @@ translators:
lang: de-de
---
**Qt** ist ein weithin bekanntes Framework zum Entwickeln von cross-platform Software,
die auf verschiedenen Hard- und Softwareplatformen mit wenig oder keinen Veränderungen im Code läuft.
Dabei besitzt man die Power und Geschiwindigkeit von nativen Anwendungen.
**Qt** ist ein weithin bekanntes Framework zum Entwickeln von Cross-Platform Software,
die auf verschiedenen Hard- und Softwareplattformen mit wenig oder keinen Veränderungen im Code läuft.
Dabei besitzt man die Power und Geschwindigkeit von nativen Anwendungen.
Obwohl **Qt** ursprünglich in *C++* geschrieben wurde,
gibt es verschiedene Ports für andere Sprachen: *[PyQt](https://learnxinyminutes.com/docs/pyqt/)*, *QtRuby*, *PHP-Qt*, etc.
@ -29,7 +29,7 @@ Dieses Tutorial zeigt, wie man das in *C++* macht.
#include <QLineEdit>
int main(int argc, char *argv[]) {
// Erstellt ein Objekt um applikationsweit die Resourcen zu managen.
// Erstellt ein Objekt um applikationsweit die Ressourcen zu managen.
QApplication app(argc, argv);
// Erstellt ein Line edit Widget und zeigt es auf dem Bildschirm
@ -41,7 +41,7 @@ int main(int argc, char *argv[]) {
}
```
Die GUI bezogene Teile von **Qt** bestehen aus *Widgets* und den *Verbindungen*
Die GUI-bezogene Teile von **Qt** bestehen aus *Widgets* und den *Verbindungen*
dazwischen.
[Lies mehr über Widgets](http://doc.qt.io/qt-5/qtwidgets-index.html)
@ -66,7 +66,7 @@ int main(int argc, char *argv[]) {
QDialog dialogWindow;
dialogWindow.show();
// Füge ein vertikales Layout hinzu
// Füge ein vertikales Layout hinzu.
QVBoxLayout layout;
dialogWindow.setLayout(&layout);
@ -101,7 +101,7 @@ Als Nächstes lernen wir, dass wir nicht nur Standard Widgets verwenden können,
sondern auch ihr Verhalten mithilfe von Vererbung verändern können.
Lass uns einen Button erschaffen, der zählt, wie häufig er gedrückt wird.
Dafür definieren wir unsere eigene Klasse *CounterLabel*.
Diese muss wegen der speziellen Qt Architektur in einer seperaten Datei deklariert werden.
Diese muss wegen der speziellen Qt Architektur in einer separaten Datei deklariert werden.
```c++
// counterlabel.hpp
@ -164,10 +164,10 @@ int main(int argc, char *argv[]) {
}
```
Das wars! Natürlich ist das Qt Framework erheblich größer, als der der Teil der in diesem Tutorial behandelt wurde.
Das wars! Natürlich ist das Qt Framework erheblich größer als der Teil, der in diesem Tutorial behandelt wurde.
Das heißt, es gibt viel zu lesen und zu üben.
## Further reading
## Weitere Informationen
- [Qt 4.8 tutorials](http://doc.qt.io/qt-4.8/tutorials.html)
- [Qt 5 tutorials](http://doc.qt.io/qt-5/qtexamplesandtutorials.html)

View File

@ -10,39 +10,36 @@ lang: de-de
---
RST ist ein Dateiformat, das von der Python Community entwickelt wurde,
um Dokumentation zu schreiben (und ist somit Teil von Docutils).
RST-Dateien sind simple Textdateien mit einer leichtgewichtigen Syntax (im Vergleich zu HTML).
um Dokumentation zu schreiben (und ist somit Teil von Docutils).
RST-Dateien sind simple Textdateien mit einer leichtgewichtigen Syntax (im
Vergleich zu HTML).
## Installation
Um Restructured Text zu vewenden musst du [Python](http://www.python.org)
installieren und das `docutils` Packet installieren. `docutils` kann mit dem folgenden
Befehl auf der Kommandozeile installiert werden:
Um Restructured Text zu verwenden, musst du [Python](http://www.python.org)
installieren und das `docutils` Paket installieren. `docutils` kann mit dem
folgenden Befehl auf der Kommandozeile installiert werden:
```bash
$ easy_install docutils
easy_install docutils
```
Wenn auf deinem System `pip` installiert kannst du es statdessen auch verwenden:
Ebenso kann die Installation mit `pip`
```bash
$ pip install docutils
pip install docutils
```
initiiert werden.
## Dateisyntax
Ein einfaches Beispiel für die Dateisyntax:
```
.. Zeilen, die mit zwei Punkten starten sind spezielle Befehle.
.. Zeilen, die mit zwei Punkten starten sind spezielle Befehle.
.. Wenn kein Befehl gefunden wird, wird die Zeile als Kommentar gewertet.
.. Wenn kein Befehl gefunden wird, wird die Zeile als Kommentar gewertet.
============================================================================
Haupttitel werden mit Gleichheitszeichen darüber und darunter gekennzeichnet
@ -57,7 +54,7 @@ Titel werden auch mit Gleichheitszeichen unterstrichen
Untertitel werden mit Strichen gekennzeichnet
---------------------------------------------
Text in *kursiv* oder in **fett**. Du kannst Text als Code "makieren", wenn
Text in *kursiv* oder in **fett**. Du kannst Text als Code "markieren", wenn
du doppelte Backquotes verwendest ``: ``print()``.
Listen sind so einfach wie in Markdown:
@ -75,43 +72,47 @@ oder
Tabellen sind einfach zu schreiben:
=========== ==========
Land Hauptstadt
Land Hauptstadt
=========== ==========
Frankreich Paris
Japan Tokyo
=========== ========
Komplexere Tabellen (zusammengeführte Spalten und Zeilen) können einfach
erstellt werden, aber ich empfehle dir dafür die komplette Dokumentation zu lesen :)
Komplexere Tabellen (zusammengeführte Spalten und Zeilen) können einfach
erstellt werden, aber ich empfehle dir dafür die komplette Dokumentation zu
lesen :)
Es gibt mehrere Möglichkeiten um Links zu machen:
- Wenn man einen Unterstrich hinter einem Wort hinzufügt: Github_ Zusätzlich
muss man die Zielurl nach dem Text hinzufügen.
- Wenn man einen Unterstrich hinter einem Wort hinzufügt: GitHub_ Zusätzlich
muss man die Zielurl nach dem Text hinzufügen.
(Dies hat den Vorteil, dass man keine unnötigen Urls in lesbaren Text einfügt.
- Wenn man die vollständige Url eingibt : https://github.com/
- Wenn man die vollständige Url eingibt: https://github.com/
(Dies wird automatisch in ein Link konvertiert.)
- Wenn man es mehr Markdown ähnlich eingibt: `Github <https://github.com/>`_ .
.. _Github https://github.com/
- Wenn man es mehr Markdown ähnlich eingibt: `GitHub <https://github.com/>`_ .
.. _GitHub https://github.com/
```
## Wie man es verwendet
RST kommt mit docutils, dort hast du den Befehl `rst2html`, zum Beispiel:
Mit der Installation von [docutils](https://docutils.sourceforge.io/) bietet
sich beispielsweise die Umwandlung zu html (mehrere Standards stehen zur
Auswahl) an:
```bash
$ rst2html myfile.rst output.html
rst2html myfile.rst output.html
```
*Anmerkung : Auf manchen Systemen könnte es rst2html.py sein*
*Anmerkung: Auf manchen Systemen könnte es `rst2html.py` sein.*
Es gibt komplexere Anwendungen, die das RST Format verwenden:
Weitere Exporte bieten beispielsweise `rst2latex`, `rst2man`, `rst2odt`,
`rst2pdf` und `rst2xml`.
- [Pelican](http://blog.getpelican.com/), ein statischer Websitengenerator
- [Sphinx](http://sphinx-doc.org/), Ein Dokumentationsgenerator
Es gibt komplexere Anwendungen, die das RST Format verwenden:
- [Pelican](http://blog.getpelican.com/), ein statischer Webseitengenerator
- [Sphinx](http://sphinx-doc.org/), ein Dokumentationsgenerator
- und viele Andere
## Zum Lesen

View File

@ -75,7 +75,7 @@ nil.class #=> NilClass
true.class #=> TrueClass
false.class #=> FalseClass
# Gleicheit
# Gleichheit
1 == 1 #=> true
2 == 1 #=> false
@ -190,7 +190,7 @@ array = [1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5]
# Array können verschiedene Typen beinhalten
[1, 'hello', false] #=> [1, "hello", false]
## Arrays könnenindiziert werden.
## Arrays können indiziert werden.
# Von vorne...
array[0] #=> 1
@ -207,8 +207,8 @@ array[2, 3] #=> [3, 4, 5]
# ...oder mit einem Range...
array[1..3] #=> [2, 3, 4]
# Du kanns ein Array umkehren.
# Gib ein neues Array mit umgkehrten Werten zurück
# Du kannst ein Array umkehren.
# Gib ein neues Array mit umgekehrten Werten zurück
[1,2,3].reverse #=> [3,2,1]
# Kehre ein Array an Ort und Stelle um, um die Variable mit den
@ -257,7 +257,7 @@ hash.value?(3) #=> true
# Tipp: Arrays und Hashes sind Enumerables!
# Sie haben viele nützliche Methoden gemein, wie each, map, count, und andere.
# Kontrolstrukturen
# Kontrollstrukturen
# Bedingungen
if true
@ -427,7 +427,7 @@ surround { puts 'hallo Welt' }
# Blocks können in ein 'Proc' Objekt umgewandelt werden.
# Dieses ist eine Art Container um den Block und erlaubt ihn an eine
# andere Methode zu übergeben, ihn in einen anderen Gültigkeitsbereicht
# andere Methode zu übergeben, ihn in einen anderen Gültigkeitsbereich
# einzubinden oder ihn andersweitig zu verändern.
# Am häufigsten findet man dies bei Parameterlisten von Methoden, in Form
# eines letzten '&block' Parameters, der den Block wenn es einen gibt
@ -487,7 +487,7 @@ best *ranked_competitors
# Wenn ein Methodenname mit einem Ausrufezeichen endet, dann tut diese Methode
# per Konvention etwas Destruktives, wie z.B. das aufrufende Objekt zu
# verändern.
# Viele Mehtoden haben eine !-Version um eine direkte Änderung zu machen und
# Viele Methoden haben eine !-Version um eine direkte Änderung zu machen und
# eine Nicht-!-Version, die ein neues Objekt mit den Veränderungen zurück gibt.
company_name = "Dunder Mifflin"
company_name.upcase #=> "DUNDER MIFFLIN"

View File

@ -72,7 +72,7 @@ Am ausgereiftesten und stabilsten:
* [MRI](https://github.com/ruby/ruby) - Geschrieben in C, das ist die Referenz Implementierung.
Sie ist 100% kompatibel (mit sich selbst ;-). Alle anderen rubies
bleiben kompatibel mit MRI (siehe [RubySpec](#rubyspec) weiter unten).
bleiben kompatibel mit MRI (siehe [Ruby Spec](#ruby-spec) weiter unten).
* [JRuby](http://jruby.org/) - Geschrieben in Java and Ruby, Robust und ziemlich schnell.
Der größte Vorteil von JRuby ist die Interoperabilität mit JVM/Java und damit die
Benutzung von Ruby im Java Ecosystem.
@ -91,16 +91,16 @@ Weniger ausgereift/kompatibel:
* [Topaz](http://topazruby.com/) - Geschrieben in RPython (via PyPy)
Topaz ist noch ziemlich jung und versucht die schnellste Implementierung
zu werden.
* [IronRuby](http://ironruby.net/) - Geschrieben in C# für die .NET Plaftform
* [IronRuby](http://ironruby.net/) - Geschrieben in C# für die .NET Plattform
Das letzte Release von IronRuby ist mittlerweile 5 Jahre her.
Die Ruby Implementierungen haben ihre eigenen Versionsnummern, sind aber
trotzdem immer zu einer MRI Version kompatibel.
Viele können sogar zwischen verschiedenen Modi wechseln (1.8 mode -> 1.9 mode)
## RubySpec
## Ruby Spec
Die meisten Ruby Implementierungen vertrauen der [RubySpec](http://rubyspec.org/).
Die meisten Ruby Implementierungen vertrauen der [Ruby Spec](https://github.com/ruby/spec).
sehr stark. Da Ruby keine offizielle Spezifikation hat, hat die
Community ausführbare Specs (in Ruby) geschrieben, um so die Kompatibilität
zur MRI testen zu können.

View File

@ -11,7 +11,7 @@ filename: lernerust-de.rs
Rust ist eine Programmiersprache von Mozilla Research.
Rust vereint Sicherheit, Nebenläufigkeit und eine hohe Praxistauglichkeit.
Sicherheit bedeuted, dass Programmierfehler ausgeschlossen werden, die zu
Sicherheit bedeutet, dass Programmierfehler ausgeschlossen werden, die zu
Speicherzugriffsfehlern führen könnten. Das funktioniert u.a. dadurch, dass
es keinen Garbage Collector gibt, sondern ein besonderes Typsystem.
@ -21,8 +21,8 @@ entwickelt, dass es einfach keine stabile gab und geraten wurde den
nightly build zu nutzen.
Am 15. Mai 2015 wurde Rust 1.0 freigegeben, und zwar mit der Garantie einer
Abwärtskompatabilität. Verbesserungen der Kompilierzeit und andere Compiler
verbesserungen finden im Moment im nightly build statt. Von Rust gibt es im
Abwärtskompatibilität. Verbesserungen der Kompilierzeit und andere Compiler
Verbesserungen finden im Moment im nightly build statt. Von Rust gibt es im
Moment ungefähr alle sechs Wochen ein Release. Rust 1.1 beta wurde zusammen
mit dem 1.0 Release zur Verfügung gestellt.

View File

@ -19,8 +19,6 @@ Wenn du bereits mit CSS3 vertraut bist, wirst du dir Sass relativ schnell aneign
```scss
//Einzeilige Kommentare werden entfernt, wenn Sass zu CSS kompiliert wird.
/* Mehrzeilige Kommentare bleiben bestehen. */
@ -427,7 +425,6 @@ body {
.gutter {
width: 6.25%;
}
```
## SASS oder Sass?
@ -442,7 +439,7 @@ Du kannst beide Syntax-Optionen benutzen, gehe einfach in die Einstellungen und
Sass kann in jedem Projekt verwendet werden, solange du ein Programm hast, um es in CSS zu kompilieren.
Du solltest verifizieren, dass das CSS, was du verwendest, mit deinen Ziel-Browsern kompatibel ist.
[QuirksMode CSS](http://www.quirksmode.org/css/) und [CanIUse](http://caniuse.com) sind gute Resourcen um die Kompatibilät zu überpüfen.
[QuirksMode CSS](http://www.quirksmode.org/css/) und [CanIUse](http://caniuse.com) sind gute Resourcen um die Kompatibilität zu überprüfen.
## Literaturhinweise

View File

@ -307,7 +307,7 @@ do {
// Endrekursionen sind idiomatisch um sich wiederholende
// Aufgaben in Scala zu lösen. Rekursive Funtionen benötigen explizit einen
// Aufgaben in Scala zu lösen. Rekursive Funktionen benötigen explizit einen
// Rückgabe-Typ, der Compiler kann ihn nicht erraten.
// Der Rückgabe-Typ in diesem Beispiel ist Unit:
@ -457,7 +457,7 @@ class Dackel extends Hund {
}
// Object
// Wird ein Objekt ohne das Schlüsselwort "new" instanziert, wird das sog.
// Wird ein Objekt ohne das Schlüsselwort "new" instanziiert, wird das sog.
// "companion object" aufgerufen. Mit dem "object" Schlüsselwort wird so
// ein Objekt (Typ UND Singleton) erstellt. Damit kann man dann eine Klasse
// verwenden, ohne ein Objekt instanziieren zu müssen.
@ -634,10 +634,10 @@ val patternFunc: Person => String = {
// 7. "Higher-order"-Funktionen
/////////////////////////////////////////////////
// Scala erlaubt, dass Methoden und Funktionen wiederum Funtionen und Methoden
// Scala erlaubt, dass Methoden und Funktionen wiederum Funktionen und Methoden
// als Aufrufparameter oder Rückgabewert verwenden. Diese Methoden heißen
// higher-order functions.
// Es gibt zahlreiche higher-order-Funtionen nicht nur für Listen, auch für
// Es gibt zahlreiche higher-order-Funktionen nicht nur für Listen, auch für
// die meisten anderen Collection-Typen, sowie andere Klassen in Scala.
// Nennenswerte sind:
// "filter", "map", "reduce", "foldLeft"/"foldRight", "exists", "forall"
@ -796,7 +796,7 @@ import scala.collection.immutable.{List, Map}
import scala.collection.immutable.{List => ImmutableList}
// Importiere alle Klasses, mit Ausnahem von....
// Importiere alle Klassen, mit Ausnahme von....
// Hier ohne: Map and Set:
import scala.collection.immutable.{Map => _, Set => _, _}
@ -824,7 +824,6 @@ val writer = new PrintWriter("myfile.txt")
writer.write("Schreibe Zeile" + util.Properties.lineSeparator)
writer.write("Und noch eine Zeile" + util.Properties.lineSeparator)
writer.close()
```
## Weiterführende Hinweise

View File

@ -1,7 +1,7 @@
---
category: tool
category: framework
filename: learnshutit-de.html
tool: ShutIt
framework: ShutIt
contributors:
- ["Ian Miell", "http://ian.meirionconsulting.tk"]
translators:
@ -22,10 +22,9 @@ Es ist verfügbar als pip install.
## Hello World
Starten wir mit dem einfachsten Beispiel. Erstelle eine Datei names example.py
Starten wir mit dem einfachsten Beispiel. Erstelle eine Datei namens example.py
```python
import shutit
session = shutit.create_session('bash')
session.send('echo Hello World', echo=True)
@ -50,7 +49,7 @@ Ians-MacBook-Air.local:ORIGIN_ENV:RhuebR2T#
Das erste Argument zu 'send' ist der Befehl, den du ausführen möchtest.
Das 'echo' Argument gibt die Terminalinteraktion aus. ShuIt ist standardmäßig leise.
'Send' kümmert sich um die nervige Arbeiten mit den Prompts und macht
'Send' kümmert sich um die nervigen Arbeiten mit den Prompts und macht
alles was du von 'expect' erwarten würdest.
@ -79,7 +78,7 @@ example.com:cgoIsdVv:heDa77HB#
```
Es ist klar das das nicht sicher ist. Stattdessen kann man Folgendes machen:
Es ist klar, dass das nicht sicher ist. Stattdessen kann man Folgendes machen:
```python
import shutit
@ -149,8 +148,8 @@ two.example.com:Gl2lldEo:D3FavQjA#
## Beispiel: Überwachen mehrerer Server
Wir können das obige Programm in ein einfaches Überwachungstool bringen indem
wir Logik hinzufügen um die Ausgabe von einem Befehl zu betrachten.
Wir können das obige Programm in ein einfaches Überwachungstool bringen, indem
wir Logik hinzufügen, um die Ausgabe von einem Befehl zu betrachten.
```python
import shutit
@ -171,11 +170,11 @@ session1.logout()
session2.logout()
```
Hier kannst du die 'send\_and\_get\_output' Methode verwenden um die Ausgabe von dem
Hier kannst du die 'send\_and\_get\_output' Methode verwenden, um die Ausgabe von dem
Kapazitätsbefehl (df) zu erhalten.
Es gibt elegantere Wege als oben (z.B. kannst du ein Dictionary verwenden um über
die Server zu iterieren), aber es hängt and dir wie clever das Python sein muss.
Es gibt elegantere Wege als oben (z.B. kannst du ein Dictionary verwenden, um über
die Server zu iterieren), aber es hängt an dir wie clever das Python sein muss.
## kompliziertere IO - Expecting
@ -232,7 +231,7 @@ der Ausgabecode dich nicht interessiert.
Wenn du das Argument nicht mitgegeben hättest, dann hätte dir ShutIt
ein interaktives Terminal zurückgegeben, falls es ein Terminal zum
kommunizieren gibt. Dies nennt sich ein 'Pause point'.
Kommunizieren gibt. Dies nennt sich ein 'Pause point'.
## Pause Points
@ -247,7 +246,7 @@ session.pause_point('Das ist ein pause point')
Danach kannst du das Skript fortführen, wenn du CTRL und ']' zur selben Zeit drückst.
Dies ist gut für Debugging: Füge ein Pause Point hinzu und schaue dich um.
Danach kannst du das Programm weiter ausführen. Probiere folgendes aus:
Danach kannst du das Programm weiter ausführen. Probiere Folgendes aus:
```python
import shutit
@ -276,10 +275,10 @@ Ians-Air.home:ORIGIN_ENV:I00LA1Mq#
## noch kompliziertere IO - Hintergrund
Kehren wir zu unseren Beispiel mit dem Überwachen von mehreren Servern zurück.
Kehren wir zu unserem Beispiel mit dem Überwachen von mehreren Servern zurück.
Stellen wir uns vor, dass wir eine langlaufende Aufgabe auf jedem Server durchführen möchten.
Standardmäßig arbeitet ShutIt seriell, was sehr lange dauern würde.
Wir können jedoch die Aufgaben im Hintergrund laufen lassen um sie zu beschleunigen.
Wir können jedoch die Aufgaben im Hintergrund laufen lassen, um sie zu beschleunigen.
Hier ist ein Beispiel, welches du ausprobieren kannst.
Es verwendet den trivialen Befehl: 'sleep'.
@ -323,8 +322,8 @@ Um mehr zu erfahren, siehe:
[ShutIt](https://ianmiell.github.io/shutit/)
[GitHub](https://github.com/ianmiell/shutit/blob/master/README.md)
Es handelt sich um ein breiteres Automatiesierungsframework, und das oben
genannte ist der sogennante 'standalone Modus'.
Es handelt sich um ein breiteres Automatisierungsframework, und das oben
genannte ist der sogenannte 'standalone Modus'.
Feedback, feature requests, 'Wie mache ich es' sind herzlich willkommen! Erreiche mit unter
[@ianmiell](https://twitter.com/ianmiell)

116
de-de/sql-de.html.markdown Normal file
View File

@ -0,0 +1,116 @@
---
language: SQL
filename: learnsql-de.sql
contributors:
- ["Bob DuCharme", "http://bobdc.com/"]
translators:
- ["denniskeller", "https://github.com/denniskeller"]
lang: de-de
---
Die Structured Query Language (SQL) ist eine ISO Standardsprache zum Erstellen und Arbeiten mit Datenbanken, die in einem Set von Tabellen gespeichert sind. Implementierungen fügen in der Regel eigene Erweiterungen zur Sprache hinzu; [Der Vergleich von verschiedenen SQL Implementierungen](http://troels.arvin.dk/db/rdbms/) ist eine gute Referenz für Produktunterschiede.
Implementierungen bieten typischerweise eine Eingabeaufforderung, in den du die hier gezeigten Befehle interaktiv eingeben kannst. Sie bieten auch einen Weg, um Serien von Befehlen in einer Skript auszuführen. (Die Anzeige, dass du fertig mit der interaktiven Eingabeaufforderung bist, ist ein gutes Beispiel für etwas, was nicht standardisiert ist. Die meisten SQL Implementierungen unterstützen die Schlüsselwörter QUIT, EXIT oder beides.
Einige dieser Beispielbefehle gehen davon aus, dass sie die [MySQL employee sample database](https://dev.mysql.com/doc/employee/en/), verfügbar auf [GitHub](https://github.com/datacharmer/test_db), schon geladen wurde. Die GitHub Dateien sind Skripte von Befehlen, ähnlich wie die entsprechenden Befehle unten, die Tabellen mit Daten über die Mitarbeiter einer fiktiven Firma erstellen und füllen. Die Syntax für die Ausführung dieser Skripte hängt von der verwendeten SQL-Implementierung ab. Ein Dienstprogramm, das man über die Betriebssystemeingabeaufforderung ausführen kann, ist typisch.
```sql
-- Kommentare starten mit zwei Bindestrichen. Jeder Befehl endet mit einem Semikolon.
-- SQL unterscheidet nicht zwischen Groß- und Kleinschreibung bei
-- Schlüsselwörtern. Die Beispielbefehle folgen der Konvention der
-- Schreibweise in Großbuchstaben, damit sie leichter von Datenbank-,
-- Tabellen- und Spaltennamen zu unterscheiden sind.
-- Erstellen und Löschen einer Datenbank. Bei Datenbank- und Tabellennamen
-- wird zwischen Groß- und Kleinschreibung unterschieden.
CREATE DATABASE someDatabase;
DROP DATABASE someDatabase;
-- Liste verfügbare Datenbanken.
SHOW DATABASES;
-- Verwende eine bestimmte Datenbank.
USE employees;
-- Wähle alle Zeilen und Spalten aus der Tabelle departmens aus der aktuellen
-- Datenbank aus.
-- Das Standardverhalten für den Interpreter ist die Ergebnisse auf
-- dem Bildschirm zu scrollen.
SELECT * FROM departments;
-- Hole dir alle Zeilen aus der departments Tabelle,
-- aber nur die dept_no und die dept_name Spalten.
-- Das Aufteilen von Befehlen auf mehrere Zeilen ist in Ordnung.
SELECT dept_no,
dept_name FROM departments;
-- Hole dir alle departments Spalten, aber nur 5 Zeilen.
SELECT * FROM departments LIMIT 5;
-- Hole dir die dept_name Spaltenwerte aus der departments Tabelle,
-- in der der Wert dept_name die Teilzeichenfolge 'en' hat.
SELECT dept_name FROM departments WHERE dept_name LIKE '%en%';
-- Hole dir alle Spalten von der departments Tabelle, in der die dept_name
-- Spalte mit einem 'S' beginnt und exakt 4 Zeichen danach besitzt.
SELECT * FROM departments WHERE dept_name LIKE 'S____';
-- Wähle die Titelwerte aus der Titeltabelle, aber zeige keine Duplikate an.
SELECT DISTINCT title FROM titles;
-- Das Gleiche wie oben, aber sortiert nach den Titelwerten, mit Beachtung
-- der Groß und Kleinschreibung.
SELECT DISTINCT title FROM titles ORDER BY title;
-- Zeige die Anzahl der Zeilen in der departments Tabelle an.
SELECT COUNT(*) FROM departments;
-- Zeige die Anzahl der Zeilen in der departments Tabelle an, die 'en' als
-- Teilezeichenkette des Wertes dept_name haben.
SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%';
-- Eine Vereinigung von Informationen von mehreren Tabellen:
-- Die titles Tabelle zeigt, wer welche Jobtitel hatte, wer welche Mitarbeiter-
-- nummer hat, von welchen Startdatum und zu welchen Enddatum
-- Wir rufen diese Information ab, aber anstelle der Mitarbeiternummer,
-- verwenden wir die Mitarbeiternummer als Querverweis auf die employees Tabelle
-- um die die Vor- und Nachnamen jedes Mitarbeiters zu erhalten.
-- (und nur 10 Reihen)
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;
-- Liste alle Tabellen in allen Datenbanken auf. Verschiedene Implementierungen
-- stellen typischerweise einen eigenen Abkürzungsbefehl zur Verfügung für
-- die aktuell verwendete Datenbank.
SELECT * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE='BASE TABLE';
-- Erstelle eine Tabelle in der aktuell verwendeten Datenbank
-- mit dem Namen tablename1, in der die beiden Spalten angezeigt werden
-- Es gibt viele weiteren Optionen, wie man die Spalten spezifizieren kann,
-- wie z.B. deren Datentyp.
CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20));
-- Füge eine Zeile mit Daten in die Tabelle tablename1. Dies setzt voraus,
-- das die Tabelle so definiert worden ist, dass sie die geeigneten
-- Werte akzeptiert.
INSERT INTO tablename1 VALUES('Richard','Mutt');
-- Verändere den fname Wert zu 'John' für alle Zeilen,
-- die einen lname Wert von 'Mutt' haben.
UPDATE tablename1 SET fname='John' WHERE lname='Mutt';
-- Lösche Zeilen aus der tablename1 Tabelle,
-- deren lname Wert mit dem Wert 'M' beginnen.
DELETE FROM tablename1 WHERE lname like 'M%';
-- Lösche alle Zeilen von der tablename1 Tabelle, hinterlasse nur eine leere
-- Tabelle.
DELETE FROM tablename1;
-- Lösche die gesamte tablename1 Tabelle.
DROP TABLE tablename1;
```

View File

@ -13,7 +13,7 @@ lang: de-de
Swift ist eine Programmiersprache von Apple für die Entwicklung von iOS und macOS Applikationen. Swift wurde 2014 zu Apples WWDC Entwicklerkonferenz vorgestellt und wurde mit dem Ziel entwickelt, fehlerträchtigen Code zu vermeiden sowie mit Objective-C zu koexistieren. Es wird mit dem LLVM Compiler gebaut und ist ab Xcode 6+ verfügbar.
Das offizielle [Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329) Buch von Apple ist kostenlos via iBooks verfügbar.
Das offizielle [Swift Programming Language](https://itunes.apple.com/us/book/swift-programming-language/id881256329) Buch von Apple ist kostenlos via Apple Books verfügbar.
Außerdem hilfreich ist Apples [Getting Started Guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/RoadMapiOS/index.html), ein guter Einstiegspunkt mit komplettem Swift-Tutorial.
@ -210,7 +210,7 @@ default: // notwendig (um alle möglichen Eingaben zu verarbeiten)
:param: name Ein Name
:param: day Ein Tag
:returns: Ein String, der Name und Tag beinhält.
:returns: Ein String, der Name und Tag enthält.
*/
func greet(name: String, day: String) -> String {
return "Hello \(name), today is \(day)."
@ -585,7 +585,7 @@ prefix func !!! (inout shape: Square) -> Square {
// Aktueller Wert
print(mySquare.sideLength) // 4
// Wert nach verwendung des eigenen Operators
// Wert nach Verwendung des eigenen Operators
!!!mySquare
print(mySquare.sideLength) // 12
```

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