
Hallo,
das unten befindliche Programm funktioniert mit f-String-Formatierung nicht so, wie ich das erwarte. Wenn ich das F-String-Format, das ich haben möchte, zuerst als Striing formatiere (s), sieht es richtig aus.
Aber bei print(s) wird nicht das in s steckende f-string-Format interpretiert, sondern einfach nur s als String ausgegeben.
Das Programm soll übrigens Binärzahlen in Gray umwandeln und zurück. Mit der .format-Methode funktioniert das auch einwandfrei.
Aufruf des Programms in der kürzesten Weise:
grayCode.py 2 1
2 ist der kürzeste Graycode und 1 schaltet in den debug-Modus
Vielen Dank
Martin Ruppert
#!/usr/bin/python3 import sys if(len(sys.argv)<2): a=sys.argv[0].split('/') a=a[len(a)-1] print('usage:',a,'digits of GrayCode') print(' eg.',a,'12') exit(1)
def bintogray(bin): return(bin^(bin>>1))
def graytobin(n,gray): val=0 for i in range(n,-1,-1): val = val|((((1<<(i+1))&val)>>1)^((1<<i)&gray)) return(val)
dbg=0 if(len(sys.argv)>2):dbg=int(sys.argv[2]) fl=int(sys.argv[1]) fw=fl if(fw<4):fw=4 dl=int(fl/3.321928+1) #dezimale Stellen if(dl<4):dl=4 f="%%-%ds %%-%ds %%-%ds"%(dl,fw,fw) if(dbg>0):print("f=",f) h=f%("#val","gray","bin") f="{{:0{:1d}d}} {{:0{:1d}b}} {{:0{:1d}b}}".format(dl,fw,fw) #s wird in der for-Schleife unten nicht interpretiert, #sondern als string ausgegeben: s='f"'+str(f"{{i:0{dl}d}} {{gray:0{fw}b}} {{bin:0{fw}b}}")+'"' if(dbg>0):print("f=",f) if(dbg>0):print("s=",s) for i in range(2**fl): if(i%24==0):print(h) gray=bintogray(i) bin=graytobin(fl,gray) print(f.format(i,gray,bin)) s='f"'+(f"{{i:0{dl}d}} {{gray:0{fw}b}} {{bin:0{fw}b}}")+'"' print(s)

Das `f` gehört vor den String:
a = 5
print(f'{a}')
nicht in den String:
print(f"'{a}'")
Viele Grüße Mike
Am 22.06.20 um 12:36 schrieb ruppert@hs-worms.de:
Hallo,
das unten befindliche Programm funktioniert mit f-String-Formatierung nicht so, wie ich das erwarte. Wenn ich das F-String-Format, das ich haben möchte, zuerst als Striing formatiere (s), sieht es richtig aus.
Aber bei print(s) wird nicht das in s steckende f-string-Format interpretiert, sondern einfach nur s als String ausgegeben.
Das Programm soll übrigens Binärzahlen in Gray umwandeln und zurück. Mit der .format-Methode funktioniert das auch einwandfrei.
Aufruf des Programms in der kürzesten Weise:
grayCode.py 2 1
2 ist der kürzeste Graycode und 1 schaltet in den debug-Modus
Vielen Dank
Martin Ruppert
#!/usr/bin/python3 import sys if(len(sys.argv)<2): a=sys.argv[0].split('/') a=a[len(a)-1] print('usage:',a,'digits of GrayCode') print(' eg.',a,'12') exit(1)
def bintogray(bin): return(bin^(bin>>1))
def graytobin(n,gray): val=0 for i in range(n,-1,-1): val = val|((((1<<(i+1))&val)>>1)^((1<<i)&gray)) return(val)
dbg=0 if(len(sys.argv)>2):dbg=int(sys.argv[2]) fl=int(sys.argv[1]) fw=fl if(fw<4):fw=4 dl=int(fl/3.321928+1) #dezimale Stellen if(dl<4):dl=4 f="%%-%ds %%-%ds %%-%ds"%(dl,fw,fw) if(dbg>0):print("f=",f) h=f%("#val","gray","bin") f="{{:0{:1d}d}} {{:0{:1d}b}} {{:0{:1d}b}}".format(dl,fw,fw) #s wird in der for-Schleife unten nicht interpretiert, #sondern als string ausgegeben: s='f"'+str(f"{{i:0{dl}d}} {{gray:0{fw}b}} {{bin:0{fw}b}}")+'"' if(dbg>0):print("f=",f) if(dbg>0):print("s=",s) for i in range(2**fl): if(i%24==0):print(h) gray=bintogray(i) bin=graytobin(fl,gray) print(f.format(i,gray,bin)) s='f"'+(f"{{i:0{dl}d}} {{gray:0{fw}b}} {{bin:0{fw}b}}")+'"' print(s)

Am 22.06.20 um 14:27 schrieb Mike Müller:
Das `f` gehört vor den String:
a = 5
print(f'{a}')
nicht in den String:
print(f"'{a}'")
Die falsche Variante richtig geschrieben: ;)
print("f'{a}'")
Viele Grüße Mike
Am 22.06.20 um 12:36 schrieb ruppert@hs-worms.de:
Hallo,
das unten befindliche Programm funktioniert mit f-String-Formatierung nicht so, wie ich das erwarte. Wenn ich das F-String-Format, das ich haben möchte, zuerst als Striing formatiere (s), sieht es richtig aus.
Aber bei print(s) wird nicht das in s steckende f-string-Format interpretiert, sondern einfach nur s als String ausgegeben.
Das Programm soll übrigens Binärzahlen in Gray umwandeln und zurück. Mit der .format-Methode funktioniert das auch einwandfrei.
Aufruf des Programms in der kürzesten Weise:
grayCode.py 2 1
2 ist der kürzeste Graycode und 1 schaltet in den debug-Modus
Vielen Dank
Martin Ruppert
#!/usr/bin/python3 import sys if(len(sys.argv)<2): a=sys.argv[0].split('/') a=a[len(a)-1] print('usage:',a,'digits of GrayCode') print(' eg.',a,'12') exit(1)
def bintogray(bin): return(bin^(bin>>1))
def graytobin(n,gray): val=0 for i in range(n,-1,-1): val = val|((((1<<(i+1))&val)>>1)^((1<<i)&gray)) return(val)
dbg=0 if(len(sys.argv)>2):dbg=int(sys.argv[2]) fl=int(sys.argv[1]) fw=fl if(fw<4):fw=4 dl=int(fl/3.321928+1) #dezimale Stellen if(dl<4):dl=4 f="%%-%ds %%-%ds %%-%ds"%(dl,fw,fw) if(dbg>0):print("f=",f) h=f%("#val","gray","bin") f="{{:0{:1d}d}} {{:0{:1d}b}} {{:0{:1d}b}}".format(dl,fw,fw) #s wird in der for-Schleife unten nicht interpretiert, #sondern als string ausgegeben: s='f"'+str(f"{{i:0{dl}d}} {{gray:0{fw}b}} {{bin:0{fw}b}}")+'"' if(dbg>0):print("f=",f) if(dbg>0):print("s=",s) for i in range(2**fl): if(i%24==0):print(h) gray=bintogray(i) bin=graytobin(fl,gray) print(f.format(i,gray,bin)) s='f"'+(f"{{i:0{dl}d}} {{gray:0{fw}b}} {{bin:0{fw}b}}")+'"' print(s)
python-de maillist - python-de@python.org https://mail.python.org/mailman/listinfo/python-de

Hallo Martin,
schön, dass du deinen Code hier veröffentlichst. Lass es mich zum Anlass nehmen, weiter unten noch ein paar Kommentare dazu zu schreiben.
Das hier
s='f"'+(f"{{i:0{dl}d}} {{gray:0{fw}b}} {{bin:0{fw}b}}")+'"'
scheint mir ein Versuch zu sein, einen f-string innerhalb einer Zeichenkette zu generieren. War das beabsichtigt? Zumindest wird er dann nirgendwo verarbeitet. Wie Mike schon bemerkte, fehlt da irgendwas, aber mir ist nicht so ganz klar, was der Zweck war und was dann die richtige Korrektur wäre. Kannst du das ein bisschen erklären?
ruppert@hs-worms.de schrieb am 22.06.20 um 12:36:
#!/usr/bin/python3 import sys if(len(sys.argv)<2): a=sys.argv[0].split('/') a=a[len(a)-1] print('usage:',a,'digits of GrayCode') print(' eg.',a,'12') exit(1)
def bintogray(bin): return(bin^(bin>>1))
def graytobin(n,gray): val=0 for i in range(n,-1,-1): val = val|((((1<<(i+1))&val)>>1)^((1<<i)&gray)) return(val)
dbg=0 if(len(sys.argv)>2):dbg=int(sys.argv[2]) fl=int(sys.argv[1]) fw=fl if(fw<4):fw=4 dl=int(fl/3.321928+1) #dezimale Stellen if(dl<4):dl=4 f="%%-%ds %%-%ds %%-%ds"%(dl,fw,fw) if(dbg>0):print("f=",f) h=f%("#val","gray","bin") f="{{:0{:1d}d}} {{:0{:1d}b}} {{:0{:1d}b}}".format(dl,fw,fw) #s wird in der for-Schleife unten nicht interpretiert, #sondern als string ausgegeben: s='f"'+str(f"{{i:0{dl}d}} {{gray:0{fw}b}} {{bin:0{fw}b}}")+'"' if(dbg>0):print("f=",f) if(dbg>0):print("s=",s) for i in range(2**fl): if(i%24==0):print(h) gray=bintogray(i) bin=graytobin(fl,gray) print(f.format(i,gray,bin)) s='f"'+(f"{{i:0{dl}d}} {{gray:0{fw}b}} {{bin:0{fw}b}}")+'"' print(s)
Zusätzlich zu dem, was Mike schon gesagt hat: es wäre vermutlich auch für dich einfacher gewesen, in diesem Code einen Fehler zu finden, wenn du den Code mit mehr Abständen hingeschrieben hättest. Als jemand, der schon oft genug kopfschüttelnd vor meinem eigenen Code von vor ein paar Jahren gestanden hat, kann ich dir sagen: Code wird immer für Menschen geschrieben, nicht für Maschinen.
Ich finden z.B. das hier
if(fw<4):fw=4 dl=int(fl/3.321928+1) #dezimale Stellen if(dl<4):dl=4 f="%%-%ds %%-%ds %%-%ds"%(dl,fw,fw)
sehr schwer zu lesen, wohingegen ich das folgende viel klarer finde:
if fw < 4: fw = 4
dl = int(fl / 3.321928 + 1) # dezimale Stellen if dl < 4: dl = 4
f = "%%-%ds %%-%ds %%-%ds" % ( dl, fw, fw)
Noch besser als das letzte Kommando finde ich in diesem Fall:
f = f"%-{dl}s %-{fw}s %-{fw}s"
Und der Zahl "3.321928" würde ich auch noch einen Namen geben, damit klar ist, woher die so plötzlich kommt und was für eine Bedeutung die hat, z.B.
DEZIMALE_STELLEN_PRO_FRZLFIFF = 3.321928
dezimale_stellen = int(fl / DEZIMALE_STELLEN_PRO_FRZLFIFF + 1)
Vielleicht ist das nicht auf den ersten Blick klar, aber es könnte irgendwann ein Tag kommen, an dem du jemandem auf den Knien danken möchtest, dass eine Variable im Code "dezimale_stellen" heißt und nicht "dl". Im besten Fall dir selbst.
Stefan

Am 22.06.2020 um 12:36 schrieb ruppert@hs-worms.de:
das unten befindliche Programm funktioniert mit f-String-Formatierung nicht so, wie ich das erwarte. Wenn ich das F-String-Format, das ich haben möchte, zuerst als Striing formatiere (s), sieht es richtig aus.
Aber bei print(s) wird nicht das in s steckende f-string-Format interpretiert, sonde
...
#!/usr/bin/python3 import sys if(len(sys.argv)<2):
...
Ähm, welches /usr/bin/python3? die F-Strings gibt es erst seit Python 3.6. Läuft da vielleicht ein älteres Dreier-Python?
Grüße, A.B.

Andreas B. ab@sysing.de wrote:
Am 22.06.2020 um 12:36 schrieb ruppert@hs-worms.de:
das unten befindliche Programm funktioniert mit f-String-Formatierung nicht so, wie ich das erwarte. Wenn ich das F-String-Format, das ich haben möchte, zuerst als Striing formatiere (s), sieht es richtig aus.
Aber bei print(s) wird nicht das in s steckende f-string-Format interpretiert, sonde
...
#!/usr/bin/python3 import sys if(len(sys.argv)<2):
...
Ähm, welches /usr/bin/python3? die F-Strings gibt es erst seit Python 3.6. Läuft da vielleicht ein älteres Dreier-Python?
python 3.7.3 aus debian stable
Grüße, A.B.
Grüße M.Ruppert

Hallo nochmal,
es hilft doch durchaus, nicht nur Code zu lesen, sondern auch den Text, den du dazu geschrieben hast. :)
ruppert@hs-worms.de schrieb am 22.06.20 um 12:36:
das unten befindliche Programm funktioniert mit f-String-Formatierung nicht so, wie ich das erwarte. Wenn ich das F-String-Format, das ich haben möchte, zuerst als Striing formatiere (s), sieht es richtig aus.
Du meinst wohl diese Zeilen:
f = "{{:0{:1d}d}} {{:0{:1d}b}} {{:0{:1d}b}}".format(dl,fw,fw)
# s wird in der for-Schleife unten nicht interpretiert, # sondern als string ausgegeben:
s = 'f"' + str(f"{{i:0{dl}d}} {{gray:0{fw}b}} {{bin:0{fw}b}}") + '"'
bzw. wenn ich mir nur den f-string ansehe:
>>> dl = 5 >>> fw = 6 >>> f"{{i:0{dl}d}} {{gray:0{fw}b}} {{bin:0{fw}b}}" '{i:05d} {gray:06b} {bin:06b}'
Für mich sieht das soweit erstmal korrekt aus. Ich vermute, du möchtest etwas machen, was mit .format() funktioniert aber mit f-strings nicht: den Formatstring programmatisch erzeugen statt hinzuschreiben, stimmt das? f-strings sind ein festes Sprachkonstrukt, das direkt in der Sprache (bzw. im Parser) auf String-Literalen ausgewertet wird, daher ist es nicht möglich, f-strings zu generieren. (Ok, du könntest eval() verwenden, aber das ist recht langsam und auch fehleranfällig – tu's lieber nicht.) ".format()" dagegen wird dynamisch auf beliebigen Strings ausgewertet, nicht nur auf Literalen.
Du kannst .format() und f-strings aber auch mischen:
formatiere_ausgabe = \ f"{{i:0{dl}d}} {{gray:0{fw}b}} {{bin:0{fw}b}}".format
print(formatiere_ausgabe(i=i, gray=gray, bin=bin))
Hier ist "formatiere_ausgabe" die ".format" String-Methode, angewendet auf meinen Formatierungsstring, den ich per f-string erzeugt habe. Wenn ich diese Methode dann aufrufe, und meine drei Argumente übergebe, dann wird meine Ausgabe entsprechend dem Formatierungsstring zusammengestellt.
Stefan
participants (4)
-
Andreas B.
-
Mike Müller
-
ruppert@hs-worms.de
-
Stefan Behnel