Categories
Go

Golang: Get the function caller’s name

Problem

Consider this code:

package main 

import "fmt"

func foo() {
    // foo() wants to know who called it
    fmt.Println("HI")
}

func main() {
    foo()
}

In the function foo, we want to get the name of the function (and preferably file name and number ) that called it.

Solution

We can get this information by traversing the stack trace (which Go’s “runtime” package has handy functions for:

func foo() {
    fpcs := make([]uintptr, 1)
    // Skip 2 levels to get the caller
    n := runtime.Callers(2, fpcs)
    if n == 0 {
        fmt.Println("MSG: NO CALLER")
    }

    caller := runtime.FuncForPC(fpcs[0]-1)
    if caller == nil {
        fmt.Println("MSG CALLER WAS NIL")
    }

    // Print the file name and line number
    fmt.Println(caller.FileLine(fpcs[0]-1))

    // Print the name of the function
    fmt.Println(caller.Name())
}
Categories
Go

Golang: Connect to Postgres and selecting data from a table

You will need to get the Postgres driver first. In the terminal type:

go get github.com/lib/pq

Connecting to Postgres

package main

import (
    _ "github.com/lib/pq"
    "database/sql"
    "fmt"
)

func main() {
    // Connect to the DB, panic if failed
    db, err := sql.Open("postgres", "postgres://user:[email protected]/dbName?sslmode=disable")
    if err != nil {
        fmt.Println(`Could not connect to db`)
        panic(err)
    }
    defer db.Close()
}

Selecting data from a table

After connecting to the database, you can do the following:

rows, err := db.Query(`SELECT * FROM table WHERE name=$1`, `Moz`)
if err != nil {
    panic(err)
}

var col1 string
var col2 string
for rows.Next() {
    rows.Scan(&col1, &col2)
    fmt.Println(col1, col2)
}
Categories
Uncategorized

Earn more by learning Go!

According to this article a friend forwarded to me, software developers who learn Go, Python or Scala (along with tech like Apache Spark) have found it easier to find jobs with better salaries. Learning Scala caused the highest boost and in the second place was Go.

Learning python is a bit subjective in terms of getting a raise. It depends on what you are doing and which field you are in. So the increase in income with Python isn’t as consistent as it is with the other 2 languages.

Here is the article in detail: http://www.infoworld.com/article/3071623/salary/want-to-boost-your-salary-learn-scala-golang-or-python.html

Categories
Uncategorized

Golang: Testing HTTP requests

Unit testing HTTP calls to external services is pretty easy in Go. Let’s say we have some code that makes HTTP requests like so:

package something

import (
    "net/http"
)

func SomeFunc(url) string {
    rs, _ := http.Get(url)
    defer rs.Body.Close()
    body, _ := ioutil.ReadAll(rs)

    return string(body)   
}

We can test if the request is made and we get the response we want by mocking the external service. Below is the code:

package something

import (
    "net/http/httptest"
)

/**
This code uses Ginkgo and Gomega for unit tests but this can be easily adopted to any other framework or vanilla Go tests
**/
var _ = Describe("It makes HTTP requests", func () {
    Context("In some context", func () {
        It("makes an HTTP response which returns something", func() {
            server := httptest.NewServer(http.HandlerFunc(func(rs http.ResponseWriter, rq *http.Request) {
                if rq.RequestURI == `/` {
                    content := "Hello"
                    if err != nil {
                        fmt.Println("FL", err)
                    }
                    rs.Write(content)
                }
            }))
            defer server.Close()

            // If we were testing for the response, we do assert it.  
            Expect(someFunc(server.URL)).To(Equal("Hello")
        }
    })
})
Categories
Uncategorized

Golang: Make HTTP requests

A simple GET request can be made like this:

package main

import (
    "net/http"
    "ioutil"
)

func main() {
    // Make a get request
    rs, err := http.Get("https://google.com")
    // Process response
    if err != nil {
        panic(err) // More idiomatic way would be to print the error and die unless it's a serious error
    }
    defer rs.Body.Close()

    bodyBytes, err := ioutil.ReadAll(rs.Body)
    if err != nil {
        panic(err)
    }

    bodyString := string(bodyBytes)
}

POST request:

import (
    "bytes"
)
func main() {
    body := []byte("key1=val1&key2=val2")
    rs, err := http.Post("http://someurl.com", "body/type", bytes.NewBuffer(body))
    // Code to process response (written in Get request snippet) goes here

    // Simulating a form post is done like this:
    rs, err := http.PostForm("http://example.com/form",
                            url.Values{"key": {"Value"}, "id": {"123"}})
    // Code to process response (written in Get request snippet) goes here
}

If more control is needed, like specifying headers, cookies, etc:

// ...
client := &http.Client{}
req, err := http.NewRequest("GET", "http://example.com", nil)
req.Header.Add("If-None-Match", `some value`)
resp, err := client.Do(req)
// Code to process response
Categories
Uncategorized

Golang: Polymorphism

Polymorphism is a bit different in Go. It supports polymorphism only through interfaces (and not through inheritance). To help you understand better, here is an example:

import "fmt"

type Car interface {
    func Drive()
}

type Lamborgini struct {
    // Implement the Car interface
    func Drive() {
        fmt.Println("Driving")
    }
}

func driveACar(car Car) {
    car.Drive()
}

// This will work 
lambo := new(Lamborgini)
lambo.Drive() // Will work 
driveACar(lambo)  // Will print "Driving"

However, Polymorphism doesn’t work when driveACar(lammborgini) would not work if Car was a struct and not an interface. Here is an example:

import "fmt"

type Car struct {
    func Drive() {
        fmt.Println("Driving")
    }
}

type Lamborgini struct {
    Car
}

func driveACar(car Car) {
    car.Drive()
}

lambo := new(Lamborgini)
lambo.Drive() // Will call car's Drive method and will work
driveACar(lambo)  // Will throw an error
Categories
Uncategorized

Don’t waste time

A friend of mine sent me an interesting quote by Imam Ghazali which puts things in perspective.

Your time should not be without any structure, such that you occupy yourself arbitrarily with whatever comes along.
Rather, you must take account of yourself and order your worship during the day and the night, assigning to each period of time an activity that must not be neglected nor replaced by another activity.
By this ordering of time, the blessing in time will show itself. A person who leaves himself without a plan as animals do, not knowing what he is to do at any given moment, will spend most of his time fruitlessly.
Your time is your life, and your life is your capital: by it you make your trade, and by it you will reach the eternal bounties in the proximity of Allah.
Every single breath of yours is a priceless jewel, because it is irreplaceable; once it is gone, there is no return for it.
So do not be like fools who rejoice each day as their wealth increases while their lives decrease. What good is there in wealth that increases while one’s lifespan decreases?
Do not rejoice except in an increase of knowledge or an increase of good works.
Truly they are your two friends who will accompany you in your grave, when your spouse, your wealth, your children, and your friends will remain behind.
— Imam al-Ghazali

Categories
Uncategorized

Go: Declaring and using objects

Go (or Golang) doesn’t have the concept of classes. The class equivalent in Go loos like this:

  // Make a Car class equivalent
  type Car struct {
    // object properties go here
    doors int

  }

  // Get the number of doors 
  func (car *Car) Doors() int {
    return car.doors
  }

  // Set the number of doors in a car
  func (car *Car) SetDoors(doors int) {
    car.doors = doors
  }

The above declaration can now be used as an object like so:

  import fmt

  func main() {
    lamborgini := new(Car)
    lamborgini.setDoors(2)

    fmt.Println("This lamborgini has: " + lamborgini.Doors()  + " Doors")    
  }

Categories
Uncategorized

First impressions of Go

I have been in search for a language I can use for web programming, writing computationally intensive and general scripting among other things. The language that came close to fitting all of these things was Racket, a dialect of Chicken Lisp. It can even do geometry drawings. However, there were issues with it so I ended up concluding it wasn’t that language in was in search of.

I started learning Go some time ago and, at first, found its syntax backwards. Declaring types after variable names was hard to get used to. And, the syntax for writing “classes” is even more weird. However, when I found out that Go supported concurrency (and parallelism) natively, I was intrigued. On a side note: default Python and Ruby interpreters do not support parallelism. PHP has some support through pthreads but using it could mean you not being able to use other extensions.

If you want to have a true parallel app in Ruby or Python you have to get the interpreter that runs on JVM. So, you Ruby code is run by the Ruby interpreter which is running on JVM. Ruby and Python support concurrency but their threads run one at a time. So, no parallelism.

Once you get past the syntax weirdness, Go is actually a pretty cool language. It makes it easy to write concurrent apps. They call them “go routines”. From what I have learned, go routines are cheaper to create and maintain than normal threads and the way Go is designed, it is very easy to communicate between threads (using channels). And, all of this makes sense since one of the goals of Go was to make multi-threaded network applications.

Those used to dynamic languages might find it a bit difficult to work with Go in the beginning as it is strongly typed. I was, however, able to adjust pretty easily (then again I have done C++, Java and C# in the past). Your mileage may vary but I highly recommend trying it out. You might like it.

Categories
Arduino Uncategorized

Programming Macros for Ergodox

The default configuration tool on Input Club or Massdrop don’t allow for macro programming. So you will have to get your hands dirty and mess with the firmware code a little. It’s not hard.

  1. Run the following commands on your terminal to clone Ben Blazak’s firmware code from github and create a custom layout for yourself
              git clone https://github.com/benblazak/ergodox-firmware.git
              cd ergodox-firmware
              # Macros are supported in his partial re-write branch 
              git checkout partial-rewrite
              cp firmware/keyboard/ergodox/layouts/qwerty--ben.c firmware/keyboard/ergodox/layouts/qwerty--custom.c
          
  2. Open keyboard/ergodox/options.mk and add qwerty–custom to the KEYBOARD_LAYOUTS and change the KEYBOARD_LAYOUT to qwerty–custom. The keyboard layout will look something like this :

    KEYBOARD_LAYOUT := qwerty--custom
    # default layout for this keyboard
    
    KEYBOARD_LAYOUTS := \
        test \
        arensito--ben \
        qwerty--ben \
        qwerty--custom \
        colemak--kinesis-mod \
        dvorak--kinesis-mod \
        qwerty--kinesis-mod
            
  3. Edit keyboard/ergodox/layout/fragments/macros.part.h and create a function for your macro. As an example, we will do a macro that prints b4.

    // Define a constant for the keys
    #define K_4 0x5C   // 4
    #define K_b 0x05   // b
    
    // Our macro's name is m_b4
    void keys__press__m_b4(void) {
        // Press and release b
        usb__kb__set_key(true, K_b);
        usb__kb__send_report();
        usb__kb__set_key(false, K_b);
        usb__kb__send_report();
    
        // Press and release 4
        usb__kb__set_key(true, K_4);
        usb__kb__send_report();
        usb__kb__set_key(false, K_4);
        usb__kb__send_report();
    }
    
    // Do this for all your macro functions
    void R(m_copy)(void) {}
    
          
  4. Now that the macro is ready, it can be placed in the layout. Put m_b4 for whichever key you want the macro to trigger. Edit firmware/keyboard/ergodox/layouts/qwerty–custom.c and put your macro in it.

        MATRIX_LAYER(  // layer 2 : symbols and function keys
    // macro, unused,
           K,    nop,
    // left hand ...... ......... ......... ......... ......... ......... .........
      lpo2l2,       F1,       F2,       F3,       F4,       F5,      F11,
      transp,   braceL,   braceR,    brktL,    brktR,      nop,   lpo2l2,
      transp,  semicol,    slash,     dash,        0,    colon,
      transp,        6,        7,        8,        9,     plus, lpupo3l3,
      transp,   transp,   transp,   transp,   transp,
                                                                  transp,     m_b4,
                                                        transp,   transp,   transp,
                                                        transp,   transp,   transp,
    // right hand ..... ......... ......... ......... ......... ......... .........
                   F6,       F7,       F8,       F9,       F10,      F11,      F12,
                lpo2l2,    caret,  undersc, lessThan, grtrThan,   dollar,  volumeU,
                         bkslash,        1,   parenL,   parenR,    equal,  volumeD,
              lpupo3l3, asterisk,        2,        3,        4,        5,     mute,
                                    transp,   transp,   transp,   transp,   power,
      transp,   transp,
      transp,   transp,   transp,
      transp,   transp,   transp  ),
    
    
    
  5. In the terminal, run make It will create firmware.hex
    Upload the file to Ergodox and your macro will be ready for use.

You can look up the hex codes for keys here: http://www.usb.org/developers/hidpage/Hut1_12v2.pdf