From 59aa481703273d4ebfb75ba981075538228bc1ee Mon Sep 17 00:00:00 2001 From: Adam Hayes Date: Sat, 27 Nov 2021 22:40:45 -0500 Subject: [PATCH 1/2] First pass at changing the way we map for filtering in filter.go Doing the right type conversion. Works, but not debugged. --- filter.go | 76 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 21 deletions(-) diff --git a/filter.go b/filter.go index f79decc..9e16911 100644 --- a/filter.go +++ b/filter.go @@ -4,7 +4,11 @@ package mop -import "strings" +import ( + "strings" + "log" + "strconv" +) // Filter gets called to sort stock quotes by one of the columns. The // setup is rather lengthy; there should probably be more concise way @@ -26,30 +30,60 @@ func (filter *Filter) Apply(stocks []Stock) []Stock { var filteredStocks []Stock for _, stock := range stocks { - var values = map[string]interface{}{ - "ticker": strings.TrimSpace(stock.Ticker), - "last": m(stock.LastTrade), - "change": c(stock.Change), - "changePercent": c(stock.ChangePct), - "open": m(stock.Open), - "low": m(stock.Low), - "high": m(stock.High), - "low52": m(stock.Low52), - "high52": m(stock.High52), - "volume": m(stock.Volume), - "avgVolume": m(stock.AvgVolume), - "pe": m(stock.PeRatio), - "peX": m(stock.PeRatioX), - "dividend": m(stock.Dividend), - "yield": m(stock.Yield), - "mktCap": m(stock.MarketCap), - "mktCapX": m(stock.MarketCapX), - "advancing": stock.Advancing, - } + //var values = map[string]interface{}{ + // "ticker": strings.TrimSpace(stock.Ticker), + // "last": m(stock.LastTrade), + // "change": c(stock.Change), + // "changePercent": c(stock.ChangePct), + // "open": m(stock.Open), + // "low": m(stock.Low), + // "high": m(stock.High), + // "low52": m(stock.Low52), + // "high52": m(stock.High52), + // "volume": m(stock.Volume), + // "avgVolume": m(stock.AvgVolume), + // "pe": m(stock.PeRatio), + // "peX": m(stock.PeRatioX), + // "dividend": m(stock.Dividend), + // "yield": m(stock.Yield), + // "mktCap": m(stock.MarketCap), + // "mktCapX": m(stock.MarketCapX), + // "advancing": stock.Advancing, + //} + + var values = make(map[string]interface{}) + //values["pe"] = 8; + var err error + values["ticker"] = strings.TrimSpace(stock.Ticker) + values["last"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.LastTrade),"$",""),64) + values["change"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.Change),"$",""),64) + values["changePercent"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.ChangePct),"$",""),64) + values["open"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.Open),"$",""),64) + values["low"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.Low),"$",""),64) + values["high"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.High),"$",""),64) + values["low52"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.Low52),"$",""),64) + values["high52"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.High52),"$",""),64) + values["volume"],err = strconv.ParseFloat(stock.Volume,64) + values["avgVolume"],err = strconv.ParseFloat(stock.AvgVolume,64) + values["pe"],err = strconv.ParseFloat(stock.PeRatio,64) + values["peX"],err = strconv.ParseFloat(stock.PeRatioX,64) + values["dividend"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.Dividend),"$",""),64) + values["yield"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.Yield),"$",""),64) + values["mktCap"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.MarketCap),"$",""),64) + values["mktCapX"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.MarketCapX),"$",""),64) + values["advancing"] = stock.Advancing + log.Println(stock.Dividend) + log.Println("m9: ",m("$9")) + log.Printf("type m($9) is %T\n",m("$9")) + log.Println("dividend:",stock.Dividend,m(stock.Dividend)) + log.Printf("dividend is %T\n",stock.Dividend) + log.Printf("m(dividend) is %T\n",m(stock.Dividend)) + log.Printf("values[pe] is type %T\n",values["pe"]) result, err := filter.profile.filterExpression.Evaluate(values) if err != nil { + log.Println("In filter.go, err:",err) // The filter isn't working, so reset to no filter. filter.profile.Filter = "" // Return an empty list. The next main loop cycle will From f88377fc07b7943e55fb5b5ab0a69e50c774eab6 Mon Sep 17 00:00:00 2001 From: Adam Hayes Date: Sat, 27 Nov 2021 23:52:52 -0500 Subject: [PATCH 2/2] Bugfix--filters now work: filter.go converts correctly to floats * Replaced suffice M,B,T with exponentional notation. * Removed $ and % symbols. * Booleans were left unchanged. --- filter.go | 84 ++++++++++++++++++++++--------------------------------- 1 file changed, 34 insertions(+), 50 deletions(-) diff --git a/filter.go b/filter.go index 9e16911..68ae446 100644 --- a/filter.go +++ b/filter.go @@ -6,7 +6,6 @@ package mop import ( "strings" - "log" "strconv" ) @@ -24,66 +23,51 @@ func NewFilter(profile *Profile) *Filter { } } +// Changes money and % notation to a plain float for math, comparisons. +func stringToNumber (numberString string) float64 { + // If the string "$3.6B" is passed in, the returned float will be 3.6E+09. + // If 0.03% is passed in, the returned float will be 0.03 (NOT 0.0003!). + newString := strings.TrimSpace(numberString) // Take off whitespace. + newString = strings.Replace(newString,"$","",1) // Remove the $ symbol. + newString = strings.Replace(newString,"%","",1) // Remove the $ symbol. + newString = strings.Replace(newString,"K","E+3",1) // Thousand (kilo) + newString = strings.Replace(newString,"M","E+6",1) // Million + newString = strings.Replace(newString,"B","E+9",1) // Billion + newString = strings.Replace(newString,"T","E+12",1) // Trillion + finalValue, _ := strconv.ParseFloat(newString, 64) + return finalValue +} + // Apply builds a list of sort interface based on current sort // order, then calls sort.Sort to do the actual job. func (filter *Filter) Apply(stocks []Stock) []Stock { var filteredStocks []Stock for _, stock := range stocks { - //var values = map[string]interface{}{ - // "ticker": strings.TrimSpace(stock.Ticker), - // "last": m(stock.LastTrade), - // "change": c(stock.Change), - // "changePercent": c(stock.ChangePct), - // "open": m(stock.Open), - // "low": m(stock.Low), - // "high": m(stock.High), - // "low52": m(stock.Low52), - // "high52": m(stock.High52), - // "volume": m(stock.Volume), - // "avgVolume": m(stock.AvgVolume), - // "pe": m(stock.PeRatio), - // "peX": m(stock.PeRatioX), - // "dividend": m(stock.Dividend), - // "yield": m(stock.Yield), - // "mktCap": m(stock.MarketCap), - // "mktCapX": m(stock.MarketCapX), - // "advancing": stock.Advancing, - //} - var values = make(map[string]interface{}) - //values["pe"] = 8; - var err error - values["ticker"] = strings.TrimSpace(stock.Ticker) - values["last"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.LastTrade),"$",""),64) - values["change"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.Change),"$",""),64) - values["changePercent"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.ChangePct),"$",""),64) - values["open"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.Open),"$",""),64) - values["low"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.Low),"$",""),64) - values["high"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.High),"$",""),64) - values["low52"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.Low52),"$",""),64) - values["high52"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.High52),"$",""),64) - values["volume"],err = strconv.ParseFloat(stock.Volume,64) - values["avgVolume"],err = strconv.ParseFloat(stock.AvgVolume,64) - values["pe"],err = strconv.ParseFloat(stock.PeRatio,64) - values["peX"],err = strconv.ParseFloat(stock.PeRatioX,64) - values["dividend"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.Dividend),"$",""),64) - values["yield"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.Yield),"$",""),64) - values["mktCap"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.MarketCap),"$",""),64) - values["mktCapX"],err = strconv.ParseFloat(strings.ReplaceAll(strings.TrimSpace(stock.MarketCapX),"$",""),64) - values["advancing"] = stock.Advancing + // Make conversions from the strings to floats where necessary. + values["ticker"] = strings.TrimSpace(stock.Ticker) // Remains string + values["last"] = stringToNumber(stock.LastTrade) + values["change"] = stringToNumber(stock.Change) + values["changePercent"] = stringToNumber(stock.ChangePct) + values["open"] = stringToNumber(stock.Open) + values["low"] = stringToNumber(stock.Low) + values["high"] = stringToNumber(stock.High) + values["low52"] = stringToNumber(stock.Low52) + values["high52"] = stringToNumber(stock.High52) + values["dividend"] = stringToNumber(stock.Dividend) + values["yield"] = stringToNumber(stock.Yield) + values["mktCap"] = stringToNumber(stock.MarketCap) + values["mktCapX"] = stringToNumber(stock.MarketCapX) + values["volume"] = stringToNumber(stock.Volume) + values["avgVolume"] = stringToNumber(stock.AvgVolume) + values["pe"] = stringToNumber(stock.PeRatio) + values["peX"] = stringToNumber(stock.PeRatioX) + values["advancing"] = stock.Advancing // Remains bool. - log.Println(stock.Dividend) - log.Println("m9: ",m("$9")) - log.Printf("type m($9) is %T\n",m("$9")) - log.Println("dividend:",stock.Dividend,m(stock.Dividend)) - log.Printf("dividend is %T\n",stock.Dividend) - log.Printf("m(dividend) is %T\n",m(stock.Dividend)) - log.Printf("values[pe] is type %T\n",values["pe"]) result, err := filter.profile.filterExpression.Evaluate(values) if err != nil { - log.Println("In filter.go, err:",err) // The filter isn't working, so reset to no filter. filter.profile.Filter = "" // Return an empty list. The next main loop cycle will