Forum: PC-Programmierung Designfehler in (Micro)Python?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Manfred M. (mm_lauf)


Angehängte Dateien:

Lesenswert?

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.
von Hmmm (Gast)


Lesenswert?

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().

von DPA (Gast)


Lesenswert?

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.
von Manfred M. (mm_lauf)


Lesenswert?

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?

von Norbert (Gast)


Lesenswert?

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$

von DerEgon (Gast)


Lesenswert?

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.

von Sebastian (Gast)


Lesenswert?

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

von DPA (Gast)


Lesenswert?

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.

von Manfred M. (mm_lauf)


Lesenswert?

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$

von Manfred M. (mm_lauf)


Lesenswert?

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

von Norbert (Gast)


Lesenswert?

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.

von Manfred M. (mm_lauf)


Lesenswert?

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.

von Zeno (Gast)


Lesenswert?

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.

von Manfred M. (mm_lauf)


Lesenswert?

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.

von Manfred M. (mm_lauf)


Lesenswert?

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).

von Zeno (Gast)


Lesenswert?

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.

von Manfred M. (mm_lauf)


Lesenswert?

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.

von Norbert (Gast)


Lesenswert?

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.

von Mombert H. (mh_mh)


Lesenswert?

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 ...

von Manfred M. (mm_lauf)


Lesenswert?

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

von Manfred M. (mm_lauf)


Lesenswert?

Hinweis:
Mein Posting vom 15.07.2022 00:08 war mit
   VG & Gute N8!
   MM
noch nicht am Ende

von nfet (Gast)


Lesenswert?

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.

von Zeno (Gast)


Lesenswert?

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.

von Norbert (Gast)


Lesenswert?

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

von Norbert (Gast)


Lesenswert?

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. ;-)

von Norbert (Gast)


Lesenswert?

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.

von Rolf M. (rmagnus)


Lesenswert?

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.

von Manfred M. (mm_lauf)


Lesenswert?

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?

von Mombert H. (mh_mh)


Lesenswert?

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.

von Manfred M. (mm_lauf)


Lesenswert?

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!

von Norbert (Gast)


Lesenswert?

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)

von MaWin (Gast)


Lesenswert?

Manfred M. schrieb:
> RICHTIG?

Das sind alles Anfängerfragen, die in jedem Python-Grundlagenbuch 
beantwortet werden.

von Manfred M. (mm_lauf)


Lesenswert?

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!  ;-(

von MaWin (Gast)


Lesenswert?

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!

von Manfred M. (mm_lauf)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

Manfred M. schrieb:
> Aaah auch sehr hilfreich.

Gern geschehen.

> Da revanchiere ich mich

Vielen Dank!

von Sebastian (Gast)


Lesenswert?

Manfred M. schrieb:
> Aaah auch sehr hilfreich.

Was ist denn nun überhaupt noch die Frage?

LG, Sebastian

von Manfred M. (mm_lauf)


Lesenswert?

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
Noch kein Account? Hier anmelden.