CS 345 Homework 7

Due Monday Mar 6 at 9pm. Upload to Desire 2 Learn dropbox for homework 7.

Recursion (again), Unit Testing, & ArrayStack Solution

Description

You are going download the array_stack_hw7.py source code file. It contains a definition of a stack ADT implemented as an array. This file also contains a set of unit tests that test each method of the ArrayStack class. Your task is the following:

A. Implement the following ArrayStack methods (please note the comments indicating HOW these should be implemented):

  • get_data(self)
  • push_seq(self, seq)
  • as_string(self)

B. Implement all of the test methods in TestLinkedStackMethods:

C. Run your file to run the unit tests. All tests should pass for full credit. Recursion REQUIRED where noted.

Resources

DSAP Chapter 6 & 7

What to Turn In?

Your submission your source code file named according to syllabus.

Solution

# hw 7 solution
import unittest


class EmptyStack(Exception):
    """Custom Exception"""
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

class ArrayStack:
    """LIFO Stack implementation using a Python list as underlying storage."""

    def __init__(self):
        """Create an empty stack."""
        self._data = []                       # nonpublic list instance

    def __len__(self):
        """Return the number of elements in the stack."""
        return len(self._data)

    def is_empty(self):
        """Return True if the stack is empty."""
        return len(self._data) == 0

    def push(self, e):
        """Add element e to the top of the stack."""
        self._data.append(e)                  # new item stored at end of list

    def top(self):
        """Return (but do not remove) the element at the top of the stack.
            
        Raise Empty exception if the stack is empty.
        """
        if self.is_empty():
          raise EmptyStack('Stack is empty')
        return self._data[-1]                 # the last item in the list

    def pop(self):
        """Remove and return the element from the top of the stack (i.e., LIFO).

        Raise Empty exception if the stack is empty.
        """
        if self.is_empty():
          raise EmptyStack('Stack is empty')
        return self._data.pop()               # remove last item from list

    def get_data(self):
        """returns the underlying data structure for the stack."""
        return self._data

    def push_seq(self, seq):
        """Iteratively push each element in seq to stack."""
        for i in seq:
            self.push(i)

    def as_string(self, s):
        """Recursively build a string containing each element of the stack without modifying the stack.

        The final string should contain each element of the stack separated by a space. This time though 
        the BOTTOM of the stack should be first and the TOP of the stack should be last.
        """
        if not s:
            return ''
        return (self.as_string(s[1:]) + ' ' + str(s[0])).strip() # make sure to strip leading and trailing whitespace.


class TestArrayStackMethods(unittest.TestCase):
    """Unit tests for ArrayStack"""

    def test_init(self):
        stack = ArrayStack()
        self.assertEqual(len(stack), 0)

    def test_is_empty(self):
        stack = ArrayStack()
        self.assertEqual(stack.is_empty(), True)
    
    def test_push(self):
        stack = ArrayStack()
        stack.push(5)
        self.assertEqual(stack.top(), 5)

    def test_push_seq(self):
        stack = ArrayStack()
        stack.push(0)
        stack.push_seq([1, 3, 5, 7, 9])
        self.assertEqual(stack.top(), 9)
        self.assertEqual(len(stack), 6)

    def test_top(self):
        stack = ArrayStack()
        stack.push(5)
        self.assertEqual(stack.top(), 5)
    
    def test_top_exception(self):
        """Tests whether top correctly raises EmptyStack exception."""
        stack = ArrayStack()
        with self.assertRaises(EmptyStack):
            stack.top()

    def test_pop(self):
        stack = ArrayStack()
        stack.push(5)
        self.assertEqual(stack.pop(), 5)

    def test_get_data(self):
        stack = ArrayStack()
        stack.push_seq([1, 3, 5, 7, 9])
        self.assertEqual(stack.get_data(), [1, 3, 5, 7, 9])

    def test_pop_exception(self):
        """Tests whether pop correctly raises EmptyStack exception."""
        stack = ArrayStack()
        with self.assertRaises(EmptyStack):
            stack.pop()

    def test_as_string(self):
        """Tests that as_string correctly lists the contents of the stack in indicated order (bottom -> top)."""
        stack = ArrayStack()
        stack.push_seq([1, 3, 5, 7, 9])
        self.assertEqual(stack.as_string(stack.get_data()), '9 7 5 3 1')



"""Run the unit tests on invocation of this file with python interpreter.

> python <name of this file>.py
"""
if __name__ == '__main__':
    unittest.main()

© 2017 - . All rights reserved
Built using Jekyll