Lass uns reden! 1
Na schön, das mit dem Ausgeben klappt ja nun schon recht gut. Irgendwie kann es aber nicht alles sein, wenn das Rubyprogramm nur gestartet wird, ein wenig was arbeitet und dann irgendetwas ausgibt. Das ist, als wenn dir jemand gegenüber steht, der nur plaudert und dich nicht zu Wort kommen lässt. Dabei hast du auch etwas zu sagen, oder?
Ganz so schlimm ist es aber doch nicht. Ein wenig hattest du schon zu sagen – das Fahrrad konntest du mit der L- und R-Taste steuern und mit der X-Taste vom Rad absteigen.
In diesem Artikel zeige ich dir, wie du dein Rubyprogramm dazu bekommst, sich mit dem, der es ausführt zu unterhalten.
Eingaben von Anwenderinnen abfragen
Schauen wir uns gleich folgendes Programm an:
# theorie_02.rb
print "Gib eine Zahl a zwischen 1 und 100 ein! a="
a = gets
a = a.chomp
a = a.to_i
zahl_teilbar_durch_3 = false
if a % 3 == 0
zahl_teilbar_durch_3 = true
end
puts "Du hast a=#{a} eingegeben."
if zahl_teilbar_durch_3
puts "#{a} ist durch 3 teilbar."
else
puts "#{a} ist nicht durch 3 teilbar."
end
Wir fordern die Anwenderin zunächst mit der Ausgabe Gib eine Zahl a zwischen 1 und 100 ein! dazu auf, na was wohl, natürlich eine Zahl einzugeben, die größer oder gleich 1 aber kleiner oder gleich 100 ist. Damit sie weiß, wo beim Tippen die Zahl erwartet wird, schreiben wir noch das a= hin. Direkt nach dem = wird dann an der Kommandozeile das erscheinen, was sie eintippt. Ruby wartet nun darauf, solange, bis sie die Enter-Taste drückt.
Dann geht unser Programm zur nächsten Zeile und liest das was eingegeben wurde von der Kommandozeile in die Variable a ein. In a steht nun eine Zeichenkette mit dem Sonderzeichen für die Entertaste \n am Schluß.
Dieses Sonderzeichen schneiden wir mit dem Befehl chomp (englisch: mampfen) ab. Den Befehl oder besser die Nachricht chomp schicken wir direkt an die Variable a. Das kennst du auch schon aus den früheren Lektionen. Wir trennen dabei die Nachricht chomp vom Variablennamen mit dem Punkt . ab. Das was nach dem Abschneiden von \n noch übrig bleibt, weisen wir wieder der Variablen a zu.
In der nächsten Zeile schicken wir wieder eine Nachricht an a und zwar lautet diese to_i. Das ist die Abkürzung für englisch to integer, d.h. mache eine ganze Zahl daraus!. Den dadurch entstehenden Zahlenwert weisen wir wieder der Variablen a zu. Wir könnten auch jedesmal eine andere Variable verwenden. Da wir aber eigentlich nur am Zahlenwert interessiert sind, können wir den Wert von a ohne Sorge überschreiben.
So, jetzt steht in a keine Zeichenkette (in Ruby String genannt) mehr, sondern eine Zahl (in Ruby Fixnum oder Integer genannt).
Mit der Zahl a führen wir nun den Test durch, ob sie durch 3 teilbar ist. Dazu berechnen wir den Rest bei der Division durch 3. Den Rest erhalten wir mit dem Operator %. Nur wenn der Rest beim Teilen durch 3 Null ist, ist die Zahl (restlos) durch 3 teilbar. Ob sie das ist, merken wir uns in der Variablen zahl_teilbar_durch_3.
Okay, nun können wir der Anwenderin Bescheid geben, was wir herausgefunden haben. Wir zeigen ihr zuerst nochmal das, was sie eingegeben hat. Halt, das stimmt eigentlich nicht. Sie hat ja genau genommen noch die Entertaste eingegeben. Aber das will sie sicher nicht wissen.
Schließlich verraten wir ihr noch, ob die Zahl durch 3 teilbar ist oder nicht.
Und wenn sie nicht auf mich hört?
Versuche das Programm zu starten und gib mal eine Zahl ein, die größer als 100 ist. Es geht! Warum auch nicht. Wir prüfen nirgendwo, ob die eingegebene Zahl auch tatsächlich einen Wert hat, den wir gefordert haben. Das überlasse ich dir als Übung.
Die Büchse der Pandora
Ein Programm, das man startet, es dann irgendetwas tut und sich am Ende mit irgendeiner Ausgabe verabschiedet ist einfach. Wobei einfach hier nicht im Sinne zu verstehen ist, dass solche Programme nicht auch kompliziert oder auch schwierig zu entwickeln sein könnten. Nein, mit einfach meine ich, dass der Ablauf des Programmes recht übersichtlich ist. Man gibt etwas ein, wartet und schaut sich dann das Ergebnis an. Fertig.
Sobald du aber ein Programm während seiner Laufzeit (englisch: runtime), also nachdem du es gestartet hast und es noch nicht fertig ist, für die Anwenderinnen öffnest, verliert es seine einfache Ablaufstruktur.
Kommunizierst du mit einem realen Menschen direkt von Angesicht zu Angesicht, kannst du auf ihr Reden sofort reagieren. Du siehst ihre Mimik und Gestik und hörst auch auf den Ton, wie sie etwas sagt. Daraus kannst du neben den Worten, die von ihr an dein Ohr dringen, sogar noch eine zusätzliche Bedeutung entnehmen.
Die Kommunikation mit einem realen Menschen, allerdings nicht direkt, sondern nun über den Umweg eines Computerprogramms ist da anders. Der Austausch von Information geschieht hier zeitlich versetzt. Du musst dir während du das Programm entwickelst, Gedanken darüber machen, wie du die Fragen stellst, welche Antworten du erwartest und wie du wiederum auf diese Antworten reagieren möchtest.
Angenommen, du schreibst ein Programm, dass zwei Zahlen a und b einliest und als Ausgabe den Quotienten aus a/b ausgeben soll. Du forderst die spätere Anwenderin deines Programms etwa so auf:
"Gib die erste Zahl größer als 1 ein! a=" ... "Gib die zweite Zahl größer als 1 ein! b="
Nun hast du in deinem Programm zwei Variablen a und b. Du weißt aber während du das Programm entwickelst nicht, welchen Wert genau a und b haben werden. Du wirst sicher nicht dabei sein, wenn sie irgendwo auf der Welt vor ihrem Computer sitzt und dein Programm ausführt, du siehst nicht, was sie eingibt. Es wäre leichtsinnig sich darauf zu verlassen, dass sie wirklich das macht, wozu du sie aufgefordert hast, nämlich zwei Zahlen einzugeben, die beide je größer als 1 sind. Was, wenn sie für b eine Null eintippt? Die Division durch Null ist in der Mathematik nicht erlaubt. Ruby wird sich mit einer Fehlermeldung beklagen. Je mehr Fehlermeldungen dein Programm produziert, ums so mehr wird das Vertrauen in deine Software sinken. Sie wird nie sagen Oh, ich habe eine Null eingegeben, das war mein Fehler. Stattdessen wird sie sagen So ein dummes Programm, es lässt einfach zu, dass ich eine Null eingeben kann. Dabei weiß doch jeder, dass man durch Null nicht dividieren kann. Und sie wird sich ein anderes Divisionsprogramm suchen.
Sobald dein Programm interaktiv genutzt werden soll—also nicht nur Ausgaben produziert, sondern auch Eingaben entgegen nimmt—bist du gezwungen, jede Eingabe zu prüfen. Liegt sie nicht in dem Bereich, mit dem du weiterarbeiten kannst, dann gibt dein Programm eine freundliche Hinweismeldung zurück.
Es gibt verschiedene Formen von fehlerhaften Eingaben:
- Unabsichtliche Fehleingaben Vielleicht waren deine Anweisungen nicht verständlich genug. Oder sie hat sie nicht richtig gelesen, oder hat einfach die falsche Taste erwischt.
- Bewusste Fehleingaben Sie legt es darauf an, dein Programm in einen Fehlerzustand zu versetzen. Entweder, um dir zu zeigen, dass du dein Programm nachlässig entwickelt hast, oder sogar, um dir absichtlich zu schaden. Insbesondere ist Software, die über das Internet genutzt wird böswilligen Angriffen ausgesetzt. Sie will über dein Programm hinaus eigentlich an die dahinterliegende Hardware herankommen, bpsw. an den Server und seine Festplatten, um dort an weitere Daten zu gelangen, die du in deinem Programm niemals freiwillig über das Internet zu ihr geschickt hättest.
Du wirst bald merken, dass du manchmal viel mehr Code dafür schreiben musst, um diese Fehleingaben sicher abfangen zu können, als für das, was du eigentlich mit deinem Programm anbieten möchtest.
Üben mit Peter und Livia
- Livia: Ich will aber keine Zahl zwischen 1 und 100 eingeben. Vielleicht will ich überhaupt keine Zahl eingeben. Ändere obiges Programm so ab, dass ich dann eine höfliche Fehlermeldung von dir bekomme!
- Peter: Entwickle ein Programm, das folgendes macht:
- Es verlangt von der Anwenderin eine Zahl zwischen 1 und 5. Nennen wir sie n.
- Es fragt dann die Anwenderin nacheinander n mal nach je einer weiteren Zahl im Bereich von 1 bis 1000.
- Am Schluß teilt es der Anwenderin mit, ob die eingegebenen n Zahlen jede für sich eine Primzahl ist. Eine Primzahl ist eine Zahl, die nur durch 1 und sich selbst teilbar ist.
