As I've talked to more and more people about genetify, I have felt the growing need for a demo. I wanted something that I could direct people to offhand and also something that I could talk somebody through. I wanted it to hit all the high points and lead people to ask the right questions.
Today, after a day's work (mostly due to bugs -- nothing like a public demo to bring them out) I finished something I'm pretty proud of. And I need to be -- this demo I expect will be the front door into the world of genetify for some time to come.
So here it is: http://genetify.com/walkthru.php
Oh ya, I set up genetify.com at a new webhost yesterday but that's too boring to talk about. The more I learn to program, the more I hate sys admin.
Tuesday, October 30, 2007
Monday, October 29, 2007
Performance == cacheing
Without really needing to, I wrote in genetify.php some code to cache results locally. Once again, inspiration overwhelmed me. My new ideas today were to:
* use the default PHP temp dir in order to avoid extra setup (duh!)
* request a new result set with a random, specifiable frequency (like 0.10) -- simple but effective in reducing requests
* update the cache on disk as a shutdown function -- this means a request appears to complete just as fast as without cacheing!
I can't wait to see how much traffic the whole system can bear now. Because the information being processed by genetify is not necessary for coherent interaction with a site, it can be cached endlessly. This simple inverse relationship between the value of up-to-date information and cacheing means that genetify should be able perform to extremely well.
* use the default PHP temp dir in order to avoid extra setup (duh!)
* request a new result set with a random, specifiable frequency (like 0.10) -- simple but effective in reducing requests
* update the cache on disk as a shutdown function -- this means a request appears to complete just as fast as without cacheing!
I can't wait to see how much traffic the whole system can bear now. Because the information being processed by genetify is not necessary for coherent interaction with a site, it can be cached endlessly. This simple inverse relationship between the value of up-to-date information and cacheing means that genetify should be able perform to extremely well.
Sunday, October 28, 2007
The pleasure of control
I spent quite a bit of time today working on a portable testing panel for genetify. The effort was mostly unplanned and flowed from the thrill of building big, shiny buttons that control my creation. The really neat part is that the controls are inserted into any page from a remote script but one that is requested separately from genetify.js. The controls can be brought onscreen with a single function call but they don't weigh down the core code library. All this is for the convenience of the ultimate users of genetify -- developers.
Tuesday, October 23, 2007
Server side, no sweat
I added to the PHP server side library a few days ago (the blogger in me is slacking) and in the process I codified (excuse the pun) the universal, language-independent genetify API. In the abstract, it is something like this:
This general structure of the code is true for manipulating all types of object currently implemented -- PHP vars, Javascript objects, CSS rules, HTML elements. My hope is that this stays true as new languages are added -- Python, Ruby... who knows what else.
vary([callingContext]){
genes = getGenes(callingContext)
genome = _vary(genes)
save(genome)
}
_vary(genes){
for (gene in genes){
selected = selectVariant(gene)
genome[gene] = selected
callingContext[gene] = selected
}
return genome
}
save(genome){
saveToCookie(genome)
saveToDatabase(genome)
}
This general structure of the code is true for manipulating all types of object currently implemented -- PHP vars, Javascript objects, CSS rules, HTML elements. My hope is that this stays true as new languages are added -- Python, Ruby... who knows what else.
Friday, October 12, 2007
A lake of calm
I feel like a lake of calm now that I have successfully launched my first real live honest-to-goodness test of variants on my friend's ecommerce site. We will see from the data that is coming in how good genetify can be.
Friday, October 5, 2007
document.cookie sucks
So I was working last night on finishing a prototype PHP library for genetify. Everything was going great (it is amazing how fast you can re-write code, even in another language), until it came time to manipulate cookies client-side in Javascript that were set server-side in PHP. The cookie data was being read and passed on successfully to the rest of the system so my confidence in the PHP code was high. But when it came time to rewrite parts of the cookie data client-side -- the last test I wanted to try before calling it a night -- I ran into problems. Overwriting the server side cookie appeared to create a whole new cookie with the same name. Until this experience, I had always understood cookies to exists as keyed values in a namespace, altho represented by document.cookie as a string. So I tried to discover some sort of configuration of HTTP requests and client and server state that could reconcile the two cookies. As the night wore on, I spiraled down into a kind of mental labyrinth until I had the sense to give up.
Today, with a fresh start, I systematically tested my assumptions about cookies and I discovered after half an hour that Firefox's document.cookie prefixes the domain info in the cookie with a period "." , which apparently puts the cookie in a different namespace for writing (altho not reading!). It is no surprise that I missed it the night before. Can you spot the odd man out?
mydomain.com, mydomain.com, mydomain.com, .mydomain.com, mydomain.com
Not normally judgmental, I humbly name document.cookie a TERRIBLE API. Even before this epsiode, from my earliest days making websites, I hated it. Let's count all the sins:
1. Document.cookie is represented as a string, but the equals sign "=" appends to it. Why not "+=" ?
2. You can write to document.cookie with extra params (expires, domain, path) but these are not accessible anywhere in the DOM. Come on!
3. You can only delete a cookie by giving it an expiry in the past. Why not an empty string or null value?
4. The namespace problem described above. How to identify two cookies with the same name but different domains or paths?
5. All these problems could be avoided by making document.cookie a *normal* javascript-DOM object. Then every bloody javascript framework out there wouldn't need the functions setCookie and getCookie.
Today, with a fresh start, I systematically tested my assumptions about cookies and I discovered after half an hour that Firefox's document.cookie prefixes the domain info in the cookie with a period "." , which apparently puts the cookie in a different namespace for writing (altho not reading!). It is no surprise that I missed it the night before. Can you spot the odd man out?
mydomain.com, mydomain.com, mydomain.com, .mydomain.com, mydomain.com
Not normally judgmental, I humbly name document.cookie a TERRIBLE API. Even before this epsiode, from my earliest days making websites, I hated it. Let's count all the sins:
1. Document.cookie is represented as a string, but the equals sign "=" appends to it. Why not "+=" ?
2. You can write to document.cookie with extra params (expires, domain, path) but these are not accessible anywhere in the DOM. Come on!
3. You can only delete a cookie by giving it an expiry in the past. Why not an empty string or null value?
4. The namespace problem described above. How to identify two cookies with the same name but different domains or paths?
5. All these problems could be avoided by making document.cookie a *normal* javascript-DOM object. Then every bloody javascript framework out there wouldn't need the functions setCookie and getCookie.
Wednesday, October 3, 2007
Looking for trouble
So I launched genetify a few days ago on a friend's site with it set to record goals only. It's working, but only partially. The irritating fact is that not all goals are being recorded, as shown by my friend's own records.
After checking all the browsers again, I couldn't think of anything else to try, so I decided to gather more info -- log all javascript errors to the database. I can see this feature sticking around. It would be a bold new step in my drive for reliable software -- complete responsibility of the client-side.
After checking all the browsers again, I couldn't think of anything else to try, so I decided to gather more info -- log all javascript errors to the database. I can see this feature sticking around. It would be a bold new step in my drive for reliable software -- complete responsibility of the client-side.
Monday, October 1, 2007
Ultimate and proximate goals revisited
I had a strange and wonderful idea today, sparked by discussions with friends about genetify. Sooner or later, someone will put so many genes in their pages that it will be hard to evaluate the effect of any single variant on a distant goal. To cope, the webmaster could create separate sub-goals for particular pages where appropriate. For example, knowing that a user who ultimately buys a product must pass thru the product's detail screen,
you could make the detail screen a sub-goal. But couldn't this whole process of creating sub-goals be systematized? Every page should in principle make some quantifiable contribution in the path to a goal. And couldn't genetify itself be used to discover these page-values?
Imagine every link on a page is genetified to comprise two variants: onclick="goal(1)" and onclick="goal(0)". This means that links that lead to pages with goals will have the "goal(1)" shown more frequently. In fact, "goal(1)" should eventually be shown in proportion to the average goal total reached on the following page. Therefore, critically, every page would also have a single goal fired by default whose value is equal to the sum of its "goal(1)" links. This means that the value of outgoing links is passed on to incoming traffic. Because this works across any two neighboring pages, an arbitrary number of pages could then be chained together in a value-chain. The real-world value of some far-away externally defined goal (think of a purchase) could be made to cascade thru a whole tree of supporting pages. Most important, at every node in the tree, the page-value would be proportional to its contribution to the ultimate goal.
Pretty crazy, huh?!
you could make the detail screen a sub-goal. But couldn't this whole process of creating sub-goals be systematized? Every page should in principle make some quantifiable contribution in the path to a goal. And couldn't genetify itself be used to discover these page-values?
Imagine every link on a page is genetified to comprise two variants: onclick="goal(1)" and onclick="goal(0)". This means that links that lead to pages with goals will have the "goal(1)" shown more frequently. In fact, "goal(1)" should eventually be shown in proportion to the average goal total reached on the following page. Therefore, critically, every page would also have a single goal fired by default whose value is equal to the sum of its "goal(1)" links. This means that the value of outgoing links is passed on to incoming traffic. Because this works across any two neighboring pages, an arbitrary number of pages could then be chained together in a value-chain. The real-world value of some far-away externally defined goal (think of a purchase) could be made to cascade thru a whole tree of supporting pages. Most important, at every node in the tree, the page-value would be proportional to its contribution to the ultimate goal.
Pretty crazy, huh?!
Subscribe to:
Posts (Atom)