---
# System prepended metadata

title: Go
tags: [go]

---

# Go
###### tags: `go`

## PrintError
``` go
"runtime"

func printError(err error) {
    if err != nil {
       fmt.Println(err)
    }
}

func printError(err error, str ...string) {
    if err != nil {
        pc, _, _, _ := runtime.Caller(1)
        fmt.Println(" -> ", runtime.FuncForPC(pc).Name())
        fmt.Println("   - ", err)
        for _, s := range str {
            fmt.Println("     - ", s)
        }
    }
}

## fmt
``` go
// 清空螢幕
fmt.Print("\033[H\033[2J")



```

``` go
func printStruct(item interface{}) {
    v := reflect.ValueOf(item)
    t := reflect.TypeOf(item)

    fmt.Println("Type:", t)
    fmt.Println("Value:", v)

    if v.Kind() == reflect.Slice {
        for i := 0; i < v.Len(); i++ {
            fmt.Printf("Element %d: %v\n", i, v.Index(i).Interface())
        }
    } else if v.Kind() == reflect.Map {
        for _, key := range v.MapKeys() {
            value := v.MapIndex(key)
            fmt.Printf("Key: %v, Value: %v\n", key, value)
        }
    } else if v.Kind() == reflect.Struct {
        fmt.Println("Struct fields:")
        for i := 0; i < v.NumField(); i++ {
            field := t.Field(i)
            value := v.Field(i)
            fmt.Printf("Field %s: %v\n", field.Name, value)
        }
    } else {
        fmt.Println("Unsupported type:", t)
    }
}

```

改檔名

``` go
err := os.Rename(oldName, newName)

```

## filepath
``` go

dir, file := filepath.Split("/go/go.mod")

filepath.Join(dir, path)


"path/filepath"

var (
    RootDirPath = getRootDirPath()
    TempDirPath = getTempDirPath()

    staticPath = filepath.Join(RootDirPath, `static`)
    htmlPath   = filepath.Join(RootDirPath, `templates`, `*.html`)
)

func getRootDirPath() string {
	path, err := os.Executable()
	printError(err)
	if strings.HasPrefix(strings.ToLower(filepath.Dir(path)), strings.ToLower(os.TempDir())) {
	    path, err = os.Getwd()
		printError(err)
		return path + `\`
	}
	path = filepath.Dir(path)
	if IsWin {
		return path + `\`
	}
	return path + `/`
}


func getTempDirPath() string {
    if runtime.GOOS == "windows" {
        return `z:\Temp\`
    }
    return `/tmp/`
}

```

### fileExist
``` go
func fileExist(file string) bool {
  if _, err := os.Stat(file); err != nil {
    if os.IsNotExist(err) {
      return false
    }
  }
  return true
}
```

### list file
``` go
//"path/filepath"
func listFile(path string) []string {
    var files []string
    err := filepath.Walk(path, func(p string, info os.FileInfo, err error) error {
        if Match(p, `.*\.jpg`) {
            files = append(files, p)
        }
        return nil
    })
    printError(err)
    return files[1:]
}


"io/ioutil"

func listFile(filePath string) []string {
    var files []string
    fs, err := ioutil.ReadDir(filePath)
    printError(err)

    for _, f := range fs {
        files = append(files, f.Name())
    }
    return files
}
```
## string

### strip
`strings.TrimSpace(str)`

### string <-> int float64
``` go
"strconv"

func to_i(s string) int {
    i, _ := strconv.Atoi(s)
    return i
}

func to_f(s string) float64 {
    fn, _ := strconv.ParseFloat(s, 64)
    return fn
}
func to_s(i int) string {
    return strconv.Itoa(i)
}

func toHex(i int) string {
    return fmt.Sprintf("%x", i)
}

func To_b(s string) bool {
	b, _ := strconv.ParseBool(s)
	return b
}
```

### fill_zero
``` go
func Rjust(str string, n int, fill string) string {
	if len(str) < n {
		return strings.Repeat(fill, n-len(str)) + str
	}
	return str
}

func Ljust(str string, n int, fill string) string {
	return str + strings.Repeat(fill, n)
}
```
``` go
func removeNbsp(str string) string {
    return strings.Replace(str, "\u00A0", "", -1)
}

func removeNbsp(str string) string {
    var txt string
    for _, b := range []byte(str) {
        if b != 194 && b != 160 {
            txt += string(b)
        }
    }
    return txt
}


func removeSapce(str string) string {
    strs := `.,，、；。：:！!〝〞「」“”"《》『』（）～~?？【】 #[]-…％%·/()`
    for _, s := range strings.Split(strs, "") {
        str = strings.Replace(str, s, " ", -1)
    }

    str = strings.Replace(str, "\n", " ", -1)
    str = strings.Replace(str, "\r\n", " ", -1)

    return str
}
```


### input
``` go
func getInput() {
    var key string
    fmt.Scanln(&key)
    return key
}

reader := bufio.NewReader(os.Stdin)
fmt.Print("file: ")
ipt, _ := reader.ReadString('\n')
input := strings.TrimSuffix(ipt, "\n")
return input
```

### continue
``` go
fmt.Print("Press 'Enter' to continue...")
bufio.NewReader(os.Stdin).ReadBytes('\n')
```

### stringCH
``` go
"unicode"

func checkWordsCH(words string) {
    for _, w := range words {
        if unicode.Is(unicode.Han, w) {
            
        }
    }
}

func SplitZh(str string) []string {
    var results []string
    var idx int
    for idx < len(str) {
        var add int
        if IsHan(str[idx]) {
            add = 3
        } else {
            add = 1
        }

        results = append(results, str[idx:idx+add])
        idx += add
    }
    return results
}

func IsHan(b byte) bool {
    return ord(string(b)) > 127
}

func ord(s string) int {
    return int([]byte(s)[0])
}
```


### chr <-> ord
``` go
func ord(s string) int {
    return int([]byte(s)[0])
}
func chr(i int) string {
    return fmt.Sprintf("%c", rune(i))
}

```

### string reverse
``` go
func strReverse(str string) string {
    var comb string
    for i := len(str) - 1; i >= 0; i-- {
        comb += string(str[i])
    }
    return comb
}
```

### index
``` go
func strIndex(str string, bstr string) int {
    arr := strings.Split(str, "")
    for i, e := range arr {
        if bstr == string(e) {
            return i
        }
    }
    return -1
}
func strIndexS(str string, bstr string) []int {
    arr := strings.Split(str, "")
    is := []int{}
    for i, e := range arr {
        if bstr == string(e) {
            is = append(is, i)
        }
    }
    return is
}
```
### slice ch string
``` go
func sliceChString(ch string, start int, end int) string {
    var size int
    var chs = []rune(ch)
    if len(chs) > end && end > start {
        result := ""
        for _, e := range chs {
            str := string(e)
            if ord(str) > 127 {
                size += 2
            } else {
                size += 1
            }
            result += str
            if size > (end-start)*2 {
                break
            }
        }
        return result
    }
    return ch
}
```

``` go
func strEachSlice(str string, l int) []string {
    arr := strings.Split(str, "")
    var ar []string
    size := len(arr)
    for i := 0; i < size; i = i + l {
        j := i + l
        if j > size {
            j = size
        }
        ar = append(ar, strings.Join(arr[i:j], ""))
    }
    return ar
}

```

## run Cmd
``` go
func runCmd(cmd string) {
    c, err := exec.Command(`bash`, `-c`, cmd).CombinedOutput()
    printError(err)
}

func runCmd(cmd string) {
    c, err := exec.Command(`cmd`, `/c`, cmd).CombinedOutput()
    printError(err)
}

func RunCmd(cmd string) {
    var bash, args = `bash`, `-c`
    if runtime.GOOS == "windows" {
        bash, args = `cmd`, `/c`
    }
    exec.Command(bash, args, cmd).CombinedOutput()
}

func runCmd(cmd string) {
    c := exec.Command(cmd)
    _, err := c.Output()
    printError(err)
}

"bytes"
"io/ioutil"
"os/exec"
"strings"

"golang.org/x/text/encoding/traditionalchinese"
"golang.org/x/text/transform"

func RunPS(cmd string) []string {
    big5utf8 := func(str string) string {
        reader := transform.NewReader(bytes.NewReader([]byte(str)), traditionalchinese.Big5.NewDecoder())
        out, _ := ioutil.ReadAll(reader)
        return string(out)
    }
    c, err := exec.Command("powershell", "/c", cmd).CombinedOutput()
    printError(err)
    content := big5utf8(string(c))
    return strings.Split(content, "\n")
}

// 亂碼

func big5utf8(str string) string {
    reader := transform.NewReader(bytes.NewReader([]byte(str)), traditionalchinese.Big5.NewDecoder())
    out, _ := ioutil.ReadAll(reader)
    return string(out)
}

```

## crawler
``` go

"github.com/anaskhan96/soup"
"fmt"
"io/ioutil"
"net/http"

doc := getDoc(url)

func getDoc(url string) soup.Root {
    // req, err := http.NewRequest("GET", url, nil)
    // printError(err)
    // res, err := http.DefaultClient.Do(req)
    // printError(err)

    // cookie := http.Cookie{
    //    Name:  "over18",
    //    Value: "1",
    //}
    // req.AddCookie(&cookie)   
    
    res, err := http.Get(url)
    printError(err)

    res.Header.Set(`User-Agent`, `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36`)

    body, err := ioutil.ReadAll(res.Body)
    printError(err)
    //save(resp, "/tmp/log.html")
    return soup.HTMLParse(string(body))
}
```

### table
``` go
var data [][]string
info := doc.Find("table", "class", "auto-style4")
tables := info.FindAll("tr")
for _, table := range tables {
    var tmp []string
    for _, td := range table.FindAll("td", "class", "auto-style5") {
        tmp = append(tmp, td)
    }
    data = append(data, tmp)
}
```

### class with blank
``` go
for _, div := range doc.FindAll("div") {
    div.Attrs()["class"] == "grid grid-1 grid-2"
}
```



``` go
"github.com/sclevine/agouti"

page, driver := openBrowser()
defer driver.Stop()

page.Navigate(url)

doc := getDoc(page)


func openBrowser(screenX, screenY int) (*agouti.Page, *agouti.WebDriver) {
    driver := agouti.ChromeDriver(
        agouti.ChromeOptions("args", []string{
            "--headless",
            "--disable-gpu",
            "--disable-notifications",
            //"--no-sandbox",
            fmt.Sprintf("--window-size=%v,%v", screenX, screenY),
        }),
    )
    err := driver.Start()
    printError(err)
    page, err := driver.NewPage()
    printError(err)
    return page, driver
}

func getDoc(page selenium.WebDriver) soup.Root {
    resp, _ := page.HTML()
    return soup.HTMLParse(resp)
}

func runJs(page *agouti.Page) string{
    js := `window.scrollTo(0,window.scrollY+window.innerHeight*.9);`
    var text string
    page.RunScript(js, nil, &text)
    return text
}

func sendKeys(page *agouti.Page, key string) {
    var k string
    switch key {
    case "Home":
        k = "\uE011"
    case "pageDown":
        k = "\uE00F"
    }
    page.Find("html").SendKeys(k)
   
 // NULL        = "\uE000", CANCEL     = "\uE001", HELP     = "\uE002"
 // BACK_SPACE  = "\uE003", TAB        = "\uE004", CLEAR    = "\uE005"
 // RETURN      = "\uE006", ENTER      = "\uE007", SHIFT    = "\uE008"
 // CONTROL     = "\uE009", ALT        = "\uE00A", PAUSE    = "\uE00B"
 // ESCAPE      = "\uE00C", SPACE      = "\uE00D", PAGE_UP  = "\uE00E"
 // PAGE_DOWN   = "\uE00F", END        = "\uE010", HOME     = "\uE011"
 // LEFT        = "\uE012", ARROW_LEFT = "\uE012", ARROW_UP = "\uE013"
 // ARROW_RIGHT = "\uE014", ARROW_DOWN = "\uE015", INSERT   = "\uE016"
 // DELETE      = "\uE017", SEMICOLON  = "\uE018", EQUALS   = "\uE019"
 // NUMPAD0     = "\uE01A", NUMPAD1    = "\uE01B", NUMPAD2  = "\uE01C"
 // NUMPAD3     = "\uE01D", NUMPAD4    = "\uE01E", NUMPAD5  = "\uE01F"
 // NUMPAD6     = "\uE020", NUMPAD7    = "\uE021", NUMPAD8  = "\uE022"
 // NUMPAD9     = "\uE023", MULTIPLY   = "\uE024", ADD      = "\uE025"
 // SEPARATOR   = "\uE026", SUBTRACT   = "\uE027", DECIMAL  = "\uE028"
 // DIVIDE      = "\uE029", F1         = "\uE031", F2       = "\uE032"
 // F3          = "\uE033", F4         = "\uE034", F5       = "\uE035"
 // F6          = "\uE036", F7         = "\uE037", F8       = "\uE038"
 // F9          = "\uE039", F10        = "\uE03A", F11      = "\uE03B"
 // F12         = "\uE03C", META       = "\uE03D", COMMAND  = "\uE03D"


}
```

``` go
"github.com/tebeka/selenium"
"github.com/tebeka/selenium/chrome"

func OpenBrowser(screenX, screenY int) (selenium.WebDriver, *selenium.Service) {
    opts := []selenium.ServiceOption{}
    caps := selenium.Capabilities{"browserName": "chrome"}
    // imagCaps := map[string]interface{}{"profile.managed_default_content_settings.images": 2}
    chromeCaps := chrome.Capabilities{
        // Prefs: imagCaps,
        Path: "",
        Args: []string{
            fmt.Sprintf("--window-size=%v,%v", screenX, screenY),
            fmt.Sprintf(`--user-agent=%s`, `Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240`),
            "--ignore-certificate-errors",
            "--disable-gpu",
            "--disable-notifications",
            "--no-sandbox",
            // "--headless",
            // `--user-data-dir=z:\chrome`,
        },
    }
    caps.AddChrome(chromeCaps)
    port := 9515
    driver, err := selenium.NewChromeDriverService("chromedriver.exe", port, opts...)
    printError(err)
    page, err := selenium.NewRemote(caps, fmt.Sprintf("http://localhost:%d/wd/hub", port))
    printError(err)

    return page, driver
}


func getDoc(page selenium.WebDriver) soup.Root {
    resp, _ := page.PageSource()
    return soup.HTMLParse(resp)
}

func locateCss(page selenium.WebDriver, css string) []selenium.WebElement {
    eles, err := page.FindElements(selenium.ByCSSSelector, css)
    printError(err)
    return eles
}

func inputText(page selenium.WebDriver, css, inputText string, i int) {
    for idx, input := range locateCss(page, css) {
        if i == idx {
            input.Clear()
            input.SendKeys(inputText)
        }
    }
    script.Sleep(delay)
}

func click(page selenium.WebDriver, css string, i int) {
    elms := locateCss(page, css)
    // fmt.Println(len(elms))
    for idx, elm := range elms {
        // fmt.Println(elm)
        if i == idx {
            elm.Click()
        }
    }
    script.Sleep(delay)
}

func getScreenshot(page selenium.WebDriver, imagePath string, px, py, width, height int) {
    imgByte, err := page.Screenshot()

    printError(err)
    img, _, err := image.Decode(bytes.NewReader(imgByte))
    printError(err)

    file, _ := os.Create(imagePath)
    defer file.Close()

    croppedImg, err := cutter.Crop(img, cutter.Config{
        Anchor: image.Point{px, py},
        Width:  width,
        Height: height,
    })
    printError(err)
    png.Encode(file, croppedImg)
}

```
## IO

``` go
"io/ioutil"

func ReadFile(path string) string {
	bytes, err := os.ReadFile(path)
	printError(err)
	return string(bytes)
}

func WriteFile(content, path string) {
	err := os.WriteFile(path, []byte(content), 0777)
	printError(err)
}

func ReadLines(path string) []string {
	strs := ReadFile(path)
	return strings.Split(string(strs), "\r\n")
}

func WriteLines(lines []string, path string) {
	WriteFile(strings.Join(lines, "\n"), path)
}

//file.WriteString("\xEF\xBB\xBF")


"golang.org/x/text/encoding/traditionalchinese"
"golang.org/x/text/transform"

"io/ioutil"
"strings"
"bytes"

func readFile(path string) []string {
    dat, err := ioutil.ReadFile(path)
    printError(err)
    var lines []string
    win16be := unicode.UTF16(unicode.BigEndian, unicode.IgnoreBOM)
    utf16bom := unicode.BOMOverride(win16be.NewDecoder())
    unicodeReader := transform.NewReader(bytes.NewReader(dat), utf16bom)
    decoded, err := ioutil.ReadAll(unicodeReader)
    printError(err)

    for _, l := range strings.Split(string(dat), "\n") {
        //str, _, _ := transform.String(traditionalchinese.Big5.NewDecoder(), str2)
        //str2, _, _ := transform.String(traditionalchinese.Big5.NewEncoder(), str)
        lines = append(lines, l)
    }
    return lines
}

//win utf-16 le to utf-8
import "github.com/malexdev/utfutil"
d, _ := utfutil.ReadFile("txt", utfutil.UTF8)
c := string(d)


func appendFile(data []string, path string ) {
    f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
    printError(err)
    defer f.Close()

    for _, line := range data {
        f.WriteString(line + "\n")
    }
}

```
## Json
``` go
"encoding/json"
"io/ioutil"

ReadJson[Type](path)

func ReadJson[T any](path string) []T {
    b, err := os.ReadFile(path)
    printError(err)
    var jdata []T
    err = json.Unmarshal(b, &jdata)
    printError(err)
    return jdata
}

func WriteJson(datas any, path string) {
    b, err := json.MarshalIndent(datas, "", "  ") //json.Marshal
    printError(err)

    err = os.WriteFile(path, b, 0777)
    printError(err)
}

func ReadJsonStr[T any](str string) T {
	var jdata T
	err := json.Unmarshal([]byte(str), &jdata)
	printError(err)
	return jdata
}

type Employee struct {
    Name string
    Age  int
}

type List struct {
    ID []*Employee
}

func ReadJson(path string) []Comic {
    b, err := ioutil.ReadFile(path)
    printError(err)
    var jdata []Comic
    err = json.Unmarshal([]byte(b), &jdata)
    printError(err)
    return jdata
}


func ReadJson(path string) []Comic {
    b, err := ioutil.ReadFile(path)
    printError(err)
    str := script.DeBase64(string(b))

    var jdata []Comic
    err = json.Unmarshal([]byte(str), &jdata)
    printError(err)
    return jdata
}

func WriteJson(datas any, path string) {
    b, err := json.Marshal(datas)
    printError(err)
    str := script.EnBase64(string(b))
    err = ioutil.WriteFile(path, []byte(str), 0777)
    printError(err)
}

```


``` go
var c map[string][]map[string]interface{}
var cs []string
json.Unmarshal([]byte(str), &c)

t := c["content_elements"]

for _, e := range t {
    c := e["content"]
    if c != nil {
        cs = append(cs, fmt.Sprintf("%s", c))
    }
}
return cs
```

## time
``` go
monthTab := []string{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
monthTab = []string{"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"}
mTab := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
```

``` go
func GetNow() time.Time {
    return time.Now()
}

func GetTimeStamp() string {
    // t.Add(time.Second * afterSec)
    t := time.Now()
    return fmt.Sprintf("%d-%02d-%02d %02d:%02d:%02d", t.Year(), int(t.Month()), t.Day(), t.Hour(), t.Minute(), t.Second())
}

func GetTimeStamp() (string, int) {
    t := time.Now()
    return fmt.Sprintf(`%02d/%02d`, int(t.Month()), t.Day()), int(t.Unix())
}

func GetNextDay(year, month, day int) time.Time {
    // t = t.Add(time.Hour * time.Duration(add))
    return TimeTime(year, month, day).AddDate(0, 0, +1)
}

int(time.Weekday())

func GetWeek(year, month, day int) int {
    monthValue := []int{6, 2, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}[month-1]
    yearValue := year % 100
    centuryValue := []int{0, 5, 3, 1}[(year/100)%4]
    w := day + monthValue + yearValue + yearValue/4 + centuryValue
    if isLeapYear(year) && month <= 2 {
        w -= 1
    }
    return w % 7
}

func GetWeek2(year, month, day int) int {
    utime := getUnixTime(5024, 5, 8)
    // 0, 1, 1 // 禮拜四
    return (2 + ((utime - (-62135596800)) / 86400)) % 7
}

func getUnixTime(year, month, day int) int {
    date := fmt.Sprintf("%v-%02v-%02vT00:00:00.000+08:00", year, month, day)
    t, _ := time.Parse(time.RFC3339, date)
    return int(t.Unix())
}

func Range() {
    startDate := time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC)
    endDate := time.Date(2024, 12, 31, 0, 0, 0, 0, time.UTC)

    for date := startDate; date.Before(endDate) || date.Equal(endDate); date = date.AddDate(0, 0, 1) {
        fmt.Println(date)
    }
}


```

### Unix
``` go
// RFC822      = "02 Jan 06 15:04 MST"
// RFC822Z     = "02 Jan 06 15:04 -0700"
// RFC850      = "Monday, 02-Jan-06 15:04:05 MST"
// RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"
// RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700"
// RFC3339     = "2006-01-02T15:04:05Z07:00"
// RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"

func GetUnixTime(year, month, day, hour, min, sec int) time.Time {
    date := fmt.Sprintf("%v-%02v-%02vT%02v:%02v:%02v.000+08:00", year, month, day, hour, min, sec)
    fmt.Println(date)
    t, _ := time.Parse(time.RFC3339, date)
    return t
}


func GetUnixTime(t time.Time) int {
    return int(t.Unix())
}

func GetTimeTime(unixTime int64) time.Time {
    return time.Unix(unixTime, 0)
}

```

### date cal
``` go
package main

import (
    "fmt"
    "time"
)

var _ = fmt.Println

var (
    y1, m1, d1 = 2019, 9, 2
    y2, m2, d2 = 2020, 7, 20
)

func main() {
    days := getTwoDate(y1, m1, d1, y2, m2, d2)
    fmt.Println(days)

    y3, m3, d3 := getAfterDays(y1, m1, d1, days)
    fmt.Println(y3, m3, d3)
}

func unixTime(year, month, day int) int {
    date := fmt.Sprintf("%v-%.2v-%.2vT00:00:00.000Z", year, month, day)
    t, _ := time.Parse(time.RFC3339, date)
    return int(t.Unix())
}

func getTwoDate(y1, m1, d1, y2, m2, d2 int) int {
    s := unixTime(y2, m2, d2) - unixTime(y1, m1, d1)
    return s / 86400
}

func getAfterDays(year, month, day, days int) (int, int, int) {
    unix := int64(unixTime(year, month, day) + days*60*60*24 - 60*60*8)
    t := time.Unix(unix, 0)
    return t.Year(), int(t.Month()), t.Day()
}

func DaysInMonth(year, month int) int {
    days := []int{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    if isLeapYear(year) {
        days[1] = 29
    }
    return days[month-1]
}

func isLeapYear(year int) bool {
    return (year%4 == 0 && year%100 != 0) || (year%400 == 0 && year%3200 != 0)
}


```

### sleep
``` go
time.Sleep(1 * time.Second)

func sleep(t int) {
    time.Sleep(time.Duration(t) * time.Millisecond)
}

func Sleep(t int) {
    max := t * (1 + 3/10)
    min := t * (1 - 3/10)
    t = min + 
    
    
    
    .Intn(max-min+1)
    time.Sleep(time.Duration(t) * time.Millisecond)

```

### mtime
``` go
func statTimes(path string) {
    fi, err := os.Stat(path)
    printError(err)
    mtime := fi.ModTime().Unix()
    ctime := fi.Sys().(*syscall.Win32FileAttributeData).CreationTime
}
```


## ipconfig
``` go
func getLocalIp() []string {
    var result []string
    ifaces, _ := net.Interfaces()
    for _, i := range ifaces {
        addrs, _ := i.Addrs()
        for _, addr := range addrs {
            var gip net.IP
            switch v := addr.(type) {
            case *net.IPNet:
                gip = v.IP
            case *net.IPAddr:
                gip = v.IP
            }
            ip := gip.To4()
            if ip != nil && !ip.IsLoopback() {
                result = append(result, ip.String())
            }
        }
    }
    return result
}

```

##  checkUrl
``` go
func checkUrl(url string) bool {
    resp, err := http.Head(url)
    if err != nil {
        return false
    }
    if resp.StatusCode != http.StatusOK {
        return false
    }
    return true
}
```


## screenShot
``` go
"github.com/kbinani/screenshot"
"github.com/oliamb/cutter"
"image"
"image/png"

func getScreenshot(px, py, width, height int, imageName string) {
    bounds := screenshot.GetDisplayBounds(0)

    img, err := screenshot.CaptureRect(bounds)
    printError(err)
    file, _ := os.Create(imageName)
    defer file.Close()

    croppedImg, err := cutter.Crop(img, cutter.Config{
        Anchor: image.Point{px, py},
        Width:  width,
        Height: height,
    })

    png.Encode(file, croppedImg)
    sleep(delay)
}
```

``` go
func ThresholdImage(img image.Image, threshold uint8) image.Image {
    bounds := img.Bounds()
    thresholdColor := color.Gray{Y: 100 - threshold}

    // Create a new grayscale image with the same size as the input image
    outputImg := image.NewGray(bounds)

    // Loop through each pixel in the input image and set the corresponding pixel in the output image
    for x := bounds.Min.X; x < bounds.Max.X; x++ {
        for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
            pixelColor := color.GrayModel.Convert(img.At(x, y)).(color.Gray)
            if pixelColor.Y >= thresholdColor.Y {
                outputImg.SetGray(x, y, color.Gray{Y: 255})
            } else {
                outputImg.SetGray(x, y, color.Gray{Y: 0})
            }
        }
    }
    return outputImg
}

```

## screenshot
``` go
"github.com/oliamb/cutter"
"github.com/sclevine/agouti"
"image"
"image/png"

func getScreenshot(page *agouti.Page, px, py, width, height int, imageName string) {
    page.Screenshot(imageName)

    f, err := os.Open(imageName)
    printError(err)
    img, _, err := image.Decode(f)
    printError(err)
    file, _ := os.Create(imageName)
    defer file.Close()

    croppedImg, err := cutter.Crop(img, cutter.Config{
        Anchor: image.Point{px, py},
        Width:  width,
        Height: height,
    })

    png.Encode(file, croppedImg)
    sleep(delay)
}

```

## Csv
``` go
"encoding/csv"
func readCsv(path string) [][]string {
    f, err := os.Open(path)
    printError(err)
    lines, err := csv.NewReader(f).ReadAll()
    return lines
}

func writeCsv(lines [][]string, path string) {
    file, err := os.Create(path)
    printError(err)
    defer file.Close()
    file.WriteString("\xEF\xBB\xBF")
    for _, line := range lines {
        file.WriteString(strings.Join(line, ", ") + "\n")
    }
}

```

## imageSize
``` go
_ "image/jpeg"
_ "image/png"

func getImageSize(file string) (string, string) {
    cmd = fmt.Sprintf(`identify %s`, file)
    c := runCmd(cmd)
    size := strings.Split(strings.Split(c, " ")[2], "x")
    return size[0], size[1]
}

func getImageSize(path string) (image.Image, int, int) {
    f, err := os.Open(path)
    defer f.Close()

    im, _, err := image.DecodeConfig(f)
    printError(err)

    ioReader, err := os.Open(path)
    printError(err)

    img, _, err := image.Decode(ioReader)
    printError(err)
    return img, im.Width, im.Height
}
```

## type class
``` go  
import "reflect"  
fmt.Println(reflect.TypeOf(doc))

import "github.com/go-ffmt/ffmt"
ffmt.P(m)  // type
ffmt.Puts  
ffmt.Pjson 


```  

## ignore not used
``` go
import (
    _ "fmt" //imported and not used
 )
```

## skip declared
``` go
i := 1 
_ = i
```

## screen
``` go
import "github.com/inancgumus/screen"

func cleanScreen() {
    screen.Clear()
    screen.MoveTopLeft()
}
```

## regexp
``` go
// 中文 \p{Han}

func Match(str, keyword string) bool {
    match, _ := regexp.MatchString(keyword, str)
    return match
}

func Scans(str, keyword string) []string {
    re := regexp.MustCompile(keyword)
    match := re.FindStringSubmatch(str)
    if len(match) > 0 {
        return match[1:]
    }
    return match
}

//scan
func Scan(str, keyword string, i int) string {
    re := regexp.MustCompile(keyword)
    match := re.FindStringSubmatch(str)
    var result string
    if len(match) > i {
        result = match[i]
    }
    return result
}

func Scans(str, keyword string, is ...int) []string {
    re := regexp.MustCompile(keyword)
    match := re.FindStringSubmatch(str)
    //.FindAllStringSubmatch
    var txts []string
    for _, i := range is {
        txts = append(txts, match[i])
    }
    return txts
}

//replace
keyword := `"(.*)", "(.*)"`
re := regexp.MustCompile(keyword)
s := re.ReplaceAllString(e, ` $1 $2`)
```


## array

### pop
``` go
words = append(words[:idx], words[idx+1:]...)


```

### eachSlice N part
``` go
func eachSlice(arr []string, l int) [][]string {
    var ar [][]string
    size := len(arr)
    for i := 0; i < size; i = i + l {
        j := i + l
        if j > size {
            j = size
        }
        fmt.Println(len(arr[i:j]))
        ar = append(ar, arr[i:j])
    }
    return ar
}
```

### index
``` go
func arrIncludeIndex(arr []string, str string) int {
    for i, e := range arr {
        if str == e {
            return i
        }
    }
    return -1
}
func arrIndexS(arr []string, str string) []int {
    is := []int{}
    for i, e := range arr {
        if str == e {
            is = append(is, i)
        }
    }
    return is
}

func arrRemoveByIndex(arr []string, idx int) []string {
    arr[idx] = arr[len(arr)-1]
    return arr[:len(arr)-1]
}
```

### Sort
``` go
func bubbleSort(arr []int) {
    size := len(arr)
    for i := 0; i < size; i++ {
        for j := 1; j < size-i; j++ {
            if arr[j] > arr[j-1] {
                arr[j], arr[j-1] = arr[j-1], arr[j]
            }
        }
    }
}

func quickSort(arr []int) {
    if len(arr) <= 1 {
        return
    }
    
    left, right := 0, len(arr)-1
    
    for i, pivot := 1, arr[0]; i <= right; {
        switch {
        case arr[i] > pivot:
            left++
            arr[i], arr[left] = arr[left], arr[i]
            i++
        case arr[i] < pivot:
            arr[i], arr[right] = arr[right], arr[i]
            right--
        default:
            i++
        }
    }

    arr[0], arr[left] = arr[left], arr[0]
    
    quickSort(arr[:left])
    quickSort(arr[left+1:])
}
```

### duplicate
``` go
type Count struct {
    id    string
    count int
}

func bubbleSort(arr []Count) {
    size := len(arr)
    for i := 0; i < size; i++ {
        for j := 1; j < size; j++ {
            if arr[j].count > arr[j-1].count {
                arr[j], arr[j-1] = arr[j-1], arr[j]
            }
        }
    }
}
// 計算重複次數
func arrayDuplicate(arr []string) []Count {
    cs := make(map[string]int)
    for _, e := range arr {
        _, exist := cs[e]
        if exist {
            cs[e] += 1
        } else {
            cs[e] = 1
        }
    }
    var count []Count
    for cc := range cs {
        c := Count{cc, cs[cc]}
        count = append(count, c)
    }
    bubbleSort(count)
    return count
}
//  移除重複
func RemoveDuplicates[T comparable](arr []T) []T {
	// 使用 map 來記錄元素是否已經出現過
	seen := make(map[T]struct{})
	var result []T

	for _, v := range arr {
		if _, ok := seen[v]; !ok {
			// 如果元素還沒出現過，將其加入結果陣列
			seen[v] = struct{}{}
			result = append(result, v)
		}
	}

	return result
}
// 比對舊資料 移除重複
func RemoveDuplicates[T comparable](newArr, oldArr []T) []T {
	seen := make(map[T]struct{})
	for _, v := range oldArr {
		seen[v] = struct{}{}
	}

	var result []T
	for _, v := range newArr {
		if _, ok := seen[v]; !ok {
			result = append(result, v)
		}
	}

	return result
}

```

### reverse
``` go
func arrReverse(arr []int) {
    for i := 0; i < len(arr)/2; i++ {
        arr[i], arr[len(arr)-i-1] = arr[len(arr)-i-1], arr[i]
    }
}

```

### sub
``` go
func arrSub(arr1 []int, arr2 []int) []int {
    r := []int{}
    for _, e1 := range arr1 {
        if !arrInclude(arr2, e1) {
            r = append(r, e1)
        }
    }
    return r
}
```

### include
``` go
func arrInclude(arr []int, str int) bool {
    for _, e := range arr {
        if str == e {
            return true
        }
    }
    return false
}
func arr1InclueArr2(arr1 []int, arr2 []int) bool {
    for _, e := range arr1 {
        if !reflect.DeepEqual(e, arr2) {
            return false
        }
    }
    return true
}
```

### Equal
`reflect.DeepEqual(a, b)`

###`` compare
``` go
func arrCompare(a1, a2 []string) ([]string, []string, []string) {
    var d1, same []string
    for _, e1 := range a1 {
        idx := arrIncludeIndex(a2, e1)
        if idx != -1 {
            same = append(same, e1)
            a2 = arrRemoveByIndex(a2, idx)
        } else {
            d1 = append(d1, e1)
        }
    }
    return d1, a2, same
}
```


## math
### power
``` go
"math"
math.Pow(2, 5)

func power(n, p int) int {
    if p == 1 {
        return n
    }
    return n * pow(n, p-1)
}

func power(base, exponent int) int {
    result := 1
    for exponent > 0 {
        if exponent&1 == 1 {
            result *= base
        }
        base *= base
        exponent >>= 1
    }

    return result
}

```
### bit
``` go
n, err := strconv.ParseUint(val, 16, 32)
if err != nil {
    panic(err)
}
```
###  d
``` go
math.Ceil(0.2)
math.Floor(0.2)
```

### even odd
``` go
func evenBool(i int) bool {
    return i%2 == 0
}
func oddBool(i int) bool {
    return i%2 != 0
}
```

### rand
``` go
"math/rand"
rand.Seed(time.Now().UnixNano())

func Str(min, max float64) string {
    rand.Seed(time.Now().UnixNano())
    n := min + rand.Float64()*(max-min)
    return fmt.Sprintf("%.1f", n)
}

func randNumInt(min, max int) int {
    rand.Seed(time.Now().UnixNano())
    return min + rand.Intn(max-min+1)
}

func RandNumFloat(min, max float64) float64 {
    return min + rand.Float64()*(max-min)
}

func randArr(array []string) string {
    rand.Seed(time.Now().UnixNano())
    return array[rand.Intn(len(array))]
}
```

## image
``` go
func getColor(img image.Image, x int, y int) string {
    r, g, b, _ := img.At(x, y).RGBA()
    return fmt.Sprintf("%2x%2x%2x", r/257, g/257, b/257)
}

ioReader, err := os.Open(path)
printError(err)
img, _, err := image.Decode(ioReader)
printError(err)


img = image.NewRGBA(image.Rect(0, 0, width, width))

pixel := getColor(img, x, y)


```

## br 
``` go
data := [][]string
for _, t := range td.Children() {
    if t.NodeValue != "br" {
        data = append(data, t.NodeValue)
    }
}
```

## excel
``` go

"github.com/xuri/excelize/v2"

func readXlsx(path string) [][]string {
    f, err := excelize.OpenFile(path)
    printError(err)
    var datas [][]string
    sheet1 := f.GetSheetMap()[1]
    rows := f.GetRows(sheet1)
    for _, row := range rows {
        var data []string
        for _, cell := range row {
            cell = strings.TrimSpace(cell)
            data = append(data, cell)
        }
        datas = append(datas, data)
    }
    return datas
}

func writeXlsx(path string, data [][]string) {
    f, err := excelize.OpenFile(path)
    printError(err)
    sheet := f.GetSheetMap()[1]

    f := excelize.NewFile()
    index := f.NewSheet("Sheet1")
    
    for i, row := range data {
        for j, cell := range row {
            c := fmt.Sprintf("%c%v", rune(j+65), i+1)
            f.SetCellValue("Sheet1", c, cell)
        }
    }
    f.SetActiveSheet(index)
    err := f.SaveAs(path)
    printError(err)
}

```

``` go
func moniterExit() {
    c := make(chan os.Signal)
    signal.Notify(c)

    go func() {
        for s := range c {
            switch s {
            case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM:
                fmt.Println(s)
                ExitFunc()
            default:
                fmt.Println(s)
            }
        }
    }()
}

```

## image
``` go
"github.com/fogleman/gg"

img, err := gg.LoadImage(gfiImage)
printError(err)
s := img.Bounds().Size()
width, height := s.X, s.Y

dc := gg.NewContext(width, height)
dc.SetRGB(0, 0, 0)
dc.DrawImage(img, 0, 0)

addText(dc, timeFormat(), 45, 48, 40)
dc.SavePNG(imageFakeSend)


func addText(dc *gg.Context, str string, x, y, s float64) {
    dc.LoadFontFace("/data/font/msjh.ttc", s)
    dc.SetRGB(150, 150, 150)
    dc.DrawStringAnchored(str, x, y, 0, 0)
}

func LoadImage(dc *gg.Context, path string, x, y, rotate int) *gg.Context {
    im, _ := gg.LoadImage(path)
    size := im.Bounds().Size()
    width, height := size.X, size.Y
    dc.Push()
    // 旋轉
    dc.RotateAbout(gg.Radians(float64(rotate)), float64(x+width/2), float64(y+height/2))
    // 1240, 1754
    dc.DrawImage(im, x, y)
    dc.Pop()
    return dc
}

func Crop(dc *gg.Context, px, py, width, height int) *gg.Context {
    img := dc.Image()
    croppedImg := cropImg(img, px, py, width, height)

    dc1 := Create(width, height)
    dc1.DrawImage(croppedImg, (-1)*px, (-1)*py)
    return dc1
}

func cropImg(img image.Image, px, py, width, height int) image.Image {
    croppedImg, err := cutter.Crop(img, cutter.Config{
        Anchor: image.Point{px, py},
        Width:  width,
        Height: height,
    })
    printError(err)
    return croppedImg
}

```

## mp3 
``` go
"github.com/faiface/beep/mp3"
"github.com/faiface/beep/speaker"

func mp3Play(path string, sec ...int) {
    f, err := os.Open(path)
    printError(err)
    streamer, format, err := mp3.Decode(f)
    printError(err)
    defer streamer.Close()
    speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
    speaker.Play(streamer)
    if len(sec) > 0 {
        sleep(sec[0])
    } else {
        sleep(1000)
    }
}
```


## win UI
`https://github.com/harry1453/go-common-file-dialog`  

``` go
"github.com/harry1453/go-common-file-dialog/cfd"
"github.com/harry1453/go-common-file-dialog/cfdutil"
func Run() string {
    path, err := os.Getwd()

    var fileFilters []cfd.FileFilter
    fileFilters = append(fileFilters, cfd.FileFilter{"*.xlsx", "*.xlsx"})
    fileFilters = append(fileFilters, cfd.FileFilter{"*.*", "*.*"})

    result, err := cfdutil.ShowOpenFileDialog(cfd.DialogConfig{
        Title:       "開啟檔案",
        Role:        "開啟檔案",
        FileFilters: fileFilters,
        Folder:      path,

        SelectedFileFilterIndex: 0,
        FileName:                ``,
        DefaultExtension:        ``,
    })
    if err != nil && err.Error() == "使用者取消" {
        fmt.Println("使用者取消")
        os.Exit(0)
    }
    return result
}

func pickFolder() string {
     path, err := os.Getwd()

    pickFolderDialog, err := cfd.NewSelectFolderDialog(cfd.DialogConfig{
        Title: "開啟目錄",
        Role:  "開啟目錄",
        Folder: path,
    })
    printError(err)
    err = pickFolderDialog.Show()
    printError(err)
    result, err := pickFolderDialog.GetResult()
    if err != nil && err.Error() == "使用者取消" {
        fmt.Println("使用者取消")
        os.Exit(0)
    }
    return result
}
``` 

### Msgbox
``` go
"syscall"

func MessageBox(title, caption string) {
    syscall.NewLazyDLL("user32.dll").NewProc("MessageBoxW").Call(
        uintptr(0),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))),
        uintptr(0))
}
```

### barCode
``` go

"github.com/makiuchi-d/gozxing"
"github.com/makiuchi-d/gozxing/oned"

func genCode128(id string) {
    enc := oned.NewCode128Writer()
    img, _ := enc.Encode(id, gozxing.BarcodeFormat_CODE_128, 250, 50, nil)
    path := genPath(id)
    file, _ := os.Create(path)
    defer file.Close()
    png.Encode(file, img)
}

```

## ssh
``` go
"github.com/sfreiberg/simplessh"

client, err := simplessh.ConnectWithKeyFile("192.168.0.201:22", "icps", "/home/icps/.ssh/192.168.0.201")
defer client.Close()
printError(err)

output, err := client.Exec("uptime")
printError(err)
fmt.Println(string(output))

err = client.Upload("/tmdp/weatherTmp", "/tmp/123")
printError(err)

```

## encoding big5
``` go
"golang.org/x/text/transform"
"bytes"
"golang.org/x/text/encoding/traditionalchinese"
"io/ioutil"

func big5utf8(str string) string {
    reader := transform.NewReader(bytes.NewReader([]byte(str)), traditionalchinese.Big5.NewDecoder())
    out, _ := ioutil.ReadAll(reader)
    return string(out)
}
```

## any
```
// any to string
v.(string)
```


## base64
``` go
"encoding/base64"

func EnBase64(str string) string {
    return base64.StdEncoding.EncodeToString([]byte(str))
}

func DeBase64(str string) string {
    s, err := base64.StdEncoding.DecodeString(str)
    printError(err)
    return string(s)
}
```

## interface 
``` go
func interface_to_i(i interface{}) int {
    var int = -1
    is, ok := i.(string)
    if ok {
        int = to_i(is)
    }
    return int
}

func interface_to_s(i interface{}) text {
    var text string
    is, ok := i.(string)
    if ok {
        text = is
    }
    return is
}
```