Exercises

Stack as package

  • See the Stack exercise. In this exercise we want to create a separate packagefor that code. Create a proper package for your stack implementation, Push,Pop and the Stack type need to be exported.

  • Write a simple unit test for this package.You should at least test that a Pop works after a Push.

Answer

  • There are a few details that should be changed to make a proper packagefor our stack. First, the exported functions should begin with a capitalletter and so should Stack. The package file is named stack-as-package.goand contains:
  1. package stack
  2. // Stack holds the items.
  3. type Stack struct {
  4. i int
  5. data [10]int
  6. }
  7. // Push pushes an item on the stack.
  8. func (s *Stack) Push(k int) {
  9. s.data[s.i] = k
  10. s.i++
  11. }
  12. // Pop pops an item from the stack.
  13. func (s *Stack) Pop() (ret int) {
  14. s.i--
  15. ret = s.data[s.i]
  16. return
  17. }
  • To make the unit testing work properly you need to do somepreparations. We’ll come to those in a minute. First the actual unit test.Create a file with the name pushpop_test.go, with the following contents:
  1. package stack
  2. import "testing"
  3. func TestPushPop(t *testing.T) {
  4. c := new(Stack)
  5. c.Push(5)
  6. if c.Pop() != 5 {
  7. t.Log("Pop doesn't give 5")
  8. t.Fail()
  9. }
  10. }

For go test to work we need to put our package files in a directoryunder $GOPATH/src:

  1. % mkdir $GOPATH/src/stack
  2. % cp pushpop_test.go $GOPATH/src/stack
  3. % cp stack-as-package.go $GOPATH/src/stack

Yields:

  1. % go test stack
  2. ok stack 0.001s

Calculator

  • Create a reverse polish calculator. Use your stack package.

Answer

  • This is one answer:
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "os"
  6. "strconv"
  7. )
  8. var reader *bufio.Reader = bufio.NewReader(os.Stdin)
  9. var st = new(Stack)
  10. type Stack struct {
  11. i int
  12. data [10]int
  13. }
  14. func (s *Stack) push(k int) {
  15. if s.i+1 > 9 {
  16. return
  17. }
  18. s.data[s.i] = k
  19. s.i++
  20. }
  21. func (s *Stack) pop() (ret int) {
  22. s.i--
  23. if s.i < 0 {
  24. s.i = 0
  25. return
  26. }
  27. ret = s.data[s.i]
  28. return
  29. }
  30. func main() {
  31. for {
  32. s, err := reader.ReadString('\n')
  33. var token string
  34. if err != nil {
  35. return
  36. }
  37. for _, c := range s {
  38. switch {
  39. case c >= '0' && c <= '9':
  40. token = token + string(c)
  41. case c == ' ':
  42. r, _ := strconv.Atoi(token)
  43. st.push(r)
  44. token = ""
  45. case c == '+':
  46. fmt.Printf("%d\n", st.pop()+st.pop())
  47. case c == '*':
  48. fmt.Printf("%d\n", st.pop()*st.pop())
  49. case c == '-':
  50. p := st.pop()
  51. q := st.pop()
  52. fmt.Printf("%d\n", q-p)
  53. case c == 'q':
  54. return
  55. default:
  56. //error
  57. }
  58. }
  59. }
  60. }