Kursmaterial: Seite 3, Daten

In der Welt des Computers gibt es nur Daten. Was nicht Daten ist, ist nicht. Programme sind Daten. Programmen erschaffen neue Daten. Es ist ein eigenartiger, auf Silikon basierender Kreislauf des Lebens.

Datenstrukturen

Ziel

Lerne mehrere Werte in einer Datenstruktur zu gruppieren und diese Gruppierung zu verwenden.

Aufgabe: Zeichne einen Regenbogen indem du sieben konzentrische Kreise mit den Farben red, orange, yellow, green, cyan, purple, white zeichnest, wobei jeder Kreis kleiner als der zuvor ist.

Anweisungen

Das ist der naive Ansatz:

function rainbow(x, y) {
  color("red");
  circle(x, y, 150);
  color("orange");
  circle(x, y, 145);
  color("yellow");
  circle(x, y, 140);
  color("green");
  circle(x, y, 135);
  color("cyan");
  circle(x, y, 130);
  color("purple");
  circle(x, y, 125);
  color("white");
  circle(x, y, 120);
}

Das ist nicht falsch, aber es ist einfach nicht richtig. Es ist voller Wiederholungen. Hier ist eine bessere Variante:

function rainbow(x, y) {
  var colors = ["red", "orange", "yellow", "green", "cyan", "purple", "white"];
  var count = 0;
  while (count < colors.length) {
    color(colors[count]);
    circle(x, y, 150 - 5 * count);
    count = count + 1;
  }
}

Erklärung

Das Ding mit den eckigen Klammern ([ und ]) wird ein Array genannt. Ein Array ist ein Wert der andere Werte enthält - in diesem Fall enthält er sieben Strings die Farben benennen.

Die Werte in einem Array werden seine Elemente genannt. Die Elemente in einem Array sind geordnet, was bedeutet, dass jedes Element eine Position innerhalb des Arrays hat. Die Positionen in einem Array werden ab Null gezählt, so dass im Beispiel oben "red" die Position 0 hat, und "white" (das siebte Element) die Position 6. Die Schreibweise colors[1] wird benutzt, um auf die Elemente in einem Array zuzugreifen — in diesem Fall wäre es "orange".

Eine weitere neue Schreibweise ist der Punkt in colors.length, auch wenn wir den bei Math.random schon gesehen haben. Er wird verwendet, um auf andere Arten von Werten zuzugreifen, die Eigenschaften (properties) genannt werden. Bei Math.random wird es nur zur Gruppierung verwendet: Eine ganze Sammlung von mathematischen Funktionen sind als Eigenschaften von Math verfügbar (zum Beispiel Math.round zum Runden von Zahlen). Aber im Fall von colors.length wird auf eine Eigenschaft zugegriffen, die in direkter Verbindung zum Array colors steht: die Gesamtzahl der Elemente im Array (sieben).

Die while-Schleife läuft eines nach dem anderen über die Elemente des Arrays und verwendet dabei die Variable count, um ihre Position zu speichern. Bei jedem Schritt werden die Elemente benutzt, um die aktuelle Farbe zu setzen und anschließend wird ein Kreis der passenden Größe gezeichnet.

Weil diese Art von Schleife (Variable erzeugen, in der while-Bedingung prüfen, und aktualisieren) sehr häufig vorkommt, gibt es eine kompaktere Schreibweise dafür. Dieses Programm ist äquivalent zu dem vorherigen:

function rainbow(x, y) {
  var colors = ["red", "orange", "yellow", "green", "cyan", "purple", "white"];
  for (var count = 0; count < colors.length; count = count + 1) {
    color(colors[count]);
    circle(x, y, 150 - 5 * count);
  }
}

In einer for-Schleife werden das Initialisieren der Variablen der Schleife, das Prüfen der Bedingung, und das Aktualisieren der Werte zusammen gruppiert, damit einfacher gesehen werden kann, dass sie gemeinsam die Schleife ausmachen.

Benannte Eigenschaften

Ziel

Lerne Objekte zu erzeugen und auf ihre Eigenschaften zuzugreifen.

Anweisungen

Öffne die Konsole wieder, falls du sie geschlossen hast.

Erzeuge eine Variable indem du folgendes in die Konsole eingibst: var myObject = {name: "Larry", score: 100};

Führe myObject.name und myObject.score aus.

Führe zudem myObject["name"] und myObject["sco" + "re"] aus.

Gib dem Objekt mit myObject.color = "purple" eine Eigenschaft hinzu. Dann führe myObject.color aus.

Verändere die score-Eigenschaft mit myObject.score = 105. Führe dann wieder myObject.score aus, um sicher zu gehen, dass es geklappt hat.

Erklärung

Objekte sind ebenfalls Gruppierungen von Werten. Sie verlangen aber, dass jeder Wert einen Namen hat. Arrays sind nützlich, um irgendeine Menge von Werten in einer homogenen Gruppe zu sammeln. Objekte dagegen sind besser geeignet wenn jeder Wert eine klar bestimmte Rolle in der Gruppierung spielt. Zum Beispiel ist eine Tüte Chips ein Array, aber die Teile eines Autos (Motor, Räder, etc.) bilden ein Objekt.

Die Schreibweise {property1: value1, property2: value2} wird verwendet, um ein Objekt zu erzeugen. Es gibt zwei Arten um auf die Eigenschaften eines Objektes zuzugreifen. Die Art mit Punkt, object.property, wird verwendet, wenn der Name der Eigenschaft schon beim Schreiben des Programms bekannt ist. Die Art mit Klammern, object["property"], lässt zu, dass der Name der Eigenschaft als beliebiger Ausdruck angegeben wird und ist daher nützlich, wenn der Name erst noch erstellt werden muss.

Zusammen bieten Objekte und Arrays die Möglichkeit, eine große Bandbreite an Informationen darzustellen. Ein Beispiel: Eine Liste von Spielern in einem Spiel würde üblicherweise ein Array von Objekten sein, worin jedes Objekt einen Spieler repräsentiert. Falls eine Liste von Ergebnissen mit einzelnen Spielern verbunden wird, wäre diese wiederum ein Array in jedem der Spieler-Objekte. So kann man beliebig fortfahren.

Übung: Überlege dir eine JavaScript-Repräsentierung eines Schachbretts. Es gibt mehrere gute Lösungen.

Wir haben Daten

Ziel

Mache eine einfache Visualisierung eines Datensatzes

Anweisungen

In unserer Spielumgebung haben wir eine neue Variable zur Verfügung, countryData. Sie enthält ein Array von Objekten mit Informationen (Bevölkerung, Lebenserwartung) über die meisten Länder der Erde.

Jedes Objekt stellt ein Land dar und enthält eine name-Eigenschaft mit einem String, sowie population- und life_expectancy-Eigenschaften die Arrays mit Zahlen enthalten. Diese Zahlen geben die Werte der entsprechenden Statisiken (Bevölkerungszahl und Lebenserwartung in Jahren) für die Jahre 1960 bis 2011 an.

Dieses Programm wählt ein paar Länder aus und stellt den Trend ihrer jeweiligen Lebenserwartung für den verfügbaren Zeitraum als Punktdiagramm dar.

var width = 600, height = 300;

function showCountry(country) {
  var step = width / country.life_expectancy.length;
  for (var pos = 0; pos < country.life_expectancy.length; pos = pos + 1) {
    var le = country.life_expectancy[pos];
    circle(step * pos, le * height / 100, 2);
  }
}

function drawing() {
  moveTo(-width / 2, -height / 2);
  color("red");
  showCountry(countryData[66]); // Germany
  color("green");
  showCountry(countryData[81]); // India
  color("blue");
  showCountry(countryData[150]); // Russian Federation
}

Du kannst es hier in Aktion sehen.

Erklärung

Um die Zeichnung mit ein wenig Disziplin zu erstellen, definiert das Programm zunächst die Breite und Höhe des Bereichs in den gezeichnet werden soll. 600 auf 300 Einheiten.

Die Funktion showCountry nimmt ein Land-Objekt als Parameter und läuft in einer Schleife über alle Lebenserwartungs-Werte dieses Landes. Es berechnet den horizontalen Abstand den es zwischen Punkten lassen will und speichert ihn in der Variable step. Unter der Annahme, dass die Lebenserwartung stets zwischen 0 und 100 Jahren liegen wird, teilt es die Höhe des Zeichenbereichs durch 100, um die Zahl der Einheiten zu bestimmen, die ein Jahr Lebenserwartung darstellen.

Die Funktion drawing bewegt zuerst das Koordinatensystem so, dass (0,0) die linke untere Ecke des Zeichenbereichs und damit des Graphen ist. Es ruft dann showCountry auf drei verschiedenen Ländern auf, wobei es jedem eine andere Farbe gibt.

Übung: Die Position eines Landes in der Sammlung kennen zu müssen, um es anzeigen zu können, ist irgendwie unpraktisch. Schreibe eine Funktion findCountry, die einen String mit einem Ländernamen als Parameter nimmt, durch das Array countryData läuft und das Objekt für das genannte Land zurück gibt.

Um das tun zu können, musst du wissen, dass das Stichwort return benutzt werden kann, um eine Anweisung zu schreiben, die einen Wert an die Stelle im Code zurück gibt, die die Funktion aufgerufen hat. Zum Beispiel:

function timesThree(x) {
  return x * 3;
}
console.log(timesThree(3)); // Logs 9

Übung: Ein großes Problem mit unseren Graphen ist, dass man gar nicht erkennen kann, wofür die Punkte eigentlich stehen. Schreibe zusätzlichen Code der graue horizontale Linien zeichnet (mit der Funktion line(x1, y1, x2, y2)), sodass hinter dem Graph zu sehen ist, wo 10, 20, ..., usw. bis 100 Jahre Lebenserwartung liegen. Benutze die Variablen width und height, um die Linien richtig zu platzieren.

Wenn du magst, kannst du auch noch Beschriftungen mit der Funktion text(x, y, string) hinzufügen oder eine Skala für den Zeitraum zeichnen lassen.

Übrung: Passe die Funktion showCountry so an, dass sie eine durchgehene Linie statt einer Folge von Punkten zeichnet..

Daten transformieren

Ziel

Schreib auf eigene Faust ein Programm, dass einen Datensatz zusammen fasst.

Anweisungen

Im Programm für diesen Schritt, gibt es die Funktion visualizeHistory, die der zuvor genutzten Funktion showCountry sehr ähnlich ist, die aber einen Graphen für beliebige Daten zeichnen kann. Sie nimmt als Parameter ein Array mit Zahlen und eine vertikale Einheit entgegen. Die vertikale Einheit gibt an, wieviel vertikalen Raum eine Einheit des Zahlen-Arrays einnimmt.

Vervollständige die Funktion showWorldPopulation. Sie soll die Weltbevölkerung für jedes der Jahre im Datensatz berechnen, die Ergebnisse in ein Array speichern und damit die Funktion visualizeHistory aufrufen.

Um ein Array aufzufüllen kannst du folgende Technik verwenden

var newArray = []; // empty
for (var i = 0; i < 10; i = i + 1) {
  newArray.push(i);
}

Die Funktion push ist eine Eigenschaft (Methode) jedes Arrays und fügt dem Array einen Wert hinzu.

Um die richtige vertikale Einheit für deinen Graph zu bestimmen, musst du die maximale Weltbevölkerung, der dein Programm begegnet, speichern. Das kannst du entweder mit if und dem >-Operator tun, oder mit der Funktion Math.max, die zwei Zahlen als Parameter nimmt und die größere der beiden zurück gibt.

Erklärung

Die Daten sind nicht im geeignetsten Format, um die Bevölkerung pro Jahr zusammen zu zählen. Dafür hätten wir lieber die Möglichkeit, eine Sammlung aller Bevölkerungszahlen eines Jahres direkt zu erhalten.

Trotzdem kommen wir an die Daten heran, indem wir eine Schleife in einer Schleife verwenden, wobei die äußere Schleife über die Jahre läuft (zum Beispiel mit countryData[0].population.length als Gesamtzahl des Zeitraums), und die innere Schleife über die Länder. So kann die Bevölkerungszahl für das aktuelle Jahr aus jedem Land geholt werden und zur Gesamtzahl für das Jahr addiert werden. Es ist wichtig, dass der Zähler für die Gesamtzahl eines Jahres am Beginn der äußeren Schleife zurück gesetzt wird.

Probier es aus! Falls du nicht weiterkommst, stelle einen Coach auf die Probe.

Einige andere Ideen, um interessante Darstellungen aus diesen Daten zu erschaffen:

Und damit kommen wir zu

→ Vierte und letzte Seite für Samstag.