Finding the first 100 prime numbers with Javascript

The first homework assignment for the Stanford Startup Engineering class on Coursera was HARD. Hard for me as someone new to programming, anyway.

I did a lot of Googling to help me get the right answer, but I had a hard time deciphering what I found. Most of the resources seem to have been written by programmers for programmers, not for learners. Although my process (and my code) may look ridiculous to the CS majors out there, I’m hoping that sharing will help others who are learning to code from scratch. Maybe it will also help those who design programming curricula to see how a beginner thinks.

Assignment

… write a node.js script that writes the first 100 prime numbers to a file, with each prime separated by a comma. Remember that the first prime number is 2, and use a function that tests for primality. Here is what the file would look like for the first four prime numbers:

2,3,5,7

There are many ways to do this problem. You may want to look at the methods in the JavascriptMath object, especially ceilfloor, and sqrt. You will also probably want to look at the Arrayobject’s length and push methods.

Submit: A file containing a comma-delimited list of the first 100 prime numbers, and the corresponding node.js script that you used to generate it.

I think that experienced programmers may take some of the steps to completing this assignment for granted. Here is how I went about it.

Sandboxes

For the class, we have been using the command line. (I am probably going to be explaining all of this in the wrong terms, sorry!) They had us writing code in Nano, which I just Googled and learned is a Linux text editor. It is hard to code this way because you can’t make changes easily. Codecademy has a nice sandbox that gives you little syntax error messages on the side. I wrote the code in Sublime Text (which I installed for Railsbridge) and then tested it in the sandbox.

Step 1 – Determining if a number (n) is prime

Oh, Math. The day I passed my AP Calculus test was one of the happiest days of my life because I knew I would never have to take a math class again! Thanks to that terrible attitude I am trying to learn programming at 29 with a 6 month old to take care of…

Not being a fan of math, I had to Google prime numbers and how to determine if a number is prime. Trial division is the simplest way, although it is time consuming if you need to do it by hand. Luckily, Javascript was doing the dividing, not me. I also knew that I only needed to test a  relatively small quantity of numbers in order to get the first 100 primes. (Note this is not the primes from 1-100, which some people in the class thought at first.)

Step 2 – For loop

I am working my way through Codecademy while I do the Startup Engineering class. I had not gotten to section on loops in Javascript yet, so I had to stop working on the homework to get up to speed. The Codecademy lessons helped a lot. It was fairly straightforward loop to get the numbers to run through my trial division. The problem was that it was printing out “undefined” whenever a number was not prime instead of just skipping it. I googled around to solve this and found this very helpful bit of code:

arr = arr.filter(Number);

This is filtering out everything that is not actually a number from my results (or so it appears).

I also ended up having to add in the lower primes manually that I was using as divisors. I’m pretty sure this is not the best way to do this, but it worked. Here is the code (I’m having trouble recreating the indention, so hopefully you get the idea):

var prime = function (n) {
if (n === 2 || n === 3 || n === 5 || n === 7 || n === 11 || n === 13 || n === 17 || n === 19) {return n;} This says to print out those numbers.
if (n % 2 > 0 && n % 3 > 0 && n % 5 > 0 && n % 7 > 0 && n % 11 > 0 && n % 13 > 0 && n % 17 > 0 && n % 19 > 0 && n % Math.sqrt (n) > 0) {return n;} This says to divide by those numbers and then divide n by its own square root. If there is a remainder, the number will be printed.
};

Step 3 – Printing and formating

Now I had a clean list of numbers, but I needed to push them to an array and I only wanted the first 100. I also needed commas between the numbers. All of this took some trial and error. I used some of the code that we had gone over in the class lecture.

var first100primes = function(k) {
var n = 1;
var arr = []; Here I created the array, which will be the list of primes.

for (n = 1; n < k+1; n++) {
arr.push(prime (n)); Here I am pushing the results of the loop into the array.
}
arr = arr.filter(Number); Here is were I removed the undefined results.
arr.length=100; I made the length of the array 100 to only show the first 100 results.
return arr; And I print the array.
};

var fmt = function (arr) {
return arr.join(“,”); This is to add commas into the array. I am not sure that this was actually necessary. There was some debate about the commas in the class forums, but the professor used this in his example.
};

var final = (fmt(first100primes(1000))); Here I am actually calling the loop for number 1-1000. This is not the most efficient way to accomplish my goal, but I knew the first 100 primes would be in here somewhere. I also made the results into a new variable so I could do the next part more easily.

Step 4 – Moving my program around

I felt great that I had gotten the right answer, even if it was in a roundabout way. My code was producing the results I wanted in the Codecademy sandbox, but that was not enough. I needed the code to print to a file and I needed to do all of this on my Amazon Web Services instance through the command line. Then I needed to download the .txt file that contained the 100 primes and the .js file that generated the .txt file to my computer. I pretty much copied the professor’s code from the lecture to print the .txt file:

var fs = require(‘fs’);
var outfile = “prime.txt”;
fs.writeFileSync(outfile, out);
console.log(“Script: ” + __filename + “\nWrote: ” + out + “To: ” + outfile);

He had also given us instructions on how to push and pull from our AWS instance. Finally, miracle of miracles, I had prime.txt with the first 100 primes and prime.js on my local machine.

Step 5 – Debugging

Elated, I went to upload my files to Coursera for class credit. To my extreme frustration, I got an error saying my primes needed to be comma delimited. They were already comma delimited! I headed over to the class forums to find that this was a problem for many people. Some said you needed to added a terminal comma, some said you needed to remove the terminal comma, some said you needed to remove any spaces around the commas, and some found other solutions. The solutions were contradicting each other and I was annoyed. I had the right answer! Maybe the problem was not solved in the very best way, but it was solved. What did the automatic grader want to see?

My results did not have the terminal comma, but because some people’s answers were accepted without it, I couldn’t imagine that was all I needed. Still, it was the quickest thing to test. I literally just stuck a comma on the end of my results:

var out = final + “,”;

Crazy as it might seem, this worked! My answer was accepted and I passed the homework!!

Takeaway

I learned a lot from this assignment. Mostly I learned that I can do this. It might take me awhile and my code might not be as efficient as it could be, but I can keep up with assignments for a Stanford software engineering course. I hope this gives other CAHMs hope that they can do it too!

Complete final program

#!/usr/bin/env node

var prime = function (n) {
if (n === 2 || n === 3 || n === 5 || n === 7 || n === 11 || n === 13 || n === 17 || n === 19) {return n;}
if (n % 2 > 0 && n % 3 > 0 && n % 5 > 0 && n % 7 > 0 && n % 11 > 0 && n % 13 > 0 && n % 17 > 0 && n % 19 > 0 && n % Math.sqrt (n) > 0) {return n;}
};

var first100primes = function(k) {
var n = 1;
var arr = [];

for (n = 1; n < k+1; n++) {
arr.push(prime (n));
}
arr = arr.filter(Number);
arr.length=100;
return arr;
};

var fmt = function (arr) {
return arr.join(“,”);
};

var final = (fmt(first100primes(1000)));

var fs = require(‘fs’);
var outfile = “prime.txt”;
var out = final + “,”;
fs.writeFileSync(outfile, out);
console.log(“Script: ” + __filename + “\nWrote: ” + out + “To: ” + outfile);