# [Edu-sig] Partial Sums using List Comprehensions

kirby urner kirby.urner at gmail.com
Sat Feb 24 19:40:07 CET 2007

```I've appending a posting (of mine) from another group,
because of the Python syntax it contains:  a list
comprehension giving partial sums.  So often in math,
we want to do that, or in simple grocery store arithmetic,
or statistics, where what interests is a list of cumulative
sums, running totals.

Now an interesting way to date yourself is if you have
a "cringe reflex" when you see:

>>> halfoctas = [sum(manylayers[0:x]) for x in range(1,21)]

when you realize the *same totals* are starting over for
every member of the list, i.e. we're not capitalizing on having
start all over.  What a waste of perfectly good ADDs, right?

If you're old school assembler with limited RAM (8K sound
like a lot?) your reflex will be to cache those totals and run
screaming from any VHLL (very high level language) that
doesn't mirror your sense of memory/clock economy.

But in Python, is in other VHLLs such as J, it's economy
of syntax, and therefore conceptual economy in the
programmer's own brain, that we're seeking, less so a
perfectly optimized fleet of electrons through the CPU's

We waste "clock cycles" with wild abandon, because most
computers just sit there wasting clock cycles anyway -- that's
what they have, in magnificent abundance (*way* too much
time on their hands).

Programmers, on the other hand, have busy lives and need to
get on with learning their sums.  List comprehension syntax
is easy to master and any decent Python course gets into it
quickly (within the first hour, during an overview pass?).

And that's the tradeoff in electronics:  pushing the busy work
onto the machines, freeing up our own minds for more interesting
challenges.  But you still need old school type thinkers, for
when memory really does get to be tight (which it still does,
in many knowledge domains, e.g. climatology).

Also you could just go:

>>> def halfoctas(n):
return [sum([x*x for x in range(1, n+1)][0:i]) for i in range(1, n+1)]

>>> halfoctas(10)
[1, 5, 14, 30, 55, 91, 140, 204, 285, 385]
>>> halfoctas(20)
[1, 5, 14, 30, 55, 91, 140, 204, 285, 385, 506, 650, 819, 1015, 1240,
1496, 1785, 2109, 2470, 2870]

but that's a lot less transparent I think.  Or write it as a generator
-- don't have
to specify n in that case (just invoke .next() without limit).

Kirby

=========================

Re: School Boycott

--- In synergeo at yahoogroups.com, "Alan Michelson"
<amichelson2002 at ...> wrote:

> As you can see, there hasn't been as much discussion about the
> half-coupler as there was about the octant (they both have the same
> volume — one-sixth of the cube!)
>

Yeah, you're doing good work. And every school child gets at least
a tactile and/or visual gander at the Egyptian variety, especially
if getting brainwashed with Biblical stories, in which Pharoh is
bound to come in (and go out). So "half octahedron" is no unfamiliar
concept. Nor should be the ball packing corresponding thereto,
beginning with a plane of XY spheres, surmounted by another "down
in the valleys", and another, and so on, tapering right up to a
tippy top apex ball -- maybe it makes more sense to begin from there,
excavating as you grow the base.

We're talking about the sum of consecutive squares of course, and
so in Python:

>>> def layers(n): return n**2

>>> manylayers = [layers(n) for n in range(1, 21)]

>>> halfoctas = [sum(manylayers[0:i]) for i in range(1,21)]

>>> halfoctas
[1, 5, 14, 30, 55, 91, 140, 204, 285, 385, 506, 650, 819, 1015, 1240,
1496, 1785, 2109, 2470, 2870]

Then we cut and paste the first few into the Encyclopedia of
Integer Sequences and voila:

http://www.research.att.com/~njas/sequences/A000330

> > I mean, why aren't we teaching this stuff? There's no coherent
> > opposition, just mindless inertia. A boycott might help us focus.

...

Kirby
```