Tripling up

I have another 22″ Acer and an HDMI slot for it,
but I’m all out of desk space.
Do iframe pages show up in browser history?
The answer is yes and no.
This Google R&D guy gives a good rundown.
http://codinginparadise.org/weblog/2005/08/ajax-tutorial-tale-of-two-iframes-or.html
Long story short… The first IFrame src url will not be included in the browser history for static IFrames. However, all subsequent page urls within the IFrame will.
Unless… You do something tricky like insert the IFrame using JS or manipulate the src attribute in which case the behavior differs by browser and version.
What’s in a name
I’ve been using this as my source of device names for several years.
http://www.playdota.com/items
I have or used to have:
TRAVS – An Asus Eee 1002HA netbook named after Boots of Travel
MJOLLNIR – A new Core i7 desktop named after Thor’s hammer, Mjollnir
DEFIANCE – A used 1U dual 3.06Ghz HP Proliant DL360 G3 webserver with 2Gb RAM running Centos 5.5 in a rack at HE in Fremont named after Hood of Defiance
MANTLE – A new Ubuntu VMWare guest instance running on Mjollnir with shared folders named after Mantle of Intelligence
IRONWOOD – A deceased Ubuntu VirtualBox VM instance named after Ironwood Branch
SANGE – A deceased desktop named after Sange (Sange and Yasha)
YASHA – A deceased desktop named after Yasha (Sange and Yasha)
RADIANCE – A previous company-owned laptop named after Radiance
Linus Torvalds thinks you are ugly.
… ugly AND STUPID (unless you use git).
Best way to store an ip in mysql
I used to use varchar(15).
But a little poking around yielded a better solution.
Turns out there’s a standard set of MySQL functions for translating an IP address to and from an integer.
ALTER TABLE `sessions` ADD `client_ip` INT NOT NULL AFTER `created_at`; mysql> SELECT INET_ATON('192.168.10.50') AS ipn; +------------+ | ipn | +------------+ | 3232238130 | +------------+ mysql> SELECT INET_NTOA(3232238130) AS ipa; +--------------+ | ipa | +--------------+ | 192.168.10.50 | +--------------+
Here’s the algo in case you’re curious:
(192 * 2^24) + (168 * 2^16) + (10 * 2^8) + 50 = 3232238130
UI anti-pattern: Cross Column Alpha Sort
The human eye is trained to follow edges. In the case of a list such as this, the eye’s natural inclination is to move from top to bottom along the column of icons, not left to right across jagged gaps between columns. Splitting the first 4 in the sort across 4 columns is highly illegible.

Shame on you, Microsoft. You should know better.
Don’t write apologetic code
If your code needs explaining, you’re doing it wrong. Rewrite it.
/* Bad */ $tuucount=0; // total unique users $tlcount=0; // total lead count $tlrcount=0; // total lead rev $tarcount = 0; // total aftermarket revenue $trcount=0; // total toal
/* Better */ $total_unique_users = 0; $total_lead_count = 0; $total_lead_revenue = 0; $total_aftermarket_revenue = 0; $total = 0;
Git batch deploy
I should have done this ages ago. 1-click blast is awesome.
deploy.bat
cd c:\web\site\dev call git push dev master call git push stage master call git push appsrv01 master call git push appsrv02 master call git push tasksrv01 master pause
Javascript Phone Number Validation Regex
Adheres to the US North American Numbering Plan
http://en.wikipedia.org/wiki/North_American_Numbering_Plan
validate_phone("16505217791x1234") == "(650)521-7791 x1234";
validate_phone("16505217791x") == "(650)521-7791";
validate_phone("6505217791") == "(650)521-7791";
validate_phone("1234567890") == false;
validate_phone("12345678901") == "(234)567-8901";PHP
function validate_phone($num) { $num = preg_replace("/[^x0-9]/",'',$num); $num = preg_replace("/^1/",'',$num); $regx = "/^([2-9][0-8][0-9])([2-9][0-9]{2})([0-9]{4})x?([0-9]{1,})?$/"; $match = preg_match($regx, $num, $m); if($match) { return "(".$m[1].")".$m[2]."-".$m[3].($m[4]?" x".$m[4]:""); } return false; }
Javascript
function validate_phone(num) { num = num.replace(/[^x0-9]/g,'') num = num.replace(/^1/,''); var regx = /^([2-9][0-8][0-9])([2-9][0-9]{2})([0-9]{4})x?([0-9]{1,})?$/; var m = num.match(regx); if(m) { return "("+m[1]+")"+m[2]+"-"+m[3]+(m[4]!=undefined?' x'+m[4]:''); } return false; }
Lazy Eye Tracking
Anyone who does any sort of design for a living has honed an awareness of the way their attention moves across a medium. The behavior depicted in this commercial is absolutely nonsensical to anyone who does interface design.
People don’t navigate an interface by staring at the tabs and clicking blindly around the screen.
Two monks on a pilgrimage
Two monks on a pilgrimage are walking along a road and they come across a 17 year old girl with a long kimono trying to cross a very muddy road but she’s not daring to step into the mud so the first monk picks her up and carries her across the road and puts her down on the other side of the road and the monks walk on in noble silence.
4 or 5 hours pass and they are nearing their destination and the second monk turns to the first and says “you know you shouldn’t have done that because us monks are not supposed even to touch women so you shouldn’t have picked up that girl. You’re not supposed to do that.” In response the first monk says “Oh, are you still carrying that girl? I put her down hours ago.”
The second monk was still carrying the girl, the event, in his head, and for 4 hours he was walking with this burden. This shows the human mind’s reluctance to let go of the past. It’s like carrying a useless weight around with you, and some people carry it all their lives, and they even derive some identity from that.
Release your identity and become one with the true formless nature of your self.
</wisdom>
Happy 2010-04-20
Asynchronous HTTP requests in PHP
Fire an HTTP request at a URL and move on without waiting for a response.
function http_async($method, $host, $url, $data) { $query = http_build_query($data); $request = "$method $url HTTP/1.1\r\n" ."HOST: $host\r\n" ."Content-type: application/x-www-form-urlencoded"."\r\n" ."Content-Length: ".strlen($query)."\r\n" ."Connection: Close\r\n\r\n" .$query; $fp = fsockopen($host, 80, $errno, $errstr, 5); fwrite($fp, $request); fclose($fp); }
And don’t forget to ignore_user_abort(true); on the target url.
Meth – A global helper function
I use functions like this a lot during development. I tuck them into a prepend file so they’re only available on my local machine. My first was shout()
function shout() { echo "<pre>"; foreach(func_get_args() as $var) { print_r($var); } echo "<\/pre>"; # (sic) die(); }
Great for looking at data.
But I very often found myself wanting to see the API for an object without having to look it up. So I wrote meth()
function meth($obj, $method_name = null) { $ref = new ReflectionClass($obj); echo "<pre>"; foreach ($ref->getMethods() as $method) { if(!$method_name || $method_name == $method->name) { echo $method; } } echo "<\/pre>"; # (sic) die(); } meth($this->Session, 'read'); # /** # * Used to read a session values for a key or return values for all keys. # * # * In your controller: $this->Session->read('Controller.sessKey'); # * Calling the method without a param will return all session vars # * # * @param string $name the name of the session key you want to read # * @return mixed value from the session vars # * @access public # */ # Method [ public method read ] { # @@ C:\web\kbya\dev\src\cake\libs\controller\components\session.php 150 - 156 # # - Parameters [1] { # Parameter #0 [ $name = NULL ] # } # }
Pretty handy so far.
Oh ya, and here’s the VHost line
php_value auto_prepend_file "/home/kev/web/prepend.php"The Anorexic Startup
The term Lean Startup has become a battle cry against the archetype of the ego-pumping dot-com executive flexing his Web 2.0 buzz words at an audience of Venture Capitalists and PR mavens. It has come to represent the antithesis of the multi-million dollar hail mary. But is this sense of the word really accurate?
The lean startup movement is essentially just a collection of interlocking disciplines, but the term `lean startup` has taken on this second meaning far from its roots in lean manufacturing and lean software development. To qualify a startup as `lean` now often implies that said startup operates with a heightened measure of scrutiny over its self-image.
The greatest truth the wisest man will ever know is that he knows nothing. That’s the heart of lean.
- Think of something you can’t already do.
- Write a test.
- Fulfill the test.
- Release the code.
- Engage your audience.
- Distill their feedback.
- GOTO 2.
The only difference between Agile Software Development and a Lean Startup is 5 and 6.
Agile Manufacturing iterates on the efficiency of the production system as a whole through Process Engineering.
Agile Software Development iterates on the structure of the software as a whole through Software Engineering.
Lean Startups iterate on the product offering itself through Customer Development Engineering.
It is entirely possible to practice agile software development within a non-agile organization, but it is much much harder to practice non-agile methodologies within an agile organization. The cycle times of a lean startup’s release and discovery schedule are just too short for waterfall project plans. Like trying to trim a bonzai with a riding lawn mower.
For this reason, taking a company lean requires the cooperation of everyone involved. The smaller the organization, the easier it is to keep everyone in flow. You probably won’t see anyone throwing around the term Lean Enterprise any time soon.
But does this necessarily mean that a Lean Startup’s small size leaves it afflicted with a neurosis of diminished optimism?
I would say that it does not.
I would say that a Lean Startup is a startup with a realistic understanding of the current and potential viability of its product, achieved through an unyielding acceptance of uncertainty.
CakePHP session error : User-Agent must be consistent
I noticed some erratic behavior with CakePHP sessions and finally tracked down the error. I have FireBug installed with an extension called FirePHP. When FireBug is enabled, I noticed that my User-Agent tends to vary.
Sometimes my browser’s user agent reads :
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 FirePHP/0.4
Sometimes it reads :
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8
Whenever the User-Agent changes, CakePHP resets the session. This means that I can’t view 3-4 pages on the site before being logged out.
This is the firebug extension that caused the problem.
https://addons.mozilla.org/en-US/firefox/addon/6149
Here’s a link to an error report on FirePHP’s forums
http://n2.nabble.com/FirePHP-and-CakePHP-Session-Reset-tp4671294ef842658.html
This is a great add-on called HTTPFox I used to track down this error.
https://addons.mozilla.org/en-US/firefox/addon/6647
php memcache vs memcached
The newer memcached PHP extension was created recently by some guys at Digg.
It has some new features and performance enhancements.
Here’s a comparison
http://code.google.com/p/memcached/wiki/PHPClientComparison
But, the interface is not identical.
We’re going with memcache over memcached for it’s guaranteed backward compatibility.
The newer memcached has some additional features that I’m not really interested in.
If I had to worry about supporting over 10,000 daily uniques, it might be a different story.
Network Solutions Wildcard SSL Certificate
If you’re thinking of buying a Wildcard SSL Certificate from Network Solutions, beware it will not be valid for the base domain.
Your $400 SSL Certificate will cover
https://www.example.com https://abc.example.com https://whatever.example.com
But it will not cover
https://example.com
If you want SSL on example.com, you will have to buy ANOTHER SSL Certificate ($150).
I couldn’t find this fact mentioned anywhere on the Network Solutions website.
I had to call their 800 number to get an answer.
Note that some registrars do cover the base domain with their Wildcard SSL Certificates (like GoDaddy).
Not all SSL Certificates are created equal.
Multiple Arguments
In real life, I’m not a fan of arguments.
But sometimes in code, arguments can be a good thing.
function addFailure($id) { $query = "insert into billing_history (id, auth_success) values($id, 0)"; mysql_query($query) or die(mysql_error()); } function addSuccess($id) { $query = "insert into billing_history (id, auth_success) values($id, 1)"; mysql_query($query) or die(mysql_error()); }
Sometimes 1 function with 2 arguments is better than 2 functions with 1 argument.
function billing_history_create($id, $success) { $query = "insert into billing_history (id, auth_success) values($id, $success)"; mysql_query($query) or die(mysql_error()); }
Comments(0)