Tuesday, March 19, 2013

Some useful development patterns via the raspberry pi & minecraft

Programming minecraft on the raspberry pi is not just fun, it's also a great chance to learn some of the cool things that can be done from the linux command line.
We're going to look at two problems:
  1. How can I edit files on my raspberry pi using an editor on my pc?
  2. How can I run minecraft on a raspberry pi with a screen connected but without a mouse and keyboard connected?
  3. Minecraft fails to start: something about a problem loading shared library libGLESv2.so
The Setup
  • 1 raspberry pi connected to a network and a monitor
  • 1 PC (I'm using linux, it should work equally well on osx, not sure about windows.)

How can I edit files on my raspberry pi using an editor on my pc?


Create an empty folder on your PC:
mkdir ~/pi
Then use sshfs to mount it
sshfs pi@192.168.1.82: ~/pi/
Where pi is my user name and 192.168.1.82 is the ip address of the pi.
Now, on my pc if I cd to ~/pi I can see the files in the home directory of my pi, which means I can open them on my pc using my editor of choice

How can I run minecraft on a raspberry pi with a screen connected but without a mouse and keyboard connected?


From your pc ssh into the pi specifying -X
ssh -X pi@192.168.1.82
This turns on X11 forwarding - you don't need to know what that means for now, just start minecraft from inside ssh. You should see an empty minecraft window appear
Now take a look at your monitor, you should see minecraft there and be able to use your laptop's mouse and keyboard to move yourself around
As a bonus, you should be able to drag the window around on your pc, and have the window move around on your pi as well

Minecraft fails to start: something about a problem loading shared library libGLESv2.so


When I run minecraft I get this:
./minecraft-pi
error while loading shared libraries: libGLESv2.so: cannot open shared object file: No such file or directory
Shared libraries are essentially bits of code that are shared amongst many programs. You can see what shared objects a program needs by typing
ldd ./minecraft-pi
You might see some stuff marked "not found" at the top
        /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0x4022c000)
        libGLESv2.so => not found
        libEGL.so => not found
        libbcm_host.so => not found
        libpng12.so.0 => /lib/arm-linux-gnueabihf/libpng12.so.0 (0x40182000)
        libSDL-1.2.so.0 => /usr/lib/arm-linux-gnueabihf/libSDL-1.2.so.0 (0x40235000)
        libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0x402c8000)
        libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x401aa000)
To help linux find some of these shared object you can specify an option on the command line before you run your command:
LD_LIBRARY_PATH=/opt/vc/lib ./minecraft-pi

Thursday, January 17, 2013

Using go to unmarshal json lists with multiple types

Everyday I seem to be writing go code to parse a json string, and this problem seems to come up often enough for me to write about it. Thanks to adg and asoko on #go-nuts for their suggestions.

The Problem

Given a list of json objects of different types (lets say People and Places). You want to Unmarshal them into two lists. A list of all the people and a list of all the places.

A bit more definition

Let's use this json string
{
    "things": [
        {
            "name": "Alice",
            "age": 37
        },
        {
            "city": "Ipoh",
            "country": "Malaysia"
        },
        {
            "name": "Bob",
            "age": 36
        },
        {
            "city": "Northampton",
            "country": "England"
        }
    ]
}
To help us write some code, let's give ourselves a function, which should be self explanatory:
func solution(jsonString []byte) ([]Person []Place) {}
And some structures
type Person struct {
 Name string
 Age  int
}

type Place struct {
 City    string
 Country string
}
I've got two solutions to this problem. I would love to know of better ways.

SolutionA: map and type assert

If we tell json to unmarshal into a map we can get it to deal with the parts we know about, and the rest of it will go into an interface{}. As we loop over the json structures we use what we do know about the structures to pass the interface{} to some helper functions what will create one of our structs and add it to our list. Because the map we take in is a map[string]interface{} we will need to type assert our values
func solutionA(jsonStr []byte) ([]Person, []Place) {
 persons := []Person{}
 places := []Place{}
 var data map[string][]map[string]interface{}
 err := json.Unmarshal(jsonStr, &data)
 if err != nil {
  fmt.Println(err)
  return persons, places
 }

 for i := range data["things"] {
  item := data["things"][i]
  if item["name"] != nil {
   persons = addPerson(persons, item)
  } else {
   places = addPlace(places, item)
  }

 }
 return persons, places
}

func addPerson(persons []Person, item map[string]interface{}) []Person {
 name, _ := item["name"].(string)
 age, _ := item["age"].(int)
 person := Person{name, age}
 persons = append(persons, person)
 return persons
}

func addPlace(places []Place, item map[string]interface{}) []Place {
 city, _ := item["city"].(string)
 country, _ := item["city"].(string)
 place := Place{city, country}
 places = append(places, place)
 return places
}

SolutionB: Mixed Type struct

This solution involves creating an interim struct which can be used to represent either a person or a place
type Mixed struct {
 Name    string `json:"name"`
 Age     int    `json:"age"`
 City    string `json:"city"`
 Country string `json:"country"`
}
With this struct we can then unmarshal our json string into a list of these mixed types. As we loop over our Mixed structs we just need to examine each one to work out which type it represents, and then build the right struct from it
func solutionB(jsonStr []byte) ([]Person, []Place) {
 persons := []Person{}
 places := []Place{}
 var data map[string][]Mixed
 err := json.Unmarshal(jsonStr, &data)
 if err != nil {
  fmt.Println(err)
  return persons, places
 }

 for i := range data["things"] {
  item := data["things"][i]
  if item.Name != "" {
   persons = append(persons, Person{item.Name, item.Age})
  } else {
   places = append(places, Place{item.City, item.Country})
  }

 }
 return persons, places
}
These are just two ways I've used to solve these problems, I'd love to know how others have done it.

SolutionC: json.RawMessage (Updated 18Jan13)

Thanks to Jordan's comment and zemo on reddit there is another solution. Using the json.RawMessage structure in the json package we can delay unmarshalling the json structures in the list. We can then go through our list and unmarshal each of them into the correct type
func solutionC(jsonStr []byte) ([]Person, []Place) {
 people := []Person{}
 places := []Place{}
 var data map[string][]json.RawMessage
 err := json.Unmarshal(jsonStr, &data)
 if err != nil {
  fmt.Println(err)
  return people, places
 }
 for _, thing := range data["things"] {
            people = addPersonC(thing, people)
            places = addPlaceC(thing, places)
        }
 return people, places
}

func addPersonC(thing json.RawMessage, people []Person) []Person {
    person := Person{}
    if err := json.Unmarshal(thing, &person); err != nil {
        fmt.Println(err)
    } else {
        if person != *new(Person) {
            people = append(people, person)
        }
    }

    return people
}

func addPlaceC(thing json.RawMessage, places []Place) []Place {
    place := Place{}
    if err := json.Unmarshal(thing, &place); err != nil {
        fmt.Println(err)
    } else {
        if place != *new(Place) {
            places = append(places, place)
        }
    }

    return places
}
Here's the full gist:

Monday, January 7, 2013

Using vim's path to speed up your Go project

If you're working on a project in Go, and you're using vim, then you really need to check out path:
:help path
Here's a very quick tour.

Add this to you .vimrc:
set path +=/your/projects/gopath/src/**
** tells path to include all subdirectories. By adding your projects GOPATH entry it opens up access to two rather cool features that are useful in navigating your project.

:find

You can use :find to open a file instead of using :e. But :find will look in all of your project's directories to find the file. So rather than having to do:
:e /package/v10/another-dir/god.go
You just need:
:find god.go
You also get tab-completion for free - just in case you can't remember the file's name.

gf

gf is the useful little command that goes to the file under the cursor. Well providing you've set your path correcly you can navigate your project's imports with ease:
package main

import (
 "code.google.com/p/go.net/websocket"
)
By "gf"ing over the import vim will open the directory, giving you the list of files in that package.

Just don't dare navigate the directory using the arrow keys!

Update: 8th Jan 2012

On the subject of vim and Go it's worth remembering this little gem:
au BufWritePost *.go !gofmt -w %
Whenever a Go file is saved gofmt will be run against it.

Sunday, December 30, 2012

go(ing) under

Lots of people like go and this year I began to find it unavoidable - I'm even ending the year with go being the main language that helps pay my bills!

One of the things that go lets you do is pass functions around.
I started the year talking about under from the j language. Which lets you 'bookend' some function with another function (a verb) and a function which undoes that function (obverse).
A great example is Pythagoras' theorem:
  1. You perform some 'pre-processing' on each value (squaring)
  2. You add all the values up
  3. You square root the result
I started the year talking about under in clojure. Here it is implemented in go. Complete with functions being passed around, closures, and functions returning functions. Happy new year!

Monday, October 22, 2012

Running juju locally on 12.04 (or getting over agent-status pending)

I've just tried following the instructions here to get juju running locally on my brand new Ubuntu 12.04 (desktop) system.
No matter what I tried my wordpress and mysql charms seemed stuck in agent-status pending and ip address null. Even waiting a couple of hours.

I needed to take to a couple of extra steps to get it working that didn't seem to be documented in one place. So I thought I'd put them both here.

All it took was to add a rule to ufw:
sudo ufw allow from 192.168.122.0/24 to any
You also need to have an ssh service running:
sudo /etc/init.d/ssh start
Hope this helps someone who was stuck in the same way I was.

Saturday, September 15, 2012

Clojure, Vim and the delay sending to screen

So, long story short: I'm use vim for writing clojure (and everything else for that matter)

If you're following the setup How I develop Clojure with Vim on the :wq blog then you might encounter a problem where it takes a few seconds for code you send from vim to appear in your screen session. Here's the solution.

Add the following lines to you ~/.screenrc

msgwait 0
msgminwait 0

And there you have it, instant code from vim to your REPL!

Tuesday, August 14, 2012

Another clojure macro tutorial (that no one should follow)

Disclaimer: This post shows you something you can do with macros. Not something you should do.

I like python.

You define functions

def something(x, y):
    return x + y

And you can document functions
def something(x, y):
"""Adds two things together"""
    return x + y

I also like clojure.

You can define functions
(defn something [x y]
  (+ x y))

And you can document functions
(defn something 
  "Adds to things together"
  [x y]
  (+ x y))

Documentation before the arguments? Despicable! If only there was a way of putting them in the right order.

Well, for the sake of argument let's try

Remember that in clojure code is data. A function is just a list, and we want to be able to define functions with some of the items of the list in a different order. At the moment a function definition list looks like this:

(function-name doc-string args function-body)

and we want to be able to make a function using the argument order

(function-name args doc-string function-body)

The first rule of matco club is "Don't write macros". So lets try:

First, how do we want our function (let's call it defndoc) to work? We want it to behave just like a normal function definition but with the docstring after the args.

(defndoc something [x y]
  "Adds to things together"
  (+ x y))

Now let's try to write it. We want to call our defndoc function and have that call defn with the arguments in the correct order.

(defn defndoc [fname args docs & body]
  (defn fname docs args body))

But this isn't going to work as our arguments are going to get evaluated. But this isn't what we want, looks like we will have to write a macro. This is how it looks

(defmacro defndoc [fname args docs & body]
    `(defn ~fname ~docs [~@args] ~@body))

Let's discuss the differences between this and our non-macro attempt.

First we use a syntax-quote (`). This is going to allow us to choose which bits of our list our evaluated and which are not. For example, the defn we want to be evaluated but the other parts we don't.

The next symbol is unquote (~) which tells clojure to evaluate these symbols.

The last symbol is unquote-split (~@) which tells clojure that there is a list of things here that needs to be expanded in place.

now if you do call macroexpand-1 using our defndoc macro on our function with the docstring following the arguments you will get the following

(clojure.core/defn something "Adds two things together" [x y] (+ x y))

Perfect, now we can sprinkle defndoc all over our code and have the docstring in the place we want it, but also keep clojure happy.

Now don't let me ever catch you doing this!