EduSearch Network is hiring a Javascript Hacker

After over a year of working at EduSearch Network, Inc., I decided to move on to explore different opportunities. I have learned so much from Edusearch and grown as a developer as well as a team player. The whole experience has been amazing. Now that I am leaving, I do want to look for someone to replace my role at Edusearch.

I was a full stack dev at Edusearch. My role spanned from handling CakePHP back end, front end Javascript, to dev-ops, and database management. You will pretty much own the whole vertical just like me but your role will incline towards Javascript significantly. The position is based out of downtown Los Angeles.

Working at Edusearch is phenomenal. You have full code ownership. You have freedom to pick the right tool for the job. The team is small and moving fast. Team dynamic is amazing. Everyone is relaxing and fun to be around with. You will learn so much here!

Some of the buzzed words that we throw around in our products:
– CakePHP
– Datatables, Highcharts,
– Twitter bootstrap
– AWS, CDN
– Scalability, load balancer
– Memcached, Redis
– Beanstalk
– Git

You don’t need to know any of those but you do need to be a fast learner. If any of those bullet points are of interest to you and you have a solid Javascript foundation, reach out to me at: khoi@ethandev.com with subject: “EduSearch Javascript Hacker”. I will ask some technical questions and move your resume along to the hiring manager. EVERY E-MAIL WILL BE REPLIED. Feel free to test your skills with some of these coding questions and send the source code along with your resume:
– Unflatten a nested array in Javascript into a simple array
– Set up a simple working demo of DataTables. This is our bloodline at Edusearch.

Stream manipulation with grep, sed, and xargs

It’s not unusual for a developer or data analyst to have the need to modify files with similar pattern across all board. Scenario: Say you have 100 files in your project that contain the text “ORANGE” and you want to replace them all into “APPLE.” A novice approach would be to manually open each file, look for ORANGE, and replace with APPLE. But we can do better with the following UNIX command:

grep -rl "ORANGE" . | xargs sed -i '' 's/ORANGE/APPLE/g'

Let’s see what’s going on here:

  • grep is UNIX command for searching text in files: ‘-r’ will search through all files recursively; ‘-l’ will force only file names to be return; “ORANGE” is our searching pattern; and finally ‘.’ specify where we are searching from, in this case, starting at current location
  • xargs: grep will usually output result to stdout. But this time, we will pipe (‘|’) it to xargs command, which turn the result into an array and invoke a new Unix command on each of the array element
  • sed (or stream editor), will take each of those file name and apply a regular expression search/replace pattern to it; ‘-i’ option will allow in-place editing of files and making an extention back-up. In this case, -i is passed with ” or there will be no back up (Make sure you know what you are doing here because it’s irreversible. ‘g’ option makes the search global throughout the stream;

And that’s it. There, we have successfully replaced 100 files with one simple command.

Bonus Scenario:
There are many .tmp files laying around in your project. How to delete them all?

find . -iname "*.tmp" | xargs rm

Again, make sure you know what you are doing because it’s irreversible.

Super Bonus Scenario:
This question comes up often in software developer’s job interview question: “How to extract out phone numbers in many huge files?”
My approach would be to use grep with clever regular expressions. How complicated does the pattern matching have to be in order to avoid under-match and over-match? That’d open an interesting conversation between the interviewer and the interviewee

Notes on Improving Memory


My reading habit has long been overdue so I am trying to get back in the saddle with at least one book (non-fiction) a month. This time, I stumbled upon a very interesting introductory read on human’s memory capacity: Moonwalking with Einstein: The Art and Science of Remembering Everything by Joshua Foer. The book picked up its steam (and came under my radar) through the recommendation of Bill Gates himself.

Ever wonder how some people can recite lengthy Pi number while most of us can’t go beyond 3.14? Or how a seemingly random grocery/to-do list can be memorized? This book will open your mind into the world of “mental athletes”. The author will walk you through his personal journey of how he, an average journalist, thrived to become U.S. Memory Championship’s winner. This is not a self-help book for those of you looking for a quick hack into instant memory enhancement; it’s a reading-for-pleasure book with useful beginner information into the world of memory.

Notes I collected about the world of memory:

  • Memory will persist if you can make it lively, buoyant, and bizarre; i.e.: having sushi on a woman’s body for lunch is much more memorable than your regular office lunch.
  • Most savants with incredible memory reportedly have a common mental health condition: every word and number has a distinct taste and visualization. That helps trigger their different senses aiding their unconscious memorization.
  • Memory by association: try to relate what you want to remember to something you already remember.
  • Human brain is mostly receptive and responsive to two things: sex and jokes; especially jokes about sex. Want to remember buying a can of milk? Try to think of Megan Fox pouring down milk all over her in a hot tub in the middle of Trader Joe’s. Now try to forget that. Cant? Me neither.
  • Mental athletes remember by remembering more. (More on that below: Major System).
  • Practice makes perfect!

Two simple memory techniques that the author mentioned:
They can be used to remember a long number or a list of random items:

  • Major System: for memorizing number. You have to come up with a list of images associated with all numbers between 00 and 99. The numbers have to follow this rule. Then instead of remembering a meaningless number 524157, you get to remember something more fun like “a LION is playing with a HEART shape object(probably in love) inside a LAKE.” Now in order to recall the number, pick up “LION, HEART, and LAKE” and match them with the pre-defined table in your memory. It may sound idiotic at first to remember a pre-defined list of 100 numbers, but the return is worth it. I am currently playing around with this system.
  • Memory Palace (Loci): for memorizing a list of random items. Pick a familiar place to you (your house, your bedroom etc…). Walk around the house and drop each item from the list in a unique location. Try to associate each item with something bizarre (see above). Now in order to recall the list, you just have to trace back through the building.

This intro won’t do justice, so go ahead and grab the book. It’s an easy and fun read!

Note: I am actually working on an iPhone app to assist people in training through Major System. If you are interested in the release date, its functionality, or having any oppinions on the app, leave your comment below or e-mailing at khoi@ethandev.com

How to Set up a Git Repo on Dropbox

Last weekend, I was finally able to persuade my co-worker to join me in a hackathon. It is an annual event where a herd of passionate coders gather together and hack away any projects (web/mobile/hardware) in a timeframe of 2 days to compete for prizes, glories, and/or VC’s/angel investors’/employers’ attention. The only requirement is that the project has to be within Hollywood theme — media and entertainment. Being hosted for the 2nd time, it already attracted a lot more developers/sponsors and had a better location than last year. Our project was PlayFrame — a simple Twitter meets online presentation to display concise messages. (Check out a wicked neat project done by my new friend from the Hackathon, Anand,: Fotage).

Anyways, my team was discussing about how to collaborate and set up our development environment. Some obvious options comes to mind: GitHub and Beanstalk. However, we wanted to try something different this time. Being Dropbox addicts, we tried to figure out how to set up a Git repository on it (from my awesome co-worker/teammate’s idea). After all, Dropbox is amazing with syncing files, which makes it ideal for this purpose. Here are the steps of how we did it and you can replicate them easily:

Set up a Git Repo on Dropbox

1) Go to your dropbox shared folder ~/Dropbox/projects/
2) Make a new git repo directory ex. > mkdir project1.git
3) Create a blank repo ex. > cd project1.git; git init --bare;
4) Now you can clone the directory and share it with your teammate

Clone the git repo and ready for development

1) Go to your favorite project directory ex. ~/projects
2) Clone one of the git projects in this directory.
ex. git clone ~/Dropbox/projects/projectx.git
3) Now you can edit, commit and push the files back to the shared directory.

Do a git push and wait for the Dropbox icon to sync. On the other hand, if you see your Dropbox signals a new sync, you know it’s time to do a git pull

That’s it! You officially have a private Git repository that can be collaborated by as many developers as you wish to share with.

Some tips developing iOS apps with Appcelerator Titanium

I just got my first free app, Khan Archiver, approved under iOS store. It was quite an exciting experience. However, more time was actually spent wresting with Titanium SDK, and waiting for app approval, than development itself.

These are some tricks I learned throughout my struggling and have I known of them before, life would have been much easier

  • Push your app out for App store review as soon as possible even if you don’t have all the features in place. It’s important to get in the queue and start getting feedbacks from App Store review. Along the way, you may have violated their development guidelines so it’s better sooner than later to find out.
  • My app got rejected the first time because I tried to store my database/library under “applicationDataDirectory.” Apple implemented an iCloud mechanism that will back up everything under that folder so they only allow critical user-generated non-retrievable information to be stored in that area.
    Other stuff that can be recreated or downloaded has to be under /Library/Caches/ folder. Appcelerator does not have a variable to access that folder yet. A work around I used is:

    var file = Titanium.Filesystem.getFile( Titanium.Filesystem.applicationDataDirectory + "../Library/Caches/" + file_name )
  • When I tried to deploy an update for my app, I got a persistent error message 65, even though simulation and install on device work properly. I reinstalled Titanium and XCode but it was still no vail. I then discovered that there were actually 2 distribution certificates in my Keychain Access and the expired one replaced the ‘legit’ one. It turnes out that every time you make a deployment (through Appcelerator at least), XCode will duplicate a random expired certificate to your Keychain Access (weird? I don’t know why). And if you remove the wrong one, you are screwed. Work around: keep your original distribution .cer and remove the old ones in Keychain Access with it.

So far so good. Happy coding!