Wednesday, September 30, 2015

Spider Attacks

One thing that's been bothering me ever since I started the comics on Amphibian.com is how my visitor stats keep getting skewed by spider attacks.

Not like actual arachnids, I'm talking about the automated systems that are constantly out there reading web pages and cataloging data extracted from them. All the search engines use them to index the web, but spammers use them as well - seeking out web pages with comments forms or other input fields in which they can inject links to Russian pornography sites. I get these things all the time.

While most of my traffic is legitimate, every once in a while I'll have a day where there's a huge spike in "visitors" to the comics, and 90% of them are not real people. I can tell because I record the user agent strings and then check them for legitimacy.

While I can't stop the spiders from crawling, I just want to make sure I don't count them in my stats. I want to know how many real humans viewed comics. Today I tried something new with my stats that maybe I should have done months ago but didn't think of until recently. Instead of counting accesses to one of the comic URLs directly (like http://amphibian.com/227) I'll count access to a small 1x1 pixel image with the comic number as part of the name (like http://amphibian.com/images/v/227). I put this image on every comic. Real browsers operated by humans will load the image while Russian porno spiders won't. I checked the logs, except for the Google Image Search bot, images are largely ignored by spiders.

We'll see if that helps. So if you're a human, please read my comic.

Amphibian.com comic for 30 September 2015

Monday, September 28, 2015

Our 13th Anniversary

Today marks 13 years since my wife Rebecca and I were married. While we've mutually agreed to abandon the practice of gift purchasing every year on this date, I thought it would be nice if I devote my blog today to our lives together.

Really that just means I'm going to share lots of old pictures. So here it is, our relationship over the last 15 years...


One of our earliest photos, this is Rebecca in my Cougar at the All Ford Nationals car show in Carlisle. As you can see from the date imprint (pre-digital camera here), it was June 3, 2000.


Here she is as my fiance in January of 2002.


And here we are shoving cake in each other's faces at our wedding reception. That's a weird tradition. And what's with that light being held by that person on the right? Is that a camera flash?


We used to travel to the U.K. back before we had kids.
Here she is in London back in the Spring of 2003.


And the two of us together in front of a big pile of rocks a week later.
They call the rocks Stonehenge. I don't know what you call that old jacket I was wearing, but the thing hanging around my neck is for the audio tour.


In the fall of that year, we somehow got this picture of us taken at a scenic overlook near our home. I don't know if the camera had a timer or we found someone out in the forest to help us.


We were back in the U.K. again the following year. This picture was taken in Bourton-on-the-Water in 2004. They had a lovely hedge maze which entrapped us for hours, but today could easily be thwarted by the availability of satellite imagery on mobile phones.


There was no international travel for us in 2005, as we brought home our first daughter. Here she is with Rebecca when she was about a month old.


Here is Rebecca showing off baby Alex's first Halloween costume.


And here's a family picture from early 2006. I have no idea where we were in this photo.


In this photo from the summer of 2007, we find Rebecca and a two-year-old Alex sharing an ice cream cone at a local fair.


This was the best picture I could find of the two of us together in 2008. I have a strange expression on my face, but I probably have one of those most of the time.


The following year, we added another daughter to our family. This picture shows Rebecca and Gladrielle at the Juniata County Fair in September.


In 2010, we had this lovely vacation at Walt Disney World in Florida. Above, Rebecca waits for the Big Thunder Mountain Railroad after just getting off Splash Mountain.


Here we have a wonderful family picture from that same 2010 trip. Goofy is not part of our family. But notice the frog shirts. I'm wearing Science Frog years before he showed up in a comic.


In 2011 we took two vacations. Above, you see us back at Disney World for the Star Wars Weekends. That was the Droid we were looking for.


And then later that summer we visited Corbin, Kentucky. In the photo above, we're about to get in a raft for an up-close encounter with Cumberland Falls (which produced a moon-bow for us that evening).


In this picture from the fall of 2012, we have the first appearance of our third daughter, Natasha (on the far right). We were foster parents when this picture was taken, but we would adopt her later. Yes, it is the same scenic overlook where we were photographed in 2003.


By the time this photo was taken in March of 2013, Rebecca had this wonderfully purple hair. This picture was taken at the airport...


...where we were on our way to the big OUYA party in San Francisco on March 28. In the above photo, Rebecca was waiting with me for the fun to start. Unfortunately, OUYA didn't make it (it sold to Razer earlier this year) but she still has dress she bought for the occasion.


Here is a fun family photo from early 2014.


Here we see that Rebecca is not afraid to face the Dark Side, at least when taking the kids to get autographs. We're back at Disney World for Star Wars Weekends 2014.


We also had this great family photo taken there that year. No one was frozen in carbonite.


Here she is with all our girls in April of this year, 2015. It was a little windy that day, so she couldn't keep her hair out of her face. Also, since she's standing behind Gladrielle it is not easy to notice that she is pregnant in this picture.


Finally, here is Rebecca with our fourth daughter, Kayci. This picture was taken on June 6th, 2015, almost exactly 15 years after that picture of her in my old Cougar.

And there is my photographic journey through the last 15 years of our lives together, 13 of which we've spent as husband and wife. Hopefully she doesn't hate any of these pictures, since I didn't tell her I was going to share them here.

She's also been really good about putting up with me writing these blogs and frog comics every night...

Amphibian.com comic for 28 September 2015

Friday, September 25, 2015

Faux Bold is Better Than No Bold

Today I'm going to forego another in-depth discussion of a new ES6 language feature that recently became available in Node 4. Instead, I'd like to make a brief mention of what I learned this last week concerning "faux" font styles and PhantomJS.

First of all, what are faux font styles? As I recently learned, when you use a web font and not all the special styles are available (such as bold and italic), the browser will just alter the normal version of the font to create the faux styles. As a side note, I also learned that faux has only been used in English by itself to mean "fake" since the 1980's. I am older than this usage.

So when a font has its own bold and italic styles available, you should probably use them. Typically, this is accomplished by specifying multiple @font-face directives in your CSS. Each should define font-weight and font-style appropriately.

@font-face {
    font-family: 'Whatnot';
    src: url('/css/Whatnot-Regular.ttf');
    font-weight: normal;
    font-style: normal;
}

@font-face {
    font-family: 'Whatnot';
    src: url('/css/Whatnot-Bold.ttf');
    font-weight: bold;
    font-style: normal;
}

@font-face {
    font-family: 'Whatnot';
    src: url('/css/Whatnot-Italic.ttf');
    font-weight: normal;
    font-style: italic;
}

Like the above example, if you have multiple versions of the font you should use them. They'll probably look better than the faux versions made by the browser.

I use Sniglet as my standard font for the comics and it doesn't have an italic version. I have no choice but to settle for the faux version. It's not the end of the world, but I noticed a problem. When I made a comic that actually relied on bold italic text, the text was showing up as neither bold nor italic in the .png image generated by PhantomJS. Why?

After a bit of investigation, it would appear that PhantomJS can't make faux font styles out of SVG fonts. Any attempt to show bold or italic Sniglet was being ignored for as long as I've been making these comics. The solution? Switch to the True Type version of the font. It doesn't look that great when PhantomJS renders it but it's better than nothing.

Amphibian.com comic for 25 September 2015

Wednesday, September 23, 2015

Template Strings - New in Node 4

Today on Amphibian.com, the frogs try to get past ad blockers by interleaving the text of ads with the rest of the text on their website. But since their website is their comic about their website (see Monday's topic - meta), there are problems.

Similarly, when you want to put the values of variables or other expressions in your JavaScript strings you probably do something like this:

var str1 = "some static text and " + someVar + " and some more text";

JavaScript Strings, circa 1905
A cool new ES6 feature now available in Node 4 is the Template String, which can make the above code a little nicer.

Template Strings are a new way of creating strings with embedded expressions. These expressions can be simply variables, formulas, or function calls. To make a Template String, use the back-tick ` (the thing that shares the key with ~ on an American English keyboard) instead of the regular tick ' or double-quote ". Inside, put expressions inside curly braces { } prefixed with a dollar sign $.

Here's an example.

var frogType = "Science";
var numFlies = 42;

console.log("The " + frogType + " frog caught " + numFlies + " flies");
console.log(`The ${frogType} frog caught ${numFlies} flies`);

Both messages print out exactly the same, but the second one, using a Template String, is shorter and looks nicer. I think it helps keep your code cleaner.

Another feature of Template Strings is that they can include literal new-lines. Look at this:

var str1 = "this is string 1\n" +
           "with two lines";

var str2 = `this is string 1
with two lines`;

console.log(str1);
console.log(str2);

console.log(str1 === str2); // prints true

The str2 variable is created by simply starting a new line in the middle of the string instead of embedding the \n. Also note that the two strings are equal when compared, despite being created in different ways. Personally, I'm not sold on this particular attribute of Template Strings. I think putting literal new-lines in there hurts the readability of the code, but you might not have a problem with it. Just throwing it out there!

Obviously, using this technique to include variable values in strings is useful. But you can put more complex expressions inside the braces.

var a = 2;
var b = 4;
console.log(`the product is ${a * b}`);

The code above prints the product of a and b by performing the multiplication in the Template String. But please note that the expression is only evaluated once, when the string is created. The following code exemplifies that:

var c = 3;
var d = 7;
var str3 = `the sum is ${c + d}`;

console.log(str3); // the sum is 10

d = 14;

console.log(str3); // the sum is 10

Changing the value of d after str3 has been created does not change the value of str3. Be careful, however, because the process of creating a Template String can change the values of your variables - just like if you did things the old-fashioned way.

var e = 1;
console.log(`the variable e = ${e++}`);

console.log(e); // prints 2

In the above code, printing out the Template String changed the value of e. Maybe this is what you want...maybe it's not. Be mindful.

But wait! There's more!

Template Strings also support tagging, meaning that they can be passed to a function which can modify their output. This feature is a bit unusual.

To use tagging, simply define a string processor function which should expect to receive as arguments
  1. a string array containing the "normal" parts of the Template String
  2. zero or more additional arguments, each representing an expression value
The tagging function should return a string, which is probably going to be some version of the data passed to it, but doesn't have to be related at all! Here's an example.

var test1 = 33;
var test2 = 44;

function tag(strings) {

    // print the static parts, in order
    strings.forEach(function(s) {
        console.log(s);
    });

    // print the expression values, if any
    if (arguments.length > 1) {
        for (var i = 1; i < arguments.length; i++) {
            console.log(arguments[i]);
        }
    } else {
        console.log("no expressions!");
    }

    // this will be the tagged string value
    return "not the string you're looking for";

}

console.log(tag `Part 1 ${test1} part 2 ${test2}`);
console.log(tag `what? no expressions?`);

I've called my tagging function tag, but it can be anything you want. This first example just prints out the parts of the Template String so you can see how it works. It totally ignores the real contents of the Template String and returns nonsense. Those two calls to console.log both print the return value from tag. Probably not useful, but shows you what can be done. I honestly haven't thought of a legitimate use for tagging yet, but I might someday. Maybe you already know of one?

And there you have it. Template Strings, the good and the weird. I think the hardest part will be hitting that back-tick key. Not used to typing that one...

Amphibian.com comic for 23 September 2015

Monday, September 21, 2015

Symbols - New in Node 4

In continuing my discussions of new ES6 language features now available in Node 4, today I'm turning my attention to Symbols.

I'm not as sold on Symbols as I am on some of the other new features. What is a Symbol? A technical explanation is that Symbols are unique and immutable data types. Their purpose is to provide another way of making private properties on objects.

Ecmascript 6: The Future is Now!

Making Symbols is easy.

var sym1 = Symbol();
var sym2 = Symbol("whatnot");
var sym3 = Symbol("whatnot");

console.log(sym2 == sym3);  // false
console.log(sym2 === sym3); // false

The string parameter passed to Symbol() is optional and simply serves as a label. It doesn't mean anything to the Symbol itself. Making another Symbol with the same label doesn't mean the two Symbols are equal. Each Symbol created is unique.

So what does one do with these Symbols? I said that they're used for making private properties on objects, but how is that accomplished?

Let's start by defining the problem. When you have an object, JavaScript provides no protection of its properties. They can be redefined, or even removed! Consider this example.

var Frog = (function() {

    function Frog(type) {
        this.type = type;
    }

    Frog.prototype.getType = function() {
        return this.type;
    };

    return Frog;

}());

var f = new Frog("Science");
console.log(f.getType()); // prints Science

f.type = 27;
console.log(f.getType()); // prints 27

delete f.type;
console.log(f.getType()); // prints undefined

How can the frog type be made immutable outside of its own functions? Symbols are one possibility. Look at this code, slightly modified to use Symbols.

var Frog = (function() {

    var typeSymbol = Symbol("type");

    function Frog(type) {
        this[typeSymbol] = type;
    }

    Frog.prototype.getType = function() {
        return this[typeSymbol];
    };

    return Frog;

}());

var f = new Frog("CEO");
console.log(f.getType()); // prints CEO

console.log(f.type); // prints undefined

console.log(f["type"]); // prints undefined

var s = Symbol("type");
console.log(f[s]); // prints undefined

delete f.type;
console.log(f.getType()); // prints CEO

Instead of setting and accessing the frog type property internally using the dot notation (this.type), this code uses the bracket notation (this["type"]). BUT it uses the Symbol instead of the string "type" to make it inaccessible from outside. All attempts to read or delete the private type property will be unsuccessful. Even trying to do it with another Symbol fails, because Symbols made with the same label are not equivalent.

So that's Symbols. There are of course other ways to make fields private in JavaScript, such as using more closures or with Object.defineProperty. I haven't experienced any scenario where Symbols are really that much better than the previously available alternatives, but it's always nice to have more options.

I can't think of any way to tie this to the Amphibian.com comic for today, so here's the link to it without further comment.

Amphibian.com comic for 21 September 2015

Friday, September 18, 2015

Block Scoping - New in Node 4.0.0

Today wraps up "games week" on Amphibian.com. I had the frogs playing the lottery on Monday, Let's Make a Deal on Wednesday, and poker today. Since there's not much to discuss concerning poker being a game of skill or a game of chance, I'm back to discussing new JavaScript language features available in the recently released Node 4.0.0. (they've actually released 4.1.0 already but it's mostly just bug fixes).

So let's talk about Block Scoping!


This new ES6 feature gives you a new option for limiting the scope of declared variables to a block, statement, or expression. Just declare a variable with let instead of var and it won't be accessible to the entire function!

Here's an example that illustrates the point.

var x = 37;
if (x > 30) {
    let x = -1;
    let y = 900;
    console.log(x); // prints -1
    console.log(y); // prints 900
}
console.log(x); // prints 37
console.log(y); // prints undefined

if (x > 10) {
    var x = 5;
    var y = 777;
    console.log(x); // prints 5
    console.log(y); // prints 777
}
console.log(x); // prints 5
console.log(y); // prints 777

Inside the first if block, let x = -1 declares a block scoped variable x which is distinct from the global x variable declared on the first line. Changing it inside the block has no effect outside the block. By contrast, the second if block declares var x = 5, which isn't really much of a declaration at all. The x variable already in scope simply has its value reassigned. Once outside the block, it still has the value give it inside the block.

Also note the behavior of the y variable. Declared using let inside the first if block, it is undefined when used outside. But declaring it using var inside the second if block makes it global.

Declaring variables with let also works in for loops.

var i = 50;
for (let i = 0; i < 5; i++) {
    console.log(i); // prints 0 through 4
}
console.log(i); // prints 50

for (var j = 0; j < 5; j++) {
    console.log(j); // prints 0 through 4
}
console.log(j); // prints 5

The first loop, using let, prints the value of the variable i which is scoped to just the for loop. Outside of the loop, i still refers to the global variable. The second loop declares j with var and so j becomes available outside of the loop.

Making good use of let for variable declaration can make your code cleaner and lead to fewer bugs.

One final thing to note, however. While block scoping is available in Node 4.0.0+ it only works in strict mode. That means either launch node with the --use_strict flag or put
"use strict";
at the top of your source file. But you're probably using strict mode already, right?

Good. Now enjoy today's comic.

Amphibian.com comic for 18 September 2015

Wednesday, September 16, 2015

What Are the Odds?

I was going to return to discussions of new language features available in Node 4.0.0 today, but I feel like a discussion of today's comic is in order. Node's not going anywhere. I can talk about it on Friday.
Science! When you don't want a goat!

The Amphibian.com comic today is once again interactive as the story arc continues. Business Frog is trying to win money for the company instead of earning it. The lottery ticket plan from Monday failed, but with Science Frog's help maybe a television game show will work. Remember Let's Make a Deal? It spawned one of the most highly contested and poorly understood examples of the laws of probability...what is now known as the Monty Hall Problem.

The problem seems simple. The game show host, presumably Monty Hall, shows the contestant three doors. Behind one of the doors is the grand prize. Behind the other two are much less desirable prizes. In the classic description of the problem, the less desirable prizes are goats. I don't know why, but they are. Goats. Yes. After the contestant picks a door, Monty offers a deal. He'll give you whatever is behind one of the other two doors and the game ends. He opens one of the doors, revealing a goat. Do you want a goat? Probably not. You want the grand prize! So you continue. There are still two closed doors. Monty asks if you want to stick with your first choice door, or if you want to change your mind and pick the other closed door.

What should you do?

You should always change doors.

That's right. If you initially picked Door 1 and Monty opened Door 3, switch to Door 2. If you initially picked 3 and Monty showed you 2, switch to 1. And so on.

Your chances of winning the grand prize are greater when you switch doors. It seems counter-intuitive, but it is absolutely true.

Here's why. Assume that Monty knows what is behind each of the three doors. Initially, you have a 1 in 3 chance of picking the grand prize and a 2 in 3 chance of picking a goat. But after making your selection, Monty is going to open one of the other two doors. He's not going to open the door you selected, and he's certainly not going to open the one with the grand prize behind it! That means sticking with your original door still gives you a 1/3 chance, but the 2/3 chance of picking a goat is now a 2/3 chance of picking the grand prize since one of the two goats has been revealed and can no longer be selected!


It boggles the mind!

But to prove it, I put a working simulation of the game in the comic. In the third frame, help Business Frog win the money. Try it a bunch of times by refreshing the page and see for yourself - switching doors leads to wins more often than staying with your first choice.

In the end, though, I couldn't resist tossing in a more philosophical line about the nature of winning. How do you know if you're a winner? Business Frog always considers himself a winner. You should too.

Amphibian.com comic for 16 September 2015

Monday, September 14, 2015

Not a Chance

Luck has nothing to do with it.
Did you ever sit down to do something that you thought would be easy, only to give up in frustration many hours later? That's the story of today's Amphibian.com comic.

Well, maybe not the whole story. It started because I wanted to make a comic that included three things: scratch-off lottery tickets, a reference to The Lottery by Shirley Jackson, and a statement about the odds of winning the lottery.

One of my uncles gives a big stack of scratch-off lottery tickets to one lucky family member every year for Christmas. Everyone loves them for some reason. I've often wondered about the cost-to-wins ratio on those things, and how much time it would take to play a whole bunch of them. I thought I would make a comic where several of the frames were hidden beneath a silvery covering that could be "scratched" off with the mouse cursor on desktop browsers or your finger on mobile browsers.

The desktop, mouse-based interaction was fairly easy. There were just a few quirks that had to be addressed. Since the user would be holding down the mouse button and dragging a "coin" cursor all over the cell, there were the unfortunate side-effects of having the speech bubble text selected and the frog images getting drug around with that "ghost" effect.

To prevent text on a web page from being selected by the mouse cursor, there is some CSS that can be used. Here it is (with all the possible browser-specific versions):

.noselect {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

I simply applied this .noselect class to the text in the scratch-off frames. To prevent the image drag ghosting, the solution is to set a handler for the dragstart event on all the images which simply returns false. No drags allowed. I use jQuery in my comic to do these tasks, as is reflected by the following code snippets:

$('.myclass').addClass("noselect");
$('.myclass img').on("dragstart", function() { return false; });

With those two issues out of the way it worked great on the desktop. Oh, but those mobile browsers... I had thought that I could make the page perform pretty much the same way on mobile by using touch events in addition to mouse events. I was wrong. So very wrong.

On the desktop it works by detecting the mouseenter event. When the mouse cursor enters on the cover elements (a bunch of rounded divs), the element is removed if the mouse button is down. In a mobile browser, there is of course no mouse cursor so I attempted to use a touchmove event instead. If the user is touching the screen and moves over one of the cover elements, it should vanish. Except that doesn't work.

It turns out that the target of a touchmove event is always the same element - the one where the touch started. Not that helpful, but I thought I could deal with it. Instead of capturing a finger moving across the cover divs, I could track the page X/Y of the touches on the comic cell div and use the little-known document.elementFromPoint(x, y) function to figure out which cover elements to remove.

var elem = document.elementFromPoint(x - window.scrollX, y - window.scrollY);
$(elem).remove();

Well, that maybe sorta worked. To get the right element you have to adjust for the page scroll, but the performance was terrible on my phone. I could have probably worked on it some more, but it was time to cut my losses. I'd spent too much time on this problem already. I made a mobile-specific, not-quite-as-cool, auto-scratch-off effect and called it a day.

I hate it when this happens, but it's worse to not ship than to ship with a sub-optimal product. At least in my opinion. That's why there are comics 3 times per week, even if some are terrible.

Amphibian.com comic for 14 September 2015

Friday, September 11, 2015

Generator Functions - New in Node 4.0.0

On Wednesday I wrote about arrow functions, a more concise syntax for anonymous functions that is now available in Node 4.0.0. But the new Node has many more new features! Another of the most interesting and useful additions is generator functions.

Generator functions are special functions which can be exited and then re-entered while maintaining their context. That means their variable bindings are saved across entrances. Their name comes from the ability to use these functions to produce sequences of values, like an Iterator in Java.

Generator functions are declared with the special function* syntax, and contain in their bodies a yield statement. Calling a generator function does not execute the body, but instead returns an iterator object which can be used to invoke the body. The statements in the body will be executed until the yield is reached, at which point control returns to the caller.

Consider this example code, which uses a generator function to print out the first 20 numbers in the Fibonacci sequence.

function* fibonacci(){
    var a = 0;
    var b = 1;
    var c = 1;
    while(true) {
        yield c;
        c = a + b;
        a = b;
        b = c;
    }
}

var gen = fibonacci();

for (var i = 0; i < 20; i++) {
    console.log(gen.next().value);
}

It might not be the most efficient way to generate Fibonacci numbers, but it's a good illustration of a generator. When gen.next() is called for the first time, the fibonacci function body is executed up to the yield statement on line 6. All subsequent calls to gen.next() pick up at the next line (seven), which happens to be inside the while loop. After changing the values of the internal variables, we're back to the yield again. This sequence of steps repeats every time gen.next() is called.

As you may notice, calling .next() actually returns on object with a value property. The value property contains whatever was yielded.

Generator functions can come in handy, but since they are part of the ECMAScript 2015 standard, or ES6, they aren't universally available yet. They've just come to Node. Use in the browser is limited to the latest Chrome and Firefox, which means that you're probably going to want to limit yourself to the server-side if you intend to incorporate them in your code.

But as my frogs have learned, being on the cutting edge can be less dangerous than living in the past.

Amphibian.com comic for 11 September 2015

Wednesday, September 9, 2015

Arrow Functions - New in Node 4.0.0

New! Improved! Skipping Numbers!
In news much more important than whatever my frogs did today, Node 4.0.0 was just released. If you're confused by that version number, you're in good company. I thought we were just on version 0.12.7. Did 1.x.x through 3.x.x end up in the same place as Windows 9?

No, no. Node 4.0.0 represents the merge of the Node and Io.js baselines. Io.js split off Node back in December but the two projects have settled their differences and come back together. This means Node now has support for a bunch of new features from the JavaScript ECMA-262 specification, like promises and arrow functions.

I've talked about promises before, but arrow functions...those are interesting. They are basically an even shorter way of expressing anonymous functions.

Consider this example. Let's say you had an array of the first 10 prime numbers and you wanted to add them all up. In a prior version of Node, you could reduce the array by supplying a simple anonymous function as the argument to reduce.

var arr = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29];

var sum = arr.reduce(function(a, b) {
    return a + b;
});

Not bad. I'm sure we've all done simple anonymous functions like that before. But with an arrow function, the same process looks like this:

var arr = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29];

var sum = arr.reduce((a, b) => a + b);

A bit shorter, and it looks nicer as a single line. So what does that syntax really mean?

The arrow function notation basically says execute one or more statements on the right side of the arrow using one or more arguments from the left side of the arrow. If there is only one statement, the return is implicit (above, the statement a + b is equivalent to return a + b). The arrow, of course, is just an equals sign followed by a greater-than sign. It's really just a more concise way of expressing a function which you may find appealing in certain situations.

// multiple args, one statement
var f = (a, b, c) => c ? a + b : a * b;
f(3, 6, false); // equals 18
f(3, 6, true);  // equals 9

// one arg, multiple statements
var g = a => { var b = a * a; var c = a / 2; return b + c };
g(44); // equals 1958
g(22); // equals 495

Nice, huh? There's a lot more new with Node 4.0.0 as well, so you might want to check it out. I'll probably be migrating Amphibian.com to it within the next few weeks. I expect a painless transition, but we'll see. In the mean time, continue to enjoy the comics served up by a prior version of Node.

Amphibian.com comic for 9 September 2015

Monday, September 7, 2015

Code Now Displayed with Hack

I hope everyone's having a nice Labor Day and not working. I'm not, unless you count working on more frog comics.

I did, however, take a few minutes to update my Eclipse to use this awesome font. It's called Hack, and it's designed specifically for source code.

This is the Hack font. Note how l looks different than 1, and 0 looks different than O. I like it.

After remembering that Eclipse has waaaaaay more configuration items than reasonably fit on its chosen method of display and fumbling through them anyway to find where to change the font, I had the thought that I should update the way I display code on my blog here to use Hack as well.

The code snippets that show up on my blog are styled using SyntaxHighlighter by Alex Gorbatchev. I downloaded it years ago and set it up on my web server. I then edited my blog template code here on Blogger to load the scripts and stylesheets necessary to make it work. Here's what I added inside the HEAD tag near the top of my Blogger template's HTML (not a real IP address - if you do this, use the address of wherever you have the SyntaxHighlighter installation):

<link href='//cdn.jsdelivr.net/font-hack/2.010/css/hack.min.css' rel='stylesheet' type='text/css'/>
<script src='//1.2.3.4/syntaxhighlighter/scripts/shCore.js' type='text/javascript'/>
<script src='//1.2.3.4/syntaxhighlighter/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='//1.2.3.4/syntaxhighlighter/scripts/shBrushJava.js' type='text/javascript'/>
<script src='//1.2.3.4/syntaxhighlighter/scripts/shBrushXml.js' type='text/javascript'/>
<script src='//1.2.3.4/syntaxhighlighter/scripts/shBrushCss.js' type='text/javascript'/>
<script src='//1.2.3.4/syntaxhighlighter/scripts/shBrushBash.js' type='text/javascript'/>
<link href='//1.2.3.4/syntaxhighlighter/styles/shCoreEclipse.css' rel='stylesheet' type='text/css'/>
<script type='text/javascript'>SyntaxHighlighter.config.bloggerMode = true; SyntaxHighlighter.all();</script>

I am using a CDN for the Hack font itself, but my own server for SyntaxHighlighter. On my server, I just edited the CSS to prefer the Hack font first before "standard" monospace fonts. I also changed the font-size to 0.98em from 1em because I thought it was a bit large. I think it looks great now. Hopefully you agree, if you actually look at any of the code I post here.

When I post code, I use the <pre> method. I have to escape my HTML code with this method, but that's not usually a big deal. Take this snippet, for example:

<pre class="brush: js">
// I put JavaScript code here
console.log("log something");
while (froot) {
    console.log("loop")'
}
</pre>

It will look this this on the page:

// I put JavaScript code here
console.log("log something");
while (froot) {
    console.log("loop")'
}

Using SyntaxHighlighter to highlight the code used for syntax highlighting. So meta.

One thing I did notice about this font is that it is very similar to the default terminal font on my Red Hat Linux workstation. Maybe that's why I like it.

I hope you like today's comic as much.

Amphibian.com comic for 7 September 2015

Friday, September 4, 2015

Frog Soccer with Phaser - the Finishing Touches

I'm finally finishing up Frog Soccer, my 404 page game. There were a few outstanding bugs with it that I was able to fix this week (be sure to tell me if you find more!) and I also had to make the page a little nicer. I now include links to play it in full-screen mode as well as a link to the repository on GitHub.

There were two main issues.
WebGL fail! Ignore!
  1. If the web fonts could not be loaded, the game never started. It has come to my attention that some proxies (like the kind used in schools and businesses) prevent the web fonts from loading. Besides totally ruining the look of my comic, this actually causes the soccer game to fail since I wait on the active callback from the Typekit Web Font Loader before initializing the game. I fixed this by adding a callback for inactive, which is called when the fonts fail to load. Why the fonts fail to load is a problem for another day.
  2. If a frog stood in the corner of the field and blocked a ball toss-in twice in a row, the ball would end up in an endless toss-in loop. This was because a timer was being set to go off one second after the ball went out-of-bounds which assumed the ball had not re-entered play in between. If the ball toss-in bounced off a frog in less than a second, another toss cycle would begin which would be interrupted by the timer, which would move the ball back out-of-bounds and the cycle could continue without end. Crazy. I put a check in to see if the ball was already back in play before starting the toss. Maybe not the most eloquent solution but it works.
There was one additional minor issue. When I tried playing the game on my phone, a Samsung Galaxy S3, it always failed because of some WebGL problem. I believe this to happen in Phaser's startup process which checks to see if it should render with WebGL or Canvas. I changed the code to always use Canvas instead of auto-detecting and now it works...but I still sometimes see the error anyway. I'm going to chalk this one up to a device-specific annoyance and let it go for now. Could be something weird with Phaser's detection method too. I might look into it more if it's happening to other people as well.

var game = new Phaser.Game(width, height, Phaser.CANVAS, "gameArea", {
    preload: preload,
    create: create,
    update: update,
    render: render
});

One more thing - on the comic site, I changed the meta tag on the 404 page to set the page width to the width of the game's canvas. I don't usually set the width for responsive sites, but it made sense for this one page.

<meta name="viewport" content="width=800,user-scalable=1">

So what's next? I might tinker with this game from time to time, but I think I might start working on another one soon. This was my first experience using Phaser and I was very happy with it for the most part. I'm thinking of maybe making a (gasp!) Facebook game to integrate with Amphibian.com. Don't hate me. Look, here's today's comic...

Amphibian.com comic for 4 September 2015

Wednesday, September 2, 2015

Refactoring Express Router Middlewares

This past weekend I went back to an old comic to fix some bad code that it used. It had been bothering me for a long time. I knew it was not great when I made it, but since it was a bit of a rush-job (to capitalize on the sudden popularity of a dress color meme) I just lived with it. But no more! It had to be cleaned-up!

The problem with it was that the comic in question stored data about how people interacted with it, but never persisted that data to disk. Every time I re-started the comic application, the previous data was lost. No problem, I just put in a timer that wrote the data as a JSON string to disk every 30 minutes. When the application starts, it reads the file.

But when I was adding this stuff, it bothered me how all the code for the routes for this comic were scattered about in the main app.js file. They really should have been put in a separate file and configured as a router. Again, no problem. I moved the four routes into a separate router module and included it from app.js.

But then I noticed something else that bothered me. I had a bunch of router middlewares now that all used very repetitious blocks of code. Seemed like it was time to make more improvements.

The code originally looked like this.

//------------ set up routes for /data/*

app.use('/data', dataRoutes({
    express: express,
    auth: ensureAuthenticated,
    dataSource: cfact
}));

//------------ set up routes for /memeGen/*

app.use('/memeGen', memeRoutes({
    express: express,
    config: conf
}));

//------------ set up routes for /fb/*

app.use('/fb', fbRoutes({
    express: express,
    config: conf
}));

//------------ set up routes for /colors/*

app.use('/colors', colorRoutes({
    express: express
}));

//------------ set up routes for /images/*

app.use('/images', imgRoutes({
    express: express,
    auth: ensureAuthenticated,
    dataSource: cfact
}));

All the middlewares were passed a very similar object into their constructor, but it was not always identical. Some needed only a single item, some needed three. But they all overlapped. I decided to create the options object only once and pass it to all the middlewares. They could then use whatever they needed and ignore what they didn't. But instead of copying-and-pasting a block of code whenever I want to add another one, I created an array of their names and a function to set everything up. Now I have this:

var express = require('express');

var routers = ["data", "images", "memeGen", "colors", "fb"];

var app = express();

// ... other stuff ...

(function setupRouters() {

    var opts = {
            express: express,
            auth: ensureAuthenticated,
            dataSource: cfact,
            config: conf
    };

    routers.forEach(function(val) {

        try {
            console.log("loading router [" + val + "] ...");
            var r = require("./routers/" + val);
            app.use("/" + val, r(opts));
        } catch (e) {
            console.error("error loading router [" + val + "] - " + e);
        }

    });

})();

With the array of router names configured, I create and call a function which goes over that list and creates each router. It sets each one up with the path to match its name. It's now very easy for me to add new router middlewares.

I always enjoy a good refactoring. Much more than I enjoy taking a picture of myself (see today's comic).

Amphibian.com comic for 2 September 2015