629 lines
15 KiB
Plaintext
629 lines
15 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "e009ef80",
|
|
"metadata": {},
|
|
"source": [
|
|
"# First Contact\n",
|
|
"\n",
|
|
"Dieses Kapitel soll beim 'Loslegen' helfen. Es läßt viele Details weg und die Codebeispiele sind oft eher suboptimal. \n",
|
|
"\n",
|
|
"\n",
|
|
"## Julia als Taschenrechner\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "b488cb23",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"#| eval: true\n",
|
|
"#| echo: false\n",
|
|
"#| output: false\n",
|
|
"\n",
|
|
"using REPL, Markdown\n",
|
|
"\n",
|
|
"function mhelp(s,n,m)\n",
|
|
" helptxt = Core.eval(Main, REPL.helpmode(s))\n",
|
|
" helpstr=Markdown.plaininline(helptxt)\n",
|
|
" print(\"...\\n\", join(split(helpstr,'\\n')[n:m],'\\n'), \"\\n...\")\n",
|
|
"end;\n",
|
|
"\n",
|
|
"function Tab(s)\n",
|
|
" l = filter(x->startswith(x,s), REPL.doc_completions(s))\n",
|
|
" println.(l[2:end])\n",
|
|
" return # return nothing, since broadcast println produces empty vector\n",
|
|
"end\n",
|
|
"\n",
|
|
"▷ = |>\n",
|
|
"\n",
|
|
"# IJulia.set_verbose(true)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "76000398",
|
|
"metadata": {},
|
|
"source": [
|
|
"Berechne $\\qquad 12^{1/3} + \\frac{3\\sqrt{2}}{\\sin(0.5)-\\cos(\\frac{\\pi}{4})\\log(3)}+ e^5$\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "0f9feb86",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"12^(1/3) + 3sqrt(2) / (sin(.5) - cos(pi/4)*log(3)) + exp(5)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "3e9fad84",
|
|
"metadata": {},
|
|
"source": [
|
|
"Man beachte:\n",
|
|
"\n",
|
|
"- Potenzen schreibt man `a^b`.\n",
|
|
"- Die Konstante `pi` ist vordefiniert.\n",
|
|
"- `log()` ist der natürliche Logarithmus.\n",
|
|
"- Das Multiplikationszeichen `a*b` kann nach einer Zahl weggelassen werden, wenn eine Variable, Funktion oder Klammer folgt.\n",
|
|
"\n",
|
|
"\n",
|
|
"## Die wichtigsten Tasten: `Tab` und `?`\n",
|
|
"\n",
|
|
"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:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "734300ba",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"lo = \"lo\" #| hide_line\n",
|
|
"lo ▷ Tab"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "155bc575",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"pri = \"pri\" #| hide_line\n",
|
|
"pri ▷ Tab"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "ba74dc32",
|
|
"metadata": {},
|
|
"source": [
|
|
"Die eingebaute Julia-Hilfe `?name` zu allen Funktionen und Konstrukten ist sehr umfassend. Hier ein eher kurzes Beispiel: \n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "1b941a97",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"?for"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "c8f7da7b",
|
|
"metadata": {},
|
|
"source": [
|
|
":::{.content-hidden unless-format=\"xxx\"}\n",
|
|
"\n",
|
|
"::: {.cell }\n",
|
|
"``` {.julia .cell-code}\n",
|
|
"?for\n",
|
|
"```\n",
|
|
"\n",
|
|
"::: {.cell-output .cell-output-stdout}\n",
|
|
"```\n",
|
|
"search: for foreach foldr floor mapfoldr factorial EOFError OverflowError\n",
|
|
"\n",
|
|
"for loops repeatedly evaluate a block of statements while iterating over a sequence of values.\n",
|
|
"\n",
|
|
"Examples\n",
|
|
"\n",
|
|
"julia> for i in [1, 4, 0]\n",
|
|
" println(i)\n",
|
|
" end\n",
|
|
"1\n",
|
|
"4\n",
|
|
"0\n",
|
|
"\n",
|
|
"```\n",
|
|
":::\n",
|
|
":::\n",
|
|
":::\n",
|
|
"\n",
|
|
"\n",
|
|
"## Variablen und Zuweisungen\n",
|
|
"\n",
|
|
"Variablen entstehen durch Zuweisung *(assignment)* mit dem Zuweisungsoperator `=` . Danach können sie in weiteren Anweisungen verwendet werden.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "da1dc7ec",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"x = 1 + sqrt(5) \n",
|
|
"y = x / 2"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "37b29541",
|
|
"metadata": {},
|
|
"source": [
|
|
"Im interaktiven Betrieb zeigt Julia das Ergebnis der letzten Operation an.\n",
|
|
"\n",
|
|
":::{.callout-note .titlenormal}\n",
|
|
"Zuweisungen sind keine mathematischen Gleichungen. Die Semantik des Zuweisungsoperators (Gleichheitszeichens) ist: \n",
|
|
"\n",
|
|
"- berechne die rechte Seite und\n",
|
|
"- weise das Ergebnis der linken Seite zu.\n",
|
|
"\n",
|
|
"Ausdrücke wie `x + y = sin(2)` sind daher unzulässig. Links darf nur ein Variablenname stehen.\n",
|
|
":::\n",
|
|
"\n",
|
|
"\n",
|
|
"## Datentypen\n",
|
|
"\n",
|
|
"Julia ist eine [stark typisierte](https://de.wikipedia.org/wiki/Starke_Typisierung) Sprache. Alle Objekte haben einen Typ. \n",
|
|
"So gibt es unter anderem die Basistypen \n",
|
|
"\n",
|
|
"- Ganze Zahlen *(integers)*,\n",
|
|
"- Gleitkommazahlen *(floating point numbers)*,\n",
|
|
"- Zeichenketten *(strings)* und \n",
|
|
"- Wahrheitswerte *(booleans)*.\n",
|
|
"\n",
|
|
"Den Typ einer Variablen kann man mit der Funktion `typeof()` ermitteln. \n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "173f7324",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"#| warning: true\n",
|
|
"#| error: true\n",
|
|
"for x ∈ (42, 12.0, 3.3e4, \"Hallo!\", true)\n",
|
|
" println(\"x = \", x, \" ..... Typ: \", typeof(x))\n",
|
|
"end"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "13a8984f",
|
|
"metadata": {},
|
|
"source": [
|
|
"Die Standard-Gleitkommazahl hat eine Länge von 64 Bit, entspricht also einer `double` in C/C++/Java.\n",
|
|
"\n",
|
|
"Julia ist eine [dynamisch typisierte](https://de.wikipedia.org/wiki/Dynamische_Typisierung) Sprache. \n",
|
|
"Variablen haben keinen Typ. Sie sind typlose Referenzen (Zeiger) auf Objekte. \n",
|
|
"Wenn man vom „Typ einer Variablen“ spricht, meint man den Typ des Objektes, das der Variablen gerade zugewiesen ist. \n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "cd3b3e96",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"x = sqrt(2)\n",
|
|
"\n",
|
|
"println( typeof(x), \" - Wert von x = $x\" )\n",
|
|
"\n",
|
|
"x = \"Jetzt bin ich keine Gleitkommazahl mehr!\"\n",
|
|
"\n",
|
|
"println( typeof(x), \" - Wert von x = $x\" )"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "eae463bf",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Druckanweisungen\n",
|
|
"Die Funktion `println()` unterscheidet sich von `print()` dadurch, dass sie am Ende einen Zeilenvorschub ausgibt.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "df98312b",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"print(y)\n",
|
|
"print(\"...die Zeile geht weiter...\")\n",
|
|
"print(\"immernoch...\")\n",
|
|
"println(y)\n",
|
|
"println(\"Neue Zeile\")\n",
|
|
"println(\"Neue Zeile\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "b74dcb3f",
|
|
"metadata": {},
|
|
"source": [
|
|
"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)*.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "3b76d855",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"x = 23\n",
|
|
"y = 3x + 5\n",
|
|
"zz = \"Fertig!\"\n",
|
|
"println(\"x= \", x, \" ...und y= \", y, \"...\", zz) # 1. Variante\n",
|
|
"println(\"x= $x ...und y= $y...$zz\") # Variante mit string interpolation"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "c06fc5da",
|
|
"metadata": {},
|
|
"source": [
|
|
":::{.callout-note .titlenormal collapse=true icon=false }\n",
|
|
"## Wenn man ein Dollarzeichen drucken will...\n",
|
|
"\n",
|
|
"muss man einen *backslash* voranstellen. Wenn man einen *backslash* drucken will, muss man ihn verdoppeln.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "00a46544",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"println(\"Ein Dollar: 1\\$ und drei backslashs: \\\\\\\\\\\\ \")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "3ba46a2c",
|
|
"metadata": {},
|
|
"source": [
|
|
":::\n",
|
|
"\n",
|
|
"## Funktionen\n",
|
|
"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.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "6e83b8e2",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"function hypotenuse(a, b) # heute besonders umständlich\n",
|
|
" c2 = a^2 + b^2\n",
|
|
" c = sqrt(c2)\n",
|
|
" return c \n",
|
|
"end"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "6ae72d3a",
|
|
"metadata": {},
|
|
"source": [
|
|
"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. \n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "2b68ec32",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"#| error: true\n",
|
|
"x = 3\n",
|
|
"z = hypotenuse(x, 4)\n",
|
|
"println(\"z = $z\")\n",
|
|
"println(\"c = $c\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "d62b25c3",
|
|
"metadata": {},
|
|
"source": [
|
|
"Sehr einfache Funktionen können auch als Einzeiler definiert werden.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "436bf54a",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"hypotenuse(a, b) = sqrt(a^2+b^2)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "13485711",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Tests\n",
|
|
"Tests liefern einen Wahrheitswert zurück. \n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "fbfc37d5",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"x = 3^2\n",
|
|
"x < 2^3"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "d43e3179",
|
|
"metadata": {},
|
|
"source": [
|
|
"Neben den üblichen arithmetischen Vergleichen `==, !=, <, <= ,> ,>=` \n",
|
|
"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. \n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "7e289c8e",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"test1 = \"Auto\" in [\"Fahrrad\", \"Auto\", \"Bahn\"]\n",
|
|
"test2 = x == 100 || !(x <= 30 && x > 8)\n",
|
|
"test3 = startswith(\"Lampenschirm\", \"Lamp\") \n",
|
|
"println(\"$test1 $test2 $test3\")"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "0ca8fc84",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Verzweigungen\n",
|
|
"Verzweigungen (bedingte Anweisungen) haben die Form \n",
|
|
"\n",
|
|
"```default\n",
|
|
"if <Test> \n",
|
|
" <Anweisung1> \n",
|
|
" <Anweisung2>\n",
|
|
" ...\n",
|
|
"end\n",
|
|
"``` \n",
|
|
"\n",
|
|
"\n",
|
|
"Ein `else`-Zweig und `elseif`-Zweige sind möglich.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "6ab36f93",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"x = sqrt(100)\n",
|
|
"\n",
|
|
"if x > 20\n",
|
|
" println(\"Seltsam!\")\n",
|
|
"else\n",
|
|
" println(\"OK\")\n",
|
|
" y = x + 3\n",
|
|
"end "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "3247aa40",
|
|
"metadata": {},
|
|
"source": [
|
|
"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:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "6b6f3846",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Bitte nicht so programmieren! Sie werden es bereuen!\n",
|
|
"x=sqrt(100); if x > 20 println(\"Seltsam!\") else println(\"OK\"); y = x + 3 end "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "4f8718ea",
|
|
"metadata": {},
|
|
"source": [
|
|
"Es wird dringend empfohlen, von Anfang an den eigenen Code übersichtlich mit sauberen Einrückungen zu formatieren!\n",
|
|
"\n",
|
|
"\n",
|
|
"## Einfache `for`-Schleifen\n",
|
|
"\n",
|
|
"zum wiederholten Abarbeiten von Anweisungen haben die Form\n",
|
|
"```default\n",
|
|
"for <Zähler> = Start:Ende\n",
|
|
" <Anweisung1> \n",
|
|
" <Anweisung2>\n",
|
|
" ...\n",
|
|
"end\n",
|
|
"```\n",
|
|
"Beispiel:\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "e2518e65",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"sum = 0\n",
|
|
"for i = 1:100\n",
|
|
" sum = sum + i\n",
|
|
"end \n",
|
|
"sum"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "3fa36879",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Arrays\n",
|
|
"1-dimensionale Arrays (Vektoren) sind eine einfache Form von Containern. Man kann sie mit echigen Klammern anlegen\n",
|
|
"und auf die Elemente per Index zugreifen. Die Indizierung beginnt mit 1. \n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "cf56b9fc",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"v = [12, 33.2, 17, 19, 22]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "2e6ae1f4",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"typeof(v)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "18a71a80",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"v[1] = v[4] + 10\n",
|
|
"v"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "6833c60b",
|
|
"metadata": {},
|
|
"source": [
|
|
"Man kann leere Vektoren anlegen und sie verlängern.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "49a0d406",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"v = [] # leerer Vektor\n",
|
|
"push!(v, 42)\n",
|
|
"push!(v, 13)\n",
|
|
"v"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "ca3e6d8e",
|
|
"metadata": {},
|
|
"source": [
|
|
":::{.callout-note icon=\"false\" .titlenormal collapse=\"true\" font-variant-ligatures=\"no-contextual\" }\n",
|
|
"\n",
|
|
"## Nachtrag: wie die Wirkung der Tab-Taste auf dieser Seite simuliert wurde...\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "087b10f7",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"using REPL\n",
|
|
"\n",
|
|
"function Tab(s)\n",
|
|
" l = filter(x->startswith(x,s), REPL.doc_completions(s))\n",
|
|
" println.(l[2:end])\n",
|
|
" return # return nothing, since broadcast println produces empty vector\n",
|
|
"end\n",
|
|
"\n",
|
|
"▷ = |> # https://docs.julialang.org/en/v1/manual/functions/#Function-composition-and-piping\n",
|
|
"\n",
|
|
"pri = \"pri\";"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "0b8be63e",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"pri ▷ Tab"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "cd067cf0",
|
|
"metadata": {},
|
|
"source": [
|
|
":::"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Julia 1.8.5",
|
|
"language": "julia",
|
|
"name": "julia-1.8"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|