Here's the stack module for py4th.
nick
---------------<cut here>----------------
#!/usr/Util/bin/python
#
# @(#)stack.py 1.1
#
# stack.py
# generic stack class.
class Stack:
def __init__(self):
self.__heap = []
def push (self, word):
self.__heap.append (word)
def pop (self):
if len(self.__heap) == 0:
raise InnerInterpreterError, "stack underflow"
result = self.__heap[-1]
del self.__heap[-1]
return result
def __repr__(self):
return `self.__heap`
def __str__(self):
return `self.__heap`
def flush (self):
self.__heap = []
> class Stack:
> def __init__(self):
> self.__heap = []
A "heap" has a technical meaning in programming. To describe the
internals of a stack as "heap" will be disconcerting and confusing to
anyone who knows about stacks and heaps.
> def push (self, word):
> self.__heap.append (word)
> def pop (self):
> if len(self.__heap) == 0:
> raise InnerInterpreterError, "stack underflow"
"InnerInterpreterError" is the most inappropriate exception name I've
ever seen. It has nothing to do with the interpreter, it's a stack error.
> result = self.__heap[-1]
> del self.__heap[-1]
That is better written as result = self.__heap.pop().
--
Steven
def pop (self):
if len(self.__heap) == 0:
raise InnerInterpreterError, "stack underflow"
return self.__heap.pop(1)
P.S. - I'm puzzled why the OP even put this message here. There's no
question posted with it.
DaveA
> or even better, without the extra local var:
>
> def pop (self):
> if len(self.__heap) == 0:
> raise InnerInterpreterError, "stack underflow"
> return self.__heap.pop(1)
pop(1)?
Anyway if would be simpler and almost certainly faster to not bother
checking before the pop:
def pop(self):
try:
return self.__heap.pop()
except IndexError:
raise InnerInterpreterError, "stack underflow"
and if performance mattered the OP might even consider pre-binding the pop
method in __init__:
self.__pop = self.__heap.pop
but that's probably premature optimisation.
> P.S. - I'm puzzled why the OP even put this message here. There's no
> question posted with it.
Me too. It's a repost of something from 2004. Bizarre.
>> "InnerInterpreterError" is the most inappropriate exception name I've
>> ever seen. It has nothing to do with the interpreter, it's a stack
>> error.
>>
>>
> It has everything to do with the (Forth) interpreter. Exceptions can
> readily be named according to their application -- it's not always about
> Python. Anyway, Forth has an inner-interpreter and an
> outer-interpreter, and the name will make sense to a Forth programmer.
Pardon me, but I *am* a Forth programmer. Or was, it's been many years,
and I'm rusty. I guess this is a difference of terminology: what you're
calling an inner interpreter and an outer interpreter I know of as the
Forth engine and the (text) interpreter. Gforth refers to them as such,
so did Leo Brodie's Forth books, and the (ancient) Macintosh Forth
compiler "Mach 2".
But in any case... a stack is an general-purpose data structure, and the
error message shouldn't be coupled so tightly to one use. That would be
like this (made-up) example:
>>> 1/0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
GraphicsApplicationError: too few pixels to calculate average
Ridiculous, yes?
Yes, Forth uses a stack (technically two, a parameter stack and a return
stack, and some implementations include a third, floating point, stack).
Virtually all languages use stacks in their implementation, and Python
byte-code is also stack-based.
>>> result = self.__heap[-1]
>>> del self.__heap[-1]
>>>
>>>
>> That is better written as result = self.__heap.pop().
>>
>>
>>
> or even better, without the extra local var:
>
> def pop (self):
> if len(self.__heap) == 0:
> raise InnerInterpreterError, "stack underflow"
> return self.__heap.pop(1)
pop(1)? I don't think so.
>>> L = list('abcdef')
>>> L.pop(1)
'b'
>>> L
['a', 'c', 'd', 'e', 'f']
You probably meant pop(-1), but that's unnecessary because pop defaults
to popping from the end of the list.
> P.S. - I'm puzzled why the OP even put this message here. There's no
> question posted with it.
Me too.
--
Steven
Since self.__heap is a list, the canonical Python for the above test
would, of course, be the much simpler
if not self.__heap
regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
PyCon is coming! Atlanta, Feb 2010 http://us.pycon.org/
Holden Web LLC http://www.holdenweb.com/
UPCOMING EVENTS: http://holdenweb.eventbrite.com/
> <snip>
>
>> or even better, without the extra local var:
>>
>> def pop (self):
>> if len(self.__heap) == 0:
>> raise InnerInterpreterError, "stack underflow"
>> return self.__heap.pop(1)
>>
>
> pop(1)? I don't think so.
>
>
>
That was a typo; I meant pop(). And of course others have improved on
my remarks anyway.
DaveA