TypeScript Resources

Below is my recommended list of TypeScript Resources:

Are there other resources that I should add to the list?  Let me know.

Sucking less every sprint

After battling the feature for about a week, he could see the light at the end of the tunnel.  His comment to me was, “man, looking back I could have gotten this completed so much faster if I knew what I know now.”

Earlier this month we hired a recent C.S. graduate.  He had been working as an intern for several months, and with the transition to full-time he let me know that he wanted to take on a bigger task.  The timing was right and I assigned him a simple yet slightly more involved task than he was accustomed to, and he went to work.

During our morning standups each day he would indicated progress — and it truly was progress — but the final solution kept eluding him.  After four days he said during standup, “today is the day I will complete this feature.”  But it didn’t get done.  It took him an additional three days.

I don’t fault him at all for taking the amount of time that he did on this feature.  It was more difficult than he was used to, and he wanted to make sure he nailed it.  In the end, he did a great job.

What struck me was his statement about how quickly he could have completed the task had he known what he knew after he was done.  It seems obvious, doesn’t it?  In a way it’s part of becoming self-aware:

Self awareness
Self-awareness

OK, maybe not self-awareness. Maybe it’s closer to self-reflection. This helps us suck less every year:

I’ve often thought that sucking less every year is how humble programmers improve. You should be unhappy with code you wrote a year ago. If you aren’t, that means either A) you haven’t learned anything in a year, B) your code can’t be improved, or C) you never revisit old code. All of these are the kiss of death for software developers.

I’d go as far as to say that you should suck less every sprint. If you’re not self-aware, if you’re not continually self-reflecting — you are dying as a programmer. If your team slogs through sprint after sprint, release after release, without any time to reflect on recent work, and how it could have been improved, it may die. Or at least lose momentum. Which may turn you into a zombie.

How to Start a Django REST Framework project

Lately I’ve been working with Django REST framework.  Here are some notes to get you started:

1. Create a folder for your project:

mkdir myProject
cd myProject

2. Create a virtualenv to isolate dependencies, and activate it:

virtualenv venv
source venv/bin/activate

3. Install Django and Django REST framework:

pip install django
pip install djangorestframework

4. ‘Start’ (create) your new project:

django-admin.py startproject myProject . # don't forget about the trailing '.' character!!

5. ‘Start’ (create) your initial app:

django-admin.py startapp myApp

6. Sync your database:

python manage.py migrate

7. Create a superuser:

python manage.py createsuperuser

That’s it!  Now you can launch your project by invoking the runserver command:

python manage.py runserver

Pull up http://127.0.0.1:8000/ in a browser window to see your project running from your local box.

Bash: create alias

If you find yourself repeatedly running a wordy command, having to look up how to run a command, or forgetting a username and password combination, I suggest looking into creating a bash alias.

To create a bash alias, do the following:

1. Start up terminal

2. Type cd ~  to go to your home folder

3. Type touch .bash_profile to create the new file

4. Type vim .bash_profile or open this file in your favorite editor.

5. Add your alias by adding a line to this file in the format alias <alias name>='<command>’ . For example alias gw=’./gradlew’ .  This will create an alias named gw , which when typed will run the command ./gradlew  from wherever gw  is typed.

6. Type . .bash_profile  to reload your bash profile which loads any newly added aliases.

At this point you can type your alias instead of the wordy command you had been previously typing.

java.net.BindException: Address already in use:8080

Address already in use, BindException

If you’ve ever encountered this exception:
java.net.BindException: Address already in use:8080
there’s a great tool that you can use to determine what application(s) are running on a specific port: lsof

Looking at the man page for lsof, we find the following:

DESCRIPTION
Lsof revision 4.81 lists on its standard output file information about files opened by processes for the following UNIX dialects:

AIX 5.3
FreeBSD 4.9 for x86-based systems
FreeBSD 7.0 and 8.0 for AMD64-based systems
Linux 2.1.72 and above for x86-based systems
Solaris 9 and 10

(See the DISTRIBUTION section of this manual page for information on how to obtain the latest lsof revision.)

An open file may be a regular file, a directory, a block special file, a character special file, an executing text reference, a library, a stream or a network file (Internet socket, NFS file or UNIX domain socket.) A specific file or all the files in a file system may be selected by path.

Instead of a formatted display, lsof will produce output that can be parsed by other programs. See the -F, option description, and the OUT-PUT FOR OTHER PROGRAMS section for more information.

In addition to producing a single output list, lsof will run in repeat mode. In repeat mode it will produce output, delay, then repeat the output operation until stopped with an interrupt or quit signal. See the +|-r [t[m<fmt>]] option description for more information.

To use it, type the following:
lsof -i:<port>
So in our case, we attempt to bind to port 8080, so running:
lsof -i:8080
Gives us an output like the following:

COMMAND PID   USER          FD  TYPE DEVICE SIZE/OFF NODE NAME
MyApp   50845 dustinkendall ... ...  ...    ...      ...  ...

To kill the process, type:
kill <pid>
So in our case:
kill 50845
This will help you get past the java.net.BindException and allow you to bind to that port.

How to Add a Private Key to Your Mac OS X Keychain

Add a Private Key to Your Mac OS X Keychain

If you are using Mac OS X, you can add a private key to the built-in keychain by typing the following:

ssh-add -K /path/to/private/key

Oftentimes your ssh key is named id_rsa and is stored at ~/.ssh. To add this file to your keychain do the following:

ssh-add -K ~/.ssh/id_rsa

Whenever you boot/reboot your Mac, all SSH keys in your keychain will be automatically loaded.

You should be able to see the keys from the command line via:

ssh-add -l

Hope this helps!

6 tips for better interviewing for Software Engineers

A few weeks ago a good friend of mine interviewed for a Software Engineering position on my team. We have a very high bar when it comes to interviewing — our interview sessions usually include a lot of whiteboarding and tough programming problems. We didn’t end up making my friend an offer, and a few days later he texted me asking for advice that I could give him that he could use to improve his interviewing skills. Here’s what I ended up sending him:

1. Pick 5 hard problems, and know them well. I would suggest starting with 5 good programming problems, maybe even problems you heard while interviewing here or others you’ve come across. Make sure you understand the problem very well. Spend time thinking about the problem.

2. Practice in an environment that simulates the interview setting. Grab a friend and have her/him ask you questions that you’ve prepared in advance, and allow them to ask their own questions. Practice in front of a whiteboard, if possible in a meeting room or office, to simulate a real interview. Envision in your mind being at an actual interview, at the company you plan on interviewing with.

3. Restate the problem to the interviewer, and make sure that they know that you understand the problem. Part of this may be repeating or restating the question back to the interviewer. Doing this shows that you can communicate well. It also helps make sure that you are sure of what they are asking. At this point you want to clarify any assumptions you are making before you move forward. Getting an assumption cleared up or removed will help you tremendously — if they aren’t cleared up you can end up in left field real fast, solving a problem that is either not the problem the interviewer had in mind or is considerably harder than what was originally asked. If you clear up assumptions, you make the problem set very clear in your mind, and more often than not the problem becomes easier than it might have been.

4. Don’t ‘sign off’ too early. What I mean by this is many times interviewees tell the interviewer that they are done with their solution, when they haven’t double checked their work. When you feel you are done, take a deep breath and run through your code a couple of times. Test your code (see point 5). Don’t be too eager to be done with your solution. You’ll appear much better if you relax and take a second to revise and thoroughly inspect your code. You most likely have a problem that you’re not seeing. Fix the problem and repeat this process.

5. Test your code. In particular, boundary conditions. For example, if the problem being asked involved operations on a list, I would make sure that test cases I run through included lists with the following properties: null list, empty list, list with 1 item, list with a many items (or maximum depending on implementation/structure), list with mixture of null and non-null items, etc.

6. Think about memory and big O. More often than not, I’ll ask the interviewee, “Is there any way you can make this algorithm more efficient?” What I’m looking for is an understanding from you that you know there are tradeoffs of time and space when designing an algorithm. Can you reduce the amount of memory your solution uses? Can you improve the time complexity. What is the time complexity of your algorithm? Be prepared to answer these questions. Bonus: take a look at Wirth’s law and understand its implications.

Conclusion

These are just a few of the observations I’ve made while interviewing Software Engineers. I’m sure I’ve missed many other tips. Do you have any to add? Leave your suggestions in the comments below.

How to send a message from your WatchKit app to your iOS app

Have you ever wondered how to communicate from your WatchKit app to its containing iOS app?

Enter openParentApplication.

openParentApplication is a method on WKInterfaceController. It allows you to pass in an object that contains the information you want to pass along to the WatchKit app’s containing iOS app.

Here is a simple example:

func sendMessageToPhone(buttonClicked: String) {

   let dictionary = ["buttonClicked" : buttonClicked]

   WKInterfaceController.openParentApplication(dictionary, reply: nil)

}

Here I am sending a dictionary with a key of ‘buttonClicked’ and value of type String that represents which button in my UI was clicked. If you look at the method signature on openParentApplication, you’ll see that it accepts an NSObject of AnyObject:

class func openParentApplication(userInfo: [NSObject : AnyObject], reply: (([NSObject : AnyObject]!, NSError!) -> Void)?) -> Bool // launches containing iOS application on the phone. userInfo must be non-nil

That’s simple enough. What about receiving this message on the containing iOS app end?

Introducing handleWatchKitExtensionRequest.

Add handleWatchKitExtensionRequest to your application’s AppDelegate.

For example:

func application(application: UIApplication,
     handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]?,
     reply: (([NSObject : AnyObject]!) -> Void)!) {
            
   if (userInfo?.indexForKey("buttonClicked") != nil) {
      println(userInfo?.indexForKey("buttonClicked"))
   }

}

handleWatchKitExtensionRequest allows you to receive the object you had sent from your WatchKit app. In this example, since I had sent a dictionary from the WatchKit app, I get a dictionary on the iOS containing app’s side. I then look inside the dictionary for the existence of the key I had set on the WatchKit side, checking for nil. If the key exists in the dictionary, I print it out.

What about that reply parameter?

openParentApplication allows you to pass a closure via the reply parameter. This allows you to send a message from the containing iOS app to the WatchKit app. I will modify my example to demonstrate this. Here, instead of passing in nil for reply, I pass in a closure:

func sendMessageToPhone(buttonClicked: String) {

    let dictionary = ["buttonClicked" : buttonClicked]

    WKInterfaceController.openParentApplication(dictionary, reply: { (replyInfo, error) -> Void in
        if (error != nil) {
            println("error from parent \(error)")
        } else {
            println("replyInfo \(replyInfo)")
        }
    })

}

The closure for the reply parameter expects a dictionary and an NSError to be passed to it. If I run this code, what happens? The closure is executed, but we get an error:

error from parent Error Domain=com.apple.watchkit.errors Code=2 "The UIApplicationDelegate in the iPhone App never called reply() in -[UIApplicationDelegate application:handleWatchKitExtensionRequest:reply:]" UserInfo=0x618000069080 {NSLocalizedDescription=The UIApplicationDelegate in the iPhone App never called reply() in -[UIApplicationDelegate application:handleWatchKitExtensionRequest:reply:]}

Fortunately, the error is very helpful: ‘The UIApplicationDelegate in the iPhone App never called reply()’. So let me fix that. For simplicity’s sake, let’s say that I wanted the iOS app to communicate back to the WatchKit app a count of the number of times a particular button had been clicked. I’ll simply invoke the reply closure, passing along a dictionary of the desired information:

func application(application: UIApplication,
    handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]?,
    reply: (([NSObject : AnyObject]!) -> Void)!) {
            
        if (userInfo?.indexForKey("buttonClicked") != nil) {
            println(userInfo?.indexForKey("buttonClicked"))
        }
            
        let count = 5
        reply(["buttonClicked" : count])
}

Back on the WatchKit side, in the else block, the dictionary that we received from the containing iOS app gets printed out:

func sendMessageToPhone(buttonClicked: String) {
 
    let dictionary = ["buttonClicked" : buttonClicked]
 
    WKInterfaceController.openParentApplication(dictionary, reply: { (replyInfo, error) -> Void in
        if (error != nil) {
            println("error from parent \(error)")
        } else {
            println("replyInfo \(replyInfo)")
        }
    })
 
}

When I run the WatchKit app, I now get the dictionary printed out to the debugger:

replyInfo [buttonClicked: 5]

UIApplicationState.Background

Something you should be aware of is that the containing iOS app launches in the background. This is fine except that the normal app lifecycle is triggered and executes. For example, your app’s viewWillAppear method will be called. The way I got around that in my app is by adding the following to the containing iOS app’s AppDelegate didFinishLaunchingWithOptions method:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.
        
    if (application.applicationState != UIApplicationState.Background) {
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

        var storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)

        self.window?.rootViewController = storyBoard.instantiateViewControllerWithIdentifier("ViewController") as? UIViewController
    }

    return true
}

Final Thoughts

openParentApplication and handleWatchKitExtensionRequest are a powerful combination. Use them when you want to send information between your WatchKit extension and its containing iOS app. Be aware that the iOS app’s lifecycle is triggered and executes, even with the app running in the background.

Do you have any feedback? What has your experience been with these two methods? Let me know in the comments section below.

Related Links

WatchKit Framework Reference openParentApplication

UIKit Framework Reference handleWatchKitExtensionRequest