Format float in golang html/template - go

I want to format float64 value to 2 decimal places in golang html/template say in index.html file. In .go file I can format like:
strconv.FormatFloat(value, 'f', 2, 32)
But I don't know how to format it in template. I am using gin-gonic/gin framework for backend. Any help will be appreciated. Thanks.

You have many options:
You may decide to format the number e.g. using fmt.Sprintf() before passing it to the template execution (n1)
Or you may create your own type where you define the String() string method, formatting to your liking. This is checked and used by the template engine (n2).
You may also call printf directly and explicitly from the template and use custom format string (n3).
Even though you can call printf directly, this requires to pass the format string. If you don't want to do this every time, you can register a custom function doing just that (n4)
See this example:
type MyFloat float64
func (mf MyFloat) String() string {
return fmt.Sprintf("%.2f", float64(mf))
}
func main() {
t := template.Must(template.New("").Funcs(template.FuncMap{
"MyFormat": func(f float64) string { return fmt.Sprintf("%.2f", f) },
}).Parse(templ))
m := map[string]interface{}{
"n0": 3.1415,
"n1": fmt.Sprintf("%.2f", 3.1415),
"n2": MyFloat(3.1415),
"n3": 3.1415,
"n4": 3.1415,
}
if err := t.Execute(os.Stdout, m); err != nil {
fmt.Println(err)
}
}
const templ = `
Number: n0 = {{.n0}}
Formatted: n1 = {{.n1}}
Custom type: n2 = {{.n2}}
Calling printf: n3 = {{printf "%.2f" .n3}}
MyFormat: n4 = {{MyFormat .n4}}`
Output (try it on the Go Playground):
Number: n0 = 3.1415
Formatted: n1 = 3.14
Custom type: n2 = 3.14
Calling printf: n3 = 3.14
MyFormat: n4 = 3.14

Use the printf template built-in function with the "%.2f" format:
tmpl := template.Must(template.New("test").Parse(`The formatted value is = {{printf "%.2f" .}}`))
tmpl.Execute(os.Stdout, 123.456789)
Go Playgroung

You can register a FuncMap.
package main
import (
"fmt"
"os"
"text/template"
)
type Tpl struct {
Value float64
}
func main() {
funcMap := template.FuncMap{
"FormatNumber": func(value float64) string {
return fmt.Sprintf("%.2f", value)
},
}
tmpl, _ := template.New("test").Funcs(funcMap).Parse(string("The formatted value is = {{ .Value | FormatNumber }}"))
tmpl.Execute(os.Stdout, Tpl{Value: 123.45678})
}
Playground

Edit: I was wrong about rounding/truncating.
The problem with %.2f formatting is that it does not round but truncates.
I've developed a decimal class based on int64 for handling money that is handling floats, string parsing, JSON, etc.
It stores amount as 64 bit integer number of cents. Can be easily created from float or converted back to float.
Handy for storing in DB as well.
https://github.com/strongo/decimal
package example
import "github.com/strongo/decimal"
func Example() {
var amount decimal.Decimal64p2; print(amount) // 0
amount = decimal.NewDecimal64p2(0, 43); print(amount) // 0.43
amount = decimal.NewDecimal64p2(1, 43); print(amount) // 1.43
amount = decimal.NewDecimal64p2FromFloat64(23.100001); print(amount) // 23.10
amount, _ = decimal.ParseDecimal64p2("2.34"); print(amount) // 2.34
amount, _ = decimal.ParseDecimal64p2("-3.42"); print(amount) // -3.42
}
Works well for my debts tracker app https://debtstracker.io/

Related

Golang default return 2 decimal places

I need to export the json with default 2 decimal places for amount.
In Query i have used "SELECT FORMAT(amount, 2) from product"
type product struct {
Amount float32 `db:"Amount"`
}
So i need if the Amount value is 99 it should export 99.00
every time it is returning 99.
I just simply retrieving data from DB and exporting like json marshal the dynamic product struct.
From DB i am getting with decimal formatted value but the decimal getting lost when we are assigning the value in struct.
NOTE :: fmt.Sprintf("%.2f", value) will not work.
To export 99.00 instead of 99 ,you can convert the amount value from int to float with specified number of decimal points.Here is a simple code with the same logic :
package main
import (
"fmt"
)
func main() {
amount := 99
var desiredVal float64 = float64(amount)
fmt.Printf("amount = %d \n", amount)
fmt.Printf("\nnew amount= %.2f", desiredVal)
}
Output:
amount = 99
new amount= 99.00
As stated above, the formatting needs to be done on the client side - it make sense that way.
Nevertheless here is a workaround - just create a another type with the formatted values, and marshal it:
package main
import (
"encoding/json"
"fmt"
)
type product struct {
Amount float32
}
func main() {
p := product{Amount: 99.00}
fmt.Println(string(marshal(p)))
}
type N struct {
Amount string
}
func NewN(p product) N {
return N{
Amount: fmt.Sprintf("%.2f", p.Amount),
}
}
func marshal(p product) []byte {
n := NewN(p)
r, _ := json.Marshal(&n)
return r
}
{"Amount":"99.00"}
One solution is to assign some improbable value like 7777.777 and then marshal the structure. Then do a string replace of the marshalled string i.e., replace 7777.77 with 99.00.

How to compare data using Reflection between struct and map[string]interface{} in Golang

I am trying to compare these two interfaces together as a function. It is working as far as I am concerned. I am sending a struct in A interface{} and map[string]interface{} in B, having the same values but when being compared with reflect they are not resulting to be the same. I would like to be able to convert the map[string]interface{} into a struct interface inside this function so that my tests can get shorter. I have tried using https://github.com/mitchellh/copystructure, but does not work inside this function.(from outside it works though:
var m map[string]interface{}
var something StructType
err := mapstructure.Decode(m, &something)
if err....
and then i send the something in the B interface)
below is the function to compare the interfaces. You can copy and paste and see how it works for yourself
package main
import (
"log"
"reflect"
)
type Something struct {
Name string
Age int
Male bool
Cars []string
}
func main() {
var s Something
s.Name = "joe"
s.Male = true
s.Age = 20
s.Cars = []string{"Fordd", "Chevy", "Mazda"}
m := make(map[string]interface{})
m["Name"] = "joe"
m["Male"] = true
m["Age"] = 20
m["Cars"] = []string{"Fordd", "Chevy", "Mazda"}
//with map[string]interface{} although the same values it does not work
log.Println("Are these the same: ", CompareData(s, m))
//with struct of same type it works
var s2 Something
s2.Name = "joe"
s2.Male = true
s2.Age = 20
s2.Cars = []string{"Fordd", "Chevy", "Mazda"}
log.Println("Are these the same: ", CompareData(s, s2))
}
func CompareData(A interface{}, B interface{}) bool {
a := reflect.ValueOf(A)
b := reflect.ValueOf(B)
akind := a.Kind().String()
bkind := a.Kind().String()
if akind == "slice" && bkind == "slice" {
for i := 0; i < a.Len(); i++ {
// log.Println("they are sliced")
CompareData(a.Index(i).Interface(), b.Index(i).Interface())
// log.Println("\n", a.Index(i).Interface(), "\n", b.Index(i).Interface())
}
// t.Fatal("this is a slice you need to iterate over the values")
} else {
// log.Println("\n\n", A, "\n", B)
if !reflect.DeepEqual(a.Interface(), b.Interface()) {
log.Println("These should be equal\nSuccessData:\t", a.Interface(), "\nData:\t\t", b.Interface())
return false
}
// log.Println("\nA:\t", A, "\nB:\t", B)
}
return true
}

Currency Format in Golang using currency.Symbol from golang.org/x/text/currency

Hi I'm working on a function to format values in currency. I'm using golang.org/x/text/currency for the job, but I'm getting the output with points at the place of commas and no thousands separators.
func (produto *Produto) FormataPreco(valor int64) string {
unit, _ := currency.ParseISO("BRL")
p := message.NewPrinter(language.BrazilianPortuguese)
return p.Sprint(currency.Symbol(unit.Amount(float64(valor) / 100)))
}
The expected result should be R$ 123.456,78 but I'm getting R$ 123456.78
--- Edit ---
I did a version using hardcoded values, but I would like a solution that uses system locale resources.
func (produto *Produto) FormataPreco(valor int64) string {
p := message.NewPrinter(language.BrazilianPortuguese)
return p.Sprintf("R$ %.2f", float64(valor/100))
}
In this example, I inferred the currency format from the language code.
https://goplay.space/#fqs9t8MG062
n := display.Tags(language.English)
for _, lcode := range []string{"en_US", "pt_BR", "de", "ja", "hi"} {
lang := language.MustParse(lcode)
cur, _ := currency.FromTag(lang)
scale, _ := currency.Cash.Rounding(cur) // fractional digits
dec := number.Decimal(100000.00, number.Scale(scale))
p := message.NewPrinter(lang)
p.Printf("%24v (%v): %v%v\n", n.Name(lang), cur, currency.Symbol(cur), dec)
}
// American English (USD): $100,000.00
// Brazilian Portuguese (BRL): R$100.000,00
// German (EUR): €100.000,00
// Japanese (JPY): ¥100,000
// Hindi (INR): ₹1,00,000.00
You could also parse ISO currency codes, but then you must also specify the language in which to format the number. The output language will not affect the number of fractional digits, but it will affect where commas and periods are used:
https://goplay.space/#DlxSmjZbHH6
for _, iso := range []string{"USD", "BRL", "EUR", "JPY", "INR"} {
cur := currency.MustParseISO(iso)
scale, _ := currency.Cash.Rounding(cur) // fractional digits
dec := number.Decimal(100000.00, number.Scale(scale))
p := message.NewPrinter(language.English)
p.Printf("%v: %v%v\n", cur, currency.Symbol(cur), dec)
}
// USD: $100,000.00
// BRL: R$100,000.00
// EUR: €100,000.00
// JPY: ¥100,000
// INR: ₹100,000.00
Certain currencies are rounded in increments, like 0.05 or 0.50. For those cases, the second return value of currency.Cash.Rounding(cur) will return 5 or 50 instead of 1. To give the Decimal formatter the IncrementString it expects, we have to do a little more processing:
package main
import (
"math"
"strconv"
"golang.org/x/text/currency"
"golang.org/x/text/language"
"golang.org/x/text/language/display"
"golang.org/x/text/message"
"golang.org/x/text/number"
)
func main() {
n := display.Tags(language.English)
for _, lcode := range []string{"en_US", "en_CA", "da", "ja"} {
lang := language.MustParse(lcode)
cur, _ := currency.FromTag(lang)
scale, incCents := currency.Cash.Rounding(cur) // fractional digits
incFloat := math.Pow10(-scale) * float64(incCents)
incFmt := strconv.FormatFloat(incFloat, 'f', scale, 64)
dec := number.Decimal(100000.26,
number.Scale(scale), number.IncrementString(incFmt))
p := message.NewPrinter(lang)
p.Printf("%24v %v, %4s-rounding: %3v%v\n",
n.Name(lang), cur, incFmt, currency.Symbol(cur), dec)
}
}
// American English USD, 0.01-rounding: $100,000.26
// Canadian English CAD, 0.05-rounding: CA$100,000.25
// Danish DKK, 0.50-rounding: DKK100.000,50
// Japanese JPY, 1-rounding: ¥100,000
As you may notice, the golang.org/x/text/currency is still a work in progress and hasn't been updated in a while.
NOTE: the formatting functionality is currently under development and
may change without notice.
If you prefer a simple helper function to get the job done, you can use something like this:
func formatMoney(value int32, thousand, decimal string) string {
var result string
var isNegative bool
if value < 0 {
value = value * -1
isNegative = true
}
// apply the decimal separator
result = fmt.Sprintf("%s%02d%s", decimal, value%100, result)
value /= 100
// for each 3 dígits put a dot "."
for value >= 1000 {
result = fmt.Sprintf("%s%03d%s", thousand, value%1000, result)
value /= 1000
}
if isNegative {
return fmt.Sprintf("$ -%d%s", value, result)
}
return fmt.Sprintf("$ %d%s", value, result)
}
usage:
formatMoney(10, ",", ".") // $ 0.10
formatMoney(12345, ",", ".") // $ 123.45
formatMoney(1234567, ",", ".") // $ 12,345.67
formatMoney(-1234567, ",", ".") // $ -12,345.67

Allowing for a variable number of return values in method declaration

I have a function that solves the problem of Go not allowing for the setting of default values in method declarations. I want to make it just a little bit better by allowing for a variable number of return variables. I understand that I can allow for an array of interfaces as a return type and then create an interface array with all the variables to return, like this:
func SetParams(params []interface{}, args ...interface{}) (...[]interface{}) {
var values []interface{}
for i := range params {
var value interface{}
paramType := reflect.TypeOf(params[i])
if len(args) < (i + 1) {
value = params[i]
} else {
argType := reflect.TypeOf(args[i])
if paramType != argType {
value = params[i]
}
value = args[i]
}
values = append(values, value)
}
return values
}
This is an example of a method you want to define default values for. You build it as a variadic function (allowing a variable number of parameters) and then define the default values of the specific params you are looking for inside the function instead of in the declaration line.
func DoSomething(args ...interface{}) {
//setup default values
str := "default string 1"
num := 1
str2 := "default string 2"
//this is fine
values := SetParams([]interface{str, num, str2}, args)
str = values[0].(string)
num = values[1].(int)
str = values[2].(string)
//I'd rather support this
str, num, str2 = SetParams(params, args)
}
I understand that
[]interface{str, num, str2}
in the above example is not syntactically correct. I did it that way to simplify my post. But, it represents another function that builds the array of interfaces.
I would like to support this:
str, num, str2 = SetParams(params, args)
instead of having to do this:
values := SetParams([]interface{str, num, str2}, args)
str = values[0].(string)
num = values[1].(int)
str = values[2].(string)
Any advice? Help?
Please don't write horrible (and ineffective due to reflect) code to solve nonexistent problem.
As was indicated in comments, turning a language into
one of your previous languages is indeed compelling
after a switch, but this is counterproductive.
Instead, it's better to work with the idioms and approaches
and best practices the language provides --
even if you don't like them (yet, maybe).
For this particular case you can roll like this:
Make the function which wants to accept
a list of parameters with default values
accept a single value of a custom struct type.
For a start, any variable of such type, when allocated,
has all its fields initialized with the so-called "zero values"
appropriate to their respective types.
If that's enough, you can stop there: you will be able
to pass values of your struct type to your functions
by producing them via literals right at the call site --
initializing only the fields you need.
Otherwise have pre-/post- processing code which
would provide your own "zero values" for the fields
you need.
Update on 2016-08-29:
Using a struct type to simulate optional parameters
using its fields being assigned default values which happen
to be Go's native zero values for their respective data types:
package main
import (
"fmt"
)
type params struct {
foo string
bar int
baz float32
}
func myfun(params params) {
fmt.Printf("%#v\n", params)
}
func main() {
myfun(params{})
myfun(params{bar: 42})
myfun(params{foo: "xyzzy", baz: 0.3e-2})
}
outputs:
main.params{foo:"", bar:0, baz:0}
main.params{foo:"", bar:42, baz:0}
main.params{foo:"xyzzy", bar:0, baz:0.003}
As you can see, Go initializes the fields of our params type
with the zero values appropriate to their respective types
unless we specify our own values when we define our literals.
Playground link.
Providing default values which are not Go-native zero values for
the fields of our custom type can be done by either pre-
or post-processing the user-submitted value of a compound type.
Post-processing:
package main
import (
"fmt"
)
type params struct {
foo string
bar int
baz float32
}
func (pp *params) setDefaults() {
if pp.foo == "" {
pp.foo = "ahem"
}
if pp.bar == 0 {
pp.bar = -3
}
if pp.baz == 0 { // Can't really do this to FP numbers; for demonstration purposes only
pp.baz = 0.5
}
}
func myfun(params params) {
params.setDefaults()
fmt.Printf("%#v\n", params)
}
func main() {
myfun(params{})
myfun(params{bar: 42})
myfun(params{foo: "xyzzy", baz: 0.3e-2})
}
outputs:
main.params{foo:"ahem", bar:-3, baz:0.5}
main.params{foo:"ahem", bar:42, baz:0.5}
main.params{foo:"xyzzy", bar:-3, baz:0.003}
Playground link.
Pre-processing amounts to creating a "constructor" function
which would return a value of the required type pre-filled
with the default values your choice for its fields—something
like this:
func newParams() params {
return params{
foo: "ahem",
bar: -3,
baz: 0.5,
}
}
so that the callers of your function could call newParams(),
tweak its fields if they need and then pass the resulting value
to your function:
myfunc(newParams())
ps := newParams()
ps.foo = "xyzzy"
myfunc(ps)
This approach is maybe a bit more robust than post-processing but
it precludes using of literals to construct the values to pass to
your function right at the call site which is less "neat".
Recently I was playing with anonymous functions in Go and implemented an example which accepts and returns undefined parameters:
func functions() (funcArray []func(args ... interface{}) (interface{}, error)) {
type ret struct{
first int
second string
third bool
}
f1 := func(args ... interface{}) (interface{}, error){
a := args[0].(int)
b := args[1].(int)
return (a < b), nil
}
funcArray = append(funcArray , f1)
f2 := func(args ... interface{}) (interface{}, error){
return (args[0].(string) + args[1].(string)), nil
}
funcArray = append(funcArray , f2)
f3 := func(args ... interface{}) (interface{}, error){
return []int{1,2,3}, nil
}
funcArray = append(funcArray , f3)
f4 := func(args ... interface{}) (interface{}, error){
return ret{first: 1, second: "2", third: true} , nil
}
funcArray = append(funcArray , f4)
return funcArray
}
func main() {
myFirst_Function := functions()[0]
mySecond_Function := functions()[1]
myThird_Function := functions()[2]
myFourth_Function := functions()[3]
fmt.Println(myFirst_Function(1,2))
fmt.Println(mySecond_Function("1","2"))
fmt.Println(myThird_Function())
fmt.Println(myFourth_Function ())
}
I hope it helps you.
https://play.golang.org/p/d6dSYLwbUB9

Evaluate/Execute Golang code/expressions like js' eval()

Is there a eval() like method on golang?
Evaluate/Execute JavaScript code/expressions:
var x = 10;
var y = 20;
var a = eval("x * y") + "<br>";
var b = eval("2 + 2") + "<br>";
var c = eval("x + 17") + "<br>";
var res = a + b + c;
The result of res will be:
200
4
27
Is this possible in golang? and why?
Its perfectly possible. At least for expressions, which seems to be what you want:
Have a look at:
https://golang.org/src/go/types/eval.go
https://golang.org/src/go/constant/value.go
https://golang.org/pkg/go/types/#Scope
You'd need to create your own Package and Scope objects and Insert constants to the package's scope. Constants are created using types.NewConst by providing appropriate type information.
Is this possible in golang? and why?
No, because golang is not that kind of language. It is intended to be compiled, not interpreted, so that the runtime does not contain any “string to code” transformer, or indeed knows what a syntactically correct program looks like.
Note that in Go as in most other programming languages, you can write your own interpreter, that is, a function that takes a string and causes computations to be done accordingly. The choice of the Go designers is only not to force a feature of such dubious interest and security on everyone who did not need it.
There is no built-in eval. But it is possible to implement evaluation which will follow most of GoLang spec: eval (only expression, not a code) package on github / on godoc.
Example:
import "github.com/apaxa-go/eval"
...
src:="int8(1*(1+2))"
expr,err:=eval.ParseString(src,"")
if err!=nil{
return err
}
r,err:=expr.EvalToInterface(nil)
if err!=nil{
return err
}
fmt.Printf("%v %T", r, r) // "3 int8"
It is also possible to use variables in evaluated expression, but it requires pass them with theirs names to Eval method.
This parsing example parses GO code at runtime:
package main
import (
"fmt"
"go/parser"
"go/token"
)
func main() {
fset := token.NewFileSet() // positions are relative to fset
src := `package foo
import (
"fmt"
"time"
)
func bar() {
fmt.Println(time.Now())
}`
// Parse src but stop after processing the imports.
f, err := parser.ParseFile(fset, "", src, parser.ImportsOnly)
if err != nil {
fmt.Println(err)
return
}
// Print the imports from the file's AST.
for _, s := range f.Imports {
fmt.Println(s.Path.Value)
}
}
go-exprtk package will probably meet all kinds of your needs to evaluate any kind of mathematical expression dynamically.
package main
import (
"fmt"
"github.com/Pramod-Devireddy/go-exprtk"
)
func main() {
exprtkObj := exprtk.NewExprtk()
exprtkObj.SetExpression("x * y")
exprtkObj.AddDoubleVariable("x")
exprtkObj.AddDoubleVariable("y")
exprtkObj.CompileExpression()
exprtkObj.SetDoubleVariableValue("x", 10)
exprtkObj.SetDoubleVariableValue("y", 20)
a := exprtkObj.GetEvaluatedValue()
exprtkObj.SetExpression("2 + 2")
exprtkObj.CompileExpression()
b := exprtkObj.GetEvaluatedValue()
exprtkObj.SetExpression("x + 17")
exprtkObj.CompileExpression()
c := exprtkObj.GetEvaluatedValue()
res := a + b + c
fmt.Println(a, b, c, res)
}

Resources