Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #197800 > unrolled thread
| Started by | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| First post | 2026-06-12 03:46 +0000 |
| Last post | 2026-06-14 23:56 +0000 |
| Articles | 18 — 3 participants |
Back to article view | Back to comp.lang.python
get_used_memory Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-12 03:46 +0000
Re: get_used_memory Jon Ribbens <jon+usenet@unequivocal.eu> - 2026-06-12 07:18 +0000
Re: get_used_memory Paul Rubin <no.email@nospam.invalid> - 2026-06-13 12:38 -0700
Re: get_used_memory Jon Ribbens <jon+usenet@unequivocal.eu> - 2026-06-13 19:58 +0000
Re: get_used_memory Jon Ribbens <jon+usenet@unequivocal.eu> - 2026-06-13 20:02 +0000
Re: get_used_memory Paul Rubin <no.email@nospam.invalid> - 2026-06-13 14:13 -0700
Re: get_used_memory Jon Ribbens <jon+usenet@unequivocal.eu> - 2026-06-13 21:35 +0000
Re: get_used_memory Paul Rubin <no.email@nospam.invalid> - 2026-06-13 15:20 -0700
Re: get_used_memory Jon Ribbens <jon+usenet@unequivocal.eu> - 2026-06-13 22:53 +0000
Re: get_used_memory Paul Rubin <no.email@nospam.invalid> - 2026-06-14 17:23 -0700
Re: get_used_memory Jon Ribbens <jon+usenet@unequivocal.eu> - 2026-06-15 00:40 +0000
Re: get_used_memory Paul Rubin <no.email@nospam.invalid> - 2026-06-14 18:18 -0700
Re: get_used_memory Jon Ribbens <jon+usenet@unequivocal.eu> - 2026-06-15 07:20 +0000
Re: get_used_memory Paul Rubin <no.email@nospam.invalid> - 2026-06-15 12:02 -0700
Re: get_used_memory Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-14 01:10 +0000
Re: get_used_memory Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-14 01:09 +0000
Re: get_used_memory Paul Rubin <no.email@nospam.invalid> - 2026-06-14 01:28 -0700
Re: get_used_memory Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-06-14 23:56 +0000
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-06-12 03:46 +0000 |
| Subject | get_used_memory |
| Message-ID | <110fvf3$1tqe3$1@dont-email.me> |
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"]))
[toc] | [next] | [standalone]
| From | Jon Ribbens <jon+usenet@unequivocal.eu> |
|---|---|
| Date | 2026-06-12 07:18 +0000 |
| Message-ID | <slrn112nclh.5fs.jon+usenet@raven.unequivocal.eu> |
| In reply to | #197800 |
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']
))
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2026-06-13 12:38 -0700 |
| Message-ID | <8733yq9qov.fsf@nightsong.com> |
| In reply to | #197801 |
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)
[toc] | [prev] | [next] | [standalone]
| From | Jon Ribbens <jon+usenet@unequivocal.eu> |
|---|---|
| Date | 2026-06-13 19:58 +0000 |
| Message-ID | <slrn112rdj8.5fs.jon+usenet@raven.unequivocal.eu> |
| In reply to | #197803 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Jon Ribbens <jon+usenet@unequivocal.eu> |
|---|---|
| Date | 2026-06-13 20:02 +0000 |
| Message-ID | <slrn112rdrf.5fs.jon+usenet@raven.unequivocal.eu> |
| In reply to | #197804 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2026-06-13 14:13 -0700 |
| Message-ID | <878q8i87p7.fsf@nightsong.com> |
| In reply to | #197805 |
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')
[toc] | [prev] | [next] | [standalone]
| From | Jon Ribbens <jon+usenet@unequivocal.eu> |
|---|---|
| Date | 2026-06-13 21:35 +0000 |
| Message-ID | <slrn112rj8p.5fs.jon+usenet@raven.unequivocal.eu> |
| In reply to | #197806 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2026-06-13 15:20 -0700 |
| Message-ID | <874ij684ls.fsf@nightsong.com> |
| In reply to | #197807 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Jon Ribbens <jon+usenet@unequivocal.eu> |
|---|---|
| Date | 2026-06-13 22:53 +0000 |
| Message-ID | <slrn112rnrs.5fs.jon+usenet@raven.unequivocal.eu> |
| In reply to | #197808 |
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())}
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2026-06-14 17:23 -0700 |
| Message-ID | <877bo07itf.fsf@nightsong.com> |
| In reply to | #197809 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Jon Ribbens <jon+usenet@unequivocal.eu> |
|---|---|
| Date | 2026-06-15 00:40 +0000 |
| Message-ID | <slrn112uifb.5fs.jon+usenet@raven.unequivocal.eu> |
| In reply to | #197814 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2026-06-14 18:18 -0700 |
| Message-ID | <87tsr461p9.fsf@nightsong.com> |
| In reply to | #197815 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Jon Ribbens <jon+usenet@unequivocal.eu> |
|---|---|
| Date | 2026-06-15 07:20 +0000 |
| Message-ID | <slrn112v9t5.5fs.jon+usenet@raven.unequivocal.eu> |
| In reply to | #197816 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2026-06-15 12:02 -0700 |
| Message-ID | <87pl1r62zn.fsf@nightsong.com> |
| In reply to | #197817 |
Jon Ribbens <jon+usenet@unequivocal.eu> writes: > 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. Yeah that's pretty annoying. Haskell doesn't have destructive assignments at all, but you can put the equivalent of match/case inside expressions. So, something like: fromList [(a, read b) | (a:b:_) <- words x | x <- xs] :: Map String Int The vertical bar is like "for" in Python's list comprehensions, "read" is like int(str) except it converts to arbitrary datatypes, "words" is like "split", and ":: Map String Int" is a type annotation that says it's making a dictionary mapping strings to Ints. The Int type signature tells "read" to convert to ints instead of floats or whatever. Finally, (a:b:_) binds the first two elements of x.split() and throws away the rest. I haven't tested the above so maybe I did something dumb. I haven't written any Haskell in a while.
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-06-14 01:10 +0000 |
| Message-ID | <110kv1c$3a32m$8@dont-email.me> |
| In reply to | #197808 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-06-14 01:09 +0000 |
| Message-ID | <110kuvc$3a32m$7@dont-email.me> |
| In reply to | #197803 |
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 ...
[toc] | [prev] | [next] | [standalone]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2026-06-14 01:28 -0700 |
| Message-ID | <87se6p7cg7.fsf@nightsong.com> |
| In reply to | #197810 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-06-14 23:56 +0000 |
| Message-ID | <110nf2u$3vra6$4@dont-email.me> |
| In reply to | #197812 |
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.”
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web