Abschnitt 2 · Lektion 8
Synthese: der Kassenzettel
Die letzte Lektion eines Abschnitts bringt zusammen, was einzeln schon dastand. Hier ist es eine kleine Rechnung mit allem, was Abschnitt 2 gebracht hat: benennen, rechnen, umwandeln, ausgeben.
Wichtiger als die Rechnung ist die Reihenfolge, in der man sie hinschreibt.
Erst denken, dann tippen
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> // 1. Die Eingaben. Alles in Cent, alles mit sprechendem Namen.
const grundpreisInCent = 2400;
const versandInCent = 495;
const steuersatzInProzent = 19;
// 2. Die Zwischenschritte. Jeder bekommt einen eigenen Namen.
const nettoInCent = grundpreisInCent + versandInCent;
const steuerInCent = Math.round((nettoInCent * steuersatzInProzent) / 100);
const bruttoInCent = nettoInCent + steuerInCent;
// 3. Die Ausgabe. Erst hier wird aus Cent ein Betrag zum Lesen.
console.log("Netto in Cent:", nettoInCent);
console.log("Steuer in Cent:", steuerInCent);
console.log("Brutto in Cent:", bruttoInCent); Drei Blöcke, immer dieselben drei:
Die Eingaben. Alles, was von außen kommt oder feststeht, bekommt zuerst einen Namen. Beträge in Cent, Prozentsätze als ganze Zahl. Danach kommt in der ganzen Datei keine nackte Zahl mehr vor.
Die Zwischenschritte. Jede Teilrechnung bekommt einen eigenen Namen, auch wenn sie nur einmal gebraucht wird. Das ist der Teil, den man am Anfang für überflüssig hält.
Die Ausgabe. Ganz zum Schluss, und erst hier wird aus einer Zahl etwas zum Lesen.
Das klingt nach Bürokratie für sechs Zeilen Code. Der Nutzen zeigt sich, sobald etwas nicht stimmt.
Warum Zwischenschritte eigene Namen bekommen
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> // Dieselbe Rechnung, in einer Zeile. In dieser Fassung steckt ein Fehler.
console.log(Math.round((2400 + 495) * 19 / 100 + 2400));
// Und hier dieselbe Rechnung noch einmal zerlegt.
// Jetzt siehst du, an welcher Stelle sie falsch abbiegt.
const netto = 2400 + 495;
const steuer = Math.round((netto * 19) / 100);
const brutto = netto + steuer;
console.log("Netto:", netto);
console.log("Steuer:", steuer);
console.log("Brutto:", brutto); In der ersten Zeile steckt ein Fehler: Die Steuer wird auf Grundpreis plus Versand gerechnet, am Ende aber nur der Grundpreis addiert. Der Versand fällt unter den Tisch. Das Ergebnis sieht trotzdem plausibel aus, es ist eine vierstellige Zahl in der richtigen Größenordnung, und genau das macht solche Fehler teuer.
Jetzt schau auf die zerlegte Fassung. Jeder Zwischenschritt steht in der Console, und du siehst sofort, welcher Wert nicht stimmt. Aus „irgendwo in dieser Zeile” wird „in genau dieser einen”.
Das ist der ganze Punkt: Eine Zwischenrechnung mit Namen ist eine Stelle, an der du nachschauen kannst. Ohne Namen hast du eine Zeile und ein Ergebnis, und dazwischen nichts.
Und du musst dafür nicht einmal console.log schreiben. Während dieses Beispiel dasteht, tipp netto in die Eingabezeile der Console, dann steuer, dann brutto. Jeder Name antwortet mit seinem Wert. In der ersten Fassung kannst du das nicht: Dort gibt es keine Namen, also auch nichts zu fragen. Genau das ist gemeint, wenn hier steht, eine Zwischenrechnung sei eine Stelle zum Nachschauen.
Der zweite Gewinn ist die Lesbarkeit. nettoInCent + steuerInCent sagt, was passiert. (2400 + 495) * 19 / 100 sagt es nicht, auch nicht, wenn du es selbst geschrieben hast. Nach drei Wochen liest du deinen eigenen Code wie fremden.
Die Sorge, dass viele Namen den Code langsam machen, kannst du übrigens vergessen. Der Browser optimiert das weg, lange bevor es messbar wäre.
Von Cent zu Euro
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> const bruttoInCent = 4141;
// Die ganzen Euro: abgerundete Division durch 100.
const euro = Math.floor(bruttoInCent / 100);
// Die restlichen Cent: der Rest derselben Division.
const cent = bruttoInCent % 100;
console.log(`Summe: ${euro},${cent} Euro`);
// Vorsicht bei Beträgen unter zehn Cent: da fehlt eine Null.
const knapp = 405;
console.log(`So nicht: ${Math.floor(knapp / 100)},${knapp % 100} Euro`); Gerechnet wird in Cent, das ist die Regel aus Lektion 2.3. Zum Anzeigen brauchst du trotzdem eine Zahl mit Komma.
Zwei Werkzeuge aus derselben Lektion reichen dafür. Die ganzen Euro sind die abgerundete Division durch 100, die restlichen Cent sind der Rest derselben Division. Zusammengesetzt wird das im Template Literal aus Lektion 2.5.
Die letzten beiden Zeilen des Beispiels zeigen die Grenze dieser Methode. Bei 405 Cent kommt 4,5 Euro heraus statt 4,05 Euro, denn die führende Null fehlt. Für die Aufgabe gleich stört das nicht, weil dort keine solchen Beträge vorkommen. Sauber lösen lässt es sich mit padStart aus Abschnitt 8 oder gleich mit toLocaleString, das nebenbei auch das Tausenderzeichen setzt und weiß, dass im Deutschen ein Komma steht. Das ist Lektion 8.4.
Bis dahin gilt: Die einfache Fassung ist gut genug, solange du weißt, wo sie kippt. Etwas zu benutzen und seine Grenze zu kennen, ist besser, als auf die perfekte Lösung zu warten.
Was du gleich baust
Ein Kassenzettel aus drei Posten. Die Summe der Posten, die Mehrwertsteuer darauf, und die Ausgabe als Zettel mit einer Zeile je Posten.
Zwei der Schritte packst du dabei in Funktionen. Warum, siehst du an der Prüfung: Sie ruft nettoInCent() und bruttoInCent() direkt auf und schaut, was herauskommt. Eine Ausgabe in der Console ließe sich auch dadurch erzeugen, dass du die richtige Zahl abschreibst. Ein Funktionsaufruf nicht.
Zum Mitnehmen
Eine Zeile, in der alles auf einmal passiert, ist kürzer. Der Fehler darin ist unauffindbar.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
Was in dieser Lektion steckt
-
Artikel mit 3 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe im Editor, direkt im Browser geprüft
Öffnet sich mit dem Basis Konto.