2 September 2025

Heute drei graue Haare mehr. Grund: Rechnen in JS

Eigentlich sollte die Sache recht einfach sein: Schreibe ein kleines Skript für eine Seite, auf der Schüler:innen das Umrechnen von Einheiten üben können.

Die Seite ist in ihrem Aufbau trivial: jeweils eine Checkbox für die Größen „Masse“ und „Volumen“, dann ein Text-Input für die Anzahl der zu generierenden Aufgaben, ein Button, der die Aufgabengenerierung startet und ein zweiter Button, mit dem man zwischen Aufgaben und Musterlösungen hin und her springen kann.

Die Einheiten zu den Größen habe ich in einem Dictionary zusammengefasst, das für jede Größe ein weiteres Dictionary mit den Umrechnungen der Einheiten enthält:

var groessen = {"m": {"kg": 1, "g":	1000, "mg":1000000, "t":0.001}, "v": {"": 1, "dm³": 1000, "cm³": 1000000, "l": 1000, "ml": 1000000}}

Der erste Eintrag in jedem „Einheiten-Dictionary“ ist die Basiseinheit (beim m ist es z.B. kg). Dabei gibt der Zahlenwert das Äquivalent von der Grundeinheit an (1 kg = 1000 g).

Nach ein paar Verrenkungen, die im verhindern sollen, dass man von einer Einheit in sie selbst umrechnen soll und die geeignete Zahlen für die Umrechnungen per Zufall generiert wird, erfolgt die Umrechung des Zahlenwertes. Dazu wird der generierte Zahlenwert erst in die Grundeinheit umgerechnet und dieser Wert dann in die Zieleinheit.

Und hier beginnen die Probleme.

Das erste Problem ist, dass das Ergebnis in englischer Schreibweise angegeben wird („.“ statt „,“). Hier ist die Lösung trivial:

//tv steht für "target value" ist schon ein String
var commapos = tv.indexOf(".");
		if (commapos > 0){
			var tvsv = tv.substring(0,commapos);
			var tvsh = tv.substring(commapos+1);

//Some more shit happens

tv = tvsv + "," + tvsh;

Finde die Position des Kommas (Zeile 2). indexOf() gibt als Wert -1 zurück, wenn das Zeichen nicht in der Zeichenkette ist, somit erklärt sich die Bedingung in Zeile 3. tvsv ist die Zeichenkette vor dem Punkt, tvsh ist der String dahinter. In Zeile 9 wird dann der Wert zusammengeführt.

Das zweite Problem kenne ich schon von Python: Gleitkommazahlen mit der Basis 10 (also die, die wir alle kennen), können im Rechner schlecht abgebildet werden. Das hängt damit zusammen, wie Gleitkommazahlen im Computer repräsentiert werden. Wer möchte, kann sich mal mit dem IEEE-Standard 754 beschäftigen, der das regelt. Somit kann es dazu kommen, dass die Zahl 17,802 z.B. als 17,80200000000000001 dargestellt wird. Hier hätte man eine kurze Erklärung einfügen können, aber Schüler:innen, die eh Angst vor Mathe haben und geradezu in eine Duldungsstarre verfallen, wenn sie solche Aufgaben lösen müssen, überlesen so etwas eher und verwenden die Seite nicht zum Üben. Noch größer wird die Verwirrung in einigen anderen Fällen, in denen 0,893 als 0,892999999999999994 oder ähnlich ausgegeben wird. Hier ist das Problem in der Rundung, die man durchführen muss, um auf das richtige Ergebnis zu kommen.

Die Lösung für das Problem war gar nicht schwierig, ich hatte eh schon die Zeichenkette des Nachkommawertes bestimmt. Zunächst kümmere ich mich um den Fall mit den vielen 0 (17,80200000000000001). Hier fiel mir auf, dass nach den vielen Nullen nur eine weitere Ziffer kam. Daher iteriere ich durch den String mit den Nachkommastellen bis einschließlich der vorletzten Stelle (Zeile 44). Lese ich eine Ziffer ungleich 0 (Zeile 45), nehme ich an, dass die Nullen beim nächsten Zeichen anfangen (Zeile 47). Ist dieser Index deutlich kleiner als die Länge des Nachkomma-Strings, dann kann ich hier abschneiden (Zeile 51-53). In Zeile 46 zähle ich die Neunen für den zweiten Fall.

for (var j = 0; j < tvsh.length-1; j++){
  if (["1", "2", "3", "4", "5", "6", "7", "8", "9"].includes(tvsh[j])){
		if (tvsh[j] == "9"){nc++;}
		si = j+1;
	}				
}

if (si < tvsh.length - 5){
				tvsh = tvsh.substring(0,si);
}

Ob dieser Fall (z.B. 0,892999999999999994 statt 0,892) eingetreten ist, kann ich über die Anzahl der Neunen erkennen. Ist dieser z.B. größer als 5, dann wird äquivalent zum vorherigen Fall mit den vielen Nullen vorgegangen:

if (nc > 5){
  si = 0;
	for (var j = 0; j <tvsh.length-1; j++){
	  if (["1", "2", "3", "4", "5", "6", "7", "8", "0"].includes(tvsh[j])){
		  si = j;
		}
	}
	if (si < tvsh.length - 5){
		tvsh = tvsh.substring(0,si)+(parseInt(tvsh[si], 10)+1).toString();
	}
}

Es wird zunächst nach dem Index gesucht, wo die ganzen Neunen anfangen (Zeilen 60-64). Liegt die typische Häufung von Neunen vor, nehme ich nur die Ziffern bis einschließlich der vorletzten Ziffer vor der 9. Die letzte Ziffer muss aufgerundet werden, dazu wandel ich diese in eine Zahl um, die ich mit 1 addiere und dann wieder in einen String verwandle. Diese Ziffer hänge ich an den String mit einschließlich der vorletzten Ziffer an (passiert alles in Zeile 66).

Ein zweites Problem ist die wissenschaftliche Schreibweise mit Exponentialdarstellung: 0,000000078 wird dann eben als 7,8e-8 ausgegeben. Vereinfacht wird das Problem zum einen durch den Fakt, dass bei meinen Fällen nur negative Exponenten vorkommen, zum anderen dadurch, dass es vor dem Komma nur eine Ziffer gab. Um das Problem habe ich mich parallel gekümmert, weswegen die Zeilennummern etwas springen:

var ioe = tvsh.indexOf("e");
var tvshb = "";
  if (ioe > -1) {
	  tvshb = tvsh.substring(ioe+1);
		tvsh = tvsh.substring(0,ioe)
	}
if (ioe > -1){
  tvsh = "0".repeat((parseInt(tvshb,10)*(-1))-1) + tvsv + tvsh;
	tvsv = "0";
}

Der Algorithmus läuft so:

  1. Suche das Exponentenzeichen („e“) im Nachkommastring. (Z. 37)
  2. Speichere den Zehnerexponenten in der Variable tvshb. (Z. 40)
  3. Verkürze den Nachkommastring bis zum Zeichen vor dem „e“. (Z. 41).
  4. Der Nachkommstring wird neu zusammengebaut aus einer Anzahl Nullen (Betrag des Exponenten minus 1), der Ziffer vor dem Komma und dem bisherigen Nachkommastring.(Z. 55)
  5. Zum Abschluss (Z. 56) muss jetzt die Vorkommazahl nur noch auf null gesetzt werden. (Z. 56)

Richtig ins Bein geschossen habe ich mir auch. All diese Akrobatik war in einer for-Schleife eingebunden, da ich ja eine wählbare Anzahl an Aufgaben generieren wollte. Für diese Zählschleife habe ich die Zählvariable i gewählt (ich liebe Traditionen). Dummerweise habe ich i auch allerdings auch für die Zählschleifen in Zeile 60 z.B. verwendet. Das sorgte dafür, dass ich 20 Aufgaben wollte und je nachdem mal 4, 6 oder auch 32 bekam.

Die Verrenkungen haben Spaß gemacht. Und ihr wisst ja: Alles für die Kinder!

25 November 2023

Fooling around with JavaScript

In my computer science classes, I expect that my students can compress a text using the LZW algorithm, Huffman codes in grade 11 and do array sorting (Bubble Sort, Insertion Sort and Selection Sort) in grade 12.

Some of the students get it quickly, while others need some more exercises. Therefore, I came up with the idea to provide online exercises that provide samples and sample solutions. So, no student can complain about not having enough exercise opportunities.

Originally, all applications were written in Python and hosted on repl.it. As repl.it is hosted in the U.S.A., I was not really comfortable forcing students to use it, because there are some data protection concerns addressed by Thuringian government officials. Hence, I had to redo the codes for JavaScript.

Here are my solutions:

Of course, there are other solutions online. But coding it myself is way more fun than searching for alternatives.

21 Oktober 2020

Warum man als Lehrkraft eine eigene Internetseite haben sollte.

Bild: (c) Dipsey, 2012

Ich habe neulich ein tolles Authoring-Tool gefunden, das heißt h5p. Offensichtlich braucht man aber eine Webpräsenz, um die Skripte zu nutzen. Da gibt es nichts Einfacheres als eine eigene Webseite, so wie ich eine habe.

Also habe ich einem Freund, der dieses Tool nutzen wollte, vorgeschlagen, eine eigene Webpräsenz für sich zu besorgen. Er wollte nicht.

Was spricht für eine Webpräsenz?

Hier spricht jetzt der Edupunk aus mir: Oft trifft man im e-Learning-Bereich an Grenzen, die nicht durch Gesetze oder Regeln gesetzt sind, sondern allein wegen der Sturheit von meist technischen Administratoren existieren. Da wird ein Tool nicht installiert, weil man es (entgegen aller Vernunft) nicht sicher hält. Da will man keine Schreibrechte auf Verzeichnissen einrichten … Manchmal ist aber nicht die Sturheit schuld, sondern einfacher Zeitmangel. Dumm ist dann, wenn man ein Tool wollte, es sich aber in der Praxis nicht als tauglich erwies. Dann ist man richtig angeschmiert: Erst hat man konstant genervt und dann wird das Tool nicht genutzt.

Hierfür ist es einfach praktisch, selbst eine Internetpräsenz zu haben: Man kann ein Tool oft recht schnell installieren, testen und wenn es sich in der Praxis als untauglich erweist auch gern wieder löschen.

Aber das ist der nicht der Haupgrund. Die Gründe sind mannigfaltig:

Informationen und Transparenz

Auf der Seite kann man allgemeine Infos teilen:

  • Formatierungshinweise zu Hausarbeiten,
  • Lösungshinweise zu Aufgaben,
  • kurze Zusammenfassungen,
  • Bewertungsmatrizen für Vorträge etc.
  • Stoffverteilungspläne …

Vieles, was Schüler*innen gern verlieren, kann man dort nochmals zum Download zur Verfügung stellen. Im Zweifelsfall kann man so auch eigene Druck- und Kopierkosten sparen.

Die Veröffentlichung sorgt auch für Transparenz bei den Eltern.

Zusatzaufgaben

Man kann dort auch Zusatzaufgaben sammeln, die entweder leistungsschwachen Schüler*innen helfen können oder leistungsstarke Schüler*innen fördern können. Diese Aufgaben eignen sich dann auch zur Püfungsvorbereitung.

Unabhängigkeit von großen Anbietern

Man muss nicht unbedingt mehr Google Forms benutzen, wenn man eine Befragung machen will. Entweder nimmt man ein elaboriertes Formulartool wie Quform für WordPress (kostet nicht viel) oder das für wissenschaftliche Umfragen geeignete LimeSurvey. Für kleine Interaktionen braucht man auch nicht mehr unbedingt PollDaddy: Alles kann auf einer eigenen Internetpräsenz laufen. Ich benutze das WordPress-Plugin YOP.

Sharing is caring

Andere Lehrer*innen können die eigenen Materialien finden. Man freut sich ja auch immer, wenn man Material online findet. Warum dann nicht eigenes Material auch zur Verfügung stellen.

Das schlimmste, was passieren kann, ist, dass man Hinweise bekommt, wie man ein AB verbessern könnte.

Außenwirkung

email@mein-name.de wirkt um einiges besser als lehrgott123@web.de.

Eigene Cloud

Meist gibt es eine Menge Webspace zur Präsenz mit dazu. Genug, um die eigene Cloud zu installieren. Dafür gibt es eine Menge Skripte: OwnCloud, Nextcloud. Diese Clouds sind so komfortabel wie eine Dropbox oder das Google Drive.

Eigener URL-Shortener

Ob Veranstaltungshinweis oder Seitenempfehlung: Oftmals sind URLs lang. Zu lang, um sie korrekt ins Heft zu schreiben oder an eine Tafel. Deswegen bieten sich Services wie bit.ly an. Aber seien wir ehrlich, dort bekommt man auch nie einen passenden Shortlink. Es gibt aber eine Lösung: YOURLS, nicht sehr fancy, aber man bekommt den Link, den man braucht. Und wenn nötig, löscht man den alten.

Die dunkle Seite

Natürlich ist nicht alles rosig. Einige Probleme gibt es schon.

Rechtliche Aspekte

Copyright, Datenschutz, Haftungen …, man kann schnell in eine Falle treten. Deswegen geht es nicht, ohne sich vorher kundig zu machen.

Technische Kompetenz

Braucht man oft nicht wirklich, für Standardoberflächen wie WordPress, Drupal oder auch Joomla bieten viele Provider schon Installationswerkzeuge an. Ansonsten ist der Rest auch nicht schwer, zumal es tonnenweise Tutorials gibt.

Kosten

Sind als fest angestellte Lehrperson nicht wirklich hoch. Die meisten Tools sind Open-Source und somit auch kostenfrei.

tl;dr und weitere Infos (als Mindmap)

Für eine vergrößerte Darstellung bitte klicken.