Sequoia / clijs

Nodeschool lesson-set for learning to build shell tools with javascript
GNU General Public License v3.0
5 stars 0 forks source link

"Using Pipes" revisions #17

Closed Sequoia closed 9 years ago

Sequoia commented 9 years ago

Notes

I'd probably say that this lesson is "too hard" as it currently stands. It took me a minute to figure it out and I'm reasonably good at this stuff. I want to carefully avoid (as much as possible) learners getting "stuck", and I think this lesson would get people a lot of people stuck.

Proposal

  1. Focus-group it some on IRC
  2. Add hints
  3. Find ways to make this one "easier"
ghost commented 9 years ago
ghost commented 9 years ago

@Sequoia

I'd probably say that this lesson is "too hard" as it currently stands. It took me a minute to figure it out and I'm reasonably good at this stuff. I want to carefully avoid (as much as possible) learners getting "stuck", and I think this lesson would get people a lot of people stuck.

Understood. I can't say I completely disagree.

After amending the readme with another 1,000 words of explanation and several more code examples, it's clear that -- at least for absolute beginners -- this example has too many dependencies.

I'll start thinking of new ways to maybe make the lesson a little easier :tired_face:

ghost commented 9 years ago

@Sequoia new idea !

What if we try something more like this:

(proposed intro for updated lesson)

So far our CLI programs have taken a small number or command line arguments. But what if our program needed to accept a different kind of input? Or, what if we didn't know value of the inputs at the time our program was launched?

It's possible to feed information into a program's standard input (or stdin) using a mechanism called piping. The primary benefit of using this kind of input is that we can accept input from another program's output. The command line supports piping via the | symbol and we'd like to take advantage of that.

In this exercise, a Bingo Number Generator will send a number to your program once per second. Your program will receive a total of 5 numbers. Your job is to output each number and finally say "BINGO!" after all 5 numbers have been printed.


Whipped these up quick

index.js

var letters = ["B", "I", "N", "G", "0"];
var numbers = ["1", "2", "3", "4", "5"];

function sample(arr) {
  return arr[Math.floor(Math.random()*arr.length)];
}

function getNumber() {
  return sample(letters) + sample(numbers);
}

function asyncForEach(arr, iterator, callback) {
  var queue = arr.slice(0);
  function next(err) {
    if (queue.length === 0) return;
    iterator(queue.shift(), next);
  }
  next();
}

asyncForEach([1,2,3,4,5], function(_, done) {
  setTimeout(function() {
    process.stdout.write(getNumber());
    done();
  }, 1000);
});

solution.js

process.stdin.on("data", function(number) {
  console.log("received: %s", number);
});

process.stdin.on("end", function() {
  console.log("BINGO!");
});

Example run

node index.js | node solution.js

Output

received: G3
received: I5
received: B5
received: G4
received: N5
BINGO!

Looking at that solution.js file, it seems like a much nicer example.

Let me know your thoughts.

ghost commented 9 years ago

And yes, I know that 5 random numbers don't always result in a bingo... I just ...

/me gives up :sob:

Sequoia commented 9 years ago

I disagree with using the + to automatically cast the buffer into a string.

You do this in the solution tho :question: If the learner uses toString they will get an error when .read() returns null which is just another layer of complexity. Basically my point was "if they need to cast/convert buffers let's mention that in the Readme"

if the user did so something like total += chunk

This is gr8 I like it, my concern is that they are not going to know to do that from the readme/examples.

The end event does not fire until you've consumed the stream though. E.g., I've verified this solution does not work

I just meant don't put console.log in there cuz it makes it seem like that's where you should be outputting lines for your solution-- I didn't mean to say "don't listen to readable at all" tho I can see how I wasn't totally clear.

ghost commented 9 years ago

Using Pipes revisions will not result in an elementary exercise that benefits the learner