learnyounode Lesson 2 – Baby Steps

In lesson 2 we need to write a program that accepts one or more numbers as command line arguments and then prints out the sum of those arguments.  Hmm…that’s a tough one, especially if you are accustomed to using JavaScript for browser applications.  You could spend a bunch of time researching how to build command line applications in node.  Fortunately,  you don’t have to.  Learnyounode give’s us a great hint to start with.

The hint tells us that command line arguments can be accessed from the process object.  One of the properties of the process object is argv, an array that contains the complete list of command line arguments.  If you like, you can see the contents of process.argv by creating a simple program that contains the code that follows.

console.log(process.argv)

You can run this from the command line the same way you ran your helloWorld.js application from the previous lesson.  If you run this code with a couple of numbers passed as arguments, you might notice that those arguments are stored as strings in the process.argv property.

node myProgram.js 1 2 3
['node', 'myProgram.js', '1', '2', '3']

The hint in learnyounode points out that we may need to convert these strings to numbers to complete the exercise by passing it to the Number() method, or by prepending it with the unary + operator.  Ah, that’s pretty simple after all.  Here is the official solution in learnyounode that ties all of the hints together.

Official Solution

[toggle title=’Click to show/hide solution’ border=’none’]

var result = 0

for (var i = 2; i < process.argv.length; i++)
  result += Number(process.argv[i])

console.log(result)

[/toggle]

Notice that the loop in the official solution starts at array index[2].  If it didn’t, we would get slapped with NaN instead of the sum of our arguments because the path to node and the path to your program are strings.  The official solution is really all you need to pass the lesson.  But, it isn’t the only way to pass the lesson, and it has a flaw that may be important to know about if you would like to build on this lesson in the future.

Let’s say that instead of passing only numbers as arguments, you are passing numbers and strings all mixed together.

node babySteps-official.js 1 2 a 3
NaN

Instead of getting the sum of our numbers, we get NaN because a is a string.  The official solution is only valid if you will only pass numbers as arguments.  If you want to pass a combination of data types, but only sum the numbers without getting NaN (not a number), you will need to make your program a bit smarter.  Below is my solution for the baby steps exercise, which can handle a list of arguments has non-number datatypes.

Alternate Solution

var sum = process.argv.reduce(function (a, b, c) {
  if (c >= 2 && !isNaN(b)) {
    return +a + +b
  } else if (c >= 2) {
     return +a + 0;
  } else {
     return 0;
  }
})

console.log(sum)

Instead of using a for loop, I am using the Array.prototype.reduce() method.  In my callback function, a is the previous value, b is the current value, and c is the index.  Note that I am prepending a and b with the unary + operator to coerce the process.argv string values into numbers.  One criticism of my solution is that the index start position is still hard coded (c >= 2).  Technically, it will only sum a list of arguments starting at index[2].  For the sake of accessing the process.argv property, this is probably fine as index[0] is always the path to node, and index[1] is always the path to your program.  However, you would need to modify this solution if you were going to use it for something other than accessing the process.argv property where the data type of index[0] and index[1] might not be known.

Lesson 3

Contents