Math Is Not Necessary for Software Development

As a developer, written communication and reading comprehension are more valuable than math proficiency.

Sometimes, I tweet. When I tweet, sometimes people agree with me. One such occasion happened recently when I said this.

This was part of a string of tweets that was kicked off by seeing the following image tweeted by Sara Chipps.

I think the main thing to take away from that image is that if you are looking for a new career and you aren't involved computer science or mathematics, you should be, and I hope my post here encourages you to get involved, especially if math has been scaring you away. It also means we should be providing more and better training for these jobs - but that's another post entirely.

So here's my question about that chart, why are computer science and mathematics combined? Why are computer science and mathematics *always* combined? In my day-to-day as a developer I rarely do what I would call *math*. Now admittedly, computer science is different than software development, but I don't think laypeople know that. I don't think that high school kids who are deciding what do do with their lives know that. Our industry desperately needs more talented developers - and it turns out that the skills that make a good mathematician don't necessarily line up with the skills that make a good software developer.

Logic > Math

People who are good at math are good at breaking problems down into parts, recognizing patterns, and applying known formulae to those parts to arrive at *the one right answer*. This skill will definitely help you solve some problems in software development. However, in software we are constantly running into interesting new problems that don't have a singular *right answer*. This is where we get to use our creativity to create solutions. Rarely in math are you coming up with a new way to solve a problem, but in software development you do that all the time!

If you don't like math because it is repetitive and boring, look into software development!

Modern tools have abstracted away (almost) all of the ugly 1s and 0s from software development. Modern developers can focus on crafting a solid system, and (for the most part) not have to worry about things like memory management, endianness and other computer science gobbeldy-gook. Sometimes it is fun to deal with low-level stuff like that - but you don't need to understand it to build a CRUD app.

Certain types of software development do require quite a bit of math: statistical/financial software, and games involving physics - for example. However, these require math because that is the *thing* that the software does, it's not simply a fact of building software. When we do need math, we have code libraries and computers to help us!

The majority of code for something like Facebook or Twitter probably involves very little math.

The math that we do use everyday in software development is called Mathematical Logic. In particular, software development involves a lot of Boolean Algebra. Known broadly as Discrete Math, it was one of my favorite classes in college, and I would recommend it to anyone, even if you aren't really a fan of numbers (also, take an Astronomy class!). I was blown away by this whole new type of thinking. If you are unfamiliar with discrete math, evaluating "`if true and false`" won't make any sense to you - but software developers deal with statements like this all the time.

Written Communication && Reading Comprehension

Taking the idea in your head and writing code to make it happen is clearly an important part of being a software developer. However, if you are doing custom development for a client, you need to start by being able to take their idea and get it into your brain. You need to be able to ask the right questions, and understand what they are telling you, and a *ton* of that happens through written communication like email. Effective communication is a requirement.

Writing code is like writing in another language, so language skills are extremely important! Not only do you need to understand what people before you have written in code, you need to write code in such a way that those who come after you can understand what you were trying to say. With enough experience, writing code that you and the computer understand is relatively easy - writing code that you, the computer, and *future you* understand is a whole 'nother story. But it's not even just future you, when other developers get involved, they will need to be able to understand the code.

Interestingly, some of the worst code can come out of very smart people thinking they're being clever. Smart people can write really complex code in a complicated way and understand it. Smart people aren't bothered by an `x` for a variable name because they can hold the whole system in their head and they remember what all those variables represent. A very smart person doesn't need to write any comments, the code is obvious to them!

Someone lacking superhuman mental capacity forgets what `x` is supposed to represent and so they name it something meaningful like `target_value`. This person gets lost in the middle of a 300 line function and thinks "Can I break this up into smaller parts so I stop getting so confused?" In the long run this person will be able to create better software as a system grows and the interactions become too big for *anyone* to hold in their head all at once.

If Only I Had Known Then...

I really wish high school Ross had read this blog post. High school Ross was good at math, but didn't really enjoy it. High-school Ross was even better at language arts, but he wanted to get a good job <*zing*>. I was turned off from getting involved in software because I didn't want to do math and I didn't think my skillset matched.

I was also told that great white whale of a lie that we have all heard, that all IT jobs have been shipped overseas - refer to the job growth chart above to see how that is working out!

Open + Download Native Apps with a PhoneGap/Cordova Plugin

Are you working on a PhoneGap/Cordova app that needs to be able to communicate with other native applications? You may want to get the demo code, give it a once over, and then continue reading.

Note: This work was completed in a pre-PhoneGap 3.0.0 world. There is now a Plugin Specification Guide that should be adhered to. This code would need to be adapted to fit that structure.

Prologue

Recently, we were brought in to add functionality to an existing PhoneGap app that had been created by an internal team. One new bit of functionality was to integrate with another 3rd party app. We wanted to be able to click a button in our PhoneGap app and have it open a native Android or iOS app if it was already installed. If the 3rd party app was not installed, we wanted to launch the appropriate marketplace to download the app.

As anyone who has done any PhoneGap development knows, "write once, deploy everywhere" is a bigger lie than the cake. We decided that when we needed to write platform specific code we would keep it isolated to plugins and create a plugin for each platform that conformed to the same interface. Examples of plugins we implemented in this app include calendar, datepicker (Android only) and Google Analytics. Our process for these followed the same template as *ExternalAppLauncher*: a common interface in *lib* that references a Cordova Plugin that is defined in a platform specific javascript file. In the demo code, you'll notice a *Dependencies* folder for each platform, which is concatenated to the common codebase of the PhoneGap site by our build process.

Pretend we are building a web app

The folder structure represented in the demo code is a remnant of the original project we inherited. I have not done extensive PhoneGap development outside of this project, so I am not sure if those are PhoneGap/Cordova conventions or not, but they work.

Being the good little OO developer that I am, I was hyper focused on keeping the same interface for our app code regardless of platform or environment. We abstracted Environment options into an Environment object and our platform specific code into Cordova plugins. So in our app, the actual call to open the external app is quite simple

Android uses the app identifier for both launching and finding the app in the Google Play store. iOS uses a custom url scheme. for launching the native app, but in order to find it in the app store you need to know the app store url.

In order to cover our bases, we defined an app options object in our Environment object like so:

Going Native

Now let's move into the platform specific code. Basing my code off open-source examples, I created a plugin in Java for Android and in Objective-C for iOS. The basics of setting up a Cordova plugin for iOS and Android are outside the scope of this blog post but check out PhoneGap documentation for Android and iOS, if you'd like to know more. PhoneGap's documentation is pretty good. There are examples of how to do this in just iOS, but I found the information about Android was quite scattered.

We wanted these 2 plugins to have the same external interface. Cordova enforces some of this for us by giving us the cordova.exec() method. The 2 methods I wanted to be able to pass through to the native code were *launchApp* and *launchMarket*. For Android, we passed an *androidAppId* as the argument for both *launchApp* and *launchMarket*, but in iOS we needed to pass *iosUrlScheme* for *launchApp* and *appStoreUrl* to *launchMarket*. Yay! We've successfully isolated the platform specific code to plugins!

Now for specifics on the native plugins. We leveraged the CDVPlugin and CordovaPlugin classes that we got from Cordova and implemented our two methods *launchApp* and *launchMarket*. Android adds some extra boilerplate, which required us to implement the *execute* method ourselves, but it's essentially just a controller method that calls the other methods. I chose to develop this solution such that instead of the plugin handling either launching the app or the market, the result of *launchApp* would return success or error back into our app. This allowed us to handle the state inside of our app instead of inside the plugin. On error, we launch our *_askToDownload* message. I am glad this code lives inside our app and not inside of a native plugin, as we won't need to update this code in 2 places when we want to change the confirmation message or any other behavior.

Epilogue

Personally, I am unhappy with PhoneGap/Cordova as a solution for mobile development. However, it does have its place where cross-platform is an immediate goal, budget is a consideration, and the app doesn't require too much functionality. I was surprised to find so many examples of PhoneGap developers who only develop for one platform - why aren't they doing native development?

When I began working on this problem, I couldn't find a single example of how to launch an external app using PhoneGap that gave any consideration toward multiple platforms. Hopefully my post helps fill this void and you have found it useful.

Tips for Novice Developers (and why you should become a rubyist)

Work Locally

Working locally means that you have an instance of your web app running on your machine. You edit files directly on your machine, rather than uploading every change to the server.

It is tempting to edit files directly on your shared server, but don't do it! It is a very bad practice and will bite you over and over again if you let it become habit. You may start out thinking of a website as one chunk of information and logic intertwined, but working locally and pushing your completed changes up to the server helps you to understand the difference between the data/logic that lives in the database and the data/logic that lives in the code. Understanding this difference will allow you to create more modular systems by putting all data in the database and all logic in the code.

Also, by editing a live site, you must always be afraid of breaking it and will have to be more careful. Phooey, download your site locally and break it over and over again! Only by breaking it will you learn how to fix it and make it better!

Use Version Control

Version control is a way to keep track of all the changes you have made to your code. It allows you to save working states of your code and easily revert back, and see differences between states. It also allows multiple people to work on the same code base without overwriting each other's changes

Version control is one of the first things you should learn as a developer! There are people graduating with computer science degrees from universities who have never used any form of version control. This is a travesty! It is such a simple thing, and so important - not only is it essential for working with others, but as a way to provide a safety net and allow you to freely experiment with code and always be able to get back to a safe spot. Learn how to use git!

Get Good at Computering

Learn how to use your computer! Learn keyboard shortcuts for the programs you use. Develop workflows that work for you and allow you to be more productive. Learn how to use your editor, and find some great debugging tools. Go to local meetups and mingle with other developers and ask questions - people will gladly help! Ask to pair with an advanced developer and pick up on some of their tricks. This includes learning the command line! Start by learning how to navigate your file system, make folders and delete files. As you become a more advanced developer being comfortable on the command will save you a bunch of time.

Believe in Yourself

So many people think "I could never do that with web development, I am not smart enough, I could only ever tinker with Wordpress". This is a load of bullshit. Web development is hard, this is true, but an awesome thing about web development is that all the information is out there just waiting for you to find it! You absolutely do not need a formal education to be a great developer.

With great open source software like Wordpress and Drupal, you don't need to know a lot to be able to get started creating real software that gets work done. I started in web development by hacking together some open source PHP. I lurked in forums, followed tutorials, and installed modules and for a long time. I didn't really embrace learning to code, because I thought I wouldn't be good at it. I learned some CSS and some Drupal and went to town making websites for people that had a surprising amount of functionality. Go ahead and start there, but use it as a platform to learn more!

Learn Ruby

As you start writing code and realizing how powerful it is you will never want to install anyone else's crappy module again! As you write more code and begin to appreciate the elegance of code you will be pulled away from PHP. Look into Ruby! It is a *dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.* It is also said to be *optimized for developer happiness*. That sounds pretty good, doesn't it?

Also, Ruby is an object-oriented language. Object-Orientated Design (OOD) is fantastic way to design and build software that, among other things, promotes practices that make software easier to test, debug, change and maintain over time.

There are lots of great, fun resources to learn Ruby, Rails and OOD.

Tags: 

Better Rails Debugging with better_errors and jazz_hands

Go beyond the stacktrace with 2 gems that grant you debugging superpowers.

Better Errors

Does this screen look familiar? Do you notice anything wrong with this picture?

That is correct, that is the default Rails error page and you are absolutely right, it is completely hideous and hurts to look at. It is begging to be improved.

By answering these questions you have already proven yourself to be quite a smart cookie, my dear reader, so you probably can guess what a gem called `better_errors` does. However, you might not realize just how much of an improvement `better_errors` actually is.



It is clearly more visually appealing, but it also provides much more detailed debug information, as well as providing a REPL for interacting with the code (assuming you have the separate binding_of_caller gem installed).

One of my favorite parts of better_errors is that it filters application frames in the stacktrace, so when debugging you can focus (at least at first) on the code *you* are writing and less on the Rails internals. The flipside of that is that by showing you a little bit of code context, as well as local variables, instance variables, request info, and providing a REPL for the full stacktrace, it is much easier to examine those Rails internals and pick up on that Rails Magic™ going on.

If you are debugging a Rails API, AJAX, want to investigate a non-critical error like missing images, or for any other reason don't access the error page directly at the time of the error `better_errors` provides a page accessible via the url "/__better_errors" which contains the error page for the last error on the server.

Another awesome part of `better_errors` is that it can open up files in your editor! It comes out of the box with support for textmate, but also supports for vim and a couple other editors. You can add Sublime Text by downloading sublime-handler and configuring an initializer for `better_errors` that simply contains:

BetterErrors.editor = :sublime if defined? BetterErrors

The error page page is even responsive! This is an extremely polished gem and I simply can't live without it.

Jazz Hands

When I need to really get my mitts in there and dig around for debugging, I like to use `jazz_hands`.


This is not intended to be an exhaustive tutorial on how to debug using `pry`, but suffice it to say I mostly interact with `pry` by setting breakpoints with `binding.pry` in my source code to launch the pry REPL in the terminal running my rails server. `better_errors` is great at catching exceptions and helping to isolate a problem by showing the stacktrace, but once you know the problem and need to experiment in order to figure out the solution, `pry` is a much more powerful tool than the REPL provided by `better_errors`.

The part of the `jazz_hands` extension that I interact with the most is `awesome print`. This provides a prettier output in the REPL when getting descriptions of objects and variables. `pry-debugger` is also great for allowing you to step through the code right from the REPL. `pry-rails` is great and I find myself using the show-routes functionality frequently.

I have found `pry-git` to be quite buggy and have not been able to use it successfully. The syntax highlighting as you type technically works, but oddly it causes my cursor to be offset by 10 or so characters to the right, so I don't use it.

In Conclusion

One of the best things about `jazz_hands` and `better_errors` is that they are so simple to set up and have no downsides. These gems are my defaults and are in every single rails project I do. By giving you debugging superpowers these gems can not only be huge time-savers, but they can reduce your stress to add years to your life. Not every gem can say that!

Tags: 

Pages

Subscribe to Front page feed