How does a novice start building a credible foundation in programming without the benefit of a formal curriculum or training? This post offers one possible answer and some recommended resources from the perspective of a current student.
Introduction: My Story
I started studying programming part-time in January 2013 with no prior experience. After several months of exploring programming as one of several possibilities leading towards a new career path, I decided to pursue a career in the software industry with a focus on development for the web. In order to overcome my lack of both a formal background in computer science and prior work history in an immediately related field, land a job, and do it well over the long term, I knew that it would be vitally important for me to invest serious, sustained effort in building a strong practical and conceptual foundation. Although I knew that in a year or so of part-time independent study I could not expect to match the depth of knowledge and experience gained by formally-trained computer science majors, I was also convinced that I could at least ground myself more firmly than many other self-taught programmers. So, despite temporal and financial pressure to move as quickly as possible to building sample projects with popular libraries and web frameworks, I’ve focused most of my attention so far on building a deeper understanding of the underlying concepts and languages upon which current and future software development will depend on a deeper level. For me, these foundations most definitely include significant forays into mathematics, databases, and networking, which I will leave to other posts.
Please note that I am offering this post as contribution back to the larger community of students and professionals whose work has helped me to learn, rather than as a “how-to guide” or curriculum for a transition I’ve yet to complete. I similarly make no claims to exclusivity or comprehensiveness, either as a description of my own learning, or as an account of helpful resources or necessary concepts. There are surely other good resources that I do not mention here and other approaches to learning that could work both for me and for others.
1. Basic Concepts and Exposure
I had to start at the very beginning. I needed a basic, working concept of both software development and computer science as fields, and I needed to learn to recognize and use the basic building blocks of both programming and markup languages in a manageable, controlled way. I needed exposure. Luckily for me, all of this is possible with nothing more than Internet access and a modern browser. In fact, thanks to free, self-paced courses and tutorials available online and the availability of tutorial programming environments in web browsers, it has probably never been easier to gain the familiarity I needed to get started.
Resources for Getting Started:
If you are also interested in starting from the very beginning, I can recommend the following free resources from my own experience.
A. For background and context:
Nick Parlante of Stanford’s Computer Science 101 Course on Coursera. This is a MOOC (Massive Open Online Course) available as a “self study” without waiting for a new session to be offered. I found the “self study” option, in which all of the course materials are immediately available, to be particularly helpful for picking up an accessible introduction to topics like information storage in bits and bytes or Ethernet. There are also basic introductions to topics like Boolean logic that you will quickly encounter in programming tutorials. In some cases, I have found it can be helpful to have access to another explanation. The beauty of the “self study” option lies in your ability to get what you need and come back later.
Blog Posts by Kyle Kingsbury (Aphyr): “Getting Started in Software” and “Core Language Concepts”. My friend and mentor Aphyr wrote these posts to help me get oriented, and he is sharing them with you too on his blog. The first, “Getting Started” should be accessible almost right away. The second, “Core Language Concepts,” will probably make more sense once you’ve had a chance to work with some programming tutorials.
B. Early exposure
Codecademy can be a good resource for interactive lessons and tutorials to help you get started and prepare you for further learning. It’s not perfect. You will probably run into a variety of criticisms of Codecademy and its competitors, some more tempered and well-intentioned than others. Look for a few that seem reasonable to you and read them. Think about the points they raise. Try out a few lessons, and see what you think. I’m not going to add my own proper review of Codecademy here, but I will offer a few comments to frame my recommendation.
For someone with little or no prior experience, Codecademy courses can be great for basic exposure to some very simple programming. As with most things in life, in order to get the maximum benefit from the courses, you will need to have reasonable expectations and a positive attitude. If you are a total novice as I was, resources like those above in section ‘A’ will help provide some valuable additional context.
Be patient and don’t expect too much of a free resource still under development. For instance, you will almost certainly run into an exercise validation issue that you don’t immediately understand. It may or may not actually be a problem with the site. Sometimes it will be part of the site or a browser behavior that you have no control over as a user. Sometimes you will have a perfectly good–or even better–solution to an exercise and it will not validate. Still other times it will be entirely your own mistake. Be patient. Try to figure out what is happening. Read your own code very carefully first, and then check the forums. If it still doesn’t make sense, check back later and try again. If/when you are able, try to reason about why the error is happening and learn something more in addition to resolving the immediate issue. Problems with exercise validation can be teaching moments about testing and writing your own tests in the future. Similarly, browser issues with the interface are teaching you about the very real challenges of making highly interactive applications behave well and predictably across the spectrum of browsers. To give one final example, in February, there was a database migration problem on Codecademy’s backend. Some of my user data was permanently lost. This was also a teaching moment –an opportunity to start thinking and learning about databases. With the right attitude, you can make problems part of your learning process rather than an impediment to it. In my experience, it will be vital to adopt this attitude as a learner whether or not you are working with Codeacademy.
Furthermore, remember that, although they can be valuable, these courses are just a start, and treat them as such. By itself, working through Codecademy (or something similar) is not going to turn you into a credible developer. The courses will also not necessarily teach you the best way to write or think about even a basic concept or problem. In fact, there can be content problems on a variety of levels that someone with more training and experience will notice. But here’s the thing: working through the lessons can start you on a path to become a person who can point out those problems yourself. This has worked for me. At least in my experience, Codecademy courses are enough to give a beginner just enough exposure and practice to take on more complex tutorials and resources, and just enough of a taste to pique a learner’s interest and help build zir confidence to make that sound both possible and fun. As such, I think Codecademy can be a valuable resource for beginners and I can recommend the site.
That said, you could also choose not to use Codecademy at all. You might try something different to get comparable exposure, or even skip right ahead to something like Chris Pine or Zed Shaw’s tutorials (see below). My guess is that it would take a little extra momentum and encouragement to launch most total novices right into those, but it could certainly work.
2. Next Steps:
I’ve generally been learning these subjects in parallel, mostly because I get excited to know how the pieces will fit together in the end, and I have a lot of experience managing that kind of parallel learning successfully. I don’t regret learning this way, but it has probably made things more complicated than they otherwise would need to be. If you are learning too, it might be easier to handle one thing at a time.
My general strategy here was to make sure that I had the basics down, and then move onto more intermediate-level resources. I deliberately sought and invested time in second and even third presentations of the basics I had seen before on Codecademy or other tutorials. I wanted to be sure that I was learning best practices, and furthermore, in my experience, repetition and practice, especially in variations, powerfully promotes retention of new information.
Resources for your next steps:
The following is a kind of annotated outline of resources that I have personally used and would recommend to another learner at this stage. Some of these are books that you would need to borrow from a friend or buy. Although money can be tight for those making a career change, I think these are still worth acquiring because of their quality and ongoing utility to a learner.
First, you’ll want to solidify the basics with some resources aimed at newcomers to both programming and Ruby. In respect, I found Chris Pine’s Learn to Program to be helpful. I used the free online version, but there is also a revised and expanded second edition available in paperback (ISBN: 978-1934356364).
Zed Shaw’s Learn Ruby The Hard Way, available in a free online version, is also very helpful. Shaw will take you back through the basics and then push you onto a more intermediate level. Start with the same author’s “Command Line Crash Course” if you need to learn (or re-learn) the basics of the command line interface as I did.
I recently acquired a copy of Peter Cooper’s Beginning Ruby: From Novice to Professional (2nd ed. : ISBN 978-1430223634), skimmed the earlier portions, and started working through some of the later chapters, which cover some more advanced topics at a greater depth than Shaw’s book. It also has the advantage of being originally written about Ruby, whereas Shaw’s work is translation of his Python book. Cooper’s book is helping me to solidify my grasp of a number of things that I didn’t quite master the first time around by jumping from Shaw to Olsen’s Eloquent Ruby (see below), so I’m also recommending it here.
I personally like Shaw’s Hard Way a lot and think it is worth working through in addition to Cooper’s Beginning Ruby, especially because Shaw’s format deliberately emphasizes practice in reading and writing as well as introducing concepts. However, in retrospect, I think it might also work to move from the Pine book or a similar introductory resource (even if in a different language) right into and through Cooper without Shaw. I think the choice would come down to your own learning style and time you can make available to study.
Around this point, you may also find the Ruby Koans to be useful as extra practice and reinforcement. I know that I benefitted from working through the exercises. You will read a lot of Ruby carefully, find and fix problems, and get more practice using the command line and your favorite text editor.
Also at this stage, start working through the Project Euler problems. These will make you apply your knowledge in new ways. You can also learn an enormous amount about efficient algorithms and writing eloquent code by reading a variety of programmers’ solutions to the same problems. It may also drive you to learn more mathematics, which is definitely a good thing.
If and when you feel ready to dig a little deeper, you might move on to Russ Olsen’s Eloquent Ruby (ISBN: 978-0321584106). Olsen will help you to understand and think in the language at a deeper level. My personal copy of this is joyfully and extensively annotated. I keep coming back to it and learning more every time. Try to find ways to apply what you learn here to your work in Project Euler or building the practice projects described by Shaw and Cooper.
For other ideas about books, you might also consider Olsen’s own recommendations. You can check out his “Ruby Reading List” here.
B. Front-End Web Development with HTML, CSS, and the DOM
In my own work towards that goal, I have personally learned a lot through the companion books Designing with Web Standards, 3rd ed., by Jeffrey Zeldman with Ethan Marcotte (ISBN: 978-0321616951) and Developing with Web Standards, by John Allsopp (ISBN: 978-0321646927).
These books are written for professionals and serious students, with a strong emphasis on understanding and applying web standards and best practices. Working through and referring back to these really helped me to be able to open up Firebug or Chrome DevTools and grasp a lot of what I see, even if I can’t yet build it all myself. Thanks to these, I can also read and understand a lot of the conversations and arguments that front-end developers and web designers are having, which opens up a whole universe of professional discourse to an advancing student.
On the first page of his preface, Crockford explicitly writes that The Good Parts is “not a book for beginners” and warns that “the book is small, but it is dense” (xi). He deserves to be taken at his word. I’ve learned a great deal from this book, but only by working slowly and carefully, and only because I had already built a substantial conceptual foundation in programming through another language. In my case, this was Ruby, but for you, it could be something else.
There are, of course, many paths to building a foundation in programming. In this post, I’ve described how I started building my own from the ground up, and I’ve offered references to some resources that have been helpful to me as an independent learner. No two students are exactly alike. You may not like these same resources or prefer others. You might prefer to learn Ruby, for example, from the ever-popular and quite entertaining Why’s (Poignant) Guide to Ruby, by Why the Lucky Stiff. I think that’s great.
Remember, I never meant this to be comprehensive, exclusive, or read as some sort of a curriculum. Frankly, I’m nowhere close to having earned the right make a curriculum. At this point, I’m still working at level of the “intermediate” Ruby books I describe above, and consider myself something like an “advanced beginner.” I’m not yet an expert by any means. I simply wrote this in order to share part of my own story and help give back to the larger community of teachers and learners making this all possible. I hope that his post proves helpful to you in some way. The most important things to take away may simply be that it is possible to learn and that good help is available.
- To be fair, I understand that the Codecademy team is actively working to improve their content all the time. I hope that the larger context of my comments here will make it clear that I do not intend to carp at Codecademy or its employees, but rather to recommend their product, which like all products, has its limitations. I also realize that it may seem somewhat unfair of me to suggest that there are problems without citing specific examples and evidence. In this case I disagree. Citing and arguing about specific lessons would take us too far afield from the main topics of this post and would also require me to put considerable time and effort into an unsolicited and unpaid work of criticism, which would be unlikely to directly improve the content itself.
- The server seems to be inconsistently available at the time of this writing. Don’t be surprised if you get a 503 error.
- I certainly don’t intend this as a criticism of Shaw or Olsen’s work. My need to go back has much more to do with my own learning process and growing levels of understanding and ability at different times in my training than any flaw in the materials. A big part of my journey has been circling back to pick up bits and pieces of knowledge that I skipped over, forgot, or didn’t quite understand at an earlier point. Even the most diligent student attempting this kind of learning at speed will not be able to retain all of the details or fully work through each and every example or exercise in this many resources. I certainly don’t claim to have managed this myself. I don’t see that as a failure, but rather as utterly normal and nothing to be worried or embarrassed about in itself. Gaps in the foundation become a problem when you ignore them and fail to address them when they appear. So I go back. I put in my time. This is why review is important. This is why learning takes practice. If you want to build a solid foundation, you have to fill in the gaps. To paraphrase the great poet Kanye West, you must crawl before you ball. Maybe that should have been the subtitle of this post– “Programming Foundations: Crawl Before You Ball”?