Hallo,
ich suche schon seit längerem ein PHP oder Javascript Programm, mit dem
man eine Fallblattanzeige (wie am Flughafen Frankfurt die Klapperdinger)
simuliert. Man sollte eine Funktion haben, mit der man bestimmte Zeilen
auf einen neuen Wert bringt.
Mein eigener Versuch ist daran gescheitert, die Anzeige (von Berlin nach
Frankfurt) bei der ersten stelle bei F, bei der 2. Stelle bei R, u.s.w.
anzuhalten.
Mein verwendeter Zeichensatz ist folgender:
> $fertig[stelle] ist ein Array, wenn es auf 1 ist ist die Stelle fertig
4
>
5
> for (jedes Zeichen aus $auf){
6
>
7
> finde index-Nummer aus $buchstaben für das Zeichen, addiere 1 und wandle
8
> sie in einen Buchstaben um.
9
>
10
> Wenn der Buchstabe = dem Buchstaben der Stelle in $von ist, setze
11
> $fertig[stelle]auf 1.
12
>
13
> setze $final auf das Wort (Berlin->Cfsmjo)
14
>
15
> zeige das Wort in der Zeile an (schon von mir gelöst)
16
>
17
> warte 200ms.
18
> }
19
> }
20
>
Sollen alle Stellen gmeinsam um 1 Blatt weiterfallen, falls noch nicht
notwendig, oder geht das von links nach rechts? (also erst mal die 1.
Stelle auf den richtigen Buchstaben, dann die 2. Stelle, etc. ....)
Mal davon abgesehen, dass man das Array eigentlich nicht wirklich
braucht, solltest du dir in deinem Pseudocode mal die Frage stellen: was
mach ich eigentlich mit dem Array.
SOll heissen: du vermerkst zwar, dass eine Stelle fertig ist, aber du
verwendest diese Information nirgens.
Abgesehen davon, kommt mir der Anstz zweifelhaft vor.
Worum geht es denn? Es geht doch darum, dass an einer bestimmten Stelle
der aktuell angezeigte Buchstabe identisch ist mit dem Buchstaben der
dort stehen sollte oder nicht.
Sind die beiden identisch, dann braucht an dieser Stelle nix mehr
passieren. Sind sie nicht identisch, dann wird ein Buchstabe weiter
geschaltet (und nicht vergessen: es muss am Anfang wieder angefangen
werden, wenn man am Ende ist)
1
solange die Anzeige nicht völlig korrekt ist {
2
3
für alle Stellen {
4
5
if aktuell angezeigter Buchstabe an dieser Stelle == Sollbuchstabe an dieser Stelle
6
mach nichts
7
else
8
zeige den nächsten Buchstaben aus dem Vorrat an (lass ein Blatt fallen)
9
}
10
11
warte ev. ein bischen, damit auch alle Blätter fallen können
könnte man zb damit realsieren, dass man ganz einfach mitzählt, wieviele
Buchstaben in einem Durchgang durch alle Stellen bereits korrekt sind.
Wenn diese Anzahl identisch ist mit der Anzahl der STellen insgesammt,
dann sind offensichtlich alle Stellen korrekt und der Zieltext steht
komplett in der Anzeige.
1
wiederhole {
2
3
korrekteStellen = 0
4
5
für alle Stellen {
6
7
if aktuell angezeigter Buchstabe an dieser Stelle == Sollbuchstabe an dieser Stelle
8
korrekteStellen = korrekteStellen + 1
9
else
10
zeige den nächsten Buchstaben aus dem Vorrat an (lass ein Blatt fallen)
11
}
12
13
warte ev. ein bischen, damit auch alle Blätter fallen können
14
15
} solange korrekteStellen ungleich Anzahl der Stellen
Karl Heinz schrieb:> Sollen alle Stellen gmeinsam um 1 Blatt weiterfallen,
ja
Karl Heinz schrieb:> SOll heissen: du vermerkst zwar, dass eine Stelle fertig ist, aber du> verwendest diese Information nirgens.
Was ich vergessen habe:
1
if($fertig[stelle]!=1)
2
umfallen
3
}
Karl Heinz schrieb:> Mal davon abgesehen, dass man das Array eigentlich nicht wirklich> braucht, solltest du dir in deinem Pseudocode mal die Frage stellen: was> mach ich eigentlich mit dem Array.> SOll heissen: du vermerkst zwar, dass eine Stelle fertig ist, aber du> verwendest diese Information nirgens.
Das ist mir kurz nach dem Absenden aufgefallen, dass ich das vergessen
habe.
Karl Heinz schrieb:> wiederhole {>> korrekteStellen = 0>> für alle Stellen {>> if aktuell angezeigter Buchstabe an dieser Stelle == Sollbuchstabe> an dieser Stelle> korrekteStellen = korrekteStellen + 1> else> zeige den nächsten Buchstaben aus dem Vorrat an (lass ein Blatt> fallen)> }>> warte ev. ein bischen, damit auch alle Blätter fallen können>> } solange korrekteStellen ungleich Anzahl der Stellen
Das wäre ja dieser PHP-Code:
Karl Heinz schrieb:> könnte man zb damit realsieren, dass man ganz einfach mitzählt, wieviele> Buchstaben in einem Durchgang durch alle Stellen bereits korrekt sind.> Wenn diese Anzahl identisch ist mit der Anzahl der STellen insgesammt,> dann sind offensichtlich alle Stellen korrekt und der Zieltext steht> komplett in der Anzeige.
Ist eine Möglichkeit.
Eine andere, noch einfachere:
Wenn beim Durchlauf durch alle Stellen kein einziges mal es der Fall
war, dass ein Blatt fallen gelassen werden musste (weil ja schon der
richtige Buchstabe in dieser Stelle angezeigt wird), dann ist
offensichtlich ebenfalls die Anzeige bereits auf dem korrekten
Zielzustand und es muss kein weiterer Durchgang mehr erfolgen.
Flughafen schrieb:> Das wäre ja dieser PHP-Code:
Du musst sorgfältiger arbeiten!
Nein. das ist nicht die korrekte UMsetzung des Pseudocodes.
Ich hab mir schon was dabei gedacht, dass die Zählung der korrekten
Stellen vor JEDEM Durchlauf durch die Stellen wieder erneut bei 0
anfängt.
so stellst du nur fest, ob die letzte Stelle korrekt war
Du musst das anders herum aufziehen.
bevor du die Stellen durchgehst, triffst du die Annahme, dass alle
Stellen korrekt sind. Muss ein Blatt fallen gelassen werden, dann war
die Annahme offensichtlich falsch und wird zu 'sie waren nicht korrekt'
geändert
1
do {
2
3
sindKorrekt = 1 // Annahme: alles ist korrekt
4
5
für alle Stellen {
6
7
if( IstBuchstabe an dieser Stelle ungleich
8
SollBuchstabe an dieser Stelle ) {
9
10
umblättern
11
sindKorrekt = 0 // die Annahme war falsch
12
}
13
}
14
15
} while sindKorrekt ist gleich 0
Nachtrag:
Erst dann, wenn ein Durchlauf durch alle Stellen ergeben hat, dass diese
alle auf ihrem jeweiligen Zielbuchstaben stehen, erst dann muss nicht
mehr geblättert werden, 'sindKorrekt' wird nicht mehr auf 0 korrigiert
und die äussere Schleife endet.
Karl Heinz schrieb:> Flughafen schrieb:>> for($i=0;$i<$alle_stellen;$i++){>> if($aktuell_angezeigt[$i]==$nach[$i]){>> //Fertig>> $korrekt=1;>> }else{>> //Umblättern>> $korrekt=0;>> }>> echo $i $korrekt;//Stelle, Richtig>> }
Für jede Stelle prüft er, ob sie richtig ist. Wenn dies nicht so ist,
wird diese Stelle umgeblättert.
Karl Heinz schrieb:> so stellst du nur fest, ob die letzte Stelle korrekt war
Den Sinn dieser Aussage verstehe ich nicht. Es wird ja für jede Stelle
geprüft (for-Schleife)!
Flughafen schrieb:> Karl Heinz schrieb:>> Flughafen schrieb:>>> for($i=0;$i<$alle_stellen;$i++){>>> if($aktuell_angezeigt[$i]==$nach[$i]){>>> //Fertig>>> $korrekt=1;>>> }else{>>> //Umblättern>>> $korrekt=0;>>> }>>> echo $i $korrekt;//Stelle, Richtig>>> }>> Für jede Stelle prüft er, ob sie richtig ist. Wenn dies nicht so ist,> wird diese Stelle umgeblättert.>> Karl Heinz schrieb:>> so stellst du nur fest, ob die letzte Stelle korrekt war>> Den Sinn dieser Aussage verstehe ich nicht. Es wird ja für jede Stelle> geprüft (for-Schleife)!
Welchen Zweck hat denn die Varianle &korrekt?
Ja doch wohl, zu entscheiden, ob ein weiterer Durchlauf durch alle
Stellen notwendig ist, oder ob alle Stellen schon auf ihrem
Zielbuchstaben stehen.
Diese Aussage kann diese Variable nicht treffen, denn nachdem die
for-Schleife komplett durch ist, sagt sie nur aus, ob die letzte Stelle
(die ganz rechts) korrekt war oder nicht. Über alle Stellen links von
ihr weisst du deswegen ja nichts.
Du musst aber wissen, ob ALLE Stellen schon korrekt sind oder nicht!
Denn nur wenn ALLE Stellen korrekt sind, ist die ANzeige fertig im
Zielzustand. ALLE - nicht nur die Stelle ganz rechts.
Probiers halt mal mit einem Blatt Papier und 2 (kurzen) Namen aus.
Die Anzeige habe 4 Stellen und zeigt momentan "ROM" an. Sie soll auf
"PRAG" geändert werden
1
+---+---+---+---+
2
| R | O | M | |
3
+---+---+---+---+
4
5
P R A G
erste Stelle: angezeigt wird 'R'. Ziel wäre 'P'. Die beiden sind nicht
gleich, also muss umgeblättert werden
1
+---+---+---+---+
2
| P | O | M | |
3
+---+---+---+---+
4
5
P R A G
zweite Stelle: O und R sind nciht gleich. Also umblättern
1
+---+---+---+---+
2
| P | Q | M | |
3
+---+---+---+---+
4
5
P R A G
dritte Stelle: M und A sind nicht leich. Also umblättern
1
+---+---+---+---+
2
| P | Q | N | |
3
+---+---+---+---+
4
5
P R A G
vierte Stelle: Leerzeichen und G sind nicht gleich -> blättern
1
+---+---+---+---+
2
| P | Q | N | A |
3
+---+---+---+---+
4
5
P R A G
(damit ist dir for-schleife abgearbeitet)
Es erhebt sich die Frage: musste geblättert werden?
Ja, musste es. Also konnte zumindest vor dem Durchlauf die Anzeige nicht
richtig gewesen sein. Ein erneuter Duchlauf ist nötig.
erste Stelle: angezeigt wird P, Ziel ist P. Keine Aktion notwendig
1
+---+---+---+---+
2
| P | Q | N | A |
3
+---+---+---+---+
4
5
P R A G
zweite Stelle: Q versus R. sind nicht gleich. Also umblättern
1
+---+---+---+---+
2
| P | R | N | A |
3
+---+---+---+---+
4
5
P R A G
dritte Stelle: N versus A. nicht gleich. Also blättern
1
+---+---+---+---+
2
| P | R | O | A |
3
+---+---+---+---+
4
5
P R A G
vierte Stelle: A versus G. sind nicht gleich. Also blättern
1
+---+---+---+---+
2
| P | R | O | B |
3
+---+---+---+---+
4
5
P R A G
wir sind durch. Mussten wir blättern? Ja, mussten wir. Daher: neuer
Durchgang
erste Stelle: P versus P. Das passt
zweite Stelle: R versus R. Passt ebenfalls
dritte Stelle: O versus A. Passt nicht -> blättern
1
+---+---+---+---+
2
| P | R | P | B |
3
+---+---+---+---+
4
5
P R A G
vierte Stelle: B versus G. passt nicht. blättern
1
+---+---+---+---+
2
| P | R | O | C |
3
+---+---+---+---+
4
5
P R A G
wieder: wir sind durch. mussten wir blättern? Ja -> neuer DUrchgang
P versus P: passt
R versus R: passt
O versus A: passt nicht, blättern
1
+---+---+---+---+
2
| P | R | P | C |
3
+---+---+---+---+
4
5
P R A G
vierte Stelle: C versus G. passt nicht. blättern
1
+---+---+---+---+
2
| P | R | P | D |
3
+---+---+---+---+
4
5
P R A G
usw. usw.
So gehts immer weiter. die Stellen 3 und 4 werden sukzessive weiter
geblättert, bis die Stelle 4 (bald) beim G angekommen ist.
Und irgendwann ist es dann auch soweit, dass die Stelle 3 am Ende des
Alphabets angekommen ist, wieder am Anfang mit einem Leerzeichen anfängt
und dann auf das A klappt.
Und dann hast du einen Durchlauf
P versus P: passt
R versus R: passt
A versus A: passt
G versus G: passt
Alle Stellen wurden durchsucht. Es musste nicht geblättert werden. Ergo
ist die Anzeige vollständig um geschaltet.
Was lesen wir
1
+---+---+---+---+
2
| P | R | A | G |
3
+---+---+---+---+
4
5
P R A G
Genau so, wie es ja auch sein soll. Die Zielvorgabe war ja Prag.
Karl Heinz schrieb:>>>> echo $i $korrekt;//Stelle, Richtig
Das Script gibt jedes mal aus, ob die Stelle xyz richtig ist.
Da steht dann z.b.
0 0
1 0
2 1
3 0
d.h. Nur die 2. Stelle ist korrekt.
Karl Heinz schrieb:> Welchen Zweck hat denn die Varianle &korrekt?> Ja doch wohl, zu entscheiden, ob ein weiterer Durchlauf durch alle> Stellen notwendig ist, oder ob alle Stellen schon auf ihrem> Zielbuchstaben stehen.
Wenn $korrekt beinhalten würde, ob alle korrekt sind, stimmt die
Aussage.
Flughafen schrieb:> Karl Heinz schrieb:>>>>> echo $i $korrekt;//Stelle, Richtig>> Das Script gibt jedes mal aus, ob die Stelle xyz richtig ist.> Da steht dann z.b.> 0 0> 1 0> 2 1> 3 0>> d.h. Nur die 2. Stelle ist korrekt.
Schön.
Nur interessiert das überhaupt nicht.
Sieh dir das Beispiel durch. Nachdem alle Stellen abgearbeitet sind,
will ich wissen, ob irgendeine Stelle falsch war oder nicht.
> Wenn $korrekt beinhalten würde, ob alle korrekt sind, stimmt die> Aussage.
Genau.
Nur ist das nicht die Aussage, die $korrekt nach Abarbeitung aller
Stellen in deinem Code macht. In deinem Code
1
for($i=0;$i<$alle_stellen;$i++){
2
if($aktuell_angezeigt[$i]==$nach[$i]){
3
//Fertig
4
$korrekt=1;
5
}else{
6
//Umblättern
7
$korrekt=0;
8
}
9
}
10
11
// Hier(!) will ich wissen, ob alle korrekt waren oder nicht!
12
// Es ist völlig uninteressant, welche Stelle nicht korrekt war. Wichtig
13
// ist nur, ob irgendeine nicht korrekt war oder nicht.
14
echo $korrekt;
enthält $korrekt nach der for-Schleife den Status der letzten Stelle.
Wenn wir dein konstruiertes Beispiel mal umdrehen:
1
> 0 1
2
> 1 1
3
> 2 0
4
> 3 1
Alle Stellen sind korrekt, nur die Stelle 2 ist es nicht.
Dass die Stelle 3 den Status 1 hat, ist zwar schön, wenn man die
einzelnen Stellen mitloggen möchte, aber nachdem alle Stellen
abgearbeitet wurden, will ich wissen, ob bei irgendeiner Stelle eine 0
aufgetreten ist. Denn diese 0 zwingt mich ja dazu einen weiteren
Durchlauf durch alle Stellen anzuhängen. Die 0, die in der Stelle 2
aufgetreten ist, ist dazu der entscheidende Auslöser. Diese 0 geht aber
verloren, sobald du Stelle 3 untersuchst und da zu einer 1 in $korrekt
kommst.
Flughafen schrieb:
...
> Mein verwendeter Zeichensatz ist folgender:$buchstaben = array("> ","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R ",> "S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9",> ".",",","&","!","?","-","_","ü","Ü","ä","Ä","ö","Ö","ß",");
Das sind übrigens zu viele Zeichen. Gewöhnlich haben Fallblattpaletten
39 oder 40 Blätter.
Die bis in die letzten Jahren bei der Deutschen Bahn auf den Bahnsteigen
als Zugzielanzeiger eingesetzten Module verfügten z.B. nur über die
Großbuchstaben „A“ bis „Z“, die Umlaute „Ä“, „Ö“ und „Ü“ sowie die
Ziffern „0“ bis „9“ und die Sonderzeichen „_“ „-“ und „/“. "?","!" und
Satzzeichen sind optional vorhanden.
aus de.wikipedia.org
Daniel Schuhmann schrieb:> Das sind übrigens zu viele Zeichen. Gewöhnlich haben Fallblattpaletten> 39 oder 40 Blätter.
In Wikipedia steht das aber nicht so!
Karl Heinz schrieb:> for($i=0;$i<$alle_stellen;$i++){> if($aktuell_angezeigt[$i]==$nach[$i]){> //Fertig> $korrekt=1;> }else{> //Umblättern> $korrekt=0;> }> }>> // Hier(!) will ich wissen, ob alle korrekt waren oder nicht!> // Es ist völlig uninteressant, welche Stelle nicht korrekt war.> Wichtig> // ist nur, ob irgendeine nicht korrekt war oder nicht.> echo $korrekt;
Ich wollte aber erstmal, dass das Programm die Korrektheit der Stellen
ausgibt. Dies dann verarbeiten erst im nächsten Schritt.
Ich bin zwar auch ein Freund vom schrittweisen vorgehen.
Aber wenn mir wer einen simplen 5 Zeilen 'Algorithmus' im Detail
vorkaut, dann kann man das schon mal riskieren, den in einem Schritt zu
implementieren.
Coole Idee, eine Fallblattanzeige Simulieren! Das muss ich auch mal
versuchen...
Im Anhang ist eine noch unvollständige, jedoch Funktionsfähige
Fallblattanzeigen Simulation mit JavaScript und CSS3, sowie ein Beispiel
in HTML5.
Daniel A. schrieb:> FlapDisplay.js (5,47 KB, 5 Downloads)> FlapDisplay.css (2,31 KB, 5 Downloads)> index.html (1,12 KB, 5 Downloads)
Tolle Anzeige! Besonders die Fallanimation gefällt mir. Ich finde es
eine gute Idee, die Uhrzeit anzuzeigen.
Flughafen schrieb:> In den letzten 2 Tagen habe ich mal programmiert, und das ist> herausgekommen:
Da ist aber noch ein Fehler drinnen.
Wenn man genau schaut, und sich die Ausgabe ein wenig verlangsamt. dann
taucht da ein paar mal 'undefined' in der Ausgabe auf.
(Das Problem ist, dass die for-Schleife immer komplett durchläuft und
nicht aufhört, sobald das Zeichen gefunden wurde. Dadurch findest du
immer das letzte der beiden Leerzeichen in deinem Zeichensatz. Das aber
hat keinen Nachfolger mehr, wodurch das hier
1
...
2
ziffer++;
3
buchstabe=zeichensatz[ziffer];
4
...
auf ein nicht existierendes Element im Array zugreift.
Ich würde halt ganz einfach nach dem ziffer++ überprüfen, ob ziffer
dadurch größer geworden ist, als es Elemente im Array gibt. Und wenn ja,
dann einfach ziffer auf 0 setzen.
Dann braucht man auch diesen Trick
1
var zeichensatz = new Array(" ","A", ......... "ß"," ");
Wenn bei folgendem code Ziffer das letzte Zeichen war, ist
zeichensatz[ziffer] undefined:
1
ziffer++;
2
buchstabe=zeichensatz[ziffer];
Das nächste Zeichen kann mittels folgender Rechnung ermittelt werden:
1
ziffer = (ziffer+1)%zeichensatz.length;
2
buchstabe=zeichensatz[ziffer];
Wenn das Zeichen jetzt nicht in der Liste wahr, ist ziffer -1 und
(-1+1)%zeichensatz.length ist 0.
Wenn (ziffer+1) gleich zeichensatz.length ist, ist
(ziffer+1)%zeichensatz.length gleich 0
Ansonsten ergibt hier (ziffer+1)%zeichensatz.length immer ziffer+1
Das % ist die modulo Operation. Dieser gibt den Rest einer Division
zurück.
Daniel A. schrieb:> Das hier macht Garnichts://Ausgabe> $(document).ready(function() {>> });
Das stimmt, das hatte ich nur nicht gelöscht.
Daniel A. schrieb:> Die funktion welche den Index des Zeichens im Zeichensatz ermittelt:> for(var i = 0;i<zeichensatz.length;i++){> if(zeichen==zeichensatz[i]&&zeichen!="undefined"){> ziffer=i;> gefunden=1;> }> }> if(gefunden==0){> Kann durch indexOf ersetzt werden:> var ziffer = zeichensatz.indexOf(zeichen);> if(ziffer==-1){
Das ist eine gute Idee, das so zu machen, da der Code dann kürzer und
übersichtlicher ist.
Daniel A. schrieb:> <link rel="stylesheet" type="text/css" hrref="css.css"/>
Den Fehler habe ich direkt mitkorrigiert und das Stylesheet ins Dokument
gepackt (ist ja nicht viel).
Flughafen schrieb:> Hier ist der Code für eine 3-Zeiliege Anzeige:
Hmm.
Stimmt wohl noch nicht so ganz. Siehe Bild
Die Leerzeichen nach 'Hamburg' sind alle weg. Und bei PUENKTLICH fehlt
das H.
Muss schon sagen: du testest ein wenig schlampig. Das ist jetzt deine
zweite Lösung, die man nach 15 Sekunden als fehlerhaft erkennen kann. Du
musst dir deine Ergebnisse schon ein wenig genauer ansehen. Denn deine
Kunden werden das irgendwann mal tun!
Das klassische 'Made in Germany' stand einmal weltweit für
Zuverlässigkeit und Fehlerfreiheit.
Ganz abgesehen davon. Da läuft nur die 3.te Zeile. Was ist mit den
anderen beiden?
Karl Heinz schrieb:> Die Leerzeichen nach 'Hamburg' sind alle weg
Nein, sind sie nicht. Sie werden nur nicht angezeigt.
Mit der CSS proterty white-space:pre; sollte sich dass beheben lassen.
PS: Die neuste Version meiner Implementierung eines FlapDisplays ist
immer unter http://87.102.188.235/FlapDisplay/ zu finden und darf von
jedem uneingeschränkt genutzt werden.
Karl Heinz schrieb:> Muss schon sagen: du testest ein wenig schlampig.
Das Problem ist eigentlich ein schönes Einsteigerbeispiel zum Test
Driven Development. Das geht auch ohne Framework auf printf-Niveau.
Karl Heinz schrieb:> Ganz abgesehen davon. Da läuft nur die 3.te Zeile. Was ist mit den> anderen beiden?
Den habe ich nur nicht den Befehl gegeben, sich umzustellen. Möglich ist
es mit window.setTimeout('umstellen (2,"KOELN-BONN 9:15 B03
ANNULLIERT","HAMBURG 23:58 C34 PUENKTLICH")',1000);.
Jede Fallblattanzeige braucht ihren eigenen Zahler, und ihr eigene
variable "fertig". Zudem sollte redundanter Code vermieden werden.
In JavaScript gibt es 3 scopes:
Den Globalen scope: Alle Variabeln ausserhalb einer Funktion sind in
window[variablenname] zu finden, alle Variabeln im Obect window sind
innerhalb ihres Browserfensters/Frame Global.
Der Locale scope: Wird in einer Funktion eine locale Variable oder
Funktion definiert, ist diese nur Innerhalb der Funktion verfügbar. Es
gibt keinen Block scope!
Die Closure: Wenn bei einem Funktionsaufruf eine Lokale Funktion
definiert wird, Erbt diese alle Localen Variabeln aller darüberliegenden
Funktionen. Dessen scope wird dan als "Closure" bezeichnet.
Daniel A. schrieb:> Jede Fallblattanzeige braucht ihren eigenen Zähler, und ihr eigene> variable "fertig". Zudem sollte redundanter Code vermieden werden.
Daran hatte ich schon gedacht. Meine Idee war es, in der Variable fertig
die Zeile zu vermerken, also etwa so:
1
fertig[zeile][nr]
Das umzusetzen habe ich dann aber nicht geschafft.
Daniel A. schrieb:> In JavaScript gibt es 3 scopes:> ...
Was sollen mir diese Informationen bringen?
Die einzeilige Anzeige funktioniert gut.
Jetzt brauche ich nur einen Code für eine mehrzeilige Anzeige (wie im
Bild), bei der mehrere Zeilen gleichzeitig umstellbar sind. Die Anzeige
sollte bis auf mindestens 5 Zeilen erweiterbar sein.
Daniel A. schrieb:> Jede Fallblattanzeige braucht ihren eigenen Zähler, und ihr eigene> Variable "fertig".
Die Funktion hat schon eine Variable 'zeile', mit der die Zeile bestimmt
werden soll. Die Ausgabe soll in den <div> Elementen sein. Die id darf
angepasst werden.
> Daniel A. schrieb:>> In JavaScript gibt es 3 scopes:>> ...>> Was sollen mir diese Informationen bringen?
a) Algemeinwissen
b) Ein Scope definiert den Gültigkeitsbereich einer Variable.
Bei jedem Funktionsaufruf werden neue Referenzen auf dessen lokale
variabeln erzeugt. Deshalb sind z.B. Rekursionen möglich.
Du kannst die variablen "Zahler" und "Fertig" In einem Localen Scope
anlegen, und lange nachdem es diesen nichtmehr gibt auf dessen locale
variabeln mit dem Closure scope zugreifen. Das ist besonder nützlich,
wenn man in JavaScript objectorientiert programmieren will.
Beim Objektorientierten Programieren ist das keyword new besonders
wichtig.
Der symtax ist new Funktionsname(argument1,...);
Es erstellt ein Object, bei welchem das feld "constructor" auf die
funktion Funktionsname gesetzt wird, ruft die Funktion mit this=object
auf, und gibt das Objekt zurück.
Dieses wissen kann man nun folgendermassen anwenden:
1
function Person(name){
2
var alter=0; // alter und name sind hier im Localen scope
Flughafen schrieb:> Daniel A. schrieb:> Jede Fallblattanzeige braucht ihren eigenen Zähler, und ihr eigene> variable "fertig". Zudem sollte redundanter Code vermieden werden.
Wie stellst du die Umsetzung davon vor?
Jetzt ist unten noch eine Eingabemöglichkeit dazugekommen, mit der man
(mit den entsprechenden Befehlen) die Anzeige beeinflussen kann, um z.B.
Veränderungen einzutragen. Das CSS-Stylesheet ist das gleiche wie davor.
Jetzt möchte ich, dass ein bestimmter Flugplan angezeigt wird. Das
bedeutet, dass es eine Datei oder ein Array gibt, in dem Flüge und
Zeiten stehen.
Beispiel:
1.Flug: HAMBURG 09:47 PÜNKTLICH ,9,47
2.Flug: MUENCHEN 10:45 VERSPAETET,10,45
...
Die Anzeige zeigt die ersten 10 Flüge vor der aktuellen Uhrzeit an. Wenn
es dann 09:47 Uhr wird, soll der Flug nach HAMBURG von der Tafel
weggeklappert werden. Dann ist der Flug nach MUENCHEN wieder erster, bis
es 10:45 Uhr ist. Dann ist dieser weg u.s.w..
Immer zum Minutenumsprung (also bei xx,00 Minuten) soll geprüft werden,
op ein Flug von der Tafel verschwinden muss. Dies muss in jeder Zeile
geprüft werden und ggf. ausgeführt werden.
Flughafen schrieb:> Jetzt möchte ich, dass ein bestimmter Flugplan angezeigt wird. Das> bedeutet, dass es eine Datei oder ein Array gibt, in dem Flüge und> Zeiten stehen.
Du könntest auch echte daten von http://transport.opendata.ch verwenden.
Flughafen schrieb:> Das stimmt zwar, erst benötige ich aber das Script.
Dann versuche es selbst, und Poste deinen versuch. Dann wird das Forum
sicher viel kommunikativer, und man lernt dabei auch etwas. Wenn du die
Daten als strings in einem array hast, kannst du die zeit von den
strings mit der funktion match, parseInt, und etwas arithmatik
isolieren. Das updaten der anzeigen wird dann zu einer simplen schleife
und einem vergleich. Die aktuelle zeit in ms bekommt man mit Date.now().
Die idee find ich wieder witzig, deshalb hab ich sowas mal mit meinem
flapdisplay, und der nächstgelegenen tram/bus/zughaltestelle in der
schweiz ausprobiert:
http://87.102.188.235/FlapDisplay/ankunft.html
Okay, hier mein Ansatz:
1. Ich definiere ein Array mit allen Flügen
1
var flug = new Array();
2
flug[1045]="HAMBURG ";
flug[1045] ist dabei ein Flug um 10:45 Uhr und flug[1145] ist ein Flug
um 11:45 Uhr.
2. Funktion planumstellen()
1
function planumstellen (){
2
3
}
3. In der Funktion: Zeit ermitteln
1
var date = new Date();
2
var h = date.getHours()+"";
3
var m = date.getMinutes()+"";
4. In der Funktion: noch 3 Variablen definieren
1
var index="";
2
var anzahl_angezeigter_fluege=0;
3
var flug_zwischenspeicher;
Die Variable index beinhaltet die index-Nummer des flug-Arrays (dazu
später)
Die Variable anzahl_angezeigter_fluege erklärt sich von selbst.
5. In der Funktion: Maximal 10 Flüge herausfinden
1
for(var i=m;i<60;i++){
2
index=h+i+"";
3
if(typeof flug[index] != "undefined"){
4
5
}
6
}
Hiermit wird für jede Minute der aktuellen Stunde ein Code ausgeführt:
Die Variable index erhält zunächst ihren Wert. Wenn ein Flug um diese
Zeit ausgeführt wird, wird die if durchlaufen.
6. In der Funktion: In der if: Flug speichern
1
anzahl_angezeigter_fluege++;
2
flug_zwischenspeicher=flug[index];
7. In der Funktion: In der if: ???
1
Jetzt muss der Flug in die Zeile anzahl_angezeigter_fluege gesetzt werden.
Flughafen schrieb:> var flug = new Array();> flug[1045]="HAMBURG ";
Das Verbraucht enorm viel Speicher, weil das Array danach 1045
objekreferenzen gross ist. Für soetwas nimmt man kein Array, sondern ein
Object. Und wass passiert, wenn zwei flieger gleichzeitig losfliegen?
Die Informationen sollten im gleichen objekt stehen, und die objekte in
einem array:
> 4. In der Funktion: noch 3 Variablen definieren>
1
> var index="";
2
> var anzahl_angezeigter_fluege=0;
3
> var flug_zwischenspeicher;
4
>
> Die Variable index beinhaltet die index-Nummer des flug-Arrays (dazu> später)> Die Variable anzahl_angezeigter_fluege erklärt sich von selbst.
Ich denke das ist überflüssig
> 5. In der Funktion: Maximal 10 Flüge herausfinden>
1
> for(var i=m;i<60;i++){
2
> index=h+i+"";
3
> if(typeof flug[index] != "undefined"){
4
>
5
> }
6
> }
7
>
Da ist doch noch garkeine mengenbeschränkung? Ich würde dass so lösen:
1
var lines=[];
2
var lineCount=10;
3
while(fluege.length&&fluege[0].abflugzeit<date)
4
fluege.splice(0,1); // bereits abgeflogen, aus liste entfernen...
5
for(var i=0;i<lineCount;i++){
6
var entry="";
7
if(i<fluege.length){
8
var flug=fluege[i];
9
entry = flug.nach; // hier zeile zusammensetzen
10
}
11
lines[i]=entry;
12
}
> 6. In der Funktion: In der if: Flug speichern>
1
> anzahl_angezeigter_fluege++;
2
> flug_zwischenspeicher=flug[index];
3
>
Du suchst wmöglich die Methode Array.prototype.slice?
Daniel A. schrieb:> Das ergibt irgendwie keinen sinn???
Doch. Wenn der Flug 1045 in Zeile eins muss, dann ist der Befehl
eins.umstellen.callAfter(eins,1000)("HAMBURG
");.
Für Zeile Zwei zwei.umstellen.call...
3 drei.umstellen.callafter(drei,10...
...
Das meinte ich damit.
Daniel A. schrieb:> var fluege=[> {> "abflugzeit": "2014-10-25T12:00",> "nach": "Hamburg"> },> {> "abflugzeit": "2014-10-25T12:01",> "nach": "Berlin"> }> ];
Das ist zwar aufwendiger zu definieren und nimmt mehr Codezeilen weg,
bietet aber mehr Raum für Erweiterungen wie z.B. mit Uhrzeit.
Daniel A. schrieb:> var lines=[];> var lineCount=10;> while(fluege.length&&fluege[0].abflugzeit<date)> fluege.splice(0,1); // bereits abgeflogen, aus liste entfernen...> for(var i=0;i<lineCount;i++){> var entry="";> if(i<fluege.length){> var flug=fluege[i];> entry = flug.nach; // hier zeile zusammensetzen> }> lines[i]=entry;> }
Die for-Schleife verstehe ich noch nicht vollständig. Wie bekommt die
Variable flug immer nur die 10 aktuellen Flüge?
Es ergibt sich außerdem das Problem, dass flug.nach und flug.uhrzeit
eine bestimmte Anzahl Stellen haben müssen, weil sonst nicht die Anzahl
der Zeichen für die umstell-Funktion erfüllt ist. Sollte das nicht
besser in der umstell-Funktion geändert werden, dass sie mit Leerzeichen
auffüllt?
Es steht noch nicht drin, wo und wie der Flug angezeigt werden muss.
Steht der Flug für Zeile 1 in lines[1] und für Zeile i<lineCount in
lines[i]? Wenn Ja, muss keine Funktion definiert werden, die alle Flüge
um 1 verschiebt und dabei einen unten anfügt, weil alle Flüge in der
Variable stehen. Dies würde die Arbeit erleichtern.
Wo muss der neue Code denn hin?
Kann man es mit Uhr so definieren:
1
if(i<fluege.length){
2
var flug=fluege[i];
3
entry = flug.nach+flug.uhrzeit; // hier zeile zusammensetzen
Flughafen schrieb:> Die for-Schleife verstehe ich noch nicht vollständig. Wie bekommt die> Variable flug immer nur die 10 aktuellen Flüge?
Der trick ist, dass die flüge nach abflugzeit sortiert wurden:
Daniel A. schrieb:> fluege.sort(function(a,b){> return a.abflugzeit-b.abflugzeit;> });
und somit die bereits abgeflogenen zuoberst sind. Durch das entfernen
der bereits Abgeflogenen aus der Liste:
> while(fluege.length&&fluege[0].abflugzeit<date)> fluege.splice(0,1); // bereits abgeflogen, aus liste entfernen...
Fängt die Liste jetzt mit dem ersten noch nicht Abgeflogenen flugzeug
an. Da die Liste ja immernoch nach abflugzeit sortiert ist, kann man
einfach die ersten 10 einträge durchgehen.
Flughafen schrieb:> Es steht noch nicht drin, wo und wie der Flug angezeigt werden muss.> Steht der Flug für Zeile 1 in lines[1] und für Zeile i<lineCount in> lines[i]?
Genau. Und der für zeile 0 ist in lines[0]
Arrays beginnen immer mit index 0.
Flughafen schrieb:> Kann man es mit Uhr so definieren:> entry = flug.nach+flug.uhrzeit; // hier zeile zusammensetzen
Sicher, wenn du etwas sinnvolles nach flug.uhrzeit schreibst...
Obwohl man das sicher noch etwas besser formatieren könnte, z.B. mit
einem Abstand zwischen dem Ziel und der Zeit
Daniel A. schrieb:> Und der für zeile 0 ist in lines[0]
Okay, also muss danach noch die umstell-Funktion aufgerufen werden:
1
eins.umstellen.callAfter(eins,1000)(lines[0]);
2
zwei.umstellen.callAfter(zwei,1000)(lines[1]);
3
//u.s.w. bis
4
zehn.umstellen.callAfter(zehn,1000)(lines[9]);
Für das Uhrzeit-Problem:
Ein Flug besteht aus verschiedenene Teilen mit verschiedenen Längen:
Abflug,Zeit,Gate,Bemerkung 10,6,4,10.
Die Flugdefinition wäre also
1
var fluege=[
2
{
3
"abflugzeit": "2014-10-25T12:00",
4
"nach": "Hamburg"
5
"uhr": "12:00"
6
"gate": "A10"
7
"bemerkung": "PUENKTLICH"
8
},
9
{
10
"abflugzeit": "2014-10-25T12:01",
11
"nach": "Berlin"
12
"uhr": "12:01"
13
"gate": "A11"
14
"bemerkung": "PUENKTLICH"
15
}
16
];
In fluege muss jeder Flug auf die gewünschte Länge gebracht werden, so
dass aus "Hamburg" "Hamburg " wird. Daran arbeite ich im Moment noch.
Das neue Teilscript ist also das folgende:
Falsche Datei.
#3856155:
131 while(fluege.length&&fluege[0].abflugzeit<date)
ReferenceError: date is ot defined in line 131
Was ist das?
Flughafen schrieb:> "nach": "Hamburg"> "uhr": "12:00"> "gate": "A10"
muss heißen
"nach": "Hamburg",
"uhr": "12:00",
"gate": "A10",
Dan werden die Flüge richtig definiert.
Nach etwas rumgebastle hier eine funktionierende Datenbank-Version mit
zeitabhängiger Anzeige!
Datenbank:
1
DROP TABLE IF EXISTS `fluege`;
2
CREATE TABLE IF NOT EXISTS `fluege` (
3
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
4
`von` text,
5
`nach` text,
6
`std` int(2) DEFAULT NULL,
7
`mni` int(2) DEFAULT NULL,
8
PRIMARY KEY (`id`)
9
)DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;
10
11
INSERT INTO `fluege` (`id`, `von`, `nach`, `std`, `mni`) VALUES
12
(1, 'Hamburg', 'Koeln', 10, 35),
13
(2, 'Hamburg', 'Berlin', 11, 35),
14
(3, 'Muenchen', 'koeln', 12, 15),
15
(4, 'Moskau Vnukovo', 'Friedrichshafen', 01, 00),
16
(5, 'Hamburg', 'Koeln', 11, 55),
17
(6, 'Hamburg', 'Berlin', 11, 30),
18
(7, 'Muenchen', 'koeln', 15, 15),
19
(8, 'Moskau Vnukovo', 'Friedrichshafen', 23, 55);
Im Moment werden maximal 5 Zeilen umgestellt, dies ist aber natürlich
einfach erweiterbar!
Die Tabelle fluege in der Datenbank flugmanager hat folgende Spalten:
id, von, nach, std (Stunden), mni (Minuten). Einträge müssen ohne die
folgenden Zeichen sein: äöüß!"§$%&/()=?ÄÜÖ{[]}²³@€#'+*~´`,.-;:_ . Sonst
kann es Fehlermeldungen geben, und meistens stürzt der Browser ab. Es
sind also nur Buchstaben erlaubt. Es ist egal, ob die Zeichen groß oder
klein sind, das Script konvertiert mit strtoupper() automatisch. Gebaut
ist alles mit phpmyadmin 4.0.4 und PHP 5.4.16. Benutzername und Passwort
müssen natürlich ersetzt werden!
Eine neuere Version beinhaltet folgendes neues:
- Db-Tabelle hat nun char(10) für von und nach,
- Struktur der Flüge
- Zufällige Gate-Nr
- Zufälliges Annullieren (etwa alle 5 Flüge einer Annulliert)
- Sortieren der Flüge nach Stunden und Minuten
- Am Anfang Lade-Daten-Anzeige
- Nacheinander Aufblättern (Zeilenweises Anfangen)
- Erste 2 Zeilen fangen gleichzeitig an (wie in echt)
- Unnötiger Quellcode rausgeschmissen (Datei kleiner)
- Beispielprogramm abgeschafft
v1.2 fallblattanzeige_mit_steuerung.php:
- Automatischer Check jede Minute
- Text in URL mit GET vorhanden
- Umstellaufrufzeit verschnellert
- Zeitladezeit verkürzt
- Gate fest
- LADE-DATEN nur wenn Zeile nicht festgelegt ist oder der für die Zeile
festgelegte Wert nichts ist.
1
-- version 4.0.4
2
-- http://www.phpmyadmin.net
3
-- PHP-Version: 5.4.16
4
CREATE TABLE IF NOT EXISTS `fluege` (
5
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
6
`von` char(10) DEFAULT NULL,
7
`nach` char(10) DEFAULT NULL,
8
`gate` char(2) NOT NULL,
9
`std` int(2) DEFAULT NULL,
10
`mni` int(2) DEFAULT NULL,
11
PRIMARY KEY (`id`)
12
) DEFAULT CHARSET=utf8 AUTO_INCREMENT=11 ;
13
INSERT INTO `fluege` (`id`, `von`, `nach`, `gate`, `std`, `mni`) VALUES
14
(1, 'Hamburg', 'Koeln', 'A5', 10, 35),
15
(2, 'Hamburg', 'Berlin', 'B3', 11, 35),
16
(3, 'berlin s', 'koeln', 'C5', 18, 25),
17
(4, 'Moskau Vnu', 'Friedrichs', 'F9', 10, 10),
18
(5, 'Hamburg', 'Koeln', 'L4', 11, 55),
19
(6, 'Hamburg', 'Berlin', 'D5', 11, 30),
20
(7, 'Muenchen', 'koeln', 'A2', 15, 15),
21
(8, 'Moskau Vnu', 'Friedrichs', 'H1', 23, 55),
22
(9, 'Muenchen', 'berlin t', 'M3', 20, 35),
23
(10, 'Muenchen', 'berlin s', 'D2', 20, 35);
Für die Anzeige des Abflugflughafens muss der Code in der PHP-while
Schleife in folgendes geändert werden:
v1.3:
- Master Control
- mehr Zeichen
- error_reporting
- etwas langsamerer Umstelleffekt
Um die Master Control aufzurufen, muss an die URL
1
?master=
angehangen werden.
Da bei der voherigen Version der Zufall manchmal blöde Ergebnisse
geliefert hat (s. Bilder) ist er jetzt durch die Master-Control ersetzt
worden.
Ich habe mein Passwort geändert.
Damit man die update.php-Datei außerhalb betrieben kann, muss die Zeile
1
echo "<style>html,body {color:white;}</style>";
auf
1
echo "<style>html,body {color:black;}</style>";
geändert werden, um die Schrift schwarz zu machen.
Neues in der Version 1.4:
- Uhrzeit wird nun immer angezeigt.
- Spaltenüberschriften stimmen wieder
Die DB (Datenbank, nicht Deutsche Bahn) ist gleichgeblieben.
Falls jemand noch Ideen für eine kommende Version hat, soll er die bitte
schreiben, mir fällt langsam nichts mehr ein.
Ich habe mich mal angemeldet.
Für Version 2.0 ist schon geplant:
- update.php intigrieren und über SESSIONs aufrufen (=1 Datei)
- realitätsnahes Design
- Schwarzfahren (in echt bei Unfällen, damit keine falschen
Informationen angezeigt werden)
- Aufruf durch Knöpfe und nicht durch URL-Veränderungen
- Zeit durch PHP-Zeit ersetzen (schon fertig)
Ich bin aber noch nicht fertig.
Weitere Vorschläge hier schreiben oder mir per Mail senden.