Skip to content

Commit

Permalink
Creation of generator in Go with Tests WIP #1
Browse files Browse the repository at this point in the history
  • Loading branch information
Richard Peres committed Apr 1, 2022
1 parent 9353faa commit 80a6931
Show file tree
Hide file tree
Showing 9 changed files with 291 additions and 4 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ It will also use modern CI/CD technologies (see the full list [below](#List-of-T
* TBD

# RoadMap
[] Create a simple generator of knapsack problems (list of items + bag size)
[] Create a first simple MVP of a naive solver
[] TBD
- [ ] Create a simple generator of knapsack problems (list of items + bag size)
- [ ] Create a first simple MVP of a naive solver
- [ ] TBD
2 changes: 1 addition & 1 deletion architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
- Identification of 'all' different services and modules involved
## Changed
## Removed
![](architecture-diagrams/v0.1.png)
![](doc/architecture-diagrams/v0.1.png)
File renamed without changes
12 changes: 12 additions & 0 deletions generator/entities/entities.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package entities

type Item struct {
Id int
Size int
Value int
}

type KnapSet struct {
BagSize int
Items []Item
}
62 changes: 62 additions & 0 deletions generator/generator/generator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package generator

import (
. "generator/entities"
"log"
"math/rand"
"sync"
)

const MAX_DEFAULT_SIZE = 100
const MAX_DEFAULT_NB_ITEM = 100
const MAX_ITEM_VALUE = 100

func GenerateNewKnapSet(knapSet KnapSet, nbItem int) KnapSet {
//rand.Seed(time.Now().UnixNano()) TODO

if knapSet.BagSize == 0 {
knapSet.BagSize = rand.Intn(MAX_DEFAULT_SIZE) + 1 // To avoid 0
}

if nbItem == 0 {
nbItem = rand.Intn(MAX_DEFAULT_NB_ITEM) + 1 // To avoid 0
}

knapSet.Items = generateItems(nbItem, knapSet.BagSize)

return knapSet
}

func generateItems(nbItem int, bagSize int) []Item {
if nbItem <= 0 {
log.Fatal("nbItem cannot be <= 0")
}

itemList := make([]Item, nbItem)
var wg sync.WaitGroup

for itemID := 0; itemID < nbItem; itemID++ {
wg.Add(1)

go func(itemID int, bagSize int) {
defer wg.Done()
itemList[itemID] = generateItem(itemID, bagSize)
}(itemID, bagSize)
}

wg.Wait()

return itemList
}

func generateItem(itemID int, maxSize int) Item {
if maxSize <= 0 {
log.Fatal("Max Size cannot be <= 0")
}
//rand.Seed(time.Now().UnixNano()) TODO

value := rand.Intn(MAX_ITEM_VALUE) + 1
size := rand.Intn(maxSize) + 1

return Item{Id: itemID, Value: value, Size: size}
}
138 changes: 138 additions & 0 deletions generator/generator/generator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package generator

import (
. "generator/entities"
"reflect"
"testing"
)

func Test_generateItem(t *testing.T) {
type args struct {
itemID int
maxSize int
}
tests := []struct {
name string
args args
}{
// Item Size 1
{"size = 1", args{0, 1}},

// default Item Size
{"size = MAX_DEFAULT_SIZE", args{1, MAX_DEFAULT_SIZE}},

// TODO error cases ?
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := generateItem(tt.args.itemID, tt.args.maxSize)

isItemCorrect(t, got, tt.args.itemID, tt.args.maxSize)
})
}
}

func isItemCorrect(t *testing.T, item Item, itemID int, maxSize int) {
// Same ID from args
if !reflect.DeepEqual(item.Id, itemID) {
t.Errorf("item ID = %v, expected %v", item, itemID)
}

// Value between 1 and MAX_ITEM_VALUE const
if item.Value <= 0 {
t.Errorf("value is <= 0")
}
if item.Value > MAX_ITEM_VALUE {
t.Errorf("value = %v, should be between 1 and %v", item, MAX_ITEM_VALUE)
}

// Size should be between 1 and either args (or MAX_DEFAULT_SIZE if not defined)
if item.Size > maxSize || item.Size == 0 {
t.Errorf("size = %v, should be between 1 and %v", item, maxSize)
}
}

func Test_generateItems(t *testing.T) {
type args struct {
nbItem int
bagSize int
}
tests := []struct {
name string
args args
}{
// 1 item & 1 bag size
{
name: "1 item & 1 bag size",
args: args{
nbItem: 1,
bagSize: 1,
},
},

// 10 item & 10 bag size
{
name: "10 item & 0 bag size",
args: args{
nbItem: 10,
bagSize: 10,
},
},

// 5 item & 4 bag size
{
name: "5 item & 4 bag size",
args: args{
nbItem: 5,
bagSize: 4,
},
},

// 1 item & 5 bag size
{
name: "1 item & 5 bag size",
args: args{
nbItem: 1,
bagSize: 5,
},
},

// TODO error cases ?
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := generateItems(tt.args.nbItem, tt.args.bagSize)

// Right number of items
if len(got) != tt.args.nbItem {
t.Errorf("generateItems() = %v, expected %v items, got %v", got, tt.args.nbItem, len(got))
}

// Correct items
for id, item := range got {
isItemCorrect(t, item, id, tt.args.bagSize)
}
})
}
}

func TestGenerateNewKnapSet(t *testing.T) {
type args struct {
knapSet KnapSet
nbItem int
}
tests := []struct {
name string
args args
want KnapSet
}{
// TODO: Add test cases. How to use cmd args in tests ?
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := GenerateNewKnapSet(tt.args.knapSet, tt.args.nbItem); !reflect.DeepEqual(got, tt.want) {
t.Errorf("GenerateNewKnapSet() = %v, want %v", got, tt.want)
}
})
}
}
3 changes: 3 additions & 0 deletions generator/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module generator

go 1.15
48 changes: 48 additions & 0 deletions generator/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package main

import (
. "generator/entities"
"generator/generator"
"log"
"os"
"strconv"
)

const BAG_SIZE_ARG = 1
const NB_ITEM_ARG = 2

func main() {
bagSize, nbItem := handleArgs()

newSet := KnapSet{
BagSize: bagSize,
}

newSet = generator.GenerateNewKnapSet(newSet, nbItem)

log.Printf("%+v\n\n", newSet)
}

func handleArgs() (int, int) {
if len(os.Args) == 1 {
return 0, 0
}

bagSize, err := strconv.Atoi(os.Args[BAG_SIZE_ARG])
if err != nil {
log.Fatal("Error while reading Bag Size arg :", err)
}
if bagSize < 0 {
log.Fatal("Bag Size argument cannot be < 0")
}

nbItem, err := strconv.Atoi(os.Args[NB_ITEM_ARG])
if err != nil {
log.Fatal("Error while reading NB item Size arg :", err)
}
if nbItem < 0 {
log.Fatal("Nb item argument cannot be <= 0")
}

return bagSize, nbItem
}
24 changes: 24 additions & 0 deletions generator/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import "testing"

func Test_handleArgs(t *testing.T) {
tests := []struct {
name string
want int
want1 int
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1 := handleArgs()
if got != tt.want {
t.Errorf("handleArgs() got = %v, want %v", got, tt.want)
}
if got1 != tt.want1 {
t.Errorf("handleArgs() got1 = %v, want %v", got1, tt.want1)
}
})
}
}

0 comments on commit 80a6931

Please sign in to comment.