Anbei eine .txt.-Datei, deren Inhalt ich nicht so in das Textfeld dieses Forums brachte, dass er mir gut verständlich erschien. Problem ist das unterschiedliche Verhalten von print und file.write in (Micro)Python Es ist mir nicht gelungen in ein file das zu schreiben was print nach tty sendete
Beitrag #7126352 wurde von einem Moderator gelöscht.
Manfred M. schrieb: > Es ist mir nicht gelungen in ein file das zu schreiben was print nach > tty sendete file.write() will nur einen Parameter. Also nicht: > file.write("\n","start","\n" ) sondern: file.write("\nstart\n") Funktioniert natürlich auch mit print().
Das funktioniert alles so wie es soll und dokumentiert ist. Die erwarteten Argumente sind nunmal andere. Default für buffering ist je nach ziel auch anders. Und ein paar andere Unterschiede gibt es auch noch. Das ist kein bug oder Designfehler. Die Funktionen haben schlicht andere Anwendungsfälle. Du kannst dein file an print() übergeben, das es dort hin geht, und du kannst stdout als file haben, über sys.stdout. Buffering kann man sicher auch irgendwie festlegen. Einfach in der offiziellen python API Dokumentation nachlesen, was genau die dinge machen (und nicht vage inoffizielle Tutorials ansehen).
Beitrag #7126450 wurde von einem Moderator gelöscht.
DPA schrieb: > Das funktioniert alles so wie es soll und dokumentiert ist. Die > erwarteten Argumente sind nunmal andere. Default für buffering ist je > nach ziel auch anders. Und ein paar andere Unterschiede gibt es auch > noch. Das ist kein bug oder Designfehler. Die Funktionen haben schlicht > andere Anwendungsfälle. > > Du kannst dein file an print() übergeben, das es dort hin geht, und du > kannst stdout als file haben, über sys.stdout. Buffering kann man sicher > auch irgendwie festlegen. Einfach in der offiziellen python API > Dokumentation nachlesen, was genau die dinge machen (und nicht vage > inoffizielle Tutorials ansehen). Ich las bei www.python.org und docs.micropython.org Ist dort die "offizielle python API Dokumentation" ? > Das funktioniert alles so wie es soll und dokumentiert ist. Das mag sein, die Frage ist nur: Warum? Ich bin verwundert (und nur das wollte ich mitteilen), dass die Ausführung der Befehle so unterschiedlich entworfen / realisiert wurde. Ich erwartete, dass es unerheblich ist, wohin ich einen byte-stream sende. Wenn dann der stream gelesen und interpretiert wird (zB als Text, also als Folge von ASCII- oder ...text oder als Bild oder sonstige Grafik) , dann sollte es identische Arten der Interpretation geben. Niklas Wirth und andere haben vorgemacht wie es sein sollte. Es kann aber sein, dass write ein ungeeigneter Befehl ist, um das zu erreichen was ich möchte. Dann aber ist die Frage: Welcher wäre geeigneter?
Manfred M. schrieb: > Es kann aber sein, dass write ein ungeeigneter Befehl ist, um das zu > erreichen was ich möchte. Dann aber ist die Frage: Welcher wäre > geeigneter? Nö, der klappt prima.
1 | #!/usr/bin/python3
|
2 | # -*- coding: UTF-8 -*-
|
3 | |
4 | import sys |
5 | print(type(sys.stdout)) |
6 | # <class '_io.TextIOWrapper'>
|
7 | |
8 | fw = open('dummy', 'w') |
9 | print(type(fw)) |
10 | # <class '_io.TextIOWrapper'>
|
11 | |
12 | print('Ab in in die Datei 1', file=fw) |
13 | fw.write('Ab in in die Datei 2\n') |
14 | # 19
|
15 | |
16 | fw.close() |
17 | |
18 | |
19 | #
|
20 | # ~/tmp$ ls -l dummy
|
21 | # -rw------- 1 xxx xxx 38 Jul 14 09:15 dummy
|
22 | # ~/tmp$ cat dummy
|
23 | # Ab in in die Datei 1
|
24 | # Ab in in die Datei 2
|
25 | # ~/tmp$
|
Manfred M. schrieb: > Niklas Wirth und andere haben vorgemacht wie es sein sollte. Gerade Niklas Wirth hat das nicht vorgemacht; Funktionen wie writeln kann man in Pascal selbst nicht schreiben, denn in Pascal gibt es keine variadischen Funktionen -- außer eben writeln.
Manfred M. schrieb: > Ich erwartete, dass es unerheblich ist, wohin ich einen byte-stream > sende. Du sendest ja gar keinen byte-stream an file.write, du übergibst drei strings. Ich glaube dein Problem ist eher print(). print() ist so eine Convenience-Funktion mit historisch überfrachteter Funktionalität. LG, Sebastian
Manfred M. schrieb: >> Das funktioniert alles so wie es soll und dokumentiert ist. > Das mag sein, die Frage ist nur: Warum? > Ich bin verwundert (und nur das wollte ich mitteilen), dass die > Ausführung der Befehle so unterschiedlich entworfen / realisiert wurde. Wenn beide Funktionen das gleiche täten, könnte man eine gleich weg lassen. Write ist eine low level Funktion. Jenachdem nimmt sie einen string oder einen byte string, schreibt soviel wie ohne Blockieren gerade geht, und gibt zurück wie viel geschrieben werden konnte, damit man später den rest noch schreiben/senden kann. print ist eine high level Funktion. Man gibt ihm Objekte, es macht daraus strings, haut ein paar newlines dazu, und kümmert sich darum, das das alles ausgegeben wird. Unter der Haube verwendet es zur Ausgabe vermutlich wieder die .write Methode / baut darauf auf. Was das buffering angeht, ungepuffert ist sehr ineffizient. Ein TTY ist interaktiv, da will man neue Zeilen meist sofort sehen, deshalb Zeilenpufferung. Besser als ungepuffert, aber nicht so schnell wie voll gepuffert. In Dateien schaut man meist nicht, während sie geschrieben werden, also puffert man so viel wie möglich. Das hängt übrigens nicht davon ab, welche Funktion man nimmt. Das wird entschieden, wenn das file artige Objekt erstellt wird. Leitest du z.B. die Ausgabe von python in ne Datei um, ist sys.stdout voll gepuffert stat Zeilengepuffert.
Es ist wieder einmal Norbert, der den nützlichsten Hinweis mitteilt Dank! Aber ganz so funktioniert's bei mir nicht. Ich bekommen im shell-Fenster das: <class 'FileIO'> <class 'TextIOWrapper'> ??? Die Zeilen im file enthalten das Gleiche Ich verwende MicroPython v1.18 on 2022-01-17; Raspberry Pi Pico with RP2040 VG MM Norbert schrieb: > Manfred M. schrieb: >> Es kann aber sein, dass write ein ungeeigneter Befehl ist, um das zu >> erreichen was ich möchte. Dann aber ist die Frage: Welcher wäre >> geeigneter? > > Nö, der klappt prima. > >
1 | #!/usr/bin/python3
|
2 | > # -*- coding: UTF-8 -*- |
3 | >
|
4 | > import sys |
5 | > print(type(sys.stdout)) |
6 | > # <class '_io.TextIOWrapper'> |
7 | >
|
8 | > fw = open('dummy', 'w') |
9 | > print(type(fw)) |
10 | > # <class '_io.TextIOWrapper'> |
11 | >
|
12 | > print('Ab in in die Datei 1', file=fw) |
13 | > fw.write('Ab in in die Datei 2\n') |
14 | > # 19 |
15 | >
|
16 | > fw.close() |
17 | >
|
18 | >
|
19 | > # |
20 | > # ~/tmp$ ls -l dummy |
21 | > # -rw------- 1 xxx xxx 38 Jul 14 09:15 dummy |
22 | > # ~/tmp$ cat dummy |
23 | > # Ab in in die Datei 1 |
24 | > # Ab in in die Datei 2 |
25 | > # ~/tmp$ |
DerEgon schrieb: > Manfred M. schrieb: >> Niklas Wirth und andere haben vorgemacht wie es sein sollte. > > Gerade Niklas Wirth hat das nicht vorgemacht; Funktionen wie writeln > kann man in Pascal selbst nicht schreiben, denn in Pascal gibt es keine > variadischen Funktionen -- außer eben writeln. richtig und das war ein bewusste Entscheidung, die Wirth auch begründete (sofern ich mich richtig erinnere - was wahrscheinlich ist). MM
MicroPython sieht da etwas anders aus, macht aber nichts.
1 | #!/usr/bin/python3
|
2 | # -*- coding: UTF-8 -*-
|
3 | import sys |
4 | import os |
5 | fw = open('dummy', 'w') |
6 | print(type(fw)) |
7 | print('Ab in in die Datei 1', file=fw) |
8 | fw.write('Ab in in die Datei 2\n') |
9 | fw.close() |
10 | print(os.listdir()) |
11 | |
12 | with open('dummy') as fr: |
13 | for line in fr: |
14 | print(line) |
Legt eine dummy Datei an. Schreibt Zeile 1 mit print() und Zeile 2 mit write(). os.listdir() zeigt die Datei und die ›with open(…‹ Sequenz gibt die Zeilen aus.
Nun sieht mein Programm mit dem ich das Verhalten beim IRQ-Hanlimng testen wollte so aus:
1 | import machine |
2 | import sys |
3 | |
4 | global count, fw |
5 | |
6 | fw = open('dummy', 'w') |
7 | print(type(fw)) |
8 | |
9 | print("buzzer = machine.Pin(17, machine.Pin.OUT, machine.Pin.PULL_DOWN") |
10 | print("buzzer = machine.Pin(17, machine.Pin.OUT, machine.Pin.PULL_DOWN /n", file=fw) |
11 | buzzer = machine.Pin(17, machine.Pin.OUT, machine.Pin.PULL_DOWN) #GPIO17 = Pin22 |
12 | buzzer.value(0) |
13 | fw.flush() |
14 | |
15 | print("actor = machine.Pin(18, machine.Pin.OUT, machine.Pin.PULL_UP)") |
16 | print("actor = machine.Pin(18, machine.Pin.OUT, machine.Pin.PULL_UP)", file=fw) |
17 | actor = machine.Pin(18, machine.Pin.OUT, machine.Pin.PULL_UP) #GPIO18 = Pin24 |
18 | print("actor(0)") |
19 | print("actor(0)", file=fw) |
20 | actor(1) |
21 | fw.flush() |
22 | |
23 | print("sensor = machine.Pin(16,machine.Pin.IN, machine.Pin.PULL_UP)") |
24 | print("sensor = machine.Pin(16,machine.Pin.IN, machine.Pin.PULL_UP)", file = fw) |
25 | sensor = machine.Pin(16,machine.Pin.IN, machine.Pin.PULL_UP) #GPIO16 = Pin21 |
26 | fw.flush() |
27 | |
28 | count = 0 |
29 | print ("count=" + "{:04d}".format(count)) |
30 | print ("count=" + "{:04d}".format(count), file=fw) |
31 | print("running") |
32 | print("running", file=fw) |
33 | fw.flush() |
34 | |
35 | |
36 | def sensor_handler(pin): |
37 | global count, fw |
38 | fw = open('dummy_2', 'w') |
39 | print("\n im sensor_handler") |
40 | print("\n im sensor_handler", file=fw) |
41 | print("pin.value=", pin) |
42 | print("pin.value=", pin, file = fw) |
43 | #fw.flush() |
44 | #print("pin.value=" + "{:04d}".format(value(pin))) |
45 | #print("pin.value=" + "{:04d}".format((pin)), file=fw) |
46 | #fw.flush() |
47 | #print("pin=", pin) |
48 | #print("pin=", pin, file=fw) |
49 | #fw.flush() |
50 | print(type(pin)) |
51 | #print(type(pin), file=fw) |
52 | #fw.flush |
53 | |
54 | count = count +1 |
55 | print("count=" + "{:04d}".format(count)) |
56 | print("count=" + "{:04d}".format(count), file=fw) |
57 | fw.flush() |
58 | if pin.value()==1: |
59 | buzzer.value(1) |
60 | print("buzzer on") |
61 | print("buzzer on", file=fw) |
62 | fw.flush() |
63 | print("pin.value()", pin.value()) |
64 | print("pin.value()", pin.value(), file=fw) |
65 | fw.flush() |
66 | fw.close() |
67 | #print("pin="+ pin + "\n") |
68 | #print("pin="+ pin + "\n", file=fw) |
69 | #fw.flush() |
70 | #print("pin.value()=" + pin.value()) |
71 | #print("pin.value()=" + pin.value(), file=fw) |
72 | #fw.flush() |
73 | #print("pin=" + pin, file=fw) |
74 | #fw.flush() |
75 | else: |
76 | buzzer.value(0) |
77 | print("buzzer off") |
78 | print("buzzer off", file=fw) |
79 | fw.flush() |
80 | fw.close() |
81 | #print("pin.value()=" + pin.value()) |
82 | #print("pin.value()=" + pin.value(), file=fw) |
83 | #fw.flush() |
84 | #print("pin="+ pin + "\n") |
85 | #print("pin="+ pin + "\n", file=fw) |
86 | #fw.flush() |
87 | #print("pin.value()=" + pin.value(), file=fw) |
88 | #fw.flush() |
89 | #print("pin="+ pin, file=fw) |
90 | #fw.flush() |
91 | |
92 | |
93 | |
94 | # import sys |
95 | print("sensor = machine.Pin(16,machine.Pin.IN, machine.Pin.PULL_UP)") |
96 | print("sensor = machine.Pin(16,machine.Pin.IN, machine.Pin.PULL_UP)",file=fw) |
97 | sensor = machine.Pin(16,machine.Pin.IN, machine.Pin.PULL_UP) |
98 | print("sensor.irq(trigger=machine.Pin.IRQ_FALLING, handler=sensor_handler)" + "\n") |
99 | print("sensor.irq(trigger=machine.Pin.IRQ_FALLING, handler=sensor_handler)" + "\n", file=fw) |
100 | sensor.irq(trigger=machine.Pin.IRQ_FALLING, handler=sensor_handler) |
101 | fw.flush() |
102 | print("irq activated", "\n") |
103 | print("irq activated", "\n", file=fw) |
104 | fw.flush() |
Der IRQ-Handler scheint nichts mehr von fw zu wissen :-(, daher öffne ich in ihm eine zweite Datei. :-( Leider fand ich nicht, wie man Python veranlasst, das Schreiben in eine Datei an deren Ende fortzusetzen :-(( Die vorschau zeigt mir leider nicht, dass es mir gelang code als code zu markieren. Schau mer mal.
DerEgon schrieb: > denn in Pascal gibt es keine > variadischen Funktionen -- außer eben writeln. Nö, write ist ebenso variadisch. Unterschied zwischen beiden ist, das writeln immer ein Zeilenendezeichen anhängt, also Textdateien schreibt. Hingegegen kann writ auch mit binären Daten umgehen.
Ich benutzte mal einen Compiler (habe vergessen zu welcher Sprache und auf welcher Maschine, war vermutlich eine CDC 6600), der viel komfortabler war als die, die ich später benutzte (benutzen musste). Da gab es z.B. die Compiler-Anweisung "trace" und der Compiler sorgte für eine Ausgabe welcher Befehl als nächstes ausgeführt wird. Ebenso ein "trace variable1, variable2, ..." dann gab er jede Neubesetzung dieser Variablen aus. Außerdem gab er aus ob [undefined] und wo jede Variable definiert war und insbes. wo sie referenziert wurde. Man konnte auch festlegen wie Parameter übergeben werden (by reference oder by value). Und außerdem gab es ein Syntaxdiagramm und eine vollständige, lineare Beschreibung der verfügbaren Module / Klassen, die durchsuchbar war. Die Frage, ob es einen Befehl gibt, der eine Datei verlängert, war damit leicht zu lösen oder eben ein Modul, das ... machen könnte.
Zeno schrieb: > DerEgon schrieb: >> denn in Pascal gibt es keine >> variadischen Funktionen -- außer eben writeln. > Nö, write ist ebenso variadisch. Unterschied zwischen beiden ist, das > writeln immer ein Zeilenendezeichen anhängt, also Textdateien schreibt. > Hingegegen kann writ auch mit binären Daten umgehen. Das ist auch mein Wissen. Die Frage ist aber auch, ob man variadische Funktionen braucht /haben oder vielleicht nur nützlich sind. Die Übergabe von Feldern (Vektoren, Matizen u.ä.) geht doch wohl immer (sofern eine Sprache halbwegs nutzbar ist).
Manfred M. schrieb: > Zeno schrieb: >> DerEgon schrieb: >>> denn in Pascal gibt es keine >>> variadischen Funktionen -- außer eben writeln. >> Nö, write ist ebenso variadisch. Unterschied zwischen beiden ist, das >> writeln immer ein Zeilenendezeichen anhängt, also Textdateien schreibt. >> Hingegegen kann writ auch mit binären Daten umgehen. > > Das ist auch mein Wissen Bei read und readln ist es ebenso, da ist Anzahl der Parameter nicht vorbestimmt.
Zeno schrieb: > Manfred M. schrieb: >> Zeno schrieb: >>> DerEgon schrieb: >>>> denn in Pascal gibt es keine >>>> variadischen Funktionen -- außer eben writeln. >>> Nö, write ist ebenso variadisch. Unterschied zwischen beiden ist, das >>> writeln immer ein Zeilenendezeichen anhängt, also Textdateien schreibt. >>> Hingegegen kann writ auch mit binären Daten umgehen. >> >> Das ist auch mein Wissen > > Bei read und readln ist es ebenso, da ist Anzahl der Parameter nicht > vorbestimmt. Aha, Zeon erinnert sich. Ich auch, habe aber Niklas Wirts Buch nicht hier, so dass ich hier nur aus der Erinnerung Stellung beziehen kann, also ohne Nachprüfung. anderewrseite muss man nur in der Wikipedia nachsehen wie dort Realisierungen variadischer Funktionen beschrieben ist. Ich kann nicht erkennen, dass variadische Funktionen etwas nach dem Design von Pascal o.ä Sprachen etwas Neues wäre. Nice to have, but not necessary.
Manfred M. schrieb: > Der IRQ-Handler scheint nichts mehr von fw zu wissen :-(, daher öffne > ich in ihm eine zweite Datei. :-( Du meine Güte, willst du im IRQ-Handler eine Lebensgeschichte erzählen? ;-) Das Ding soll so kurz wie möglich sein, besser noch etwas kürzer. Steht übrigens auch ausführlich in der MicroPython Dokumentation. Wenn's dennoch etwas länger sein soll - wozu keinerlei Veranlassung besteht - dann mittels schedule() > Leider fand ich nicht, wie man Python veranlasst, das Schreiben in eine > Datei an deren Ende fortzusetzen :-(( Alle Parameter sind beim open() Befehl beschrieben. > Die vorschau zeigt mir leider nicht, dass es mir gelang code als code zu > markieren. Schau mer mal. Versuch als erste Zeile: #!/usr/bin/python3 Mal schauen ob dieser Thread noch zu retten ist, gerade wird ja wieder mal reichlich sabotiert.
Manfred M. schrieb: > Leider fand ich nicht, wie man Python veranlasst, das Schreiben in eine > Datei an deren Ende fortzusetzen :-(( Wie wärs mit Doku lesen? Ein help(open) sollte schon etwas Licht auf die Sache werfen ...
Norbert schrieb: > Manfred M. schrieb: >> Der IRQ-Handler scheint nichts mehr von fw zu wissen :-(, daher öffne >> ich in ihm eine zweite Datei. :-( > > Du meine Güte, willst du im IRQ-Handler eine Lebensgeschichte erzählen? > ;-) In der Endversion natürlich nicht, aber ich wollte mir genaustens ansehen, was passiert und die möglichen Varianten in einem File dokumentieren. Dazu kamen dann noch Variationen, die durch (Micro-)Python möglich sind. Tja woran liegt es denn, wenn etwas Unterwartetes passiert? Es gab mal eine Zeit, in der ich mir Maschinencode ansah, um zu sehen was ein Compiler aus meinen Wünschen machte und manchmal gar nicht das, was anzunehmen war. Compiler-Errors waren selten, kamen aber vor. Wenn heute neue Compiler generiert werden, wieso sollten sie frei von Fehlern sein? Oder Klassen? Nimm mal aus meinem Code print("pin.value=", pin) was (lt. print("pin.value=", pin)) erzeugt: pin.value= Pin(16, mode=IN, pull=PULL_UP) doch dann bringt if pin.value()==1: das was ich, ohne Kenntnis von "pin.value= Pin(16, mode=IN, pull=PULL_UP)" erwarte (obwohl "Pin(16, mode=IN, pull=PULL_UP" kein boolscher Wert ist), nämlich etwas das mittels == 1 verglichen werden kann Ist das nicht komisch? VG & Gute N8! MM Leider habe ich bei der Kopie meines Codes nicht alle Zeilen, die mit "#"begannen, gelöscht. Sorry. > Das Ding soll so kurz wie möglich sein, besser noch etwas kürzer. > Steht übrigens auch ausführlich in der MicroPython Dokumentation. Ach ja, wieder mal ein Hinweis auf eine Doku oder ein DaBla. Ich hoffe aber, dass alles was verwendbar oder sogar wichtig ist in sokchen Dokumenten steht. Fragt sich nur: Wo? Ein Buch ohne umfangreichen Index ist oft nicht besonders hilfleich. > Wenn's dennoch etwas länger sein soll - wozu keinerlei Veranlassung > besteht - dann mittels schedule() ??? schedule waht? > >> Leider fand ich nicht, wie man Python veranlasst, das Schreiben in eine >> Datei an deren Ende fortzusetzen :-(( > Alle Parameter sind beim open() Befehl beschrieben. Tja, das war zu vermuten, zumindest zu hoffen. Ich hab jüngst mal nachgesehen welche Doku es für Python gibt und wie diese strukturiert ist. My humble opinion only: Grausam. >> Die vorschau zeigte mir leider nicht, dass es mir gelang code als code zu >> markieren. Schau mer mal. > Versuch als erste Zeile: > #!/usr/bin/python3 > Naja es gelang ja doch, was jedoch mittels Vorschau nicht erkennbar war :-( > > Mal schauen ob dieser Thread noch zu retten ist, gerade wird ja wieder > mal reichlich sabotiert. Es vermengen sich halt verschiedene Intentionen und Meinungen. Keep it easy! VG MM
Hinweis: Mein Posting vom 15.07.2022 00:08 war mit VG & Gute N8! MM noch nicht am Ende
Manfred M. schrieb: > Nimm mal aus meinem Code > print("pin.value=", pin) > was (lt. print("pin.value=", pin)) erzeugt: > pin.value= Pin(16, mode=IN, pull=PULL_UP) > doch dann bringt > if pin.value()==1: Das dürfte daran liegen, dass pin != pin.value ist. Bzw. versuch es doch mal mit print("pin.value=", pin.value). Ansonten kann ich dir zustimmen. Ich komm mit der Python Doku auch nicht gut klar. Glücklicherweise wurden so ziemlich alle Probleme, die man haben kann schon einmal gelöst und irgendwer hat auf StackOverflow danach gefragt.
Manfred M. schrieb: > Aha, Zeon erinnert sich. Ich auch, habe aber Niklas Wirts Buch nicht > hier, so dass ich hier nur aus der Erinnerung Stellung beziehen kann, > also ohne Nachprüfung Da ich mehrere Delphiversionen installiert hab ist so etwas schnell nachgeprüft.
https://docs.micropython.org/en/latest/ https://docs.python.org/3/ Also ich - persönliche Erfahrung - finde darin alles was ich brauche. Beide Websites haben eine Suchfunktion die einem das Blättern in dicken Büchern erspart. ;-) Manfred M. schrieb: > Nimm mal aus meinem Code > print("pin.value=", pin) > was (lt. print("pin.value=", pin)) erzeugt: > pin.value= Pin(16, mode=IN, pull=PULL_UP) > doch dann bringt > if pin.value()==1: > das was ich, ohne Kenntnis von "pin.value= Pin(16, mode=IN, > pull=PULL_UP)" erwarte (obwohl "Pin(16, mode=IN, pull=PULL_UP" kein > boolscher Wert ist), nämlich etwas das mittels == 1 verglichen werden > kann Sauberer:
1 | #!/usr/bin/python3
|
2 | |
3 | from machine import Pin |
4 | pin_x = Pin(16, Pin.IN, Pin.PULL_UP) |
5 | print(type(pin_x)) |
6 | ## <class 'Pin'>
|
7 | |
8 | ## pin_x: Die Referenz auf das angelegte Objekt.
|
9 | |
10 | print(type(pin_x.value)) |
11 | ## <class 'bound_method'>
|
12 | |
13 | ## pin_x.value: Eine Methode des angelegten Objektes.
|
14 | |
15 | print(type(pin_x.value())) |
16 | ## <class 'int'>
|
17 | |
18 | ## pin_x.value(): Die liefert einen Integer Wert, den Zustand des pins.
|
19 | |
20 | pin_level = pin_x.value() |
21 | pin_level
|
22 | ## 1
|
Manfred M. schrieb: > schedule waht? https://docs.micropython.org/en/latest/reference/isr_rules.html?highlight=schedule Manfred M. schrieb: >>> Leider fand ich nicht, wie man Python veranlasst, das Schreiben in eine >>> Datei an deren Ende fortzusetzen :-(( >> Alle Parameter sind beim open() Befehl beschrieben. > > Tja, das war zu vermuten, zumindest zu hoffen. > > Ich hab jüngst mal nachgesehen welche Doku es für Python gibt und wie > diese strukturiert ist. My humble opinion only: Grausam. https://docs.python.org/3.7/library/functions.html#open
nfet schrieb: > Das dürfte daran liegen, dass pin != pin.value ist. > Bzw. versuch es doch mal mit print("pin.value=", pin.value). Das wird nicht funktionieren. Um den Wert zu bekommen muss man die Methode value auch aufrufen (Klammern beachten): print( "pin.value=", pin.value() ) > Ansonten kann ich dir zustimmen. Ich komm mit der Python Doku auch nicht > gut klar. Nun, die Dokumentation ist enorm umfangreich und kann einen zuerst ›erschlagen‹. Dennoch, man findet so ziemlich alles was man braucht. Was die Doku nicht bietet sind fertige Vorschläge oder Programme. Aus gutem Grund, das ist ein Kochbuch und keine Speisekarte. ;-)
Manfred M. schrieb: > Ach ja, wieder mal ein Hinweis auf eine Doku oder ein DaBla. > Ich hoffe aber, dass alles was verwendbar oder sogar wichtig ist in > sokchen Dokumenten steht. Fragt sich nur: Wo? Eines hatte ich noch vergessen zu erwähnen: Beide Dokumentationen kann man komplett herunterladen und auf dem eigenen Rechnerlein in seinen lokalen Webserver einmassieren. Dann gibt's die Antworten auf alle Fragen in annähernd Lichtgeschwindigkeit. Mit Index, Referenz, Erklärung aller Module, Tutorial, Suchfunktion. etc. Und ja, alles ist ausgiebig erklärt.
Manfred M. schrieb: >> Gerade Niklas Wirth hat das nicht vorgemacht; Funktionen wie writeln >> kann man in Pascal selbst nicht schreiben, denn in Pascal gibt es keine >> variadischen Funktionen -- außer eben writeln. > > richtig und das war ein bewusste Entscheidung, die Wirth auch begründete > (sofern ich mich richtig erinnere - was wahrscheinlich ist). Für mich ein Fehler im Sprachdesign. Entweder ist so ein Feature nützlich, dann baut man die Möglichkeiten dafür in die Sprache ein, oder man hält es für unnötig, dann gibt's sowas halt nicht - und zwar gar nicht. Aber dann ein paar Ausnahmen für "spezielle" Funktionen zu machen, ist irgendwie merkwürdig. Manfred M. schrieb: > Die Frage ist aber auch, ob man variadische Funktionen braucht /haben > oder vielleicht nur nützlich sind. Naja, Wirth ist bei seiner Sprache ja offenbar nicht ohne ausgekommen, also hat er sie wohl für nützlich gehalten. Nur: Warum bekommt der Nutzer der Sprache dann nicht die gleichen Möglichkeiten? Das ist so ähnlich wie bei der nicht vorhandenen Operator-Überladung für Klassen in Java - außer beim Operator + für die Klasse String. Das ist doch doof wenn eine Sprache sich eine Klasse an den eigenen Regeln vorbei definieren muss.
Norbert schrieb 15.07.2022 07:24 im Beitrag #7127486:
> Sauberer:
Hallo Norbert,
vielen Dank für Deine hilfreichen Mitteilungen.
und @all:
Oben zitierte ich ein Wort, worin gewissermaßen "der Hund begraben ist":
Man kann in Python sauber(er) und unsauber(er) programmieren. Das passt
nicht gut zu meiner Vorstellung wie programmiert werden sollte (aber
vielleicht zum rapid prototyping). So eine Art rapid prototyping mag ja
nützlich nützlich sein, doch ist es gefährlich wenn bei Beendigung von
einem Projekt(chen) ein Prototyp übrig bleibt (weil man bereits zum
nächsten eilen muss).
Was ich beobachte (besonders im Umfeld von Android) ist, dass sehr viele
Prototypen als App bezeichnet werden. Dass es Prototypen sind erkennt
man an den Mängeln, die sie haben, und viele sind ziemlich voll davon.
Bereits an den Meldungen, die manche Android-Apps produzieren, erkennt
man, dass es sich um so etwas wie einen Prototypen handelt (z.B.
Meldungen, die nicht mitteilen woher sie kommen).
Beispiel: Umwandlungen von Datentypen dürfen m.E. nicht implizit (also
im Verborgenen) stattfinden, müssen statt dessen mit
Konvertierungsfunktionen/-methoden durchgeführt werden.
Ganz schlimm wird es dann, wenn Syntax erst zur Laufzeit geprüft wird,
so wie ich es bei meinen IRQ-Testprogrämmchen beobachten konnte. Da wird
dann erst beim Sprung in den IRQ-Handler gemeldet, dass sich darin ein
Syntaxfehler befindet. Nanu ??? Wie oft mag es vorkommen, dass eine
Methode, ein Stückchen Code während der Entwicklung und Test nie
angesprungen wird und irgendwann später dann doch und es knallt erst
dann? Und dann eine für den Benutzer des Codes erratische Fehlermeldung
"syntax error in line 1"?
Ich wollte mir ja nur das Verhalten des Pico bei IRQ genauer ansehen,
habe ein Stückchen Code abgeschrieben, ein bisserl dran rumgeschraubt
und bin in mich erstaunende Probleme gelaufen.
Vielleicht sollte ich hier erwähnen, dass ich mich seit 1970 mit
allerlei Code-, Compiler- und Maschinenverhalten herumgeärgert habe
(manchmal) und nicht nur ich allein in den Gruppen, in denen ich
arbeitete.
Also: Mein Idee war "nur", ich schau mir mal was genauer an und stelle
fest: Ich griff in etwas, das ist lauwarm und riecht übel. Keinen
Zweifel haben ich, dass man's sauberer machen kann. Problem: Man muss es
nicht tun.
Beispiel:
1 | import machine |
2 | |
3 | sensor = machine.Pin(28, machine.Pin.IN, machine.Pin.PULL_DOWN) |
4 | |
5 | def irq_handler(pin) |
6 | if pin.value(): |
7 | print("pin.value = ", pin.value()) |
8 | |
9 | sensor.irq(trigger=machine.Pin.IRQ_RISING, handler= irq_handler) |
produziert File "<stdin>", line 6 SyntaxError: invalid syntax Du wirst es wahrscheinlich sofort sehen, dass ein ":" fehlt. Also ergänze ich es, doch dabei verwandelt sich "pin" in ein kursives "pin". Wieso? Annahme: Es wurde ein Objekt "pin" (eine Instanz der Klasse Pin ??) übergeben, die im Code aber nicht (explizit) deklariert wurde. In einem "object inspector" kann ich nachsehen, welche Attribute und Methoden zur Class "Pin" gehören, darunter eine function "value". Dann die Idee, dass ich mir anschaue, was diese liefert, also print("pin.value = ", pin.value()) was 1 ausgibt. Also ist pin.value eine integer-function! Oder? Nun sind einige Fragen in meinem Kopf, insbes.: Wie sind die Objekte miteinander verbandelt? daher füge ich einige "print("type von xyz = ", type(xyz))" und auch "print("pin.value = ", pin.value())" ein und erfahre type von sensor = <class 'Pin'> type von sensor.irq = <class 'bound_method'> >>> type(irq_handler) = <class 'function'> ' Wieso ">>>"? type von pin = <class 'Pin'> type von pin.value = <class 'bound_method'> type von pin.value() = <class 'int'> pin.value = 1 Es wird also (vermutlich) ein Objekt "sensor" der class "Pin" erzeugt mit einer bound_method "sensor.irq" mit einem Parameter "pin" aus der class "Pin", die eine bound_method "pin.value" enthält, deren returnvalue aus der class int ist (mit dem Wert 1). Nun wäre zu klären wie die function irq-handler es schafft, sich mit dem realen Pin28 zu verbandeln Ich nehme an so: realer Pin 28 --> Objekt "sensor" --> sensor.irq --> Funktion "irq_handler" mit Parameter "pin" aus Klasse "Pin" mit der bound_method "pin.value", deren Returnvalue aus der Klasse "int" ist. RICHTIG?
Manfred M. schrieb: > [...blub...] > Also: Mein Idee war "nur", ich schau mir mal was genauer an und stelle > fest: Ich griff in etwas, das ist lauwarm und riecht übel. Keinen > Zweifel haben ich, dass man's sauberer machen kann. Problem: Man muss es > nicht tun. > [...blub...] Du hast es dir eben nicht genau angeguckt. Du hast flüchtig drüber geguckt und das gesehen, was du sehen wolltest: "Das ist keine Wirth'sche Sprache". Und dann hast du über dinge gejammert, die du einfach nicht verstehst. Das ist zumindest, was bei mir angekommen ist. Aber dann, ich bin mit Vorurteilen (Oh da hat wieder jemand nach ein paar Tagen Beschäftigung mit einem schlechten online-Tutorial ein Problem gefunden, dass niemand gefunden hat, der sich 40h/Woche professionell damit beschäftigt) in diesen Thread gekommen, die auf dem Titel basieren.
Mombert H. schrieb: > Manfred M. schrieb: >> [...blub...] >> Also: Mein Idee war "nur", ich schau mir mal was genauer an und stelle >> fest: Ich griff in etwas, das ist lauwarm und riecht übel. Keinen >> Zweifel haben ich, dass man's sauberer machen kann. Problem: Man muss es >> nicht tun. >> [...blub...] > Du hast es dir eben nicht genau angeguckt. > Du hast flüchtig drüber > geguckt und das gesehen, was du sehen wolltest: "Das ist keine > Wirth'sche Sprache". Und dann hast du über dinge gejammert, die du > einfach nicht verstehst. Dinge die ich einfach nicht verstehe: Das habe ich selbst bemerkt, dh. dass es mir nicht mitgeteilt werden muss. > Das ist zumindest, was bei mir angekommen ist. Fein! So war's beabsichtigt: Dass bei anderen ankommt, das ich etwas "einfach" (oder nicht) nicht verstehe. Das genaue angucken wollte ich ja tun. Eine triviale Anmerkung ist also auch diese: "Du hast es dir eben nicht genau angeguckt." > Aber dann, [... snipped... ] Fazit: Dein Posting ist ziemlich überflüssig gewesen!
Manfred M. schrieb: > Ich nehme an so: > realer Pin 28 --> > Objekt "sensor" --> > sensor.irq --> > Funktion "irq_handler" mit Parameter "pin" aus Klasse "Pin" mit der > bound_method "pin.value", deren Returnvalue aus der Klasse "int" ist. > > RICHTIG?
1 | #!python
|
2 | import machine |
3 | |
4 | ## Definiere eine ›normale‹ Funktion mit einem Parameter.
|
5 | ## Dieser Parameter wird später beim Aufruf als Referenz auf die
|
6 | ## triggernde Instanz übergeben.
|
7 | ## Da es eine Instanz der Klasse Pin sein wird,
|
8 | ## kann man die Pin-Methoden anwenden.
|
9 | ## Die value Methode liefert in diesem Fall einen Int Wert.
|
10 | def eine_interrupt_funktion(instanz) |
11 | if instanz.value(): |
12 | print(f"value = {instanz.value()}") |
13 | |
14 | ## Erzeuge eine Instanz der Klasse Pin
|
15 | sensor = machine.Pin(28, machine.Pin.IN, machine.Pin.PULL_DOWN) |
16 | |
17 | ## Rufe für diese Instanz die Methode irq auf.
|
18 | ## Übergebe worauf sie triggern soll
|
19 | ## und welche Funktion sie aufrufen soll.
|
20 | sensor.irq(trigger=machine.Pin.IRQ_RISING, handler= eine_interrupt_funktion) |
Manfred M. schrieb: > RICHTIG? Das sind alles Anfängerfragen, die in jedem Python-Grundlagenbuch beantwortet werden.
MaWin schrieb: > Manfred M. schrieb: >> RICHTIG? > > Das sind alles Anfängerfragen, gut erkannt! > die in jedem Python-Grundlagenbuch beantwortet werden. Aha, hast also in allen nachge-sehen /-lesen? :-O Deine Mitteilung ist sehr hilfreich! ;-) :-( ;-( Dank! ;-(
Manfred M. schrieb: > Aha, hast also in allen nachge-sehen /-lesen? Nö. Aber du könntest es ja einmal versuchen. Aber aufpassen! Am Ende hast du noch die Grundlagen gelernt!
MaWin schrieb: > Manfred M. schrieb: >> Aha, hast also in allen nachge-sehen /-lesen? > > Nö. Aber du könntest es ja einmal versuchen. Aber aufpassen! Am Ende > hast du noch die Grundlagen gelernt! Aaah auch sehr hilfreich. Da revanchiere ich mich mit einem für Dich sicher hilfreichen Tipp: Adolph Freiherr von Knigge: "Über den Umgang mit Menschen" 8 € und für Dich sicher sehr zu empfehlen.
Manfred M. schrieb: > Aaah auch sehr hilfreich. Gern geschehen. > Da revanchiere ich mich Vielen Dank!
Manfred M. schrieb: > Aaah auch sehr hilfreich. Was ist denn nun überhaupt noch die Frage? LG, Sebastian
Sebastian schrieb: > Manfred M. schrieb: >> Aaah auch sehr hilfreich. > > Was ist denn nun überhaupt noch die Frage? > > LG, Sebastian Dank für die Nachfrage, doch momentan gibt es meinerseits keine weitere(n) Frage(n), insbes. Norbert sei Dank! Schönes Wochenende! VG MM
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.