How to convert Point Coordinate in Database to Point struct GoLang - go

CurrentCoordinates []uint8 `json:"current_coordinates"`
type Points struct {
Lat float64 `json:"lat"`
Lng float64 `json:"lng"`
}
DB Column has data as :
POINT(6.887035 79.883757)
From DB i got it into []uint8, then the result is :
[0 0 0 0 1 1 0 0 0 35 161 45 231 82 140 27 64 28 39 133 121 143 248 83 64]
Anyone know how to convert this to coordinates?

The coordinates are stored at the end of your slice, both have 8 bytes which are the little-endian encoded bytes of the IEEE 754 double-precision representation of the floating point numbers.
You may use the encoding/binary package to get the floating-point data of the coordinates as an uint64, and you may use math.Float64frombits() to "convert" that data to float64 type.
This is how you can decode them:
data := []byte{0, 0, 0, 0, 1, 1, 0, 0, 0, 35, 161, 45, 231, 82, 140, 27, 64, 28, 39, 133, 121, 143, 248, 83, 64}
d := binary.LittleEndian.Uint64(data[9:])
x := math.Float64frombits(d)
d = binary.LittleEndian.Uint64(data[17:])
y := math.Float64frombits(d)
fmt.Println(x, y)
This will output (try it on the Go Playground):
6.887035 79.883757
The beginning of your data may be SRID (spatial reference identifier) and/or some kind of distance / accuracy for searches, depends on the database you're using.
Alternatively you may create an io.Reader reading from your slice using bytes.NewReader(), and use the binary.Read() function:
data := []byte{0, 0, 0, 0, 1, 1, 0, 0, 0, 35, 161, 45, 231, 82, 140, 27, 64, 28, 39, 133, 121, 143, 248, 83, 64}
r := bytes.NewReader(data[9:])
var x, y float64
if err := binary.Read(r, binary.LittleEndian, &x); err != nil {
panic(err)
}
if err := binary.Read(r, binary.LittleEndian, &y); err != nil {
panic(err)
}
fmt.Println(x, y)
This will output the same. Try this one on the Go Playground.

Related

Finding numbers above the mean

I could use some help finding all the numbers from a struct array that are above a calculated mean!
//MeanMedianMode struct
type MeanMedianMode struct {
numbers []float64
}
func main() {
// range of numbers
dataType := MeanMedianMode{
numbers: []float64{
84, 25, 88, 56, 10, 19, 11, 80,
45, 83, 22, 40, 22, 52, 61, 13, 73, 23, //Data to be used
90, 89, 6,
},
}
I've figured out how to pass my data easily and find the average as follows...
//CalcMean float64
func (mm *MeanMedianMode) CalcMean() float64 {
total := 0.0
for _, v := range mm.numbers {
total += v
}
return (total / float64(len(mm.numbers)))
//return math.Round(total / float64(len(mm.numbers))) //Should it need to be rounded
}
My biggest issue is replicating that process and using the values stored in the array within another function and iterating over them to find the values greater than (>) the found mean!
I appreciate the insights!
I don't know how you'd like to do it, but something like this I guess:
package main
import (
"fmt"
)
//MeanMedianMode struct
type MeanMedianMode struct {
numbers []float64
}
func main() {
m := &MeanMedianMode{
numbers: []float64{
84, 25, 88, 56, 10, 19, 11, 80,
45, 83, 22, 40, 22, 52, 61, 13, 73, 23,
90, 89, 6,
},
}
mean := m.CalcMean()
for _, n := range m.numbers {
if n > mean {
fmt.Printf("%.3f is greater than the mean\n", n)
}
}
}
//CalcMean float64
func (mm *MeanMedianMode) CalcMean() float64 {
total := 0.0
for _, v := range mm.numbers {
total += v
}
return (total / float64(len(mm.numbers)))
}

Go code running result in local environment is not same with run in go play

I am using Go to implement an algorithm described below:
There is an array,only one number appear one time,all the other numbers appear three times,find the number only appear one time
My code listed below:
import (
"testing"
)
func findBySum(arr []int) int {
result := 0
sum := [32]int{}
for i := 0; i < 32; i++ {
for _, v := range arr {
sum[i] += (v >> uint(i)) & 0x1
}
sum[i] %= 3
sum[i] <<= uint(i)
result |= sum[i]
}
return result
}
func TestThree(t *testing.T) {
// except one nubmer,all other number appear three times
a1 := []int{11, 222, 444, 444, 222, 11, 11, 17, -123, 222, -123, 444, -123} // unqiue number is 17
a2 := []int{11, 222, 444, 444, 222, 11, 11, -17, -123, 222, -123, 444, -123} // unque number is -17
t.Log(findBySum(a1))
t.Log(findBySum(a2))
}
However,I found that the running result in my PC is wrong,and the same code running in https://play.golang.org/p/hEseLZVL617 is correct,I do not know why.
Result in my PC:
Result in https://play.golang.org/p/hEseLZVL617:
As we see,when the unique number is positive,both result are right,but when the unique number is negative,the result in my PC in wrong and the result online is right.
I think it has something to do with the bit operations in my code,but I can't find the root cause.
I used IDEA 2019.1.1 and my Golang version listed below:
I don't know why the same code can works fine online and do not work in my local PC,can anyone help me analysis this? Thanks in advance!
Size of int is platform dependent, it may be 32-bit and it may be 64-bit. On the Go Playground it's 32-bit, on your local machine it's 64-bit.
If we change your example to use int64 explicitly instead of int, the result is the same on the Go Playground too:
func findBySum(arr []int64) int64 {
result := int64(0)
sum := [32]int64{}
for i := int64(0); i < 32; i++ {
for _, v := range arr {
sum[i] += (v >> uint64(i)) & 0x1
}
sum[i] %= 3
sum[i] <<= uint(i)
result |= sum[i]
}
return result
}
func TestThree(t *testing.T) {
// except one nubmer,all other number appear three times
a1 := []int64{11, 222, 444, 444, 222, 11, 11, 17, -123, 222, -123, 444, -123} // unqiue number is 17
a2 := []int64{11, 222, 444, 444, 222, 11, 11, -17, -123, 222, -123, 444, -123} // unque number is -17
t.Log(findBySum(a1))
t.Log(findBySum(a2))
}
You perform bitwise operations that assume 32-bit integer size. To get correct results locally (where your architecture and thus size of int and uint is 64-bit), change all ints to int32 and uint to uint32:
func findBySum(arr []int32) int32 {
result := int32(0)
sum := [32]int32{}
for i := int32(0); i < 32; i++ {
for _, v := range arr {
sum[i] += (v >> uint32(i)) & 0x1
}
sum[i] %= 3
sum[i] <<= uint(i)
result |= sum[i]
}
return result
}
func TestThree(t *testing.T) {
// except one nubmer,all other number appear three times
a1 := []int32{11, 222, 444, 444, 222, 11, 11, 17, -123, 222, -123, 444, -123} // unqiue number is 17
a2 := []int32{11, 222, 444, 444, 222, 11, 11, -17, -123, 222, -123, 444, -123} // unque number is -17
t.Log(findBySum(a1))
t.Log(findBySum(a2))
}
Lesson: if you perform calculations whose result depend on the representation size, always be explicit, and use fixed-size numbers like int32, int64, uint32, uint64.

Difficulty with variadic functions [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
From An Introduction to Programming in Go, page 91, Exercise Question no 4, Topic: Functions:
Write a function with one variadic parameter that finds the greatest number in a list of numbers?
So far I had written this code but it is showing errors
package main
import (
"fmt"
)
func findMaximum(args ...[]int) []int {
max := args[0]
for _, v := range args {
if v > []args {
max = v
}
}
return args
}
func main() {
x := []int{
48, 96, 86, 68,
57, 82, 63, 70,
37, 34, 83, 27,
19, 97, 9, 17,
}
fmt.Println(findMaximum(x))
}
I had taken reference from this Program
(Page, 75, Question No. - 4, Topic: Arrays, Slices and Maps)
Write a program that finds the smallest number
in this list:
x := []int{
48,96,86,68,
57,82,63,70,
37,34,83,27,
19,97, 9,17,
}
This is the program I had written to solve this Question
package main
import "fmt"
func main() {
arr := []uint{
48, 96, 86, 68,
57, 82, 63, 70,
37, 34, 83, 27,
19, 97, 9, 17,
}
min := arr[0] // assume first value is smallest
for _, value := range arr {
if value < min {
min = value // found another value, replace previous value of min
}
}
fmt.Println("The smallest value is : ", min)
}
This Question Program is running but the First one is not I don't know why.
In mathematics and in computer programming, a variadic function is a
function of indefinite arity, i.e., one which accepts a variable
number of arguments.
Source: Wikipedia
Your function signature is slightly incorrect.
func findMaximum(args ...[]int) []int
This indicates that findMaximum takes in a variable number of int slices as arguments and returns an int slice. The problem that you're trying to solve is asking to take in a variable number of int arguments and return a singular int which is the largest in the set provided.
Calling your function would look something like this:
largest := findMaximum([]int{1, 2, 3}, []int{4, 5, 6}, []int{7, 8, 9})
In this case, largest would be of type []int indicating that the function returned multiple int values in the form of a slice. This wouldn't make sense, since there should only be one largest value (assuming no duplicates).
You're wanting a function signature that looks like this:
func findMaximum(args ...int) int
Calling this function would look like this:
largest := findMaximum(1, 2, 3, 4, 5, 6, 7, 8, 9)
...or if you had your numbers in a slice:
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
largest := findMaximum(nums...)
In this case, largest would be of type int, which is the correct return value you're looking for in this problem.
(Go Playground)
Good luck!
If you run your code through https://play.golang.org/ you will see a couple of syntax errors. Below is the correct version which finds max in a slice.
As you can note you had extra ... in the slice argument call.
package main
import (
"fmt"
)
func findMaximum(args []int) int {
max := args[0]
for _, v := range args {
if v > max{
max = v
}
}
return max
}
func main() {
x := []int{
48, 96, 86, 68,
57, 82, 63, 70,
37, 34, 83, 27,
19, 97, 9, 17,
}
fmt.Println(findMaximum(x))
}

How to extract a .jar file

I like to extract a .jar file in Go. I tried different approaches with the build in libraries but with no success. In buff is a little part of the JAR I try to analyze. The errors also occur on the full byte array.
flate:
buff := []byte{80, 75, 3, 4, 10, 0, 8, 8, 8, 0, 239, 77, 77, 78,
147,
98, 6, 159, 116, 0, 0, 0, 132, 0, 0, 0, 20, 0, 0, 0, 77, 69, 84, 65,
45, 73, 78, 70, 47, 77, 65, 78, 73, 70, 69, 83, 84, 46, 77, 70, 37,
140, 49, 14, 194, 48, 12, 0, 247, 72, 249, 131, 63, 16, 43, 128, 88,
178, 181, 221, 144, 178, 178, 91, 196, 64, 32, 184, 81, 28, 42, 248,
61,5, 214, 187, 211, 69, 146, 124, 102, 237}
b := bytes.NewReader(buff)
zr := flate.NewReader(b)
if _, err := io.Copy(os.Stdout, zr); err != nil {
log.Fatal(err)
}
if err := zr.Close(); err != nil {
log.Fatal(err)
}
fmt.Println()
Error: flate: corrupt input before offset 5
zlib:
b := bytes.NewReader(buff)
r, err := zlib.NewReader(b)
if err != nil {
panic(err)
}
io.Copy(os.Stdout, r)
r.Close()
Error: zlib: invalid header
Wikipedia says JAR is a extension of zip and normal compression programs can unzip them. Any ideas how to get this working? Like adding a working header or is my code wrong?
JAR files are zip archives, not just zlib or flate compressed data.
So use the archive/zip package to properly process them. For example, to list the files inside the JAR file:
r, err := zip.NewReader(bytes.NewReader(buff), int64(len(buff)))
if err != nil {
panic(err)
}
for _, f := range r.File {
fmt.Println("Found in jar:", f.Name)
}
Of course you have to provide the full file content, else you will most likely get an error when obtaining the zip.Reader.
If you also want to print the contents of the files inside the archive, this is how you could do it:
for _, f := range r.File {
fmt.Printf("Found in jar: %s, contents:\n", f.Name)
rc, err := f.Open()
if err != nil {
log.Fatal(err)
}
_, err = io.CopyN(os.Stdout, rc, int64(f.UncompressedSize64))
if err != nil {
log.Fatal(err)
}
rc.Close()
fmt.Println()
}
Here's a JAR file which contains a single file named a.txt, with contents "Hello Gopher":
buff := []byte{80, 75, 3, 4, 10, 0, 0, 0, 0, 0, 91, 109, 103, 78, 132, 225, 60, 127, 13, 0, 0, 0, 13, 0, 0, 0, 5, 0, 28, 0, 97, 46, 116, 120, 116, 85, 84, 9, 0, 3, 206, 17, 129, 92, 219, 17, 129, 92, 117, 120, 11, 0, 1, 4, 232, 3, 0, 0, 4, 232, 3, 0, 0, 72, 101, 108, 108, 111, 32, 71, 111, 112, 104, 101, 114, 10, 80, 75, 1, 2, 30, 3, 10, 0, 0, 0, 0, 0, 91, 109, 103, 78, 132, 225, 60, 127, 13, 0, 0, 0, 13, 0, 0, 0, 5, 0, 24, 0, 0, 0, 0, 0, 1, 0, 0, 0, 164, 129, 0, 0, 0, 0, 97, 46, 116, 120, 116, 85, 84, 5, 0, 3, 206, 17, 129, 92, 117, 120, 11, 0, 1, 4, 232, 3, 0, 0, 4, 232, 3, 0, 0, 80, 75, 5, 6, 0, 0, 0, 0, 1, 0, 1, 0, 75, 0, 0, 0, 76, 0, 0, 0, 0, 0}
Running the above code on this buffer, the output is (try it on the Go Playground):
Found in jar: a.txt, contents:
Hello Gopher

Converting []uint8 to float64

What is the best way to handle an http resp.Body which is formatted as []uint8 and not as JSON?
I would like to convert the bytes into a float64.
This is the returned value response:
value : %!F([]uint8=[48 46 48 48 49 50 53 53 50 49])
Try using ParseFloat from the strconv package (play):
b := []uint8{48, 46, 48, 48, 49, 50, 53, 53, 50, 49}
f, err := strconv.ParseFloat(string(b), 64)
if err != nil {
// Handle parse error
}
fmt.Printf("%f\n", f) // 0.001255

Resources