summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Abbott <george@gabbott.dev>2023-11-03 19:39:48 +0000
committerGeorge Abbott <george@gabbott.dev>2023-11-03 19:39:48 +0000
commitf64b83de5e28a038d47d11c325ebd292adc70ceb (patch)
tree5b19a4553ae963b5f3f290dac87acac5e174f75f
Commit allHEADmaster
-rw-r--r--go.mod27
-rw-r--r--go.sum63
-rw-r--r--main.go188
3 files changed, 278 insertions, 0 deletions
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..d6fa99d
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,27 @@
+module bt-eqpct
+
+go 1.19
+
+require (
+ anyxcelize v0.0.0-00010101000000-000000000000
+ badtudexo v0.0.0-00010101000000-000000000000
+ saggytrousers v0.0.0-00010101000000-000000000000
+)
+
+require (
+ git.gabbott.dev/george/excelize/v2 v2.99.1 // indirect
+ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
+ github.com/richardlehane/mscfb v1.0.4 // indirect
+ github.com/richardlehane/msoleps v1.0.3 // indirect
+ github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect
+ github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect
+ golang.org/x/crypto v0.5.0 // indirect
+ golang.org/x/net v0.5.0 // indirect
+ golang.org/x/text v0.6.0 // indirect
+)
+
+replace saggytrousers => ../saggytrousers
+
+replace anyxcelize => ../../anyxcelize
+
+replace badtudexo => ../badtudexo
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..22585c7
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,63 @@
+git.gabbott.dev/george/excelize/v2 v2.99.1 h1:pencpuy3D+7TgEV+BraIj5SUSkcErop3Pes05CDp71M=
+git.gabbott.dev/george/excelize/v2 v2.99.1/go.mod h1:JqW30EL316o52Ya+R3++QL7oW13PBwAqYVbSprqTVz4=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
+github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
+github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
+github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
+github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
+github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 h1:6932x8ltq1w4utjmfMPVj09jdMlkY0aiA6+Skbtl3/c=
+github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
+github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M=
+github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
+golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
+golang.org/x/image v0.0.0-20220902085622-e7cb96979f69 h1:Lj6HJGCSn5AjxRAH2+r35Mir4icalbqku+CLUtjnvXY=
+golang.org/x/image v0.0.0-20220902085622-e7cb96979f69/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
+golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
+golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
+golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..41dab39
--- /dev/null
+++ b/main.go
@@ -0,0 +1,188 @@
+package main
+
+import (
+ "fmt"
+ "strconv"
+ "os"
+ "time"
+ // "path/filepath"
+ xl "anyxcelize"
+ // "git.gabbott.dev/george/excelize/v2"
+ st "saggytrousers"
+ bt "badtudexo"
+)
+
+func usage() {
+ fmt.Println(`bt-eqpct: check fields calculated from percentages
+Usage:
+ bt-eqpct FILE -b BASE -p PERCENT -r RESULT -t TOLERANCE
+ -s SHEET -o OUTPUT
+As an example, -b can be a price, -p can be discount %, and -r discount value.
+Then it is calculated: BASE * (PERCENT ± TOLERANCE), and checked if RESULT is
+in this range. This checks the discount amount is always within the tolerance
+of what the percentage should be; if out, either the percentage or the value
+(either -p or -r) are probably wrong and need correcting in the data.
+
+The fields -b, -p and -r are required. If they are not passed, they will be
+prompted for. The function Locate() is used to find these and is passed the
+strings you passed in as params.
+`)
+ os.Exit(0)
+}
+
+func parseArgs(args []string) {
+ if len(args) < 2 {
+ usage()
+ }
+
+ for i := 0; i < len(args); i++ {
+ arg := args[i]
+ switch arg {
+ case "--help", "-h", "help", "helpme":
+ usage()
+
+ case "-b", "--base":
+ i++
+ base = args[i]
+ case "-p", "--pct", "--percent", "--percentage":
+ i++
+ percent = args[i]
+ case "-r", "--result":
+ i++
+ result = args[i]
+ case "-t", "--tol", "--tolerance":
+ i++
+ t, err := strconv.ParseFloat(args[i], 64)
+ if err != nil {
+ fmt.Printf("Tolerance passed with -t could not be parsed into a float64\n")
+ os.Exit(-1)
+ }
+ tol = t
+
+ case "-s", "--sheet":
+ i++
+ sheet = args[i]
+
+ case "--time", "--timings":
+ timeme = true
+ case "-o", "--out", "--output":
+ i++
+ out = args[i]
+ case "-v", "--verbose":
+ verbose = true
+
+ default:
+ filename = arg
+ }
+ }
+}
+
+// Constants
+const ToleranceNotSetValue float64 = 420.69
+
+// Globals
+var base string
+var percent string
+var result string
+var tol float64 = ToleranceNotSetValue
+var timeme bool = false
+var verbose bool = false
+var out string
+var sheet string
+var filename string
+
+
+func main() {
+ args := os.Args
+ parseArgs(args)
+
+ file, err := xl.OpenFile(filename)
+ if err != nil {
+ fmt.Printf("Cannot open file [%s], err [%v].\n", filename, err)
+ return
+ }
+
+ /* Ask user to select the sheet */
+ sheet = st.SelectSheet(file, sheet)
+
+ /* Try find base, percent, result rows, else prompt for them */
+ header := st.GetHeader(file, sheet)
+ baseIdx := bt.LocateOrAsk(header, base, "Please choose the base: ")
+ percentIdx := bt.LocateOrAsk(header, percent, "Please choose the percent: ")
+ resultIdx := bt.LocateOrAsk(header, result, "Please choose the resultant value: ")
+ if tol == ToleranceNotSetValue {
+ tol = st.GetFloat64("Please set the tolerance: ")
+ }
+
+ if verbose {
+ fmt.Printf("base index: %v\n", baseIdx)
+ fmt.Printf("percent index: %v\n", percentIdx)
+ fmt.Printf("result index: %v\n", resultIdx)
+ }
+
+ /* Now load all rows in. */
+ st.Log(verbose, "Loading rows...")
+ loadStart := time.Now()
+ rows := st.GetRows(file, sheet) // panics if fails, which is ok
+ loadTime := time.Since(loadStart)
+ st.Log(verbose, " done!\n")
+
+ /* Get columns from rows as []float64 for call to EqPct. */
+ var wasError bool = false
+ start := time.Now()
+ db, err := st.DowncastF64(st.TransmogrifyRows(rows, baseIdx))
+ if err != nil {
+ wasError = true
+ fmt.Printf("%v\n", err)
+ }
+ dp, err := st.DowncastF64(st.TransmogrifyRows(rows, percentIdx))
+ if err != nil {
+ wasError = true
+ fmt.Printf("%v\n", err)
+ }
+ dr, err := st.DowncastF64(st.TransmogrifyRows(rows, resultIdx))
+ if err != nil {
+ wasError = true
+ fmt.Printf("%v\n", err)
+ }
+ st.Log(verbose, "About to call bt.EqPct.\n")
+
+ if len(db) != len(dp) || len(dp) != len(dr) {
+ st.ErrLog(verbose,
+ fmt.Sprintf("Length mismatch: db = %v, dp = %v, dr = %v",
+ len(db), len(dp), len(dr)))
+ } else {
+ st.Log(verbose, fmt.Sprintf("Lengths are %v\n", len(db)))
+ }
+
+ indexes, err := bt.EqPct(db, dp, dr, tol)
+ if err != nil {
+ wasError = true
+ fmt.Printf("There was an error [%v]\n", err)
+ os.Exit(-1)
+ }
+ st.Log(verbose, "bt.EqPct completed successfully.\n")
+ end := time.Since(start)
+ // lenMax := len(string(len(db)))
+ for _, v := range indexes {
+ st.Log(true, fmt.Sprintf("%7v: %v * %v pct should be %v but found %v.\n",
+ v,
+ db[v],
+ dp[v],
+ (db[v] * dp[v])/100.00,
+ dr[v]))
+ }
+ if verbose {
+ fmt.Printf("base index: %v\n", baseIdx)
+ fmt.Printf("percent index: %v\n", percentIdx)
+ fmt.Printf("result index: %v\n", resultIdx)
+ }
+
+ if timeme {
+ fmt.Printf("Time to load: %v\n", loadTime)
+ fmt.Printf("Time to process: %v\n", end)
+ }
+ if verbose {
+ fmt.Printf("Was error: %v\n", wasError)
+ }
+}