Pkg.go.dev is a new destination for Go discovery & docs. Check it out at pkg.go.dev/github.com/jtolds/qod and share your feedback.

package qod

import "github.com/jtolds/qod"

Package qod should NOT be used in a serious software engineering environment. qod stands for Quick and Dirty bahaha I just realized I got the acronym wrong. It's fine. It's on brand. Quick AND Dirty.

The context is I noticed that Go is my favorite language, but when a task gets too complicated for a shell pipeline or awk or something, I turn to Python. Why not Go?

In Python, I'd frequently write something like:

for line in sys.stdin: vals = map(int, line.split())

Here that is in Go:

package main import ( "bufio" "fmt" "os" "strconv" "strings" ) func main() { scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { var vals []int64 for _, str := range strings.Fields(scanner.Text()) { val, err := strconv.ParseInt(str, 10, 64) if err != nil { panic(err) } vals = append(vals, val) } } if err := scanner.Err(); err != nil { panic(err) } }

Ugh! Considering I don't care about this throwaway shell pipeline replacement, I'm clearly fine with it blowing up if something's wrong, and wow this was too much.

Package qod allows me to write the same type of thing in Go. Here is a reimplementation of the Python code above using qod:

package main import ( "os" "strings" "github.com/jtolds/qod" ) func main() { for line := range qod.Lines(os.Stdin) { vals := qod.Int64Slice(strings.Fields(line)) } }

Better! I'm more likely to use Go now for little scripts!

Reminder: don't use this for anything real. Most of the stuff in here panics at the sight of any errors. That's obviously Bad and Wrong and you should actually handle your errors. Set up your build system's linter to reject anything that imports github.com/jtolds/qod please. If you have a build system for what you're doing at all this isn't for you. If you have some one-off tab-delimited data you need to process real quick like I seem to ALL THE TIME then okay.

qod.go

❖ func AFH(f *os.File, err error) *os.File

AFH stands for Assert File Handle. It asserts there was no error and passes the file handle on through. Usage like:

fh := qod.AFH(os.Open(path))

❖ func AI(i int, err error) int

AI stands for Assert Int. It asserts there was no error and passes the int on through. Usage like:

qod.AI(fmt.Println("a line"))

ANE stands for Assert No Error. It panics if err != nil.

Bytes will take an integer amount of bytes and format it with units.

Float64 converts a string to a float64

Float64Slice converts a []string to a []float64

Int64 converts a string to an int64

Int64Slice converts a []string to an []int64

Lines makes reading lines easier. Usage like:

for line := range Lines(os.Stdin) { // do something with the line }

Returned lines will be right-stripped of whitespace. If you care about the lifetime of the channel that you're reading from and don't want it to leak, you probably shouldn't be using this package at all.

❖ func Printlnf(format string, vals ...interface{})

Printlnf is just cause I constantly use Println, then turn it into Printf, then get frustrated I forgot the newline.

SortedKeysBool returns the keys of a map[string]bool in sorted order.