function input(prompt = "Eingabe:")
println(prompt)
flush(stdout)
return chomp(readline())
endinput (generic function with 2 methods)
Das Betriebssystem stellt für ein Programm üblicherweise 3 Kanäle (streams) zur Verfügung:
stdinstdout undstderr.Wenn das Programm in einem Terminal (oder Konsole bzw. Shell) gestartet wird, kann das Programm über stdin die Tastatureingaben einlesen und Ausgaben über stdout sowie stdout erscheinen im Terminal.
stdout: print(),println(),printstyled()stderr: print(strerr,...), println(stderr,...), printstyled(stderr,...)stdin: readline()Die Sprache Python stellt eine Funktion input() zur Verfügung:
ans = input("Bitte eine positive Zahl eingeben!")Die Funktion gibt den Prompt aus, wartet auf eine Eingabe und liefert die Eingabe als string zurück.
In Julia kann man diese Funktion so implementieren:
function input(prompt = "Eingabe:")
println(prompt)
flush(stdout)
return chomp(readline())
endinput (generic function with 2 methods)
Anmerkungen
flush(stdout) wird die Leerung des Buffers und sofortige Schreiboperation erzwungen.readline() liefert einen String zurück, der mit einer Newline \n endet. Die Funktion chomp() entfernt einen eventuellen Zeilenumbruch vom Ende eines Strings.a = input("Bitte 2 Zahlen eingeben!")"34 56"
split(str)zerlegt einen String in “Wörter” und liefert einen (array of strings):
av = split(a)2-element Vector{SubString{String}}:
"34"
"56"
parse(T, str)versucht,strin den TypTumzuwandeln:
v = parse.(Int, av)2-element Vector{Int64}:
34
56
parse() erzeugt einen Fehler, wenn der String sich nicht als Wertangabe von Typ T parsen lässt. Man kann den Fehler mit try/catch abfangen oder die Funktion tryparse(T, str) verwenden, die in so einem Fall nothing zurückgibt - worauf man dann z.B. mit isnothing() testen kann.
readline() u.ä. warten auf den Abschluss der Eingabe durch Drücken der Enter-Taste.
Techniken zum Einlesen einzelner keystrokes findet man hier:
Printf-MakroOft möchte man Zahlen oder Strings mit einer strikten Formatvorgabe - Gesamtlänge, Nachkommastellen, rechts/linksbündig usw - ausgeben.
Dazu definiert das Paket Printf die Makros @sprintf und @printf, welche sehr ähnlich wie die gleichnamigen C-Funktionen arbeiten.
using Printf
x = 123.7876355638734
@printf("Ausgabe rechtsbündig mit max. 10 Zeichen Platz und 3 Nachkommastellen: x= %10.3f", x)Ausgabe rechtsbündig mit max. 10 Zeichen Platz und 3 Nachkommastellen: x= 123.788
Das erste Argument ist ein String, der Platzhalter (hier: %10.3) für auszugebende Variablen enthält; gefolgt von diesen Variablen als weitere Argumente.
Platzhalter haben die Form
%[flags][width][.precision]type
wobei die Angaben in eckigen Klammern alle optional sind.
Typangaben im Platzhalter
%s |
string |
%i |
integer |
%o |
integer octal (base=8) |
%x, %X |
integer hexadecimal (base=16) with digits 0-9abcdef or 0-9ABCDEF, resp. |
%f |
floating point number |
%e |
floating point number, scientific representation |
%g |
floating point, uses %f or %e depending on value |
Flags
| Pluszeichen | rechtsbündig (Standard) |
| Minuszeichen | linksbündig |
| Null | mit führenden Nullen |
Width
Anzahl der minimal verwendeten Zeichen (wenn nötig, werden auch mehr genommen)
using Printf # Paket laden nicht vergessen!@printf("|%s|", "Hallo") # string mit Platzhalter für String|Hallo|
Die senkrechten Striche sind nicht Teil des Platzhalters. Sie sollen die Begrenzung des Ausgabefeldes anzeigen.
@printf("|%10s|", "Hallo") # Minimallänge, rechtsbündig| Hallo|
@printf("|%-10s|", "Hallo") # linksbündig|Hallo |
@printf("|%3s|", "Hallo") # Längenangabe kann überschritten werden
# besser eine 'kaputt formatierte' Tabelle als falsche Werte!|Hallo|
j = 123
k = 90019001
l = 3342678
@printf("j= %012i, k= %-12i, l = %12i", j, k, l) # 0-Flag für führende Nullenj= 000000000123, k= 90019001 , l = 3342678
@printf und @sprintf können wie alle Makros wie Funktionen aufgerufen werden:
@printf("%i %i", 22, j)22 123
– oder wie Makros, also ohne Funktionsklammern und ohne Komma:
@printf "%i %i" 22 j22 123
@printf kann als erstes Argument noch einen Stream übergeben bekommen.
Ansonsten besteht die Argumentliste aus
@printf(stderr, "Erstes Resultat: %i %s\nZweites Resultat %i",
j, "(geschätzt)" ,k)Erstes Resultat: 123 (geschätzt)
Zweites Resultat 90019001
Das Makro @sprintf druckt nichts, sondern liefert den ausgefüllten formatierten String zurück:
str = @sprintf("x = %10.6f", π );str"x = 3.141593"
Bedeutung des Precision-Wertes:
%f und %e-Format: maximale Anzahl der Nachkommastellen%g-Format: maximale Anzahl von ausgegebenen Ziffern (Vor- + Nachkommastellen)x = 123456.7890123456
@printf("%20.4f %20.4e", x, x) # 4 Nachkommastellen 123456.7890 1.2346e+05
@printf("%20.7f %20.7e", x, x) # 7 Nachkommastellen 123456.7890123 1.2345679e+05
@printf("%20.7g %20.4g", x, x) # insgesamt 7 bzw. 4 Stellen 123456.8 1.235e+05
Dateien werden
stdin, stdout, stderr)stream = open(path, mode)"r" read, öffnet am Dateianfang
"w" write, öffnet am Dateianfang (Datei wird neu angelegt oder überschrieben)
"a" append, öffnet zum Weiterschreiben am Dateiende
Schreiben wir mal eine Datei:
file = open("datei.txt", "w")IOStream()
@printf(file, "%10i\n", k)println(file, " zweite Zeile")close(file)Schauen wir uns die Datei an:
;cat datei.txt 90019001
zweite Zeile
…und jetzt öffnen wir sie wieder zum Einlesen:
stream = open("datei.txt", "r")IOStream()
readlines(stream) liefert alle Zeilen einer Textdatei als Vector von Strings.
eachline(stream) liefert einen Iterator über die Zeilen der Datei.
n = 0
for line in eachline(stream) # Lese zeilenweise
n += 1
println(n, line) # Drucke mit Zeilennummer
end
close(stream)1 90019001
2 zweite Zeile
Für die Ein- und Ausgabe in den verschiedensten Dateiformaten existieren Julia-Pakete, z.B.
und viele andere mehr…
Dieses Paket ermöglicht das bequeme Abspeichern/Einlesen von Matrizen. Dazu stellt es die Funktionen writedlm() und readdlm() zur Verfügung.
using DelimitedFilesWir erzeugen eine 200×3-Matrix von Zufallszahlen
A = rand(200,3)200×3 Matrix{Float64}:
0.672342 0.303105 0.930836
0.385606 0.982857 0.297996
0.982319 0.13608 0.963767
0.700655 0.244917 0.745423
0.892462 0.677228 0.495121
0.909235 0.627747 0.831661
0.371466 0.759464 0.88495
0.62678 0.70573 0.404305
0.504154 0.0573904 0.374065
0.668662 0.161108 0.269653
⋮
0.371035 0.582342 0.413769
0.223072 0.983405 0.0632649
0.781323 0.114408 0.0111916
0.808109 0.541896 0.487848
0.122619 0.710159 0.238551
0.229855 0.236011 0.308402
0.825045 0.486915 0.818736
0.327997 0.691566 0.204639
0.0339736 0.966453 0.163437
und speichern diese
f = open("data2.txt", "w")
writedlm(f, A)
close(f)Die geschriebene Datei fängt so an:
;head data2.txt0.6723418093633674 0.3031053013517715 0.9308361275030339
0.38560613566454505 0.9828565448875306 0.29799580632013134
0.9823188234171364 0.136079648886137 0.9637673224574909
0.7006547221425034 0.2449165218995646 0.7454234552064191
0.8924615626866147 0.6772279207528131 0.49512143423556876
0.9092346088022356 0.6277466070820665 0.8316605232323371
0.3714658487798871 0.7594644096269569 0.8849501793885042
0.626779832412877 0.7057301938882777 0.4043049315040659
0.5041543711407259 0.05739039511206501 0.37406500965366407
0.6686624219387581 0.1611078145265057 0.2696531319719828
Das Wiedereinlesen ist noch einfacher:
B = readdlm("data2.txt")200×3 Matrix{Float64}:
0.672342 0.303105 0.930836
0.385606 0.982857 0.297996
0.982319 0.13608 0.963767
0.700655 0.244917 0.745423
0.892462 0.677228 0.495121
0.909235 0.627747 0.831661
0.371466 0.759464 0.88495
0.62678 0.70573 0.404305
0.504154 0.0573904 0.374065
0.668662 0.161108 0.269653
⋮
0.371035 0.582342 0.413769
0.223072 0.983405 0.0632649
0.781323 0.114408 0.0111916
0.808109 0.541896 0.487848
0.122619 0.710159 0.238551
0.229855 0.236011 0.308402
0.825045 0.486915 0.818736
0.327997 0.691566 0.204639
0.0339736 0.966453 0.163437
Noch ein Punkt: Beim Umgang mit Dateien wird in Julia oft die do-Notation verwendet, s. Kapitel 10.6. Dazu nutzt man, dass open() auch Methoden hat, bei denen das 1. Argument eine function(iostream) ist. Diese wird dann auf den stream angewendet und dieser abschliessend automatisch geschlossen. Die do-Notation erlaubt es, diese Funktion anonym nach dem do zu definieren:
open("data2.txt", "w") do io
writedlm(io, A)
endusing CSV, DataFrames, Downloads
# Wetterdaten von Westerland, s. https://dev.meteostat.net/bulk/hourly.html
url = "https://bulk.meteostat.net/v2/hourly/10018.csv.gz"
http_response = Downloads.download(url)
file = CSV.File(http_response, header=false);Die Daten sehen so aus:
# https://dev.meteostat.net/bulk/hourly.html#endpoints
#
# Spalte 1 Datum
# 2 Uhrzeit (Stunde)
# 3 Temp
# 5 Luftfeuchtigkeit
# 6 Niederschlag
# 8 Windrichtung
# 9 Windstärke
df = DataFrame(file)| Row | Column1 | Column2 | Column3 | Column4 | Column5 | Column6 | Column7 | Column8 | Column9 | Column10 | Column11 | Column12 | Column13 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Date | Int64 | Float64? | Float64? | Int64? | Float64? | Missing | Int64? | Float64? | Float64? | Float64? | Missing | Int64? | |
| 1 | 1989-03-18 | 7 | 6.0 | missing | missing | missing | missing | 270 | 11.2 | missing | missing | missing | missing |
| 2 | 1989-03-18 | 8 | 6.0 | -1.9 | 57 | missing | missing | 250 | 11.2 | missing | missing | missing | missing |
| 3 | 1989-03-18 | 9 | 7.0 | -3.0 | 49 | missing | missing | 250 | 14.8 | missing | missing | missing | missing |
| 4 | 1989-03-18 | 10 | 7.0 | -1.9 | 53 | missing | missing | 250 | 18.4 | missing | missing | missing | missing |
| 5 | 1989-03-18 | 11 | 8.0 | -1.0 | 53 | missing | missing | 220 | 24.1 | missing | missing | missing | missing |
| 6 | 1989-03-18 | 12 | 8.0 | 0.0 | 57 | missing | missing | 240 | 27.7 | missing | missing | missing | missing |
| 7 | 1989-03-18 | 13 | 8.0 | -1.0 | 53 | missing | missing | 240 | 25.9 | missing | missing | missing | missing |
| 8 | 1989-03-18 | 14 | 8.0 | 0.0 | 57 | missing | missing | 230 | 29.5 | missing | missing | missing | missing |
| 9 | 1989-03-18 | 15 | 8.0 | 0.0 | 57 | missing | missing | 230 | 31.7 | missing | missing | missing | missing |
| 10 | 1989-03-23 | 9 | 7.0 | -0.9 | 57 | missing | missing | 280 | 37.1 | missing | missing | missing | missing |
| 11 | 1989-03-23 | 10 | 7.0 | -0.9 | 57 | missing | missing | 270 | 64.8 | missing | missing | missing | missing |
| 12 | 1989-03-23 | 11 | 7.0 | -0.9 | 57 | missing | missing | 280 | 33.5 | missing | missing | missing | missing |
| 13 | 1989-03-27 | 7 | 6.0 | 4.0 | 87 | missing | missing | 160 | 11.2 | missing | missing | missing | missing |
| ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ | ⋮ |
| 185243 | 2025-03-08 | 23 | 4.1 | 2.8 | 91 | missing | missing | 228 | 13.0 | 24.1 | 1014.3 | missing | 2 |
| 185244 | 2025-03-09 | 0 | 3.9 | 2.7 | 92 | missing | missing | 229 | 13.0 | 27.8 | 1014.2 | missing | 2 |
| 185245 | 2025-03-09 | 1 | 3.7 | 2.7 | 93 | missing | missing | 230 | 13.0 | 27.8 | 1014.0 | missing | 2 |
| 185246 | 2025-03-09 | 2 | 3.4 | 2.7 | 95 | missing | missing | 235 | 13.0 | 27.8 | 1013.8 | missing | 2 |
| 185247 | 2025-03-09 | 3 | 3.3 | 2.6 | 95 | missing | missing | 243 | 13.0 | 27.8 | 1013.7 | missing | 7 |
| 185248 | 2025-03-09 | 4 | 3.1 | 2.5 | 96 | missing | missing | 244 | 13.0 | 25.9 | 1013.7 | missing | 7 |
| 185249 | 2025-03-09 | 5 | 2.4 | 2.0 | 97 | missing | missing | 262 | 18.5 | 27.8 | 1015.8 | missing | 7 |
| 185250 | 2025-03-09 | 6 | 2.6 | 2.2 | 97 | missing | missing | 258 | 18.5 | 29.6 | 1015.8 | missing | 7 |
| 185251 | 2025-03-09 | 7 | 3.2 | 2.3 | 94 | missing | missing | 255 | 20.4 | 27.8 | 1016.0 | missing | 7 |
| 185252 | 2025-03-09 | 8 | 4.4 | 2.7 | 89 | missing | missing | 255 | 20.4 | 29.6 | 1016.1 | missing | 7 |
| 185253 | 2025-03-09 | 9 | 5.4 | 3.2 | 86 | missing | missing | 252 | 22.2 | 31.5 | 1016.2 | missing | 7 |
| 185254 | 2025-03-09 | 10 | 6.3 | 3.5 | 82 | missing | missing | 259 | 24.1 | 33.3 | 1016.4 | missing | missing |
Zum bequemen Plotten und zum Umgang mit den Datums- und Zeitformaten in der Wettertabelle laden wir noch 2 Helferlein:
using StatsPlots, DatesWir erzeugen eine neue Spalte, die Datum (aus Spalte 1) und Uhrzeit (aus Spalte 2) kombiniert:
# neue Spalte mit Sp.1 und 2 (date & time) kombiniert
df[!, :datetime] = DateTime.(df.Column1) .+ Hour.(df.Column2);Und nun zum Plot:
@df df plot(:datetime, [:Column9, :Column6, :Column3],
xlims = (DateTime(2023,9,1), DateTime(2024,5,30)),
layout=(3,1), title=["Wind" "Regen" "Temp"],
legend=:none, size=(800,800))