Unexpected int at end of statement - go

I'm struggling a bit with this piece of Go code. I have been searching all over the place, but can't understand what is wrong about it.
Error message is: syntax error: unexpected int at end of statement
for that line near the bottom: func (TOHLCV TOHLCVs) Len() int {
I also have this error message for the second to the last line of code:
syntax error: non-declaration statement outside function body
In case the 2 errors are related
package main
import (
"fmt"
"time"
"strconv"
//from https://github.com/pplcc/plotext/
"log"
"os"
"github.com/360EntSecGroup-Skylar/excelize"
"github.com/pplcc/plotext/custplotter"
"gonum.org/v1/plot"
"github.com/pplcc/plotext"
"gonum.org/v1/plot/vg/vgimg"
"gonum.org/v1/plot/vg/draw"
)
// Len implements the Len method of the TOHLCVer interface.
func (TOHLCV TOHLCVs) Len() int {
return len(TOHLCV)
func main() {
//read excel file******************************************
xlsx, err := excelize.OpenFile("/media/Snaps/test snaps.xlsm")
if err != nil {
fmt.Println(err)
return
}
//read all rows into df
df := xlsx.GetRows("ticker_2")
type TOHLCVer interface {
// Len returns the number of time, open, high, low, close, volume tuples.
Len() int
// TOHLCV returns an time, open, high, low, close, volume tuple.
TOHLCV(int) (float64, float64, float64, float64, float64, float64)
}
type TOHLCVs []struct{ T, O, H, L, C, V float64 }
// Len implements the Len method of the TOHLCVer interface.
func (TOHLCV TOHLCVs) Len() int {
return len(TOHLCV)
}
df3 := make(TOHLCVs, 60) // create slice for 60 rows
idx := 0
this code is adapted from:
https://github.com/pplcc/plotext/blob/master/custplotter/tohlcv.go

Function declarations need to be moved out of other functions, Like this:
package main
import (
"fmt"
"github.com/360EntSecGroup-Skylar/excelize"
)
type TOHLCVer interface {
// Len returns the number of time, open, high, low, close, volume tuples.
Len() int
// TOHLCV returns an time, open, high, low, close, volume tuple.
TOHLCV(int) (float64, float64, float64, float64, float64, float64)
}
type TOHLCVs []struct{ T, O, H, L, C, V float64 }
// Len implements the Len method of the TOHLCVer interface.
func (TOHLCV TOHLCVs) Len() int {
return len(TOHLCV)
}
func main() {
//read excel file******************************************
xlsx, err := excelize.OpenFile("/media/Snaps/test snaps.xlsm")
if err != nil {
fmt.Println(err)
return
}
//read all rows into df
df := xlsx.GetRows("ticker_2")
df3 := make(TOHLCVs, 60) // create slice for 60 rows
idx := 0
}
Type declarations can be inside of a function. But, in this case, it makes more sense for them to be outside. There are some situations where it's helpful to declare a function inside another function:
Passing a function as an argument: https://play.golang.org/p/4NgeUvsexto
Assigning an anonymous function to a variable: https://play.golang.org/p/r1DF9_iP0-k
(I'm not sure about the exact logic you're looking for - the above code doesn't do anything yet. I'll also caution against creating an interface unless you needed it.)

So based on answer of #Tyler Bui-Palsulich and #aec my code now looks like below, and no more error messages :-), thanks all !
package main
import (
"fmt"
"time"
"strconv"
//from https://github.com/pplcc/plotext/
"log"
"os"
"github.com/360EntSecGroup-Skylar/excelize"
"github.com/pplcc/plotext/custplotter"
//"github.com/pplcc/plotext/examples"
"gonum.org/v1/plot"
"github.com/pplcc/plotext"
"gonum.org/v1/plot/vg/vgimg"
"gonum.org/v1/plot/vg/draw"
)
// Len implements the Len method of the TOHLCVer interface.
//func (TOHLCV TOHLCVs) Len() int {
// return len(TOHLCV)
//}
type TOHLCVer interface {
// Len returns the number of time, open, high, low, close, volume tuples.
Len() int
// TOHLCV returns an time, open, high, low, close, volume tuple.
TOHLCV(int) (float64, float64, float64, float64, float64, float64)
}
type TOHLCVs []struct{ T, O, H, L, C, V float64 }
// Len implements the Len method of the TOHLCVer interface.
func (TOHLCV TOHLCVs) Len() int {
return len(TOHLCV)
}
// TOHLCV implements the TOHLCV method of the TOHLCVer interface.
func (TOHLCV TOHLCVs) TOHLCV(i int) (float64, float64, float64, float64, float64, float64) {
return TOHLCV[i].T, TOHLCV[i].O, TOHLCV[i].H, TOHLCV[i].L, TOHLCV[i].C, TOHLCV[i].V
}
func main() {
start := time.Now()
//create data for each chart****************************************************
//******************************************************************************
//read excel file******************************************
xlsx, err := excelize.OpenFile("/media/hugues/M.2 windows/Hugues/Snaps/test snaps.xlsm")
if err != nil {
fmt.Println(err)
return
}
//read all rows into df
df := xlsx.GetRows("ticker_2")
df3 := make(TOHLCVs, 60) // create slice for 60 rows
idx := 0
for _, row := range df[1:61] { // read 60 rows
df3[idx].T, err = strconv.ParseFloat(row[28], 64)
df3[idx].O, err = strconv.ParseFloat(row[29], 64)
df3[idx].H, err = strconv.ParseFloat(row[30], 64)
df3[idx].L, err = strconv.ParseFloat(row[31], 64)
df3[idx].C, err = strconv.ParseFloat(row[32], 64)
df3[idx].V, err = strconv.ParseFloat(row[33], 64)
idx++
}

Related

How to determine the element type of slice interface{}?

I have the following code to double the slice.
func doubleSlice(s []int) []int {
t := make([]int, len(s), (cap(s) + 1) * 2 )
for i := range s {
t[i] = s[i]
}
return t
}
I want to make the func to double any type of slice. And I need to know the element type first.
func showInterfaceItem(s interface{}) interface{} {
if reflect.TypeOf(s).Kind() != reflect.Slice {
fmt.Println("The interface is not a slice.")
return
}
var t interface{}
newLen := reflect.ValueOf(s).Len()
newCap := (cap(reflect.ValueOf(s).Cap()) + 1) * 2
t = make([]reflect.TypeOf(s), newLen, newCap)
return t
}
The reflect.TypeOf(s) return the type of interface{}, not the type of element. How can I get the element type of slice interface?
You can use reflect.TypeOf(s).Elem()
to get the type of element of slice.
package main
import (
"fmt"
"reflect"
)
func doubleSlice(s interface{}) interface{} {
if reflect.TypeOf(s).Kind() != reflect.Slice {
fmt.Println("The interface is not a slice.")
return nil
}
v := reflect.ValueOf(s)
newLen := v.Len()
newCap := (v.Cap() + 1) * 2
typ := reflect.TypeOf(s).Elem()
t := reflect.MakeSlice(reflect.SliceOf(typ), newLen, newCap)
reflect.Copy(t, v)
return t.Interface()
}
func main() {
xs := doubleSlice([]string{"foo", "bar"}).([]string)
fmt.Println("data =", xs, "len =", len(xs), "cap =", cap(xs))
ys := doubleSlice([]int{3, 1, 4}).([]int)
fmt.Println("data =", ys, "len =", len(ys), "cap =", cap(ys))
}
The output will be:
data = [foo bar] len = 2 cap = 6
data = [3 1 4] len = 3 cap = 8
Check it in: Go Playground
This is doable in golang and takes me whole day to discover the pattern.
Firstly, we want to get a pointer of slice to make gorm happy, which is has type "*[]Obj". To achieve that in golang, we can create a make wrapper like so:
func makeWrapper(cap uint) interface{} {
arr:= make([]Sth, 0, cap)
return &arr
}
Notice that, we can't directly reference the maked value, which might be the book keeping data need to have a stack space to store.
//Not working example
func makeWrapper(cap uint) interface{} {
return &(make([]Sth, 0, cap))
}
And as the answer before, the reflect.MakeSlice(reflect.SliceOf(typ), 0, capacity).Interface() returns interface{[]Sth}. (the typ here is refer to reflect.TypeOf(Sth{}), which equiv to typ == reflect.TypeOf(v))
Thus we need to create a return object of *[]Sth and the value inside is a slice []Sth with capacity. After understanding the objective, we can have this code:
package main
import (
"reflect"
)
type Sth struct {
a, b string
}
func main() {
af:= createSlice(Sth{})
arr := makeWrapper(10).(*[]Sth)
println(reflect.TypeOf(arr).String())
// equiv to makeWrapper, but we do it via reflection
arr = af(10).(*[]Sth)
println(reflect.TypeOf(arr).String())
}
func makeWrapper(cap uint) interface{} {
arr:= make([]Sth, 0, cap)
return &arr
}
func createSlice(v interface{}) func(int) interface{} {
var typ reflect.Type
if reflect.ValueOf(v).Kind() == reflect.Ptr {
typ = reflect.ValueOf(v).Elem().Type()
} else if reflect.ValueOf(v).Kind() == reflect.Struct {
typ = reflect.TypeOf(v)
} else {
panic("only support instance of struct or pointer of that instance")
}
return func(capacity int) interface{}{
// create the outer object saves our slice
outerObj:=reflect.New(reflect.SliceOf(typ))
// create the slice and save it to return
outerObj.Elem().Set(reflect.MakeSlice(reflect.SliceOf(typ), 0, capacity))
// retrive the interface of outer object
return outerObj.Interface()
}
}

Go: How to embed same interface twice?

Suppose we have something like this:
type ReadHandler interface {
Reader
Reader
}
Obviously, it will cause ambiguity when we call members of Reader interface on instances of ReadHandeler. So how can we achieve this in Golang?
1- Use io.MultiReader, see func MultiReader(readers ...Reader) Reader Docs:
MultiReader returns a Reader that's the logical concatenation of the
provided input readers. They're read sequentially. Once all inputs
have returned EOF, Read will return EOF. If any of the readers
return a non-nil, non-EOF error, Read will return that error.
2- or name it:
type ReadHandler interface {
Read(p []byte) (n int, err error)
Read2(p []byte) (n int, err error)
}
or:
type ReadHandler interface {
io.Reader
Read2(p []byte) (n int, err error)
}
Demonstration working sample code:
package main
import (
"errors"
"fmt"
"io"
)
func main() {
s := my{[]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, []byte{10, 20, 30, 40, 50}}
buf := make([]byte, 5)
n, e := s.Read(buf)
fmt.Println(n, e, buf)
n, e = s.Read2(buf)
fmt.Println(n, e, buf)
}
type ReadHandler interface {
io.Reader
Read2(p []byte) (n int, err error)
}
type my struct {
buf []byte
buf2 []byte
}
func (t *my) Read(p []byte) (n int, err error) {
if len(p) > len(t.buf) {
return 0, errors.New("len(p)>len(buf)")
}
m := copy(p, t.buf)
return m, nil
}
func (t *my) Read2(p []byte) (n int, err error) {
if len(p) > len(t.buf2) {
return 0, errors.New("len(p)>len(buf2)")
}
m := copy(p, t.buf2)
return m, nil
}
Output:
5 <nil> [1 2 3 4 5]
5 <nil> [10 20 30 40 50]
3- name it:
Looking for a general solution to embed an interface (with any number
of methods), twice in a struct.
type my struct {
io.Reader
Rdr2 io.Reader
}
or
type my struct {
Rdrs []io.Reader
}

Generate crypto Random Integer beetwen min, max values

I trying to generate a random number beetwen a min value and a max value,
but seems I'm lost with this, what is wrong?
package main
import (
"crypto/rand"
"encoding/binary"
"fmt"
)
func genRandNum(min, max int8) int {
var num int8
binary.Read(rand.Reader, binary.LittleEndian, &num)
return int(num*(max-min)+min)
}
func main() {
// trying to get a random number beetwen -10 and 10
fmt.Println(genRandNum(-10,10))
}
How about this
func main() {
fmt.Println(genRandNum(-10, 10))
}
func genRandNum(min, max int64) int64 {
// calculate the max we will be using
bg := big.NewInt(max - min)
// get big.Int between 0 and bg
// in this case 0 to 20
n, err := rand.Int(rand.Reader, bg)
if err != nil {
panic(err)
}
// add n to min to support the passed in range
return n.Int64() + min
}
Go play

invalid operation: s[k] (index of type *S)

I want to define a type like this:
type S map[string]interface{}
and I want add a method to the type like this:
func (s *S) Get( k string) (interface {}){
return s[k]
}
when the program runs, there was a error like this:
invalid operation: s[k] (index of type *S)
So, how do I define the type and add the method to the type?
For example,
package main
import "fmt"
type S map[string]interface{}
func (s *S) Get(k string) interface{} {
return (*s)[k]
}
func main() {
s := S{"t": int(42)}
fmt.Println(s)
t := s.Get("t")
fmt.Println(t)
}
Output:
map[t:42]
42
Maps are reference types, which contain a pointer to the underlying map, so you normally wouldn't need to use a pointer for s. I've added a (s S) Put method to emphasize the point. For example,
package main
import "fmt"
type S map[string]interface{}
func (s S) Get(k string) interface{} {
return s[k]
}
func (s S) Put(k string, v interface{}) {
s[k] = v
}
func main() {
s := S{"t": int(42)}
fmt.Println(s)
t := s.Get("t")
fmt.Println(t)
s.Put("K", "V")
fmt.Println(s)
}
Output:
map[t:42]
42
map[t:42 K:V]

Looking for Go equivalent of scanf

I'm looking for the Go equivalent of scanf().
I tried with following code:
1 package main
2
3 import (
4 "scanner"
5 "os"
6 "fmt"
7 )
8
9 func main() {
10 var s scanner.Scanner
11 s.Init(os.Stdin)
12 s.Mode = scanner.ScanInts
13 tok := s.Scan()
14 for tok != scanner.EOF {
15 fmt.Printf("%d ", tok)
16 tok = s.Scan()
17 }
18 fmt.Println()
19 }
I run it with input from a text with a line of integers.
But it always output -3 -3 ...
And how to scan a line composed of a string and some integers?
Changing the mode whenever encounter a new data type?
The Package documentation:
Package scanner
A general-purpose scanner for UTF-8
encoded text.
But it seems that the scanner is not for general use.
Updated code:
func main() {
n := scanf()
fmt.Println(n)
fmt.Println(len(n))
}
func scanf() []int {
nums := new(vector.IntVector)
reader := bufio.NewReader(os.Stdin)
str, err := reader.ReadString('\n')
for err != os.EOF {
fields := strings.Fields(str)
for _, f := range fields {
i, _ := strconv.Atoi(f)
nums.Push(i)
}
str, err = reader.ReadString('\n')
}
r := make([]int, nums.Len())
for i := 0; i < nums.Len(); i++ {
r[i] = nums.At(i)
}
return r
}
Improved version:
package main
import (
"bufio"
"os"
"io"
"fmt"
"strings"
"strconv"
"container/vector"
)
func main() {
n := fscanf(os.Stdin)
fmt.Println(len(n), n)
}
func fscanf(in io.Reader) []int {
var nums vector.IntVector
reader := bufio.NewReader(in)
str, err := reader.ReadString('\n')
for err != os.EOF {
fields := strings.Fields(str)
for _, f := range fields {
if i, err := strconv.Atoi(f); err == nil {
nums.Push(i)
}
}
str, err = reader.ReadString('\n')
}
return nums
}
Your updated code was much easier to compile without the line numbers, but it was missing the package and import statements.
Looking at your code, I noticed a few things. Here's my revised version of your code.
package main
import (
"bufio"
"fmt"
"io"
"os"
"strconv"
"strings"
"container/vector"
)
func main() {
n := scanf(os.Stdin)
fmt.Println()
fmt.Println(len(n), n)
}
func scanf(in io.Reader) []int {
var nums vector.IntVector
rd := bufio.NewReader(os.Stdin)
str, err := rd.ReadString('\n')
for err != os.EOF {
fields := strings.Fields(str)
for _, f := range fields {
if i, err := strconv.Atoi(f); err == nil {
nums.Push(i)
}
}
str, err = rd.ReadString('\n')
}
return nums
}
I might want to use any input file for scanf(), not just Stdin; scanf() takes an io.Reader as a parameter.
You wrote: nums := new(vector.IntVector), where type IntVector []int. This allocates an integer slice reference named nums and initializes it to zero, then the new() function allocates an integer slice reference and initializes it to zero, and then assigns it to nums. I wrote: var nums vector.IntVector, which avoids the redundancy by simply allocating an integer slice reference named nums and initializing it to zero.
You didn't check the err value for strconv.Atoi(), which meant invalid input was converted to a zero value; I skip it.
To copy from the vector to a new slice and return the slice, you wrote:
r := make([]int, nums.Len())
for i := 0; i < nums.Len(); i++ {
r[i] = nums.At(i)
}
return r
First, I simply replaced that with an equivalent, the IntVector.Data() method: return nums.Data(). Then, I took advantage of the fact that type IntVector []int and avoided the allocation and copy by replacing that by: return nums.
Although it can be used for other things, the scanner package is designed to scan Go program text. Ints (-123), Chars('c'), Strings("str"), etc. are Go language token types.
package main
import (
"fmt"
"os"
"scanner"
"strconv"
)
func main() {
var s scanner.Scanner
s.Init(os.Stdin)
s.Error = func(s *scanner.Scanner, msg string) { fmt.Println("scan error", msg) }
s.Mode = scanner.ScanInts | scanner.ScanStrings | scanner.ScanRawStrings
for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
txt := s.TokenText()
fmt.Print("token:", tok, "text:", txt)
switch tok {
case scanner.Int:
si, err := strconv.Atoi64(txt)
if err == nil {
fmt.Print(" integer: ", si)
}
case scanner.String, scanner.RawString:
fmt.Print(" string: ", txt)
default:
if tok >= 0 {
fmt.Print(" unicode: ", "rune = ", tok)
} else {
fmt.Print(" ERROR")
}
}
fmt.Println()
}
}
This example always reads in a line at a time and returns the entire line as a string. If you want to parse out specific values from it you could.
package main
import (
"fmt"
"bufio"
"os"
"strings"
)
func main() {
value := Input("Please enter a value: ")
trimmed := strings.TrimSpace(value)
fmt.Printf("Hello %s!\n", trimmed)
}
func Input(str string) string {
print(str)
reader := bufio.NewReader(os.Stdin)
input, _ := reader.ReadString('\n')
return input
}
In a comment to one of my answers, you said:
From the Language Specification: "When
memory is allocated to store a value,
either through a declaration or make()
or new() call, and no explicit
initialization is provided, the memory
is given a default initialization".
Then what's the point of new()?
If we run:
package main
import ("fmt")
func main() {
var i int
var j *int
fmt.Println("i (a value) = ", i, "; j (a pointer) = ", j)
j = new(int)
fmt.Println("i (a value) = ", i, "; j (a pointer) = ", j, "; *j (a value) = ", *j)
}
The declaration var i int allocates memory to store an integer value and initializes the value to zero. The declaration var j *int allocates memory to store a pointer to an integer value and initializes the pointer to zero (a nil pointer); no memory is allocated to store an integer value. We see program output similar to:
i (a value) = 0 ; j (a pointer) = <nil>
The built-in function new takes a type T and returns a value of type *T. The memory is initialized to zero values. The statement j = new(int) allocates memory to store an integer value and initializes the value to zero, then it stores a pointer to this integer value in j. We see program output similar to:
i (a value) = 0 ; j (a pointer) = 0x7fcf913a90f0 ; *j (a value) = 0
The latest release of Go (2010-05-27) has added two functions to the fmt package: Scan() and Scanln(). They don't take any pattern string. like in C, but checks the type of the arguments instead.
package main
import (
"fmt"
"os"
"container/vector"
)
func main() {
numbers := new(vector.IntVector)
var number int
n, err := fmt.Scan(os.Stdin, &number)
for n == 1 && err == nil {
numbers.Push(number)
n, err = fmt.Scan(os.Stdin, &number)
}
fmt.Printf("%v\n", numbers.Data())
}

Resources