Welcome, guest | Sign In | My Account | Store | Cart
"""
rb_stack 1.0:  A (less and less) simple stack class.
Copyright (C) 2000 Gordon Worley.

To contact me, please visit my Web site at <http://www.rbisland.cx/> or e-mail me at <redbird@rbisland.cx>.

History:

1.0 - Added trigonometric functions and inverse.
0.9 - Updated for Python 2.0.  Uses the new self modifying math operators (+=, *=, **=, etc.).
0.8 - Added neg_all() to RPN_Stack.
0.7.9 - Oops, found bug in do all methods.  Called flush() as an attribute rather than as a function.
0.7.8 - Added negation function.
0.7.7 - Added functions to do operations to all registers in stack.
0.7.1 - Removed some error handeling.  Eventually all will be removed to make it easier for implimentations to display errors.
0.7 - Added math to RPN_Stack.  Removed math from rpn.py.
0.6.5 - Added flush to Stack.
0.6.4 - Found and squashed bug in roll up/down functions in Stack.
0.6.3 - Pop now allows multiple pops using extra optional argument.
0.6.2 - Added register roll functions to RPN_Stack.
0.6 - Created RPN_Stack to add RPN specific stack functions.  Moved flip_xy to RPN_Stack.
0.5.3 - Added flip_xy
0.5.2 - Added stack roll functions.
0.5 - Complete rewrite.  Thanks to Programming Python for some sample code in building this stack class.
0.1 - A few bug fixes and added flip_xy.  Initial release.
0.0 - Just a few built-in methods overridden.
"""
import math  #this is just until I can get it to import only in RPN_Stack

class Stack:
       
        def __init__(self, start=[]):
                self.stack = []
                for x in start: self.push(x)
                self.reverse()

        #these first few carry out basic stack functions.  always necessary

        def push(self, item):
                self.stack = [item] + self.stack

        def pop(self, num_of_loops=1):
                x=[]
                curr_loop=0
                while curr_loop < num_of_loops:
                        try:
                                x, self.stack = x + [self.stack[0]], self.stack[1:]
                        except:
                                pass #return "error:  stack underflow"
                        curr_loop += 1
                return tuple(x)

        def empty(self):  #returns true if stack is empty
                return not self.stack
               
        def flush(self):
                self.stack = []
               
        #some extra stack functions that make things nicer
       
        def roll_down(self):
                try:
                        self.stack=self.stack[1:]+[self.stack[0]]
                except:
                        print "error:  stack underflow"

        def roll_up(self):
                try:
                        self.stack=[self.stack[-1]]+self.stack[:-1]
                except:
                        print "error:  stack underflow"
                       
        #okay, enough of that.  now to overload opperators

        def __repr__(self):
                return '%s' % self.stack

        def __cmp__(self, other):
                return cmp(self.stack, other.stack)

        def __len__(self):
                return len(self.stack)

        def __add__(self, other):
                return Stack(self.stack + other.stack)

        def __mul__(self, reps):
                return Stack(self.stack * reps)

        def __getitem__(self, index):
                return self.stack[index]

        def __getslice__(self, low, high):
                return Stack(self.stack[low:high])

        def __getattr__(self, name):
                return getattr(self.stack, name)



class RPN_Stack(Stack):
               
        def getx(self):  #get x register (bottom)
                try:
                        self.stack[0]
                except:
                        return "error:  stack underflow"
                return self.stack[0]
       
        def gety(self):  #get y register
                try:
                        self.stack[1]
                except:
                        return "error:  stack underflow"
                return self.stack[1]

        def getz(self):  #get z register
                try:
                        self.stack[2]
                except:
                        return "error:  stack underflow"
                return self.stack[2]

        def gett(self):  #get t register (top)
                try:
                        self.stack[3]
                except:
                        return "error:  stack underflow"
                return self.stack[3]
               
        #roll the stack around
               
        def roll_regs_down(self):
                try:  #try with all four registers
                        self.stack[0], self.stack[1], self.stack[2], self.stack[3]=self.stack[1], self.stack[2], self.stack[3], self.stack[0]
                except:
                        try:  #well, maybe there are just three
                                self.stack[0], self.stack[1], self.stack[2]=self.stack[1], self.stack[2], self.stack[0]
                        except:  #if there aren't two, the stack is too small
                                self.flip_xy()
       
        def roll_regs_up(self):
                try:  #try with all four registers
                        self.stack[0], self.stack[1], self.stack[2], self.stack[3]=self.stack[3], self.stack[0], self.stack[1], self.stack[2]
                except:
                        try:  #well, maybe there are just three
                                self.stack[0], self.stack[1], self.stack[2]=self.stack[2], self.stack[0], self.stack[1]
                        except:  #if there aren't two, the stack is too small
                                self.flip_xy()
               
        def flip_xy(self):  #flip the x and y registers
                try:
                        self.stack[0], self.stack[1] = self.stack[1], self.stack[0]
                except:
                        print "error:  stack underflow"
                       
        #do some math
       
        def add(self):
                newx = self.gety() + self.getx()
                self.pop(2); self.push(newx)
               
        def sub(self):
                newx = self.gety() - self.getx()
                self.pop(2); self.push(newx)
       
        def mul(self):
                newx = self.gety() * self.getx()
                self.pop(2); self.push(newx)
       
        def div(self):
                newx = self.gety() / self.getx()
                self.pop(2); self.push(newx)
       
        def modulo(self):
                newx = self.gety() % self.getx()
                self.pop(2); self.push(newx)
       
        def pow(self):  #raise y register to the x power
                newx = self.gety()**self.getx()
                self.pop(2); self.push(newx)
               
        def neg(self):  #negate
                newx = -self.getx()
                self.pop(); self.push(newx)
               
        def sin(self):
                newx = math.sin(self.getx())
                self.pop(); self.push(newx)
               
        def cos(self):
                newx = math.cos(self.getx())
                self.pop(); self.push(newx)
       
        def tan(self):
                newx = math.tan(self.getx())
                self.pop(); self.push(newx)
       
        def arcsin(self):
                newx = math.asin(self.getx())
                self.pop(); self.push(newx)
               
        def arccos(self):
                newx = math.acos(self.getx())
                self.pop(); self.push(newx)
       
        def arctan(self):
                newx = math.atan(self.getx())
                self.pop(); self.push(newx)
               
        def inverse(self):
                newx = 1 / self.getx()
                self.pop(); self.push(newx)
       
        #same as above, but acting over whole list
       
        def add_all(self):
                newx=self.getx()
                for x in self.stack[1:]:
                        newx += x
                self.flush(); self.push(newx)
               
        def sub_all(self):
                newx=self.getx()
                for x in self.stack[1:]:
                        newx -= x
                self.flush(); self.push(newx)
       
        def mul_all(self):
                newx=self.getx()
                for x in self.stack[1:]:
                        newx *= x
                self.flush(); self.push(newx)
       
        def div_all(self):
                newx=self.getx()
                for x in self.stack[1:]:
                        newx /= x
                self.flush(); self.push(newx)
       
        def modulo_all(self):
                newx=self.getx()
                for x in self.stack[1:]:
                        newx %= x
                self.flush(); self.push(newx)
               
        def pow_all(self):
                newx=self.getx()
                for x in self.stack[1:]:
                        newx **= x
                self.flush(); self.push(newx)
               
        def neg_all(self):
                index=0
                while index < len(self.stack):
                        self.stack[index] = -self.stack[index]
                        index += 1
       
        def sin_all(self):
                index = 0
                while index < len(self.stack):
                        self.stack[index] = math.sin(self.stack[index])
                        index += 1

        def cos_all(self):
                index = 0
                while index < len(self.stack):
                        self.stack[index] = math.cos(self.stack[index])
                        index += 1
                       
        def tan_all(self):
                index = 0
                while index < len(self.stack):
                        self.stack[index] = math.tan(self.stack[index])
                        index += 1
                       
        def arcsin_all(self):
                index = 0
                while index < len(self.stack):
                        self.stack[index] = math.asin(self.stack[index])
                        index += 1

        def arccos_all(self):
                index = 0
                while index < len(self.stack):
                        self.stack[index] = math.acos(self.stack[index])
                        index += 1
                       
        def arctan_all(self):
                index = 0
                while index < len(self.stack):
                        self.stack[index] = math.atan(self.stack[index])
                        index += 1
                       
        def inverse_all(self):
                index = 0
                while index < len(self.stack):
                        self.stack[index] = 1 / self.stack[index]
                        index += 1

History

  • revision 2 (22 years ago)
  • previous revisions are not available