Byte arrays and Channels

Hi folks and a Happy new Year! Today, I would like to show you some interesting things you can do with channels. Consider the following simple example. package main import "fmt" func main() { generatedPassword := make(chan int, 100) correctPassword := make(chan int) defer close(generatedPassword) defer close(correctPassword) go passwordIncrement(generatedPassword) go checkPassword(generatedPassword, correctPassword) pass := <-correctPassword fmt.Println(pass) } func checkPassword(input <-chan int, output chan<- int) { for { p := <-input //Introduce lengthy operation here // time.Sleep(time.Second) fmt.Println("Checking p:", p) if p > 100000 { output <- p } } } func passwordIncrement(out chan<- int) { p := 0 for { p++ out <- p } } The premise is as follows. It launches two go routines. One, which generates passwords, and an other which checks for validity. The two routines talk to each other through the channel generatedPassword. That’s the providing connections between them. The channel correctPassword provides output for the checkPassword routine. ...

January 1, 2016 · 4 min · hannibal

Use Byte Array Instead of Strings

Hello Folks. This is just a quick post on the topic and a reminder for myself and everybody to ALWAYS USE []BYTE INSTEAD OF STRINGS. []Byte is marginally faster than a simple Strings. In fact, I would say using []byte should be the standard instead of strings. Sample code: package solutions import "fmt" const ( //INPUT input INPUT = "1321131112" //LIMIT limit LIMIT = 50 ) //LookAndSay translates numbers according to Look and Say algo func LookAndSay(s string, c chan string) { charCount := 1 look := "" for i := range s { if i+1 < len(s) { if s[i] == s[i+1] { charCount++ } else { look += fmt.Sprintf("%d%s", charCount, string(s[i])) charCount = 1 } } else { look += fmt.Sprintf("%d%s", charCount, string(s[i])) } } c <- look } //GetLengthOfLookAndSay Retrieve the Length of a lookandsay done Limit times func GetLengthOfLookAndSay() { c := make(chan string, 0) go LookAndSay(INPUT, c) finalString := <-c for i := 0; i <= LIMIT-2; i++ { go LookAndSay(finalString, c) finalString = <-c // fmt.Println(finalString) } fmt.Println("Lenght of final String:", len(finalString)) } This, with the limit raised to 50 run for ~1 hour. Even with the routines although they were just for show since they had to wait for each others input. ...

December 29, 2015 · 2 min · hannibal

Use Byte Slice Instead of Strings

Hello Folks. This is just a quick post on the topic and a reminder for myself and everybody to ALWAYS USE []BYTE INSTEAD OF STRINGS. []Byte is marginally faster than a simple Strings. In fact, I would say using []byte should be the standard instead of strings. Sample code: package solutions import "fmt" const ( //INPUT input INPUT = "1321131112" //LIMIT limit LIMIT = 50 ) //LookAndSay translates numbers according to Look and Say algo func LookAndSay(s string, c chan string) { charCount := 1 look := "" for i := range s { if i+1 < len(s) { if s[i] == s[i+1] { charCount++ } else { look += fmt.Sprintf("%d%s", charCount, string(s[i])) charCount = 1 } } else { look += fmt.Sprintf("%d%s", charCount, string(s[i])) } } c <- look } //GetLengthOfLookAndSay Retrieve the Length of a lookandsay done Limit times func GetLengthOfLookAndSay() { c := make(chan string, 0) go LookAndSay(INPUT, c) finalString := <-c for i := 0; i <= LIMIT-2; i++ { go LookAndSay(finalString, c) finalString = <-c // fmt.Println(finalString) } fmt.Println("Lenght of final String:", len(finalString)) } This, with the limit raised to 50 run for ~1 hour. Even with the routines although they were just for show since they had to wait for each others input. ...

December 29, 2015 · 2 min · hannibal

Recursive Letter Frequency Count

Hello everybody! I wanted to do a sort post about word frequency count. I did it many times now and I was curious as how a recursive solution would perform as opposed to looping. So I wrote it up quickly and added a few benchmarks with different sized data. First…. The code: var freqMap = make(map[string]int, 0) func countLettersRecursive(s string) string { if len(s) == 0 { return s } freqMap[string(s[0])]++ return countLettersRecursive(s[1:]) } func countLettersLoop(s string) { for _, v := range s { freqMap[string(v)]++ } } Very simple. The first run with a small sample: “asdfasdfasdfasdfasdf” ...

December 23, 2015 · 1 min · hannibal

Go Development Environment

Hello folks. Here is a little something I’ve put together, since I’m doing it a lot. Go Development Environment If I have a project I’d like to contribute, like GoHugo, I have to setup a development environment, because most of the times, I’m on a Mac. And on OSX things work differently. I like to work in a Linux environment since that’s what most of the projects are built on. So here you go. Just download the files, and say vagrant up which will do the magic. ...

December 8, 2015 · 1 min · hannibal

Welcome To My New Blog

Hello Folks Welcome to my new blog. I decided to move away for a number of reasons, but setting up a static page blog site is very cool if you don’t directly use a database. Since posts are just posts and I have a different way of hosting images, this really was just a matter of time. And Hugo / Github pages provided the tools which made this move possible. Also, I love writing this post in Markdown. I always liked the formatting rules of it, so this is quiet the blast. ...

December 7, 2015 · 1 min · hannibal

Go JIRA API client

Hi folks. So, I was playing around and created a client for JIRA written in Go. It was nice to do some JSON transformation. And sending POSTS was really trivial. It’s still in it’s infancy and I have a couple of more features I want to implement, but, here is the code. package main import ( "bytes" "encoding/json" "flag" "fmt" "io/ioutil" "log" "net/http" "os" "github.com/BurntSushi/toml" ) var configFile = "~/.jira_config.toml" var parameter string var flags struct { Comment string Description string IssueKey string Priority string Resolution string Title string Project string } //Issue is a representation of a Jira Issue type Issue struct { Fields struct { Project struct { Key string `json:"key"` } `json:"project"` Summary string `json:"summary"` Description string `json:"description"` Issuetype struct { Name string `json:"name"` } `json:"issuetype"` Priority struct { ID string `json:"id"` } `json:"priority"` } `json:"fields"` } //Transition defines a transition json object. Used for starting, stoppinp //generally for state stranfer type Transition struct { Fields struct { Resolution struct { Name string `json:"name"` } `json:"resolution"` } `json:"fields"` Transition struct { ID string `json:"id"` } `json:"transition"` } //Credentials a representation of a JIRA config which helds API permissions type Credentials struct { Username string Password string URL string } func init() { flag.StringVar(&flags.Comment, "m", "Default Comment", "A Comment when changing the status of an Issue.") flag.StringVar(&flags.Description, "d", "Default Description", "Provide a description for a newly created Issue.") flag.StringVar(&flags.Priority, "p", "2", "The priority of an Issue which will be set.") flag.StringVar(&flags.IssueKey, "k", "", "Issue key of an issue.") flag.StringVar(&flags.Resolution, "r", "Done", "Resolution when an issue is closed. Ex.: Done, Fixed, Won't fix.") flag.StringVar(&flags.Title, "t", "Default Title", "Title of an Issue.") flag.StringVar(&flags.Project, "o", "IT", "Define a Project to create a ticket in.") flag.Parse() } func (cred *Credentials) initConfig() { if _, err := os.Stat(configFile); err != nil { log.Fatalf("Error using config file: %v", err) } if _, err := toml.DecodeFile(configFile, cred); err != nil { log.Fatal("Error during decoding toml config: ", err) } } func main() { if len(flag.Args()) < 1 { log.Fatal("Please provide an action to take. Usage information:") } parameter = flag.Arg() switch parameter { case "close": closeIssue(flags.IssueKey) case "start": startIssue(flags.IssueKey) case "create": createIssue() } } func closeIssue(issueKey string) { if issueKey == "" { log.Fatal("Please provide an issueID with -k") } fmt.Println("Closing issue number: ", issueKey) var trans Transition //TODO: Add the ability to define a comment for the close reason trans.Fields.Resolution.Name = flags.Resolution trans.Transition.ID = "2" marhsalledTrans, err := json.Marshal(trans) if err != nil { log.Fatal("Error occured when marshaling transition: ", err) } fmt.Println("Marshalled:", trans) sendRequest(marhsalledTrans, "POST", issueKey+"/transitions?expand=transitions.fields") } func startIssue(issueID string) { if issueID == "" { log.Fatal("Please provide an issueID with -i") } fmt.Println("Starting issue number:", issueID) } func createIssue() { fmt.Println("Creating new issue.") var issue Issue issue.Fields.Description = flags.Description issue.Fields.Priority.ID = flags.Priority issue.Fields.Summary = flags.Title issue.Fields.Project.Key = flags.Project issue.Fields.Issuetype.Name = "Task" marshalledIssue, err := json.Marshal(issue) if err != nil { log.Fatal("Error occured when Marshaling Issue:", err) } sendRequest(marshalledIssue, "POST", "") } func sendRequest(jsonStr []byte, method string, url string) { cred := &Credentials{} cred.initConfig() fmt.Println("Json:", string(jsonStr)) req, err := http.NewRequest(method, cred.URL+url, bytes.NewBuffer(jsonStr)) req.Header.Set("Content-Type", "application/json") req.SetBasicAuth(cred.Username, cred.Password) client := &http.Client{} resp, err := client.Do(req) if err != nil { panic(err) } defer resp.Body.Close() fmt.Println("response Status:", resp.Status) fmt.Println("response Headers:", resp.Header) body, _ := ioutil.ReadAll(resp.Body) fmt.Println("response Body:", string(body)) } It can also be found under my github page: GoJira Github. ...

November 20, 2015 · 3 min · hannibal

The One Hundred Day GitHub Challenge

Hello folks. Today, I present to you the One Hundred Day Github Challenge. The rules are simple: Minimum of One commit every day for a Hundred days. Commit has to be meaningful but can be as little as a fix in a Readme.md. Doesn’t matter if you are on vacation, there are no exceptions. There. Are. No. Exceptions. If you fail a day, you have to start over. No cheating. You only cheat yourself, so this is really up to you. Let me be more clear here, because it seems I wasn’t clear enough. What you make out of this challenge, it’s up to you. If you just update a readme.md for hundred days, that’s fine. Just do it every day. It’s a commitment. At least you’ll have a nice Readme. ...

November 15, 2015 · 1 min · hannibal

Go Progress Quest

Hi Folks. I started to build a Progress Quest type of web app in Go. If you’d like to join, or just tag along, please drop by here => Go Progress Quest and feel free to submit an issue if you have an idea, or would like to contribute! I will try and document the Progress. Thank you for reading! Gergely.

November 9, 2015 · 1 min · hannibal

Kill a Program on Connecting to a specific WiFi – OSX

Hi folks. If you have the tendency, like me, to forget that you are on the corporate VPN, or leave a certain software open when you bring your laptop to work, this might be helpful to you too. It’s a small script which kills a program when you change your Wifi network. Script: #!/bin/bash function log { directory="/Users/<username>/wifi_detect" log_dir_exists=true if [ ! -d $directory ]; then echo "Attempting to create => $directory" mkdir -p $directory if [ ! -d $directory ]; then echo "Could not create directory. Continue to log to echo." log_dir_exists=false fi fi if $log_dir_exists ; then echo "$(date):$1" >> "$directory/log.txt" else echo "$(date):$1" fi } function check_program { to_kill="[${1::1}]${1:1}" log "Checking if $to_kill really quit." ps=$(ps aux |grep "$to_kill") log "ps => $ps" if [ -z "$ps" ]; then # 0 - True return else # 1 - False return 1 fi } function kill_program { log "Killing program" `pkill -f "$1"` sleep 1 if ! check_program $1 ; then log "$1 Did not quit!" else log "$1 quit successfully" fi } wifi_name=$(networksetup -getairportnetwork en0 |awk -F": " '{print $2}') log "Wifi name: $wifi_name" if [ "$wifi_name" = "<wifi_name>" ]; then log "On corporate network... Killing Program" kill_program "<programname>" elif [ "$wifi_name" = "<home_wifi_name>" ]; then # Kill <program> if enabled and if on <home_wifi> and if Tunnelblick is running. log "Not on corporate network... Killing <program> if Tunnelblick is active." if ! check_program "Tunnelblick" ; then log "Tunnelblick is active. Killing <program>" kill_program "<program>" else log "All good... Happy coding." fi else log "No known Network..." fi Now, the trick is, on OSX to only trigger this when your network changes. For this, you can have a ’launchd’ daemon, which is configured to watch three files which relate to a network being changed. ...

October 26, 2015 · 2 min · hannibal