• Is there a better way? [combining f-string, thousands separator,right align]

    From Gilmeh Serda@gilmeh.serda@nothing.here.invalid to comp.lang.python on Sun Aug 25 15:12:20 2024
    From Newsgroup: comp.lang.python

    Subject explains it, or ask.

    This is a bloody mess:

    s = "123456789" # arrives as str
    f"{f'{int(s):,}': >20}"
    ' 123,456,789'
    --
    Gilmeh

    I have a rock garden. Last week three of them died. -- Richard Diran
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From ram@ram@zedat.fu-berlin.de (Stefan Ram) to comp.lang.python on Sun Aug 25 15:42:24 2024
    From Newsgroup: comp.lang.python

    Gilmeh Serda <gilmeh.serda@nothing.here.invalid> wrote or quoted:
    Subject explains it, or ask.

    Or, you could have asked this way:

    |Please fill in the implementation (replacing "pass" below) for
    |the following function definition!
    |
    |def format_number(number_str: str) -> str:
    | """
    | Format a string of digits as a right-aligned, comma-separated number.
    |
    | This function takes a string of digits and returns a formatted string where:
    | - The number is right-aligned in a field width of 20 characters
    | - Commas are inserted as thousand separators
    | - Leading spaces are added for alignment
    |
    | Args:
    | number_str (str): A string containing only digits (0-9)
    |
    | Returns:
    | str: A formatted string with the number right-aligned and comma-separated
    |
    | Examples:
    | >>> format_number("123456789")
    | ' 123,456,789'
    | >>> format_number("1000000")
    | ' 1,000,000'
    | >>> format_number("42")
    | ' 42'
    | >>> format_number("1234567890123456789")
    | '1,234,567,890,123,456,789'
    | """
    | pass


    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From ram@ram@zedat.fu-berlin.de (Stefan Ram) to comp.lang.python on Sun Aug 25 15:46:25 2024
    From Newsgroup: comp.lang.python

    ram@zedat.fu-berlin.de (Stefan Ram) wrote or quoted:
    | >>> format_number("123456789")
    | ' 123,456,789'

    Yeah, you totally can combine the two format specifications into one:

    f"{int(number):>20,}"

    .


    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Pierre Fortin@pf@pfortin.com to comp.lang.python on Sun Aug 25 21:38:22 2024
    From Newsgroup: comp.lang.python

    On Sun, 25 Aug 2024 15:12:20 GMT Gilmeh Serda via Python-list wrote:

    Subject explains it, or ask.

    This is a bloody mess:

    s = "123456789" # arrives as str
    f"{f'{int(s):,}': >20}"
    ' 123,456,789'

    Oops.. forgot comma

    f"{int(s):>20,}"
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From MRAB@python@mrabarnett.plus.com to comp.lang.python on Mon Aug 26 02:55:03 2024
    From Newsgroup: comp.lang.python

    On 2024-08-25 16:12, Gilmeh Serda via Python-list wrote:
    Subject explains it, or ask.

    This is a bloody mess:

    s = "123456789" # arrives as str
    f"{f'{int(s):,}': >20}"
    ' 123,456,789'

    You don't need to format twice; you can combine them:

    s = "123456789"
    f'{int(s): >20,}'
    ' 123,456,789'

    or if you rely on default behaviour:

    f'{int(s):20,}'
    ' 123,456,789'

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Pierre Fortin@pf@pfortin.com to comp.lang.python on Sun Aug 25 21:34:51 2024
    From Newsgroup: comp.lang.python

    On Sun, 25 Aug 2024 15:12:20 GMT Gilmeh Serda via Python-list wrote:

    Subject explains it, or ask.

    This is a bloody mess:

    s = "123456789" # arrives as str
    f"{f'{int(s):,}': >20}"
    ' 123,456,789'


    f"{s:>20}"
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From dn@PythonList@DancesWithMice.info to comp.lang.python on Mon Aug 26 20:42:32 2024
    From Newsgroup: comp.lang.python

    On 26/08/24 03:12, Gilmeh Serda via Python-list wrote:
    Subject explains it, or ask.

    This is a bloody mess:

    s = "123456789" # arrives as str
    f"{f'{int(s):,}': >20}"
    ' 123,456,789'


    With recent improvements to the expressions within F-strings, we can
    separate the string from the format required. (reminiscent of FORTRAN
    which had both WRITE and FORMAT statements, or for that matter HTML
    which states the 'what' and CSS the 'how')

    Given that the int() instance-creation has a higher likelihood of
    data-error, it is recommended that it be a separate operation for ease
    of fault-finding - indeed some will want to wrap it with try...except.

    s = "123456789" # arrives as str
    s_int = int( s ) # makes the transformation obvious and distinct

    s_format = ">20," # define how the value should be presented

    F"{s_int:{s_format}}"
    ' 123,456,789'


    Further, some of us don't like 'magic-constants', hence (previously):

    S_FIELD_WIDTH = 20
    s_format = F">{S_FIELD_WIDTH},"


    and if we really want to go over-board:

    RIGHT_JUSTIFIED = ">"
    THOUSANDS_SEPARATOR = ","
    s_format = F"{RIGHT_JUSTIFIED}{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"

    or (better) because right-justification is the default for numbers:

    s_format = F"{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"


    To the extreme that if your user keeps fiddling with presentations (none
    ever do, do they?), all settings to do with s_format could be added to a config/environment file, and thus be even further separated from program-logic!
    --
    Regards,
    =dn
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From 2QdxY4RzWzUUiLuE@2QdxY4RzWzUUiLuE@potatochowder.com to comp.lang.python on Mon Aug 26 06:00:32 2024
    From Newsgroup: comp.lang.python

    On 2024-08-26 at 20:42:32 +1200,
    dn via Python-list <python-list@python.org> wrote:

    and if we really want to go over-board:

    RIGHT_JUSTIFIED = ">"
    THOUSANDS_SEPARATOR = ","
    s_format = F"{RIGHT_JUSTIFIED}{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"

    or (better) because right-justification is the default for numbers:

    s_format = F"{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"


    To the extreme that if your user keeps fiddling with presentations (none
    ever do, do they?), all settings to do with s_format could be added to a config/environment file, and thus be even further separated from program-logic!

    And then you'll need a parser, many of whose Unique Challenges™ aren't
    even apparent until you start parsing files from actual users, and
    you'll still need some sort of fallback in the code anyway for the case
    that s_format can't be parsed (for whatever reason).

    Isn't a config file what just caused the global CrowdStrike outage? ;-)

    That said, I understand that report generators are a thing, not to
    mention RPG (https://en.wikipedia.org/wiki/IBM_RPG).

    Okay, sorry; I'll just crawl back into the hole from whence I came.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From ram@ram@zedat.fu-berlin.de (Stefan Ram) to comp.lang.python on Mon Aug 26 11:30:44 2024
    From Newsgroup: comp.lang.python

    dn <PythonList@DancesWithMice.info> wrote or quoted:
    and if we really want to go over-board:
    RIGHT_JUSTIFIED = ">"
    THOUSANDS_SEPARATOR = ","
    s_format = F"{RIGHT_JUSTIFIED}{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"

    def PROCEDURE_DEFINIION( NAME, BODY ):
    return f'\ndef {NAME}():\n{" "*4}{BODY}\n'

    def PRINT_STATEMENT( WHAT_TO_PRINT ):
    return f'print( "{WHAT_TO_PRINT}" )'

    def PROCEDURE_INVOCATION( WHAT_TO_INVOKE ):
    return f'{WHAT_TO_INVOKE}()'

    exec\
    ( PROCEDURE_DEFINIION( "f", PRINT_STATEMENT( "Hello, world!" ))+
    PROCEDURE_INVOCATION( "f" ))


    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From dn@PythonList@DancesWithMice.info to comp.lang.python on Tue Aug 27 08:27:11 2024
    From Newsgroup: comp.lang.python

    On 26/08/24 23:00, Dan Sommers via Python-list wrote:
    On 2024-08-26 at 20:42:32 +1200,
    dn via Python-list <python-list@python.org> wrote:

    and if we really want to go over-board:

    RIGHT_JUSTIFIED = ">"
    THOUSANDS_SEPARATOR = ","
    s_format = F"{RIGHT_JUSTIFIED}{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"

    or (better) because right-justification is the default for numbers:

    s_format = F"{S_FIELD_WIDTH}{THOUSANDS_SEPARATOR}"


    To the extreme that if your user keeps fiddling with presentations (none
    ever do, do they?), all settings to do with s_format could be added to a
    config/environment file, and thus be even further separated from
    program-logic!

    And then you'll need a parser, many of whose Unique Challenges™ aren't
    even apparent until you start parsing files from actual users, and
    you'll still need some sort of fallback in the code anyway for the case
    that s_format can't be parsed (for whatever reason).

    Isn't a config file what just caused the global CrowdStrike outage? ;-)

    That said, I understand that report generators are a thing, not to
    mention RPG (https://en.wikipedia.org/wiki/IBM_RPG).

    Okay, sorry; I'll just crawl back into the hole from whence I came.


    Not at all. Please continue to question/ask/suggest!

    This is a valid point. There are costs and benefits (trade-offs) to all decisions!

    That said, writing one's own parser would become a veritable can of worms/rabbit hole. Here be dragons!

    Similarly, explaining this takes longer than writing the example itself!


    Older Windows users will know about .ini files, and Linux Admins are
    familiar with .conf files. Many of us are already using JSON or YAML
    formats. Any of these (and more) could be pressed into service, as
    above. At the 'top end', there are also whole libraries devoted to establishing application configuration or "environments": default
    values, config files, command-line options, user-input...

    Have switched to using Python-poetry, which replaces packaging methods
    such as setuptools (as well as virtual-environment tools). It takes its project configuration specifications from a pyproject.toml file. So, for
    a few projects lately, I've been using .toml for application-config as
    well. However, I have to say, this more from an attempt at consistency
    than a decision of logic. (critique welcome)

    That said, a setup.py configuration, took the form:

    setup(
    name='demo_project',
    version='1.1.0',
    packages=find_packages(),
    install_requires=[
    'requests',
    'numpy',
    ...
    ],
    entry_points={
    ...

    Accordingly, it offers an example of the simplest format (for us), and
    one which has a zero-learning pre-requisite. At execution-time, the
    moment such a config is import-ed, a syntax-error will immediately bring proceedings to a halt!


    I have some stats-wonks as clients. They dabble in programming, but (fortunately) realise their limitations. (usually!) The boss has had to
    ban them from 'improving' my code ($paid to be an improvement on their
    usual quality), but including a .py configuration/options file has
    proven to be an honor-preserving compromise. Of course, they manage
    their own runs, adjusting parameters as they go. So, any errors are
    their own, and they can fix themselves (without anyone else knowing!).

    Such would not work in many?most other environments - children: do not
    try this at home!


    An irritation for those of us who have to delve into projects after
    they've been written, is a git-history full of the sorts of
    user-tweaking changes vilified earlier. Putting user-config into a
    separate file, even a separate sub-directory, makes it easy to spot
    which updates to ignore, and thus, which to consider!


    PS the reason why CrowdStrike was not the end of humanity as we know it,
    (and only that of those who only know MSFT's eco-system) is because the majority of the world's Internet servers run Linux - including Azure
    (brings to mind the old saw: the package said "runs on Windows-95 or
    better" so I installed it on Linux!)

    Joking aside, we (virtuous ones) ALWAYS test BEFORE release. Correct?
    --
    Regards,
    =dn
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Gilmeh Serda@gilmeh.serda@nothing.here.invalid to comp.lang.python on Tue Aug 27 20:48:27 2024
    From Newsgroup: comp.lang.python

    On 25 Aug 2024 15:46:25 GMT, Stefan Ram wrote:

    f"{int(number):>20,}"

    Great. Thanks. Do you have a link to where that's documented?

    I did web search, found nothing.
    --
    Gilmeh

    When a fellow says, "It ain't the money but the principle of the thing,"
    it's the money. -- Kim Hubbard
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From ram@ram@zedat.fu-berlin.de (Stefan Ram) to comp.lang.python on Tue Aug 27 21:36:47 2024
    From Newsgroup: comp.lang.python

    Gilmeh Serda <gilmeh.serda@nothing.here.invalid> wrote or quoted:
    On 25 Aug 2024 15:46:25 GMT, Stefan Ram wrote:
    f"{int(number):>20,}"
    Great. Thanks. Do you have a link to where that's documented?
    I did web search, found nothing.

    Stoked to hear you're into it!

    For docs, I usually snag the PDFs from "python.org," especially
    "reference.pdf" (the Python Language Reference) and "library.pdf"
    (the Python Library Reference), then I search them for keywords.

    The f-string stuff is laid out in "The Python Language Reference"
    since they're part of the language itself. A quick search for
    "f-str" gets you to "2.4.3 Formatted string literals," which says,
    "The result is then formatted using the format() protocol." So, you
    got to check out "The Python Library Reference" too! Searching for
    "format(" there zooms you right to "6.1.3 Format String Syntax"
    (via "Format Specification Mini-Language").

    But honestly, I usually just hit up a chatbot first. I'll drop
    in my code and say, "How can I make this shorter?".


    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Grant Edwards@grant.b.edwards@gmail.com to comp.lang.python on Tue Aug 27 17:39:21 2024
    From Newsgroup: comp.lang.python

    On 2024-08-27, Gilmeh Serda via Python-list <python-list@python.org> wrote:
    On 25 Aug 2024 15:46:25 GMT, Stefan Ram wrote:

    f"{int(number):>20,}"

    Great. Thanks. Do you have a link to where that's documented?

    I did web search, found nothing.

    https://docs.python.org/3/library/string.html#formatspec https://docs.python.org/3/reference/lexical_analysis.html#f-strings

    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Gilmeh Serda@gilmeh.serda@nothing.here.invalid to comp.lang.python on Fri Aug 30 05:22:17 2024
    From Newsgroup: comp.lang.python

    On Tue, 27 Aug 2024 17:39:21 -0400 (EDT), Grant Edwards wrote:

    On 2024-08-27, Gilmeh Serda via Python-list <python-list@python.org> wrote:
    On 25 Aug 2024 15:46:25 GMT, Stefan Ram wrote:

    f"{int(number):>20,}"

    Great. Thanks. Do you have a link to where that's documented?

    I did web search, found nothing.

    https://docs.python.org/3/library/string.html#formatspec https://docs.python.org/3/reference/lexical_analysis.html#f-strings

    Thanks. I'll check those as time allows.
    --
    Gilmeh

    National security is in your hands - guard it well.
    --- Synchronet 3.20a-Linux NewsLink 1.114
  • From Gilmeh Serda@gilmeh.serda@nothing.here.invalid to comp.lang.python on Fri Aug 30 05:25:40 2024
    From Newsgroup: comp.lang.python

    On 27 Aug 2024 21:36:47 GMT, Stefan Ram wrote:

    For docs, I usually snag the PDFs from "python.org," especially
    "reference.pdf" (the Python Language Reference) and "library.pdf"
    (the Python Library Reference), then I search them for keywords.

    Thanks, that's a good idea. I've usually gone for the web docs only.

    The f-string stuff is laid out in "The Python Language Reference"
    since they're part of the language itself. A quick search for
    [snip]

    Great. Thanks. I'll try to remember that.

    But honestly, I usually just hit up a chatbot first. I'll drop
    in my code and say, "How can I make this shorter?".

    In other words, a shortcut. :)
    --
    Gilmeh

    More people are flattered into virtue than bullied out of vice. -- R. S. Surtees
    --- Synchronet 3.20a-Linux NewsLink 1.114