Monday, February 13, 2017

Some Helpful Resources

Recently I was prompted to compile a few of the resources that have helped me become a better developer. Below are a some books, blogs, and other odds and ends that I've found helpful. It's not comprehensive by any means, so take what you're able to from it.


Mother. Fucking. Tar.


This doesn't exactly fit in the list, but it's caused me more headaches than I care to admit. No matter how many times I've typed that goddamn command, it took forever to remember it. Here's a reference forever for me and anyone else who needs to know how to get files out of a damn tarball.

Extracting a tarball:

tar -xzf theTarBall.tar.gz
The way I remember it is by saying in my head "extract zee file".

Create a tarball:

tar -czf nameOfTarFile.tar.gz directoryOrFileToCompress
I remember this one with  "compress zee file".

Remember that the 'f' goes at the end because it's always followed by the name of the tarball to be extracted or created.

Helpful Books

Release It! -- Michael T. Nygard
This book is incredible for understanding how to build solid, scalable systems with sensible interactions. It references some dated technology, but has excellent real world examples of how to build flexible APIs and rebust services.
Clean Code -- Robert C. Martin
While not everything in this book is useful, I've found a majority of it suggests some helpful practices for writing good code. At best you'll love it, and at worst you'll spend a lot of time thinking about how you want the code to read.
Head First Design Patterns -- Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra
Honestly, I really hated this book. However, of everyone I've met who has read other design pattern books, they say this is the best. Other books worth looking at are Patterns of Enterprise Application Architecture by Martin Fowler, and the 'Gang of Four' book.
Machine Learning -- Kevin P. Murphy
This is more tangentially related to programming, and nevertheless is an excellent intro to machine learning. It details the theory as well as the practice.

Helpful Blogs/Websites

Call Me Maybe? -- https://aphyr.com/tags/jepsen
I wasn't able to grasp how eventually consistent systems work until I found this blog. 'Aphyr' (Kyle Kingsbury) does an excellent job of explaining why commonly used distributed systems fail and how they should actually work.
Eloquent Javascript -- http://eloquentjavascript.net
This is one of the best 'Intro to Programming' resources I've found. It's simple, detailed, and interactive. It's one I almost always recommend to folks who want to learn the how/what/why of coding.
The Twelve Factor Application -- https://12factor.net/
Awesome resource detailing some best practices for developing modern applications.

New Hotness Technology


This is likely dated, but here are is some tech that's hot right now and that I've found pretty useful:
  • AngularJS (Javascript framework)
  • Bootstrap (CSS framework)
  • Docker
  • Kubernetes
  • Drone
  • Go Lang
  • Riak 
  • Ratpack (https://ratpack.io)
  • Reactive (http://reactivex.io/)
  • Spring 5*
*Caution: Not really done yet... and not really hot. Spring is something that's nice to know but can be a mega pain in the ass.

Also do some googling on 'DevOps'.

Other Misc. Thoughts


Test Test Test


Get good at writing tests. I didn't link any resources because I haven't found any that do an awesome. Here are some things to think about when testing:

  • How will my program respond to unexpected inputs?
  • What is the best way to structure a program so that I'm only ever testing small amounts of code?
  • Will my tests fail if I change the way my code works?

Get comfortable in a linux/unix shell


Knowing how to operate in only a terminal is imperative. When remote connecting to a server to debug something broken, there isn't a GUI. Learn how to use:
  • less
  • cat
  • grep
  • ssh
  • ssh-keygen
  • scp
  • vim (or emacs)
  • cd
  • ls 
  • rm
  • mkdir
And a shitton of others. Spend time in a terminal, and it will make everything easier in the long run. 

Learn a few languages


I've found that, while knowing multiple programming languages isn't necessary, it's incredibly useful. Having multiple languages means there are more tools available to solve a problem. More importantly, it help reveal why one language is used over another. Also, as a former coworker and brilliant person Nate Ashford said, "Solving a problem in one language often reveals the easiest solution in another". Using another language can often force a developer to look at the problem in a different, and better, way.

Build something


Find a problem that's simple in your life that's interesting, and appears to be simple. For example, my new puppy gets homesick when we're gone, and so every day we play her radio. I quickly got sick of manually doing this, and hacked together a crap program called 'autoCaster'. Now everyday at 7 am, my script casts the radio to my chromecast audio, and at 6 turns it off. I recommend doing something hacky, and simple like this -- try using some of the new hotness tech to do it!

Remember that no one really knows how to code


In terms of a discipline, software development is still new. There isn't a right way to solve every problem, and years of development don't always make someone a better developer. It's hard to know that, though, because many developers assert opinions as facts. For example, you'll probably here things like this:

  • "The only way to do this is..."
  • "That's one way to do it, but the right way is to..."
  • "I can't believe anyone would ever right the code in this way..."
They may be correct, but it's important to remember that it might be a load of shit.

Most importantly, it's best to be open to input, to critique others both honestly and kindly, and most importantly to listen, listen, listen.  




Wednesday, January 22, 2014

Avoiding Dynamic DNS using D, cURL, and Gmail


After buying a C720 to use as a remote keyboard/screen for my home computer, I quickly realized I needed an easy way to sync my files between the two computers.  Since google drive still doesn't support Linux, my choices were to sign up for a free dynamic dns service or to constantly check my home IP and copy it to my laptop.  I'd been looking for more excuses to code in D, and so I decided to write a simple dynamic dns replacement using cURL and one of my junk mail Gmail accounts.

The concept behind a dynamic dns service is fairly simple.  For a client computer to connect to a host computer, the client needs to know the host's IP.  If the host's computer doesn't have a statically set IP, the client computer can't connect, because the IP is constantly changing.  To avoid this, use a third computer, with a static IP, to pass the current IP from the host to the client.  That's essentially what my code does, but instead of using a service like dynDNS I used Gmail and two programs (a host and a client) to send/receive the new IP.

Using D and cURL made writing the host and client executables fairy simple.  For the host executable, I needed to write some code that kept track of the current IP and previous IPs, and updated the IP address when it changed.  To track the IP address, I had the host program check and update a csv file with the date stamp of the last time an IP address changed.  To check the current IP I used ipecho.net.  I then scheduled the program to run every 25 minutes with cron and was done.  (If you're interested in setting this up yourself I would recommend scheduling the task for 25-30 minutes to avoid abusing the ipecho website. It's enough time so that if you're at a coffee shop and lose access to your home computer during one of those thousand coffee pee breaks, you won't have to wait around too long for the updated IP to arrive).

The client program is just as simple as the host program, but relies on some prior configuration in gmail.  In order to keep the client progam simple, I relied on the gmail automated filter options to take the email with the new IP from the host program, and automatically file it away to a unique, predetermined, folder.  This filter can be anything that ensures that /only/ the IP update emails are filtered away.  Since I'm using a junk email address, I ensured that the filter checked the to and from address lines (both are set to me) and the title of the email (an arbitrary long name).  The other nice side effect of this setup is that the newest email always has the most recent IP.  Getting the email is then simple; just use the curl imap support to get mail and we're done!  The IP is saved in a file called "ip_address.txt".  

One other step I chose to implement was a pseudo-cipher for the IP address.  Initially I was afraid that Google would see my IP, or that someone else may intercept the IP in transit and attempt to hack me.  After further reflection both seem a bit unlikely, so I included a version of the code that just sends and receives the IP from gmail.  The one fun part of the ciphered IP address is that it has a sort of 'mad-lib' quality.  To make the cipher I wrote a lengthy sentence, and replaced all of the words with their grammatical equivalents.  For example:

"Google should really get google drive working on Linux" ==> becomes ==>
"noun should really verb noun noun gerund on noun"

I then just created an array with 11 words for each array type, and picked the word by adding the ip number to and offset, and taking it modulus 11 (11 for 0-10, where 10 is null).  It was fun to make, but in the end not necessary.  It's all contained in the configuration file, which also holds the email username, password, filter name, email subject name.

I've been running the code for a few weeks now and it works pretty great.  This obviously isn't a perfect replacement for those who want to host a webserver at their home address, but it's convenient for easy file syncing and ssh sessions.  Also, I'm sure there are probably a few issues that will crop up, but I've been pleased with the success of the project.  It's nice working on a project that I actually use in my day-to-day life :).

Compiling the Code
I ended up using LDC (D llvm compiler) for my Makefile, but any other compiler should work as well, as long as curl is installed.

Source

Monday, December 23, 2013

Attempting to Fix Android's Back

Problem Overview

Android app switching is often both slow and confusing.  If a user wants to switch from the current app to the most recently used app, they have more than one way to make that switch.  The easiest way is to tap the recent applications button, and then choose the app the most recent app.  Users can also go to home launcher, and then choose the recent app from its shortcut icon.  And for the most confusing way; a user can sometimes get to the most recently used app by pressing the back button.  With the exception of the last method, each of these steps takes a minimum of two screen taps, and the last method often takes multiple taps.  Although two taps isn't a significant amount of time relative to the age of the universe, I figured it would be a fun project to try and improve these actions.  In the end I would say I've been kinda, sorta, but not really, successful.

Fixing the Issues

At first my plan was to edit everything about the way the back and recent apps buttons worked by adding a new recent apps list and simplified back button actions, but after digging through the android source I realized that would require a ton of work.  I would have needed to reinvent and create new actions and a whole new set of functions and classes, more of a challenge than I really wanted to take on.  So, in the interests of time and laziness, I decided to steal some already existing code, and come up with a simple modification that would make a significant effect.  The end result was an "overloading" the back and recent apps buttons resulting in quick app switching by a simple modification to the Google Now launcher code.

When a user launches Google Now, they hold down the home button and swipe up, an "overload" of the home button.  In order to implement my simple app switches, I used this same action to allow instant switching between the most recently used application by swiping left (overloading the back button) and the second most recently used app by swiping right (overloading the recent apps button).  




Using the Google Now code in the SearchPanelView apk, these modifications were easy, and to make the actions more obvious I added two icons "above" the back button and the recent apps button. (Technically they are next to the back and recent apps buttons due to my laziness.  Just use imagination you see them as beautifully crafted icons hovering gently above the back and recent apps buttons.)


With these new swiping gestures a user can go back to the most recently used application by  simply hold down the home button as if to activate Google Now, and swipe left. To access the second most recently used application, a user can swipe right to the "up" arrow icon.  I also decided that I am a fan of the way that iOS allows users to four finger swipe through the list of recently used applications, and so I allowed users to perform the same list iteration through  repeated swipes to the right.  The iteration stops when the end of the list is reached; it does not wrap to preserve the concept of ordered recent apps.


These new actions allow users to switch apps faster and more effectively than what is currently available.  I will say that going from two taps to a tap and a swipe may not seem like a speed boost on a fast and sexy device like the Nexus 5, but lower-end hardware would benefit from this action.  The recent apps list in android is notorious for slow loading, and even with the improvements that have been made, I think a tap and swipe is faster (or at least way more fun than waiting for the recent apps list to load).  With the tap and swipe, the recent apps list doesn't need to be displayed or even loaded, saving a few seconds of time.  

Another cool side-effect of these actions is that, users can move between three apps easily.  This comes in handy when a users needs to get information from one app to use in another.    Let's say I need to send my friend a piece of text from a web page.  Assuming it was not recently used, I need to go home, open the browser, copy the text, and switch back to google voice.  With this implementation once I have copied the text I can swipe right and presto!  I'm back in voice.  



Final Thoughts

After using this new system for the past two months, I'd say it really hasn't made a huge difference.  It's been helpful to quickly move back an application, but often the most recently used app is the home launcher, and there is already a button for that.  I tried to remove the home button from the recently used apps list, but that caused even more confusion.  The three app switching mentioned above I rarely used, because I kept forgetting that I could swipe right.

About the only actual added benefit I received from this modification was entertainment.  I often toy with my phone when I'm bored by swiping around the home screens or swiping up into Google Now.  With these new swipes I could swipe around my list of recently used apps, which I found more entertaining than looping 'round the home screens.  

Implementation and Source

The implementation of this code isn't very difficult, and is mostly localized to the SearchPanelView java file.  To recreate it you will also need to add icons to the GlowPadView associated with the Google Now launching (the ring you see when activating search intent).  I'd also recommend resizing the ring so that the icons sit directly on top of the back and recent apps buttons.  I was too lazy to make pretty icons or worry about the exact locations.  

Link to search panel code:  SearchPanelView.java

(Please note that there are probably some bugs in the modifications I made.  Don't expect perfection)

+Android