Jump to content

Recommended Posts

Tabellen - Teil 4

Eine Lua Tabelle kann Elemente vom Typ 'table' enthalten

Beispiel = { {1, 2, 3} , {63, 127, 255} , {true, true, false} }

Das Ergebnis hat Ähnlichkeit mit mehrdimensionalen Tabellen.
Die 63 im obigen Beispiel steht an Position Beispiel[2][1], nämlich im zweiten Block an erster Stelle.

Der Vergleich mit landläufigen Tabellen ist aber irreführend. Hilfreicher ist, die Lua-Tabellen einfach als Datensammlung zu verstehen. Sie haben in mancher Hinsicht mehr Ähnlichkeit mit Objekten als mit Tabellen. Deshalb müssen Lua-Tabellen nicht dimensioniert werden. Das heißt, dass man nicht (wie in anderen Sprachen) vorher die Anzahl der Zellen festlegen muss.

Bands = {
  Beatles = {"John", "Paul", "George", "Ringo"},
  Stones = {"Mick", "Keith", "Brian", "Ian", "Bill", "Charlie"},
  Who = {"Pete", "Roger", "John", "Keith"}
}
print(Bands.Stones[2]) 

Die Tabelle Bands enthält 3 Elemente, deren Index jeweils ein String ist. Nämlich der Bandname. Jedes der drei Elemente ist ebenfalls eine Tabelle. Die Elemente dieser Untertabellen sind einfache Aufzählungen. Der Index jedes Elements ist also eine Nummer, beginnend mit der Zahl 1 für das erste Element.

Beachtet bitte das Komma hinter jeder Untertabelle. Dieses Komma ist erforderlich, um die Elemente Beatles, Stones und Who voneinander zu trennen.

Die Zeilenumbrüche und Einrückungen in der Tabelle sind optional und dienen nur der Lesbarkeit. Man könnte ebenso gut den gesamten Tabelleninhalt in eine lange Zeile schreiben. Oder umgekehrt auf noch mehr Zeilen verteilen:

Bands = {
  Beatles = {
    "John", 
    "Paul", 
    "George", 
    "Ringo"
  },
  Stones = {
    "Mick", 
    "Keith", 
    "Brian", 
    "Ian", 
    "Bill", 
    "Charlie"
  },
  Who = {
    "Pete", 
    "Roger", 
    "John", 
    "Keith"
  }
}

Das ist reine Geschmacksache. Die Trennung der Elemente entsteht allein durch die Kommas und die geschweiften Klammern.

Aber aus Erfahrung kann ich empfehlen, Programmzeilen mit mehr als 80 Zeichen Länge zu vermeiden.

 

Im Übrigen werdet ihr im MBS keine großen Tabellen am Stück erstellen. Dazu besteht kein Grund. Diese Tabellen entstehen auf andere Weise. Aber es wird euch helfen, wenn ihr versteht wie Tabellen in Lua aufgebaut sind. Weil ihr später an einzelne Daten aus solchen Tabellen drankommen wollt. Weil ihr zum Beispiel von einem Zug den Namen des dritten Waggons benötigt:

Zuege = {
  {
    Name = "Gueterzug_1",
    Geschwindigkeit = 80,
    Typ = "Gueter",
    Lok = {
      Name = "V200",
      Typ = "Diesel",
      Kupplung_vorne = false,
      Kupplung_hinten = true
    },
    Waggons = {
      {
        Name = "G10",
        Typ = "Kasten",
        Kupplung_vorne = true,
        Kupplung_hinten = true
      },
      {
        Name = "Kbs",
        Typ = "Rungen",
        Kupplung_vorne = true,
        Kupplung_hinten = true
      },
      {
        Name = "OVP",
        Typ = "Tank",
        Kupplung_vorne = true,
        Kupplung_hinten = true
      },
      {
        Name = "G10",
        Typ = "Kasten",
        Kupplung_vorne = true,
        Kupplung_hinten = false
      },
    }
  }
} 
      
print(Zuege[1].Waggons[3].Name)

 

Share this post


Link to post
Share on other sites

Tabellen - Teil 5

Ihr habt nun gesehen, dass man in einer Tabelle Zahlen, Strings, Booleans und Tabellen speichern kann. Und das letzte Beispiel hat euch vielleicht gezeigt, warum das praktisch ist. Es geht bei Tabellen nur darum, eine Ansammlung von Daten vernünftig zu organisieren.

Das ist ungefähr so, als würde man alles, was zu einem bestimmten Waggon gehört, in eine Schachtel packen:
Seinen Namen, die Beschriftungen, die Länge, den Status der beiden Kupplungen, die Position beweglicher Teile etc.

Und dann einen Zug bilden, indem man eine Lok-Schachtel und mehrere Waggon-Schachteln hintereinander in eine große Zug-Schachtel steckt.

Das hat alles nur organisatorische Bedeutung. @wopitir schrieb mir gestern eine PN, in der er die ganze Tabellenstruktur mit den Ordnern und Unterordnern bei Windows verglich. Und das trifft es ganz gut.

 

Aber Lua Tabellen können noch mehr.
Man kann in einer Tabelle auch eine Funktion speichern.

Warum auch nicht?

Man speichert in Lua ja eigentlich nur die Adressen, unter denen etwas liegt. Ob an dieser Speicheradresse eine Zahl, ein Text oder eine Funktionsdefinition zu finden ist, macht technisch also gar keinen Unterschied.

 

Vorweg muss ich eine alternative Schreibweise für die Definition einer Funktion vorstellen.

Diese Variante kennt ihr schon:

function Beispiel()
  print("Ich bin eine Beispielfunktion")
end

 

Diese Schreibweise macht dasselbe:

Beispiel = function()
  print("Ich bin eine Beispielfunktion")
end

Der einzige Unterschied ist die Reihenfolge, in der etwas passiert. Im zweiten Beispiel wird zuerst eine namenlose Funktion angelegt und dann die Adresse dieser Funktion an den Namen Beispiel übergeben. Das Resultat ist aber dasselbe wie bei der ersten Schreibweise.

Die zweite Schreibweise eignet sich, um die Adresse einer Funktion an einen Tabellenplatz zu übergeben:

Bands = {
  Beatles = {"John", "Paul", "George", "Ringo"},
  Stones = {"Mick", "Keith", "Brian", "Ian", "Bill", "Charlie"},
  Who = {"Pete", "Roger", "John", "Keith"},
  Anzahl = function(Bandname)
    print("Die Band "..Bandname.." hat "..#Bands[Bandname].." Mitglieder")
  end,
  Erster = function(Bandname)
    print("Das erste Bandmitglied der "..Bandname.." heißt: "..Bands[Bandname][1])
  end
}

Bands.Anzahl("Stones")
Bands.Erster("Who")

Beachtet bitte, dass innerhalb der Funktion keine Kommas am Zeilenende stehen dürfen. Denn der gesamte Funktionsblock bildet ein Element.

Am Ende der Funktionsdefinition muss hingegen zwingend ein Komma stehen, falls weitere Tabellenelemente folgen. Deshalb steht im obigen Beispiel ein Komma hinter dem end, welches die Definition von Anzahl abschließt.

 

Im MBS sind die Modelle Objekte. Und diese Objekte werden, wenn ich Neo richtig verstanden habe, in V5 eigene Funktionen bekommen, welche man per Lua aufrufen kann. Wie ihr oben seht, ist der Aufruf solcher Funktionen sehr einfach. Aber es hilft wenn man eine Vorstellung davon hat, wie die Daten dazu tabellarisch organisiert sind.

Share this post


Link to post
Share on other sites

Tabellen - Teil 6

Für den Aufruf von Funktionen, die in einer Tabelle stehen, kennt Lua noch einen besonderen Trick. Und der macht das Anlegen von Funktionen innerhalb von Tabellen erst sinnvoll.

Man kann die Adresse der Tabelle beim Aufruf der Funktion als Argument mitgeben. Damit ist es selbst bei tief gestaffelten Tabellen ein Leichtes, direkt auf Elemente der Tabelle zuzugreifen, in der auch die Funktion steht.

Ich möchte etwas weiter ausholen, um die Zusammenhänge möglichst durchschaubar zu machen.
Als Beispiel soll noch einmal die Zugtabelle aus dem vorletzten Kapitel dienen:

Zuege = {
  {
    Name = "Gueterzug_1",
    Geschwindigkeit = 80,
    Typ = "Gueter",
    Lok = {
      Name = "V200",
      Typ = "Diesel",
      Kupplung_vorne = false,
      Kupplung_hinten = true
    },
    Waggons = {
      {
        Name = "G10",
        Typ = "Kasten",
        Kupplung_vorne = true,
        Kupplung_hinten = true
      },
      {
        Name = "Kbs",
        Typ = "Rungen",
        Kupplung_vorne = true,
        Kupplung_hinten = true
      },
      {
        Name = "OVP",
        Typ = "Tank",
        Kupplung_vorne = true,
        Kupplung_hinten = true
      },
      {
        Name = "G10",
        Typ = "Kasten",
        Kupplung_vorne = true,
        Kupplung_hinten = false
      },
    }
  }
}

Zuege enthält die Adresse der ganzen Tabelle
Zuege[1] enthält die Adresse der ersten Untertabelle (in der alle Daten des ersten Zuges stehen)
Zuege[1].Waggons enthält die Adresse der Untertabelle mit allen Waggons in der Untertabelle 1 der Tabelle Zuege.
Zuege[1].Waggons[1] enthält die Untertabelle mit den Details des ersten Waggons innerhalb der Untertabelle aller Waggons innerhalb …

Solche Adressen kann man an eine neue Variable übergeben:

Dings = Zuege[1].Waggons[1]

Das ist dann sinnvoll, wenn man anschließend diese Adresse mehrfach benötigt. Weil es die Schreibweise der Adressen innerhalb dieser Untertabelle jetzt vereinfacht

Dings.Name
Dings.Typ
Dings.Kupplung_vorne

Selbstverständlich wählt man im Ernstfall einen sinnvolleren Namen als „Dings“.

Nun stellt euch bitte vor, dass in der Untertabelle eines Waggons eine Funktion enthalten ist, die etwas mit den Daten dieses Waggons tut. Die zum Beispiel den Namen und den Typ des Waggons ausgibt (um die Geschichte jetzt nicht ausufern zu lassen.) Dann würde man beim Aufruf der Funktion die gesamte Adresse innerhalb der Tabelle mit angeben.

Zuege[1].Waggons[1].Ausgabe()

Jetzt könnte man die Adresse außerdem als Argument mitgeben:

Zuege[1].Waggons[1].Ausgabe( Zuege[1].Waggons[1] )

Für dieses Argument legt man in der Funktionsdefinition eine Variable an. Ein gebräuchlicher Name für diese Variable ist „self“. Aber jeder andere Name funktioniert genauso gut.

Zuege[1].Waggons[1].Ausgabe = function(self)
  print("Mein Name ist "..self.Name.." und ich bin vom Typ "..self.Typ)
end

Das ist ungemein praktisch, weil es die Adressierung der Daten innerhalb dieser Tabelle so bequem macht. Die komplette Adresse der Untertabelle wird an die lokale Variable self übergeben. Also muss man innerhalb der Funktion nur noch self schreiben, wenn man Zuege[1].Waggons[1] meint

Und das ist noch nicht alles. Ich kann die identische Funktion für alle Waggons benutzen, weil ich nur die jeweils passende Adresse als Argument an self übergeben muss.

Und deshalb hat man in Lua die Schreibweise für den Funktionsaufruf vereinfacht. Programmierer mögen es nämlich nicht, wenn sie etwas doppelt schreiben müssen. Weil es das Risiko vergrößert, sich dabei zu verschreiben.

In Lua kann man die Adresse an einer Stelle mit einem Doppelpunkt anstelle des einfachen Punkts aufteilen.

Zuege[1].Waggons[1]:Ausgabe()

Dann wird automatisch alles, was vor dem Doppelpunkt steht, als erstes Argument übergeben. Werte, die man in die Klammern schreibt, sind damit die Argumente 2 bis …

 

Der Grund, warum ich diesen relativ schweren Stoff in einem Einsteiger-Tutorial anspreche, ist folgender:

Die einzelnen Objekte im MBS werden mit V5 fertige Lua Funktionen enthalten. Und der Aufruf dieser Funktionen wird dem folgenden Muster entsprechen:

Objektname:Funktionsname(Argumente)

Das Objekt hat eigene Daten. Und diese wird die Funktion des Objekts verwenden. Wenn die Funktion ein Signal umstellen soll, dann wird sie dafür die Achsen der Signalflügel ansprechen. Wenn man an einem Kran einen Haken anheben kann, dann muss die Funktion dafür ebenfalls die entsprechenden Parameter des Krans ansprechen und verändern. Wie das im Einzelnen passiert, ist für uns unwichtig. Die Funktion ist in V5 ja fertig definiert. Die Definition müssen wir nicht selbst entwerfen.

Aber der Funktionsaufruf wird diesen Gesetzmäßigkeiten folgen. Wir schreiben möglicherweise so etwas wie: 

Kran:Haken(0)

um den Haken in Nullstellung zu bringen. Wie das konkret aussieht, weiß ich auch erst wenn der Beta-Test der V5 beginnt. Mir geht es jetzt ausschließlich darum, dass ihr anhand meiner generischen Beispiele das zugrundeliegende Prinzip durchschaut. Weil dann verständlicher wird, warum was in welcher Reihenfolge im Befehl stehen muss und was es mit dem Doppelpunkt im Funktionsaufruf auf sich hat.

Darüber hinaus könnt ihr euch dieses Wissen natürlich auch in eurem eigenen Programmcode zunutze machen. Denn alles, was man rund um den Eisenbahnverkehr steuert, lässt sich wunderbar tabellarisch verwalten. Es lohnt sich wirklich, die Lua-Tabellen zu durchschauen und den Umgang damit zu üben. Weil man tabellarisch später auch sehr komplexe Situationen gut und überschaubar in den Griff bekommt.

Share this post


Link to post
Share on other sites

Schleifen - Teil 3

Schleifen gehören zu den wichtigsten Hilfsmitteln in der Programmierung. Sie nehmen einem viel Arbeit ab und gerade im Zusammenspiel mit einer Software wie dem 3D-Modellbahnstudio sind das genau die Arbeiten, welche überhaupt den Einsatz eines Skripts rechtfertigen.

Nehmt zum Beispiel einen Schattenbahnhof mit zehn Gleisen. Ein eintreffender Zug soll in eins dieser Gleise einfahren. Dazu muss geprüft werden, welche Gleise noch frei sind, um dann eine Fahrstraße zu einem dieser freien Gleise zu legen.

Zunächst muss zehnmal dasselbe getan werden. Die Prüfung, ob ein Gleis besetzt ist. Und bei jedem der zehn Durchläufe muss genau ein Parameter geändert werden: Die Gleisnummer.

Für solche Zwecke ist die for ... do Schleife gedacht.
Zwischen die Schlüsselworte for und do schreibt man den Namen einer Variablen, ihren Anfangswert, ihren Schlusswert und den Abstand, in dem man von Anfang bis Schluss zählen möchte. Also zum Beispiel so etwas:

for Gleis = 1, 10, 1 do

Beachtet bitte das = Zeichen hinter der Variablen für die Zuweisung der Werte und die Kommas für die Trennung von Anfangswert, Schlusswert und Schrittweite.

In den folgenden Zeilen steht dann das, was mehrmals hintereinander ausgeführt werden soll und am Ende des Blocks steht, wie bei Lua üblich, das Schlüsselwort end.

Ich weiß noch nicht, wie man in V5 prüft, ob ein Gleis besetzt ist. Deshalb bleibe ich bei meinem bisherigen Prinzip, dass ich ersatzweise einfach etwas Text ausgebe:

for Gleis = 1, 10, 1 do
  print("Ich prüfe, ob Gleis "..Gleis.." besetzt ist.")
end

Wenn ihr diese drei Zeilen bei Lua-Demo eingebt und laufen lasst, dann steht im Ausgabefenster die Textzeile zehnmal untereinander. Dabei steht an Stelle der Variablen Gleis in jeder Zeile eine andere Nummer. Das ist die Zahl, welche bei jedem neuen Durchlauf der Schleife an die Variable Gleis übergeben wurde.

Beim Programmieren muss man sehr genau auf das Verhalten solcher Methoden achten. Man muss zum Beispiel sehen, dass der Anfangs- und der Schlusswert beide enthalten sind. Die Schleife wird also mit den Zahlen 1 bis 10 inklusive durchgeführt. 
Muss man so etwas wissen? Nein!
Muss man so etwas lernen? Auswendig können? Nein, auch nicht. Das ginge gar nicht. Es gibt zu viele Unterschiede, die man kennen müsste.

Wenn man programmiert, dann muss man ein Bewusstsein für diese Fragen entwickeln. Dann muss man kurz innehalten und denken:
"for ... do könnte sich so oder so verhalten. Es könnte inklusive oder exklusive zählen. Ich habe keine Ahnung, wie das bei Lua ist."
Und dann probiert man es kurz aus. Wie einfach man solche Dinge testen kann, seht ihr im obigen Beispiel.


Hier ist ein weiteres Beispiel:
Was passiert, wenn man den Wert der Variablen innerhalb der Schleife ändert? Was bedeutet das für den nächsten Durchlauf?
Keine Ahnung! Also probiere ich, was passiert:

for Gleis = 1, 10, 1 do
  Gleis = Gleis + 2
  print("Ich prüfe, ob Gleis "..Gleis.." besetzt ist.")
end

Werden jetzt Zahlen übersprungen?
Oder werden alle Zahlen um 2 erhöht und dann ausgegeben?

Das muss man nicht auswendig wissen. Das ist auch solange uninteressant, bis man einen Grund hat, den Wert der Variablen innerhalb der Scheife zu ändern. Aber dann will man es zuverlässig wissen. Also muss man sich jetzt bewusst machen, dass es zwei mögliche Verhaltensweisen gibt. Und man muss ausprobieren, welches von beiden das tatsächliche Verhalten ist.

Programmieren ist nichts, was man auswendig lernt und dann nach Schema abspult. Programmieren ist eine sehr kreative Beschäftigung. Ständig muss man sich etwas einfallen lassen. Und immer mit der Neugier eines Detektivs betrachten, was genau passiert. Deshalb kann man Programmieren auch nur lernen, indem man sich aktiv damit beschäftigt.

Share this post


Link to post
Share on other sites

Schleifen - Teil 4 (für Fortgeschrittene)

Die for … do Schleife kann man auch verwenden, um ganze Tabellen auszulesen:

Beatles = {"John", "Paul", "George", "Ringo"}

for i = 1, 4 do
  print("Beatle Nummer "..i.." ist "..Beatles[i])
end

 

In Lua gibt es für diesen Zweck aber eine eigene, bessere Methode.
Sie heißt in pairs(), weil sie paarweise den Index und den Inhalt zum Index liefert:

Beatles = {"John", "Paul", "George", "Ringo"}

for key, value in pairs(Beatles) do
  print("Beatle Nummer "..key.." ist "..value)
end

Die Namen der beiden Variablen für Index und Inhalt sind natürlich frei wählbar. Gebräuchlich sind die Buchstaben k und v für key (= Schlüssel) und value (= Wert).
Deshalb habe ich im obigen Beispiel zum besseren Verständnis die Worte key und value gewählt.

 

Die in pairs() Methode liefert alle Schlüssel/Wert Paare zurück. Auch solche, bei denen der Schlüssel keine Zahl, sondern ein String ist:

Beatles = {John = "Gitarre", Paul = "Bass", George = "Gitarre", Ringo = "Schlagzeug"}

for k, v in pairs(Beatles) do
  print(k.." spielt "..v)
end

Beachtet bitte, dass die Aufzählung nicht sortiert ist. Sie kann zufällig mit der Reihenfolge übereinstimmen, in der die Tabelle erstellt wurde. Aber sie muss es nicht und man weiß nie, in welcher Reihenfolge die Werte ausgelesen werden. Auch dann nicht, wenn die Indexe eine lückenlos nummerierte Aufzählung (wie im ersten Beispiel) sind.

 

Aus diesem Grund gibt es eine zweite, sehr ähnliche Methode: in ipairs()

Der Buchstabe i im Wort ipairs steht für „iterable“. Damit ist gemeint, dass nur lückenlos nummerierte Elemente der Tabelle ausgelesen werden und dass die Ausgabe sortiert stattfindet.

Beatles = {
  "John",
  "Paul",
  "George",
  "Ringo",
  Ort = "Liverpool",
  Jahr = 1960,
  Manager = "Brian Epstein",
  Studio = "Abbey Road"
}

for k, v in ipairs(Beatles) do
  print("Schlüssel: "..k..", Wert: "..v)
end

 

Vergleicht die Ausgabe mal mit dem , was ihr bei in pairs() bekommt.

Und lasst die in pairs() Version mehrfach laufen.
Ihr werdet sehen, dass sich Reihenfolgen ändern, obwohl ihr das Skript zwischen den einzelnen Ausführungen nicht ändert.
Der nummerierte Teil der Tabelle steht dabei für gewöhnlich vorne und ist sortiert. Aber garantiert ist auch das nicht!

Wenn eine numerisch sortierte Aufzählung benötigt wird, dann muss man in ipairs() verwenden.
Die Ausgabe von in ipairs() beginnt bei 1, endet bei der ersten Lücke in der nummerierten Liste und ignoriert namentliche Indexe.

Beispiel = {
  Name = "Test",
  "Eins", 
  "Zwei", 
  "Drei", 
  "Vier",
  "Fünf", 
  "Sechs", 
  "Sieben", 
  "Acht"
}

Beispiel[6] = nil

for k, v in ipairs(Beispiel) do
  print("Schlüssel: "..k..", Wert: "..v)
end

Eine fertige Methode für eine alphabetisch sortierte Aufzählung gibt es nicht.

Share this post


Link to post
Share on other sites

Da ich gerade für jemanden ein kurzes Video erstellt habe, welches im Kern denselben Aspekt behandelt wie das Kapitel "Tabellen - Teil 6" in dieser Reihe hier, möchte ich das Video auch hier anbieten:

 

Share this post


Link to post
Share on other sites

Endlich kann ich euch ein weiteres Video anbieten.
Die Sprachaufnahme ist leider sehr träge geraten. Aber besser kriege ich es derzeit nicht hin.

Dafür habe ich mich bemüht den Inhalt zu strukturieren. Und weil das Video recht lang ist, habe ich bei YouTube im Kommentar Sprungmarken hinterlegt.

Das Video ist Anfängertauglich, denn es setzt kein Vorwissen voraus. Das heißt aber nicht, dass der Stoff einfach ist.
Ich bin überzeugt, dass "Anfänger" ebenso gut Schweres lernen können wie Fortgeschrittene. Es muss nur auf ihrem aktuellen Wissensstand aufbauen.

Im Video geht es um "Strings". Die werdet ihr im MBS später mal benötigen. Weil alle Namen, die ihr auslest, Strings sind. 
Als "String" bezeichnen Programmierer ein Stück Text. Egal, ob es sich dabei um einen Namen handelt oder um eine Nachricht.

Wer nicht alles auf Anhieb versteht, der weiß zumindest später, wo er etwas zu dem Thema findet.

Das Video reißt die verschiedenen Themen nur an. Es vermittelt ein prinzipielles Verständnis für die Materie, kein "alles, was man wissen muss".
Es ist nämlich Humbug, alles auf einmal erklären zu wollen. Damit erreicht man nur, dass der Lernende am Ende überhaupt nichts mehr weiß.
Es ist viel wichtiger, den Kern zu verstehen. Dann holt man sich zu gegebener Zeit selber das, was man noch braucht.

Viel Spaß beim Lernen und Experimentieren!

Share this post


Link to post
Share on other sites

Hier sind die wichtigsten Beispiele aus dem Video noch einmal zum Nachlesen.
Manche habe ich um nützliche Hinweise ergänzt.

 

-- Escape Sequenzen

-- \a bell
-- \b back space
-- \f form feed
-- \n newline
-- \r carriage return
-- \t horizontal tab
-- \v vertical tab
-- \\ backslash
-- \" double quote
-- \' single quote
-- \[ left square bracket
-- \] right square bracket

-- zwei Bindestriche kennzeichnen in Lua einen Kommentar

 

Beispiel = "Die Version 5 des \"3D Modellbahn Studios\"\n stellt 'Lua' Befehle zur Verfügung"
print(Beispiel)

 

Beispiel1 = 'Die Version 5 '
Beispiel2 = 'des "3D Modellbahn Studios" '
Beispiel3 = "stellt 'Lua' Befehle zur Verfügung",

print(Beispiel1 .. Beispiel2 .. Beispiel3)

 

Beispiel = {
  'Die Version',
  'des "3D Modellbahn Studios"',
  "stellt 'Lua' Befehle zur Verfügung",
  Version = 5
}

Muster = "%s %d %s %s"
Text = Muster:format(Beispiel[1], Beispiel.Version, Beispiel[2], Beispiel[3])
print(Text)

-- Muster:format(...) ist die verkürzte Schreibweise von: string.format(Muster, ...)

 

Beispiel = 'des "3D Modellbahn Studios" '

Anfang, Ende = string.find(Beispiel, "3D")  -- vereinfacht: Beispiel:find("3D")
print("Die Zeichenkette '3D' im String 'Beispiel2' \nbeginnt bei Zeichen "..Anfang..
  " \nund endet bei Zeichen "..Ende)

 

Beispiel = 'des "3D Modellbahn Studios" '

Teiltext = string.sub(Beispiel, 9, 25)      -- vereinfacht: Beispiel:sub(9, 25)
print(Teiltext)

 

for i = 1, 10, 1 do
  Formel = string.format("%2d * %d = %2d", i, 3, i*3)
  print(Formel)
end

-- die 2 im %2d füllt einstellige Zahlen mit Leerzeichen auf zwei Stellen auf
-- Dadurch steht in der Ausgabe alles fein säuberlich untereinander.

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×