Author Topic: Funny (as in debugging-useful) print format in Python  (Read 3729 times)

0 Members and 1 Guest are viewing this topic.

Offline RoGeorgeTopic starter

  • Super Contributor
  • ***
  • Posts: 8459
  • Country: ro
Funny (as in debugging-useful) print format in Python
« on: February 14, 2025, 01:58:29 am »
Found in these random YT suggested videos from Indently channel:
https://youtu.be/EoNOWVYKyo0
https://youtu.be/aa39jL7wdJs

Code: [Select]
a: int = 5000
b: int = 10000
print(f'{a + b = }')

in python 3 will print "a + b = 15000"  :)
Or, print(f'{a + b = :_.2f}') will print "a + b = 15_000.00"  8)

Offline bpiphany

  • Regular Contributor
  • *
  • Posts: 137
  • Country: se
Re: Funny (as in debugging-useful) print format in Python
« Reply #1 on: February 14, 2025, 06:59:55 am »
Python 3.11 or 12 or so to be more specific. Where you may not yet be depending on how far back on the LTS chain you exist.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17783
  • Country: fr
Re: Funny (as in debugging-useful) print format in Python
« Reply #2 on: February 14, 2025, 09:28:44 am »
Yeah, f-strings allow some funky stuff.
https://realpython.com/python-f-strings/
 

Offline janoc

  • Super Contributor
  • ***
  • Posts: 3958
  • Country: de
Re: Funny (as in debugging-useful) print format in Python
« Reply #3 on: February 14, 2025, 10:30:46 am »
F-strings are old news, this was added in Python 3.6, back in 2016. I.e. almost a decade back:

https://www.python.org/downloads/release/python-360/

PEP 498, Literal String Formatting
 

Offline tszaboo

  • Super Contributor
  • ***
  • Posts: 9787
  • Country: nl
  • Current job: ATEX product design
Re: Funny (as in debugging-useful) print format in Python
« Reply #4 on: February 14, 2025, 10:50:45 am »
Found in these random YT suggested videos from Indently channel:
https://youtu.be/EoNOWVYKyo0
https://youtu.be/aa39jL7wdJs

Code: [Select]
a: int = 5000
b: int = 10000
print(f'{a + b = }')

in python 3 will print "a + b = 15000"  :)
Or, print(f'{a + b = :_.2f}') will print "a + b = 15_000.00"  8)
IMHO this falls under the category of programming for side effects.
Which is bad practice.
f string is there to substitute a part of a string with something. So f'{a]' is OK. f'{max(a)}' is questionable, your example is bad practice. Only reason to do it is if there is like a list comprehension or some other code quality reasons, and still you want to have a lot of comments on what the line does. Because 5 minutes from now nobody is going to understand it.
 

Online DiTBho

  • Super Contributor
  • ***
  • Posts: 5097
  • Country: gb
Re: Funny (as in debugging-useful) print format in Python
« Reply #5 on: February 14, 2025, 11:04:53 am »
this falls under the category of programming for side effects.
Which is bad practice.

An almost incredible tale of "triumph" and "tragedy", but ...
... there is actually people who writes book about this stuff.

what?  :o :o :o

I saw books in Japan about this for CASIO graphing programming calculators.
Practices used onto CASIO Basic + ucPython to take the control via exploits
made on "side effects" that break the interpreter.
The opposite of courage is not cowardice, it is conformity. Even a dead fish can go with the flow
 

Offline golden_labels

  • Super Contributor
  • ***
  • Posts: 2441
  • Country: pl
Re: Funny (as in debugging-useful) print format in Python
« Reply #6 on: February 14, 2025, 03:00:57 pm »
IMHO this falls under the category of programming for side effects.(…)
This expression has no side effects. That = is a part of the formatting language. This way you can print the expression and its value without having to duplicate code. See the last example. RoGeorge just used a more complicated expression.
Why 📎 | We live in times when half of people have IQ below 100.
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 4838
  • Country: us
Re: Funny (as in debugging-useful) print format in Python
« Reply #7 on: February 15, 2025, 04:11:24 am »

IMHO this falls under the category of programming for side effects.
Which is bad practice.

It's neither programming for side effects not bad practice.

Quote
f string is there to substitute a part of a string with something.

Which is what it does?

Quote
Because 5 minutes from now nobody is going to understand it.

It displays the value of the expression?  I honestly don't know what your are getting at.
 

Offline golden_labels

  • Super Contributor
  • ***
  • Posts: 2441
  • Country: pl
Re: Funny (as in debugging-useful) print format in Python
« Reply #8 on: February 15, 2025, 06:45:36 am »
I suspect tszaboo took that for some obscure quirk of Python. His reply would make sense then. :)
Why 📎 | We live in times when half of people have IQ below 100.
 

Offline tszaboo

  • Super Contributor
  • ***
  • Posts: 9787
  • Country: nl
  • Current job: ATEX product design
Re: Funny (as in debugging-useful) print format in Python
« Reply #9 on: February 15, 2025, 09:55:52 am »

IMHO this falls under the category of programming for side effects.
Which is bad practice.

It's neither programming for side effects not bad practice.

Quote
f string is there to substitute a part of a string with something.

Which is what it does?

Quote
Because 5 minutes from now nobody is going to understand it.

It displays the value of the expression?  I honestly don't know what your are getting at.
It's bullshit side effect of a design feature, that wasn't intended to be used this way.
Programmers who write code like this make code like this make unmaintainable code.
It's the equivalent of bragging: "Look at me. I'm so smart. I made a calculation implicit instead of explicit. I also obfuscated the code and made it hard to read and understand. "
Nobody likes these people.
 

Offline jfiresto

  • Super Contributor
  • ***
  • Posts: 1047
  • Country: de
Re: Funny (as in debugging-useful) print format in Python
« Reply #10 on: February 15, 2025, 10:21:33 am »

IMHO this falls under the category of programming for side effects.
Which is bad practice.

It's neither programming for side effects not bad practice.

Quote
f string is there to substitute a part of a string with something.

Which is what it does?

Quote
Because 5 minutes from now nobody is going to understand it.

It displays the value of the expression?  I honestly don't know what your are getting at.
It's bullshit side effect of a design feature, that wasn't intended to be used this way....

Except that is isn't. The language grammar page gives the syntax. The proposal for its implementation explains its rationale.
-John
 

Offline tszaboo

  • Super Contributor
  • ***
  • Posts: 9787
  • Country: nl
  • Current job: ATEX product design
Re: Funny (as in debugging-useful) print format in Python
« Reply #11 on: February 15, 2025, 10:28:13 am »
It is bullshit.
It might print "a + b = 15000" or "5000 + 10000 = " or SyntaxError: invalid syntax
You have no idea what it should print. Bad practice.
There is a more understandable and explicit way of achieving the same.
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 4838
  • Country: us
Re: Funny (as in debugging-useful) print format in Python
« Reply #12 on: February 16, 2025, 03:45:57 pm »
You have no idea what it should print..

I definitely know exactly what it should print.  It's an explicit design feature and everybody who uses it knows what it does. 

It's also the best way to implement it because there is no chance of mismatch between the printed text and the evaluated expression.  For instance if you do print(f"a+b={a + b}") and later modify it to print(f"a+b={a+b+c}") you are going to have incorrect diagnostic messages.  Same thing if you use a separate temporary variable in the same way. print(f"{a+b=}") on the other hand works correctly with less opportunity for error.
 

Offline bpiphany

  • Regular Contributor
  • *
  • Posts: 137
  • Country: se
Re: Funny (as in debugging-useful) print format in Python
« Reply #13 on: February 17, 2025, 11:58:13 am »
I was wrong. The equals thing for f-strings was added in 3.8. I believe it was primarily meant as a convenience for debugging, not production code so much.
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 4838
  • Country: us
Re: Funny (as in debugging-useful) print format in Python
« Reply #14 on: February 17, 2025, 06:41:05 pm »
I was wrong. The equals thing for f-strings was added in 3.8. I believe it was primarily meant as a convenience for debugging, not production code so much.

I would say it's useful for both debugging (a development task) and logging (a production task).  I wouldn't use it for a something end user visible or for persistent serialization.  But that has nothing to do with "side effects" or it being poorly defined.  It's just usually not desirable to export your internal identifier names to end users or to make it part of your behavior contract.
 

Offline John B

  • Super Contributor
  • ***
  • Posts: 1073
  • Country: au
Re: Funny (as in debugging-useful) print format in Python
« Reply #15 on: February 17, 2025, 08:25:40 pm »
I don't really mind that it does it, however it does seem to lack logical consistency in that the curly brackets should be evaluated like a normal line of code. It looks like it should throw a syntax error.

But then again, I'm not a python pythonista who thinks pythonically.
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 4838
  • Country: us
Re: Funny (as in debugging-useful) print format in Python
« Reply #16 on: February 18, 2025, 04:42:41 am »
I don't really mind that it does it, however it does seem to lack logical consistency in that the curly brackets should be evaluated like a normal line of code. It looks like it should throw a syntax error.

It is slightly inconsistent but the fstring  already allowed formatting specifiers in the same location like f"{x:.5f}". So it's never been the case that the entire thing in braces is evaluated as an expression. The way it is inconsistent is that it doesn't map to a .format() option because this behavior doesn't make sense for the format method.
« Last Edit: February 18, 2025, 05:59:25 am by ejeffrey »
 

Offline golden_labels

  • Super Contributor
  • ***
  • Posts: 2441
  • Country: pl
Re: Funny (as in debugging-useful) print format in Python
« Reply #17 on: February 18, 2025, 07:40:51 am »
Permitting format specifiers is no more inconsistent than allowing expressions.

F-strings are Python’s implementation of string interpolation. To be exactly consistent with the pure concept of string interpolation, an f-string should permit nothing more than a single variable name inside curly braces. The style PHP and sh do this with $ (without {…}).

Most languages do extend this basic concept for programmer’s convenience. So does Python, giving us both: expressions and format specifiers. The only quirk of Python is, that it accepts unexpectedly wide range of expressions.(1) But not only it hasn’t been touched in this topic, but what it makes “inconsistent with the idea” is expressions themselves, not the format specifiers.

Note that it should really be “intuitional consistency,” not “logical consistency.” If we’re to be precise. :)


(1) Those are valid f-strings, despite you probably don’t want them to be:
Code: [Select]
a = f'{" "}'
print(a)

x = 0
b = f'{(x:=4)}'
print(b, x)

y = 10
c = f'{#
    y}'
print(c)

o = {'Foo': 'Bar'}
d = f'{o.pop("Foo")}'
print(d)

it = iter([0, 1, 2, 3])
e = f'{next(it)} {next(it)} {next(it)} {next(it)}'
print(e)

z = None
g = f'{(z := lambda x: x + 4, z(10))[1]}'
print(g)
Why 📎 | We live in times when half of people have IQ below 100.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17783
  • Country: fr
Re: Funny (as in debugging-useful) print format in Python
« Reply #18 on: February 18, 2025, 10:12:44 am »
The problem with allowing arbitrary expressions in string formats is to allow unwanted execution of code, obviously. How does Python protect against that?
 

Offline bpiphany

  • Regular Contributor
  • *
  • Posts: 137
  • Country: se
Re: Funny (as in debugging-useful) print format in Python
« Reply #19 on: February 18, 2025, 11:04:26 am »
But it's not arbitrary any more than what you as the programmer put in there, is it? It's perfectly possible to "execute" arguments to f-formatting in other languages too. The only thing the '=' does is to output the argument as a string as well as the result of it, if I understand it correctly.
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 4838
  • Country: us
Re: Funny (as in debugging-useful) print format in Python
« Reply #20 on: February 18, 2025, 05:40:57 pm »
The problem with allowing arbitrary expressions in string formats is to allow unwanted execution of code, obviously. How does Python protect against that?

f-string parsing is part of the parser so it only works on string literals, never user input strings.  Essentially the whole f-string implementation is syntactic sugar around the "format" method.

Code: [Select]
print(f"{x}, {y}, {z}")

is transformed by by the parser into:

Code: [Select]
print("{0}, {1}, {2}".format(x, y, z))

Outside of eval() there isn't even an API that would let you inject arbitrary expressions into the formatting code.  It's still true that it puts executable code into something that might look like a string literal.  However any code editor will syntax highlight it as code not string literals.

The = operators is also handled specially by the parser.

Code: [Select]
print(f"{x=}, {y+z}")

is transformed into:

Code: [Select]
print("x={0}, y+z={1}".format(x, y+z))

That is, the parser takes the expression between braces and inserts it both as text into the resulting string literal and also as an argument to the format method.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17783
  • Country: fr
Re: Funny (as in debugging-useful) print format in Python
« Reply #21 on: February 19, 2025, 12:17:57 am »
The problem with allowing arbitrary expressions in string formats is to allow unwanted execution of code, obviously. How does Python protect against that?

f-string parsing is part of the parser so it only works on string literals, never user input strings.  Essentially the whole f-string implementation is syntactic sugar around the "format" method.

Ok. If there's absolutely no means of building a f-string dynamically, then it kind of answers my question.

There's a simple way of circumventing this though, and it's by using eval():
Code: [Select]
x, y, z = 1,2,-3

F1 = "{x+y*z}"

eval('f"' + F1 + '"')

Now you may reply that it's a potential security issue that has more to do with eval() than with f-strings themselves. But can you build and use f-strings dynamically (resorting to eval()), yes. :-/O
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf