Re-factoring

Always wanted to travel back in time to try fighting a younger version of yourself? Software development is the career for you!
-@Loh

It’s so weird to come back to something you were happy with, so happy with you posted it to your site, and say ‘gah, this is terrible.’ There were so many things wrong with that last calculator.

It’s super important to say here that there is no absolute way to determine whether code is good or bad. Beyond ‘working’ vs. ‘not working’ there are a few other standards: code that is easy for most other developers to understand, that handles error conditions in a predictable way, code that uses fewer server resources to run. Every thing except ‘doesn’t run’ is just a matter of degree, and often you gain performance by sacrificing readability etc. etc. My gripes about my own code are more a list ‘red flags’ than any absolute problem

Let’s talk about some ways to evaluate code that is in general, not so good:

  • tons of comments – comments are good and helpful when they are good and helpful. If every third line of your code needs explanation, there’s a chance your code path is pretty convoluted

  • multiple safeties – my first version had two different ‘checker’ methods for a few dozen code lines. Two methods to check one line of user input isn’t great :/ At a basic level: methods have error conditions already, or ways to handle weird input. Double-triple-checking that you’re not calling pop() on an empty array isn’t actually necessary, just make your other functions handle undefined.

  • long – I’ve talked about this before, hell everyone has talked about it, but there’s usually a good chance that going from 60 to 12 lines for the same functionality will be easier to read and understand.

so here’s the ‘better Reverse Polish Calculator’:

var stack = []
function handleInput(expressions){
  if (expressions == "q"){
    console.log("recieved 'q,' quitting")
    process.exit(0)
  }
  var inputArray = expressions.split(' ')
  inputArray.forEach(function (expression){
    if (/\d/.test(expression)){
      stack.push(parseFloat(expression))
    }
    switch (expression) {
      case '+':
        stack.push(stack.pop() + stack.pop())
        break
      case '-':
        stack.push(stack.pop() - stack.pop())
        break
      case '*':
        stack.push(stack.pop() * stack.pop())
        break
      case '/':
        stack.push(stack.pop() / stack.pop())
        break
    }
    console.log(stack)
  })
}


process.stdin.resume()
process.stdin.setEncoding('utf8')
process.stdout.write('\033[32m> \033[0m') //input prompt
process.stdin.on('data', function(datum) {
  handleInput(datum.trim())
  process.stdout.write('\033[32m> \033[0m')
});


One thing I love about this refactoring is it doesn’t actually do anything new. I did some research into whether it would be possible to just use the "+" as an operator without having to recognize the string, but there was no easy way to get it done.

Leave a Reply

Your email address will not be published.