Video Coming Soon...
36: numfmt
This exercise is pending. Quick notes about this exercise:
- My implemention is at https://lcthw.dev/go/go-coreutils
- https://www.gnu.org/software/coreutils/manual/html_node/numfmt-invocation.html
- strings -- https://pkg.go.dev/strings@go1.25.3
- strconv -- https://pkg.go.dev/strconv@go1.25.3
The Code
View Source file go-coreutils/numfmt/main.go Only
package main
import (
"fmt"
"flag"
"strconv"
"log"
"math"
"bufio"
"os"
)
type Opts struct {
From string
To string
}
func parse_opts() (Opts, []string) {
var opts Opts
flag.StringVar(&opts.From, "from", "", "Convert from")
flag.StringVar(&opts.To, "to", "", "Convert to")
flag.Parse()
return opts, flag.Args()
}
func to_si(num string) string {
number, err := strconv.ParseFloat(num, 64)
if err != nil { log.Fatal("that's not a number") }
mag := math.Floor(math.Log10(number))
switch {
case mag < 3:
return num
case mag == 3:
// need to separate k from hundres
as_k := math.Floor(float64(number) / 1000.0)
mod := math.Ceil(float64(int(number) % 1000))
return fmt.Sprintf("%d.%dk", int(as_k), int(mod))
case mag > 3 && mag < 6:
as_m := math.Ceil(float64(number) / 1000.0)
return fmt.Sprintf("%dk", int(as_m))
case mag == 6:
// need to separate mil from k
as_m := math.Floor(float64(number) / 1000000.0)
mod := math.Ceil(float64(int(number) % 1000000) / 1000.0)
return fmt.Sprintf("%d.%dM", int(as_m), int(mod))
case mag > 6 && mag <= 9:
as_m := math.Ceil(float64(number) / 1000000.0)
return fmt.Sprintf("%dM", int(as_m))
default:
return fmt.Sprintf("%sbesos", num)
}
}
func main() {
opts, nums := parse_opts()
if opts.From != "" {
log.Fatal("you should implement this")
}
if len(nums) == 0 {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
num := scanner.Text()
fmt.Println(to_si(num))
}
} else {
for _, num := range nums {
fmt.Println(to_si(num))
}
}
}
Register for Learn Go the Hard Way
Register today for the course and get the all currently available videos and lessons, plus all future modules for no extra charge.