Go Tutorial Part 2 (Slicing, File Handling I/O, Error Handling, Test Cases)

GO - Part 2

Credit goes to - Master the fundamentals and advanced features of the Go Programming Language (Golang), on Udemy by Stephen Grider.
I have tried some snippets on my own and some are referring to the snippets developed while going through the course.

Code Repo: https://github.com/namitsharma99/goLangTutorials

ioutil - package that supports in-built functions like WriteFile(), this method would require byte slices

Byte Slices - converted string into ascii codes
--------------------------------------------------------
main.go
...
[]byte("Hello World!")
...

o/p-

  temp := "Hello World!"
  fmt.Println(temp)
  fmt.Println([]byte(temp))
  
  Hello World!
[72 101 108 108 111 32 87 111 114 108 100 33]


How to convert a deck (slice of cards) into a string?
-----------------------------------------------------------------
- use type conversion


main.go
...
cards = newDeck()
  fmt.Println(cards.toString())
...

deck.go
...
func (d deck) toString() string{
  // use strings package
  return strings.Join([]string(d),",")
}
...

o/p-

Ace of Spades,Spades of Ace,Spades of Two,Spades of Three,Spades of Four,Spades of Five,Spades of Six,Spades of Seven,Spades of Eight,Spades of Nine,Spades of Ten,Spades of Jack,Spades of Queen,Spades of King,Diamonds of Ace,Diamonds of Two,Diamonds of Three,Diamonds of Four,Diamonds of Five,Diamonds of Six,Diamonds of Seven,Diamonds of Eight,Diamonds of Nine,Diamonds of Ten,Diamonds of Jack,Diamonds of Queen,Diamonds of King,Hearts of Ace,Hearts of Two,Hearts of Three,Hearts of Four,Hearts of Five,Hearts of Six,Hearts of Seven,Hearts of Eight,Hearts of Nine,Hearts of Ten,Hearts of Jack,Hearts of Queen,Hearts of King,Club of Ace,Club of Two,Club of Three,Club of Four,Club of Five,Club of Six,Club of Seven,Club of Eight,Club of Nine,Club of Ten,Club of Jack,Club of Queen,Club of King
How to Save the data in a file?
--------------------------------------

main.go
...
cards = newDeck()
  cards.saveToFile("helloCards")
...

deck.go
...
func (d deck) saveToFile(fileName string) error {
  return ioutil.WriteFile(fileName, []byte(d.toString()), 0777) // provide permissions
}
...

o/p-
helloCards file is created
Reading a saved file and converting to a deck
-----------------------------------------------------------

using ReadFile() method


main.go
...
cards = newDeckFromFile("helloCards")
  cards.print()
...

deck.go
...
func newDeckFromFile(fileName string) deck {
  bytslc, err := ioutil.ReadFile(fileName) // default error handling
  if err != nil {
    // Option 1 - log error and return a new decks
    // Option 2 - log error and quit
    fmt.Println("Error: ", err)
    os.Exit(1) // imported package os
  }
  s := strings.Split(string(bytslc), ",") // typecasting of byte slice to string, then using split to chunk on the basis of comma
  return deck(s) // using slice of strings to create a deck
}
...

o/p-
0 Ace of Spades
1 Spades of Ace
2 Spades of Two
3 Spades of Three
4 Spades of Four
5 Spades of Five
6 Spades of Six
7 Spades of Seven
8 Spades of Eight
9 Spades of Nine
10 Spades of Ten
11 Spades of Jack
12 Spades of Queen
13 Spades of King
14 Diamonds of Ace
15 Diamonds of Two
16 Diamonds of Three
17 Diamonds of Four
18 Diamonds of Five
19 Diamonds of Six
20 Diamonds of Seven
21 Diamonds of Eight
22 Diamonds of Nine
23 Diamonds of Ten
24 Diamonds of Jack
25 Diamonds of Queen
26 Diamonds of King
27 Hearts of Ace
28 Hearts of Two
29 Hearts of Three
30 Hearts of Four
31 Hearts of Five
32 Hearts of Six
33 Hearts of Seven
34 Hearts of Eight
35 Hearts of Nine
36 Hearts of Ten
37 Hearts of Jack
38 Hearts of Queen
39 Hearts of King
40 Club of Ace
41 Club of Two
42 Club of Three
43 Club of Four
44 Club of Five
45 Club of Six
46 Club of Seven
47 Club of Eight
48 Club of Nine
49 Club of Ten
50 Club of Jack
51 Club of Queen
52 Club of King



How to Shuffle
-------------------

use random numbers, using math package

Fixed routine

main.go
...
  cards = newDeck()
  cards.shuffle()
  cards.print()
...

deck.go
...
func (d deck) shuffle() {
  for i := range d {
    newPosition := rand.Intn(len(d)-1)
    d[i], d[newPosition] = d[newPosition], d[i]
  }
}
...

o/p-

0 Hearts of Three
1 Spades of Ten
2 Hearts of King
3 Hearts of Ace
4 Diamonds of Queen
5 Hearts of Nine
6 Club of Eight
7 Spades of Four
8 Spades of Eight
9 Spades of Three
10 Hearts of Queen
11 Club of Four
12 Diamonds of King
13 Club of King
14 Club of Two
15 Diamonds of Five
16 Club of Ten
17 Club of Six
18 Club of Seven
19 Diamonds of Seven
20 Diamonds of Two
21 Diamonds of Six
22 Spades of Jack
23 Spades of Ace
24 Spades of Queen
25 Diamonds of Three
26 Diamonds of Jack
27 Hearts of Ten
28 Club of Three
29 Club of Queen
30 Spades of Nine
31 Spades of Two
32 Spades of Seven
33 Diamonds of Nine
34 Hearts of Jack
35 Club of Five
36 Spades of King
37 Club of Jack
38 Spades of Five
39 Diamonds of Eight
40 Ace of Spades
41 Club of Ace
42 Hearts of Five
43 Diamonds of Four
44 Spades of Six
45 Hearts of Eight
46 Hearts of Seven
47 Diamonds of Ace
48 Diamonds of Ten
49 Club of Nine
50 Hearts of Six
51 Hearts of Four
52 Hearts of Two


Dynamic routine
- using dynamic seed in the generator

main.go
...
  cards = newDeck()
  cards.shuffle2()
  cards.print()
...

deck.go
...
func (d deck) shuffle2() {
  source := rand.NewSource(time.Now().UnixNano()) // seed
  r := rand.New(source) // generator

  for i := range d {
    newPosition := r.Intn(len(d)-1)
    d[i], d[newPosition] = d[newPosition], d[i]
  }
}
...

o/p-
0 Spades of Five
1 Diamonds of Ten
2 Diamonds of Jack
3 Hearts of Jack
4 Club of Ten
5 Diamonds of Ace
6 Club of Five
7 Spades of King
8 Diamonds of Four
9 Hearts of Seven
10 Spades of Seven
11 Hearts of Eight
12 Spades of Queen
13 Club of Three
14 Club of Two
15 Diamonds of Three
16 Hearts of King
17 Hearts of Four
18 Diamonds of King
19 Hearts of Three
20 Diamonds of Nine
21 Spades of Four
22 Club of Four
23 Hearts of Six
24 Diamonds of Five
25 Spades of Three
26 Club of Seven
27 Ace of Spades
28 Hearts of Two
29 Club of Six
30 Club of Ace
31 Club of Nine
32 Spades of Ten
33 Spades of Nine
34 Spades of Six
35 Diamonds of Queen
36 Spades of Eight
37 Diamonds of Two
38 Diamonds of Seven
39 Diamonds of Eight
40 Spades of Two
41 Spades of Jack
42 Club of King
43 Hearts of Queen
44 Club of Jack
45 Diamonds of Six
46 Spades of Ace
47 Hearts of Ten
48 Hearts of Ace
49 Hearts of Five
50 Hearts of Nine
51 Club of Queen
52 Club of Eight





Testing
---------

Not like other languages, a very small framework is there
<filename>_test.go

$ go test
?    _/Users/namitsha/goProjects/cards [no test files]

func TestNewDeck(t *testing.T) {
t is the testing helper object
*testing.T -- specifies the type of value being passed in the function


deck_test.go
----------------
package main

import "testing"

func TestNewDeck(t *testing.T) {
  d := newDeck()

  if len(d) != 52 {
    t.Errorf("Expected total 52 but got %v", len(d))
  }
}

$ go test
PASS
ok  _/Users/namitsha/goProjects/cards 0.015s



More tests --

deck.go
-------
....
func newDeck() deck {
  cards := deck{} // how to cover all combo
  cardSuits := []string {"Spades", "Diamonds", "Hearts", "Clubs"}
  cardValues := []string {"Ace", "Two", "Three", "Four", "Five" , "Six", "Seven", "Eight", "Nine" , "Ten", "Jack", "Queen", "King" }

  for _, suit := range cardSuits { // instead of i, j use _ so that no compulsion to use
    for _, value := range cardValues {
      cards = append(cards, value + " of " + suit)
    }
  }

  return cards
}
....


deck_test.go
------------

package main

import "testing"

func TestNewDeck(t *testing.T) {
  d := newDeck()

  if len(d) != 52 {
    t.Errorf("Expected total 52, but got %v", len(d))
  }

  if (d[0] != "Ace of Spades") {
    t.Errorf("Expected 1st card as Ace of Spades, but got %v", d[0])
  }

  if d[len(d) - 1] != "King of Clubs" {
    t.Errorf("Expected last card as King of Clubs, but got %v", d[51])
  }

}

func TestSaveToDeckAndNewDeckFromFile (t *testing.T) {
  os.Remove("helloCards")

  deck := newDeck()
  deck.saveToFile("helloCards")

  loadedDeck := newDeckFromFile("helloCards")

  if len(loadedDeck) != 52 {
    t.Errorf("Expected total 52, but got %v", len(loadedDeck))
  }

  os.Remove("helloCards")
}

$ go test
PASS
ok  _/Users/namitsha/goProjects/cards 0.015s



Note: In test cases, if for example we create a test file, we need to take care of the clean up activities as well, other wise it impacts the other test cases!!
Can use Remove() and RemoveAll() functions for the same.

No comments:

Post a Comment

Featured post

Oracle SQL Scheduled Jobs - An Interesting Approach

  Oracle SQL Scheduled Jobs A DB Scheduler is the best way to automate any backend database job. For instance, if you want to process the p...