Call us Toll-Free:
Live ChatEmail us
oops. I couldn't find the page you're looking for. It was either moved or removed.

You have been redirected to the Resources page where you can find anything SoftwareProjects related. (Original URL: /reviews-teamscope.htm)

Passing parameters from DoubleClick tag to landing page

Adrian Singer, February 23    --    Posted under Traffic
This took a while to figure out, so hopefully it helps others -

The goal is generating a DoubleClick tag, that will take additional parameters and pass them to the destination landing page.

Step 1

Login to your DoubleClick account, click on Campaigns, then select the Ad

Step 2

Scroll down and open the Landing page URL suffix section

Enter the url key you'd like to populate, into the URL suffix box, in this format:


This will tell DoubleClick you want to pass "key" to the landing page, populating it with the value of key sent to the tag.

If you want to populate more than one key, use this format:


Step 3

Click on the 'Tags' button at the top, then export tags. The tags you want will be under the "Iframes/Javascript Tag" column

The Art of managing Freelancers - Part 2 - Qualifying the bid

Mike Peters, January 24    --    Posted under Basics

You created a rock solid specification document and posted it on,, or any of the other freelancer sites.

Within a matter of hours, you have dozens of bids from software engineers around the world.

All of them carefully reviewed your specification document and made sure it's a perfect fit for their skills before submitting their bid, right?


Canned Bids

Winning projects as a freelancer, is a numbers game. The more projects you bid on, the more likely you are to win a few.

Based on this logic, you should try to bid on as many projects as possible.

Unfortunately a lot of freelancers abuse the system, creating scripts for automatically submitting canned bids, to all new projects in their category.

Take a closer look at the bids you received. Do they mention anything specific about -your- project? Or could the same bid very well apply to any other project in this category?

Eliminating canned bids

In most cases, you don't want to work with a freelancer who didn't even take the time to read your specification document and submitted a canned bid, without ever stopping to think if this is a good fit with their skill-set.

One trick I use to easily detect and eliminate canned bids, is adding a request in the body of the specification document, that goes something like this:

When you bid on this project
, start your bid with " is great", so that I know you actually took the time to read this spec. This helps me in eliminating canned bids.

If the freelancers bid doesn't include this text, I immediately know it's a canned bid.

Sometimes even though they didn't include the text, the freelancer might catch my attention with a stellar feedback review history. At that point, I give them a simple test, that usually goes like this:


After you get rid of the canned bids, you're left with freelancers who took the time to carefully review the specification document.

Open a message board and ask them the following questions -

1. Do you have experience creating similar apps/websites?
2. Can you share with me links to your previous work?
3. Do you have experience working with the programming language and platform I described in the document?
4. Who will be doing the actual work?
5. What milestones do you suggest?
6. How much time do you expect it will take to complete this project?
7. How will we communicate during this time?

If the freelancer answers to all of the above questions are satisfactory, shortlist them.

Pay close attention to their communication skills, how long it takes between each reply, how detailed are they and how well you understand them.

Communication is key.

Pick the best two or three

Narrow down the best matches, to a list of two or three freelancers.

You are going to award the project to all of them at the same time.

The freelancer who creates the best result, will be the one you'll continue to the following projects with.

Yes - I am suggesting you actually award and pay two or three freelancers.

Think of it as "cost of doing business". It's an essential price to pay, for finding the perfect fit for your needs.

You'll thank me later.

The Art of managing Freelancers - Part 1 - The specifications document

Mike Peters, January 24    --    Posted under Basics
If you were building a new home, would you jot down your ideas for the house in a short Word document, then send them over to construction workers and expect everything to work out well?

Of course not.

And yet, when it comes to software development, most people do exactly this.

They expect a simple unabridged outline of their thoughts, should be all an accomplished software engineer would need to get the job done.

Architects and Builders

Software engineers need a detailed specification document to work by.

In the real world, when you build a house, you would start with an architect. Your architect's job is to translate your vision into a diagram, with detailed measurements and notes about which materials to use.

A builder then takes the diagram prepared by the architect, orders the required materials, creates a work plan, rounds up the construction workers to do the work and manages them on a day-to-day basis, until the work is completed to your satisfaction.

Product Managers and Project Managers

In the software development world, these two roles are played by a Product Manager and a Project Manager.

The Product Manager's role is to translate your vision, into a language software engineers can understand, using very detailed descriptions, screenshots and visuals, not leaving any room for interpretation.

This document is called a Specification Document. Getting it right is the first step in ensuring your project will be a success.

The Project Manager's role is to manage the software engineers until they successfully build a working program that works looks and feels exactly as described in the specification document.

The Specification document

Ideally, it would be best if you have a professional help you with preparing the specification document.

Try to reach out to a Product Manager, who has experience in preparing such documents.

If you don't have access to a Product Manager, your next best option is to reach out to an experienced software engineer and ask for his/her help.

A good specification document should at minimum include these parts:

1. Overview

Explain what this project is about. Who are the users, what function does it fill and what is the value proposition.

2. Goals

Detailed list of goals. Be as specific as possible about what you want to accomplish with this project.

Include screenshots and examples of similar websites/services as necessary.

3. Technical specification

Define the programming language you want the software engineers to use, the target platform and tools they should use

4. Process flow

Step-by-step description of all the screens a typical end user will go through.

Include screenshots, or mockups - very important!

5. Technical architecture & coding convention

Explain the architecture of the product, which modules you want to have created and how they should interact with each other.

Provide a link to your preferred coding convention, so that it's easier to later manage the code.

6. Budget and timeframe

Your estimated budget and target timeframe for the project.
Ask the software engineers to confirm they can meet these, or work with you on reaching a mutually agreed-upon budget and timeframe, before the project starts.

7. Communication

Include contact information for your project manager (probably you) and be clear about expecting daily updates from the engineer, outlining the progress of the work.

Make yourself available via Skype, email, or phone.

Be sure you are responsive and insist on getting frequent progress reports, along with links to review the project at every milestone.

How to tell if you got it right

Similar to an architectural diagram, a good specification document leaves no room for interpretation.

Two different qualified software development teams, should be able to create the same result, if the specification document is sufficiently detailed.

How to delete files when argument list too long

Mike Peters, January 23    --    Posted under Programming
Ever try to delete a lot of files in a folder, only to have the operation fail with "Argument list too long"?

Here's how to get it done:


. -name "*.pdf" -print0 | xargs -0 rm

Note that this is a recursive search and will find (and delete) files in subdirectories as well.


. -name "*.pdf" -maxdepth 1 -print0 | xargs -0 rm

View 1 Comment(s)

Tracking Retention in Google Analytics

Mike Peters, January 29, 2013    --    Posted under Analytics
Tracking retention rates or cohort analysis, is the best way to visualize your site's addict-ability.

User retention tends to be an area where people pay the least amount of attention, but I think is one of the most important to monitor. I would argue that the single most telling metric for a great product is how many of them become dedicated, repeat users.

If you fail to retain users over time, traffic will never generate a "snow ball" effect. Your glass-ceiling becomes limited to the arbitrage difference between the cost of traffic and ad revenues.

Focus on continually improving your retention rates and you'll be well on your way to building a mega successful site.

First step is to monitor your retention rate numbers. As they say - "What doesn't get measured, Doesn't get done".

The goal is to have the data you need to generate a cohort report like this one:

In this post, I'll describe how to use Google Analytics, for cohort analysis.

Don't be fooled by Google's Returning visitors numbers

Google Analytics appears to provide information about visitor retention through the New vs. Returning visitors report.

That report shows you the proportion of returning visitors. You could set your date range for January, note the percentage of returning visitors, and then set the date range for February, hoping that the percentage of returning visitors has increased.

But what happens if you retain all your January visitors, but drive a ton of new visitors to the site in February? Your proportion of returning-to-new visitors will go down even though you're retaining visitors!

Additionally, if your funnel involves users leaving the site (to "Facebook-Connect" for example), Google Analytics could confuse that with a user leaving the site.

Tagging visitors

For proper cohort analysis, we need a way to "tag" users, segmenting them into groups based on the date of first visit.

We'll then be able to look at the group of new users generated on a given month and see how long they stuck around:

Google Analytics custom variables and events, lets us put it all together.

Step 1 - Install Google Analytics

Signup for Google Analytics (it's free) and create an account for your site.

Add the Google Analytics code to all pages on your site.

Generally this means adding the code to your footer include file.

Step 2 - Pulse script

Save this script under the root folder of your site:


header('Content-type: application/json');

"if(typeof pulseCallback=='function')".
' pulseCallback({"pulse":"'.date('Y-m-d').'"});');

Note that I'm assuming your server supports PHP. If you're using a different server-side scripting language, find a geek who can help or contact us.

Step 3 - Store custom variable in Google Analytics

Add this javascript code to the footer of all pages:
function jsCreateCookie(name,value,days){if(days){var date=new Date();date.setTime(date.getTime()+(days*24*60*60*1000));var expires="; expires="+date.toGMTString()}else var expires="";document.cookie=name+"="+value+expires+"; path=/"}
function jsReadCookie(name){var nameEQ=name+"=";var ca=document.cookie.split(';');for(var i=0;i!=ca.length;i++){var c=ca[i];while(c.charAt(0)==' ')c=c.substring(1,c.length);if(c.indexOf(nameEQ)==0)return c.substring(nameEQ.length,c.length)}return null}
function jsGetCookie(cvar, cval) { if (cval == undefined) cval = ''; return (jsReadCookie(cvar) != null && jsReadCookie(cvar) != '') ? jsReadCookie(cvar) : cval; }

try {
var checkpulse = jsGetCookie('checkpulse');
if (!checkpulse) {
// get timestamp
var s = document.createElement('script'); s.type = 'text/javascript'; s.src = ''; s.async = true;
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(s);
} else {
channel = ""; // Update when using channels
$(document).ready(function () { _gaq.push(['_trackEvent', 'Pulse', checkpulse, 'Channel #'+channel]); });
} catch(err){}
function pulseCallback(o) {
jsCreateCookie('checkpulse', o.pulse, 365);

What we're doing here is - on every page load, check if the user was already tagged with a "create date".

If user not tagged yet - it's a new user, we connect to the server's pulse.php script and fetch today's date. The date is then stored in a local cookie named "checkpulse".

Finally, we pass the event to Google Analytics, incrementing a count for our user's "create date".

Crunching the numbers

Congratulations! Now you can finally track your real retention rates and build a cohort chart.

Login to Google Analytics, open "Traffic Sources", then "Events" - "Top Events"

Select the date range starting with the first month you're tracking (January in the example above) through today. Change the period to "Month" and select "Unique Events":

Hover above the chart and record the numbers for each of the months

Download sample Cohort report and populate it with your data. Pay attention to your user's average life time and variations in month-to-month retention rates.

Know your numbers.

Use your cohort report as a compass for whether or not you've created a great product that users love.

Sublime Text Editor for PHP - a love story

Mike Peters, January 24, 2013    --    Posted under Basics
Sublime Text is a fast, sophisticated text editor for code.

Over the years we've tested numerous text editors, including Notepad, Notepad++, PHPStorm, Eclipse, jEdit, NetBeans, phpDesigner and PHPEdit...

Up until recently, PHPStorm and Notepad++ were our two favorites.

PHPStorm has a very extensive feature-set: syntax highlighting, autocomplete, refactoring, html wysiwyg mode, a built-in debugger and file indexing. But it's heavy. Slow. Bloated.

Notepad++ is fast, but it's missing a lot of the goodies found in PHPStorm.

Introducing Sublime Text

Sublime Text 2 combines the best of both worlds:

* Blazing fast
* Sexy
* Syntax Highlighting
* Code completion
* Multi-select and multi-edit
* Goto Anything
* Find and Replace in files
* Customizable via extensive plugin library


Step 1

Download the latest version of Sublime Text 2 here

Windows, Mac OS and Linux binaries are available.

Step 2

Install the Sublime Package Control, by launching the Sublime editor, selecting "View" - "Show Console" from the menu, then pasting this code directly into the console:

import urllib2
,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen(''+pf.replace(' ','%20')).read()); print('Please restart Sublime Text to finish installation')

Package Control is now installed. Close Sublime text editor and restart it for changes to take effect.

Step 3

Open Sublime text editor, click Ctrl-Shift-P and type "Install Package"

Search and install these packages, one by one. Simply type the package name and click it to install.

* SublimeCodeIntel
* SublimeLinter
* WordHighlight
* jQuery
* Prefixr
* Clipboard History

One other thing you're going to want to turn-on is the "Auto save" feature. Off by default, you can turn it on, by opening the "Preferences" - "Default" and setting save_on_focus_lost to true:

"save_on_focus_lost": true,

Step 4

Sublime PHP linter relies on PHP being installed on your machine.

If you haven't installed PHP earlier, grab it from

You'll want to get the Thread-safe ZIP version. Extract the ZIP file to a new "C:\Program files\php" folder.

Open Sublime editor Preferences menu, select the SublimeLinter Settings under "Preferences" - "Package Settings", locate the "sublimelinter_executable_map" block and enter the full path where PHP is installed.

For example:
"php" : "C:\\program files\\php\\php.exe"

Step 5

Install Soda-Theme to give Sublime a sexy dark look

Once installed, update your default theme under "Preferences" - "Settings" with:

"theme": "Soda Light.sublime-theme",
"soda_classic_tabs": true

Restart Sublime editor and you're good to go

Sublime Cheat Sheet

Open Folder: Opens list of all files on a left pane
Ctrl-P: Quickly find any file under your project
Ctrl-F: Find
Ctrl-H: Find/Replace in current file
Ctrl-Shift-F: Find/Replace in files
Ctrl-M: Jump to closing bracket
Ctrl-Shift-M: Select all content of current bracket
Ctrl-Z: Undo
Ctrl-Y: Redo
Ctrl-G: Goto line
Ctrl-S: Save current file
Ctrl-R: Goto symbol / function definition
Ctrl-Shift-D: Duplicate line
Alt-Shift-2: Split to two panes (shift-1 back to one)
Ctrl-2: Jump to pane 2 (Ctrl-1 jump to pane 1)
Ctrl-Shift-L: Multi select
Alt-F3: Select all occurrences of current word for multi edit

View 1 Comment(s)

6 Months with GlusterFS: a Distributed File System

Mike Peters, August 9, 2012    --    Posted under Programming
Gluster is an open-source software-only distributed file system designed to run on commodity hardware, scaling to support petabytes of storage.

Gluster supports file system mirroring & replication, striping, load balancing, volume failover, storage quotas and disk caching.

Hesitant with the lack of glowing reviews about Gluster, we were attracted by its feature set and simple architecture.

Over the last six months, we battle-tested Gluster in production, relying on the system to deliver high-availability and geo replication, to power large scale Internet Marketing product launches.


The Gluster architecture aggregates compute, storage, and I/O resources into a global namespace. Each server plus attached commodity storage is considered to be a node. Capacity is scaled by adding additional nodes or adding additional storage to each node. Performance is increased by deploying storage among more nodes. High availability is achieved by replicating data n-way between nodes.

Unlike other distributed file systems, Gluster runs on top of your existing file-system, with client-code doing all the work. The clients are stateless and introduce no centralized single point of failure.

Gluster integrates with the local file system using FUSE, delivering wide compatibility across any system that supports extended file attributes - the "local database" where Gluster keeps track of all changes to a file.

The system supports several storage volume configurations:

* None: Files are transparently distributed across servers, with each node adding to the total storage capacity.
* Replica: Files are replicated between two LAN drives (synchronous replication)
* Geo replica: Files are replicated between two remote drives (asynchronous replication, using rsync in the background)
* Stripe: Each file is spread across 4 servers to distribute load.

As of October 2011, development of Gluster is funded by RedHat

Installing Gluster

This is one of the areas where Gluster really shines. You can be up and running in minutes.

Step 1

Installing the FUSE client, which serves as the "glue" between Gluster and your local file system.

tar xvfz fuse-2.9.1.tar.gz
cd fuse
make all
make install

Step 2

Building Gluster from source

tar xvfz glusterfs-3.3.0.tar.gz
cd glusterfs
make all
make install

Starting Gluster and setting it to auto-start on next reboot

/etc/init.d/glusterd start
/usr/sbin/update-rc.d glusterd defaults

Step 3

Configuring your first two nodes as a Replica setup (mirroring)

On node 1 (backup1east):


gluster peer probe backup2west

gluster volume create backup replica 2 transport tcp backup1east
:/gfs/bricks/vol0 backup2west:/gfs/bricks/vol0

-t glusterfs backup1east:/backup /gfs/backup

On node 2 (backup2west):


gluster peer probe backup1east

-t glusterfs backup2west:/backup /gfs/backup

Important: Make sure the name of your Gluster volume ('backup' in the example above) is different than the name of the share ('gfs' in the example above) or things will not work properly.

Our Experience

Going into this experiment, we had very high hopes for Gluster. Once proven, the goal was to replace our entire private cloud storage cluster with Gluster.

Unfortunately, we have been very disappointed with Gluster...

In spite of getting a lot of help from the Gluster community, testing different platforms and configurations, results have been consistent.

Like other users reported, we struggled with poor performance, bugs, race conditions when dealing with lots of small files, difficulties in monitoring node health and worst of all - two instances of unexplained data loss.

We ended up completely abandoning Gluster and switching back to our home-grown rsync-based solution.

As always, run your own tests to determine if this is a good fit for your needs.

Proceed with caution.

More Resources

* SlideShare Introduction to GlusterFS
* Gluster Documentation
* Gluster IRC Channel
* Gluster Blog

View 1 Comment(s)
« Previous Posts

About Us  |  Contact us  |  Privacy Policy  |  Terms & Conditions