12^(1/3) + 3sqrt(2) / (sin(.5) - cos(pi/4)*log(3)) + exp(5)
136.43732662344087
Dieses Kapitel soll beim ‘Loslegen’ helfen. Es läßt viele Details weg und die Codebeispiele sind oft eher suboptimal.
Berechne \(\qquad 12^{1/3} + \frac{3\sqrt{2}}{\sin(0.5)-\cos(\frac{\pi}{4})\log(3)}+ e^5\)
12^(1/3) + 3sqrt(2) / (sin(.5) - cos(pi/4)*log(3)) + exp(5)
136.43732662344087
Man beachte:
a^b
.pi
ist vordefiniert.log()
ist der natürliche Logarithmus.a*b
kann nach einer Zahl weggelassen werden, wenn eine Variable, Funktion oder Klammer folgt.Tab
und ?
Man drücke beim Programmieren immer wieder die Tabulatortaste, sobald 2…3 Buchstaben eines Wortes getippt sind. Es werden dann mögliche Ergänzungen angezeigt bzw. ergänzt, wenn die Ergänzung eindeutig ist. Das spart Zeit und bildet ungemein:
▷ Tab lo
log
log2
lock
log1p
log10
local
logrange
lowercase
load_path
lowercasefirst
locate_package
▷ Tab pri
print
println
printstyled
primitive type
Die eingebaute Julia-Hilfe ?name
zu allen Funktionen und Konstrukten ist sehr umfassend. Hier ein eher kurzes Beispiel:
for ?
search: for nor xor floor foldr Core sort
for
for
loops repeatedly evaluate a block of statements while iterating over a sequence of values.
The iteration variable is always a new variable, even if a variable of the same name exists in the enclosing scope. Use outer
to reuse an existing local variable for iteration.
julia> for i in [1, 4, 0]
println(i)
end
1
4
0
Variablen entstehen durch Zuweisung (assignment) mit dem Zuweisungsoperator =
. Danach können sie in weiteren Anweisungen verwendet werden.
= 1 + sqrt(5)
x = x / 2 y
1.618033988749895
Im interaktiven Betrieb zeigt Julia das Ergebnis der letzten Operation an.
Zuweisungen sind keine mathematischen Gleichungen. Die Semantik des Zuweisungsoperators (Gleichheitszeichens) ist:
Ausdrücke wie x + y = sin(2)
sind daher unzulässig. Links darf nur ein Variablenname stehen.
Julia ist eine stark typisierte Sprache. Alle Objekte haben einen Typ. So gibt es unter anderem die Basistypen
Den Typ einer Variablen kann man mit der Funktion typeof()
ermitteln.
for x ∈ (42, 12.0, 3.3e4, "Hallo!", true)
println("x = ", x, " ..... Typ: ", typeof(x))
end
x = 42 ..... Typ: Int64
x = 12.0 ..... Typ: Float64
x = 33000.0 ..... Typ: Float64
x = Hallo! ..... Typ: String
x = true ..... Typ: Bool
Die Standard-Gleitkommazahl hat eine Länge von 64 Bit, entspricht also einer double
in C/C++/Java.
Julia ist eine dynamisch typisierte Sprache. Variablen haben keinen Typ. Sie sind typlose Referenzen (Zeiger) auf Objekte. Wenn man vom „Typ einer Variablen“ spricht, meint man den Typ des Objektes, das der Variablen gerade zugewiesen ist.
= sqrt(2)
x
println( typeof(x), " - Wert von x = $x" )
= "Jetzt bin ich keine Gleitkommazahl mehr!"
x
println( typeof(x), " - Wert von x = $x" )
Float64 - Wert von x = 1.4142135623730951
String - Wert von x = Jetzt bin ich keine Gleitkommazahl mehr!
Die Funktion println()
unterscheidet sich von print()
dadurch, dass sie am Ende einen Zeilenvorschub ausgibt.
print(y)
print("...die Zeile geht weiter...")
print("immernoch...")
println(y)
println("Neue Zeile")
println("Neue Zeile")
1.618033988749895...die Zeile geht weiter...immernoch...1.618033988749895
Neue Zeile
Neue Zeile
Beide Funkionen können als Argument eine Liste von strings und Variablen bekommen. Man kann Variablen auch in strings einbetten, indem man dem Variablennamen ein Dollarzeichen voranstellt (string interpolation).
= 23
x = 3x + 5
y = "Fertig!"
zz println("x= ", x, " ...und y= ", y, "...", zz) # 1. Variante
println("x= $x ...und y= $y...$zz") # Variante mit string interpolation
x= 23 ...und y= 74...Fertig!
x= 23 ...und y= 74...Fertig!
Funktionsdefinitionen beginnen mit dem Schlüsselwort function
und enden mit dem Schlüsselwort end
. In der Regel haben sie eine oder mehrere Argumente und geben beim Aufruf ein berechnetes Objekt mit der return
-Anweisung zurück.
function hypotenuse(a, b) # heute besonders umständlich
= a^2 + b^2
c2 = sqrt(c2)
c return c
end
hypotenuse (generic function with 1 method)
Nach ihrer Definition kann die Funktion benutzt (aufgerufen) werden. Die in der Definition verwendeten Variablen a,b,c,c2
sind lokale Variablen und stehen außerhalb der Funktionsdefinition nicht zur Verfügung.
= 3
x = hypotenuse(x, 4)
z println("z = $z")
println("c = $c")
z = 5.0
UndefVarError: `c` not defined in `Main.Notebook`
Suggestion: check for spelling errors or missing imports.
Stacktrace:
[1] top-level scope
@ ~/Julia/23/Book-ansipatch/chapters/first_contact.qmd:206
Sehr einfache Funktionen können auch als Einzeiler definiert werden.
hypotenuse(a, b) = sqrt(a^2+b^2)
hypotenuse (generic function with 1 method)
Tests liefern einen Wahrheitswert zurück.
= 3^2
x < 2^3 x
false
Neben den üblichen arithmetischen Vergleichen ==, !=, <, <= ,> ,>=
gibt es noch viele andere Tests. Natürlich kann man das Ergebnis eines Tests auch einer Variablen zuweisen, welche dann vom Typ Bool
ist. Die logischen Operatoren &&
, ||
und Negation !
können in Tests verwendet werden.
= "Auto" in ["Fahrrad", "Auto", "Bahn"]
test1 = x == 100 || !(x <= 30 && x > 8)
test2 = startswith("Lampenschirm", "Lamp")
test3 println("$test1 $test2 $test3")
true false true
Verzweigungen (bedingte Anweisungen) haben die Form
if <Test>
<Anweisung1>
<Anweisung2>
... end
Ein else
-Zweig und elseif
-Zweige sind möglich.
= sqrt(100)
x
if x > 20
println("Seltsam!")
else
println("OK")
= x + 3
y end
OK
13.0
Einrückungen verbessern die Lesbarkeit, sind aber fakultativ. Zeilenumbrüche trennen Anweisungen. Das ist auch durch Semikolon möglich. Obiger Codeblock ist für Julia identisch zu folgender Zeile:
# Bitte nicht so programmieren! Sie werden es bereuen!
=sqrt(100); if x > 20 println("Seltsam!") else println("OK"); y = x + 3 end x
OK
13.0
Es wird dringend empfohlen, von Anfang an den eigenen Code übersichtlich mit sauberen Einrückungen zu formatieren!
for
-Schleifenzum wiederholten Abarbeiten von Anweisungen haben die Form
for <Zähler> = Start:Ende
<Anweisung1>
<Anweisung2>
... end
Beispiel:
= 0
sum for i = 1:100
= sum + i
sum end
sum
5050
1-dimensionale Arrays (Vektoren) sind eine einfache Form von Containern. Man kann sie mit echigen Klammern anlegen und auf die Elemente per Index zugreifen. Die Indizierung beginnt mit 1.
= [12, 33.2, 17, 19, 22] v
5-element Vector{Float64}:
12.0
33.2
17.0
19.0
22.0
typeof(v)
Vector{Float64} (alias for Array{Float64, 1})
1] = v[4] + 10
v[ v
5-element Vector{Float64}:
29.0
33.2
17.0
19.0
22.0
Man kann leere Vektoren anlegen und sie verlängern.
= [] # leerer Vektor
v push!(v, 42)
push!(v, 13)
v
2-element Vector{Any}:
42
13