Skip to content

Commit

Permalink
mtgban: Guarantee to keep data arrays sorted
Browse files Browse the repository at this point in the history
  • Loading branch information
kodawah committed Oct 19, 2023
1 parent c383f90 commit 1fcf95d
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 22 deletions.
13 changes: 0 additions & 13 deletions abugames/abugames.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package abugames
import (
"errors"
"net/url"
"sort"
"sync"
"time"

Expand Down Expand Up @@ -238,18 +237,6 @@ func (abu *ABUGames) scrape() error {
}
}

// Sort to keep NM entries first
for cardId := range abu.inventory {
sort.Slice(abu.inventory[cardId], func(i, j int) bool {
return abu.inventory[cardId][i].Price > abu.inventory[cardId][j].Price
})
}
for cardId := range abu.buylist {
sort.Slice(abu.buylist[cardId], func(i, j int) bool {
return abu.buylist[cardId][i].BuyPrice > abu.buylist[cardId][j].BuyPrice
})
}

abu.inventoryDate = time.Now()
abu.buylistDate = time.Now()

Expand Down
9 changes: 0 additions & 9 deletions cardtrader/cardtrader.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"io"
"sort"
"sync"
"time"

Expand Down Expand Up @@ -294,14 +293,6 @@ func (ct *CardtraderMarket) scrape() error {
}
}

// Sort to keep NM-SP-MP-HP-PO order
conds := map[string]int{"NM": 0, "SP": 1, "MP": 2, "HP": 3, "PO": 4}
for cardId := range ct.inventory {
sort.Slice(ct.inventory[cardId], func(i, j int) bool {
return conds[ct.inventory[cardId][i].Conditions] < conds[ct.inventory[cardId][j].Conditions]
})
}

ct.inventoryDate = time.Now()

return nil
Expand Down
36 changes: 36 additions & 0 deletions mtgban/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package mtgban

import (
"fmt"
"sort"

"github.com/google/uuid"
"github.com/mtgban/go-mtgban/mtgmatcher"
"golang.org/x/exp/slices"
)

func computeSKU(cardId, condition string) (string, error) {
Expand Down Expand Up @@ -60,6 +62,24 @@ func (inv InventoryRecord) add(cardId string, entry *InventoryEntry, strict int)
}

inv[cardId] = append(inv[cardId], *entry)

// Keep array sorted
sort.Slice(inv[cardId], func(i, j int) bool {
iIdx := slices.Index(FullGradeTags, inv[cardId][i].Conditions)
jIdx := slices.Index(FullGradeTags, inv[cardId][j].Conditions)

if iIdx == jIdx {
if inv[cardId][i].Price == inv[cardId][j].Price {
// Prioritize higher quantity for same price and same condition
return inv[cardId][i].Quantity > inv[cardId][j].Quantity
}
// Prioritize lower prices first for the same condition
return inv[cardId][i].Price < inv[cardId][j].Price
}

return iIdx < jIdx
})

return nil
}

Expand Down Expand Up @@ -110,6 +130,22 @@ func (bl BuylistRecord) add(cardId string, entry *BuylistEntry, strict bool) err

bl[cardId] = append(bl[cardId], *entry)

sort.Slice(bl[cardId], func(i, j int) bool {
iIdx := slices.Index(FullGradeTags, bl[cardId][i].Conditions)
jIdx := slices.Index(FullGradeTags, bl[cardId][j].Conditions)

if iIdx == jIdx {
if bl[cardId][i].BuyPrice == bl[cardId][j].BuyPrice {
// Prioritize higher quantity for same price and same condition
return bl[cardId][i].Quantity > bl[cardId][j].Quantity
}
// Prioritize higher prices first for the same condition
return bl[cardId][i].BuyPrice > bl[cardId][j].BuyPrice
}

return iIdx < jIdx
})

return nil
}

Expand Down
76 changes: 76 additions & 0 deletions mtgban/base_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mtgban

import (
"math/rand"
"testing"
)

Expand Down Expand Up @@ -237,3 +238,78 @@ func TestAddStrict(t *testing.T) {

t.Log("PASS: AddStrict")
}

func TestSort(t *testing.T) {
testEntries := []InventoryEntry{
{
Quantity: 5,
Conditions: "NM",
Price: 20.0,
URL: "https://mtgban.com",
SellerName: "BANNED",
},
{
Quantity: 4,
Conditions: "SP",
Price: 8.0,
URL: "https://mtgban.com",
SellerName: "BANNED",
},
{
Quantity: 4,
Conditions: "SP",
Price: 10.0,
URL: "https://mtgban.com",
SellerName: "BANNED",
},
{
Quantity: 1,
Conditions: "SP",
Price: 10.0,
URL: "https://mtgban.com",
SellerName: "BANNED_TWO",
},
}

rand.Shuffle(len(testEntries), func(i, j int) {
testEntries[i], testEntries[j] = testEntries[j], testEntries[i]
})

expectedCond := []string{"NM", "SP", "SP", "SP"}
expectedPrice := []float64{20.0, 8.0, 10.0, 10.0}
expectedQty := []int{5, 4, 4, 1}

inventory := InventoryRecord{}

// Add all the entries in wrong order
for _, testEntry := range testEntries {
err := inventory.AddStrict("A", &testEntry)
if err != nil {
t.Errorf("FAIL: Unexpected error: %s", err.Error())
return
}
}
if len(inventory["A"]) != len(testEntries) {
t.Errorf("FAIL: inventory contains a differen number of entries (%d) than expected (%d) for A", len(inventory["A"]), len(testEntries))
return
}

for _, entries := range inventory {
for i := range entries {
if entries[i].Conditions != expectedCond[i] {
t.Errorf("FAIL: array not sorted: condition of %d is not %s (got %s)", i, expectedCond[i], entries[i].Conditions)
return
}
if entries[i].Price != expectedPrice[i] {
t.Errorf("FAIL: array not sorted: price of %d is not %f (got %f)", i, expectedPrice[i], entries[i].Price)
return
}
if entries[i].Quantity != expectedQty[i] {
t.Errorf("FAIL: array not sorted: quantity of %d is not %d (got %d)", i, expectedQty[i], entries[i].Quantity)
return
}
}
}

t.Log("PASS: Sort")
}

0 comments on commit 1fcf95d

Please sign in to comment.