• get_used_memory

    From Lawrence D?Oliveiro@3:633/10 to All on Fri Jun 12 03:46:43 2026
    So I looked at the example Gambas program at <https://gambaswiki.org/wiki/doc/whatisgambas> and marvelled at its
    unnecessary complexity (UUOC, even). It?s like PHP with variable
    declarations!

    Here?s my version: excluding header comments and blank lines and
    shebang line, it?s about half the size.

    info = dict \
    (
    (entry[0][:-1], int(entry[-2]))
    for line in open("/proc/meminfo", "rt")
    for entry in (tuple(s.strip() for s in line.split(" ")),)
    if entry[-2] != ""
    )
    print("Used memory: %d Kb" % (info["MemTotal"] - info["MemFree"] - info["Buffers"] - info["Cached"] + info["SwapTotal"] - info["SwapFree"] - info["SwapCached"]))

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Jon Ribbens@3:633/10 to All on Fri Jun 12 07:18:09 2026
    On 2026-06-12, Lawrence D?Oliveiro <ldo@nz.invalid> wrote:
    So I looked at the example Gambas program at
    <https://gambaswiki.org/wiki/doc/whatisgambas> and marvelled at its
    unnecessary complexity (UUOC, even). It?s like PHP with variable declarations!

    Here?s my version: excluding header comments and blank lines and
    shebang line, it?s about half the size.

    info = dict \
    (
    (entry[0][:-1], int(entry[-2]))
    for line in open("/proc/meminfo", "rt")
    for entry in (tuple(s.strip() for s in line.split(" ")),)
    if entry[-2] != ""
    )
    print("Used memory: %d Kb" % (info["MemTotal"] - info["MemFree"] - info["Buffers"] - info["Cached"] + info["SwapTotal"] - info["SwapFree"] - info["SwapCached"]))

    Better:

    with open('/proc/meminfo') as meminfo:
    info = {
    entry[0][:-1]: int(entry[1])
    for line in meminfo
    if (entry := line.split())
    }
    print('Used memory: %d kB' % (
    info['MemTotal'] - info['MemFree'] - info['Buffers'] - info['Cached'] +
    info['SwapTotal'] - info['SwapFree'] - info['SwapCached']
    ))


    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Paul Rubin@3:633/10 to All on Sat Jun 13 12:38:08 2026
    Jon Ribbens <jon+usenet@unequivocal.eu> writes:
    with open('/proc/meminfo') as meminfo:
    info = {
    entry[0][:-1]: int(entry[1])
    for line in meminfo
    if (entry := line.split())
    }

    with open('/proc/meminfo') as meminfo:
    info = dict(line.split()[:2] for line in meminfo)

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Jon Ribbens@3:633/10 to All on Sat Jun 13 19:58:32 2026
    On 2026-06-13, Paul Rubin <no.email@nospam.invalid> wrote:
    Jon Ribbens <jon+usenet@unequivocal.eu> writes:
    with open('/proc/meminfo') as meminfo:
    info = {
    entry[0][:-1]: int(entry[1])
    for line in meminfo
    if (entry := line.split())
    }

    with open('/proc/meminfo') as meminfo:
    info = dict(line.split()[:2] for line in meminfo)

    An excellent point, although it does mean the ':' characters remain
    in the dictionary keys.

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Jon Ribbens@3:633/10 to All on Sat Jun 13 20:02:55 2026
    On 2026-06-13, Jon Ribbens <jon+usenet@unequivocal.eu> wrote:
    On 2026-06-13, Paul Rubin <no.email@nospam.invalid> wrote:
    Jon Ribbens <jon+usenet@unequivocal.eu> writes:
    with open('/proc/meminfo') as meminfo:
    info = {
    entry[0][:-1]: int(entry[1])
    for line in meminfo
    if (entry := line.split())
    }

    with open('/proc/meminfo') as meminfo:
    info = dict(line.split()[:2] for line in meminfo)

    An excellent point, although it does mean the ':' characters remain
    in the dictionary keys.

    Oh, and doesn't have ints as the dictionary values, which is rather
    more fatal to the use-case.

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Paul Rubin@3:633/10 to All on Sat Jun 13 14:13:40 2026
    Jon Ribbens <jon+usenet@unequivocal.eu> writes:

    Oh, and doesn't have ints as the dictionary values, which is rather
    more fatal to the use-case.

    print("Used memory: %d Kb" % (info["MemTotal"] - info["MemFree"] - info["Buffers"] - info["Cached"] + info["SwapTotal"] - info["SwapFree"] - info["SwapCached"]))

    It really should look at the units in the meminfo file too, but anyway,

    alloced = ['MemTotal', 'SwapTotal']
    free = ['MemFree, 'Buffers', 'Cached', 'SwapFree', 'SwapCached']

    def total(xs): return sum(int(info[f'{x}:']) for x in xs)
    print(f''Used memory: {total(alloced) - total(free)} Kb')

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Jon Ribbens@3:633/10 to All on Sat Jun 13 21:35:21 2026
    On 2026-06-13, Paul Rubin <no.email@nospam.invalid> wrote:
    Jon Ribbens <jon+usenet@unequivocal.eu> writes:

    Oh, and doesn't have ints as the dictionary values, which is rather
    more fatal to the use-case.

    print("Used memory: %d Kb" % (info["MemTotal"] - info["MemFree"] - info["Buffers"] - info["Cached"] + info["SwapTotal"] - info["SwapFree"] - info["SwapCached"]))

    It really should look at the units in the meminfo file too, but anyway,

    Yes, although that's not entirely possible since proc_meminfo(5) doesn't document what units are possible (although in actual fact it appears
    that every line is hard-coded to either say 'kB' or no unit, no other
    options are available and which lines have 'kB' or not never changes).

    alloced = ['MemTotal', 'SwapTotal']
    free = ['MemFree, 'Buffers', 'Cached', 'SwapFree', 'SwapCached']

    def total(xs): return sum(int(info[f'{x}:']) for x in xs)
    print(f''Used memory: {total(alloced) - total(free)} Kb')

    Yes, obviously it is physically possible to write the code to cope with
    the altered data structure. Just, there's a reason that neither my nor Lawrence's version used your neat dict(line.split()[:2] ...) trick.

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Paul Rubin@3:633/10 to All on Sat Jun 13 15:20:31 2026
    Jon Ribbens <jon+usenet@unequivocal.eu> writes:
    Lawrence's version used your neat dict(line.split()[:2] ...) trick.

    Maybe this:

    dict((a,int(b)) for a,b in (x.split()[:2] for x in xs))

    I feel like there should be a way to do this with the := operator
    instead of the nested generators, but it doesn't seem to be there.

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Jon Ribbens@3:633/10 to All on Sat Jun 13 22:53:48 2026
    On 2026-06-13, Paul Rubin <no.email@nospam.invalid> wrote:
    Jon Ribbens <jon+usenet@unequivocal.eu> writes:
    Lawrence's version used your neat dict(line.split()[:2] ...) trick.

    Maybe this:

    dict((a,int(b)) for a,b in (x.split()[:2] for x in xs))

    I feel like there should be a way to do this with the := operator
    instead of the nested generators, but it doesn't seem to be there.

    That was the way my version did it? If I use abbreviated variable names
    like your version, it's actually shorter than yours ;-)

    {e[0][:-1]: int(e[1]) for x in xs if (e := x.split())}

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lawrence D?Oliveiro@3:633/10 to All on Sun Jun 14 01:09:00 2026
    On Sat, 13 Jun 2026 12:38:08 -0700, Paul Rubin wrote:

    with open('/proc/meminfo') as meminfo:
    info = dict(line.split()[:2] for line in meminfo)

    Output on my machine of

    print("Used memory: %d Kb" % (info["MemTotal"] - info["MemFree"] - info["Buffers"] - info["Cached"] + info["SwapTotal"] - info["SwapFree"] - info["SwapCached"]))

    from my version:

    Used memory: 13646656 Kb

    From your version:

    ---------------------------------------------------------------------------
    KeyError Traceback (most recent call last)
    Cell In[3], line 3
    1 with open('/proc/meminfo') as meminfo:
    2 info = dict(line.split()[:2] for line in meminfo)
    ----> 3 print("Used memory: %d Kb" % (info["MemTotal"] - info["MemFree"] - info["Buffers"] - info["Cached"] + info["SwapTotal"] - info["SwapFree"] - info["SwapCached"]))

    KeyError: 'MemTotal'

    Tisk-tisk ...

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lawrence D?Oliveiro@3:633/10 to All on Sun Jun 14 01:10:04 2026
    On Sat, 13 Jun 2026 15:20:31 -0700, Paul Rubin wrote:

    I feel like there should be a way to do this with the := operator
    instead of the nested generators, but it doesn't seem to be there.

    You feel like there are lots of things you could do with the :=
    operator ... if it were actually of any use.

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Paul Rubin@3:633/10 to All on Sun Jun 14 01:28:40 2026
    Lawrence D?Oliveiro <ldo@nz.invalid> writes:
    KeyError: 'MemTotal'

    Yeah you have to use 'MemTotal:' as the key. But, you still have to
    convert the digit strings to integers.

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lawrence D?Oliveiro@3:633/10 to All on Sun Jun 14 23:56:14 2026
    On Sun, 14 Jun 2026 01:28:40 -0700, Paul Rubin wrote:

    Yeah you have to use 'MemTotal:' as the key. But, you still have to
    convert the digit strings to integers.

    ?I could solve that problem in a fraction of the code, if I didn?t
    have to solve it correctly.?

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Paul Rubin@3:633/10 to All on Sun Jun 14 17:23:24 2026
    Jon Ribbens <jon+usenet@unequivocal.eu> writes:
    {e[0][:-1]: int(e[1]) for x in xs if (e := x.split())}

    Does this work?

    { a : int(b)) for x in xs if (a,b := x.split()) }

    I think it's ok to keep the ':' in the field name. Otherwise

    { a.rstrip(':') : int(b)) for x in xs if (a,b := x.split()) }

    seems a bit more explicit at the expense of a few more chars.

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Jon Ribbens@3:633/10 to All on Mon Jun 15 00:40:11 2026
    On 2026-06-15, Paul Rubin <no.email@nospam.invalid> wrote:
    Jon Ribbens <jon+usenet@unequivocal.eu> writes:
    {e[0][:-1]: int(e[1]) for x in xs if (e := x.split())}

    Does this work?

    { a : int(b)) for x in xs if (a,b := x.split()) }

    No, for three reasons. Firstly, the lines with units result in x.split()
    having 3 members, so you can't assign it to a 2-tuple. Secondly, it
    appears that (a, b := x) means "create a tuple whose first member is
    a and whose second member is x, and also assign x to b", which is not
    at all what we need. Thirdly, if we fix that second one by saying
    ((a, b) := x.split()), you get "SyntaxError: cannot use assignment
    expressions with tuple". (Assignment expressions are weirdly limited
    for no apparent reason.)

    I think it's ok to keep the ':' in the field name. Otherwise

    { a.rstrip(':') : int(b)) for x in xs if (a,b := x.split()) }

    seems a bit more explicit at the expense of a few more chars.

    a[:-1] would work and is shorter. But yeah it doesn't matter much.

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Paul Rubin@3:633/10 to All on Sun Jun 14 18:18:26 2026
    Jon Ribbens <jon+usenet@unequivocal.eu> writes:
    { a : int(b)) for x in xs if (a,b := x.split()) }
    No, for three reasons. Firstly, the lines with units result in x.split() having 3 members, so you can't assign it to a 2-tuple.

    Oh yes I had intended to say x.split()[:2] but somehow left that out.

    Secondly, it appears that (a, b := x) means "create a tuple whose
    first member is a and whose second member is x, and also assign x to
    b", which is not at all what we need.

    Yuck, I had expected tuple unpacking. Sounds like a pitfall comparable
    to "=" vs "==" that kept the := operator out of the language for so
    long. Oh well.

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Jon Ribbens@3:633/10 to All on Mon Jun 15 07:20:05 2026
    On 2026-06-15, Paul Rubin <no.email@nospam.invalid> wrote:
    Jon Ribbens <jon+usenet@unequivocal.eu> writes:
    { a : int(b)) for x in xs if (a,b := x.split()) }
    No, for three reasons. Firstly, the lines with units result in x.split()
    having 3 members, so you can't assign it to a 2-tuple.

    Oh yes I had intended to say x.split()[:2] but somehow left that out.

    Secondly, it appears that (a, b := x) means "create a tuple whose
    first member is a and whose second member is x, and also assign x to
    b", which is not at all what we need.

    Yuck, I had expected tuple unpacking. Sounds like a pitfall comparable
    to "=" vs "==" that kept the := operator out of the language for so
    long. Oh well.

    My biggest complaint about := is the arbitrary and mysterious
    restrictions on what you can use on the left hand side. You can't
    even say "a.b := c". The PEP that introduced ":=" barely even
    mentions these restrictions, let alone discusses or explains them.

    --- PyGate Linux v1.5.16
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)