jAbLoK

Can Your Programming Language Do This?

Zasláno do Tech by Pavel Kolesnikov na Květen 5th, 2008

… se jmenuje článek od Joela Spolskeho, kde autor vysvětluje základní myšlenku Map/Reduce (tedy převést problém na paralelizovatelné zpracovávání seznamů) na JavaScriptu.

Lispu neznaje, první odpověď, která mě na otázku v nadpisu napadla, byla: no jo, perl :-)

Javu samotnou hanět nezačnu ani náhodou, nicméně na Joelově stížnosti na “Java-only” vzdělávání něco bude.

Tagged with: , , ,

Skutečně umíme měřit, jak dlouho lidé setrvají na webových stránkách

Zasláno do Tech by Pavel Kolesnikov na Březen 14th, 2008

Daniel Dočekal klade řečnickou otázku, a jak to u řečnických otázkách bývá, rovnou připojuje negativní odpověď — cituji: "jediné co totiž [Navrcholu] ví, je že někdo někam přišel. A pak už nikam neodešel".

Navrcholu to možná neumí (proč?), technicky lze tuto dobu velmi dobře aproximovat za předpokladu, že při čtení stránky uživatel tu a tam zaroluje či pohne myší (schválně si to vyzkoušejte na sobě).

Třeba takto:

/**
 * a simple reading time tracking utility
 *
 * @author Pavel Kolesnikov
 */
var Tracker = function(cfg) {
	var TIMEOUT = 3000; // 3 seconds

	var config = cfg ? cfg : {};

	var mouseLogging = 1;
	var keyboardLogging = 1;

	var lastActivity;
	var total = 0;
	var saveMessage = config.saveMessage;

	function logActivity() {
		var now = new Date();
		var sinceLastActivity = now.getTime() - lastActivity.getTime();
		if (sinceLastActivity > TIMEOUT) {
			sinceLastActivity = TIMEOUT;
		}
		total += sinceLastActivity;
		lastActivity = now;
	}

	function logActivityMouse() {
		if (mouseLogging) {
			logActivity();
		}
	}

	function logActivityKeyboard() {
		if (keyboardLogging) {
			logActivity();
		}
	}

	this.stopMouseLogging = function() {
		mouseLogging = 0;
	};

	this.startMouseLogging = function() {
		mouseLogging = 1;
	};

	this.stopKeyboardLogging = function() {
		keyboardLogging = 0;
	};

	this.startKeyboardLogging = function() {
		keyboardLogging = 1;
	};

	function createXMLHttpRequest() {
		if (window.XMLHttpRequest) {
			return new XMLHttpRequest();
		} else if (window.ActiveXObject) {
			return new ActiveXObject('Microsoft.XMLHTTP' ;)
		} else {
     		return null;
		}
	}

	function postLog(params) {
		var ajax = createXMLHttpRequest();
		if (ajax) {
			ajax.onreadystatechange = function() {};
		}
		ajax.open('POST', config.o, true);
		ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		ajax.setRequestHeader("Content-length", params.length);
		ajax.setRequestHeader("Connection", "close");
		ajax.send(params);
	}

	function write() {
		var params = "u=" + config.u + "&i=" + config.i + "&t=" + total
			+ "&r=" + document.referrer;
		postLog(params);
	}
	this.write = write;

	lastActivity = new Date();
	document.onmousemove = logActivityMouse;
	document.onkeypress = logActivityKeyboard;
	window.onunload = write;
}