Jump to content

Frage zu eine Anweisung in einem LUA-Skript


Empfohlene Beiträge

 

Hallo liebe LUA-Experten und auch alle anderen

In einem Skript wird mittels verschiedener Variablen die in den Fahrzeugen und/oder den Wagen gespeichert sind, die Seite ermittelt, auf der die Türen am Bahnsteig geöffnet werden sollen.

--[[-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Aktions-Skript "Türen am Bahnsteig öffnen"
    Parameterübergabe: Der aktuelle "Zug", der gerade gestoppt hat.

    Wird vom Ereignis: "Zug stoppt, evtl Türen öffnen" aufgerufen.
    Die Türen öffnen, wenn Zug am Bahnsteig hält und die Variable "Tueren" vorhanden ist.
------------------------------------------------------------------------------------------------]]

-- In der Zugvariablen "Bahnsteig" steht "rechts" oder "links"
-- In der Zugvariablen "Fahrtrichtung" steht "vorwärts" oder "rückwärts"

local BahnsteigSeite = ({["links"] = 0, ["rechts"] = 1})[Zug.variables["Bahnsteig"]]                       -- Aus "links" oder "rechts" wird die Variable "Bahnsteigseite" = 0 oder 1
local Fahrtrichtung = ({["vorwärts"] = 0, ["rückwärts"] = 1})[Zug.variables["Fahrtrichtung"]]       -- Aus "vorwärts" oder "rückwärts" wird die Variable "Fahrtrichtung" = 0 oder 1

for i, Wagen in pairs(layout:getVehicleGroup(Zug, 0)) do                                                            -- Alle Fahrzeuge im Zugverband lesen

  if Wagen.variables["Tueren"] ~= nil then                                                                                   -- Variable "Tueren" ist in einem Wagen vorhanden
    local Wagenrichtung = ({["links"] = 0, ["rechts"] = 1})[Wagen.variables["Türen in Fahrtrichtung"]] 
                                                                                                                                                      -- Aus "links" oder "rechts" wird die Variable "Wagenrichtung" = 0 oder 1

    if BahnsteigSeite and Fahrtrichtung and Wagenrichtung then                                                -- Wenn in diesen drei Variablen Werte stehen, dann ...

      local Seite = (BahnsteigSeite + Fahrtrichtung + Wagenrichtung) % 2 + 1                            -- die Variable "Seite" ergibt immer 1 oder 2

      local Tueren = Wagen.variables["Tueren"][Seite]                                                                   -- Seite:  1 = links  und  2 = rechts

      if Tueren then                                                                                                                         -- Die Variable "Tueren" hat den Wert 1 oder 2
        Wagen.animations[Tueren]:play(-1, 1)                                                                                  -- Dementsprechend öffnen sich die Türen, die in der Liste "Tueren" vom Wagen                                                                                                                                                                   -- oder Fahrzeug mit den Nummern 1 und 2 (links und rechts) stehen
      end                                                                                                                                                  
    end
  end
end                                                                                                                                                -- Skript- und Schleifen-Ende

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Vorausgesetzt, die Variablen in den Fahrzeugen sind alle richtig eingetragen, funktioniert das Türenöffnen hervorragend.

Meine Frage:
Welche Funktion in dieser Zeile:   "local Seite = (BahnsteigSeite + Fahrtrichtung + Wagenrichtung) % 2 + 1"  hat die Anweisung "% 2"          ??????
Ich verstehe den gesamten Funktionsablauf und kann auch die Zusammenhänge nachvollziehen. Aber die mathematische Logik dieser Anweisung ist mir unklar.
Entfällt die Anweisung "% 2" dann erhalte ich die möglichen Werte 1, 2, 3 oder 4, nämlich die einfache Addition der drei Variablen und der zusätzlichen "1" am Ende, aber so immer nur 1 oder 2, was ja auch super ist, aber eben wieso?

Ich hoffe mir kann jemand diese Frage beantworten.
Viele Grüße
Walter

Bearbeitet von WalterW
Textkorrektur
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 49 Minuten schrieb WalterW:

Welche Funktion ...  hat die Anweisung "% 2"          ?

Das % Zeichen ist der Modulo Operator in Lua (bitte nicht den Namen in Versalien schreiben. Das ist falsch und hässlich ;))

Modulo gibt den Rest einer Division aus.

x     = -8  -7  -6  -5  -4  -3  -2  -1   0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15
x % 4 =  0   1   2   3   0   1   2   3   0   1   2   3   0   1   2   3   0   1   2   3   0   1   2   3   


Wenn du eine ganze Zahl durch 2 teilst, kann der Rest nur 0 oder 1 sein, denn eine Zahl ist entweder gerade oder ungerade.

Für die Türen gibt es nur zwei Möglichkeiten. Entweder sind es die Türen links oder rechts. 0 oder 1
Und weil am Ende die Zahlen 1 und 2 gebraucht werden, wird zum Schluss noch 1 hinzu addiert.

Viele Grüße
Götz

Bearbeitet von Goetz
Ergänzungen
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 4 Minuten schrieb Goetz:

Lua (bitte nicht den Namen in Versalien schreiben.)

Ja, da legt Götz sehr viel Wert drauf. 👍

Ich habe das Skript mittlerweile so angepasst, so das die Ausrichtung der Fahrzeuge, also die „Wagenrichtung“ nicht mehr vorgegebenen werden muß, sondern anhand der Ausrichtung im Zug über die Lage der vorderen und hinteren Kupplung der Wagen vom Programm ermittelt wird. 
Gibt es dafür Interessenten? Dann stelle ich das neue Skript mal ein.

Viele Grüße,

Hawkeye

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Götz,

vor einer Stunde schrieb Goetz:

Lua (bitte nicht den Namen in Versalien schreiben. Das ist falsch und hässlich 

entschuldige bitt die "hässliche" und falsche Schreibweise. Ich hoffe ich habe Lua mit "LUA" nicht beleidigt:/ (Ich will dich nicht ärgern, war nur ein Scherz)
Zum Thema. Vielen Dank für deine schnelle Antwort, zu der ich aber noch eine Frage habe. Entweder ich habe zum Zeitpunkt, als das Thema in Mathe dran' war gepennt, Kreide geholt oder ... oder ...
Für mich ist ein Divisionsrest das Ergebnis einer Division, das was nach der Kommastelle im Ergebnis steht. Also
0 : 2 = 0    hat keine Nachkommastelle, also ist der Divisionsrest  0.
1 : 2 = 0,5 hat eine Nachkommastelle, also ist der Divisionsrest 5
2 : 2 = 1    hat keine Nachkommastelle, also ist der Divisionsrest  0.
3 : 2 = 1,5 hat eine Nachkommastelle, also ist der Divisionsrest 5

"Wenn du eine ganze Zahl durch 2 teilst, kann der Rest nur 0 oder 1 sein, ..."  hast du auch noch geschrieben

Bedeutet das, dass du damit sagen willst, dass das Divisionsrestergebnis immer eine ganze Zahl mathematisch aufgerundet ist? Wie denn ?
Denn mathematisch aufgerundet ist der Divisionsrest 5 = 5, und nicht 1.

Dann verstehe ich auch dein Beispiel nicht:
x        = -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
x % 4 =  0   1  2   3  0   1  2   3 0 1 2 3 0 1 2 3 0 1  2   3   0   1   2   3

-8 : 4 = -2       hat keine Nachkommastelle, also ist der Divisionsrest  0. OK
-7 : 4 = -1,75  hat zwei Nachkommastellen, also ist der Divisionsrest = 75 !  Wie kommt dann bitte das Ergebnis 1 zustande ?
6 : 4 = 1,5     hat eine Nachkommastelle, also ist der Divisionsrest = 5 ! Und wo kommt dein Ergebnisbeispiel 2 her ?

Ganz kurios ist ja das Ergebnis bei  -1 (=3) und 1 (=1) sowie -3 (=1) und 3 (=3). Das wiederholt sich auch bei anderen Werten.

Das einzige was ich daran erkenne ist, dass bei geraden Zahlen das Ergebnis 0 oder 2 ist und bei ungeraden Zahlen 1 oder 3 ist.

vor 1 Stunde schrieb Goetz:

Nun lass Walter doch bitte erst einmal verstehen, was ein Modulo Operator ist und tut.

Vielen Dank für Dein Vertrauen in mich, dass ich den Modulo Operator verstehe (Wie kann man einem solch intelligenten Teil nur einen so blöden Namen geben). Ich hab' wohl doch offensichtlich keine Ahnung. Bitte klär mich auf. Ich komme einfach nicht hinter die Logik.
Vielen Dank im Voraus

Viele Grüße
Walter

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo @WalterW,

Der Rest einer Division ist nicht das, was hinter dem Komma steht.

Laaange, bevor du in der Schule Brüche und Dezimalzahlen lernst, wird dir das hier beigebracht:

Dividieren mit Rest - YouTube,   Schriftliches Dividieren mit Rest - EINFACH ERKLÄRT | Mathematik | Lehrerschmidt - YouTube

 

Muster = "%d geteilt durch %d ist %d Rest %d"  

for i = 1, 20, 1 do
  local Text = Muster:format(i, 4, i//4, i%4)  
  print(Text)
end

-- doppelter Schrägstrich = ganzzahlige Division. 
-- Prozentzeichen = Modulo
-- im Muster-String ist das Prozentzeichen KEIN Modulo, sondern ein Platzhalter!

 

Ist wirklich laaange her. 
Aber in der Programmierung ist das ungemein nützlich.

Denk beispielsweise an die Uhr, die immer wieder von vorne beginnt.
Oder an eine Tabelle, die du immer wieder reihum abfragen möchtest.
Alles, was im weiteren Sinne einen Kreis darstellt, weil es am Ende wieder von vorne beginnt, ist ein Fall für Modulo

 

vor 58 Minuten schrieb WalterW:

Wie kann man einem solch intelligenten Teil nur einen so blöden Namen geben

Hier ist die Erklärung zum Namen

Viele Grüße
Götz

Bearbeitet von Goetz
zweiten Videolink hinzugefügt
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Walter,

vor einer Stunde schrieb WalterW:

Ich komme einfach nicht hinter die Logik.

Hier die Modulo - Definition aus dem Lua -Handbuch

2.5.1 – Arithmetische Operatoren

Lua unterstützt die geläufigen arithmetischen Operatoren: das binäre + (Addition), - (Subtraktion), * (Multiplikation), / (Division), % (Modulo) und ^ (Exponentiation) sowie das unäre - (Negation). Sofern die Operanden Zahlen – oder Zeichenketten, welche zu Zahlen konvertiert werden können (s. § 2.2.1) – sind, so haben alle Operationen die geläufige Bedeutung. Exponentiation funktioniert mit allen Exponenten; beispielsweise berechnet x^(-0.5) das Inverse der Quadratwurzel aus x. Modulo ist wie folgt definiert:

a % b == a - math.floor(a/b)*b

Dies ist der Rest der Division, welche den Quotienten auf -Unendlich rundet.

math.floor(x)

Liefert die größte Ganzzahl kleiner oder gleich x.

 

Vielleicht hilft dir das zum Verständnis.

VG,

Hawkeye

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Götz

Ich bin dir sehr dankbar für deine ausführliche Erklärung, dein Verständnis und die Geduld für jemanden, der wahrlich kurz davor war den Verstand zu verlieren. Wie kann es nur möglich sein, dass ich das (offensichtlich) Simpelste aus den mathematischen Grundrechenarten so vergessen habe? Ich tröste mich damit, dass das sooooooooooooooo laaaaaaaaaaange (müsste noch viel länger sein) her ist - und  jetzt die wichtigste Erklärung (Ausrede) : Die ab sofort verteufelten Rechenapparate und sonstigen Geräte (ich liebe Computer & Co), die es ermöglichen, ohne sein Gehirn einzuschalten,  Rechenoperationen durchzuführen, sind schuld !!!!! Denn mein Rechenknecht sagt: 9 : 2 = 4,5 und nicht 4 Rest 1. Für Blöde, wie mich, benötigt es weitere Funktionstasten. So, Schluss mit dem Gejammere, ran an den Apparat und weiter mit Lua und dem Modellbahn-Studio (macht viel zu viel Spaß).

Nochmals herzlichen Dank für die sehr nette, hilfreiche und ausführliche Erläuterung. ICH HABE ES JETZT VERSTANDEN !

Viele Grüße
Walter

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Hawkeye

Auch dir herzlichen Dank für die erklärenden Informationen. Ich muss allerdings zugeben, dass ich (offensichtlich mangels größerem Verständnis für höhere Mathematik) deine Inhalte besser verstehen konnte, nachdem ich den Grundschulnachhilfeunterricht ((y), tolles Wort oder?) von Götz erhalten habe. 
Man lernt halt nie aus. Nochmals besten Dank.

Viele Grüße
Walter

Link zu diesem Kommentar
Auf anderen Seiten teilen

Erstelle ein Benutzerkonto oder melde dich an, um zu kommentieren

Du musst ein Benutzerkonto besitzen, um einen Kommentar verfassen zu können

Benutzerkonto erstellen

Neues Benutzerkonto für unsere Community erstellen.

Neues Benutzerkonto erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde dich hier an.

Jetzt anmelden
×
×
  • Neu erstellen...