function input(prompt = "Eingabe:")
println(prompt)
flush(stdout)
return chomp(readline())
end
input (generic function with 2 methods)
Das Betriebssystem stellt für ein Programm üblicherweise 3 Kanäle (streams) zur Verfügung:
stdin
stdout
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:
= input("Bitte eine positive Zahl eingeben!") ans
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())
end
input (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.= input("Bitte 2 Zahlen eingeben!") a
"34 56"
split(str)
zerlegt einen String in “Wörter” und liefert einen (array of strings):
= split(a) av
2-element Vector{SubString{String}}:
"34"
"56"
parse(T, str)
versucht,str
in den TypT
umzuwandeln:
= parse.(Int, av) v
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
= 123.7876355638734
x
@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|
= 123
j = 90019001
k = 3342678
l
@printf("j= %012i, k= %-12i, l = %12i", j, k, l) # 0-Flag für führende Nullen
j= 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 j
22 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",
"(geschätzt)" ,k) j,
Erstes Resultat: 123 (geschätzt)
Zweites Resultat 90019001
Das Makro @sprintf
druckt nichts, sondern liefert den ausgefüllten formatierten String zurück:
= @sprintf("x = %10.6f", π ); str
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)= 123456.7890123456
x
@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
)= open(path, mode) stream
"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:
= open("datei.txt", "w") file
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:
= open("datei.txt", "r") stream
IOStream()
readlines(stream)
liefert alle Zeilen einer Textdatei als Vector von Strings.
eachline(stream)
liefert einen Iterator über die Zeilen der Datei.
= 0
n for line in eachline(stream) # Lese zeilenweise
+= 1
n 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 DelimitedFiles
Wir erzeugen eine 200×3-Matrix von Zufallszahlen
= rand(200,3) A
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
= open("data2.txt", "w")
f writedlm(f, A)
close(f)
Die geschriebene Datei fängt so an:
;head data2.txt
0.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:
= readdlm("data2.txt") B
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)
end
using CSV, DataFrames, Downloads
# Wetterdaten von Westerland, s. https://dev.meteostat.net/bulk/hourly.html
= "https://bulk.meteostat.net/v2/hourly/10018.csv.gz"
url = Downloads.download(url)
http_response = CSV.File(http_response, header=false); file
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
= DataFrame(file) df
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, Dates
Wir 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
:datetime] = DateTime.(df.Column1) .+ Hour.(df.Column2); df[!,
Und nun zum Plot:
@df df plot(:datetime, [:Column9, :Column6, :Column3],
= (DateTime(2023,9,1), DateTime(2024,5,30)),
xlims =(3,1), title=["Wind" "Regen" "Temp"],
layout=:none, size=(800,800)) legend