# 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
}
```