Archive for the ‘Uncategorized’ Category.

JSON Decoding in Go (golang)

A quick example of JSON decoding (or unmarshaling) in Go. This is basically magic, it’s totally amazing I love it.

It’s possible to decode the JSON into generic maps, but if you know the structure you can get the JSON to populate native go structures automatically. You need to be mindful of types, go wont for example convert an int to a string, it’ll just ignore it.

This means if you have a JSON object that contains string:int key values and string:string key values and you try to populate a golang string map from it, you’ll lose all you string:int pairs. You are better off creating a struct to represent it as seen below.

package main

import (
	"encoding/json"
	"fmt"
)

type LogEntry struct {
	Time string
	Cpm		float32
	Duration	int32
	Accel_x_start	int32
	Accel_y_start	int32
	Accel_z_start	int32
	Accel_x_end	int32
	Accel_y_end	int32
	Accel_z_end	int32
}

type Log struct {
  Log_size 			int
	Onyx_version 	string
	UTC_offset		string
	Log_data			[] LogEntry

}

func main() {

	b := []byte(`{"log_size":61,"onyx_version":"pre11","UTC_offset":"undef","log_data":[{"time":"2012-10-23T22:23:54Z","cpm":46,"duration":30,"accel_x_start":-4,"accel_y_start":-97,"accel_z_start":-3,"accel_x_end":-1,"accel_y_end":-98,"accel_z_end":-2}]}`)	

	var l Log
	json.Unmarshal(b, &l)

  fmt.Printf("logsize: %d onyxversion: %s data1: %s\n",l.Log_size,l.Onyx_version,l.Log_data[0]);
}

How to justify anything as a developer

One way of calculating pi is from the area of a circle, you could even embedded that image in the code. You /could/ then suggest someone call this as an external program, to calculate pi from a script. This is clearly a stupid thing to do.

Here’s a badly written program to do it:

#include <stdio.h>
#include <math.h>

char mask [20][20] = {

// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0},
  {0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0},
  {0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},
  {0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
  {0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
  {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
  {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
  {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
  {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
  {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
  {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
  {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},
  {0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
  {0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},
  {0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},
  {0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0},
  {0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}

};


int main() {

  int area=0;

  for(int x=0;x<20;x++) {
    for(int y=0;y<20;y++) {
      if(mask[x][y] == 1) area++;
    }
  }

  printf("pi: %f\n",(float)area/((17/2)*(17/2)));
}

And here are some ways of justifying it:

Hmm perhaps we should refactor this, maybe there’s a better way?
It works so it’s fine, there are more important things for us to be working on.

Why don’t you just use a hardcoded value, or value from a library?
That’s crazy, you should /always/ avoid magic numbers in your code. How do you know a hardcoded value is correct? You’re developers get no intuitive feeling for the value of pi. They don’t know how to increase the precision of the value. I’m sorry that’s just nuts.

The answer is WRONG it calculates pi as around 3.7
There’s no /right/ answer, all values of pi are approximations. 3.7 is good enough for many applications. It’s also trivial to modify this program to use larger circles and get a better approximation.

OK, but there are FASTER ways of calculating pi
Have you benchmarked it? (people are generally too lazy to benchmark). If it’s really a performance bottleneck you can calculate the value once and store it. In any case, don’t be sucked into premature optimisation. Developer time is more expensive than compute time.

But it’s completely UNCLEAR
I disagree, this method gives the developer a visual representaion of the value of pi. They can intuatively see where the value is coming from. What’s more it’s easy from them to change to code and add larger circle images as required. There are even peer reviewed images of circles all over the Internet which can easily be incorporated.

You’re nuts
You just don’t understand the business case for doing it this way, you’re too wrapped up in the technical issues to see the big picture. You’ll understand better when you’ve been programming for (as long|at the same scale|with large teams) as me.

You can attempt to justify pretty much any programming position by appealing to: utility, premature optimisation, readability and intuition, business cases, and the old standby: experience.

simple file writing example in google go (golang)

package main

import (
	"fmt"
	"io"
	"os"
)

func main() {

	filename := "test.txt"

	fmt.Println("writing: " + filename)
	f, err := os.Create(filename)
	if err != nil {
		fmt.Println(err)
	}
	n, err := io.WriteString(f, "blahblahblah")
	n, err = io.WriteString(f, "blahblahblah")
	if err != nil {
		fmt.Println(n, err)
	}
	f.Close()
}

Bresenham’s line drawing algorithm implemetations in Go and C.

Couple of Bresenham’s line drawing implementations in C and Go. They will need hacking to suit your application.

void display_draw_line(int start_x,int start_y,int end_x,int end_y,uint16_t color) {

  // Bresenham's
  int cx = start_x;
  int cy = start_y;

  int dx = end_x - cx;
  int dy = end_y - cy;
  if(dx<0) dx = 0-dx;
  if(dy<0) dy = 0-dy;

  int sx=0; int sy=0;
  if(cx < end_x) sx = 1; else sx = -1;
  if(cy < end_y) sy = 1; else sy = -1;
  int err = dx-dy;

  for(int n=0;n<1000;n++) {
    display_draw_point(cx,cy,color);
    if((cx==end_x) && (cy==end_y)) return;
    int e2 = 2*err;
    if(e2 > (0-dy)) { err = err - dy; cx = cx + sx; }
    if(e2 < dx    ) { err = err + dx; cy = cy + sy; }
  }
}

And golang:

func draw_line(start_x int32,start_y int32,end_x int32,end_y int32,color uint32,screen* sdl.Surface) {

  // Bresenham's
  var cx int32 = start_x;
  var cy int32 = start_y;

  var dx int32 = end_x - cx;
  var dy int32 = end_y - cy;
  if dx<0 { dx = 0-dx; }
  if dy<0 { dy = 0-dy; }

  var sx int32;
  var sy int32;
  if cx < end_x { sx = 1; } else { sx = -1; }
  if cy < end_y { sy = 1; } else { sy = -1; }
  var err int32 = dx-dy;

  var n int32;
  for n=0;n<1000;n++ {
    draw_point(cx,cy,color,screen);
    if((cx==end_x) && (cy==end_y)) {return;}
    var e2 int32 = 2*err;
    if e2 > (0-dy) { err = err - dy; cx = cx + sx; }
    if e2 < dx     { err = err + dx; cy = cy + sy; }
  }
}