Recently, I’ve been making a more concerted effort to contribute to open source software. As someone who recently picked up programming, besides my friends, OSS has been my best teacher. I can’t tell you how many tutorials I’ve gone through, how many hours I’ve spent on StackOverflow or how many libraries I’ve used on my own projects I found on Github.
On to my first fork. My friend Jordan and I were talking about OSS and even though I’ve open sourced some of my own software, I’ve never contributed to a project. I told him I didn’t even know where to start, or even how to do it. So we just searched “iOS” on Github and facebook’s sdk popped up. Jordan suggested contributing to facebook’s iOS sdk. My response was, “How the hell can I contrib…wait.”
I had been playing around with the sdk last week and I had extended one of their samples - Facebook gives you some great examples and very detailed installation instructions on their developer site. I wanted to include a search feature for FriendPickerSample, a way to list all of your Facebook friends and select them to be used for invites, tagging, etc. Interestingly enough, Facebook gives you a tutorial just for that. However, I wanted instant search, I wanted the search to update every time I typed in a letter. So I built it. It was actually very little code, I just had to implement one UISearchBarDelegate method and it worked!
I told Jordan about this and he thought this would be a good feature to add to the FriendPickerSample. I was a little hesitant because I was intimidated by the thought of trying to contribute to Facebook’s sdk. Jordan suggested I email the maintainer and ask if he’d be open to this contribution, “they’re people too.” So I emailed onebit about the feature and asked what his thoughts were - just a shot in the dark. Then, an hour later, I got a reply! It was probably the best email I could have received in that situation. He thought that the feature was “Cool!” and that it “sounds like an improvement.” He was very supportive and of course, he couldn’t promise that the change would be accepted, but encouraged me to fork the repo and submit a pull request.
I had never forked a repo in my life. It’s not hard at all, but I just had never done it and I didn’t know what the etiquette was for submitting a pull request. With Jordan’s help, I forked the repo, added my feature and submitted a pull request. My first fork and pull request!
The combination of contributing to such a widely used sdk, onebits’ response and my first time contributing to another project was a rush. It felt like a blur, but I did learn a few things. Jordan advised me to look at how Facebook’s commit messages were structured so that I could format mine accordingly. This will help the maintainer easily understand what’s going on. But I think the biggest lesson I learned was through a fear that I overcame.
“They’re people too.”
Jordan’s comment resonated with me. I was really intimidated by the thought of trying to add to Facebook’s sdk and emailing onebit. I haven’t even been programming that long, who am I to do even try? My own insecurities about my programming skills were hindering me from even trying. But Jordan’s encouragement and onebit’s friendly response made me realize that I’ve got nothing to lose. Maybe my pull request won’t get accepted, maybe my code really isn’t all that great and maybe I didn’t do something correctly, but I did something I had never done before and took one more step forward in my programming journey. That’s what matters. I know I have areas to work on as programmer, but I’m learning and there’s no reason for my own insecurities to stop me from trying something out of my comfort zone. With respect to my programming skills, I try to remind myself, it’s not where you are now, but where you are going.
onebit was gracious enough to suggest that I email him with the pull request so that he’d be able to look at it easily. I emailed him and though I haven’t yet received a response, I’m looking forward to his feedback.
About the pull request, it’s more than just a few lines of code than I mentioned. This is because in FriendPickerSample, the search bar isn’t set up, so I had to include that per the howto I linked above. Also, I made the code iOS 4.x compatible so I couldn’t take advantage of new methods available for iOS 5+, which added to the lines of code.
There are so many great, free resources about programming, there are virtually no barriers if you own a computer and have internet access. It is truly the perfect time to learn how to code - just watch this video from Code.org if you need any more convincing. In my pursuit of programming, I have stood on the shoulders of giants and it motivates me to contribute. I think the computer science community is as close to a real life antithesis of the Tragedy of the Commons as any.
I just completed my first programming assignment for my Algorithms course through Coursera - if you’re looking to continue or supplement your education, I highly recommend Coursera, I’ve been impressed with the quality of content and breadth of their course offerings.
Anyway, here are three pieces of advice if you’re trying to learn algorithms for the first time like me.
1. Take a minute to stop and think
I know this sounds dumb and obvious, but since I’ve been out of a school setting for about four years, I’m used to just doing instead of taking a step back and deliberately planning out my next steps. Half the battle in solving a problem with algorithms is understanding the question. If you read a question and immediately race to your text editor to code up a solution, chances are, you don’t fully grasp the question. More often than not, this leads to seemingly endless hours down a rabbit hole and trying to brute force your way to solve a problem. These sorts of technical questions usually have nuances to them and these nuances are hints to solving the question. If you miss those hints, you’re headed down the wrong path.
2. Don’t code, talk and write
Once you understand the problem, talk it out. Talking out the problem helps me be very explicit about my approach. If I start talking out my steps and get to a point where I can’t even explain where to go myself, then I know I’ve reached a dead end. Also, if you can, talk to another person, if someone isn’t available, talk to yourself. I’ve found that when I think to myself, I make connections or assumptions that glaze over details.
When I was first trying to implement the merge sort algorithm, I had a little trouble wrapping my head around recursion. I went to my roommate, Moses, and he was gracious enough to talk it out with me for about half an hour. We stepped through the call stack, wrote out examples and talked out different ways to view the algorithm. This was a huge help. I then wrote pseudo code of what we discussed and this helped cement what I had just learned.
A good test to figure out if you actually understand something is if you can explain it out loud or write it down on a piece of paper. So before you start coding a solution, talk it out and write some pseudo code. You’ll know if you have the solution if you can do these two things. Writing the code is the last step, the hard work of actually solving the problem is already done.
3. Don’t plug and chug
When you actually get to coding the solution, check yourself that you don’t get to the point where you’re plugging and chugging, haphazardly coding in hopes of stumbling upon the solution. In the best case scenario, you’ll use your pseudo code and it will flawlessly transfer to actual code, but this rarely happens, if ever. You’ll run into snags. When you do, repeat steps one and two. Take a step back, talk and write it out. This will save time in the long run, trust me.
I fell victim of plugging and chugging when I was solving the inversion count problem (the first programming question of Coursera’s Algorithm class). I knew I had 95% of the problem figured out, but for some reason my counter was always wrong at the very last level of recursion. I printed out the counts at each iteration and everything was as expected except for the very last. Seeing the finish line, I just tried to change a few things here and there in hopes of figuring it out, I was programming by coincidence. I lost hours to this futile approach. I thought I’d be able to quickly figure it out by trying a few random pieces of logic here and there instead of taking a minute and deliberately thinking about the problem. It wasn’t until I stepped away from the code and talked out potential reasons why the counter screwed up at the last minute that I figured out what was wrong.
What was wrong? One line of code. On an edge case, I mistakenly added to the counter items I had already accounted for. Once I deleted that line, my code solved the problem.
Interestingly enough, these three thoughts all apply to programming in general. When I first started to learn how to program, I thought it was all about writing code. Yes, that’s a big part of it, but code itself is a tool. Programming and computer science is more about a way of thinking and an to approach to solving a problem. I’d argue that real programming is the process leading up to actually writing a line of code.
Horizontal navigation in iOS is an intuitive way to page through content, especially on a smaller screen, like the iPhone. There are some great apps out there that use it, like Groupon and Gilt.
These apps do a great job of showing lots of great content seemingly all at once. The swipe gesture gives the user a quick and easy feeling of scanning through information. Then, once the user finds something she’s interested in, she can drill down by interacting with the view displayed on the screen. This sort of navigation works great for Groupon and Gilt because their content can be categorized and each category has more granular details.
I first implemented horizontal navigation when I was building PictureMenu. When I was doing some research, I came across Apple’s example that used horizontal navigation, PageControl. Basically, you create a container view controller with a scrollview and you add your page controllers’ views to the scrollview.
PageControl had the navigation part down, but its pages were static view controllers and I needed to be able to implement functionalities like launching an action sheet, taking photos and pushing new view controllers.
Most of these functionalities work just fine with the PageControl example, but there are a few functions that don’t. One specific instance is when you’re presenting an UIImagePickerController. You may want to present this be sending a message to whatever page view controller you’re currently in and while that does present the picker, it will cut off the top portion of the picker since your controller’s view is a subview of the container’s view. This means your container view controller must present the picker so that the picker can use the entire screen. So, I created a property that is a container view controller type in the page controller that uses the picker and set it as the original container view controller. I then use this property to present and dismiss the picker.
Presenting from page view controller:
Results in the top portion of the camera view cut off (notice the Auto button):
Compare to presenting from the container view controller property of the page view controller:
Results in using the full view:
If you’re looking to use horizontal navigation and want to each page to have its own functionality, check out my implementation, DJHorizontalNav and let me know what you think!
One response from my last post about how learning to program changed the way I think was the following:
Have fallen off the “learn to program band-wagon” many times myself, maybe due to me setting unrealistic goals for myself or learning the wrong way. Could you walk us through how you disciplined your self to stay focused and concentrate on learning how to program?
This is a great question. I have fallen off the “learn to program band wagon” a few times as well. What was the difference this time? Necessity.
When I committed myself to learn iOS, I had recently shut down an online business I was running and was living off savings. If I couldn’t learn how to program, learn how to acquire freelance clients and learn how to execute projects, I’d run out of money and would have had to move on to plan B. I didn’t have a plan B. In my mind, I had to make this work.
This may seem dramatic and reckless, but trust me when I say that it was a calculated risk. First of all, I had enough savings to last me six months (living frugally). Second, I knew there was a big upside to learning iOS given the market demand, especially where I live, San Francisco. Third, one of my good friends, Steve, had already done exactly what I was trying to do and was a huge help - I was/am in the perfect environment (here’s my post about my environment). In my mind, the success of this new adventure was dependent on my execution. It’s the type of calculated risk I will (hopefully) take 100% of the time. I will always take a chance on myself. If you don’t believe in yourself, who will? Also, I knew the worst case scenario was that I’d have to find something else to do and I knew I would at least pick up a new skill.
I’m not suggesting that you have to put all of your eggs in the programming basket to stick with it, but rather that programming has to fulfill a need.
Do you need to learn how to program to make a living?
Do you need to learn how to program to solve a math problem?
Do you need to learn how to program to build a fun website you’ve been thinking about?
There are varying degrees of “need” and it’s different for everyone, but my guess is that the stronger the need, the more pain, frustration and punches you’re willing to take on the never ending journey of learning how to program.
My experience with learning for the sake of learning has been miserable. When I first tried to learn how to program, I started because my close friends were programmers - I just wanted to be in the club. I did every tutorial out there on Python/Django and Ruby on Rails. They were helpful in getting a basic understanding, but I never really made much progress beyond the tutorials and fell off within a few weeks. I just didn’t really need it.
This may be a topic for another post, but when you’re actually going through the process of learning how to program, once you’ve done a few tutorials and have a basic grasp of fundamental concepts, you need a project. You have to try to build something. You have to try to get something out there, whether it’s a silly website for your group of close friends (here’s mine) or a simple app to keep score for bar games (again, here’s mine). Otherwise, you just don’t need to learn how to program.
I have been a full time developer (mainly iOS) for one year and it has changed the way I think.
When I first started getting freelance work, my biggest fear was that I wouldn’t be able to deliver technically. What if I just didn’t know how to do something? As a solo developer, that thought was horrifying. When you become a developer, you realize that there is no way you’ll know how to implement every technical feature, yet. However, you come to realize that you can learn how to implement every technical feature. Part of this comes from the endless resources available: documentation, Stack Overflow, forums and blogs, but the other part is the mindset you develop as you overcome technical hurdles.
I remember working on Picturemenu and realizing that at the end of every week, I had implemented a feature I had no idea how to do at the beginning of the week. After a few weeks of this, I started to develop confidence in my ability to learn and figure things out. My classic response to the question, “Do you know how to do it?” was, “Not right now, but I’ll figure it out.”
I think this mindset has been the most positive change for me and it has carried over to all parts of my life. Knowledge is finite, but the ability to learn is infinite.
Programming is a craft and in order to become great, like at anything, you must have a long term perspective and dedicate yourself to becoming better each day. I realized that my failed attempts at learning to program before this past year was because I had a very myopic view of programming. I had the mindset that maybe I’ll do programming here and there for a little while and then move on to something else. I thought that I could just read a book and know how to program. I was wrong. It wasn’t until I committed to become an iOS developer that I saw significant strides. There’s a pretty steep learning curve to programming and I’ve fallen off three or four times. If you don’t see yourself programming for at the minimum, the next two years of your life, you’re not going to put up with all of the frustration that comes along with it - it’s just not worth it.
Along with dedication comes perseverance. One of the traits that I admire most of programmers and have been developing myself is persistence. Your code will always have bugs. Debugging can turn into a war of attrition. You have to be persistent when tracking down bugs and be willing to take the self inflicted punches along the way as you figure out that the reason why your code doesn’t work is because you forgot to reset a boolean variable.
As consumers, we take the process it takes to produce a product for granted. We complain about how we don’t like the color of an icon, how slow an app is or how something just sucks. These can all be valid points, but when you’re on the other end as a producer, you realize (usually) how much time, effort and thought goes into making a product from start to finish. It’s not a trivial task.
Apps range from very simple to very complex, but even the simplest app requires a certain amount of effort in making things work. You have to write the code, make the icon, submit it to the AppStore (trust me, submitting to the AppStore for the very first time can be a harrowing experience). As end users, we don’t care about all of that, and we shouldn’t, but as a producer, you develop a new found appreciation for great products, beautiful design and craftsmen. This way of thinking adds more depth to life. You look at things differently. Music, physical products and nature all become magical as you realize that it all came from nothing.
Have you ever tried finding the first n prime numbers?
It’s not something you think about every day, but I’ve been going through some of the problems on Project Euler and finding prime numbers seems to be a recurring exercise.
In solving these problems, I ran across the ancient algorithm, Sieve of Eratosthenes, to find prime numbers. The basic algorithm to find all prime numbers within a range is, you start with the first prime number of that range, you go through that array of numbers and divide each number by that first prime number (not including itself), if the number in the array is divisible, you throw it out of the array. You then repeat this for the next number in the array once you go through dividing and removing numbers from the array until you reach the end of the array.
Here’s a concrete example: Find all of the prime numbers from [2, 10]
2, 3, 4, 5, 6, 7, 8, 9, 10
Start with 2 and start removing all numbers divisible by two:
4, 5, 6, 7, 8, 9, 10
Do the same with the next number, 3:
2, 3, 5, 7,
As you go through with 5 and 7, there are no more numbers divisible, so you’re left with an array of all primes in [2, 10]:
2, 3, 5, 7
Here’s some code finding the sum of the primes less than 2,000,000:
I have this poster in my room at my parent’s home. I love the quote by William Blake at the bottom, “No bird soars too high, if he soars with his own wings.”
About a week ago I renewed my yearly Apple Developer’s License. That means I started building iPhone apps one year ago. I distinctly remember writing my first line of Objective-C on the very desk that I am writing this post.
One year ago, I committed to learn how to program and make iPhone apps. Since then, I’ve launched three of my own apps into the AppStore, started an iPhone app consulting business, acquired clients and began working at a design firm as an iOS engineer staffed on projects for Fortune 500 companies. Needless to say, my life has changed. I don’t think I can even begin to convey how much I’ve learned in the past year, but one lesson I do want to share from the past year is the importance of being in an environment that is conducive to reaching your goals.
You can only go so far on your own. I owe so much to my close friends who have challenged me, encouraged me and inspired me. Here are a few of the countless examples of the influences in my life that have pushed me to places beyond my own imagination:
Steve Derico. Steve has been the most influential person in my development as an iPhone developer. He was the first one to tell me that I could become one and has spent countless hours teaching me everything from code, freelancing and design. I cannot thank him enough. Early on, I asked Steve if I could buy him dinner in exchange for an hour of his time coding, debugging and asking questions. Those were the most invaluable hours for my growth as a developer. Without him, I probably would have gotten stuck and maybe even given up, but he has always been a constant source of encouragement. Just knowing that someone believes in you goes a long way. Thank you, Steve.
Hackathon guys. Even before I started doing iOS development, some of my friends and I would stay up all night, eat terrible food, drink red bull and work on side projects. This still continues today. Steve, Nick, Sam, Matt and I will hack through the night together on our respective projects. By working in the same place, we push each other to be productive and help each other when we can. I’ve picked up so much just having short conversations in passing, by asking, “Hey Sam, how would you approach this…” Then, there is the 2 AM run to Safeway to get junk food - not the healthiest idea, but it’s always an experience.
I’ve been fortunate enough to be immersed in such a great environment to learn how to become an iPhone developer. I am a testament to how valuable such a supportive environment can be. I hope that I can contribute even a fraction of the value I’ve received to that community.
Surround yourself with those that inspire and encourage you, and oh the places you’ll go.
For fun: Hackathon footage from August 19th, 2010:
I am an iOS engineer, but I don’t have much of a computer science background. I took one intro CS course at Duke and it was pretty terrible. However, with all of the free, high quality online courses available, I can learn just about anything. I’ve started taking MIT’s Intro to Algorithms.
I was watching the first lecture and taking notes. This is generally how I approached school: go to lecture, take notes, read the text book, do homework. I thought that’s what I would do for this online course, but I realized how much more flexibility I have with online videos and with all of the course material available at once. This means I can pause the video, skip to different lectures or try something out during the lecture. I think that last part is the way I’m going to learn the most. Usually, I would just watch the lecture and just listen. Now, I’m going to put more emphasis on doing some of the examples on my own.
The first algorithm presented was a classic sorting algorithm, insertion sort (I had no idea what it was). Insertion sort is an algorithm that takes an array of numbers and sorts them from least to greatest. The high level overview is that you pick a number at an index != 0, which we will call “key” and compare it to the value at the previous index. If the key is less than the value, you “insert” it at the previous index and then you move onto the next index until you get to the end of the array.
The lecture notes gave the pseudo code, but I wanted to code it on my own to really understand insertion sort. Here’s my code (in ruby):
Yesterday was one of the most inspirational days I’ve had in awhile and it wasn’t because I read a heartwarming story, watched a compelling Youtube video or listened to uplifting music. It was because I built something.
I’ve been learning how to make iPhone apps for about a month and yesterday, I submitted my first two iPhone apps to the AppStore for review. I’ll find out in a week if they are approved.
I had been talking about learning how to program for over a year, but I haven’t had much to show for it. But yesterday I shipped something I built. Is it perfect? No. Is it insanely great? Not at all. But it’s a start and that’s the key.
Submitting to the AppStore was pretty magical. It was magical because it broke down a lot of my walls. Well, maybe it didn’t break down my walls, but it did take a good chunk out of my wall of fear of failure.
I’ve always followed the well-worn path and have been pretty successful at it. I’m pretty book smart, so I got good grades in high school, went to a prestigious college and even wrote a book about it…(shameless, I know). I was pretty set on continuing that theme into my professional career - whether it be medical school or a job at a large corporation - but for some personal reasons (maybe I’ll share those in a future post) that was not going to be part of my journey, at least not right now.
When you have continued success with a certain way of life, it’s frightening to change course. This characterizes my past two years since I graduated from Duke. I was frightened by not having the safety blanket of being considered successful by association. If I told you I worked at Google, just by association you could make a lot of assumptions about my abilities, salary, stability, etc. When you don’t have that association crutch you’ve always had, you begin to doubt yourself.
It’s a continual process to overcome that doubt, but what I’ve found helpful is that you have to have the audacity to build and then take one step. Whether it be deciding to learn a new language and doing one tutorial or coming up with an idea and actually starting a business entity, the mere fact that you took one small step toward building something is progress. Just keep the momentum going and take more one step, then another and another…
I’m a sucker for inspirational things so I couldn’t leave this one out. This is a gem:
I’ve been generally impressed with XCode 4. I’ve never used it before until about a month ago and I’ve picked it up pretty quickly. I’ve primarily used KomodoEdit and Textmate before I started iOS programming so the Interface Builder was something completely new. I really liked it…at first.
Using a GUI to hook up outlets, actions, drop in views and controllers was fun at first and very easy. However, after going deeper with iOS, using IB can be a pain because you don’t have as much control over the code.
For instance, today I was building a UITableView and I used IB to drop in a UITableView object. I made sure to include the UITableViewDataSource and UITableViewDelegate protocols in my ViewController and implemented the required methods. I used the Attributes inspector to set the style of my UITableView and I programmatically set the datasource and delegate to my ViewController. Build, run. Nothing.
I couldn’t figure out what was wrong, but I looked at my XIB file and glanced at my Connections inspector. Even though I had programmatically set my datasource and delegate, it showed that these two properties were not connected. I had to manually set these in my XIB file. This is annoying.
It seems like there’s a divide between using IB to build apps or actually writing code. XCode 4 seems to be riding in the middle and little details like setting the datasource and delegate slip through the cracks. I like writing the code out, you have full control and you know how everything is connected. I think I’m going to try to manually program things from now on, and maybe I’ll use IB to mock up prototypes quickly. But for building complicated apps, relying heavily on IB seems like a nightmare.