Initial upload

This commit is contained in:
2022-08-24 14:28:45 +02:00
parent c67653ddee
commit 57bc7b0289
370 changed files with 18479 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
{
"blurb": "Learn about maps by selling items by the dozen at the Gross Store.",
"authors": [
"chocopowwwa"
],
"contributors": [
"MiroslavGatsanoga"
],
"files": {
"solution": [
"gross_store.go"
],
"test": [
"gross_store_test.go"
],
"exemplar": [
".meta/exemplar.go"
]
}
}

View File

@@ -0,0 +1 @@
{"track":"go","exercise":"gross-store","id":"7bfbc74502004cb3867b5bf345b7b1b0","url":"https://exercism.org/tracks/go/exercises/gross-store","handle":"halfdan","is_requester":true,"auto_approve":false}

40
go/gross-store/HELP.md Normal file
View File

@@ -0,0 +1,40 @@
# Help
## Running the tests
To run the tests run the command `go test` from within the exercise directory.
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:
go test -v --bench . --benchmem
Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.
## Submitting your solution
You can submit your solution using the `exercism submit gross_store.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

31
go/gross-store/HINTS.md Normal file
View File

@@ -0,0 +1,31 @@
# Hints
## General
- [Go by example map][gobyexample-map]
- [Go maps in action][goblog-map]
## 1. Store the unit of measurement in your program
- To store the measurement in your program, you can use map literal, see [go blog about map][goblog-map]
## 2. Create a new bill
- To create a new bill, you all you need to do is reinitialize the customer, see [go blog about map][goblog-map]
## 3. Add item to the customer bill
- To check whether the given unit of measurement is correct, you can test your measurement map for a key without retrieving a value, see [go blog about map][goblog-map]
## 4. Remove item from the customer bill
- To check whether the given item is in customer bill, you can test your measurement map for a key without retrieving a value, see [go blog about map][goblog-map]
- To check whether the given unit of measurement is correct, you can test your measurement map for a key without retrieving a value, see [go blog about map][goblog-map]
## 5. Return the number of specific item that is in the customer bill
- To check whether the given item is in customer bill, you can test your measurement map for a key without retrieving a value, see [go blog about map][goblog-map]
[gobyexample-map]: https://gobyexample.com/maps
[goblog-map]: https://blog.golang.org/maps

159
go/gross-store/README.md Normal file
View File

@@ -0,0 +1,159 @@
# Gross Store
Welcome to Gross Store on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
## Introduction
In go, `map` is a built-in data type that maps keys to values. In other programming language, you might be familiar with the concept of `map` as a dictionary, hash table, key/value store or an associative array.
Syntactically, `map` looks like this:
```go
map[KeyType]ElementType
```
It is also important to know that each key is unique, meaning that assigning the same key twice will overwrite the value of the corresponding key.
To create a map, you can do:
```go
// With map literal
foo := map[string]int{}
```
or
```go
// or with make function
foo := make(map[string]int)
```
Here are some operations that you can do with a map
```go
// Add a value in a map with the `=` operator:
foo["bar"] = 42
// Here we update the element of `bar`
foo["bar"] = 73
// To retrieve a map value, you can use
baz := foo["bar"]
// To delete an item from a map, you can use
delete(foo, "bar")
```
If you try to retrieve the value for a key which does not exist in the map, it will return the zero value of the value type.
This can confuse you, especially if the default value of your `ElementType` (for example, 0 for an int), is a valid value.
To check whether a key exists in your map, you can use
```go
value, exists := foo["baz"]
// If the key "baz" does not exist,
// value: 0; exists: false
```
## Instructions
A friend of yours has an old wholesale store called **Gross Store**.
The name comes from the quantity of the item that the store sell: it's all in [gross unit][gross-unit].
Your friend asked you to implement a point of sale (POS) system for his store.
**First, you want to build a prototype for it.**
**In your prototype, your system will only record the quantity.**
Your friend gave you a list of measurements to help you:
| Unit | Score |
| ------------------ | ----- |
| quarter_of_a_dozen | 3 |
| half_of_a_dozen | 6 |
| dozen | 12 |
| small_gross | 120 |
| gross | 144 |
| great_gross | 1728 |
## 1. Store the unit of measurement in your program
In order to use the measurement, you need to store the measurement in your program.
```go
units := Units()
fmt.Println(units)
// Output: map[...] with entries like ("dozen": 12)
```
## 2. Create a new customer bill
You need to implement a function that create a new (empty) bill for the customer.
```go
bill := NewBill()
fmt.Println(bill)
// Output: map[]
```
## 3. Add an item to the customer bill
To implement this, you'll need to:
- Return `false` if the given `unit` is not in the `units` map.
- Otherwise add the item to the customer `bill`, indexed by the item name, then return `true`.
```go
bill := NewBill()
units := Units()
ok := AddItem(bill, units, "carrot", "dozen")
fmt.Println(ok)
// Output: true (since dozen is a valid unit)
```
> Note that the returned value is type `bool`.
## 4. Remove an item from the customer bill
To implement this, you'll need to:
- Return `false` if the given item is **not** in the bill
- Return `false` if the given `unit` is not in the `units` map.
- Return `false` if the new quantity would be less than 0.
- If the new quantity is 0, completely remove the item from the `bill` then return `true`.
- Otherwise, reduce the quantity of the item and return `true`.
```go
bill := NewBill()
units := Units()
ok := RemoveItem(bill, units, "carrot", "dozen")
fmt.Println(ok)
// Output: false (because there are no carrots in the bill)
```
> Note that the returned value is type `bool`.
## 5. Return the quantity of a specific item that is in the customer bill
To implement this, you'll need to:
- Return `0` and `false` if the `item` is not in the bill.
- Otherwise, return the quantity of the item in the `bill` and `true`.
```go
bill := map[string]int{"carrot", 12, "grapes", 3}
qty, ok := GetItem(bill, "carrot")
fmt.Println(qty)
// Output: 12
fmt.Println(ok)
// Output: true
```
> Note that the returned value are types `int` and `bool`.
[gross-unit]: https://en.wikipedia.org/wiki/Gross_(unit)
## Source
### Created by
- @chocopowwwa
### Contributed to by
- @MiroslavGatsanoga

3
go/gross-store/go.mod Normal file
View File

@@ -0,0 +1,3 @@
module gross
go 1.16

View File

@@ -0,0 +1,59 @@
package gross
// Units stores the Gross Store unit measurements.
func Units() map[string]int {
return map[string]int{
"quarter_of_a_dozen": 3,
"half_of_a_dozen": 6,
"dozen": 12,
"small_gross": 120,
"gross": 144,
"great_gross": 1728,
}
}
// NewBill creates a new bill.
func NewBill() map[string]int {
return map[string]int{}
}
// AddItem adds an item to customer bill.
func AddItem(bill, units map[string]int, item, unit string) bool {
val, exists := units[unit]
if !exists {
return false
}
bill[item] += val
return true
}
// RemoveItem removes an item from customer bill.
func RemoveItem(bill, units map[string]int, item, unit string) bool {
qty, exists := bill[item]
if !exists {
return false
}
val, exists := units[unit]
if !exists {
return false
}
if qty - val < 0 {
return false
}
if qty - val == 0 {
delete(bill, item)
} else {
bill[item] -= val
}
return true
}
// GetItem returns the quantity of an item that the customer has in his/her bill.
func GetItem(bill map[string]int, item string) (int, bool) {
qty, exists := bill[item]
return qty, exists
}

View File

@@ -0,0 +1,255 @@
package gross
import (
"testing"
)
type entry struct {
name string
unit string
qty int
}
func TestUnits(t *testing.T) {
tests := []struct {
name string
qty int
}{
{"quarter_of_a_dozen", 3},
{"half_of_a_dozen", 6},
{"dozen", 12},
{"small_gross", 120},
{"gross", 144},
{"great_gross", 1728},
}
units := Units()
for _, tt := range tests {
qty, ok := units[tt.name]
if !ok {
t.Errorf(`Unit "%s" not found!`, tt.name)
continue
}
if qty != tt.qty {
t.Errorf(`Unit "%s" should have quantity %d, found %d`, tt.name, tt.qty, qty)
}
}
}
func TestAddItem(t *testing.T) {
tests := []struct {
name string
entry []entry
expected bool
}{
{
"Invalid measurement unit",
[]entry{
{"pasta", "", 0},
{"onion", "quarter", 0},
{"pasta", "pound", 0},
},
false,
},
{
"Valid measurement unit",
[]entry{
{"peas", "quarter_of_a_dozen", 3},
{"tomato", "half_of_a_dozen", 6},
{"chili", "dozen", 12},
{"cucumber", "small_gross", 120},
{"potato", "gross", 144},
{"zucchini", "great_gross", 1728},
},
true,
},
{
"check quantity of item added twice",
[]entry{
{"peas", "quarter_of_a_dozen", 3},
{"peas", "quarter_of_a_dozen", 6},
{"tomato", "half_of_a_dozen", 6},
{"tomato", "quarter_of_a_dozen", 9},
},
true,
},
}
units := Units()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
bill := NewBill()
for _, item := range tt.entry {
ok := AddItem(bill, units, item.name, item.unit)
if ok != tt.expected {
t.Errorf("Expected %t from AddItem, found %t at %v", tt.expected, ok, item.name)
}
itemQty, ok := bill[item.name]
if ok != tt.expected {
t.Errorf("Could not find item %s in customer bill", item.name)
}
if itemQty != item.qty {
t.Errorf("Expected %s to have quantity %d in customer bill, found %d", item.name, item.qty, itemQty)
}
}
})
}
}
func TestRemoveItem(t *testing.T) {
type expectedItem struct {
name string
unit string
qty int
exists bool
}
tests := []struct {
name string
remove []expectedItem
expected bool
}{
{"Item Not found in bill",
[]expectedItem{
{"papaya", "gross", 0, false},
},
false,
},
{"Invalid measurement unit",
[]expectedItem{
{"peas", "pound", 3, true},
{"tomato", "kilogram", 6, true},
{"cucumber", "stone", 120, true},
},
false,
},
{"Resulted qty less than 0",
[]expectedItem{
{"peas", "half_of_a_dozen", 3, true},
{"tomato", "dozen", 6, true},
{"chili", "small_gross", 12, true},
{"cucumber", "gross", 120, true},
{"potato", "great_gross", 144, true},
},
false,
},
{"Should delete the item if 0",
[]expectedItem{
{"peas", "quarter_of_a_dozen", 0, false},
{"tomato", "half_of_a_dozen", 0, false},
{"chili", "dozen", 0, false},
{"cucumber", "small_gross", 0, false},
{"potato", "gross", 0, false},
{"zucchini", "great_gross", 0, false},
},
true,
},
{"Should reduce the qty",
[]expectedItem{
{"chili", "half_of_a_dozen", 6, true},
{"cucumber", "dozen", 108, true},
{"zucchini", "gross", 1584, true},
},
true,
},
}
units := Units()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
bill := setupInitialBillData()
for _, item := range tt.remove {
ok := RemoveItem(bill, units, item.name, item.unit)
if ok != tt.expected {
t.Errorf("Expected %t from RemoveItem, found %t at %v", tt.expected, ok, item.name)
}
itemQty, ok := bill[item.name]
if ok != item.exists {
t.Errorf("Could not find item %s in customer bill", item.name)
}
if itemQty != item.qty {
t.Errorf("Expected %s to have quantity %d in customer bill, found %d", item.name, item.qty, itemQty)
}
}
})
}
}
func TestNewBill(t *testing.T) {
// Success, zero out the bill
t.Run("Should reset customerbill", func(t *testing.T) {
bill := NewBill()
if len(bill) != 0 {
t.Error("Customer bill must be empty")
}
})
}
func TestGetItem(t *testing.T) {
type expectedItem struct {
name string
expected bool
qty int
}
test := []struct {
name string
getItem []expectedItem
}{
{
"Item Not found in bill",
[]expectedItem{
{"grape", false, 0},
},
},
{
"Success",
[]expectedItem{
{"peas", true, 3},
{"tomato", true, 6},
{"chili", true, 12},
{"cucumber", true, 120},
{"potato", true, 144},
{"zucchini", true, 1728},
},
},
}
for _, tt := range test {
t.Run(tt.name, func(t *testing.T) {
bill := setupInitialBillData()
for _, item := range tt.getItem {
itemQty, ok := GetItem(bill, item.name)
if ok != item.expected {
msg := "Could not find item %s in customer bill, expected %t"
if item.expected == false {
msg = "Found item %s in customer bill, expected %t"
}
t.Errorf(msg, item.name, item.expected)
}
if itemQty != item.qty {
t.Errorf("Expected %s to have quantity %d in customer bill, found %d", item.name, item.qty, itemQty)
}
}
})
}
}
func setupInitialBillData() map[string]int {
bill := NewBill()
bill["peas"] = 3
bill["tomato"] = 6
bill["chili"] = 12
bill["cucumber"] = 120
bill["potato"] = 144
bill["zucchini"] = 1728
return bill
}