How to read software


The Most Efficient Way to Read Code Written by Someone Else | by Sara A. Metwalli

Photo by Safar Safarov on Unsplash

As developers, regardless of our specialty, whether it being data science, front end, or back end, we spend more than 75% of our time reading code written by others. That task can be such a demanding task.

That being said, the ability to read others’ code efficiently is one of the skills that could make one’s job in software engineering much more pleasant. Unfortunately, it is also a skill that is widely overlooked by schools, bootcamps, and companies. It is one of those skills that everyone assumes you know, or be good at, just because you know how to write code.

The thing about writing code is, everyone has their own coding style. Reading code is not like reading a novel or a story; it’s not just about reading instructions on the screen. Instead, when you read code written by someone else, you’re not just reading their code. You’re trying to get into their thoughts process and what they were thinking when they wrote that code.

Needless to say, that is an extremely challenging task. But, it’s a task that you can make exponentially easier. In this article, I will walk you through my 4 steps process of reading and understanding other people’s code.

To explain the different steps, I will go through a code I wrote for a web scraping tutorial.

Whenever you get a code that you need to read and understand, the first thing — and most apparent, I may argue — to do is to run the code and see what it does. What does it take as inputs? What are the outputs?

So, let’s go ahead and run the code above and explore the results.

Image by the Author (The code’s results screenshot)

Not all codes will result in a chart; some codes’ output will be a text output. Regardless of the output type, we can explore it to guess — if you don’t already know — the general idea of what the code was written to do.

However, this might not give you a lot of details about the details of the code, or if this code was a part of a bigger project, you might not know how it all connects, but you will learn how to build it and run it. Also, you will get to know about the libraries it uses and the frameworks it depends on.

Nevertheless, running the code will give you the information you need to understand it better, and to make sure you got every dependency, you need to start working and expanding it.

Now that we know what the code does and what the output is/are, we can start looking deeper into its details. To do that, we need to pinpoint the start of the code. If you’re using a programming language with a must main function, like C, C++, or Java, start from there and walk your way through to the other functions.

If you’re using Python, however, not all codes will have a main function, but you can use the indentations to know where the code starts. For example, in the code above, we have multiple functions, and then the starting point of the code is on line 80.

So, we can start going through the comments first — if there is any — and go through the entire main section of the code without going into the details of the subfunctions.

Going through the main function gives you the general flow of the code, what each subfunction does, not how they work, but what they do.

Once you’re done carefully reading the main part of the code, you may find it useful to run the code in debugging mode. The reason for that is, when you run code in the debugger, it allows you to observe how your code interacts with the memory.

It will show you how each variable changes with every step in the code. Doing so will give you a more in-depth understanding of the inner functionality of the code and its different functions.

Once you see how each variable in the code changes with every line, you can start adding your own comments in the code, explaining to yourself what every line of the code does.

One thing I found to help tremendously is to build a mindmap of the code connections while I am running it in the debugger mode. The debugger mode shows you a clear connection between the different code items.

Start with the name of the code file in the middle of your mindmap and then branch out with the different functions and how they connect. Try ti encourage the variables in the code into the mindmap as well, maybe not all of them, but the ones that have the most effect on the overall results.

Moreover, try to include the inputs and outputs of the code as well as their types or expected types. Here’s the mindmap for the code above.

Image by the author (made using Mindmeister) A mindmap of the code above

Building the mindmap will save you so much time whenever you interact with this codebase. It will help you know the connection in case you want to add or remove any parts of the code.

Reading code written by other developers can be such a challenging task; you need to understand their logic, their style, and their specific choices. I have read so many codes written by programmers of different levels and ages. Having experienced that, I came with my own 4 steps process to ease up reading, exploring, and understanding codes written by basically someone who is not me.

This 4 step process is simple and will save you a lot of time and effort; all you need to do is:

  1. Run the code and explore the results.
  2. Find the main function or the start point of the code.
  3. Run the code under the debugger and fully understand the code’s mechanics.
  4. Build a mindmap of the connections between the different code elements and use it at any time you interact with the code.

I hope you find these steps useful in saving you much time and effort in your next code exploration adventure.

“Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. …[Therefore,] making it easy to read makes it easier to write.”

― Robert C. Martin,

When you finish reading this, you’ll know how to code. | by Isaac Lyman

You’ll be bad at it, but whatever.

This is an early version of a chapter from Your First Year in Code, a book of practical how-to and advice for new developers. If you’re considering a career in software, check it out at https://leanpub.com/firstyearincode.

This is not a complete coding manual. This is a drive-through introduction to just enough coding concepts and keywords to get you from zero to a basic script. It’s a 30-minute read.

I’m writing this for:

  • people who are interested in coding, but want to get a taste of what it’s like before they commit any time or effort to it;
  • people who work directly with coders and want to understand the nuts and bolts of what they do;
  • people who are starting their Computer Science journey and want a 100-level primer in a nutshell;
  • people who have seen programmers on TV and are curious to know what they’re typing all the time.

First of all: take a deep breath. The cover picture on this post isn’t real code. At least, it isn’t code that anyone uses. Real code — what I write on the job — is mostly composed of English words, symbols, numbers (all ten of ’em, not just ones and zeros), and made-up names. Once you learn a bit of vocabulary, it’s readable. I’m going to cover each of these later on.

One request for you: if you don’t understand something, please highlight it and leave a comment so I can make it clearer. I’m an obsessive editor and I want this to be a smooth read.

Let’s get started.

A computer program — also known as an app, an application, or a piece of software — is a collection of many lines of special text. They’re special because a computer can understand them, and computers are incredibly dumb. The smallest practical apps have a hundred or so lines of text in them. The largest apps have billions.

We call this special text code. Code is a set of step-by-step instructions, like a recipe. It tells computers what to do with data. Data is any piece of information that a computer can hold in its memory. Modern computers are pretty good at holding things like dates and sentences. If you have a Twitter account, then Twitter’s got some flat, ugly computers at a warehouse that are holding your birthday and every tweet you’ve ever tweeted. Along with 300 million other people’s birthdays and tweets.

That’s all data. Don’t worry, the computers aren’t sitting around reading your old tweets for fun. And if they did, it wouldn’t be “fun,” anyway. It would be painful. Your tweets are dumb.

When you visit twitter.com, your computer borrows a whole bunch of code from one of those ugly warehouse computers. It speed-reads the heck out of that code. And then it executes that code, which means that the computer does exactly what the step-by-step instructions tell it to do.

If the instructions are written very carefully, it’s all peaches from here on out. Twitter will work. It will publish your dumb tweets to the entire world. It will let you read other people’s dumb tweets. It will let you ❤️️ those tweets.

If there is any flaw in those instructions — anything from a typo to complete misinterpretation of the data — then Twitter will not work. It will either show an “Error” message, crash the app, or suffer in silence, secretly doing things with your data that you would prefer it not to.

That’s the catch. Coding isn’t very hard. It requires you to memorize a couple hundred terms and learn some grammar rules — you could do this with English by the time you were two, and the English language is a mess. What is hard is being called out by an anal-retentive computer every time you press a wrong key or misunderstand a concept. The hard part about coding is the sheer amount of frustration you have to absorb.

The fun part is the problem-solving. In modern software, real-world problems become puzzles that can be solved by code— but only after you truly understand them. Once you wrap your mind around every possible permutation of a problem, you can write code that addresses it thoroughly, step by step.

A programmer’s toolbox typically consists of a few things:

  • A computer.
  • An internet connection. You need an Internet connection so you can use Google. When you don’t know how to do something (which happens about 787283493857 times per day) you Google it. When your app gives you an error message, you Google it. You Google everything.
  • A code editor (or an IDE, which is a code editor on steroids). Think of it as Microsoft Word (or better yet, Edward the App) for coding. It helps you organize and proofread your code.
  • A compiler or interpreter. This is a program that reads your code, tries to find mistakes so it can bug you about them, gathers your code into a nice little package, and then passes it on to the computer to execute. It does a lot of other things, too, but these are the things you need to know about right now.
  • A good pair of headphones. These help you ignore people so you can focus.

You probably already have a computer. Since you’re reading this, you definitely have an internet connection and an interpreter (Internet Explorer and Google Chrome have interpreters built in). There are plenty of free code editors available online (like this one). I can’t help you with the headphones, but a good alternative is staring at people until they leave.

So you’re all set, right?

There are thousands of programming languages in the world. Many of them are dumb and useless. You can have a long and happy career only knowing three or four — but don’t worry, this isn’t as hard as learning three or four human languages.

Programming languages are often described by their paradigm, which is a way of categorizing the kinds of features they have. For example, JavaScript is the language that all web browsers run, and possibly the most popular programming language in the world. It has a diverse feature set; I might say that JavaScript supports imperative, structured, object-oriented, and event-driven paradigms. And you might say I’m a pretentious geek.

You don’t need to know what all those words mean. What you do need to know is that programming languages with similar paradigms usually have similar syntax — that is, vocabulary and grammar. So once you’ve learned one language (like JavaScript), you’re already 75% of the way to learning similar languages, like Python and Ruby.

The best coders understand problems in terms of an algorithm — a series of steps that can be used to do a certain thing, even if the details are different each time. Have you ever bought something on Amazon? The checkout experience is a sort of algorithm. No matter what you’re buying, the steps are roughly the same: fill up your cart, choose your credit card and shipping address, pick a shipping speed and place your order. The code, in fact, is the same for each purchase. The difference is all in the data. Now get this: every algorithm that can possibly exist can be written in every normal programming language. It’s a mathematical fact. Once you learn to think in algorithms, the programming language is secondary. Sure, it kicks and drags its feet a little. But in the end it’s not about the keywords and symbols you’re using. It’s about the processes you’re describing.

From here on out, I’m going to use the JavaScript programming language to give examples. I’m doing this for my benefit, not yours. I’m good at JavaScript.

Code examples will be printed in monospace, which is a special font that looks like this. Monospaced fonts give the same exact width to every letter, number, symbol and space. All code is written in monospace even though it is harder to read than normal fonts. This is because it helps align blocks of code and allows coders to give equal attention to every letter and symbol, which helps them avoid errors. As an example, look at the following sentence in both a regular font and monospace:

There are three mistakes in the sentence: the extra space after “for”, the extra apostrophe in “Alice’s”, and Bob’s exploitation of Alice’s friendship and trust. Oh, and “without” is misspelled. You probably saw all these mistakes in the first sentence, but they’re more obvious in the second one, and obvious is your best friend when you’re scanning a 200-line code document.

Enough background: let’s write some code. The most basic building block of a computer program is a variable. A variable is a name for a piece of data, like a number or a sentence. You have to name your data.

“Sully. You’re not supposed to name it. Once you name it, you start getting attached to it.”

There are two reasons you name your data:

  1. You don’t know what it is beforehand. Does Facebook know your birthday before you type it in? No, of course not. Facebook’s code is using a name like dummy's_birthday behind the scenes (the underscore is there because variable names can’t have spaces in them). It attaches that name to whatever birthday you type in. That way, the code can be exactly the same whether your birthday is June 10th, September 9th, or December 86th. It just moves dummy's_birthday around in the program until it reaches an ugly warehouse computer.
  2. You don’t want to forget what it means. Suppose the computer program needs to know that December 86th isn’t a real date. So somewhere you have to tell it that December has 31 days. 31 is a number, a piece of data. But if you’re using the number 31 all over your code, and also using numbers like 30 and 28 (because, thank goodness, December isn’t the only month), your code is going to be confusing to read. What are all those numbers for? So you name them. 31 becomes the_number_of_days_in_december, and your code becomes self-explanatory. Beautiful.

Computers expect you to declare your variables. A variable declaration is like a birth certificate for a piece of data. It looks like this:

var the_number_of_days_in_december

The operative word here is var. It’s short for “variable.” The abbreviation is nice because it’s faster to type. It can also be typed with only one hand, so if all you’re doing is declaring variables all day, your other hand is free to do awesome things like juice grapefruits and practice with a quarterstaff.

Another thing you do with variables is assign them. This is where you attach the name to a piece of data. It looks like this:

the_number_of_days_in_december = 31

Easy stuff. You declare the variable, then you assign it, and then any time you want to use the number 31 in your program, you can type the_number_of_days_in_december and the computer will know what you mean.

You don’t have to assign every variable to an explicit piece of data when you write your program. You can declare variables and assign them to things that don’t exist yet. For example, you can declare var dummy's_birthday and tell the app to wait for the user to type it in. Whatever they type will become dummy's_birthday. You don’t even have to worry about it.

Variables can hold way more than just numbers and dates. For example, you can declare a string, or a piece of text:

var great_song_lyrics = 'La la la, la la la tonight'

Whoa. Curveball. I just declared a variable and assigned it at the same time. I’m so hecking efficient. Bring this man a grapefruit.

Now I can write great_song_lyrics in my code, wherever I want, and the computer will know that I mean 'La la la, la la la tonight'. It’s like we’re talking…in code.

Don’t believe me? Try it right now. If you’re reading this on your phone, you’ll need to open a web browser, like Google Chrome, on a computer. Press the F12 key on your keyboard (if you’re on a Mac, try this instead). You’ll see something like this:

This may be aligned to the right or bottom edge of your browser.

Make sure the “Console” tab is selected. Click in the blank area next to the > symbol, type a variable declaration and assignment, and press Enter:

The console is saying undefined because the line of code you typed didn’t produce any data. That’s okay, it wasn’t supposed to. Now type the name of your variable and press Enter again:

Hooray! The console (which is an interpreter) understands your variable. The variable great_song_lyrics evaluated (it was understood) as "La la la, la la la tonight". That’s perfect (by the way, it doesn’t matter if you use single quotes ' or double quotes " as long as you use them in matching pairs).

We’ll talk about other things variables can hold in just a second.

Many programming languages require you to be specific about what kind of variable you’re declaring. In C++, for example, there is no var keyword. There’s an int keyword (for declaring small whole numbers), a long keyword (for declaring big whole numbers), float and double keywords (for declaring decimal numbers), a string keyword (for declaring pieces of text), and a few others. Don’t worry about that right now. You can learn it later.

Objects

An important part of coding is learning how to organize data. Take the birthday example: Facebook has hundreds of millions of birthdays (and anniversaries and breakup dates) stored in computer memory in its warehouse. How does it know what’s what? If I gave you a list of a billion dates, would you know who they belong to and what they’re for? Of course you would, because you are the great Calendifus, Greek god of randomly significant dates.

Luckily, Facebook doesn’t just have a pile of arbitrary dates sitting around. They connect your birthday, your anniversary, your hometown, your employment history, your name, and everything else they know about you together with a unique ID (like the one on your Social Security card or your driver’s license). It’s probably a big number that they picked out of a hat, so to speak. That is, you are number 12884002, and every piece of data they have on you has a label that says “12884002”, and when you log in they look up everything with that number on it. It’s all organized just like that.

In code, you would do this with an object. An object is a bunch of pieces of data all organized together. We can also call this an associative array, a dictionary, or a map. But most often I just say object.

In JavaScript, objects are declared and assigned much like other variables. Here’s an example object:

var dummy = {
id: 12884002,
age: 28,
name: 'Bob',
favorite_song: 'Photograph, by Nickelback'
}

Each piece of data in an object is like a seesaw. The name is on the left, the data is on the right, and there’s a : in the middle to balance on. Really all we’ve done is declare four variables: the first two are numbers, and the last two are strings. But they’re organized together so we can find them whenever we need to know something about dummy. And instead of calling them “variables,” we call them “properties” or “fields.” An object can have any properties you want, as long as you put them all together inside of { curly brackets }.

We can move the dummy object around and refer to it just like any other variable. The computer knows what we mean. If we ever want to refer to just one property of dummy, we use a dot, like this:

dummy.id
dummy.name
dummy.age
dummy.favorite_song

Each of these is just like any other variable. We can assign something to it and refer to it later. Want to change Bob’s name? Easy:

dummy.name = 'Alice'

And that’s that. It’s a really good upgrade, isn’t it? From now on, whenever you type dummy.name, it will refer to “Alice”.

Arrays

Sometimes you don’t want to think up a unique name for every property in an object, especially if they’re all very similar. Or you don’t know how many there are going to be. That’s when it’s time to use an array, which is a list of similar pieces of data. Arrays can grow or shrink as needed.

A good example is all your dumb tweets. Twitter doesn’t know how many tweets you’re going to write. You started at 0, and look where you are now. Twitter uses an array to hold them all. Arrays in JavaScript look like this:

var dumb_tweets = ['Hello, Twitter!', 'My friends are so cool', 'Does anyone want a LaCroix?']

Remember how objects used { curly brackets } ? Arrays use [ square brackets ]. This array has three strings in it, separated by commas. And yes, it’s a variable just like anything else. You can use dumb_tweets anywhere in your code, and it will refer to the array we defined just now.

If you want to refer to a specific string in the array, you’d do it like this:

dumb_tweets[0]
dumb_tweets[1]
dumb_tweets[2]

We use the name of the array, dumb_tweets, and then inside of [ square brackets ] we use the number (or index) of the thing (or element) we want to refer to. I know it’s weird that the first element in the array is number 0. But this is your life now. From this day forward, you will always begin counting at 0. It’s the programmer way.

Each of the above expressions (an expression is any code that turns into a piece of data when you run it) is a variable. You can assign something new to it, if you want.

dumb_tweets[2] = 'I regret literally everything I have ever said'

Whatever happened to 'Does anyone want a LaCroix?'? It’s gone forever. Swallowed by the abyss. G’bye!

Arrays can hold strings, numbers, dates, objects, and even other arrays. You can put arrays inside of arrays inside of arrays inside of arrays.

Any time code or data gets all Inception-ish like that, we say it’s nested.

Arrays can also be properties of objects. An object can have a property that is an array of objects, each of which has a property that is an array of objects…and I’ve done it again. It sounds like a Russian doll, but it’s how data is structured. For example, your Twitter account could be an object that has a property which is an array of tweets; each tweet could be an object that has properties that are arrays of replies, likes, and retweets; each reply, like or retweet could be an object that has properties that are the name, profile picture and bio of the user that gave them; and so on.

var nested_object = {
an_array: [
{
another_array: [
{
yet_another: [
{
message: 'Blink twice if you need help'
}
]
}
]
}
]
}

To access message, you can write:

nested_object.an_array[0].another_array[0].yet_another[0].message

And the computer will know that you mean 'Blink twice if you need help.'.

Objects (continued)

One more trippy part, and then we can move on to the fun stuff.

Everything in JavaScript is secretly an object (don’t tell! Its parents would be so mad). For example, our dumb_tweets array has a property that we never declared:

dumb_tweets.length

What the heck is length? Well, it’s a property that JavaScript creates and updates for you automatically. It tells you how many elements are in the array. In this case it would be 3. There are 3 elements in the array. Go count ’em, but don’t start from 0 this time because I lied and you’re only supposed to start counting from 0 on special occasions. Dang it.

Time for a scary campfire story.

Once upon a time, in an alternate universe, there was a programmer named McChuck. He was the only coder in the whole universe. He had to write all the code that would ever exist, all by himself.

Sheesh, it was just a story. Calm down.

The truth is that no coder is an island. We’re all constantly using code we didn’t write — buckets of it, in fact.

Even if you are a prolific coder and write millions of lines of code in your lifetime, you will use far more lines of code that someone else wrote. Most of this code will come from complete strangers. Some of those strangers will be dead. Their code lives on, even though the fingers that typed it are decomposing in a grave. It’s zombie code. But instead of eating your brain, it saves your brain from doing a lot of hard work. Best. zombie. ever.

How do you use this zombie code? Copy and paste? Occasionally, yes, but not often. Most of the time you’ll access it through an API. An API is a bundled-up set of properties and methods (purpose-built pieces of code) that are named, like variables, so you can refer to them by their name and let them do their thing. They do all kinds of useful things for you.

JavaScript arrays have their own API. The length property is part of this API. Another part of it is the push method, which adds an element to the end of the array:

dumb_tweets.push('Man I hate good attitudes')

A method is like a property because you access it with a dot. A method is different from a property because you have to put ( parentheses ) after it. These parentheses are holding the data we want to add to our array. Now dumb_tweets has four elements. It looks like this:

['Hello, Twitter!', 'My friends are so cool', 'I regret literally everything I have ever said', 'Man I hate good attitudes']

Remember, the index of this last element is 3 (because you started counting at 0) so you would refer to it as dumb_tweets[3]. And dumb_tweets.length would now evaluate to 4.

The JavaScript array API has a lot of different methods in it, but it’s outside the purpose of this post to explain them all. You can see them in their full glory at this link.

Web browsers have a huge API that JavaScript coders use every day. This API has methods for things like animating stuff in a website, getting user input, communicating with other computers over the Internet, manipulating strings, and loads of other stuff. Building a working vocabulary in this API is an essential part of becoming a web developer.

Function is another word for method. It’s just a piece of code that does something and (usually) has a name. Functions are easy to declare in JavaScript:

function giveMeOne() {
return 1
}

We start with the keyword function. Then we give the function a name, just like if we were declaring a variable (here I’ve used capitalization, instead of underscores, to separate words). Then we use parentheses (you’ll see why in a second). Then we use { curly brackets }. Inside the curly brackets are all the lines of code we want to execute whenever the function is called (whenever an expression refers to it by name).

The word return is another special keyword. It makes a value (a piece of data) pop out of the function. Then it ends the function (if you write any code after a return statement, that code won’t execute). So you could do something like this:

var the_loneliest_number = giveMeOne()

This isn’t too hard, right? We declare a variable named the_loneliest_number. The assignment part of our statement calls giveMeOne(), and since that function says return 1, a 1 pops out. So our variable will hold the number 1. Go ahead and execute both of these blocks of code in your browser’s console. Then type the_loneliest_number, press Enter, and you’ll see that it evaluates to 1.

A function can be a property of an object. It can be an element of an array. It can return a number, a date, a string, an object, an array, another function, an array full of functions, and so forth. This stuff is like LEGO bricks. Put any kind of piece anywhere you want and it will fit.

giveMeOne() is kind of like dumb_tweets.push(). The main differences are:

  1. giveMeOne() is a function we wrote by ourselves. push() is a function that some strangers wrote. It’s okay, they don’t mind if we use it.
  2. push() is a method of dumb_tweets (and any other array we’ll ever create). giveMeOne() is global, meaning that we don’t need to refer to a specific object in order to use it.

You’ll notice one more thing that seems different about them: giveMeOne() uses empty parentheses, but push() expects us to put a piece of data in the parentheses. In fact, push() would be useless if we couldn’t tell it what to add to our array. The piece of data we give it is called an argument. An argument is just a piece of data that we drop into a function. Declaring a function that expects arguments looks like this:

function addTheseNumbersTogetherPlz(number1, number2) {
return number1 + number2
}

This function isn’t too different from giveMeOne(). But instead of empty parentheses, these have variable names in them, separated by a comma. These are our arguments. The return statement does exactly what it looks like it’s doing: it adds number1 and number2 together, then pops out the result. You’d call the function like this: addTheseNumbersTogetherPlz(3, 4). And it would pop out a 7.

Ooh! Math! Scary, right? Almost all coding languages let you write math expressions the same way you used to write them in those bricky TI calculators you used in high school. to instantly grow a neckbeard (no, it doesn’t do exponents; you need an API for that).

You could also write the function this way:

function addTheseNumbersTogetherPlz(number1, number2) {
var sum = number1 + number2
return sum
}

This function does exactly the same thing. It just uses a variable named sum as a middleman.

There are many ways to write a function. You should choose the way that most clearly expresses what the code is doing. Code that is concise and easy to understand is often called expressive or eloquent. There’s an artistic pleasure in writing this kind of code.

Programs must be written for people to read, and only incidentally for machines to execute. ~Harold Abelson

This is where code gets extra fun. (It was fun already.)

Computer programs don’t do the same exact thing every time you run them. If they did, then video games would play themselves. That would be a letdown. You’d have to just sit there and watch the story play out on the screen, like a…um…I don’t know, but it would be boring. There definitely wouldn’t be an entire industry dedicated to it.

Programs have to respond to different situations. They have to make decisions. And that’s where things like if statements come in.

Let’s say we’re writing an app that determines whether a particular person is allowed to enter a nightclub. Pretend there’s a method in the JavaScript API that gets a user’s age. We’ll call it getUserAge(). We’ll also imagine that there are two other methods, allowThemInTheNightclub() and throwThemOutOnTheirButt(). How can we help our program decide which of these last two methods to call, based on the returned value of the first method?

var age = getUserAge()
if (age >= 21) {
allowThemInTheNightclub()
} else {
throwThemOutOnTheirButt()
}

See how nice the alignment is on the right side? Monotype for the win.

You already know what the first line does. age will hold a value like 13 or 21 or 101. Now we need to know: is age 21 or over? If so, they can party away. If not, they’ll need to leave.

We do that using an if statement. if is a keyword that looks a little bit like a method. The argument it expects is an expression of some kind, usually a comparison. Comparisons take two values and compare them to each other, resulting in a value of true (if the comparison is true) or false (if it’s not true). These two values are called booleans and they’re the only two booleans in existence. We can make six different kinds of comparisons:

  • === (three equals signs) compares the values on either side to see if they are exactly equal. If they are equal, the result is true. 6 === 6 would be true.
  • !== compares the values on either side to see if they are not exactly equal. If they are not equal, the result is true. 6 !== 3 would be true.
  • > checks to see if the value on the left side is bigger than the value on the right side. 6 > 3 would be true.
  • < checks to see if the value on the right side is bigger than the value on the left side. 3 < 6 would be true.
  • >= checks to see if the value on the left side is bigger than, or equal to, the value on the right side. 6 >= 6 and 6 >= 5 are both true.
  • <= checks to see if the value on the right side is bigger than, or equal to, the value on the left side. 6 <= 6 and 6 <= 7 are both true.

if statements evaluate the comparison you give them. If it evaluates to true, they execute the code inside their block (the lines of code inside { curly brackets }). If it evaluates to false, they skip that code.

if statements can also have an else statement attached to their tail end. The else statement has a block that will be executed if the comparison is false. Look back at our nightclub app. It should make a lot of sense to you now.

Hey, we just made a bouncer redundant (he was replaced by a computer program). Isn’t that a good feeling?

Sometimes, especially when you’re working with an array, you want to execute a block of code several times in a row. This is not the time to use copy and paste. Instead, you should use a loop. The simplest kind of loop in JavaScript is a while loop:

var the_real_slim_shady = ['My name is', 'My name is', 'My name is', 'Waka waka Slim Shadyyy']var index = 0
while (index < the_real_slim_shady.length) {
rap(the_real_slim_shady[index])
index = index + 1
}

while loops use the same syntax as if statements. You use parentheses, you pass in a comparison, you follow it up with a block. But an if block only executes the code inside of it once (or zero times, if the comparison evaluates to false). A while block executes the code inside of it over and over again until the condition is false. That is, it evaluates the condition; if it’s true, it executes the block; then it evaluates the condition again; if true, it executes the block again; then it evaluates the condition again; and so on, forever. I’ve invented an imaginary API here that has a rap() method, but everything else is regular JavaScript.

How many times will the loop execute? Well, the first time it evaluates the comparison, it checks to see if index (which is 0) is smaller than the_real_slim_shady.length (which is — go on, count them — 4). Since the comparison is true, it executes the code, which raps the_real_slim_shady[0], because index is still 0. Then the magic happens: it changes index to index + 1, or 0 + 1, which is 1. Then it evaluates the comparison expression again. 1 is still less than 4, so it executes the block again — but this time, since index is 1, it raps the_real_slim_shady[1]. Get it? It will stop executing the block when index equals 4, which is good because the_real_slim_shady[4] doesn’t exist. When a loop operates on multiple elements in an array, we say it’s iterating.

If you declare a variable and do not assign a value to it, it will hold a special value called undefined. This is a geeky word that means “move along, nothing to see here.” It’s mostly useless.

JavaScript also has a special value called null. It means roughly the same thing as undefined. They really shouldn’t have included both words in the language. But they did and it’s too late now.

Functions are very selfish. If you declare a variable inside of a function, the function won’t let any of the code outside of itself use the variable. For example:

function whatHappensInVegas() {
var wildIndiscretions = ['partied', 'danced']
return 'I admit nothing'
}
whatHappensInVegas()
whatHappensInVegas()
whatHappensInVegas()if (wildIndiscretions.length > 0) {
getADivorce()
}

We have a very simple function. It declares the variable wildIndiscretions, but it doesn’t return it. The outside world knows nothing about it! We even run the function three times, because we’re young and full of stamina. The if statement is trying to pry into the function’s personal life, but it can’t. The code inside of the if block will never execute. In fact, the comparison wildIndiscretions.length > 0 will throw an error (it won’t work and you’ll see a message explaining why) because wildIndiscretions is undefined outside of the function whatHappensInVegas. It doesn’t have any properties, let alone length.

However, if you move that if block inside the function block (before the return statement, of course) then it will gain access to wildIndiscretions. Hope you had a prenup, bub!

It isn’t always obvious what a piece of code is doing, or what still needs to be done with it. If you need to break out of the computer language and have some real talk about what’s going on in the code (or just drop some dope lyrics), you can use a comment, or a line of code that the computer will ignore. You start a comment with // two forward slashes. Like this:

function isEven(num) {
// This function determines if "num" is even or odd.
// If even, it returns true. If odd, it returns false. // TO DO: add a second argument that lets you specify
// a message to display if "num" is odd.
return (num % 2) === 0 // Hey, yo, do it like Isaac
// If you ain't with me, baby ain't wise-aac
}

Don’t worry about the maths in the return statement. I’m just demonstrating that you can use comments to explain what’s going on, to leave a note for your future self, and to spit bars. The last usage is probably frowned upon in serious codebases. But don’t let the man hold you back. You were born to do what you were born to do.

The last and most important thing I can teach you is this: when you don’t know how to do something, immediately go to google.com and ask. The generosity of the programming community will astound you. Thousands of developers all around the world have freely shared their code and knowledge on sites like GitHub and Stack Overflow, which means that all you need to become an expert in any programming language is a steady internet connection and the ability to read.

Good Google queries take a little bit of practice to write. A good template is something like this:

[programming language] how to [something]

For example, want to know how to remove an element from an array in JavaScript? I’m not gonna teach you. Try typing this into Google: “JavaScript how to remove an element from an array”. The first few results should give you all the information you need (with examples!)

Most large-scale apps use all the concepts and keywords I’ve described. Their code comprises thousands upon thousands of lines of code, all built from these same basic elements. So what are they doing?

On a basic level, they’re receiving inputs (data that enters the code from somewhere else, like a user’s keyboard), transforming them (often by iterating over them, doing maths on them, or reorganizing their properties), and providing outputs (data that leaves the code). Every computer program can be described in terms of its inputs and outputs. Every programming language has methods in its API for accepting inputs and providing outputs.

An ice maker is a good analogy for a computer program. Its inputs are water and electricity (they come from an API known as “municipal utilities”). Its output is ice (which is submitted to an API known as “a tall glass of Coke”). Do you care what happens in the middle? Not right now, as long as you get your ice without too much trouble. But someday the ice maker will break down. And whoever has to fix it will care a lot about how simple, robust and well-built its internal components are.

A coder’s job isn’t just to provide the ice, although that’s important. A coder’s job is to make sure that when the ice maker breaks, the person who has to fix it doesn’t develop an explosive stress-hernia in the process. That’s the difference between an amateur coder and a pro.

Ya done good. I’ve taught you enough programming basics that, with a little imagination and plenty of Googling, you can teach yourself everything you need to know to write apps. If you want to.

You may still feel like you’re missing some vital information. And you are. But you’ll never learn it all, and this is a good start.

If you’re still shaky on your feet, go check out some more JavaScript tutorials. There are tons of free ones online. And once you feel confident enough to write some code of your own, go build something. There’s no substitute for getting your hands dirty.

Good luck!

  • How to Think Like a Computer Scientist, by Allen Downey, Jeffrey Elkner and Chris Meyers. This is a more well-written and comprehensive (but arguably less entertaining) version of what I’ve written here, geared toward the Python programming language.

This is an early version of a chapter from Your First Year in Code, a book of practical how-to and advice for new developers. If you’re considering a career in software, check it out at https://leanpub.com/firstyearincode.

8 Principles to Remember

“I hate reading other people's code” is a mantra you hear a lot from developers of all levels. However, it's a necessary skill, especially for developers who need to get comfortable with an existing codebase, and if you approach the job with the right mindset and the right tools, it can be a very enjoyable and enlightening experience.

  • 1. Learn to dig
    • git blame
    • git log
  • 2. Return to the past
  • 3. Read specs
  • 4. Think of comments as hints
  • 5. Find Main
  • 6. Pay attention to style.
  • 7. Expect to meet trash
  • 8. Don't despair

We don't like to read other people's code for the reason that it is not written by us. It goes without saying that deep down we consider ourselves the best programmers on the planet and no one can write such cool code as we do. Writing code is an intense thought process, and the passive reader experiences nothing of the sort.

The code you see on the screen could have been written by more than one person. Perhaps in the process of disputes and cooperation. It may have taken them weeks to come up with code that circumvented some undocumented limitation that you don't know about, and that knowledge is only in the minds of those who wrote it.

All you see as a reader is the finished product. And unless you do some digging, the only context you'll be working with is that same code on your screen.

1. Learn to dig

When you first encounter a serious codebase, you may not feel like a developer. Rather, you will feel like an archaeologist, private investigator, or researcher of religious books. This is quite normal, because you have several tools for "excavation" at your disposal. If you're lucky and your predecessors used version control, it's worth celebrating! You have access to a wealth of metadata that will make it much easier for you to understand the context in which the code was written. Further, I assume that you are using Git, but in the case of SVN, everything will be about the same.

git blame

This command allows you to get the author name, last modified date, and commit hash for each line of code. Meet the authors. If you're lucky, there won't be many of them, and they may still be working in their place, so you can turn to them for help. If you're unlucky, there will be dozens of authors you've never heard of before. In any case, try to identify the main contributors. If you stumble upon a strange function that you can't figure out, use git blame to find out its author and ask him personally.

git log

Use this command to see the commit history of the entire repository. This command prints commit messages, and the grep command will help you find specific text in commits, such as someFunction: git log | grep someFunction -C 3 (Last flags will show you the found expressions with three lines of surrounding context.)

Also git log can show you the history of a single file, use the -p flag: git log -p index.js . Pay attention to the names of the committers so you know who to direct questions to in the future.

2. Go back in time

You can switch to any commit you like and run the project as if it were the last commit. You may need to switch back to the commit that was last before some hard-to-track problem occurred. Or maybe you just get bored and want to dig into the history of the code and see what the project was like years before you got there.

If the project is hosted on GitHub or similar, you can get a lot of information from tickets, pull requests, and code reviews. Pay attention to the tickets that had the most discussions. There may be "pain points" that you may encounter in the future, so it's good to be aware of them in advance.

3. Read the specifications

Specifications are new comments. Read unit specifications to find out the purpose of functions and modules, and the possible edge-cases they handle. Read integration specifications to find out how users will interact with your application and what processes your application supports.

4. Think of comments as hints

If you stumble upon a feature you don't understand and read a comment on it that confuses you even more, it's possible that the comment is just outdated and hasn't been updated.

A programmer's eyes have the ability to skip the green comment text, and it's possible that this perplexing comment referred to a feature that disappeared many months (or years) ago without anyone but you noticing.

5. Find Main

This may seem obvious, but first make sure you understand where the code starts executing and what happens during the run. See what files are included, what classes are instantiated, what config options are set.

You will most likely see them all the time in the rest of your code. Some modules will be very general and stand out from the rest of the code. They are smaller and more understandable pieces of functionality that you should be familiar with before trying to understand the entire application.

Run git blame on this file and see what parts of the main file have changed recently. Recently changed code can give you clues about what issues the team has been working on lately. Perhaps they introduced a new library, or they tried for a long time to fix a library that didn't work very well. Or maybe it's just some kind of boilerplate code that needs to be updated regularly.

Try to find references to these modules in other parts of the code to understand how and when they are used. This can help you understand the place and role of modules in the main application.

6. Pay attention to style.

You're learning this application for a reason, and sooner or later your code will end up there too, so pay attention to the style. This includes things like coding standards conventions: naming conventions, spaces, brackets, and coding conventions.

What is the general level of abstraction? If it's highly abstract code with many levels of abstraction, then you should write it the same way. If you dig deep into the history, you can probably find the moment when one of the developers decided to abstract some of the code. What did it look like before, and what happened to it after it was taken to a new level of abstraction? Try to follow the same conventions when writing your code.

Going down to the micro level, look at what constructs the rest of the developers on your team are using. If they favor loops over map , then you should probably prefer loops too. If you would like to change some conventions, then discuss with your team the possibility of changing them in the future, rather than start mixing different styles in one file. Good code looks like it was all written by the same person. Being consistent is more important than being smart.

7. Expect garbage

You may encounter functions or even entire files that are never used. You may come across commented code that has been sitting untouched for several years ( git blame for help). Don't spend too much time on this, and don't be afraid to get rid of these artifacts.

If this code was needed, someone will mark it on the code review. And you will do a good deed by reducing the amount of mental load for the next person to read this code.

8.

Don't despair

Keep the previous points in mind, and don't lose heart if you feel completely confused. Learning code is not a linear process, don't expect to understand everything 100% right away. Pay attention to important details and know how to dig to find answers to questions, and you'll find things become clear pretty quickly.

Author: William Schon, consultant and developer at Ann Arbor. The original is here.

One of the easiest ways to improve your programming skills is to read other people's code / Sudo Null IT News0001

Note: This article was originally written for Fuel Your Coding back in May 2010. Unfortunately, this site is now down, so I'm posting the article here to save it for posterity. I was going to update it with the latest trends, but decided to leave it as it was written. Those parts that are outdated may seem a little funny, but oh well. Have fun...

The most obvious way to improve the quality of your programming is to write more programs. Everyone knows this. However, another way that I'm sure will improve your programming is just the opposite. I'll make this as clear as I can.

If you want to dramatically improve your programming skills, you need to… read code written by other programmers.

You may or may not believe it. Your right. But if you're willing to take the risk, I'm sure you'll be rewarded for your time.

In this article, I would like to help you choose what to read and give you practical advice on how to read it. If you are already reading other programs, then maybe you will find something here that will allow you to get more out of your efforts. If you do not read the codes of other developers, then you simply must do this.

What to read

This is an important decision, and one in which it is difficult to advise. I wouldn't like to just point you to some code that I think you should read, because what you really need to consider is what you are doing. However, I will give you some guidelines to help you choose your reading software.

Read programs related to you

A great place to start is any plugins or libraries you already use.

• A WordPress plugin you really like;
• Ruby gem that you find useful;
• The jQuery plugin you keep coming back to.

All of them are prime candidates for study. You already know their public interfaces, so the barrier to understanding their inner workings is below. In addition, you - as a user of this program - have the opportunity to add documentation, introduce a new feature, or generally contribute to this project in some way.

Read programs that impress you

I remember the first time I looked at 280 Slides, a presentation creation service, I thought, “Yeah! Cool!". I quickly found out that the program running this site is an open source Cappuccino project. This knowledge entered deep into my mind, and when I somehow stumbled upon another impressive application that worked on Cappuccino, I already knew that I could learn a lot from this project. What has made a strong impression on you lately? Is this program open source? If so, it's a great choice to read: the code is likely to impress you as much as the app itself.

Read programs written by people you respect


Programmers worthy of respect

respect. I could immediately name a few developers whose programs make me just “white envy”.

If you don't have such a developer yet, it's easy to find one. He/she is probably the author of some program in one of the previous two sections (programs related to you or programs that impressed you).

Read programs that you can actually understand quite deeply

If you're a risk taker, you might consider diving into a big project like Ruby on Rails, Drupal, or jQuery. But I would suggest that you do not use such projects yet, unless, of course, you are an experienced reader of programs.

Large projects have an enormous amount of interacting parts, and you end up spending a lot of time and effort mastering the general concepts to learn something specific. The intricacy of the subject matter is chilling, and large projects are more likely to lead to your reading frustration. The advantage of choosing a small project to read is that you can keep all the logic behind the program in your head. This allows you to work only with details in order to learn some lessons.

How to read

Now that the code to read has been chosen, what is the best way to read it? I have read many programs to date and can suggest several ways to maximize your efficiency.

Explore the big picture


The twitter gem directory structure

I'm assuming you at least know at the macro level what the code you're reading does. If not, I suggest reading the project website, tutorials, documentation, and anything else you can get your hands on besides the code.

Once the proper clarity is in place, your first step should be to consider the structure of the project. The amount of this work depends on the size of the chosen source code base, but even if it takes more than one file, it will only take slightly more time.

First of all, fix the file structure for yourself. This step is easier to do with an editor that looks like a folder hierarchy, such as TextMate. Here's a nice view of the Twitter Ruby gem as an example.

The purpose of this step is simply to familiarize yourself with the source. Understand what files include/call/load other files, where the bulk of the code is located, what namespaces are used (if any) and stuff like that. Once you get the general idea, you can dive into the details.

Document your results

Reading the code should not be some kind of passive activity. I recommend adding comments as you go, documenting your assumptions and your conclusions as you begin to understand the flow of the program. When you first start, your comments will probably look like this:

 # I believe this function is called after "initialize" # What does this task do? # Pretty sure this variable loses its scope after line 17 

As you understand the processes, you may want to remove the small hierarchical comments you've kept for yourself, and perhaps write more meaningful and authoritative comments that could be passed back to the project.

Use the tests, Luke

0151

Hopefully the project you have selected has a test suite. If not, you can skip this section altogether (or find a project that has one).

Tests are a great place to start reading someone else's code because they document what the program is supposed to do. Some tests are more informative than others, but no matter how well they are written, it is often much easier to find a programmer's intentions in tests than in implementation. When reading, try to get a successful result when running the entire test suite. This will ensure that your development environment is configured correctly and give you more confidence when making changes.

Change code, compile

Who said code reading should be passive? You will only really begin to understand the code after you break it all down and put it back together again. Do you remember the tests you passed? Make them fail, add something, or try to change the implementation so they fail. Try adding some little "feature" that you think is "cool", or set up logging throughout the project so that you can print the output at various stages of the program. Is it still reading? Absolutely, but this approach is more of an adventure of one's own than reading a detective novel. And this is exactly what you need!

Rinse and repeat

When you're done reading one codebase, pick up another and start the process again. The more codes you read, the better that reading goes and the more you get out of it in less time. I think you'll find that your efficiency builds up quite quickly and that it's actually a very enjoyable way to learn.

Where to start

The single most important source for reading code is GitHub for me. This site makes it so easy to find new projects and really great programmers that you're hurting yourself if you don't use it. I suggest starting on GitHub and reading through the code directly on the site until you find a project that you think you can learn from.


Learn more