Extracting attribute value from multiple XML nodes in golang?

I’m attempting to parse an SVG file to get all of the colors that are present in the file. SVGs are XML based and their structure can vary a bit. For example:

<svg viewBox="-80 -80 160 160">   <g stroke="black" fill="none">     <path d='...' fill='#0FF'/>     <path d='...' fill='#F0F'/>     ...   </g> </svg> 


<svg viewBox="0 0 100 100">   <a>     <path d="..." stroke="black" fill="red"/>     <ellipse stroke="black" fill="white" cx="50" cy="40" rx="22" ry="35"/>     <circle cx="50" cy="40" r="5" stroke="black" fill="red"/>   </a> </svg> 


<svg viewBox="0 0 80 120">   <rect id="background-rect" x="0%" y="0%" width="100%" height="100%" fill="#aaaaaa"/> </svg> 

Are all examples of valid SVGs. At first I attempted to create the underlying structs that would allow me to represent all of these structures but then I decided to take a more generic approach that would focus soley on the fill attribute which is all I care about:

type GenericNode struct {     XMLName xml.Name     Fill    string        `xml:"fill,attr"`     Nodes   []GenericNode `xml:",any"` }  func (s *SVGController) GetColorsFromXML() []string {     xmlFile, _ := os.Open(s.Path)     byteValue, _ := ioutil.ReadAll(xmlFile)     var svg GenericNode     xml.Unmarshal(byteValue, &svg)      // Using a map here to avoid having to worry about having     // duplicate colors in the color slice     colorMap := make(map[string]struct{})     colorMap = getSVGColors(svg, colorMap)      // Once we have a complete color map extract all the keys     // to an array and return it.     colors := make([]string, len(colorMap))     i := 0     for k := range colorMap {         colors[i] = k         i++     }     return colors }  func getSVGColors(svg GenericNode, colors map[string]struct{}) map[string]struct{} {     if svg.Fill != "" && strings.ToLower(svg.Fill) != "none" {         colors[svg.Fill] = struct{}{}     }     for _, node := range svg.Nodes {         colors = getSVGColors(node, colors)     }     return colors } 

Is this a reasonable approach to take? Am I doing anything here that should be avoided?

GoLang: есть ли доступ к железу?

Думаю вот новый проект начать на go. Нет возможности сильно его изучить и разобраться до начала работы. А этот момент определит, упадёт ли выбор на go или стандартно на Java в сцепке с С++. Хотелось бы на go.

Внутренний заказчик к нашим системам требует, чтобы на сервисах была элементарная защита от копирования. Получить бы серийники, или какие-нибудь жесткие данные железа. Понятно, что инженер всё это пере-раз-ди-ассемблит и разберется… Но необходимости защитить от инженера нет, есть необходимость защитить от контент-менеджера. Ну чтобы совсем простаками не выглядеть.

Если не получится напрямую запросить, то буду рад какой-нить библиотечке, которая проглотит С++ без лишних забот.

Looping through to check if merged in trunk in Golang

I have some code to check if any branches listed have already been merged into master, using the src-d/go-git.v4 library.

It loops through the commits in master, then compares the head of the various branches with the commit. If it matches, it means the branch has been merged into master already.

mergedBranches := make([]string, 0)  err = masterCommits.ForEach(func(commit *object.Commit) error {     for branchName, branchHead := range remoteBranchHeads {         if (branchHead.String() == commit.Hash.String()) && (branchName != "origin/master") {             log.Infof("Branch %s head (%s) was found in master, so has been merged!\n", branchName, branchHead)             mergedBranches = append(mergedBranches, branchName)         }     }     return nil })  if err != nil {     fmt.Sprintf("looking for merged commits failed:", err)     return } 

This works fine, but loops in loops always make me feel uneasy, and its not super performant if a repo has a lot of branches and a lot of commits in master.

So my question is, is there a cleaner way to do this? And would use of channels/goroutines make it more performant? I’m fairly new to golang, so I haven’t really learnt how to use them properly yet.

Golang RESTful HTTP API – would appreciate feedback

Link to the repo on GitHub

// Server is a RESTful HTTP API server offering CRUD functionality to store Payments. type Server struct {     Router  *httprouter.Router     Storage storage.PaymentStorage } 

Documentation with more details is here.

My remaining TODO list looks like this, in no particular order:

  • Increase test coverage
    • Make sure the input/output JSON formatting aligns 100% with the docs
  • Implement Mongo PaymentStorage
  • Fuzz testing
  • Dockerise
    • Terraform a GCP deployment (using App Engine custom runtimes)
  • Versioning (prefix ‘/payments’ -> ‘/v1/payments’)

Would gladly welcome any feedback, thoughts, constructive criticism, etc that anyone is willing to volunteer!

Считать двумерный вещественный массив Golang с файла

Хочу считать двумерный вещественный массив чисел. Дошел до момента, где уменя в строке data хранится содержимое файла, однако я не знаю как можно сделать на основе этого двумерный массив вещественных чисел: Вот код:

package main  import ( "fmt" //"gonum.org/v1/gonum/mat" "io" "os" "strconv" )   func main() { file, err := os.Open("matrix") if err != nil{     fmt.Println(err)     os.Exit(1) } defer file.Close()  data := make([]byte, 64)  for{     n, err := file.Read(data)     if err == io.EOF{         break         }     fmt.Print(string(data[:n]))     } }  

Содержимое файла matrix:

5.482 0.358 0.237 0.409 0.416 0.580 4.953 0.467 0.028 0.464 0.319 0.372 8.935 0.520 0.979 0.043 0.459 0.319 4.778 0.126 

Writing GOlang object code that respects Go guidelines

Learning GO and I wrote this for a programming challenge. It is working (building and running) but I feel the code is not what GO code should be :

  • am I using the struct element correctly ? especially struct methods ?
  • in the playTurn() method, I reassign results (else not taken into account) because scope. How to write it better ? Pointer ?
  • I am struggling with int, float64 and casting all the time. What’s the good practice in this context were I need float for precision in-between but inputs and outputs are int ?

full script :

package main  import (     "fmt"     "math"     "os"     "strconv" )  // Pod is life type Pod struct {     position                Dot     vx, vy, angle, nextCpID int     hasShieldOn             bool }  func squaredDist(a, b Dot) int {     return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) } func distance(a, b Dot) float64 {     return math.Sqrt(float64(squaredDist(a, b))) }  func (pod Pod) getAngle(p Dot) float64 {     d := distance(p, pod.position)     dx := float64(p.x-pod.position.x) / d     dy := float64(p.y-pod.position.y) / d     a := math.Acos(dx) * 180.0 / math.Pi      // If the point I want is below me, I have to shift the angle for it to be correct     if dy < 0 {         a = 360.0 - a     }     return a }  func (pod Pod) diffAngle(p Dot) float64 {     a := pod.getAngle(p)     pangle := float64(pod.angle)      right := 0.0     if pangle <= a {         right = a - pangle     } else {         right = 360.0 - pangle + a     }      left := 0.0     if pangle >= a {         left = pangle - a     } else {         left = pangle + 360.0 - a     }      if right < left {         return right     }     return -left }  func (pod Pod) rotate(p Dot) int {     a := pod.diffAngle(p)      // Can't turn more than 18° in one turn !     if a > 18.0 {         a = 18.0     } else if a < -18.0 {         a = -18.0     }      pod.angle += int(math.Round(a))      if pod.angle >= 360.0 {         pod.angle = pod.angle - 360.0     } else if pod.angle < 0.0 {         pod.angle += 360.0     }     return pod.angle }  func (pod Pod) boost(t int) (int, int) {     if pod.hasShieldOn {         return pod.vx, pod.vy     }     pangle := float64(pod.angle)     pod.vx += int(math.Round(math.Cos(pangle) * float64(t)))     pod.vy += int(math.Round(math.Sin(pangle) * float64(t)))     return pod.vx, pod.vy }  // t shoud become a float later on func (pod Pod) move(t int) (int, int) {     pod.position.x += pod.vx * t     pod.position.y += pod.vy * t     return pod.position.x, pod.position.y }  func (pod Pod) endTurn() (int, int) {     // todo rounding position if needed     pod.vx = int(float64(pod.vx) * 0.85)     pod.vy = int(float64(pod.vy) * 0.85)     return pod.vx, pod.vy }  func (pod Pod) playTurn(p Dot, t int) {     pod.angle = pod.rotate(p)     pod.vx, pod.vy = pod.boost(t)     pod.position.x, pod.position.y = pod.move(1)     pod.vx, pod.vy = pod.endTurn()     fmt.Fprintf(os.Stderr, "\nPredicted Pod position : ")     fmt.Fprintf(os.Stderr, "\n(%d, %d) speed (%d,%d)", pod.position.x, pod.position.y, pod.vx, pod.vy) }  // Dot is king type Dot struct {     x, y int }  func main() {     var laps int     fmt.Scan(&laps)      var checkpointCount int     fmt.Scan(&checkpointCount)     var checkPoints []Dot     for i := 0; i < checkpointCount; i++ {         var checkpointX, checkpointY int         fmt.Scan(&checkpointX, &checkpointY)         checkPoints = append(checkPoints, Dot{checkpointX, checkpointY})     }     var myPods [2]Pod     var itsPods [2]Pod     for {         for i := 0; i < 2; i++ {             // x: x position of your pod             // y: y position of your pod             // vx: x speed of your pod             // vy: y speed of your pod             // angle: angle of your pod             // nextCheckPointId: next check point id of your pod             var x, y, vx, vy, angle, nextCheckPointID int             fmt.Scan(&x, &y, &vx, &vy, &angle, &nextCheckPointID)             myPods[i] = Pod{Dot{x, y}, vx, vy, angle, nextCheckPointID, false}             fmt.Fprintf(os.Stderr, "\nActual Pod position : ")             fmt.Fprintf(os.Stderr, "\n(%d, %d) speed (%d,%d)", myPods[i].position.x, myPods[i].position.y, myPods[i].vx, myPods[i].vy)         }         for i := 0; i < 2; i++ {             // x2: x position of the opponent's pod             // y2: y position of the opponent's pod             // vx2: x speed of the opponent's pod             // vy2: y speed of the opponent's pod             // angle2: angle of the opponent's pod             // nextCheckPointId2: next check point id of the opponent's pod             var x2, y2, vx2, vy2, angle2, nextCheckPointID2 int             fmt.Scan(&x2, &y2, &vx2, &vy2, &angle2, &nextCheckPointID2)             itsPods[i] = Pod{Dot{x2, y2}, vx2, vy2, angle2, nextCheckPointID2, false}         }          // fmt.Fprintln(os.Stderr, "Debug messages...")         for _, pod := range myPods {             nx := checkPoints[pod.nextCpID].x - 3*pod.vx             ny := checkPoints[pod.nextCpID].y - 3*pod.vy             // Predicting where my pods will be next turn:             pod.playTurn(Dot{nx, ny}, 100)             //             fmt.Println(strconv.Itoa(nx) + " " + strconv.Itoa(ny) + " 100")         }     } } 

Download and save bulk URL concurrecntly in golang

I am new in golang and wrote program in order to download and save bulk url concurrently.It is work correctly but I want to ask is it efficient or can it be better? (I would like to use best practices)

package main  import (...)  // Connection String const connectionString = "connectionString"  // Declare Channels var wg sync.WaitGroup var ch = make(chan *item) // For success item(s) var errItems = make(chan *item) // For error item(s)  type item struct {     id      int     url     string     path    string     content []byte     err     error }  func main() {     start := time.Now()     var basePath = os.Args[1]     var from, to = os.Args[2], os.Args[3]     db, err := sql.Open("sqlserver", connectionString)     if err != nil {         log.Fatal(err.Error())     }     rows, err := db.Query("SELECT [ImageID],[AccommodationlID],[Link],[FileName] FROM [dbo].[AccomodationImage] where AccommodationlID between @from and @to and FileName not like '%NoHotel.png%'", sql.Named("from", from), sql.Named("to", to))     if err != nil {         log.Fatal(err.Error())     }     defer db.Close()     for rows.Next() {         var item = item{}         var accId, name string         _ = rows.Scan(&item.id, &accId, &item.url, &name)         item.path = fmt.Sprintf("%s\%s\%s", basePath, accId, name)         wg.Add(1)         go downloadFile(&item)         go func() {             select {             case done := <-ch:                 wg.Add(1)                 go saveAndUpdateFile(db, done)             case errorItem := <-errItems:                 wg.Add(1)                 go printResult(errorItem)             }         }()     }     wg.Wait()     fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds()) } func downloadFile(item *item) {     defer wg.Done()     resp, err := http.Get(item.url)     if err != nil {         item.content, item.err = nil, err     } else if resp.StatusCode != http.StatusOK {         item.content, item.err = nil, errors.New(resp.Status)     } else {         item.content, item.err = ioutil.ReadAll(resp.Body)     }     if item.err != nil {         errItems <- item     } else {         ch <- item     } } func saveAndUpdateFile(db *sql.DB, item *item) {     defer wg.Done()     if item.content == nil {         item.err = errors.New("Content is empty.")     } else {         dir := filepath.Dir(item.path)         err := os.MkdirAll(dir, os.ModePerm)         if err != nil {             item.err = err         } else {             item.err = ioutil.WriteFile(item.path, item.content, 0644)         }     }     if item.err == nil {         result, err := db.Exec("UPDATE [dbo].[AccomodationImage] SET IsRead = 1 WHERE ImageID = @id", sql.Named("id", item.id))         if rows, _ := result.RowsAffected(); rows <= 0 || err != nil {             item.err = errors.New("Update status failed.")         }     }     if item.err != nil {         errItems <- item     } } func printResult(item *item) {     defer wg.Done()     fmt.Println(item.toString()) } 

I used select statement to implement event so that when errorItems or ch channels received, save or print items.I also sorounded select statement with goroutine to prevent blocking. Thanks

Golang: Directory structure for Multiple Applications

I’m POCing a Go-app for my organization. I’ve read all of the intro docs on setting up a Go workspace, packages, etc. However, I am still unclear about the relationship amongst the recommended directory structures, packages, AND the fully-compiled applications that will eventually be deployed.

My team needs to be able to support many small, decoupled, applications –I am not sure how I can achieve this with the single-workspace-multiple-package approach, and would greatly appreciate clarification.