english translation started
This commit is contained in:
@@ -2,73 +2,65 @@
|
||||
engine: julia
|
||||
---
|
||||
|
||||
```{julia}
|
||||
#| error: false
|
||||
#| echo: false
|
||||
#| output: false
|
||||
using InteractiveUtils
|
||||
```
|
||||
# Containers
|
||||
|
||||
Julia offers a wide selection of container types with largely similar interfaces.
|
||||
We introduce `Tuple`, `Range`, and `Dict` here, and in the next chapter we will cover `Array`, `Vector`, and `Matrix`.
|
||||
|
||||
# Container
|
||||
These containers are:
|
||||
|
||||
Julia bietet eine große Auswahl von Containertypen mit weitgehend ähnlichem Interface an.
|
||||
Wir stellen hier `Tuple`, `Range` und `Dict` vor, im nächsten Kapitel dann `Array`, `Vector` und `Matrix`.
|
||||
|
||||
Diese Container sind:
|
||||
|
||||
- **iterierbar:** Man kann über die Elemente des Containers iterieren:
|
||||
- **iterable:** You can iterate over the elements of the container:
|
||||
```julia
|
||||
for x ∈ container ... end
|
||||
```
|
||||
- **indizierbar:** Man kann auf Elemente über ihren Index zugreifen:
|
||||
- **indexable:** You can access elements via their index:
|
||||
```julia
|
||||
x = container[i]
|
||||
```
|
||||
und einige sind auch
|
||||
```
|
||||
and some are also
|
||||
|
||||
- **mutierbar**: Man kann Elemente hinzufügen, entfernen und ändern.
|
||||
- **mutable:** You can add, remove, and modify elements.
|
||||
|
||||
Weiterhin gibt es eine Reihe gemeinsamer Funktionen, z.B.
|
||||
Furthermore, there are several common functions, e.g.,
|
||||
|
||||
- `length(container)` --- Anzahl der Elemente
|
||||
- `eltype(container)` --- Typ der Elemente
|
||||
- `isempty(container)` --- Test, ob Container leer ist
|
||||
- `empty!(container)` --- leert Container (nur wenn mutierbar)
|
||||
- `length(container)` --- number of elements
|
||||
- `eltype(container)` --- type of elements
|
||||
- `isempty(container)` --- test whether container is empty
|
||||
- `empty!(container)` --- empties container (only if mutable)
|
||||
|
||||
|
||||
## Tupeln
|
||||
## Tuples
|
||||
|
||||
Ein Tupel ist ein nicht mutierbarer Container von Elementen. Es ist also nicht möglich, neue Elemente dazuzufügen oder den Wert eines Elements zu ändern.
|
||||
A tuple is an immutable container of elements. It is therefore not possible to add new elements or change the value of an element.
|
||||
|
||||
|
||||
|
||||
```{julia}
|
||||
t = (33, 4.5, "Hello")
|
||||
|
||||
@show t[2] # indizierbar
|
||||
@show t[2] # indexable
|
||||
|
||||
for i ∈ t println(i) end # iterierbar
|
||||
for i ∈ t println(i) end # iterable
|
||||
```
|
||||
|
||||
Ein Tupel ist ein **inhomogener** Typ. Jedes Element hat seinen eigenen Typ und das zeigt sich auch im Typ des Tupels:
|
||||
A tuple is an **inhomogeneous** type. Each element has its own type, which is reflected in the tuple's type:
|
||||
|
||||
```{julia}
|
||||
typeof(t)
|
||||
```
|
||||
|
||||
|
||||
Man verwendet Tupel gerne als Rückgabewerte von Funktionen, um mehr als ein Objekt zurückzulieferen.
|
||||
Tuples are frequently used as function return values to return more than one object.
|
||||
|
||||
```{julia}
|
||||
# Ganzzahldivision und Rest:
|
||||
# Quotient und Rest werden den Variablen q und r zugewiesen
|
||||
# Integer division and remainder:
|
||||
# quotient and remainder are assigned to variables q and r
|
||||
|
||||
q, r = divrem(71, 6)
|
||||
@show q r;
|
||||
```
|
||||
Wie man hier sieht, kann man in bestimmten Konstrukten die Klammern auch weglassen.
|
||||
Dieses *implict tuple packing/unpacking* verwendet man auch gerne in Mehrfachzuweisungen:
|
||||
As you can see here, parentheses can be omitted in certain constructs.
|
||||
This *implicit tuple packing/unpacking* is also commonly used in multiple assignments:
|
||||
|
||||
|
||||
```{julia}
|
||||
@@ -80,56 +72,59 @@ x, y, z = 12, 17, 203
|
||||
y
|
||||
```
|
||||
|
||||
Manche Funktionen bestehen auf Tupeln als Argument oder geben immer Tupeln zurück. Dann braucht man manchmal ein Tupel aus einem Element.
|
||||
Some functions require tuples as arguments or always return tuples. Then you sometimes need a tuple with a single element.
|
||||
|
||||
Das notiert man so:
|
||||
This is written as:
|
||||
|
||||
```{julia}
|
||||
x = (13,) # ein 1-Element-Tupel
|
||||
x = (13,) # a 1-element tuple
|
||||
```
|
||||
|
||||
Das Komma - und nicht die Klammern -- macht das Tupel.
|
||||
The comma - not the parentheses - makes the tuple.
|
||||
|
||||
```{julia}
|
||||
x= (13) # kein Tupel
|
||||
x= (13) # not a tuple
|
||||
```
|
||||
|
||||
|
||||
## Ranges
|
||||
|
||||
Wir haben *range*-Objekte schon in numerischen `for`-Schleifen verwendet.
|
||||
We have already used *range* objects in numerical `for` loops.
|
||||
|
||||
```{julia}
|
||||
r = 1:1000
|
||||
typeof(r)
|
||||
```
|
||||
Es gibt verschiedene *range*-Typen. Wie man sieht, sind es über den Zahlentyp parametrisierte Typen und `UnitRange` ist z.B. ein *range* mit der Schrittweite 1. Ihre Konstruktoren heißen in der Regel `range()`.
|
||||
There are various *range* types. As you can see, they are parameterized types based on the numeric type, and `UnitRange` is, for example, a *range* with step size 1. Their constructors are usually named `range()`.
|
||||
|
||||
Der Doppelpunkt ist eine spezielle Syntax.
|
||||
The colon is a special syntax.
|
||||
|
||||
- `a:b` wird vom Parser umgesetzt zu `range(a, b)`
|
||||
- `a:b:c` wird umgesetzt zu `range(a, c, step=b)`
|
||||
- `a:b` is parsed as `range(a, b)`
|
||||
- `a:b:c` is parsed as `range(a, c, step=b)`
|
||||
|
||||
|
||||
*Ranges* sind offensichtlich iterierbar, nicht mutierbar aber indizierbar.
|
||||
|
||||
*Ranges* are obviously iterable, not mutable, but indexable.
|
||||
|
||||
```{julia}
|
||||
(3:100)[20] # das zwanzigste Element
|
||||
(3:100)[20] # the 20th element
|
||||
```
|
||||
|
||||
|
||||
|
||||
Wir erinnern an die Semantik der `for`-Schleife: `for i in 1:1000` heißt **nicht**:
|
||||
|
||||
- 'Die Schleifenvariable `i` wird bei jedem Durchlauf um eins erhöht' **sondern**
|
||||
- 'Der Schleifenvariable werden nacheinander die Werte 1,2,3,...,1000 aus dem Container zugewiesen'.
|
||||
Recall the semantics of the `for` loop: `for i in 1:1000` means **not**:
|
||||
|
||||
Allerdings wäre es sehr ineffektiv, diesen Container tatsächlich explizit anzulegen.
|
||||
- 'The loop variable `i` is incremented by one in each iteration' **but rather**
|
||||
- 'The loop variable is successively assigned the values 1,2,3,...,1000 from the container'.
|
||||
|
||||
- _Ranges_ sind "lazy" Vektoren, die nie wirklich irgendwo als konkrete Liste abgespeichert werden. Das macht sie als Iteratoren in `for`-Schleifen so nützlich: speichersparend und schnell.
|
||||
- Sie sind 'Rezepte' oder Generatoren, die auf die Abfrage 'Gib mir dein nächstes Element!' antworten.
|
||||
- Tatsächlich ist der Muttertyp `AbstractRange` ein Subtyp von `AbstractVector`.
|
||||
However, it would be very inefficient to actually create this container explicitly.
|
||||
|
||||
Das Macro `@allocated` gibt aus, wieviel Bytes an Speicher bei der Auswertung eines Ausdrucks alloziert wurden.
|
||||
- _Ranges_ are "lazy" vectors that are never really stored as a concrete list anywhere. This makes them so useful as iterators in `for` loops: memory-efficient and fast.
|
||||
- They are "recipes" or generators that respond to the query "Give me your next element!".
|
||||
- In fact, the supertype `AbstractRange` is a subtype of `AbstractVector`.
|
||||
|
||||
The macro `@allocated` outputs how many bytes of memory were allocated during the evaluation of an expression.
|
||||
|
||||
```{julia}
|
||||
@allocated r = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
|
||||
@@ -142,34 +137,35 @@ Das Macro `@allocated` gibt aus, wieviel Bytes an Speicher bei der Auswertung ei
|
||||
|
||||
|
||||
|
||||
Zum Umwandeln in einen 'richtigen' Vektor dient die Funktion `collect()`.
|
||||
|
||||
The function `collect()` is used to convert to a "real" vector.
|
||||
|
||||
|
||||
```{julia}
|
||||
collect(20:-3:1)
|
||||
```
|
||||
|
||||
Recht nützlich, z.B. beim Vorbereiten von Daten zum Plotten, ist der *range*-Typ `LinRange`.
|
||||
Quite useful, e.g., when preparing data for plotting, is the *range* type `LinRange`.
|
||||
|
||||
```{julia}
|
||||
LinRange(2, 50, 300)
|
||||
```
|
||||
`LinRange(start, stop, n)` erzeugt eine äquidistante Liste von `n` Werten von denen der erste und der letzte die vorgegebenen Grenzen sind.
|
||||
Mit `collect()` kann man bei Bedarf auch daraus den entsprechenden Vektor gewinnen.
|
||||
`LinRange(start, stop, n)` generates an equidistant list of `n` values where the first and last are the specified limits.
|
||||
With `collect()` you can also obtain the corresponding vector if needed.
|
||||
|
||||
|
||||
## Dictionaries
|
||||
|
||||
- _Dictionaries_ (deutsch: "assoziative Liste" oder "Zuordnungstabelle" oder ...) sind spezielle Container.
|
||||
- Einträge in einem Vektor `v` sind durch einen Index 1,2,3.... addressierbar: `v[i]`
|
||||
- Einträge in einem _dictionary_ sind durch allgemeinere _keys_ addressierbar.
|
||||
- Ein _dictionary_ ist eine Ansammlung von _key-value_-Paaren.
|
||||
- Damit haben _dictionaries_ in Julia den parametrisierten Typ `Dict{S,T}`, wobei `S` der Typ der _keys_ und `T` der Typ der _values_ ist
|
||||
- _Dictionaries_ (German: "associative list" or "lookup table" or ...) are special containers.
|
||||
- Entries in a vector `v` are addressable by an index 1,2,3....: `v[i]`
|
||||
- Entries in a _dictionary_ are addressable by more general _keys_.
|
||||
- A _dictionary_ is a collection of _key-value_ pairs.
|
||||
- Thus, _dictionaries_ in Julia have the parameterized type `Dict{S,T}`, where `S` is the type of _keys_ and `T` is the type of _values_.
|
||||
|
||||
|
||||
Man kann sie explizit anlegen:
|
||||
They can be created explicitly:
|
||||
```{julia}
|
||||
# Einwohner 2020 in Millionen, Quelle: wikipedia
|
||||
# Population in 2020 in millions, source: wikipedia
|
||||
|
||||
EW = Dict("Berlin" => 3.66, "Hamburg" => 1.85,
|
||||
"München" => 1.49, "Köln" => 1.08)
|
||||
@@ -180,29 +176,29 @@ EW = Dict("Berlin" => 3.66, "Hamburg" => 1.85,
|
||||
typeof(EW)
|
||||
```
|
||||
|
||||
und mit den _keys_ indizieren:
|
||||
and indexed with the _keys_:
|
||||
|
||||
```{julia}
|
||||
EW["Berlin"]
|
||||
```
|
||||
|
||||
Das Abfragen eines nicht existierenden _keys_ ist natürlich ein Fehler.
|
||||
Of course, querying a non-existent _key_ is an error.
|
||||
```{julia}
|
||||
EW["Leipzig"]
|
||||
```
|
||||
|
||||
Man kann ja auch vorher mal anfragen...
|
||||
You can also ask beforehand...
|
||||
```{julia}
|
||||
haskey(EW, "Leipzig")
|
||||
```
|
||||
|
||||
... oder die Funktion `get(dict, key, default)` benutzen, die bei nicht existierendem Key keinen Fehler wirft sondern das 3. Argument zurückgibt.
|
||||
... or use the function `get(dict, key, default)`, which does not throw an error for non-existent keys but returns the third argument.
|
||||
|
||||
```{julia}
|
||||
@show get(EW, "Leipzig", -1) get(EW, "Berlin", -1);
|
||||
```
|
||||
|
||||
Man kann sich auch alle `keys` und `values` als spezielle Container geben lassen.
|
||||
You can also request all `keys` and `values` as special containers.
|
||||
```{julia}
|
||||
keys(EW)
|
||||
```
|
||||
@@ -213,24 +209,24 @@ values(EW)
|
||||
```
|
||||
|
||||
|
||||
Man kann über die `keys` iterieren...
|
||||
You can iterate over the `keys`...
|
||||
```{julia}
|
||||
for i in keys(EW)
|
||||
n = EW[i]
|
||||
println("Die Stadt $i hat $n Millionen Einwohner.")
|
||||
println("The city $i has $n million inhabitants.")
|
||||
end
|
||||
```
|
||||
|
||||
odere gleich über `key-value`-Paare.
|
||||
or directly over `key-value` pairs.
|
||||
```{julia}
|
||||
for (stadt, ew) ∈ EW
|
||||
println("$stadt : $ew Mill.")
|
||||
println("$stadt : $ew Million.")
|
||||
end
|
||||
```
|
||||
|
||||
### Erweitern und Modifizieren
|
||||
### Extending and Modifying
|
||||
|
||||
Man kann in ein `Dict` zusätzliche `key-value`-Paare eintragen...
|
||||
You can add additional `key-value` pairs to a `Dict`...
|
||||
```{julia}
|
||||
EW["Leipzig"] = 0.52
|
||||
EW["Dresden"] = 0.52
|
||||
@@ -238,42 +234,42 @@ EW
|
||||
```
|
||||
|
||||
|
||||
und einen `value` ändern.
|
||||
and change a `value`.
|
||||
```{julia}
|
||||
# Oh, das war bei Leipzig die Zahl von 2010, nicht 2020
|
||||
# Oh, the Leipzig number was from 2010, not 2020
|
||||
|
||||
EW["Leipzig"] = 0.597
|
||||
EW
|
||||
```
|
||||
|
||||
Ein Paar kann über seinen `key` auch gelöscht werden.
|
||||
A pair can also be deleted via its `key`.
|
||||
```{julia}
|
||||
delete!(EW, "Dresden")
|
||||
```
|
||||
|
||||
Zahlreiche Funktionen können mit `Dicts` wie mit anderen Containern arbeiten.
|
||||
Many functions can work with `Dicts` like with other containers.
|
||||
|
||||
```{julia}
|
||||
maximum(values(EW))
|
||||
```
|
||||
|
||||
### Anlegen eines leeren Dictionaries
|
||||
### Creating an Empty Dictionary
|
||||
|
||||
Ohne Typspezifikation ...
|
||||
Without type specification ...
|
||||
```{julia}
|
||||
d1 = Dict()
|
||||
```
|
||||
|
||||
und mit Typspezifikation:
|
||||
and with type specification:
|
||||
```{julia}
|
||||
d2 = Dict{String, Int}()
|
||||
```
|
||||
|
||||
### Umwandlung in Vektoren: `collect()`
|
||||
### Conversion to Vectors: `collect()`
|
||||
|
||||
- `keys(dict)` und `values(dict)` sind spezielle Datentypen.
|
||||
- Die Funktion `collect()` macht daraus eine Liste vom Typ `Vector`.
|
||||
- `collect(dict)` liefert eine Liste vom Typ `Vector{Pair{S,T}}`
|
||||
- `keys(dict)` and `values(dict)` are special data types.
|
||||
- The function `collect()` converts them to a `Vector` type.
|
||||
- `collect(dict)` returns a list of type `Vector{Pair{S,T}}`
|
||||
|
||||
|
||||
```{julia}
|
||||
@@ -285,55 +281,55 @@ collect(EW)
|
||||
collect(keys(EW)), collect(values(EW))
|
||||
```
|
||||
|
||||
### Geordnetes Iterieren über ein Dictionary
|
||||
### Ordered Iteration over a Dictionary
|
||||
|
||||
Wir sortieren die Keys. Als Strings werden sie alphabetisch sortiert. Mit dem `rev`-Parameter wird rückwärts sortiert.
|
||||
We sort the keys. As strings, they are sorted alphabetically. With the `rev` parameter, sorting is done in reverse order.
|
||||
```{julia}
|
||||
for k in sort(collect(keys(EW)), rev = true)
|
||||
n = EW[k]
|
||||
println("$k hat $n Millionen Einw. ")
|
||||
println("$k has $n million inhabitants ")
|
||||
end
|
||||
```
|
||||
|
||||
Wir sortieren `collect(dict)`. Das ist ein Vektor von Paaren. Mit `by` definieren wir, wonach zu sortieren ist: nach dem 2. Element des Paares.
|
||||
We sort `collect(dict)`. This is a vector of pairs. With `by` we define what to sort by: the second element of the pair.
|
||||
|
||||
```{julia}
|
||||
for (k,v) in sort(collect(EW), by = pair -> last(pair), rev=false)
|
||||
println("$k hat $v Mill. EW")
|
||||
println("$k has $v million inhabitants")
|
||||
end
|
||||
```
|
||||
|
||||
### Eine Anwendung von Dictionaries: Zählen von Häufigkeiten
|
||||
### An Application of Dictionaries: Counting Frequencies
|
||||
|
||||
Wir machen 'experimentelle Stochastik' mit 2 Würfeln:
|
||||
We do "experimental probability" with 2 dice:
|
||||
|
||||
Gegeben sei `l`, eine Liste mit den Ergebnissen von 100 000 Pasch-Würfen, also 100 000 Zahlen zwischen 2 und 12.
|
||||
Given `l`, a list with the results of 100,000 double dice rolls, i.e., 100,000 numbers between 2 and 12.
|
||||
|
||||
Wie häufig sind die Zahlen 2 bis 12?
|
||||
How frequently do the numbers 2 to 12 occur?
|
||||
|
||||
|
||||
Wir (lassen) würfeln:
|
||||
We (let) roll:
|
||||
|
||||
```{julia}
|
||||
|
||||
l = rand(1:6, 100_000) .+ rand(1:6, 100_000)
|
||||
```
|
||||
|
||||
Wir zählen mit Hilfe eines Dictionaries die Häufigkeiten der Ereignisse. Dazu nehmen wir das Ereignis als `key` und seine Häufigkeit als `value`.
|
||||
We count the frequencies of the events using a dictionary. We take the event as the `key` and its frequency as the `value`.
|
||||
```{julia}
|
||||
# In diesem Fall könnte man das auch mit einem einfachen Vektor
|
||||
# lösen. Eine bessere Illustration wäre z.B. Worthäufigkeit in
|
||||
# einem Text. Dann ist i keine ganze Zahl sondern ein Wort=String
|
||||
# In this case, one could also solve this with a simple vector.
|
||||
# A better illustration would be, e.g., word frequency in
|
||||
# a text. Then i is not an integer but a word=string
|
||||
|
||||
d = Dict{Int,Int}() # das Dict zum 'reinzählen'
|
||||
d = Dict{Int,Int}() # the dict for counting
|
||||
|
||||
for i in l # für jedes i wird d[i] erhöht.
|
||||
for i in l # for each i, d[i] is incremented.
|
||||
d[i] = get(d, i, 0) + 1
|
||||
end
|
||||
d
|
||||
```
|
||||
|
||||
Das Ergebnis:
|
||||
The result:
|
||||
|
||||
```{julia}
|
||||
using Plots
|
||||
@@ -341,7 +337,6 @@ using Plots
|
||||
plot(collect(keys(d)), collect(values(d)), seriestype=:scatter)
|
||||
```
|
||||
|
||||
##### Das Erklär-Bild dazu:
|
||||
##### The explanatory image:
|
||||
|
||||
[https://math.stackexchange.com/questions/1204396/why-is-the-sum-of-the-rolls-of-two-dices-a-binomial-distribution-what-is-define](https://math.stackexchange.com/questions/1204396/why-is-the-sum-of-the-rolls-of-two-dices-a-binomial-distribution-what-is-define)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user