Aus Oxoscript wird NanoPy - mehr Infos

Sprache

Ausdrücke

Ausdrücke sind Anweisungen, mit denen man Variablen einen Wert zuweisen kann.

Im einfachsten Fall weisen wir einer Variablen einen Wert zu:

a = 10

Wichtig: bei der ersten Zuweisung eines Wertes wird der Typ der Variablen bestimmt. Wenn nichts angegeben ist, wird normalerweise “Int” verwendet. Dieser Datentyp kann eine Zahl von -32768 bis 32767 speichern.

Wenn wir stattdessen folgendes programmieren,

a = 10.5

wird ein anderer Typ verwendet. In diesem Fall hat die Variable den Typ “float”. Dieser Datentyp speichert eine sogenannte Fliesskommazahl im Wertebereich von 1.17549e-038 bis 3.40282e+038. Man nennt diese Datentyp so, weil man mit der Exponentialschreibweise sehr grosse und auch sehr kleine Zahlen abbilden kann, indem man das Komma verschiebt. Allerdings ist die Genauigkeit wegen der wenigen Stellen eingeschränkt.

Mit alle Zahlenwerten lässt sich beliebig rechnen

a = b / 5 -10 

etc.

Es ist auch möglich, Funktionen der Funktionsbibliothek aufzurufen, wie beispielsweise:

a = sin(b) * 100

Berechnet den Sinus des Radiant-Wertes b und multipliziert den Wert mit 100.

Grundsätzlich wenden wir die Punkt-vor-Strich-Regel an, wie wir das auch vom Mathematik-Unterricht kennen. Mit Klammern kann man die Reihenfolge jedoch verändern:

a = (5 + sin(b)) * (100 - c)

Bei Zuweisungen kann man auch Array-Werte. Diese werden mit dem Index in eckigen Klammern angegeben:

summe = a[0] + a[1] + a[2] + a[3]

Wenn der Array-Index auf der linken Seite der Zuweisung steht, kann man ein Array-Element verändern:

a[i] = a[i+1] 

Sofern Klassenobjekte numerische Komponenten enthalten, kann man diese wie normale Variablen nutzen. Hier nutzen wir den Punkt-Operator (“.”):

v1 = vector(x=1,y=1) 
v2 = vector(x=2,y=2)
dotProduct = v1.x * v2.x + v1.y * v2.y

Neben den einfachen Zuweisungen mit dem Gleichheitszeichen “=”, gibt es zusätzliche Zuweisungsvarianten:

”++”: Diese Zeichen erhöht den Variablenwert um 1.

i=10
i++
i++
i++

“i” hat jetzt den Wert 13.

”–”: reduziert den Wert um 1.

”+=”: Erhöht den Wert der Variablen um den Ausdruck, der rechts steht.

i=10
i+= (100-95)*3

“i” hat den Wert 25.

”-=”: reduziert den Wert um den Ausdruck von rechts.

Konstanten

Eine Konstante ist wie eine Variable ein Platzhalter, den man im Programm überall anstelle eines Zahlenwertes angeben kann. Im Gegensatz zu Variablen, kann man den Wert einer Konstanten allerdings nur ein einziges Mal definieren und nicht mehr ändern.

Für die Deklaration verwenden wir die Anweisung «const». Beispiel:

const MAX_SIZE = 5.8

Damit man Konstanten im Code besser erkennen kann, schreibt man sie in der Regel in Grossbuchstaben und Snake-Case (siehe Namenskonventionen).

Nutzung des Konstanten-Editors:

Wenn man die Konstanten nach folgendem Muster deklariert, erscheinen diese zusätzlich im Konstanten-Editor als Slider oder Checkbox:

const NAME = WERT # von-Bereich .. bis-Bereich

Beispiel:

const COLOR = 0         # 0 .. 255

Deklariert eine Konstante «COLOR» mit dem Anfangswert 0 und einem Werte-Bereich von 0 bis 255. Dies kann dann über den Slider eingestellt werden.

const FAST_MODE = true       # true, false

Deklariert eine boolesche Konstante, die entweder “true” (Wahr) oder “false” (Falsch) sein kann. Im Konstanteneditor wird hier ein einfacher Schalter gezeichnet, den man mittels Mausklick ein- /ausschalten kann.

Wenn ein Farbwert ausgewählt werden soll, kann “HUE” verwendet werden:

const COLOR = 0        # HUE

Konstanten können auch Berechnungen enthalten, sofern diesse sich auf Zahlenwerte oder andere, zuvor deklarierte Konstanten beschränken:

const WIDTH = 100
const HEIGHT = 80
const VOLUME = WIDHT * HEIGHT
const HALF_VOLUME = (WIDTH * HEIGHT) / 2

Wichtig Anmerkung: Vor dem #-Zeichen müssen mindestens 8 Leerzeichen stehen, sonst funktioniert der Kosteneditor nicht.

Funktion

Eine Funktion ist eine Prozedur, die eine Berechnung ausführt und einen Wert zurückgibt.

Am einfachsten lässt sich das vergleichen mit mathematischen Funktionen, beispielweise den trigonometrischen Funktionen Sinus, Cosinus, Quadratwurzel, etc. Beispielsweise kann man einer Variablen einen Wert bestimmen Sinus-Wert zuweisen:

einWert = sin(PI/2)

Der Sinus von PI/2 ist «1». D.h. die Variable «einWert» wird nach diesem Aufruf den Wert 1 haben.

Funktionen können auch Teil eines Objekts sein. Die Klasse «vector» enthält die Funktion «distance», mit der die Distanz zweier Vektoren berechnet werden kann.

Beispiel:

v1 = vector(x=2,y=4)
v2 = vector(x=10,y=10)
d = v1.distance(v2)

«d» enthält den Wert 10.

Eigene Prozeduren und Funktionen lassen sich mit der «def»- Anweisung deklarieren:

Deklaration einer Prozedur ohne Rückgabewerte:

def Prozedurnamen(Parameter1, Parameter...):
    # Anweisungen...

Deklaration einer Funktion mit Rückgabewerte:

def Funktionsname(Parameter1, Parameter ..)->Rückgabewert:
    # ....
    return Rückgabewert

Beispiele:

def drawHelloWorld():
    background(0,0,0)
    stroke(255,255,255)
    drawText(10,10,"Hello World!")
    update()

def drawMatrix(size):
    for x in size:
        for y in size:
            drawRectangle(x,y,size,size)

def diff(a:float,b:float)->float: 
    if a>b:
        return a-b
    else
        return b-a

Alle Funktionen führen die einrückten Anweisungen aus. Mit der Anweisung «return» kann man die Funktion sofort verlassen. Wenn die Funktion einen Rückgabewert definiert hat, muss bei «return» zusätzlich noch ein Wert angegeben werden.

Diese definierten Funktionen lassen sich so aufrufen:

drawHelloWorld()

Zeichnet «Hello World!» auf den Screen.

drawMatrix(10)

Zeichnet 10 * 10 Rechtecke in der Grösse 10 * 10 Pixel.

d = diff(10.4,2.1)

Liefert die Differenz der beiden Zahlen (=8.3) und speichert den Wert in der Variablen «d» ab. Wir sehen hier im Code, dass «return» eine Berechnung zurückgibt. Je nachdem, welche Zahl grösser ist, wird entweder das Ergebnis der Berechnung von “a-b” oder “b-a” zurückgegeben.

while-Schleife

Mit “while” kann ein Block von Anweisungen so lange wiederholt werden, bis eine Bedingung nicht mehr erfüllt ist.

Der Aufbau ist wie folgt:

while bedingung:
    # Anweisungen

“bedingung” kann einen beliebiger Ausdruck sein, der entweder Wahr oder Falsch ist. Solange die Bedingung erfüllt ist, wir der Block immer wieder ausgeführt.

Beispiel:

background(0,0,0)
y=10
while y<240:
    drawLine(0,y,240,y)
    y = y + 10
update()

Dieses Beispiel zeichnet eine vertikale Linie alle 10 Pixel.

Wenn die Bedingung immer erfüllt ist, spricht man von einer Endlosschleife. Diese lässt sich beispielsweise so deklarieren:

while true:
    background(0,0,0)
    update()
    delay(500)
    background(255,255,255)
    update()
    delay(500)

Das Beispiel lässt den Bildschirm endlos schwarz/weiss aufleuchten.

Programmaufbau

Ein Programm kann auf zwei Arten aufgebaut werden.

Ereignisgesteuert oder als Folge von Anweisungen.

Beim ereignisgesteuerten Ansatz reagiert das Programm auf Systemereignisse und läuft grundsätzlich endlos.

Es stehen die drei Ereignisprozeduren: “onDraw()”, “onClick()” und “onTimer()” zur Verfügung.
“onDraw()” wird laufend ausgeführt, immer wenn das System unbelastet ist. Das bedeutet, dass “onDraw()” je nach Situation mehrere tausend Mal pro Sekunde aufgerufen wird. Die Funktion dient in der Animation als Zeichnungsfunktion, die den Bildschirm aktualisiert. Man kann sie allerdings auch für andere Zwecke nutzen.

“onClick()” wird nur aufgerufen, wenn eine oder mehrere Knöpfe gedrückt sind. Diese Funktion dient zur Abfrage und Reaktion auf Klicks.

“onTimer()” wird nur aufgerufen, wenn ein Timer abläuft.

Das Ereignissystem prüft laufend, ob ein Knopf gedrückt ist oder ein Timer abgelaufen ist. Wenn dies der Fall ist, wird nach dem Aufruf von “onDraw()” “onClick()” oder “onTimer()” aufgerufen. Die Aufrufe erfolgen also immer sequenziell, nicht parallel.

Allgemeiner Aufbau:

# Deklaration von Klassen, globalen Variablen und Funktionen...

def onDraw():
    # Anweisungen...

def onClick():
    #  Anweisungen...

def onTimer():
    #  Anweisungen...

Beispiel:

hue:int

def onDraw():
    backgroundHSV(hue,255,255)
    update()

def onClick():
    b:buttons = getButtons()
    if b.up: hue = 0
    if b.down: hue = 50
    if b.left: hue = 100
    if b.right: hue = 150
    if b.middle: hue = 255

Das Beispiel färbt den Screen mit einer Farbe ein, je nachdem, welcher Button gedrückt wurde.

Alternativ kann man auch auf die Ereignisprozeduren verzichten und sein Programm als einfache Folge von Anweisungen formulieren. Das folgende Beispiel schreibt “Hello World!” auf den Screen und terminiert (stoppt) danach. Die Anzeige bleibt bestehen, bis die Oxocard ein neues Programm erhält.

background(0,0,0)
drawText(10,10,"Hello World!")
update()

Beide Varianten lassen sich auch beliebig kombinieren, wobei man beachten muss, dass global definierte Aufrufe nur beim erstmaligen Start des Scripts bzw. beim Neustart des Script ausgeführt werden.

Beispiel:

background(0,0,0)
drawText(10,10,"Write this once")
flip:bool
noStroke()

def onDraw():
    flip = not flip
    if flip:
        fill(255,0,0)
    else:
        fill(0,255,0)
    drawRectangle(10,80,220,80)
    update()
    delay(500)

Die ersten vier Zeilen dieses Scripts wird nur beim erstmaligen Start ausgeführt. Danach startet die Ereignissteuerung, die endlos “onDraw()” ausführt.

Variablen

Eine Variable ist ein Platzhalter für einen Wert. Man kann eine Variable auch als «Schublade» bezeichnen, für die im Speicher des Computers Platz reserviert wird, um irgendeinen Wert zu speichern.

Jede Variable hat ein Datentyp, mit dem die Grösse und auch die Art des Inhalts fixiert wird. Beides ist nach einer einmaligen Angabe nicht mehr änderbar. Diese Konvention nennt sich «statisch typisiert». In dynamisch typisierten Sprachen lassen sich gleiche Variablen-Namen immer wieder neu deklarieren, wodurch auch andere Inhalte möglich sind, sich aber leider auch viele Fehler einschleichen können.

Die Deklaration einer Variablen ist notwendig, d.h. bevor man diese verwendet, muss man sie definieren. Hier gibt es zwei Möglichkeiten:

  1. Deklaration durch Zuweisung eines Werts:
a = 10
b = true
c = 3.14
v = vector(x=10,y=20)

“a” wird als int-Wert, b als Boolean, c als Float und v als vector deklariert. Der Wert bestimmt also den Datentyp der Variablen, wobei bei nummerischen Werten immer mindestens der Datentyp “int” genutzt wird.

  1. Angabe des Datentyps mit «:»
a:int
b:byte
c:float
d:Rectangle

Als Datentyp können alle internen Basistypen und Klassen, sowie eigene Klassen genutzt werden.

Spezialfall Array-Typen:

Wenn man von einer Variablen mehrere Werte haben möchte, kann man die Anzahl der Werte in eckigen Klammern angeben.

punkte:int[10]

Dies deklariert eine Liste von Punkten mit dem Namen «punkte». Die Liste enthält 10 Einträge, die von 0 bis 9 nummeriert sind.

Bei der Zuweisung muss jetzt jeweils der Index, d.h. die Nummer des Eintrags angegeben werden:

punkte[0] = 10
punkte[1] = 99
...

Die Anzahl der Elemente kann nicht geändert werden. Die Anzahl muss eine Zahl sein, kann aber auch eine Konstante sein:

const ANZAHL = 10
punkte:int[ANZAHL]

Du findest mehr Informationen zu Variablen hier:

Binäre Operationen

Auf Ganzahlen lassen sich auch Bit-Operationen ausführen.

Folgende sind verfügbar:

zahl << n Verschiebt die Zahl bitweise um n Stellen nach links
zahl >> n Verschiebt die Zahle bitweise um n Stellen nach rechts
zahl1 | zahl1 Logische Oder-Verknüpfung der beiden Zahlen
zahl1 & zahl2 Logische Und-Verknüpfung der beiden Zahlen
zahl1 ^ zahl2 Logische exklusive Oder- Verknüpfung der beiden Zahlen (XOR)

Beim Verschieben der Zahlen um n bits entspricht das Linkschieben einer Multiplikation, das Rechtsschieben einer Division durch 2^n.

Einige Beispiele:

0b00000001 << 1 = 0b00000010
0b10000000 >> 1 = 0b01000000
0b00000001 | 0b11111111 = 0b11111111
0b00000001 & 0b11111111 = 0b00000001
0b00000001 ^ 0b11111111 = 0b11111110

Zahlensysteme

In der Computerwelt werden neben dem Dezimalsystem häufig auch da Binär- und das Hexadezimalsystem verwendet. In NanoPy kann man alle drei System verwenden.

Im Normalfall nutzen wir das gängige Dezimalsystem. Die Zahlen können wir einfach als Wert einer Variablen zuweisen oder in Berechnungen brauchen:

a = 10
b = 4711
c = a / 5 - 10

Die Basis dieser Zahlen ist 10 und wir verwenden die “Symbole” 0- 9.

Im binären System kennen wir nur 0 und 1. In NanoPy werden die binären Zahlen mit 0b genutzt.

a = 0b00001111
b = 0b0101

Mit binären Zahlen lässt sich auch ganz normal rechnen:

a = 10 + 0b00001111

Das dritte Zahlensystem heisst Hexadezimal. Hier haben wir 16 verschiedene Symbole, die dies das Sechzehnersystem ist. Wir ergänzen die Zahlen 0 bis 9 um die Buchstaben a - f (a=10, b=11, c = 12 etc.). Die Zahlen werde mit 0x eingeführt:

a = 0xff
b = 0x10

Man beachte, dass 0x10 NICHT dem Dezimalwert 10 entspricht, sondern 16!

Wie die Zahlensysteme untereinander umwandelbar sind, findet man auf youtube von verschiedenen Quellen.

Datentypen

Ein Datentyp definiert den Wertumfang einer Variablen. In der Mathematik kennen wir die reelen, ganzen, natürlichen, rationalen und irrationalen Zahlen. In der Informatik gibt es noch weitere solche Mengen und man kann auch eigene definieren.

Eingebaute Datentypen:

Datentyp Wertebereiche
byte 0 bis 255
int -32768 bis 32767
long -2147483648 bis 2147483647
float 1.17549e-038 bis 3.40282e+038
bool true oder false

Diese Basistypen lassen sich mittels Klassen zu Kompositionen zusammenfassen. Beispielsweise enthält die Vektor-Klasse («vector») zwei Variablen vom Typ «float» (x and y).

Folgende eingebaute Datentypen sind verfügbar:

Datentyp Beschreibung
vector Zweidimensionale Vektorklasse mit x- und y- Parmeter (floats) und vielen nützlichen Funktionen der Vektorbearbeitung.
vector3D Dreidimensionale Vektorklasse mit x-, y- und z- Parmeter (floats) und vielen nützlichen Funktionen der Vektorbearbeitung.

Texte ausgeben

Die Oxocard kann auch Texte in verschiedenen Grössen auf dem Bildschirm darstellen.

Für die Textausgabe stehen verschiedene Möglichkeiten zur Auswahl.

Im einfachsten Fall, genügt der Aufruf von drawText(..):

drawText(10,10,"Hello World!")
update()

Texte können auch aus anderen Texten oder Zahlen zusammengesetzt werden, wie dieses Beispiel zeigt:

name = "Leo"
drawText(10,10,"Ich heisse " + name)
update()

Das folgende Beispiel zeigt die aktuelle die Uhrzeit beim der Ausführung des Programm an:

background(0,0,0)
textFont(FONT_ROBOTO_24)
drawText(10,10,"Es ist " + getHour() + " Uhr")
drawText(10,50,"und " + getMinute() + " Minuten")
update()

for-Schleife

Mit der for-Schleife kann man eine Liste von Elementen durchgehen.

Der Aufbau ist wie folgt:

for variable in ausdruck:
    # Anweisungen

“ausdruck” kann eine Zahl, eine Liste oder eine Variable sein.

Beispiel 1:

push()
background(0,0,0)
translate(120,120)
for i in 12:
    rotate(PI/6)
    drawCircle(80,0,10)
update()
pop()

Dieses Beispiel zeichnet 12 Kreise. Zuerst wird der Usprung auf den Mittelpunkt des Screens gelegt. Bei jedem Durchgang der Schleife, wird die Zeichnung um 30 Grad im Urzeigersinn verschoben und ein Kreis gezeichnet.

Weitere Infos: siehe Koordinatentransformation und push() und pop().

Die Schleife lässt sich auch mit einer Liste initialisieren.

list = [1,20,80,100,80,20,1]
x = 20
background(0,0,0)
fill(255,255,255)
for y in list:
    drawRectangle(x,240-y,20,240)
    x = x+30
update()

Dieses Beispiel zeichnet ein Balkendiagramm mit den Werten der Liste, die hier fix angegeben wurden.

Das folgende Beispiel initialisiert eine Liste von Vektoren:

vectors:vector[250]
for i in sizeof(vectors):
    vectors[i].random()
    vectors[i].mulScalar(random(5,180))

angle = 0.0
def onDraw():
    push()
    strokeWeight(5)
    translate(120,120)
    rotate(angle)
    background(0,0,0)
    for i in sizeof(vectors):
        strokeHSV(255,255,i%255)
        drawLine(0,0,vectors[i].x,vectors[i].y)
    update()
    pop()
    angle = angle + 0.05

Dieses Beispiel deklariert eine Liste (Array) von 250 Vektoren. Alle diese Vektoren werden mit einer beliebigen Richtung initialisiert und haben eine zufällige Länge zwischen 5 und 180 Pixel.

In der Ereignisprozedur “onDraw” werden diese Vektoren nun als Linien vom Mittelpunkt des Bildschirms gezeichnet. Nach jedem Durchgang wird der Mittelpunkt um 0.05 Radiant gedreht.

Die For-Schleifen werden jeweils mit der Funktion:

sizeof(vectors)

initialisiert. Die Funktion “sizeof(…)” kann auf alle Listen angewendet werden und liefert die Anzahl der Elemente - in diesem Fall 250.

Bedingte Anweisung mit if/then/else

Bedingte Anweisungen werden mit der if-Anweisung formuliert.
Der Aufbau ist wie folgt:

if Hier steht eine Bedingung:
    Hier sind die Anweisungen, die ausgeführt werden,
    wenn die Bedingung erfüllt ist.
elif Hier steht eine weitere Bedingung:
    wenn die zweite Bedingung erfüllt ist, wird dieser
    Block ausgeführt.
else:
    Hier stehen die Anweisungen, die alternativ ausgeführt werden.

Der elif/else-Teile sind optional und können auch weggelassen werden. Zudem kann der “elif”-Block auch mehrere Male angegeben werden, wobei der “else”-Block immer am Schluss stehen muss (oder weggelassen wird).

Beispiel:

def onDraw():
    background(0,0,0)
    r = random(0,5)
    if r == 0:
        drawText(10,10,"Zero")
    elif r == 1:
        drawText(10,10,"One")
    else:
        drawText(10,10,"Nothing")
    update()
    delay(1000)

Folgende Vergleichsoperatoren lassen sich nutzen:

</table> Ergebnisse von Vergleichsoperatoren können auch Variablen zugewiesen werden. Nummerisch entspricht "false" dem Wert 0 und "true" dem Wert 1. Wir werden die Vergleichsoperationen neben-Bedingung auch im while-Block sehen. Der Operator "not" kann man einer Variablen voranstellen, wie im folgenden Beispiel demonstriert: ~~~pythonp to_be = false for i in 10: background(0,0,0) to_be = not to_be if to_be: drawText(10,10,"to be") else: drawText(10,10,"not to be") update() delay(1000) ~~~
Vergleichsoperatoren</td> Beschreibung</td> </tr>
== ist gleich
!= ist nicht gleich
> grösser als
>= grösser oder gleich
< kleiner als
<= kleiner oder gleich
&& oder "and" Und
|| oder "or" Oder
not Nicht

Prozedur

Eine Prozedur ist eine Art Befehlsanweisung, die der Computer ausführt, wenn man den Prozedurnamen in der Form «prozedur()» angibt. Die Klammern teilen dem Computer mit, dass wir eine Prozedur aufrufen wollen und sind immer anzugeben. Zwischen den Klammern sind teilweise noch Werte notwendig, die man angeben muss, die man Parameter nennt. Welche das sind, bzw. ob welche notwendig sind, findet man in der Dokumentation. Die Parameter müssen immer exakt angegeben werden, sonst kann die Prozedur nicht richtig funktionieren und es wird ein Fehler angezeigt.

Beispiel einer Prozedur ohne Parameter:

returnToMenu()

Diese Funktion beendet das aktuelle Programm und zeigt wieder das Menü an. Beispiel einer Prozedur mit Parametern:

drawPixel(50,100)

Diese Funktion zeichnen einen Bildpunkt an der Koordinate x= 50, y= 100.

Prozeduren können auch Werte zurückgeben. Dann spricht man von einer Funktion.

Bei der Oxocard gibt es viele internen Prozeduren und Funktionen, die man verwenden kann. Zusätzlich kann man sich auch eigene Funktionen zusammenbauen. Auch Klassenfunktionen sind möglich. Siehe Eintrag «Funktion»

Klasse

Mit Klassen lassen sich neue Datentypen erstellen. Hierbei kommt der Begriff aus der objektorientierten Programmierung, bei der zusammengehörende Dinge zu einer Gruppe - eben zu einer Klasse - zusammengefasst werden können.

Wir können beispielsweise eine Klasse Point3D definieren, welche eine 3-dimensionale Koordinate speichert, die einen x,y und z-Wert enthält.

class Point3D:
    x:float
    y:float
    z:float

    def draw():
        drawPixel(x+(z/2),y+(z/2))

Die Klasse kann jetzt wie ein normaler Datentyp verwendet werden:

p1:Point3D

p1 hat nun drei integrierte Variablen x,y,z, die man einzeln setzen und lesen kann:

p1.x = 10
a = p1.y
etc...

Alternativ kann auch der Klasseninitialisierer genutzt werden:

p1 = Point3D(x=10,y=5,z=3)

In der Dokumentation findet sich eine Liste der internen Klassen, die bereits fertig deklariert sind und genutzt werden können (“vector”, “color” u.a.).
Das folgende Beispiel deklariert eine Klasse “Circle” (Kreis). Speziell hier ist, dass die Klassenvariablen “pos” wieder einen Klassentyp hat.

class Circle:
    pos:vector
    size:int

    def init(x:int,y:int,s:int):
        pos.x = x
        pos.y = y
        size = s

    def draw():
        drawCircle(pos.x,pos.y,size)

Wir können nun die Circle-Variable “c” definieren und die definierten Funktionen aufrufen:

c:Circle
c.init(120,120,10)
c.draw()

Allgemeiner Aufbau:

class Klassennamen:
    Variable1
    Variable2
    Variable...
    ...
    Funktion1
    Funktion2
    Funktion...


Wichtige Anmerkungen:

Das objektorientierte Konzept der Vererbung von Variablen und Funktionen ist nicht implementiert. Daher sind die Klassen eher als Komponenten zu bezeichnen. Es gibt aktuell zudem in der Vorab- Version von NanoPy noch keine Konstruktoren/Destruktoren.

Ereignisprozedur

Eine Ereignisprozedur ist eine spezielle Funktion, die man nicht selbst aufrufen muss, sondern vom System automatisch zu bestimmten Zeitpunkten aufgerufen wird. Wir nutzen vor allem die Funktion «onClick()», die immer dann vom System aufgrufen wird, wenn eine Taste gedrückt wird und «onDraw()», die der Computer aufruft, wenn nichts anderes zu tun ist.