Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

RPN calculator kata

By: a guest on Jun 12th, 2011  |  syntax: Python  |  size: 2.30 KB  |  views: 360  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. import unittest
  2.  
  3. '''
  4. I want to develop a simple RPN-calculator (RPN = Reverse polish notation).
  5. It shouldn't be interactive or anything, it should just take a string as
  6. input and compute it.
  7.  
  8. For example>
  9.  
  10. 1 2 +
  11.  
  12. .. should compute to 3.
  13.  
  14. It should only work with integers and basic arithmetics: +, -, * and /.
  15. '''
  16.  
  17. def is_number(str):
  18.     try: int(str)
  19.     except: return False
  20.     return True
  21.  
  22. def rpn(expr):
  23.     parts = expr.split()
  24.     stack = []
  25.     def plus(l, r): return l + r
  26.     def minus(l, r): return l - r
  27.     def times(l, r): return l * r
  28.     def through(l, r): return l / r
  29.     words = {"+":plus, "-":minus, "*":times, "/":through}
  30.     for part in parts:
  31.         if is_number(part):
  32.             stack.append(int(part))
  33.         else:
  34.             right_number = stack.pop()
  35.             left_number = stack.pop()
  36.             op = words[part]
  37.             stack.append(op(left_number, right_number))
  38.            
  39.     if len(stack)<>1:
  40.         raise Exception()
  41.     return stack[0]
  42.  
  43. class TestCase(unittest.TestCase):
  44.     def test_no_op_returns_number(self):
  45.         self.assertEqual(1, rpn("1"))
  46.        
  47.     def test_no_op_returns_number2(self):
  48.         self.assertEqual(2, rpn("2"))
  49.        
  50.     def test_putting_up_two_numbers_is_an_error(self):
  51.         self.assertRaises(Exception, rpn, "2 3")
  52.        
  53.     def test_plus(self):
  54.         self.assertEqual(5, rpn("2 3 +"))
  55.        
  56.     def test_plus2(self):
  57.         self.assertEqual(6, rpn("2 4 +"))
  58.        
  59.     def test_two_pluses(self):
  60.         self.assertEqual(9, rpn("2 4 + 3 +"))
  61.        
  62.     def test_minus(self):
  63.         self.assertEqual(-2, rpn("2 4 -"))
  64.        
  65.     def test_minus2(self):
  66.         self.assertEqual(0, rpn("2 2 -"))
  67.  
  68.     def test_plus_minus(self):
  69.         self.assertEqual(3, rpn("2 2 + 1 -"))
  70.  
  71.     def test_tab_accepted(self):
  72.         self.assertEqual(3, rpn("2\t2 + 1 -"))
  73.  
  74.     def test_double_space_accepted(self):
  75.         self.assertEqual(3, rpn("2    2 + 1 -"))
  76.  
  77.     def test_times(self):
  78.         self.assertEqual(10, rpn("2 5 *"))
  79.  
  80.     def test_through(self):
  81.         self.assertEqual(6, rpn("12 2 /"))
  82.  
  83.     def test_through_rounds_down(self):
  84.         self.assertEqual(6, rpn("13 2 /"))
  85.  
  86.     def test_through_rounds_down2(self):
  87.         self.assertEqual(-7, rpn("-13 2 /"))