How to grow in the craft of programming?

Of course there is not one correct answer to this question. In this post I will outline 7 steps I think you can take to grow as a programmer. For myself it should be a reference to stay on track. Maybe you find it useful as well. If you have additional tactics please share them.

"We will encourage you to develop the three great virtues of a programmer: laziness, impatience, and hubris." -- LarryWallProgrammingPerl

How to grow as a programmer?

Read / write

1. You learn programming by practice, a lot of practice. Write a lot of code, best way to actually do this is to start work (and hobby) projects, look around at problems you can solve. If you cannot find interesting problems, try to automate silly or actual useful common tasks you or your team mates have to do on a regular basis. Another way is to contribute to open source.

2. Read other people's code, both bad and extraordinary code. It definitely takes some discipline to go through code that does not make sense at first sight. Look up keywords and functions you don't understand, run it if possible, take it to pieces. What is good practice, what would you do differently and why? What creative solutions did the programmer apply?

3. Develop a non-stop learning attitude, read at least 2 programming books a month, both on concepts / from the pros (code complete, clean code, making software, coders at work) as well as the programming tutorials (I personally like the O'Reilly books), it is important to NOT get into a comfort zone: PHP and Perl enough? No, learn Python and/or a compiled language. Only know Java? Check out Ruby. Done a lot of OO (object oriented)? Look into FP (functional programming).

 

Get into the field

4. Hang out/ work with programmers that are better than you: it might feel awkward, but this way you will step on the accelerator of your learning process. I think most good software developers are willing to help you if you show genuine interest, passion and a proactive attitude. In practice this means, when you don't understand something they do, go learn it and come back for more. Experienced people will like this, they probably recognize themselves when they started. Keep in mind that they were not born with the skills eiher, they learned it at some point as well.

Skills / practices

5. Become a good problem solver - this is usually what programming is all about, writing the code (syntax) is one thing, but at its core you need to understand how to effictively / creatively solve a problem. Usually this also requires being an allrounder: understand the software stack, understand some Networking and OS as well, learn to ask the right questions.

6. Not only code to code: what is a client/user need, is the program easy to use for his/her skill level? Software development practices and processes, deployment to a server, get out of the coder's cave and try to understand the bigger picture. An interesting article from Coding Horror: How To Become a Better Programmer by Not Programming. On another note: learn TDD (test drive development), learn to write code for humans (the next coder that gets to see your code), learn to write clean code. This is not a binary thing ("not done, now done"), you gradually develop these skills with experience I think.

7. Develop your toolkit. Save time and brain cycles, prevent headaches! So use version control software (I use Git), use a fast and powerful text editor (I am getting better with Vim). Automate repetitive / easy tasks to focus on the real learning challenges (e.g. shell aliases, automate ssh login, learn more Vim keystrokes, all shave off seconds, but over time it adds up!). There probably is a lot you could add or discuss here, but it boils down to becoming more efficient by using existing and/or creating new tools.

 

And you?

I assume most readers of this blog have a programmer, web developer or alike background. What techniques do you use to become better in your field?

Facebook API: how to detect canvas and a page tab's Facebook page

Facebook Apps can live inside or outside Facebook. Inside Facebook they can live in the Canvas or in a Page Tab. It is important to be able to detect these modes to provide a customized experience. Although the documentation is pretty clear, I feel it is useful to make some notes here how this works.

featured image

According to the Canvas documentation "whenever your application is loaded within a Canvas page, Facebook will make an HTTP POST to your Canvas URL. This request will include a POST variable called signed_request.". For Page Tabs this works similarly: "When a user selects your Page Tab, you will receive the signed_request parameter with one additional parameter, page. This parameter contains a JSON object with an id (the page id of the current page) ..."

It is the signed_request parameter I will focus on in this post. I will show you how to get the necessary information out of it and show examples how to use it to determine the flow of your app.

Why is this useful?

In this post I will give you two examples how this can be useful:

  • 1. get rid of the vertical scrollbar in ONLY the Canvas version of My Reading List
  • 2. identify within a page tab application what Facebook page id it runs in to deliver specific content based on that page id.

How to parse the signed request?

You can do it manually with this PHP code example or use Facebook's PHP SDK. Facebook requires your app's Secret to ensure the request was sent by Facebook and not by a third party. The response will yield a JSON object, something like:

In the canvas:

signed request response inside the canvas

And in a page tab:

signed request response inside a page tab

Practical examples:

1. My Reading List

For My Reading List (and any app for that matter) I typically want to get rid of the vertical scroll bar in the canvas. One way to do this is with Facebook's Javascript SDK's method: FB.Canvas.setAutoGrow() (another method is FB.Canvas.setSize). Additionally you set the CSS property "overflow" to "hidden" on the body tag.

However doing this makes the "standalone" (outside Facebook) non-scrollable which presents a problem.

So a solution is to ask the App if it is in the Canvas, example in PHP:

<?php
if (canvasMode($fb_secret)) {
  echo "<body style='overflow:hidden;'>";
} else {
  echo "<body>";
}
..
..
function canvasMode($secret){
  $canvas = false; 

  if( isset($_REQUEST['signed_request']) ) {
    $data = parse_signed_request($_REQUEST["signed_request"], $secret);
    if( $data ) {
      $canvas = true; 
    } 
  } 

  return $canvas;
}
?>

... and the result is I have the best of both worlds:

1. inside the Facebook Canvas: no scrollbar

inside Facebook = no scrollbar

2. outside of Facebook, overflow is not set to "hidden" on the body, hence the content is scrollable (default html rendering):

outside Facebook = scrollbar

2. Dynamic content in page tabs

Page tabs is a cool feature I recently learned about. It allows you to attach a Facebook app to a Facebook Page. Facebook makes this really easy as you can read here.

Again, you can leverage the signed request response to tell your app on which Facebook page it is running. This way you can load different content on different pages that have the Page Tab app installed.

To illustrate this, we can use the same code as above, however we are looking for the page id bit in the JSON object:

<?php
..
$signed_request = parse_signed_request($_REQUEST['signed_request'], $secret);
$pageId = $signed_request['page']['id'];
..
?>

Now you can match this page id against for example a database which holds different content for every Facebook page (id).

Conclusion

Standalone (outside Facebook) apps, Canvas and Page Tab apps are different in nature so it is important to identify when you are operating in one or the other.

The Facebook SDK or the raw code example Facebook provided, suit this purpose quite well. Once you parse the signed request you can influence the way the App works in every instance (environment).

If you have interesting use cases, other than the two examples shown in this post, feel free to share them in the comments.

New release of Sharemovies - overview of new design and features

The anticipated new release of Sharemovies is up. It provides an easier way to browse movies and provides a lot more info. I redesigned it from the ground up, keeping the most valuable elements of the initial version. In this post an overview of the new design and features.

V1

I started Sharemovies back in 2010. Since then I did some tweaking and the site looked like this:
initial release
initial release

V2

The new version is taking a whole new approach. I started using themoviedb API v3. It is a rich API with reasonable request limits. You should still use caching though.

The new release consists of 4 parts: the homepage, movie pages, person (cast / crew member) pages, and user pages.

Homepage

The homepage shows the upcoming, top-rated and "now in theatres" movies. This data gets refreshed every 24 hours.

the new homepage

Seach is important

featured image

Central in the fixed positioned header is the search box, it uses autocomplete to provide a rich search result including trailers ( I did this with v2 of themoviedb API some time ago ). I think it is one of the most important / most useful things of the site: movie info can be found quickly and easily! Before clicking on the result ( = going to the movie page), you can watch the trailer to decide if you want to know more about that movie. Appending a year makes the search more accurate and it understands other languages (at least in the cases I tried: "Caza al terrorista" gives me "The Assignment" and "Ciudade de Deus" gives me "City of God").

Autocomplete in action

sm_autocomplete.png

With trailer when hovering over the dedicated area:

sm_autocomplete_trailer.png

Movie page

When selecting the search result or clicking on a poster anywhere on the site, you are taken to the movie page:

moviepage logged out view

When you log in with Facebook you can comment, like and add the movie to your watchlist and/or favorites.

moviepage when logged in

The "Share" button is linked to addthis which surprisingly lets you use a customizable button. This way the page can be shared to most social networks.

addthis button

Below the big version of the movie poster are links to Amazon, Netflix, IMDb and TMDb

infolinks to other services

Trailers and similar movies

One of the things I really liked in v1 were the Youtube trailers in boxy overlay - this had to stay the same.

When you click on the red play button alongside the movie title, an overlay is shown with the trailer. Warning: browsing movies and watching trailers this way can be pretty addictive ;)

view youtube trailer on moviepage

You can also search for similar movies by clicking "You might also like ..." under the Plot summary.

sm_similar_movies.png

Actors

When you click the actor photos or the crew names you are taken to a page dedicated to that person. There you will see his/her details and movies. There is a filter box at the top that lets you easily find a particular movie.

actor page

Last but not least: user profiles

When you login with Facebook you can start adding movies to your Watchlist and Favorites (see the blue buttons at the top of each movie page). When adding or deleting movies from your list the button text and icon change on the fly (Javascript).

When you get more movies on your profile page ( the profile URL is http://sharemovi.es/user/facebookUserId , see mine here), you can filter the results by string (like we saw with the person pages), by genre or by "month added". Again, some Javascript (jQuery) makes the user experience a lot better: things can be found quickly and it is visually more attractive. Clicking on the "Favorites" and "Watchlist" links at the top, scrolls you down to the particular list.

user profile page

Best thing to get familiar is to open my profile and click around, then login with Facebook and start building your own movie profile by adding movies when browsing movie pages ...

Search and scroll

filtering items
scroll to a list

Filter on genre

show all crime movies
show all comedies

From here ...

Enjoy this app, and share the word. I think it is useful for the movie fans out there. I'm open for any issues or feedback ...

As far as I tried it worked reasonably well on an ipad. I'd like to build an iphone app later this year ...

Best practices of software development – II) Good Coding Methodologies

This is part II of the Best practices of Software Development series. If you want to know how to write quality code to become a better developer read on ... Today: Good Coding Methodologies.

Planning

Good Coding Methodologies

This post will talk about writing better code, common issues with program structures and how to improve them, building good methods and a short note on exceptions.

Writing better code

featured image

One of the most important criteria is human-readable code. Code should be self documenting. Don't rely on comments, use coding standards instead. It makes the code more concise and predictable and thus easier to test, debug and modify. The required code-indenting is one of the reasons I like Python for example.

Control structures should be wrapped in blocks even if not strictly required. I also try to make a habit of keeping lines under 70 or 80 characters wide. Whether you use camelCase or underscore-based style for your variables, use a consistent scheme and stick to it. .

Comments are better than external documentation because they stick with the code (modification). However don't overuse them: don't repeat the code, don't provide unnecessary explanations, watch out for code changes (forgetting to edit the comments as well!). Good comments summarize the code, describe its intent and provide info that the code cannot express.

Structure of programs

Examples of common issues:

  • Improper use of pointers (wild or dangling pointers).
  • The use of global variables making the program harder to maintain.
  • Using literals instead of constants (e.g. 86400 instead of SECONDS_IN_DAY).
  • Confusing comparison "==" with assignment "=" operators.
  • Wrong use of loop initial and end-condition values.
  • Short-circuit operators ("&&" and "||") - understanding that they might not execute in some circumstances.
  • Comparing objects ("equals" and not "==").
  • Fall-through: forget to "break" each "case" in a switch statement.
  • Lack or improper use of error handling (see further down).

Expressions

To generally improve your writing of proper expressions you should use parentheses in complex expressions. It is clearer to express Boolean expressions positively unless the outcome is likely to be negative - so use: "if(bookInStore)" instead of "if(!bookInStore)". Also avoid "(a>b) == TRUE", just say "(a>b)". You should work with TRUE and FALSE booleans instead of 1 and 0, if your language does not support them you can define them as constants.

Sequence

It is important to sequence code properly so that dependencies are visible reading the method names. This implies that one method executes only one task (more on Methods further down).

Variables and types

The advantage of strong typing is that a variable can hold only one type of value. This encourages input validation and errors that are detected early on at compilation time. You should limit the lifetime of a variable, so declare it as close as where you are going to use it. Named constants and enumerations make code more readable and thus maintainable.

Structured flow-control

As mentioned: use the most likely outcome in the if statement (not in the "else"). Enforce blocks for better readability. Other best practices for loops: separate loop control code from loop work code, keep nesting down to two or three levels at most, be careful (document) break and continue statements.

Methods (functions)

Building good methods

The purpose of a method should be clear from its name. I stress it again: one method equals one task. This alone makes code much more readable and reliable. It makes bugs easier to solve or prevents some of them at all. It also favors code re-use.

Variables should be localized to the method to prevent unexpected modifications from outside the method. In OOP you'd hide the data used by a method within a object only making it accessible through the object's public interfaces.

Bottom line is to think well what the goal of the method is, what should it accomplish? Then write it.

Handling arguments and return values

A method should not have more than 7 or 8 parameters. Optional arguments should be avoided because they lure you in 1 method > 1 task (use other methods to handle them). Distinguishing between input/working/output variables (an example: input (passed to the method) = grossSalary; working = incomeTax ; output = netSalary (to be calculated and returned) ). This prevents the wrong variables to be modified with undesired results.

It is important to validate arguments, otherwise bad data will creep in leading to failures further into the program (which are harder to debug). Return empty arrays rather than null values.

Exceptions

Unexpected events / errors should be handled by exceptions. If not, the user is presented with errors that usually don't make any sense. So make sure that the catch/except block actually handles the event. Depending the problem you'd control what happens as a result, for example: disable a module, only show a message, show debug info under the hood, etc. etc. See Wikipedia for more info.

Inspiring read: Hackers & Painters: Big Ideas from the Computer Age

This is a guest post from M. Schilling. He shares with us his views on the inspiring book Hackers & Painters: Big Ideas from the Computer Age. What can we get out of this book, how to become a better programmer and some other goodies ...

Hackers & Painters

I have just finished reading Hackers & Painters - Big Ideas from the Computer Age by Paul Graham. This book consists of an interesting collection of essays that are all independent of one another.

In 15 essays Graham covers a wide range of topics centered on computers. The first half of the book is much about social theory and politics, while the latter focusses more on computer science in general.

If you are a programmer (or hacker, as how Graham likes to call it) yourself, you will find a lot of moments of recognition (e.g. "Yep!", or "So that's why.."). That's one of the things I like about the book, and it makes reading it easy.

How to benefit from this book?

As a programmer, this book will bring you a lot of good thoughts and insights. Some of the ideas might not be totally new to you, but Graham writes it is such a way that you will find it interesting and it will make you think about everything a lot more (which is, by definition, not always desirable ;-)). Simply put: this book will affect the way how you look at your daily programming tasks and projects.

How to become a better programmer?

You will not find direct answers in this book. However, if you read very carefully you will find out that the answer is there. Andy Hertzfeld is quoted on the back cover of the book, saying "He may even make you want to start programming in Lisp" and that's probably one of the things you'll have to do. I believe that, on your way to become the best programmer, you have to know about different programming languages and dare to admit that some languages are more powerful than others.

Don't get stuck in your own comfort zone keep saying that your programming language is the best, but keep your mind open for new suggestions.

Why not try a couple of (totally) different programming languages for a few weeks and make them do the same job. When you're done, try to classify the high level languages for yourself, from less

powerful to more powerful. It's the process of doing so, that will help you on the long term to become a better programmer.

Conclusion and what's next

If you're interested in the field of computer science, or even if you're just curious about the topic "why are nerds unpopular on high school", I can recommend you to read Hackers & Painters.

A video resource I can recommend is the TV mini-series: Nerds 2.0.1: A Brief History of the Internet. Enjoy this series, and try to find out yourself, how it relates to the chapters in this book (e.g. "Good Bad Attitude", "How to Make Wealth")

You can find more info on the author's page on the book at paulgraham.com.



M.Schilling is software developer and database designer. You can follow him at Twitter or contact him via Linkedin.


Simple bash script to clone remote git repositories

From time to time I install a Linux variant on one of my boxes and start fresh, good performance, lean install. I use git for all my projects now so I am building up repositories on remote hosts fast. Wouldn't it be nice to be able to clone them all to the newly installed host? Quite useful for quick migrations, so I wrote a quick bash script that achieves this ...

Assumptions

import all remote repos

  • 1. You have a REMOTE host that holds all repositories in a central place, ~/repositories in this example.
  • 2. I use Git as version control software (I didn't look further yet as it is amazing software!).
  • 3. You can ssh to the remote host. You can set up a key based login in 3 simple steps (on local host: ssh-keygen && ssh-copy-id -i ~/.ssh/id_rsa.pub your-remote-host).
  • 4. You remote repositories are "bare", see how to push code to a remote web server with Git as a reference. I use this technique for each new coding project now, it is highly efficient.
  • 5. My naming convention for remote repositories is project_name.git, located at ~/repositories/project_name.git.
  • 6. I have a CODE directory in my home directory ($HOME) on my LOCAL host. You should change lines 5-9 of the script below with your own settings ...
  • 7. You might want to refine the script if you are going to use it in a more professional (enterprise) environment. For me it fits the purpose for now though.

Code (also available here)

#!/bin/bash
# import multiple remote git repositories to local CODE dir

# settings / change this to your config
remoteHost=example.com
remoteUser=username
remoteDir="~/repositories/"
remoteRepos=$(ssh -l $remoteUser $remoteHost "ls $remoteDir")
localCodeDir="${HOME}/CODE/"

# if no output from the remote ssh cmd, bail out
if [ -z "$remoteRepos" ]; then
    echo "No results from remote repo listing (via SSH)"
    exit
fi

# for each repo found remotely, check if it exists locally
# assumption: name repo = repo.git, to be saved to repo (w/o .git)
# if dir exists, skip, if not, clone the remote git repo into it
for gitRepo in $remoteRepos
do
  localRepoDir=$(echo ${localCodeDir}${gitRepo}|cut -d'.' -f1)
  if [ -d $localRepoDir ]; then 	
		echo -e "Directory $localRepoDir already exits, skipping ...\n"
	else
		cloneCmd="git clone ssh://$remoteUser@$remoteHost/$remoteDir"
		cloneCmd=$cloneCmd"$gitRepo $localRepoDir"
		
		cloneCmdRun=$($cloneCmd 2>&1)

		echo -e "Running: \n$ $cloneCmd"
		echo -e "${cloneCmdRun}\n\n"
	fi
done

Explanation what some concepts mean ...

  • ssh -l user host "remote command" => allows you to run remote commands from your local machine, quite nice for automating tasks over the network.
  • remoteRepos=$(.. command ..) => $() executes the command and returns the output to a new variable called remoteRepos (remoteRepos for assigning values, $remoteRepos to access them).
  • -z "$remoteRepos" => checks for an empty string.
  • cut -d'.' -f1 => takes the .git off (-d'.' = set delimiter to dot (.) , -f1 = field #1).
  • echo -e => the -e flag allows "echo" to handle the new line character (\n).
  • cloneCmd=$cloneCmd"..string.." => concatenation technique to keep lines shorter (I ideally strive to not put more than 80 chars per line).
  • 2>&1 at the end of an Unix command sends the stderr output to stdout, basically I want to send all info to the same output stream. In bigger scripts I usually send it to a stderr directory with "2>stderr/file_unix_timestamp.err" (I got this tip from a more senior programmer; it has saved me time because I get crucial data for debugging!).

Example running this from cli

$ git_clone_all.sh 
Directory /home/bob/CODE/bamboo already exits, skipping ...

Directory /home/bob/CODE/codesnippets already exits, skipping ...

Directory /home/bob/CODE/myreadinglist already exits, skipping ...

Running: 
$ git clone ssh://[email protected]/~/repositories/myreadinglist_v2.git /home/bob/CODE/myreadinglist_v2
Cloning into '/home/bob/CODE/myreadinglist_v2'...


Running: 
$ git clone ssh://[email protected]/~/repositories/portfolio.git /home/bob/CODE/portfolio
Cloning into '/home/bob/CODE/portfolio'...


Running: 
$ git clone ssh://[email protected]/~/repositories/stock.git /home/bob/CODE/stock
Cloning into '/home/bob/CODE/stock'...


Directory /home/bob/CODE/tweetdigest already exits, skipping ...

Nice Wordpress plugin for your blog archive: Grid Archives

I tweaked my Bamboo theme to be fresh, professional and above all cleaner. If not on a mobile or RSS, you are probably looking at the results. I also needed to clean up the Archive page. I found a nice plugin: Grid Archives...

Last year I showed some cool wordpress plugins, but most of them I dropped or replaced by better ones (some were just downright ugly / cluttered). One of the plugins that remained was Snazzy Archives. This is not a bad plugin, especially the images showing up is neat. The annoying thing however was that after each update it seemed to overwrite user-written CSS. The other thing I don't like is the variable height of each post, it doesn't seem very structured. Time for a grid.

Why does this seem to be a good plugin?

featured image

  • There is a classic (HTML) and a compact (JS) option. Good distinction.
  • It has nice animated Javascript effects, play with it here.
  • There is a lot of customization possible. I was mainly interested to change the CSS to make it fit my theme design (which worked out pretty well, see below), and for it to stay across updates! In the admin panel it states: "... You can also copy all the Grid Archives default css from "Plugin Editor" here and make any modifications you like, these modifications won't be lost when you update the plugin.".
  • The ability to load Grid Archives resources only in specific pages. Another advantage ... the main concern about enabling Wordpress plugins is increasing page size and requests, more functionality for less performance.

Example customized CSS

The default theme was not that appealing to me:

default theme

Copying and editing the Grid Archives default CSS - result:

styled

Overwritten CSS is here. I think this demonstrates that this plugin is worth a try!

Best practices of software development - I) Programming Techniques

The coming weeks I will have 3 articles for you about best practices of software development. Following these methods could lead to more efficient development and better quality code. In this post: Programming Techniques and Strategies.

Purpose and planning

featured image

The purpose of this series is to have some understanding of how to write quality code to become a better developer. It should be a theoretical reference to go back to from time to time. It should complement the practical day-to-day learning.

Potentially I will follow up with a 4th article about Objected-oriented Coding, whenever I have some more experience with it.

Programming Techniques and Strategies

50% to 75% of development time goes into testing and validation of code. Why? Software development is a complicated process. In this posts some techniques to handle this.

Complexity

4 things that define uncontrolled complexity and should be limited:

  • Coupling: the more dependencies of subsystems the more complex the system overall and the easier bugs get introduced;
  • Control flows; the number of independent paths (see also Cyclomatic complexity);
  • Complexity of data structures;
  • The overall size of the program.

To avoid or reduce complexity a developer can:

  • Partition: break the program up in smaller units or classes;
  • Add hierarchy to your programs. A good example is the OSI model: similar communication functions are grouped into logical layers. In programs, units are black boxes and are self contained. This way they are easier to test. Use local (not global) variables. Build in privacy: data should be local to each blackbox element (method or function);
  • Limit functionality at the start. Adding functionality scales up complexity in a non-linear fashion;
  • Use an iterative development process: have early and frequent feedback loops. See further down ...

Elegant software

Good software ought to be non verbose and elegant. The most efficient piece of software for a particular purpose uses the least amount of code and the smallest number of abstracted entities.

Human factor

The human factor is important. Pair programming can reduce the amount of bugs introduced into the system. Same with peer reviews and collective code ownership (if communicated well and version controlled).

Software quality

Good software can be measured by the following key metrics:

  • External factors: availability, efficiency, flexibility, integrity/ security, interoperability, reliability and usability.
  • Internal factors: maintainability (average time to correct faults), reusability (well documented, platform independent, modular), readability, portability, testability.

Defensive programming

The best prevention measure is to write robust code that anticipates problems, validates data inputs and terminates gracefully providing debug info to de developer.

To be defensive a developer should use:

  • Assertions: test for errors that should never occur;
  • Input validations: test ALL data inputs (whether it comes from a database, users, or from methods);
  • Error handling: these errors are expected but it depends the application how to handle them (a cash withdrawal machine should handle errors differently than a word processing program);
  • Error containment: shut down parts of the program to prevent damage to other parts.

Software development methodologies:

There are different types of development styles:

  • The Waterfall model is a sequential design process with its roots in the manufacturing industry. Progress flows from the top to the bottom. Requirements, design, implementation, verification and maintenance, each stage is completed before moving to the next one. The risk here is when requirements change throughout the process. In that case you would have to go through most of the process again.
  • Iterative development is cyclic and a response to the weaknesses of the Waterfall model. It is more flexible because it works with smaller iterations. It is adaptive, starts with a small version, changes per cycle are smaller so easier to correct if wrong. The customer has an early demo ready.
  • Agile methods are iterative and incremental. They are adaptive rather than predictive and people-oriented rather than process driven. The work is done in small self-organizing, cross-functional teams.
  • Extreme Programming is a type of agile software development. It is characterized by simplicity and clarity in code (using coding standards), rapid iterations, team work (pair programming), refactoring and unit testing, frequent feedback from the customer (changes are a fact of life) and 40-hour workweeks (no overtime).

More resources

Two must-reads on this topic are: The Pragmatic Programmer: From Journeyman to Master and Clean Code: A Handbook of Agile Software Craftsmanship.

Two of my previous posts that are related: Some tips to make a developer's life easier and Becoming a good debugger.

Javascript Bookmarklet to build Affiliate Links to Amazon

You have a blog and want to get a few bucks from linking to Amazon anytime you discuss a book. Fair enough, you sign up for the affiliate program. However if you link to various books in a post, it becomes tedious to generate the links. I made a Javascript Bookmarklet to fix this.

The concept

featured image

Bookmarklets provide one-click functionality to a browser or web page. This is an affiliate link from Amazon: http://www.amazon.com/dp/0596527241/?tag=bobbelderbos-20 ; you see you only need two variables:

The first value is something you need to query, so that is why I leverage the power of My Reading List, which has an autocomplete field at the top that can locate the most common books. There is some scripting behind it - which I will detail in an upcoming post - how I find the ASIN from the ISBN (which Google Books API returns to me). In the majority of cases it should find it.

Update after Googling:

After writing this post, I found a nice post which offers a bookmarklet to be used on Amazon's site itself. This probably is a better approach. It finds the ASIN with "document.getElementById('ASIN')".

Try it

A. add the bookmarklet:

  • In Firefox right-click on the Bookmark toolbar and click "New Bookmark"
  • Give it a name, for example : amazonAffiliateLink
  • Paste the following Javascript in the "Location Field" (a copy is also available at github).
  • 
    javascript:(
      function(){
        var tag = null;  
        var urlElement = findElementId('amazonLink'); 
            
        if(urlElement == null) {
          alert('No results for #amazonLink - does the ID element exist on this page?');
          return;      
        }
        
        url = getUrl(urlElement); 
        
        if(tag == null) {
          tag = prompt("Enter your Amazon tag for the URL: ", "Enter Tracking ID here");
        } 
        
        url = url.split("=");
        copyToClipboard(url[0]+'='+tag); 
        
        
        
        function findElementId(idElement) {
          var urlElement = document.getElementById(idElement);
          return urlElement; 
        }
        
        function getUrl(urlElement) {
          var urlHref = urlElement.href; 
          return urlHref;
        }
        
        function copyToClipboard (text) {
          window.prompt ("Copy to clipboard: Ctrl+C, Enter", text);
        }
        
      }
    )()
    

    Note that you can edit "var tag = null;" to define your tracking ID if you want to use the same for all links. If not provided (null) it will ask you.

  • Hit "Save".

Update 2 after Googling:

You can also store the script somewhere and append it to the body, see this nice article about bookmarklets on Smashing magazine. It also explains how you can use jQuery to make bookmarklets.

B. use the bookmarklet:

  • Go to My Reading List
  • In the search box at the top search your book and select it, it will go to a page with more details of the book.
  • If the ISBN-ASIN conversion worked you see a "Buy at Amazon" link which is the affiliate link I use for that site. It is a hyperlink marked with an unique ID element called "amazonLink". That id is consumed by Javascript's document.getElementById which then manipulates the URL to replace my tracking id with the one you provided (see the code above).
  • Click the bookmarklet, the Javascript will be executed.
  • If you defined the tag (aka tracking id) it will use that, otherwise you are requested to put it in (see printscreen below ...)
  • Finally you are presented with another input box with the link selected. Copy+C and you have it in on your clipboard. This is a nice trick I found at Stackoverflow (2nd answer).

Printscreen process flow

bookmarklet howto

Technical Blogging - turn your expertise into a remarkable online presence

Today I wanted to share with you an awesome title I just finished reading: Technical Blogging - turn your expertise into a remarkable online presence by Antonio Cangiano.

featured image

Technical Blogging teaches you how to gain influence and earn money from your blog. It applies to any blog, but the examples are related to a programming blog, so ideal for me.

In 254 pages you get a lot of useful insight, with quite some technical depth. The author has quite some experience in the field. Some tricks I did learn already from a couple of years blogging. However, there was still a lot of advice I could pick up to start improving my blog.

However there are two things the author cannot provide and are thus assumed: you dedicate the necessary time and your are able to provide good content. If you have that in order, complementing it with this book can indeed make you a power blogger.

... and this book covers a lot!

The book covers the whole process from starting to maintaining a blog. From the analysis/ planning stage (part I) to building it plus providing remarkable content (part II), to promotion (part III), earning from your blog (part IV) and finally scaling it (part V). In all parts are a lot of useful gems to digest.

Some things I especially liked:

  • The focus on a technical blog. This was exactly what I needed. But any blogger can benefit from this book.
  • The general depth of the topics covered (e.g. the SEO aspects are well addressed, understanding traffic stats, writing strategies (posting schedules, how to find ideas), the different ways to make money from your blog, etc.)
  • As said, the wide scope and many directly and indirectly related topics that are useful to know, some of them provided me with new insights: engaging readers, target the right social networks (for programmers hacker news, reddit and dzone) and the ways these are different, tactics for writing good content. Even productivity tips like the Pomodoro technique are explained.
  • Clear examples, mostly drawn from the author's blog. In fact the author is very open sharing his visitor stats and affiliate earnings.
  • A lot of links/ reference material.

Conclusion and what's next

I highly recommend Technical Blogging to anybody that maintains or wants to start a blog. I found it an inspiring read and it will serve as a reference as I keep improving my blog.

I also did a post on blogging myself: 10 crucial steps to become proficient at blogging.

If you want to extend this to building a business from your blog you might also want to check out ProBlogger: Secrets for Blogging Your Way to a Six-Figure Income.