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