evaluation question

avi.e.gross at gmail.com avi.e.gross at gmail.com
Mon Feb 13 12:41:16 EST 2023


Weatherby,

Of course you are right and people can, and do, discuss whatever they feel like.

My question is a bit more about asking if I am missing something here as my personal view is that we are not really exploring in more depth or breadth and are getting fairly repetitive as if in a typical SF time loop. How does one break out?

Languages often change and people do come and go so some topics can often be re-opened. This though is a somewhat focused forum and it is legitimate to ask if a conversation might best be taken elsewhere for now. The main focus is, at least in theory, aspects of python and mostly about the core as compared to very specific modules, let alone those nobody here has ever even used. Within that, it is fair at times to compare something in python to other languages or ask about perceived bugs or about possible future enhancements. We could discuss if "YIELD FROM" is just syntactic sugar as it often can be done with just the naked YIELD statement, or whether it really allows you to do innovative things, as an example.

But I think where this conversation has gone is fairly simple. The question was why print() does not return the number of characters printed. The answers boiled down to that this was not the design chosen and is mostly consistent with how python handles similar functions that return nothing when the change is largely "internal" in a sense. In addition, plenty of us have suggested alternate ways to get what the OP asked for, and also pointed out there are other things that someone may have wanted instead or in addition, including the actual number of bytes generated for encodings other than vanilla ASCII, or pixels if the text was rendered on a screen using variable width fonts and so on.

Some of the above already counted, in my mind, as adding depth or breadth to the original question. But if the conversation degrades to two or more sides largely talking past each other and not accepting what the other says, then perhaps a natural ending point has been reached. Call it a draw, albeit maybe a forfeit.

So, as part of my process, I am now stuck on hearing many questions as valid and others as not productive. I don't mean just here, but in many areas of my life. The answer is that historically, and in other ways, python took a specific path. Others took other paths. But once locked into this path, you run into goals of trying to remain consistent and not have new releases break older software or at least take time to deprecate it and give people time to adjust.

I have seen huge growing pains due to growth. An example is languages that have added features, such as promises and their variants and used them for many purposes such as allowing asynchronous execution using multiple methods or evaluating things in a more lazy way so they are done just in time. Some end up with some simple function call being augmented with quite a few additional functions with slightly different names and often different arguments and ways they are called that mostly should no longer be mixed with other variants of the function. You need compatibility with the old while allowing the new and then the newer and newest.

Had the language been built anew from scratch, it might be simpler and also more complex, as they would skip the older versions and pretty much use the shinier new version all the time, even as it often introduces many costs where they are not needed. 

So it can be very valid to ask questions as long as you also LISTEN to the answers and try to accept them as aspects of reality. Yes, python could have had a different design and perhaps someday may have a different design. But that is not happening TODAY so for today, accept what is and accept advice on how you might get something like what you want when, and if, you need it. The goal often is to get the job done, not to do it the way you insist it has to be done.

At some point, unless someone has more to say with some new twist, it does become a bit annoying.

So let me say something slightly new now. I have been reading about interesting uses of the python WITH statement and how it works. Some of the examples are creating an object with dunder methods that get invoked on entry and exit that can do all kinds of things. One is the ability to modify a list in a way that can be rolled back if there is an error and it is quite simple. You make a copy of the original list on entry. Things are then done to the copy. And if you exit properly, you copy the modified list back on top of the original list. Errors that result simply unwind the serious of transactions by leaving the original list untouched. 

Another example has your output stream redirected within the WITH and then put back in place after. What this allows, among many things, is for everything printed to be  desrever. Now clearly, such a technique could also be used to capture what is going to be printed, and count how many bytes or characters it produced and make the result available after you exit the region.  Heck, if fed a paragraph of text, it could not only print it but create one or more objects containing a detailed analysis including guessing what language it is in, translating it to English, pointing out spelling and grammar errors, and mailing you a copy! You can imagine quite a few side effects of calling print() but again, why would you put the functionality within print() versus in a function you wrote that does all that as well as calling print()?

But even assuming you code that properly and rewrite all your code as something like:

with capture:
    print(...)

# use chars_written_within_width as a variable created within that holds what you want.


Is that really any better than several other ways we have suggested would work such as creating an f-string independently and then printing it which would handle quite a few use cases?

If others wish to keep debating this topic or enhancing it, fine. I am not judging but simply expressing the personal opinion that even if I might have more to add, I am not motivated to do so any longer. Then again, I may soon lose the motivation to be part of this forum and take up other hobbies 😉


-----Original Message-----
From: Python-list <python-list-bounces+avi.e.gross=gmail.com at python.org> On Behalf Of Weatherby,Gerard
Sent: Monday, February 13, 2023 10:16 AM
To: python-list at python.org
Subject: Re: evaluation question

“Why are we even still talking about this?”

Because humans are social creatures and some contributors to the list like to discuss things in depth.


From: Python-list <python-list-bounces+gweatherby=uchc.edu at python.org> on behalf of avi.e.gross at gmail.com <avi.e.gross at gmail.com>
Date: Friday, February 10, 2023 at 6:19 PM
To: python-list at python.org <python-list at python.org>
Subject: RE: evaluation question
*** Attention: This is an external email. Use caution responding, opening attachments or clicking on links. ***

There are no doubt many situations someone wants to know how long something will be when printed but often at lower levels.

In variable-width fonts, for example, the number of characters does not really line up precisely with how many characters. Some encodings use a varying number of bytes and, again, the width of the output varies.

So for people who want to make 2-D formatted output like tables, or who want to wrap lines longer than N characters, you more often let some deeper software accept your data and decide on formatting it internally and either print it at once, when done calculating, or in the case of some old-style terminals, use something like the curses package that may use escape sequences to update the screen more efficiently in various ways.

If someone wants more control over what they print, rather than asking the
print() function to return something that is mostly going to be ignored, they can do the things others have already suggested here. You can make your message parts in advance and measure their length or anything else before you print. Or make a wrapper that does something for you before calling print, perhaps only for common cases and then returns the length to you after printing.

I wonder if the next request will be for  print() to know what your output device is and other current settings so it return the width your text takes up in pixels in the current font/size ...

I add a tidbit that many ways of printing allow you to specify the width you want something printed in such as you want a floating point value with so many digits after the decimal point in a zero or space padded field on the left. So there are ways to calculate in advance for many common cases as to how long each part will be if you specify it. Besides, I am not really sure if "print" even knows easily how many characters it is putting out as it chews away on the many things in your request and calls dunder methods in objects so they display themselves and so on. I assume it can be made to keep track, albeit I can imagine printing out an APL program with lots of overwritten characters where the number of bytes sent is way more than the number of spaces in the output.

Why are we even still talking about this? The answer to the question of why
print() does not return anything, let alone the number of characters printed, is BECAUSE.


-----Original Message-----
From: Python-list <python-list-bounces+avi.e.gross=gmail.com at python.org> On Behalf Of Python
Sent: Friday, February 10, 2023 4:56 PM
To: python-list at python.org
Subject: Re: evaluation question

On Sat, Feb 11, 2023 at 08:30:22AM +1100, Chris Angelico wrote:
> On Sat, 11 Feb 2023 at 07:36, Python <python at bladeshadow.org> wrote:
> > You would do this instead:
> >
> >     message = f"{username} has the occupation {job}."
> >     message_length = len(message)
> >     print(message)
> >     print(message_length)
> >     ...
> >
>
> It's worth noting WHY output functions often return a byte count. It's 
> primarily for use with nonblocking I/O, with something like this:
>
> buffer = b".............."
> buffer = buffer[os.write(fd, buffer):]
>
> It's extremely important to be able to do this sort of thing, but not 
> with the print function, which has a quite different job.

I would agree with this only partially.  Your case applies to os.write(), which is essentially just a wrapper around the write() system call, which has that sort of property... though it applies also to I/O in blocking mode, particularly on network sockets, where the number of bytes you asked to write (or read) may not all have been transferred, necessitating trying in a loop.

However, Python's print() function is more analogous to C's printf(), which returns the number of characters converted for an entirely different reason... It's precisely so that you'll know what the length of the string that was converted is.  This is most useful with the
*snprintf() variants where you're actually concerned about overrunning the buffer you've provided for the output string, so you can realloc() the buffer if it was indeed too small, but it is also useful in the context of, say, a routine to format text according to the size of your terminal.  In that context it really has nothing to do with blocking I/O or socket behavior.

--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!nyKmKANNzMqWDt2IGH9-Vv63_bioBGOYeokJy5GupmZVZIelplk15rvc_5NNbt6afc9yukh8y5X5mZXDVgr_PhY$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!nyKmKANNzMqWDt2IGH9-Vv63_bioBGOYeokJy5GupmZVZIelplk15rvc_5NNbt6afc9yukh8y5X5mZXDVgr_PhY$>

--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!nyKmKANNzMqWDt2IGH9-Vv63_bioBGOYeokJy5GupmZVZIelplk15rvc_5NNbt6afc9yukh8y5X5mZXDVgr_PhY$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!nyKmKANNzMqWDt2IGH9-Vv63_bioBGOYeokJy5GupmZVZIelplk15rvc_5NNbt6afc9yukh8y5X5mZXDVgr_PhY$>
--
https://mail.python.org/mailman/listinfo/python-list



More information about the Python-list mailing list