Sunday, 15 May 2016

Chrome Extension: Facebook Filter

Update 17 June 2016: I've changed the focus of the extension to simply change the aspect of stories based on status, so that stories with content are highlighted over simple shares. I am currently working on another extension that is more adaptive, but it will be branded differently.

Update 27 May 2016: I've published the very early draft of the extension because it already does a cool thing: putting original content in the foreground and shrinking the reposts and photo uploads and feeling sharing and all that. You may find and install the extension here.

Have you ever wanted to decrease the spam in your Facebook page but couldn't do it in any way that would not make you miss important posts? I mean, even if you categorize all your contacts into good friends, close friends, relatives, acquaintances, then you unfollow the ones that really spam too much and you hide all posts that you don't like, you have no control over how Facebook decides to order what you see on the page. Worse than that, try to refresh repeatedly your Facebook page and see wildly oscillating results: posts appear, disappear, reorder themselves. It's a mess.

Well, true to this and my word I have started work on a Chrome extension to help me with this. My plan is pretty complicated, so before I publish the extension on the Chrome Webstore, like I did with my previous two efforts, I will publish this on GitHub while I am still working on it. So, depending on where I am, this might be alpha, beta or stable. At the moment of this writing - first commit - alpha is a pretty big word.

Here is the plan for the extension:
  1. Detect the user has opened the Facebook page
  2. Inject jQuery and extension code into the page
  3. Detect any post as it appears on the page
  4. Extract as many features as possible
  5. Allow the user to create categories for posts
  6. Allow the user to drag posts into categories or out of them
  7. Use AI to determine the category a post most likely belongs to
  8. Alternatively, let the user create their own filters, a la Outlook
  9. Show a list of categories (as tabs, perhaps) and hide all posts under the respective categories
This way, one might skip the annoying posts, based on personal preferences, while still enjoying the interesting ones. At the time of this writing, the first draft, the extension only works on https://www.facebook.com, not on any subpages, it extracts the type of the post and sets a CSS class on it. It also injects a CSS which makes posts get dimmer and smaller based on category. Mouse over to get the normal size and opacity.

How to make it work for you:
  1. In Chrome, go to Manage Extensions (chrome://extensions/)
  2. Click on the Developer Mode checkbox
  3. Click on the Load unpacked extension... button
  4. Select a folder where you have downloaded the source of this extension
  5. Open a new tab and load Facebook there
  6. You should see the posts getting smaller and dimmer based on category.
Change statusProcessor.css to select your own preferences (you may hide posts altogether or change the background color, etc).

As usual, please let me know what you think and contribute with code and ideas.

Friday, 13 May 2016

DNS Resolver - A Chrome extension to help you with malfunctioning DNS or IP blocking.

screenshot I've written another Chrome extension that I consider in beta, but so far it works. Really ugly makeshift code, but I am not gathering data about the way I will use it, then I am going to refactor it, just as I did with Bookmark Explorer. You may find the code at GitHub and the extension at the Chrome webstore.

This is how it works: Every time you access anything with the browser, the extension will remember the IPs for any given host. It will hold a list of the IPs, in reverse order (last one first), that you can just copy and paste into your hosts file. The hosts file is found in c:/Windows/System32/drivers/etc/hosts and on Linux in /etc/hosts. Once you add a line in the format "IP host" in it, the computer will resolve the host with the provided IP. Every time there is a problem with DNS resolution, the extension will add the latest known IP into the hosts text. Since the extension doesn't have access to your hard drive, you need to edit the file yourself. The icon of DNS resolver will show the number of hosts that it wants to resolve locally or nothing, if everything is OK.

The extension allows manual selection of an IP for a host and forced inclusion or exclusion from the list of IP/host lines. Data can be erased (all at once for now) as well. The extension does not communicate with the outside, but it does store a list of all domains you visit, so it is a slight privacy risk - although if someone has access to the local store of a browser extension, it's already too late. There is also the possibility of the extension to replace the host with IP directly in the browser requests, but this only works for the browser and fails in case the host name is important, as in the case of multiple servers using the same IP, so I don't recommend using it.

There are two scenarios for which this extension is very useful:
  • The DNS server fails for some reason or gives you a wrong IP
  • Someone removed the IP address from DNS servers or replaced it with one of their own, like in the case of governments censorship

I have some ideas for the future:
  • Sharing of working IP/host pairs - have to think of privacy before that, though
  • Installing a local DNS server that can communicate locally with the extension, so no more hosts editing - have to research and create one
  • Upvoting/Downvoting/flagging shared pairs - with all the horrible head-ache this comes with

As usual, let me know what you think here, or open issues on GitHub.

Seveneves, by Neal Stephenson

Book cover Neal Stephenson is known for writing speculative science fiction with focus on technological advancements and Seveneves is all about space. He thought about the idea in 2006, while he was an adviser with Blue Origin and he let the idea fester for years, while getting feedback from all kinds of people knowledgeable about and invested in space technology, like Planetary Resources, so at least the science is good. Personally, I believe that he gathered so much material that he just had to write the book, regardless if he had a story to tell or not. Never have I read a book that is so obviously written by an engineer, with long descriptions about how space stuff works and how a culture is like or how people solve problems. It's all about the how, never about the why or the who. As such, I consider it a failed book, because it could have been so much better as a well thought, well edited trilogy of books, with compelling characters, rather than a humongous enumeration of space technologies.

The story is split into three parts, mostly unconnected: the cataclysm that dooms Earth in two years and the solution found by the people of the planet, the cataclysm and what people do afterwards and the aftermath, 5000 years into the future.

What happens is that the Moon suddenly gets splintered apart by some unknown agent, possibly a miniature black hole, which just breaks it into seven pieces (it already starts with the number 7), that are destined to further break in collisions with each other and cause a catastrophic meteor bombardment of Earth, heating its atmosphere and boiling and smashing away all life. People decide to invest everything into expanding the International Space Station, having a few thousand people escape certain death by going into space. Everything is done very orderly and the book focuses exclusively at what people do to reach the stars, with today's technology. Nothing about what 7 billion people (see? I can use seven all over the place, too) feel or do when faced with certain doom. The book continues quickly over the inevitable deaths and accidents caused by rushing into something that is not really researched, proceeding towards a part of the story where almost everything just works, as by magic. The devastating problems that people would face in space are solved quickly by engineering solutions, ignoring the unsolvable ones.

So far the book does have a sort of a main character, a woman working with robots, sent to the ISS as part of a partnership with an asteroid mining company. Before we know enough about her, the story shifts into its second part, which splits attention between several important characters. At this point it is almost impossible to empathize with anyone, a problem compounded by using personalities "slightly towards the Asperger side of the spectrum", as the author points out several times.

To continue explaining the story is pointless and would spoil it, enough said that even as I am an engineer and always complaining that there is not enough science in science fiction, I got really bored with reading this book. Long long (mobile) pages of two of three paragraphs each, containing no dialog, explaining things that had nothing to do with the story, puny and underfed as it was. The only thing that made me react emotionally was the villain of the second part, who was written well enough to make me hate. To add insult to injury, after fighting through the 880 (normal) pages, the third part just abruptly ends, like he was just tired of writing, now that the tech was all explained away and there was some human story there.

Bottom line: As someone interested in the technology necessary to colonize the Solar System, this book should have been gold. Instead, I caught myself skimming over the long descriptions, just wanting the book to end. Too bad, since the subject could have easily been split into three or even several books, each with their own story to tell in a well structured fictional universe. Also, while the author swears he was "peer reviewed" on the concepts, he also admits making huge leaps of faith over what would work or not.

Wednesday, 11 May 2016

Unit testing Javascript: QUnit

QUnit logo I have started writing Chrome extensions, mainly to address issues that my browser is not solving, like opening dozens of tabs and lately DNS errors/blocking and ad blocking. My code writing process is chaotic at first, just writing stuff and changing it until things work, until I get to something I feel is stable. Then I feel the need to refactor the code, organizing and cleaning it and, why not, unit testing it. This opens the question on how to do that in Javascript and, even if I have known once, I needed to refresh my understanding with new work. Without further ado: QUnit, a Javascript testing framework. Not that all code here will be in ES5 or earlier, mainly because I have not studied ES6 and I want this to work with most Javascript.

QUnit


QUnit is something that has withstood the test of time. It was first launched in 2008, but even now it is easy to use with simple design and clear documentation. Don't worry, you can use it even without jQuery. In order to use it, create an HTML page that links to the Javascript and CSS files from QUnit, then create your own Javascript file containing the tests and add it to the page together with whatever you are testing.

Already this raises the issue of having Javascript code that can be safely embedded in a random web page, so consider how you may encapsulate the code. Other testing frameworks could run the code in a headless Javascript engine, so if you want to be as generic as possible, also remove all dependencies on an existing web page. The oldest and simplest way of doing this is to use the fact that an orphan function in Javascript has its own scope and always has this pointing to the global object - in case of a web page, this would be window. So instead of something like:
i=0;
while (i<+(document.getElementById('inpNumber').value)) {
i++;
// do something
}
do something like this:
(function() {

var global=this;

var i=0;
while (i<+(global.document.getElementById('inpNumber').value)) {
i++;
// do something
}

})();

It's a silly example, but it does several things:
  • It keeps variable i in the scope of the anonymous function, thus keeping it from interfering with other code on the page
  • It clearly defines a global object, which in case of a web page is window, but may be something else
  • It uses global to access any out of scope values

In this particular case, there is still a dependency on the default global object, but if instead one would pass the object somehow, it could be abstracted and the only change to the code would be the part where global is defined and acquired.

Let's start with QUnit. Here is a Hello World kind of thing:
QUnit.test("Hello World", function (assert) {
assert.equal(1+1, 2, "One plus one is two");
});
We put it in 'tests.js' and include it into a web page that looks like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Unit Tests</title>
<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-1.23.1.css">
</head>
<body>
<script src="https://code.jquery.com/qunit/qunit-1.23.1.js"></script>
<div id="qunit"></div>
<div id="qunit-fixture"></div>

<script src="tests.js"></script>
</body>
</html>

The result:


As you can see, we declare a test with the static QUnit.test function, which receives a name and a function as parameters. Within the function, the assert object will do everything we need, mainly checking to see if a result conforms to an expected value or a block throws an exception. I will not go through a detailed explanation on simple uses like that. If you are interested peruse the QUnit site for tutorials.

Modules


What I want to talk about are slightly more advanced scenarios. The first thing I want to address is the concept of modules. If we declare all the tests, regardless on how many scripts they are arranged in, the test page will just list them one after another, in a huge blob. In order to somehow separate them in regions, we need a module. Here is another example:
QUnit.module("Addition");
QUnit.test("One plus one", function (assert) {
assert.equal(1+1, 2, "One plus one is two");
});
QUnit.module("Multiplication");
QUnit.test("Two by two", function (assert) {
assert.equal(2*2, 4, "Two by two is four");
});
resulting in:


It may look the same, but a Module: dropdown appeared, allowing one to choose which module to test or visualize. The names of the tests also includes the module name. Unfortunately, the resulting HTML doesn't have containers for modules, something one can collapse or expand at will. That is too bad, but it can be easily fixed - this is not the scope of the post, though. A good strategy is just to put all related tests in the same Javascript file and use QUnit.module as the first line.

Asynchronicity


Another interesting issue is asynchronous testing. If we want to test functions that return asynchronously, like setTimeout or ajax calls or Promises, then we need to use assert.async. Here is an example:
QUnit.config.testTimeout = 1000;
QUnit.module("Asynchronous tests");
QUnit.test("Called after 100 milliseconds", function (assert) {
var a=assert.async();
setTimeout(function() {
assert.ok(true, "Assertion was called from setTimeout");
a();
});
},100);

First of all, we needed to declare that we expect a result asynchronously, therefore we call assert.async() and hold a reference to the result. The result is actually a function. After we make all the assertions on the result, we call that function in order to finish the test. I've added a line before the test, though, which sets the testTimeout configuration value. Without it, an async test that fails would freeze the test suite indefinitely. You can easily test this by setting testTimeout to less than the setTimeout duration.

Asynchronous tests raise several questions, though. The example above is all nice and easy, but what about cases when the test is more complex, with multiple asynchronous code blocks that follow each other, like a Promise chain? What if the assertions themselves need to be called asynchronously, like when checking for the outcome of a click handler? If you run jQuery(selector).click() an immediately following assertion would fail, since the click handler is executed in another context, for example. One can imagine code like this, but look how ugly it is:
QUnit.test("Called after 500 milliseconds", function (assert) {
var a = assert.async();
setTimeout(function () {
assert.ok(true, "First setTimeout");
setTimeout(function () {
assert.ok(true, "Second setTimeout");
setTimeout(function () {
assert.ok(true, "Third setTimeout");
setTimeout(function () {
assert.ok(true, "Fourth setTimeout");
a();
}, 100);
}, 100);
}, 100);
}, 100);
setTimeout(function () {
assert.notOk(true, "Test timed out");
}, 500)
});

In order to solve at least this arrow antipattern I've created a stringFunctions function that looks like this:
function stringFunctions() {
if (!arguments.length)
throw 'needs functions as parameters';
var f = function () {};
var args = arguments;
for (var i = args.length - 1; i >= 0; i--) {
(function () {
var x = i;
var func = args[x];
if (typeof(func) != 'function')
throw 'parameter ' + x + ' is not a function';
var prev = f;
f = function () {
setTimeout(function () {
func();
prev();
}, 100);
};
})();
};
f();
};
which makes the previous code look like this:
QUnit.test("Called after 500 milliseconds", function (assert) {
var a = assert.async();
stringFunctions(function () {
assert.ok(true, "First setTimeout");
}, function () {
assert.ok(true, "Second setTimeout");
}, function () {
assert.ok(true, "Third setTimeout");
}, function () {
assert.ok(true, "Fourth setTimeout");
}, a);
setTimeout(function () {
assert.notOk(true, "Test timed out");
}, 500)
});

Of course, this is a specific case, but at least in a very common scenario - the one when the results of event handlers are checked - stringFunctions with 1ms instead of 100ms is very useful. Click on a button, see if a checkbox is available, check the checkbox, see if the value in a span has changed, stuff like that.

Testing average jQuery web code


Another thing I want to address is how to test Javascript that is intended as a web page companion script, with jQuery manipulations of the DOM and event listeners and all that. Ideally, all this would be stored in some sort of object that is instantiated with parameters that specify the test context, the various mocks and so on and so on. Since it is not an ideal world, I want to show you a way to test a typical such script, one that executes a function at DOMReady and does everything in it. Here is an example:
$(function () {

$('#btnSomething').click(function () {
$('#divSomethingElse').empty();
});

});
The code assumes $ is jQuery, then it adds a handler to a button click to empty another item. Think on how this should be tested:
  1. Declare a QUnit test
  2. In it, execute the script
  3. Then make some assertions

I was a bit lazy and changed the scripts themselves to check if a testContext exists and use that one. Something like this:
(function ($) {

var global = this;
var jQueryContext = global.testContext && global.testContext.document ? global.testContext.document : global.document;
var chrome = global.testContext && global.testContext.chrome ? global.testContext.chrome : global.chrome;
// etc.

$(function () {

$('#btnSomething', jQueryContext).click(function () {
$('#divSomethingElse', jQueryContext).empty();
});

});

})(jQuery);
which has certain advantages. First, it makes you aware of all the uses of jQuery in the code, yet it doesn't force you to declare everything in an object and having to refactor everything. Funny how you need to refactor the code in order to write unit tests in order to be able to refactor the code. Automated testing gets like that. It also solves some problems with testing Javascript offline - directly from the file system, because all you need to do now is define the testContext then load the script by creating a tag in the testing page and setting the src attribute:
var script = document.createElement('script');
script.onload = function () {
// your assertions here
};
script.src = "http://whatever.com/the/script.js";
document.getElementsByTagName('head')[0].appendChild(script);
In this case, even if you are running the page from the filesystem, the script will be loaded and executed correctly. Another, more elegant solution would load the script as a string and execute it inside a closure where jQuery was replaced with something that uses a mock document by default. This means you don't have to change your code at all, but you need to be able to read the script as a text, which is impossible on the filesystem. Some really messy script tag creation would be needed
QUnit.test("jQuery script Tests", function (assert) {

var global = (function () {
return this;
})();

function setIsolatedJquery() {
global.originalJquery = jQuery.noConflict(true);
var tc = global.testContext.document;
global.jQuery = global.$ = function (selectorOrHtmlOrFunction, context) {
if (typeof(selectorOrHtmlOrFunction) == 'function')
return global.originalJquery.apply(this, arguments);
var newContext;
if (!context) {
newContext = tc; //if not specified, use the testContext
} else {
if (typeof(context) == 'string') {
newContext = global.originalJquery(context, tc); //if context is a selector, use it inside the testContext
} else {
newContext = context; // use the one provided
}
}
return global.originalJquery(selectorOrHtmlOrFunction, newContext)
}
};
function restoreJquery() {
global.jQuery = global.$ = global.originalJquery;
delete global.originalJquery;
}

var a = assert.async();

global.testContext = {
document : jQuery('<div><button id="btnSomething">Something</button><div id="divSomethingElse"><span>Content</span></div></div>')
};
setIsolatedJquery();

var script = document.createElement('script');
script.onload = function () {

assert.notEqual($('#divSomethingElse').children().length, 0, "SomethingElse has children");
$('#btnSomething').click();
setTimeout(function () {
assert.equal($('#divSomethingElse').children().length, 0, "clicking Something clears SomethingElse");
restoreJquery();
a();
}, 1);
};
script.src = "sample.js";
document.getElementsByTagName('head')[0].appendChild(script);

});

There you have it: an asynchronous test that replaces jQuery with something with an isolated context, loads a script dynamically, performs a click in the isolated context, checks the results. Notice the generic way in which to get the value of the global object in Javascript.

Bottom-Up or Top-Bottom approach


A last point I want to make is more theoretical. After some consultation with a colleague, I've finally cleared up some confusion I had about the direction of automated tests. You see, once you have the code - or even in TDD, I guess, you know what every small piece of code does and also the final requirements of the product. Where should you start in order to create automated tests?

One solution is to start from the bottom and check that your methods call everything they need to call in the mocked dependencies. If you method calls 'chrome.tabs.create' and you have mocked chrome, your tabs.create method should count how many times it is called and your assertion should check that the count is 1. It has the advantage of being straightforward, but also tests details that might be irrelevant. One might refactor the method to call some other API and then the test would fail, as it tested the actual implementation details, not a result. Of course, methods that return the same result for the same input values - sometimes called immutable - are perfect for this type of testing.

Another solution is to start from the requirements and test that the entire codebase does what it is supposed to do. This makes more sense, but the combination of possible test cases increases exponentially and it is difficult to spot where the problem lies if a test fails. This would be called acceptance testing.

Well, the answer is: both! It all depends on your budget, of course, as you need to take into consideration not only the writing of the tests, but their maintenance as well. Automated acceptance tests would not need to change a lot, only when requirements change, while unit tests would need to be changed whenever the implementation is altered or new code is added.

Conclusion


I am not an expert on unit testing, so what I have written here describes my own experiments. Please let me know if you have anything to add or to comment. My personal opinion on the matter is that testing provides a measure of confidence that minimizes the stress of introducing changes or refactoring code. It also forces people to think in terms of "how will I test this?" while writing code, which I think is great from the viewpoint of separation of concerns and code modularity. On the other hand it adds a relatively large resource drain, both in writing and (especially) in maintaining the tests. There is also a circular kind of issue where someone needs to test the tests. Psychologically, I also believe automated testing only works for certain people. Chaotic asses like myself like to experiment a lot, which makes testing a drag. I don't even know what I want to achieve and someone tries to push testing down my throat. Later on, though, tests would be welcome, if only my manager allows the time for it. So it is, as always, a matter of logistics.

More info about unit testing with QUnit on their page.

Saturday, 30 April 2016

What I've learned from four months on social media

Blogger pushing through Facebook and Twitter To be frank, I never intended this to last too much. I have been (and proudly, like a true hipster) avoiding creating a Facebook account and the Twitter one I only opened because I wanted to explore it as a machine to machine messaging system and never looked back after that idea bombed. So this year I went on Facebook and reactivated my interest in Twitter, now with a more social focus. The reason doesn't really matter, but I'll share it anyway: I had an asshole colleague that refused to talk to me on anything else other than Facebook Messenger. Now we barely talk to each other, anyway. So, what have I learned from this experience? Before I answer that question, I want to tell you about how I thought it would go when I went in.

What I thought going in


I have been keeping this blog since 2007, carefully sharing whatever I thought important, especially since I am a very forgetful person and I needed a place to store valuable tidbits of information. So when Facebook blew up I merely scoffed. Have other people use some sort of weird platform to share what they think; let them post cat videos and share whenever they go to the toilet: I am above this. I carefully study and solve the problem, read the book, research new stuff, link to everything in the information that I think relevant. I have my own template, I control the code on my blog, people can chat with me and others directly, comment on whatever I have done. I can also edit a post and update it with changes that I either learn as I evolve. My posts have permanent links that look like their title, suckers! I really don't need Facebook at all.

And Twitter. Phaw! 140 characters? What is this, SMSes online? If you really have something to say, say it in bulk. It's a completely useless platform. I might take a second look at it and use it as a chat system for the blog, at most (I actually did that for a while, a long time ago). I am not social, I am antisocial, suckers! I really don't need Twitter at all.

There you go. Superior as fuck, I entered the social media having a lot of smug preconceptions that I feel ashamed for. I apologize.

Facebook


So what did I learn from months on Facebook? Nothing. Hah! To be honest, I didn't disrespect Facebook that much to begin with. I had high hopes that once I connect with all my friends I would share of their interesting experiences and projects, we would communicate and collaborate better, we would organize more parties or gettogethers, meet up more frequently if we are in the same area. Be interesting, passionate; you know... social. Instead I got cute animal videos, big pointless images with texts plastered all over them - like this would give more gravitas to bland clichés, pictures of people on vacation or at parties - as if I care about their mugs more than the location, political opinion bile, sexist jokes, driving videos, random philosophical musings, and so on and so on. Oh, I learned a lot from Facebook, most of it being how many stupid and pointless things people do. Hell, I am probably friends with people I don't really know for a good reason, not just because I am an asshole who only thinks about himself!

Not everything is bad, clearly. The messenger is the only widespread method of online communication outside email. I know when people's birthdays are (and what day it is currently). People sometimes post their achievements, link to their blog posts, share some interesting information that they either stumbled upon on the Internet (most of the time) or thought about or did themselves, there are events that I learn about from other people going there, like concerts and software meetings and so on. Oh, and the Unfollow button is a gem, however cowardly it is! However, I am no longer "reading my Facebook", I am scrolling at warp speed. I've developed internal filters for spammy bullshit and most of the time, after going through three days worth of stuff, I have only five or six links that I opened for later, one of them being probably a music video on YouTube. It still takes a huge amount of time sifting through all the shit.

Twitter


What about Twitter? Huge fucking surprise there! Forced to distill the information they share, people on Twitter either share links to relevant content or small bits of their actual thoughts, real time, while they are thinking them. There is not a comfortable mechanism for long conversations, group conferences or complicated Like-like mechanism. You do have a button to like or retweet something, but it's more of a nod towards the author that what they shared is good, not some cog in an algorithm to tell someone what YOU need. More work stuff is being shared, books that have been read and enjoyed, real time reactions to TV or cinema shows, bits of relevant code, all kind of stuff. In fact, very few people that spam Facebook are even active on Twitter. Twitter is less about a person than about the moment; it's more Zen if you want to go that way. You are not friends with folks, you just appreciate what they share. It's less personal, yet more revealing, a side effect that I had not expected. And when you reply to a tweet, you are aware of how public it is and how disassociated from the post you reply to it is. There is no ego trip on posting the most sarcastic comment like on Facebook.

Not everything is rosy there, either. They have a similar Facebooky thing that shows the title and the image/video of a shared link so you can open them directly there. So if I want to emulate the same type of behaviour on Twitter, you can by endlessly posting links to stupid stuff and follow other people who do that. You can Follow whoever you want and that means that if you are exaggerating, you end up with a deluge of posts that you have no chance of getting out of. I still haven't gotten used to the hashtag thingie. I only follow people and I only use the default Twitter website, so I am not an "advanced user", but I can tell you that after three days worth of Twitter posts that I have missed, I open around 50 links that I intend to follow up on.

So?


Some of the mental filters developed apply to both situations. The same funny ha-ha video that spams the Facebook site can be ignored just as well on the Twitter page as well. Big font misspelled or untranslatable text smacked on top of a meaningless picture is ignored by tradition, since it looks like a big ad I already have a trained eye for from years of browsing the web before ad blockers were invented.

Some of the opinion pieces are really good and I wouldn't have had the opportunity to read them if all I was looking for was news sites and some RSS feed, yet because of the time it takes to find them, I get less time in which I can pay attention to them. I catch myself feeling annoyed with the length of a text or skipping paragraphs, even when I know that those paragraphs are well researched pieces of gold. I feel like I still need to train myself to focus on what is relevant, yet I am so fucking unwilling to let go of the things that are not.

With tweaking, both platforms may become useful. For example one can unfollow all his friends on Facebook, leaving only the messaging and the occasional event and birthday notification to go through. It's a bit radical, but you can do it. I haven't played with the "Hide post (show fewer posts like this)" functionality, it could be pretty cool if it works. Twitter doesn't have a good default filtering system, though, even if I get more useful information from it. That doesn't mean that specialized Twitter clients don't have all kinds of features I have not tried. There is also the software guy way: developing your own software to sift through the stuff. One idea I had, for example, was something that uses OCR to restore images and videos to text.

Bottom line: Facebook, in its raw form, it's almost useless to me. I remember some guy making fun of it and he was so right: "Facebook is not cool. Parents are on it!". You ask someone to connect with you, which is a two directional connection, even if they couldn't care less about you, then you need to make an effort to remove the stuff they just vomit online. The graphical features of the site make it susceptible to graphical spam - everything big and flashy and lacking substance. Twitter is less so and I have been surprised to see how much actual usable information is shared there. The unidirectional following system also leads to more complex data flow and structure, not just big blobs of similar people sharing base stuff that appeals to all.

But hey! "What about you, Siderite? What are you posting on Facebook and Twitter?" You'll just have to become friends and follow me to see, right? Nah, just kidding. My main content creation platform is still Blogger and I am using this system called If This Then That to share any new post on both social networks. Sometimes I read some news or I watch some video and I use the Facebook sharing buttons to express my appreciation for the content without actually writing anything about it and occasionally I retweet something that I find really spectacular on Twitter. Because of my feelings towards the two systems, even if I find an interesting link on Tweeter, I just like it then share it on Facebook if I don't feel it's really something. So, yeah, I am also spamming more on Facebook than on Twitter.

What else?


I haven't touched Google+, which I feel is a failed social platform and only collects various YouTube comments without accurately conveying my interests. I also haven't spoken about LinkedIn, which I think is a great networking platform, but I use it - as I believe it should be - exclusively for promoting my work and finding employment. I've used some strong language above, not because I am passionate about the subject but because I am not. I find it's appropriate though and won't apologize for it. I couldn't care less if people go or don't go on social networks and surely I am not an trendsetter so that Zuckerberg would worry. I only shared my own experience.

For the future I will probably continue to use both systems unless I finally implement one of the good ideas that would allow me to focus more on what matters, thus renouncing parts of my unhealthy habits. I am curious on how this will evolve in the near future and after I leave my current hiatus and go look for employment or start my own business.

Writing Tools - 50 Essential Strategies for Every Writer, by Roy Peter Clark

Book cover The focus of Writing Tools is more on the journalist than on the novel writer. Of course there is a lot of overlap, but some of the tools there may feel either not relevant or truly gold, since book writers would not write about them so easily.

Roy Peter Clark lists the 50 tools (55 if you have the revised edition) in four categories:
  • Nuts and Bolts - about the use of language: verbs, adverbs, phrase length, punctuation and so forth
  • Special Effects - various creative ideas that give inspiration and direction to writing
  • Blueprints - overall planning
  • Useful Habits - various solutions for common problems or for improvement
I will list the entire 50 entries at the end of the review.

What I liked about the book is that it is direct, to the point, listing the tools so that you can always pick up the book and refresh your memory on how to use them. Being so many, it is impossible to just skim through the book, unless you already know and employ most of the ideas there. I feel like I have to practice, practice, practice in order to absorb everything there is inside the material. It's not a huge thing, though, like something Kendall Haven might have written, but still it is packed with information.

I am unable to understand if the source material is still under copyright or maybe Clark made it available for free. The book is sold on Amazon, but you can also read it as PDF online or listen to it freely on iTunes.

Now, for a list of the tools, something that I have shamelessly stolen from another review, because I am lazy:
  • Part One: Nuts and Bolts
    • Begin sentences with subjects and verbs.
    • Order words for emphasis.
    • Activate your verbs.
    • Be passive-aggressive.
    • Watch those adverbs.
    • Take it easy on the -ings.
    • Fear not the long sentence.
    • Establish a pattern, then give it a twist.
    • Let punctuation control pace and space.
    • Cut big, then small.
  • Part Two: Special Effects
    • Prefer the simple over the technical.
    • Give key words their space.
    • Play with words, even in serious stories.
    • Get the name of the dog.
    • Pay attention to names.
    • Seek original images.
    • Riff on the creative language of others.
    • Set the pace with sentence length.
    • Vary the lengths of paragraphs.
    • Choose the number of elements with a purpose in mind.
    • Know when to back off and when to show off.
    • Climb up and down the ladder of abstraction.
    • Tune your voice.
  • Part Three: Blueprints
    • Work from a plan.
    • Learn the difference between reports and stories.
    • Use dialogue as a form of action.
    • Reveal traits of character.
    • Put odd and interesting things next to each other.
    • Foreshadow dramatic events and powerful conclusions.
    • To generate suspense, use internal cliffhangers.
    • Build your work around a key question.
    • Place gold coins along the path.
    • Repeat, repeat, and repeat.
    • Write from different cinematic angles.
    • Report and write for scenes.
    • Mix narrative modes.
    • In short works, don’t waste a syllable.
    • Prefer archetypes to stereotypes.
    • Write toward an ending.
  • Part Four: Useful Habits
    • Draft a mission statement for your work.
    • Turn procrastination into rehearsal.
    • Do your homework well in advance.
    • Read for both form and content.
    • Save string.
    • Break long projects into parts.
    • Take an interest in all crafts that support your work.
    • Recruit your own support group.
    • Limit self-criticism in early drafts.
    • Learn from your critics.
    • Own the tools of your craft.

Wednesday, 27 April 2016

Learning to program - again?

Corporate guy with other people on his shoulders... that's a dev, not a manager. I have been a professional in the IT business for a lot of years, less if you consider just software development, more if you count that my favorite activity since I was a kid was to mess with a computer or another. I think I know how to develop software, especially since I've kind of built my career on trying new places and new methods for doing that. And now people come to me and ask me: "Can I learn too? Can you teach me?". And the immediate answer is yes and no (heh! Learnt from the best politicians that line) Well, yes because I believe anyone who actually wants to learn can and no because I am a lousy teacher. But wait a minute... can't I become one?

You may think that it is easy to remember how it was when I was a code virgin, when I was writing Basic programs in a notebook in the hope that some day my father will buy me a computer, but it's not. My brain has picked up so many things that now they are applied automatically. I may not know what I know, but I know a lot and I am using it at all times. A few weeks ago I started thinking about these things and one of the first ideas that came to me was FizzBuzz! A program that allegedly people who can't program simple can't... err... program. Well, I thought, how would I write this best? How about worst? I even asked my wife and she gave me an idea that had never occurred to me, like not using the modulo function to determine divisibility.

And it dawned on me. To know if your code is good you need to know exactly what that code has to do. In other words, you can't program without having an idea on how to use or test it afterwards. You have to think about all the other people that would be stumbling unto your masterwork: other developers, for example, hired after you left the company, need to understand what they are looking at. You need to provide up to date and clear documentation to your users, as well. You need to handle all kinds of weird situations that your software might be subjected to. To sum it up: as a good developer you need to be a bit of all the people on the chain - users, testers, documenters, managers, marketers, colleagues - and to see the future as well. After all, you're an expert.

Of course, sketches like the one above are nothing but caricatures of people from the viewpoint of other people who don't understand them. After all, good managers need to be a little of everything as well. If you think about it, to be good at anything means you have to understand a little of everybody you work with and do your part well - exactly the opposite of specialization, the solution touted as solving every problem in the modern world. Anyway, enough philosophy. We were talking programming here.

What I mean to say is that for every bit of our craft, we developers are doing good things for other people. We code so that the computer does the job well, but we are telling it to do things that users need, we write concisely yet clear so that other developers can work from where we leave off, we write unit tests to make sure what we do is what we mean and ease the work of people who need to manually check that, we comment the code so that anyone can understand at a glance what a method does and maybe even automate the creation of documents explaining what the software does. And we draw lines in a form of a kitten so that marketers and managers sell the software - and we hate it, but we do it anyway.

So I ask, do we need to learn to write programs all over again? Because, to be frank, coders today write in TDD style because they think it's cutting edge, not that they are doing it for someone; they work in agile teams not because they know everybody will get a better understanding of what they are doing and prevent catastrophic crashes caused by lack of vision, but because they feel it takes managers off their backs and they can do their jobs; they don't write comments for the documentation team, but because they fear their small attention span might make them forget what the hell they were doing; they don't write several smaller methods instead of a large one because they believe in helping others read their code, but because some new gimmick tells them they have too much cyclomatic complexity. And so on and so on.

What if we would learn (and teach) that writing software is nothing but an abstraction layer thrown over helping all kinds of people in need and that even the least rockstar ninja superhero developer is still a hero if they do their job right? What if being a good cog in the machine is not such a bad thing?

While writing this I went all over the place, I know, and I didn't even touch what started me thinking about it: politics and laws. I was thinking that if we define the purpose of a law when we write it and package them together, anyone who can demonstrate that the effect is not the desired one can remove the law. How grand would that be? To know that something is applied upon you because no one could demonstrate that it is bad or wrong or ineffective.

We do that in software all the time, open software, for example, but also the internal processes in a programming shop designed to catch flaws early and to ensure people wrote things how they should have. Sometimes I feel so far removed from "the real world" because what I am doing seems to make more sense and in fact be more real than the crap I see all around me or on the media. What if we could apply this everywhere? Where people would take responsibility individually, not in social crowds? Where things would be working well not because a lot of people agree, but because no one can demonstrate they are working bad? What if the world is a big machine and we need to code for it?

Maybe learning to code is learning to live! Who wouldn't want to teach that?