<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8573056240198184825</id><updated>2012-03-01T05:35:19.424-08:00</updated><category term='linux'/><category term='woops'/><category term='Stemming'/><category term='flash'/><category term='opencv'/><category term='tcpdump'/><category term='tools'/><category term='sysadmin'/><category term='javascript'/><category term='SQL'/><category term='CSS'/><category term='C'/><category term='programming'/><category term='politics'/><category term='perl'/><category term='piracy'/><category term='ssh'/><category term='80s'/><category term='youtube'/><category term='JS'/><category term='analytics'/><category term='philosophy'/><category term='Challenge'/><category term='mtv'/><category term='stupidity'/><category term='logo'/><category term='PHP'/><category term='getting a job'/><category term='yt'/><category term='python'/><category term='steve jobs'/><category term='software'/><category term='Gingerbread Droid X'/><category term='craigslist'/><category term='imagemagick'/><category term='IR'/><category term='fail'/><category term='JSON'/><category term='scripts'/><category term='database'/><title type='text'>kristopolous</title><subtitle type='html'>Programming, et al.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>52</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-1595661431120256609</id><published>2012-01-26T12:28:00.000-08:00</published><updated>2012-01-26T12:43:37.545-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>The Transcendance of Empathy</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;span style="font-size:180%;"&gt;Does this offend you?&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;a href="http://i.imgur.com/s8Eh3.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 468px; height: 377px;" src="http://i.imgur.com/s8Eh3.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;Awesome. &lt;/span&gt;Just don't shoot the messenger. Here's what that message is:&lt;br /&gt;&lt;/div&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 15);ButtonMouseDown(this);" class="" style="display: block;" id="formatbar_InsertOrderedList" title="Numbered List"&gt;&lt;/span&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;Tacit dissapproval of &lt;a href="http://kara.allthingsd.com/files/2009/10/applethink-gandhi.jpg"&gt;Apple's advertising&lt;/a&gt;. Apple has co-opted the greatest thinkers of the 20th century, in public domain images, to peddle electronics. To illustrate the true horror of the campaign, Mother Teresa is directly, as opposed to Apple's preferred implicitly, saying "I approve of my image being used to sell plastic stuff from China."&lt;/li&gt;&lt;li&gt;When you mouth the words, "I Approve", and look at the image, you are reminded of The Culture of Consumption, especially of excess, which is Apple's modus operandi. It means that ones excess income, which is, after all, excess by definition, goes to luxury items with full knowledge of global starvation. In so doing, you are an indirect deciding factor in people going to sleep hungry and Part of the Problem.&lt;/li&gt;&lt;li&gt;The iPad being coveted by Mother Teresa is supposed to show the line between humans and the possessions we have and how we decide to take on the responsibilities and time commitment of things and not people.&lt;/li&gt;&lt;li&gt;The real child in her arms being the background  to the iPad emits a feeling that this could easily be your child, but isn't and how the notion of those that one cares for is a fleeting subjective game, crass, and indifferent.&lt;/li&gt;&lt;/ol&gt;This is the transcendence of empathy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-1595661431120256609?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/1595661431120256609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2012/01/transcendance-of-empathy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1595661431120256609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1595661431120256609'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2012/01/transcendance-of-empathy.html' title='The Transcendance of Empathy'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-6060258588142105093</id><published>2012-01-19T11:28:00.000-08:00</published><updated>2012-01-19T11:29:31.557-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='80s'/><category scheme='http://www.blogger.com/atom/ns#' term='mtv'/><title type='text'>80s mtv</title><content type='html'>my new project, &lt;a href="http://80smtv.com"&gt;80s mtv&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-6060258588142105093?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/6060258588142105093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2012/01/80s-mtv.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6060258588142105093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6060258588142105093'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2012/01/80s-mtv.html' title='80s mtv'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-867273390113559042</id><published>2012-01-18T18:27:00.000-08:00</published><updated>2012-01-18T20:31:12.335-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='piracy'/><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>Don't Pay For Content</title><content type='html'>&lt;span style="font-size:130%;"&gt;They Don't Deserve Your Money&lt;/span&gt;&lt;br /&gt;Content providers do not trust you. They bully you into complying with a narrow view of acceptable use, shackling you to the glacial pace of policy-making.&lt;br /&gt;&lt;br /&gt;They do not offer any of the confidence, security, or assurance that you have come to expect in return for your money.&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Their are &lt;a href="http://www.bhphotovideo.com/c/product/735592-REG/Coby_MP757_16G_MP757_16GB_2_4_Touch_Pad.html"&gt;$60 devices that store 6,000 songs&lt;/a&gt;. At $1 per song, this $60 device can store $6,000 of content. It is easily stolen or lost and the songs can be deactivated at any time, for any reason.&lt;br /&gt;&lt;br /&gt;This is like paying $6,000 for a highly-delicate, non-refundable, non-replaceable $6,000 "money card" that you are supposed to carry around everywhere and hope you don't drop it, damage it, or forget it. And oh yeah, the balance can be decreased arbitrarily without notice.&lt;br /&gt;&lt;br /&gt;Sounds stupid, right?&lt;br /&gt;&lt;br /&gt;It is, and that's the best deal they offer. You'll probably pony up for the same thing multiple times. Sounds like a sweetheart deal for them, doesn't it? That's right, say it with me:&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;They Are Scamming You&lt;/span&gt;&lt;br /&gt;They want you to pay for a restricted license to play a downloaded file that can be remotely deleted at any time. Then, if you lose it and want another copy, they will act like they have no record that you already paid them for it; as if an accounting system is some technically insurmountable pipe dream. That's stupid, they already have every purchase on file and have probably already sold your data ten times over.&lt;br /&gt;&lt;br /&gt;Really, they are lying to you and are just looking for an excuse to charge you money.&lt;br /&gt;&lt;br /&gt;You should not be doing business with someone like that, who fundamentally mistrusts you and is not willing to give you control of what you pay for. So because the content provider no longer trusts you, you must no longer trust them.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;The Old Way&lt;/span&gt;&lt;br /&gt;This wasn't always this case.  15 years ago, if you purchased an audio CD, you were permitted the following:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The right to duplicate and convert.&lt;br /&gt;You could copy the CD onto a cassette or CD-R for personal use and archiving.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The right to device agnosticism.&lt;br /&gt;That CD would work in your car, handheld player, boombox, and home stereo system. They were not keyed to a class of system and were fundamentally generic.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The ad-free right.&lt;br /&gt;As a quid-pro-quo for your money, you could enjoy the CD without arbitrary advertisements.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The right of merchantability.&lt;br /&gt;If you mailed in a damaged CD in case, many record labels would send you a new copy for a nominal fee, ensuring you that you wouldn't have to double-pay to re-access what you already purchased.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The right of satisfaction.&lt;br /&gt;Many music stores permitted you to listen to the entire CD in the store prior to purchase or even return it if you simply didn't enjoy it.&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size:130%;"&gt;You Get Nothing For Your Money&lt;/span&gt;&lt;br /&gt;In the digital age, all of these rights will ideally (in the eyes of the provider), be removed; because there is a fundamental culture of distrust.&lt;br /&gt;&lt;br /&gt;Fortunately, there is still one mechanism that guarantees you such rights.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Piracy Is The Answer&lt;/span&gt;&lt;br /&gt;Piracy gives you the consumer confidence you have become accustomed to in the 90s that the content provider refuses to offer in the internet age:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You can backup the content freely in the way of your choosing.&lt;/li&gt;&lt;li&gt;You can enjoy the content on future technology or any existing one.&lt;/li&gt;&lt;li&gt;The content is pure and functional. It comes without restrictions or advertising.&lt;/li&gt;&lt;li&gt;The content is readily replaceable.&lt;/li&gt;&lt;li&gt;If you are not satisfied, you can revoke ownership of it without any fear of an unrecoverable monetary loss.&lt;/li&gt;&lt;/ol&gt;Until the content providers give you the same guarantees in the digital age that they gave in the physical one, they will not be offering a product worthy of your time or money so there is no reason to give them any of it.&lt;br /&gt;&lt;br /&gt;So, for a product you can trust in, become a Pirate today.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-867273390113559042?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/867273390113559042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2012/01/why-pirate.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/867273390113559042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/867273390113559042'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2012/01/why-pirate.html' title='Don&apos;t Pay For Content'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-2758983638928226666</id><published>2011-12-30T15:55:00.000-08:00</published><updated>2011-12-30T17:22:48.541-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='flash'/><title type='text'>Flash Sucks</title><content type='html'>&lt;div class="usertext-body"&gt;&lt;div class="md"&gt;&lt;p&gt;But where is the   alternative to the write-once run-anywhere platform that has a rich UI   toolkit, is installed on almost all machines ... what? Java you say? Really, come now; Loading anything in Java in the browser feels like I'm   booting up a Virtual Machine. What about Silverlight? No, not that   either.  &lt;/p&gt;  &lt;p&gt;Standards you say? Ok, let's roll. You can do most of what Flash does with:&lt;/p&gt;  &lt;ol&gt;&lt;li&gt;CSS3&lt;/li&gt;&lt;li&gt;HTML Video&lt;/li&gt;&lt;li&gt;WebGL&lt;/li&gt;&lt;li&gt;Adaptive Bitrate Streaming (&lt;a href="http://en.wikipedia.org/wiki/HTTP_Live_Streaming" rel="nofollow"&gt;progress&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;HTML Canvas&lt;/li&gt;&lt;li&gt;Imaginary Partial Loading Support That Doesn't Exist (maybe the partially supported &amp;lt;script defer="defer"&amp;gt;)&lt;/li&gt;&lt;li&gt;SVG&lt;/li&gt;&lt;li&gt;&lt;a href="http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/flashplayer/pdfs/flash_player_10_security.pdf" rel="nofollow"&gt;The Imaginary Sandboxing for Separation of Applications standard&lt;/a&gt;&lt;/li&gt;&lt;li&gt;HTML Audio&lt;/li&gt;&lt;li&gt;HTTPS&lt;/li&gt;&lt;li&gt;WebSockets&lt;/li&gt;&lt;li&gt;Imaginary Crossdomain.xml Equivalent That Doesn't Exist&lt;/li&gt;&lt;li&gt;LocalStorage&lt;/li&gt;&lt;li&gt;ECMAScript 5&lt;br /&gt;&lt;/li&gt;&lt;li&gt;IndexedDB&lt;/li&gt;&lt;/ol&gt;  &lt;p&gt;And even if you got the imaginary things working and the drafts finalized you still need a solution that&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;Works on all major platforms&lt;/li&gt;&lt;li&gt;Works on all major browsers&lt;/li&gt;&lt;li&gt;Has no nuanced implementation details&lt;/li&gt;&lt;li&gt;Has non-conflicting, non-ambiguous standards&lt;/li&gt;&lt;li&gt;Is well understood&lt;/li&gt;&lt;li&gt;Has a usable IDE for graphic designers&lt;/li&gt;&lt;li&gt;Has a wide, cheap, coder base.&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;Flash  does this. In fact, I had streaming, synchronized, animation  and audio  in 1996, on Netscape 2.0, on a Pentium 1 @ 120Mhz with 16MB of  RAM, on  a 28.8Kbps connection, on Windows 95.  All I had to do was  download a  160KB add-on and restart my browser; back before DOM 0, and when the W3C was moving from SGML to the fancy new "XML" standard.&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;A decade and a half later, going to the &lt;a href="http://www.optimum7.com/css3-man/" rel="nofollow"&gt;CSS3 equivalent&lt;/a&gt;   I have to carefully choose the browser, then see my cpu hosed  and still have frame drop, have audio sync problems, and have  to load  ALL of it before seeing ANY of it.&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;The Flash hate is  totally misplaced. What they have done is  absolutely phenomenal. I'm  sorry that you see teeth whitening ads and  porno site popups with it,  but don't blame the technologists; that's like blaming Honda Of Japan because some asshole cut you off on the Freeway.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;And besides, what will the ad-haters use in this future world of 2022? Some amalgamated FlashBlock equivalent that can easily just turn off all the annoying stuff? This line will be blurred and it won't be possible.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Adobe has done, and continues to do  what Microsoft Failed at,  what Apple Failed at, what Sun Failed at, and  what Google is almost,  but not quite, succeeding in, decades later.&lt;/p&gt; &lt;/div&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-2758983638928226666?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/2758983638928226666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/12/flash-sucks.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/2758983638928226666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/2758983638928226666'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/12/flash-sucks.html' title='Flash Sucks'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-6855759735739914543</id><published>2011-11-27T19:47:00.000-08:00</published><updated>2011-12-07T21:12:38.475-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fail'/><category scheme='http://www.blogger.com/atom/ns#' term='woops'/><category scheme='http://www.blogger.com/atom/ns#' term='logo'/><title type='text'>What a Nice Logo you have, Where Did You Find it?</title><content type='html'>The small record label &lt;a href="http://www.facebook.com/balancealliance"&gt;Balance Underground (or Alliance)&lt;/a&gt; has apparently lifted the &lt;a href="http://andystechblog.files.wordpress.com/2011/06/debian-logo.jpg"&gt;Debian swirl&lt;/a&gt; as their logo for the past few years (&lt;a href="http://www.debian.org/logos/"&gt;actually legal&lt;/a&gt;, but only if the jackets have a disclaimer). It's a sub-label of another swirly label called &lt;a href="http://www.discogs.com/label/Balance"&gt;Balance Recordings&lt;/a&gt; that appears to have different artwork.&lt;br /&gt;&lt;br /&gt;&lt;sub&gt;Apparently they were also Spelling-Bee Champions.&lt;/sub&gt;&lt;br /&gt;&lt;a href=http://www.discogs.com/label/Balance+Alliance&gt;&lt;img src="http://s.dsimg.com/image/L-150-144485-1247756854.jpeg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;img style="width:260px" src="http://andystechblog.files.wordpress.com/2011/06/debian-logo.jpg" /&gt;&lt;br /&gt;&lt;br /&gt;Here's some releases, most of them link back to discogs; the ones at the bottom are from their Facebook page.&lt;br /&gt;&lt;a href="http://www.discogs.com/Various-Balance-Essentials-EP-Volume-1/release/1841959"&gt;&lt;img src="http://s.dsimg.com/image/R-1841959-1247153522.jpeg" /&gt;&lt;/a&gt;&lt;a href="http://www.discogs.com/Jeremiah-Feat-Vusa-Mkhaya-Balance-Alliance-Special-Edition/release/2266873"&gt;&lt;img style="display:inline" src="http://s.dsimg.com/image/R-150-2266873-1275818354.jpeg" /&gt;&lt;/a&gt;&lt;a href="http://www.discogs.com/Brawther-Untitled/master/293816"&gt;&lt;img style="display:inline" src="http://s.dsimg.com/image/R-150-1768280-1245054188.jpeg" /&gt;&lt;/a&gt;&lt;a href="http://www.discogs.com/Joint-Movement-Project-Find-A-Love/release/2303111"&gt;&lt;img src="http://s.dsimg.com/image/R-150-2303111-1316536710.jpeg" /&gt;&lt;/a&gt;&lt;a href="http://www.discogs.com/Various-Untitled/master/297335"&gt;&lt;img style="display:inline" src="http://s.dsimg.com/image/R-150-2244792-1272018657.jpeg" /&gt;&lt;/a&gt;&lt;a href="http://www.discogs.com/Brawther-Untitled/release/2951136"&gt;&lt;img style="display:inline" src="http://s.dsimg.com/image/R-150-2951136-1308781096.jpeg" /&gt;&lt;/a&gt;&lt;a href="http://www.discogs.com/Saint-Sebastian-Wipe-The-Needle-Life/release/2607163"&gt;&lt;img style="display:inline" src="http://s.dsimg.com/image/R-150-2607163-1316536975.jpeg" /&gt;&lt;/a&gt;&lt;a href="http://www.discogs.com/Jay-Robertson-Me-Realizo/master/344222"&gt;&lt;img style="display:inline" src="http://s.dsimg.com/image/R-150-2463550-1286227977.jpeg" /&gt;&lt;/a&gt;&lt;a href="http://www.discogs.com/Various-Isaev-Cutout-Classics-Volume-Three/release/2824375"&gt;&lt;img src="http://s.dsimg.com/image/R-150-2824375-1302717041.jpeg" /&gt;&lt;/a&gt;&lt;a href=http://www.youtube.com/watch?v=HwU9ueGTT7g&amp;feature=related&gt;&lt;img style=width:150px src=http://i1.ytimg.com/vi/HwU9ueGTT7g/default.jpg&gt;&lt;/a&gt;&lt;img style=width:150px src=http://a8.sphotos.ak.fbcdn.net/hphotos-ak-snc4/34814_10150101863957814_306308832813_7757148_1731702_n.jpg&gt;&lt;img style=width:150px src=http://a4.sphotos.ak.fbcdn.net/hphotos-ak-ash2/29860_423851837813_306308832813_5750316_4209108_n.jpg&gt;&lt;img style=width:150px    src=http://a1.sphotos.ak.fbcdn.net/hphotos-ak-ash4/248650_10150284591942814_306308832813_9414866_6770676_n.jpg&gt;&lt;img style=width:150px src=http://a2.sphotos.ak.fbcdn.net/hphotos-ak-snc6/215183_10150218088582814_306308832813_8795234_5756677_n.jpg&gt;&lt;img style=width:150px src=http://photos-d.ak.fbcdn.net/hphotos-ak-snc6/168312_10150142196897814_306308832813_8382499_7349296_a.jpg&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;About the author&lt;/b&gt;&lt;br /&gt;&lt;a href=http://qaa.ath.cx/&gt;Chris Mckenzie&lt;/a&gt; writes &lt;a href=https://github.com/kristopolous&gt;Free software&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Edit 1:&lt;/b&gt; The Debian swirl appears to be &lt;a href=http://lists.debian.org/debian-legal/2010/12/msg00015.html&gt;trivial to construct&lt;/a&gt; and has been used by &lt;a href=http://i.imgur.com/gFKfs.jpg&gt;other organizations&lt;/a&gt;.&lt;br /&gt;&lt;b&gt;Edit 2:&lt;/b&gt; A representative from the organization in question has some replies below concerning the logo! :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-6855759735739914543?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/6855759735739914543/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/11/what-nice-logo.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6855759735739914543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6855759735739914543'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/11/what-nice-logo.html' title='What a Nice Logo you have, Where Did You Find it?'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-8293735913815710852</id><published>2011-11-23T13:49:00.000-08:00</published><updated>2011-11-23T14:00:47.844-08:00</updated><title type='text'>Augmented Wiki Model</title><content type='html'>&lt;h1&gt;Augmented Wiki Model&lt;/h1&gt;  &lt;h2&gt;Statement of problem&lt;/h2&gt; &lt;p&gt; An artifact of the traditional wiki model is that malice, bias, and  fiction (un-valued content) can masquerade itself as factual information.   The mechanisms deployed to prevent this; banning users, protecting,  and locking pages each require manual intervention by a member of a privileged group of users. &lt;/p&gt; &lt;h2&gt;Objective&lt;/h2&gt;  &lt;p&gt; To minimize the amount of un-valued content on a wiki by augmentation of the wiki model.&lt;br /&gt;&lt;/p&gt;&lt;h3&gt;Assumptions&lt;/h3&gt; &lt;ol&gt;&lt;li&gt; The value of a user's recent contributions can be used to predict the value of a user's contributions in the near future. &lt;/li&gt;&lt;li&gt;The value of a page of content currently to a wiki community can be used  to predict the value of the content in the future under a certain  guideline (outlined below). &lt;/li&gt;&lt;/ol&gt;  &lt;h3&gt;Methodology&lt;/h3&gt; Given the above axiomatic assumptions, I propose to augment the wiki model as follows: &lt;p&gt; &lt;/p&gt;&lt;ol&gt;&lt;li&gt;Assign a variable to every user and to every page.&lt;/li&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The user variable will be called the "integrity" of the user and be a signed number starting at 0.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The page variable will be called the "value" of the page and be a signed number starting at 0.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;li&gt;Every user will be allowed to state a fully retractable, single "+1"  "0" or "-1" on another user's or page's value. In theory this will  create the following:&lt;/li&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The value of the user's contributions will be directly reflected by  the sum of the value of their integrity, assigned by other users.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The value of the page's content will be directly reflected by the sum of the value of the page, assigned by users.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;li&gt;Under the above constraints, the following limitations, that by assertion preserve the spirit of the wiki, can be imposed:&lt;/li&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;There will be two types of edits: moderated, and un-moderated.&lt;/li&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Moderated edits&lt;/li&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Another user has to approve the edit&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Any edit where a user's integrity is less than a page's value becomes a moderated edit&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Only users whose integrity is greater than or equal to the value of the page can approve an edit queued for moderation&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;li&gt;Un-moderated edits&lt;/li&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;An edit that does not need approval.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Any edit where a user's integrity is greater than or equal to the value of the page becomes an un-moderated edit&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;li&gt;Furthermore, the following safeguards will be used&lt;/li&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Since certain accounts will now be of more value than others, hijacking will become a problem.&lt;/li&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A user's integrity will only be viewable by a user with more integrity.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Page values will always be viewable.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Only a user with an integrity greater than or equal to the a  page's value can view the queue for moderation with the exception of&lt;/li&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A user who submitted an edit for moderation can purge their submission from the queue&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;li&gt;The history of a page will not reveal to a user with insufficient integrity which edits were moderated and which edits were not&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Since people can gain integrity through deceit, and then only  disclose malicious intent after accumulation of power, any vote placed  upon a user or a page is fully retractable.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;/ol&gt; &lt;p&gt;&lt;/p&gt; &lt;h3&gt;Hypothesis 1&lt;/h3&gt; &lt;p&gt; Under the augmented wiki model as proposed above, the quantity of un-valued content on a wiki will decrease.  &lt;/p&gt; &lt;h3&gt;Hypothesis 2&lt;/h3&gt; &lt;p&gt; The augmented wiki model as proposed above eliminates the need for the  traditional manual protection mechanisms employed to prevent un-valued  content being committed. &lt;/p&gt; &lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-8293735913815710852?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/8293735913815710852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/11/augmented-wiki-model.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/8293735913815710852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/8293735913815710852'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/11/augmented-wiki-model.html' title='Augmented Wiki Model'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-5909344028471540547</id><published>2011-11-11T20:22:00.000-08:00</published><updated>2011-11-14T13:52:45.171-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>The winners are: Opera, IE, Firefox, Chrome, Safari; in that order.</title><content type='html'>This is a response to a &lt;a href=http://www.reddit.com/r/programming/comments/m7qj8/ie_10_is_the_most_standardscompliant_js_browser/&gt;contentious blog entry&lt;/a&gt; I wrote &lt;a href=http://kristopolous.blogspot.com/2011/11/acid3-of-js-has-few-surprises.html&gt;two days ago&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;In under 36 hours, a lot has changed:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ECMAscript.org has updated their tests&lt;/li&gt;&lt;li&gt;Opera 12 Alpha is out.&lt;/li&gt;&lt;li&gt;Firefox 10 Alpha is out.&lt;/li&gt;&lt;/ul&gt;Also, many said I didn't give Opera a fair shake. So now the beta and alpha builds have been included.&lt;br /&gt;&lt;br /&gt;Here's the updated (2011-11-11) results. Each browser's data is compressed with bzip2.&lt;br /&gt;&lt;table border="1" cellpadding="5" cellspacing="1"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Browser&lt;/th&gt;&lt;th&gt;Fails&lt;/th&gt;&lt;th&gt;The photo&lt;/th&gt;&lt;th&gt;The data&lt;/th&gt;&lt;th&gt;Release Status&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="border:0;;box-shadow:0;padding:0;vertical-align:middle;margin:0 6px 0 0" src=http://qaa.ath.cx/jstest/icon-opera.png&gt;Opera 11.60 beta 1147&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/747B6.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.iizuu.com/111111-jstest/111111-opera-1160-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Beta&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="border:0;margin:0 6px 0 0;box-shadow:0;padding:0;vertical-align:middle;" src=http://qaa.ath.cx/jstest/icon-ie.png&gt;IE 10 10.0.8102.0&lt;/td&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/VDSGM.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.iizuu.com/111111-jstest/111111-ie-10-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Alpha&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="border:0;margin:0 6px 0 0;box-shadow:0;padding:0;vertical-align:middle;" src=http://qaa.ath.cx/jstest/icon-opera.png&gt;Opera 12.00 alpha 1116&lt;/td&gt;&lt;td&gt;11&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/bkJWU.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.iizuu.com/111111-jstest/111111-opera-1200-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Alpha&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="border:0;margin:0 6px 0 0;box-shadow:0;padding:0;vertical-align:middle;" src=http://qaa.ath.cx/jstest/icon-firefox.png&gt;Firefox 10.0a2 2011-11-11&lt;/td&gt;&lt;td&gt;160&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/Eo8ne.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.iizuu.com/111111-jstest/111111-firefox-10-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Alpha&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="border:0;margin:0 6px 0 0;box-shadow:0;padding:0;vertical-align:middle;" src=http://qaa.ath.cx/jstest/icon-firefox.png&gt;Firefox 9.0&lt;/td&gt;&lt;td&gt;164&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/TtEhD.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.iizuu.com/111111-jstest/111111-firefox-9-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Beta&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="border:0;margin:0 6px 0 0;box-shadow:0;padding:0;vertical-align:middle;" src=http://qaa.ath.cx/jstest/icon-firefox.png&gt;Firefox 8.0&lt;/td&gt;&lt;td&gt;164&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/SEaMM.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.iizuu.com/111111-jstest/111111-firefox-8-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Release&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="border:0;margin:0 6px 0 0;box-shadow:0;padding:0;vertical-align:middle;" src=http://qaa.ath.cx/jstest/icon-ie.png&gt;IE 9 9.0.8112.16421&lt;/td&gt;&lt;td&gt;322&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/QhAbc.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.iizuu.com/111111-jstest/111111-ie-9-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Release&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="border:0;margin:0 6px 0 0;box-shadow:0;padding:0;vertical-align:middle;" src=http://qaa.ath.cx/jstest/icon-chrome.png&gt;Chrome 17 17.0.932.0 dev-m&lt;/td&gt;&lt;td&gt;415&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/SUivE.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.iizuu.com/111111-jstest/111111-chrome-17-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Alpha&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="border:0;margin:0 6px 0 0;box-shadow:0;padding:0;vertical-align:middle;" src=http://qaa.ath.cx/jstest/icon-chrome.png&gt;Chrome 16 16.0.912.36 beta-m&lt;/td&gt;&lt;td&gt;415&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/25xYA.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.iizuu.com/111111-jstest/111111-chrome-16-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Beta&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="border:0;margin:0 6px 0 0;box-shadow:0;padding:0;vertical-align:middle;" src=http://qaa.ath.cx/jstest/icon-chrome.png&gt;Chrome 15 15.0.874.120 m&lt;/td&gt;&lt;td&gt;416&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/NYZ6g.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.iizuu.com/111111-jstest/111111-chrome-15-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Release&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="border:0;margin:0 6px 0 0;box-shadow:0;padding:0;vertical-align:middle;" src=http://qaa.ath.cx/jstest/icon-safari.png&gt;Safari 5.1.1 6534.51.22&lt;/td&gt;&lt;td&gt;772&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/LNF3i.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.iizuu.com/111111-jstest/111111-safari-5-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Release&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="border:0;margin:0 6px 0 0;box-shadow:0;padding:0;vertical-align:middle;" src=http://qaa.ath.cx/jstest/icon-opera.png&gt;Opera 11.52 1100&lt;/td&gt;&lt;td&gt;3751&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/UtLZv.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.iizuu.com/111111-jstest/111111-opera-1152-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Release&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="border:0;margin:0 6px 0 0;box-shadow:0;padding:0;vertical-align:middle;" src=http://qaa.ath.cx/jstest/icon-ie.png&gt;IE 8 8.0.6001.18702&lt;/td&gt;&lt;td&gt;N/A&lt;sup&gt;[1]&lt;/sup&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/5FnJV.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;td&gt;&lt;b&gt;Release&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;small&gt;&lt;sup&gt;1&lt;/sup&gt;The test fails to run in IE8, much like the last time. But after the error is hit, the status bar quickly goes back to saying "done". The developers tools, however, shows the error in the same place.&lt;/small&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Well, Opera wins.&lt;/b&gt; and the old becomes new again. IE10 still takes the number 2 slot with everything else staying nearly the same.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;about:&lt;/i&gt;&lt;br /&gt;&lt;small&gt;Tests were done on Windows 8, XP, and Vista; to try to main consistency.  If you want to contact the author, reply here below. The author is &lt;a href=http://qaa.ath.cx&gt;Chris McKenzie&lt;/a&gt;; a programmer dedicated to truth, no matter how crazy it gets. Check out &lt;a href=http://github.com/kristopolous&gt;his projects on github&lt;/a&gt;.&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-5909344028471540547?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/5909344028471540547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/11/winners-are-opera-ie-firefox-chrome.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/5909344028471540547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/5909344028471540547'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/11/winners-are-opera-ie-firefox-chrome.html' title='The winners are: Opera, IE, Firefox, Chrome, Safari; in that order.'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-1384791180781496082</id><published>2011-11-09T19:29:00.001-08:00</published><updated>2011-11-14T13:53:11.040-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>The Acid3 of JS has a few surprises.</title><content type='html'>&lt;b&gt;Edit:&lt;/b&gt; &lt;a href=http://kristopolous.blogspot.com/2011/11/winners-are-opera-ie-firefox-chrome.html&gt;Updated Results Are Available Here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Wikipedia has an article on a Javascript conformance test called &lt;a href="http://en.wikipedia.org/wiki/Sputnik_%28JavaScript_conformance_test%29"&gt;sputnik&lt;/a&gt; from Google.&lt;br /&gt;&lt;br /&gt;It has the results from various Desktop browsers on how standards-compliant they are.  Now I know what you are thinking, probably #1 is Chrome because the test is from Google, followed by Opera, Safari, and Firefox; with IE trailing behind in a pitiful display of brokenness.&lt;br /&gt;&lt;br /&gt;But that's not what Wikipedia shows. In fact, it shows &lt;b&gt;IE as the most standards-compliant browser&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Microsoft has quite brilliant engineers and recently they've began  to take &lt;a href="http://blogs.msdn.com/b/ie/"&gt;their browser seriously again&lt;/a&gt;, but to say that Internet Explorer has the most standards compliant JS engine? This would be &lt;a href="http://www.virtuosimedia.com/dev/css/ultimate-ie6-cheatsheet-how-to-fix-25-internet-explorer-6-bugs"&gt;quite a departure&lt;/a&gt; from &lt;a href="http://www.enhanceie.com/ie/bugs.asp"&gt;history&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I needed to verify these results, for my own sanity.&lt;br /&gt;&lt;br /&gt;According to Wikipedia, the test has changed hands and is now hosted at &lt;a href="http://test262.ecmascript.org/"&gt;test262.ecmascript.org&lt;/a&gt;. You can go there now, it's on a domain registered &lt;a href="http://qaa.ath.cx/jstest/ecmascript.org.txt"&gt;by Mozilla Corporation&lt;/a&gt;. So this doesn't look like &lt;a href="http://linux.slashdot.org/story/05/02/17/1616232/Study-Finds-Windows-More-Secure-Than-Linux"&gt;some wonky unfair comparison&lt;/a&gt; that almost looks to be designed to make Microsoft look good. Let's get questions of legitimacy out of the way.&lt;br /&gt;&lt;br /&gt;Here's the updated (2011-11-09) results. Each browser's data is compressed with bzip2.&lt;br /&gt;&lt;table border="1" cellpadding="5" cellspacing="1"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Browser&lt;/th&gt;&lt;th&gt;Fails&lt;/th&gt;&lt;th&gt;The photo&lt;/th&gt;&lt;th&gt;The data&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;IE 10 10.0.8102.0&lt;/td&gt;&lt;td&gt;&lt;b&gt;6&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/Z8F1E.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://qaa.ath.cx/jstest/ie-10-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Firefox 8.0&lt;/td&gt;&lt;td&gt;164&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/GOeKV.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://qaa.ath.cx/jstest/firefox-8-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Firefox 9.0 (2011-11-08)&lt;/td&gt;&lt;td&gt;164&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/746As.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://qaa.ath.cx/jstest/firefox-9-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;IE 9 9.0.8112.16421&lt;/td&gt;&lt;td&gt;322&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/btmT5.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://qaa.ath.cx/jstest/ie-9-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Chrome 16.0.912.32 beta-m&lt;/td&gt;&lt;td&gt;415&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/0nOPU.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://qaa.ath.cx/jstest/chrome-16-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Chrome 15.0.874.106 m&lt;/td&gt;&lt;td&gt;416&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/Nbfax.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://qaa.ath.cx/jstest/chrome-15-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Opera 11.52&lt;/td&gt;&lt;td&gt;3750&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/bLy90.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://qaa.ath.cx/jstest/opera-11-results.xml.bz2"&gt;XML Results&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;IE 8 8.0.6001.18702&lt;/td&gt;&lt;td&gt;N/A&lt;sup&gt;[1]&lt;/sup&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://i.imgur.com/4vXV7.png"&gt;Screenshot&lt;/a&gt;&lt;/td&gt;&lt;td&gt;N/A&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;sup&gt;1&lt;/sup&gt;The test fails to run in IE8 and hits a Javascript error fairly early on.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;IE 10 did the best by far&lt;/span&gt;. Surprised? Me too.  The next up was Firefox. Also surprised? Yeah, here too.  Then IE 9 ... IE 9? The world is crazy sometimes.  Chrome comes in right above Opera, which basically eats shit ... that's a new one.  What has this world come to?&lt;br /&gt;&lt;br /&gt;One of the important things to note is that failures seem to happen in batches.  That is to say it's successful for a few hundred (or a few thousand) tests, then a bunch of tests fail consecutively.  Almost makes me think of that math exam you once got where questions 2-8 depended on you getting question 1 right.&lt;br /&gt;&lt;br /&gt;These tests also don't speak to how performant the browsers are on, well, anything.  Their are more factors than compliance-to-standards when it comes to providing the best web experience. Regardless, these results certainly support the on-going notion that IE is finally back in the running.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Further Work&lt;/H3&gt; I just looked at the number of failed tests; not focusing on the content of what tests failed. I'm not familiar enough (and just plain not smart enough) with the internals of ECMAScript to know whether the results warrant further investigation or concern.  I do know from my own experience that I've fallen victim to many more IE Javascript bugs then other browsers. And perhaps, that's the important thing; not whether a feature is implemented, or passes a smoke screen test, but whether the feature &lt;a href="http://msdn.microsoft.com/en-us/library/bb250448(v=vs.85).aspx"&gt;has problems&lt;/a&gt;. It would be great to hear what some of the browser developers have to say about these results.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;about:&lt;/i&gt;&lt;br /&gt;&lt;small&gt;Tests were done on Windows 8, XP, and Vista; to try to main consistency.  If you want to contact the author, reply here below. The author is &lt;a href=http://qaa.ath.cx&gt;Chris McKenzie&lt;/a&gt;; a programmer dedicated to truth, no matter how crazy it gets. Check out &lt;a href=http://github.com/kristopolous&gt;his projects on github&lt;/a&gt;.&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-1384791180781496082?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/1384791180781496082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/11/acid3-of-js-has-few-surprises.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1384791180781496082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1384791180781496082'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/11/acid3-of-js-has-few-surprises.html' title='The Acid3 of JS has a few surprises.'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-4032553970170212500</id><published>2011-11-04T13:57:00.000-07:00</published><updated>2011-11-04T16:08:10.458-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>PHP? LOLZ!</title><content type='html'>First, complaints from an imagined developer:&lt;br /&gt;&lt;blockquote&gt;OMG PHP,&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You are not nerdporn. When I do my contracting as a developer, I can no longer take my fixie to the local programmers coffee shop to do work and look cool. Since I don't go out otherwise, how the hell am I going to get a girlfriend in Sunnyvale with such crap?&lt;br /&gt;&lt;/li&gt;&lt;li&gt; You are so easy to use that your community is chock full of people who can't code. Like a  business guy fooled into the idea he can skimp out on hiring one of us expensive nerds by coding that brilliant facegrouptube idea himself (with an iphone app of course, it'll make millions!). How hard can it possibly be to write a product and platform? Pshh!, piece-o-cake!&lt;br /&gt;&lt;/li&gt;&lt;li&gt; You are simply not expressive enough. My coding boner goes way flaccid when I see how not purty PHP is. When my emacs window doesn't follow the rule of thirds when looking at code I get pissed off and it makes baby jesus cry.&lt;/li&gt;&lt;/ol&gt;Sincerely,&lt;br /&gt;Programmers of the Internet.&lt;br /&gt;&lt;/blockquote&gt;With all the hate, why is it still hands down, the most popular language for websites that people actually use?&lt;br /&gt;&lt;br /&gt;Things get done when bickering pedantic coders stop caring about process and focus on  product. Picky nerd debates about refactoring, design, coding approach ... get tossed, because they are more annoyed by the environment then they are by all those lost Dr Who episodes. This speeds things up enormously (because nobody is arguing any more) and like magic, shit actually gets done.&lt;br /&gt;&lt;br /&gt;This makes PHP an extremely productive, fluff-free language.  It's not going to change any time soon and nobody is excited about it; people don't assemble in church basements on a Tuesday night like narcotics addicts to talk about how awesome it is at solving all your problems.&lt;br /&gt;&lt;br /&gt;It becomes &lt;span&gt;just a tool; which is the ideal position of any language.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-4032553970170212500?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/4032553970170212500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/11/why-php.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/4032553970170212500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/4032553970170212500'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/11/why-php.html' title='PHP? LOLZ!'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-619103039343104053</id><published>2011-10-05T22:32:00.000-07:00</published><updated>2011-10-05T23:37:20.373-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='steve jobs'/><title type='text'>Americas wealthiest company put out a press release today.</title><content type='html'>&lt;div style="text-align: left;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" style="display:inline-block;vertical-align:middle" href="http://1.bp.blogspot.com/-akA8TrFD2TE/To1AxC4NJRI/AAAAAAAAAOQ/rTIR3oO1BNk/s1600/apple_shrunk.png"&gt;&lt;img style="cursor: pointer; width: 33px; height: 33px;border-radius:0;border:0;box-shadow:0 0 0 0;margin:0;padding:0" src="http://1.bp.blogspot.com/-akA8TrFD2TE/To1AxC4NJRI/AAAAAAAAAOQ/rTIR3oO1BNk/s320/apple_shrunk.png" alt="" id="BLOGGER_PHOTO_ID_5660251518004962578" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;iPhone 4S reviews weren't what we expected&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;So we pulled the plug. There will be no Jobs. No Jobs today, no Jobs tomorrow; no Jobs forever! Now go away because without Jobs, we'll never again have anything you'll want.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-619103039343104053?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/619103039343104053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/10/americas-wealthiest-company-put-out.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/619103039343104053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/619103039343104053'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/10/americas-wealthiest-company-put-out.html' title='Americas wealthiest company put out a press release today.'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-akA8TrFD2TE/To1AxC4NJRI/AAAAAAAAAOQ/rTIR3oO1BNk/s72-c/apple_shrunk.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-4337535481354928466</id><published>2011-10-03T15:06:00.000-07:00</published><updated>2011-10-04T11:19:11.883-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Gingerbread Droid X'/><title type='text'>Droid X Gingerbread Review</title><content type='html'>I "upgraded" my Motorola Droid X recently to Gingerbread:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Recording videos doesn't work. Instead my phone skillfully convinces me it's recording but then has no stop button, no way to leave the application, and stays in the video mode until I pull the battery.&lt;/li&gt;&lt;li&gt;The phone now runs hot and the battery lasts about 1/3 the time as before. Might as well carry around an assortment of extra batteries just so I can use it throughout a regular business day.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Swype now prefers really obscure words like "tutu" when I mean to type "you" and half the time fails to put a space in between words. The browser gets real confused when that happens and clears the input, not permitting me to manually add a space after I realize the mistake.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Although the experience is now shinier with gradients and catchy animations, it is effectively immaterial when applications are hanging left and right and the actual interface for major components (like marketplace) have discarded basic features and transformed themselves from applications to advertisements.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Now here's some big questions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Why is task switching still unsolved?  I need to download third party apps just to go in between two running processes. Really?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Why is task killing still so difficult? To kill a task,  Simply follow these 10 basic steps: (1) Go to the home screen, (2) Click the left button, (3) Press "Settings", (4) Scroll the menu down, (5) Press "Applications", (6) Press "Manage applications", (7) Press the "All" tab, (8) Scroll through the application list, (9) Press the menu item of the application you want to stop, (10) Press "Force stop".&lt;span style="font-style: italic;"&gt;&lt;br /&gt;What the hell is that? 10 steps to exit a program? &lt;/span&gt;&lt;span&gt;I'd hope that making this easier would be somewhat a priority.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Useful things that shouldn't have been removed&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Was moving an icon from the application list to the home screen so unbelievably hard and counterintuitive that you had to axe it and replace it with a 3 step process (which doesn't work if you have a task switcher btw)&lt;/li&gt;&lt;li&gt;What is the white gradient near the bottom of the screen? My guess is that 1 out of every 10,000 users had some phone background that was just a montage of android icons and then they went in to their carrier, complaining that they couldn't find the buttons on the interface.  It really harkens back to the old days when there was a d-pad with an "ok" button in the center wherein the default functions for the d-pad were operations that incurred a charge, like calling your voicemail or depositing money directly into your carriers bank account.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The interface is now branded everywhere with my mobile carrier.  Are they so insecure that I need to be reminded every screen in the largest letters on the screen, who I pay every month? My carrier has already opted to plaster their logo on both sides of the phone (in fact, it is etched in the back).&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Features that nobody wants&lt;/span&gt;&lt;br /&gt;When I press the home key slightly too quickly, a very slow and clunky application pops up that overrides my silent volume setting and chimes "Say a command".  I usually get here when I am trying to exit a hung application in order to go through the ten stop process to kill it.  However, I get redirected to conversation mode. I've tried "Go fuck yourself" or "Eat shit" but it just responds with "Did you say ... Call Mom?"&lt;br /&gt;&lt;br /&gt;And finally, Blockbuster. Costumers are literally going way out of their way, with the possibility of bricking their phone in order to remove their application from the default install list.  That's how bad blockbuster actually is.  People hack their phone to uninstall it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;I know how hard it is to make an Operating System; but having things like the video recorder crashing the phone should have been caught in early QA testing; a user trying swype for five minutes would notice the expansive vocabulary that the phone guesses when you are trying to say "I am outside near the gas station", and they should have noticed way early that they literally cut the phones battery life by 70% ... and then should have been like "hrmm ... let's not release this."&lt;br /&gt;&lt;br /&gt;This version is a major disappointment. It's such an important time too; Google has an opportunity to really snatch the marketshare from Apple; but it's not going to happen with crap like this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-4337535481354928466?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/4337535481354928466/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/10/droid-x-gingerbread-review.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/4337535481354928466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/4337535481354928466'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/10/droid-x-gingerbread-review.html' title='Droid X Gingerbread Review'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-7610751116054671897</id><published>2011-09-01T15:15:00.001-07:00</published><updated>2011-09-01T15:17:10.863-07:00</updated><title type='text'>Sometimes Old Ideas just need Good Execution</title><content type='html'>When ideas that have never been successful keep coming up over  and over again it's usually because they simply haven't been implemented  right and are just waiting for someone to think up the right sauce.&lt;br /&gt;&lt;br /&gt;Ambitious successful technology is usually a culmination of decades of failure. For example:&lt;br /&gt;&lt;br /&gt;1. Touch screen computing (iPad)&lt;br /&gt;2. On-demand video (YouTube, Hulu)&lt;br /&gt;3. Video phones (Skype)&lt;br /&gt;4. The all-in-one fits-in-the pocket pda/phone (Android/iPhone)&lt;br /&gt;&lt;br /&gt;If  you talked to say, a YouTube exec in 2004 about their ideas you'd  probably walk away thinking "Oh yeah, that idea; the one that has failed  so hard, so many times, that I was looking for the hidden cameras".&lt;br /&gt;&lt;br /&gt;And you'd be dead wrong.&lt;br /&gt;&lt;br /&gt;This  isn't new, if you go back 40 years you'll find that Credit Cards, Bar  Codes, ISBN numbers, the home theater, all had predecessors that sucked.  Even the personal computer and the home video game system had years of  failed starts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-7610751116054671897?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/7610751116054671897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/09/sometimes-old-ideas-just-need-good.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/7610751116054671897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/7610751116054671897'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/09/sometimes-old-ideas-just-need-good.html' title='Sometimes Old Ideas just need Good Execution'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-4244651039258055358</id><published>2011-08-29T13:07:00.000-07:00</published><updated>2011-08-29T13:18:16.317-07:00</updated><title type='text'>The Lottery Analogy</title><content type='html'>I've told you the lottery ticket analogy, right? It's really important that everyone understands this:&lt;br /&gt;&lt;br /&gt;If you want to win the lottery, you need to do something that makes that possible; in this case it's buy a ticket. But you'll probably lose and that ticket will probably be worthless. However, you cannot win the lottery without it. And who knows? You might, actually, indeed, win.&lt;br /&gt;&lt;br /&gt;Here's the rules:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You can't win without playing.&lt;/li&gt;&lt;li&gt;Every time you play, you get a new chance to win, independent of the previous chances.&lt;/li&gt;&lt;li&gt;Doing  the right thing on the wrong day is worthless. Even if you do  everything perfect and you get really lucky, there are still  externalities that will almost always snatch the victory from you. You  will then see someone doing the exact same thing as you on another day  and succeeding.&lt;/li&gt;&lt;li&gt;When you realize that you picked the right numbers on the wrong day, get over it and Play Again. Don't allow your past to paralyzed you.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You  will officially lose far before you personally know it.  Make sure you  know what failure and loss looks like and then accept it. Never fool  yourself into thinking you have a winner, acknowledge the loss and move  on as quickly as possible.&lt;/li&gt;&lt;/ol&gt;This is true in all aspects of life: you want to have a famous pop song? You need to do something that makes that possible; in this case work quite hard and make a song. But you'll probably lose. That song, will probably be listened to by nobody. However, you can't have a famous song without it.&lt;br /&gt;&lt;br /&gt;Want to be a successful author or get a good job or make money on the stock market or be a famous scientist? The same rules apply.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-4244651039258055358?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/4244651039258055358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/08/lottery-analogy.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/4244651039258055358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/4244651039258055358'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/08/lottery-analogy.html' title='The Lottery Analogy'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-1057829842791976503</id><published>2011-07-20T04:46:00.000-07:00</published><updated>2011-07-20T04:52:10.602-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='getting a job'/><title type='text'>on getting a job</title><content type='html'>&lt;span&gt;&lt;div style="font-weight: bold; "&gt;&lt;span style="font-weight:bold;"&gt;know what you can tolerate&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;if you don't think you could put up with being a sysadmin every day, don't ever apply as one; regardless of skill; you won't get the job unless you interview at a dysfunctional company that you won't want to work at.  know what role you would be willing to put up with and apply strictly for those positions.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;b&gt;getting an interview&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;resumes are important, github is more. you are pitching yourself, over email. silence isn't a problem. keep trying until someone explicitly says no.  remember you are talking to humans and not grammar professors. be cordial but formal; assertive, eager, and well-mannered.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;interviewing&lt;/span&gt;&lt;br /&gt;smile, agree with everything, answer slowly and clearly, make eye contact, laugh at their jokes, gloss over their mistakes, don't bring in any baggage, and don't worry too much.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;after the interview&lt;/span&gt;&lt;br /&gt;it's critical to send an email after about 4 but less then 24 hours later. repeat the same pleasantries.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;about pay&lt;/b&gt;&lt;br /&gt;understand what you need to leverage before it comes on the table. you should make the first offer, always. do it at the point of accepting the job after the employer has vested in you as a future employee. make it implicitly but not explicitly clear that you will quickly back out if conditions aren't met.&lt;div&gt;&lt;br /&gt;&lt;b&gt;remember why are you working&lt;/b&gt;&lt;br /&gt;most programmer I know would rather be working on their pet project (which is The Next Big Thing) full-time instead of for a company. If this is your goal, remember this at the negotiation table; 5 day work weeks, coming in around noon, leaving at 5 strictly every day; all of these accommodations are best set at this point.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-1057829842791976503?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/1057829842791976503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/07/on-getting-job.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1057829842791976503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1057829842791976503'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/07/on-getting-job.html' title='on getting a job'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-6496086458607672652</id><published>2011-05-27T13:08:00.000-07:00</published><updated>2011-05-27T23:39:38.078-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='philosophy'/><title type='text'>Abandon your cake</title><content type='html'>Pretend you spend all day making your spouse a cake.  You carefully research the ingredients and then painstakingly try to the best of your effort to do everything well.  However, it comes out slightly too brittle; the hand-made frosting is a little tart. But you spent a lot of time on it.&lt;br /&gt;&lt;br /&gt;You present the cake.  After the overjoyed response, you proceed to cut the first slice and your spouse takes the first bite, rolls the taste around, ponders a bit and very seriously states, "A bit bland, the frosting needs some work.  Let's go to the grocery store and get a better one."&lt;br /&gt;&lt;br /&gt;You are shocked.  "Let's go to the grocery store?!", you spent all day on that damned thing; the store wasn't even open when you started; there were not even cakes available for sale at the time you began.&lt;br /&gt;&lt;br /&gt;But sure, you aren't a pastry chef and you probably made a few mistakes along the way, but it's &lt;span style="font-weight:bold;"&gt;your&lt;/span&gt; cake.  You made it specifically for your spouse.&lt;br /&gt;&lt;br /&gt;But now, of all things, your spouse looks impartially at it, throws out the idea that you had anything to do with it and does some objective comparison.  The conclusion is inescapable; the store is in fact open now, and does sell better cakes than the one that you made and instead of making it yourself you probably &lt;span style="font-style:italic;"&gt;should have&lt;/span&gt; just gone out and bought one when the store opened, spending all of 20 minutes.&lt;br /&gt;&lt;br /&gt;However painful it may be, you must acknowledge that if you want to enjoy a great cake, you should toss yours in the garbage, forget about it, and grab one from off the shelf.&lt;br /&gt;&lt;br /&gt;Software is the same way.  Oftentimes you will find that a solution baked in-house by a colleague you know and respect is not as mature as one that is open source.  &lt;br /&gt;&lt;br /&gt;Sometimes although the in-house solution may predate the open source one by many years, the  open source solution appears to have raced ahead in quality, stability, and features.&lt;br /&gt;&lt;br /&gt;You know intellectually that you will get a better product if you go forward with the open source solution that is well supported and well written.  You know that you will free up the time of all parties involved. It looks like a pure business and logical decision.  It's easy to forget the fact that you are suggesting to toss out someone's handmade cake by effectively saying:&lt;blockquote&gt;Hi.  I just wanted to say that you wasted your time and your solution is inferior to something I found in 30 seconds on google.  We should be using this instead.&lt;/blockquote&gt;Breaking this news is  one of the most difficult things to do at a personnel level on any programming team. You look like the new kid tossing out personal insults, disparaging the quality of your colleagues works; suggesting that they produced inferior code that simply is not good enough to be put in any project that you want to work on.&lt;br /&gt;&lt;br /&gt;The truth is though, adopting open source (ie, off-the-shelf) components over in-house solutions can often be a leading factor in whether a project is successful and done on schedule. Off-loading as much responsibility as possible permits your team to focus on the product and not the dependencies.&lt;br /&gt;&lt;br /&gt;When you are the cake maker, this reality is a very difficult thing to accept.  "My cake is worthless?", you incredulously pout. You skeptically go over the open source project with a fine-toothed comb.  "But wait", you insist, "It can't do xyz, and I can. Ha!" or "Let's run some performance tests and see how this POS does".  &lt;br /&gt;&lt;br /&gt;However, you acknowledge that it is well done.  They are catching errors that you were too lazy to check for; they have active mailing lists and people around the world fixing bugs while you are at home sleeping. Intellectually, you know what to do:&lt;br /&gt;&lt;br /&gt;&lt;span style="margin:0;padding:0;display:block;text-align:center;"&gt;Abandon Your Cake.&lt;/span&gt;&lt;br /&gt;Implement the stuff you have that the open-source project does not and submit a patch.  Probably introduce yourself as someone who has written a similar project but has done the grief of switching over.&lt;br /&gt;&lt;br /&gt;Once you get over yourself and toss your cake away, you can hop on the winning team with enough courage and strength.  &lt;br /&gt;&lt;br /&gt;Don't look at it as if you need to match the feature-set of the project but as a collaborative project with &lt;span style="font-style:italic;"&gt;open-membership&lt;/span&gt; that you have specific expertise on. &lt;br /&gt;&lt;br /&gt;You came up with a solution to a generic problem that many people face and you learned a lot by building it out yourself.  You have a lot of knowledge to contribute. You were good enough to do the solution single-handed; you are certainly good enough to contribute to a group effort.&lt;br /&gt;&lt;br /&gt;So someone else won the internet lottery fame game this time, it happens. Go join them and you will be a valued member of their team. After a little while you will be able to faithfully consider it your project as much as any other contributor.&lt;br /&gt;&lt;br /&gt;It will be easier, you'll get more exposure, and you can claim part ownership of something that people actually &lt;span style="font-style:italic;"&gt;have&lt;/span&gt; heard of instead of filling your resume with github projects that are only watched by yourself.&lt;br /&gt;&lt;br /&gt;Sharing the fame beats pounding the pavement any day.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-6496086458607672652?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/6496086458607672652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/05/replacing-in-house-solutions-with-third.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6496086458607672652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6496086458607672652'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/05/replacing-in-house-solutions-with-third.html' title='Abandon your cake'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-442456583508689980</id><published>2011-04-17T17:18:00.000-07:00</published><updated>2011-04-17T17:19:26.208-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='fail'/><title type='text'>hold on ... even better</title><content type='html'>&lt;pre&gt;&lt;br /&gt;  if($level=="Level 1" &amp;&amp; $month=="Month 1")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 1";&lt;br /&gt;    $newMonth="Month 2";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 1" &amp;&amp; $month=="Month 2")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 1";&lt;br /&gt;    $newMonth="Month 3";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 1" &amp;&amp; $month=="Month 3")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 1";&lt;br /&gt;    $newMonth="Month 4";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 1" &amp;&amp; $month=="Month 4")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 1";&lt;br /&gt;    $newMonth="Month 5";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 1" &amp;&amp; $month=="Month 5")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 1";&lt;br /&gt;    $newMonth="Month 6";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 1" &amp;&amp; $month=="Month 6")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 2";&lt;br /&gt;    $newMonth="Month 1";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 2" &amp;&amp; $month=="Month 1")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 2";&lt;br /&gt;    $newMonth="Month 2";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 2" &amp;&amp; $month=="Month 2")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 2";&lt;br /&gt;    $newMonth="Month 3";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 2" &amp;&amp; $month=="Month 3")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 2";&lt;br /&gt;    $newMonth="Month 4";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 2" &amp;&amp; $month=="Month 4")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 2";&lt;br /&gt;    $newMonth="Month 5";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 2" &amp;&amp; $month=="Month 5")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 2";&lt;br /&gt;    $newMonth="Month 6";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 2" &amp;&amp; $month=="Month 6")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 3";&lt;br /&gt;    $newMonth="Month 1";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 3" &amp;&amp; $month=="Month 1")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 3";&lt;br /&gt;    $newMonth="Month 2";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 3" &amp;&amp; $month=="Month 2")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 3";&lt;br /&gt;    $newMonth="Month 3";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 3" &amp;&amp; $month=="Month 3")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 3";&lt;br /&gt;    $newMonth="Month 4";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 3" &amp;&amp; $month=="Month 4")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 3";&lt;br /&gt;    $newMonth="Month 5";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 3" &amp;&amp; $month=="Month 5")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 3";&lt;br /&gt;    $newMonth="Month 6";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 3" &amp;&amp; $month=="Month 6")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 4";&lt;br /&gt;    $newMonth="Month 1";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 4" &amp;&amp; $month=="Month 1")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 4";&lt;br /&gt;    $newMonth="Month 2";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 4" &amp;&amp; $month=="Month 2")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 4";&lt;br /&gt;    $newMonth="Month 3";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 4" &amp;&amp; $month=="Month 3")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 4";&lt;br /&gt;    $newMonth="Month 4";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 4" &amp;&amp; $month=="Month 4")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 4";&lt;br /&gt;    $newMonth="Month 5";&lt;br /&gt;  }&lt;br /&gt;  else if($level=="Level 4" &amp;&amp; $month=="Month 5")&lt;br /&gt;  {&lt;br /&gt;    $newLevel="Level 4";&lt;br /&gt;    $newMonth="Month 6";&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That must have taken like days or something ... I don't know if the programmer even knew about the advanced "copy" and "paste" concepts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-442456583508689980?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/442456583508689980/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/04/hold-on-even-better.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/442456583508689980'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/442456583508689980'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/04/hold-on-even-better.html' title='hold on ... even better'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-7833859132636330916</id><published>2011-04-16T22:23:00.001-07:00</published><updated>2011-04-16T22:23:40.662-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='fail'/><title type='text'>wait wait</title><content type='html'>&lt;h2&gt; I can top that (below) &lt;/h2&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  switch($month)&lt;br /&gt;  {&lt;br /&gt;    case'1':&lt;br /&gt;    $date = calculateenddate(1,$weakly,7,$unixtime);&lt;br /&gt;    break;&lt;br /&gt;    case '2':&lt;br /&gt;    $date = calculateenddate(2,$weakly,7,$unixtime);&lt;br /&gt;    break;&lt;br /&gt;    case '3':&lt;br /&gt;    $date = calculateenddate(3,$weakly,7,$unixtime);&lt;br /&gt;    break;&lt;br /&gt;    case '4':&lt;br /&gt;    $date = calculateenddate(4,$weakly,7,$unixtime);&lt;br /&gt;    break;&lt;br /&gt;    case '5':&lt;br /&gt;    $date = calculateenddate(5,$weakly,7,$unixtime);&lt;br /&gt;    break;&lt;br /&gt;    case '6':&lt;br /&gt;    $date = calculateenddate(6,$weakly,7,$unixtime);&lt;br /&gt;    break;&lt;br /&gt;    case '7':&lt;br /&gt;    $date = calculateenddate(7,$weakly,7,$unixtime);&lt;br /&gt;    break;&lt;br /&gt;    case '8':&lt;br /&gt;    $date = calculateenddate(8,$weakly,7,$unixtime);&lt;br /&gt;    break;&lt;br /&gt;    case '9':&lt;br /&gt;    $date = calculateenddate(9,$weakly,7,$unixtime);&lt;br /&gt;    break;&lt;br /&gt;    case '10':&lt;br /&gt;    $date = calculateenddate(10,$weakly,7,$unixtime);&lt;br /&gt;    break;&lt;br /&gt;    case '11':&lt;br /&gt;    $date = calculateenddate(11,$weakly,7,$unixtime);&lt;br /&gt;    break;&lt;br /&gt;    case '12':&lt;br /&gt;    $date = calculateenddate(12,$weakly,7,$unixtime);&lt;br /&gt;  }&lt;br /&gt;  return $date;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-7833859132636330916?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/7833859132636330916/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/04/wait-wait.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/7833859132636330916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/7833859132636330916'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/04/wait-wait.html' title='wait wait'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-4491726036327698362</id><published>2011-04-16T22:15:00.000-07:00</published><updated>2011-04-16T22:18:21.556-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='stupidity'/><title type='text'>What is a loop?</title><content type='html'>&lt;pre&gt;&lt;br /&gt;function duedates($programStartDate, $month, $request) {&lt;br /&gt;    if ($request == "accelarate")&lt;br /&gt;    {&lt;br /&gt;     $weakcycle = '2';&lt;br /&gt;    }&lt;br /&gt;    else if ($request == "deaccelerate")&lt;br /&gt;    {&lt;br /&gt;     $weakcycle = '4';&lt;br /&gt;    }&lt;br /&gt;    else&lt;br /&gt;    {&lt;br /&gt;     $weakcycle = '4';&lt;br /&gt;    }&lt;br /&gt;    $db = new databasemanager();&lt;br /&gt;    $unixtime = strtotime($programStartDate);&lt;br /&gt;&lt;br /&gt;    switch($month)&lt;br /&gt;    {&lt;br /&gt;     case'2':&lt;br /&gt;     $date[] = calculateenddate(1,$weakcycle,7,$unixtime);&lt;br /&gt;     break;&lt;br /&gt;     case'3':&lt;br /&gt;     $date[] = calculateenddate(1,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(2,$weakcycle,7,$unixtime);&lt;br /&gt;     break;&lt;br /&gt;     case'4':&lt;br /&gt;     $date[] = calculateenddate(1,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(2,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(3,$weakcycle,7,$unixtime);&lt;br /&gt;     break;&lt;br /&gt;     case '5':&lt;br /&gt;     $date[] = calculateenddate(1,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(2,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(3,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(4,$weakcycle,7,$unixtime);&lt;br /&gt;     break;&lt;br /&gt;     case '6':&lt;br /&gt;     $date[] = calculateenddate(1,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(2,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(3,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(4,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(5,$weakcycle,7,$unixtime);&lt;br /&gt;     break;&lt;br /&gt;     case '7':&lt;br /&gt;     $date[] = calculateenddate(1,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(2,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(3,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(4,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(5,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(6,$weakcycle,7,$unixtime);&lt;br /&gt;     break;&lt;br /&gt;     case '8':&lt;br /&gt;     $date[] = calculateenddate(1,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(2,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(3,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(4,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(5,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(6,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(7,$weakcycle,7,$unixtime);&lt;br /&gt;     break;&lt;br /&gt;     case '9':&lt;br /&gt;     $date[] = calculateenddate(1,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(2,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(3,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(4,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(5,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(6,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(7,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(8,$weakcycle,7,$unixtime);&lt;br /&gt;     break;&lt;br /&gt;     case '10':&lt;br /&gt;     $date[] = calculateenddate(1,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(2,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(3,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(4,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(5,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(6,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(7,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(8,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(9,$weakcycle,7,$unixtime);&lt;br /&gt;     break;&lt;br /&gt;     case '11':&lt;br /&gt;     $date[] = calculateenddate(1,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(2,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(3,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(4,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(5,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(6,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(7,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(8,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(9,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(10,$weakcycle,7,$unixtime);&lt;br /&gt;     break;&lt;br /&gt;     case '12':&lt;br /&gt;     $date[] = calculateenddate(1,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(2,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(3,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(4,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(5,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(6,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(7,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(8,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(9,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(10,$weakcycle,7,$unixtime);&lt;br /&gt;     $date[] = calculateenddate(11,$weakcycle,7,$unixtime);&lt;br /&gt;     break;&lt;br /&gt;    }&lt;br /&gt;    return $date;&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;&lt;br /&gt;... Solid Gold I tell you ... solid gold ....&lt;/h2&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-4491726036327698362?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/4491726036327698362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/04/what-is-loop.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/4491726036327698362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/4491726036327698362'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/04/what-is-loop.html' title='What is a loop?'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-5442707179761558592</id><published>2011-04-10T13:40:00.000-07:00</published><updated>2011-04-10T13:43:24.618-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fail'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>horrible css today</title><content type='html'>&lt;pre&gt;&lt;br /&gt; &amp;lt;div class="heading18 width250 brdrbtm padbtm_10"&amp;gt;Search for &lt;br /&gt;Trainings&amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;div class="gr10New width250 pad_top"&amp;gt;&lt;br /&gt;&amp;lt;strong class="bluetext11"&amp;gt;&lt;br /&gt;Search for Upcoming Teacher Training Programs&lt;br /&gt;&amp;lt;/strong&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;div class="pad_b3 width250 pad_top"&amp;gt;&amp;lt;strong&amp;gt;Select Level:&amp;lt;/strong&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now look what you did; you broke the internet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-5442707179761558592?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/5442707179761558592/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/04/horrible-css-today.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/5442707179761558592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/5442707179761558592'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/04/horrible-css-today.html' title='horrible css today'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-1210554418908784121</id><published>2011-04-10T10:12:00.000-07:00</published><updated>2011-04-10T10:14:06.625-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fail'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Horrible SQL</title><content type='html'>&lt;pre&gt;&lt;br /&gt;$db-&gt;query("delete from email_campain_settings where UserID='".$_POST['objID']."' and&lt;br /&gt;TagValue='Active' and TagID='free' ");&lt;br /&gt;$db-&gt;query("delete from email_campain_settings where UserID='".$_POST['objID']."' and&lt;br /&gt;TagValue='Active' and TagID='paid' ");&lt;br /&gt;$db-&gt;query("delete from email_campain_settings where UserID='".$_POST['objID']."' and&lt;br /&gt;TagValue='Active' and TagID='GOLD' ");&lt;br /&gt;$db-&gt;query("delete from email_campain_settings where UserID='".$_POST['objID']."' and&lt;br /&gt;TagValue='Active' and TagID='SILVER' ");&lt;br /&gt;$db-&gt;query("delete from email_campain_settings where UserID='".$_POST['objID']."' and&lt;br /&gt;TagValue='Active' and TagID='PLATINUM' ");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Fantastic. Just go home, ok?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-1210554418908784121?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/1210554418908784121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/04/horrible-sql.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1210554418908784121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1210554418908784121'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/04/horrible-sql.html' title='Horrible SQL'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-6265133182450576851</id><published>2011-04-08T17:31:00.001-07:00</published><updated>2011-04-08T17:31:54.575-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><title type='text'>Javascript Database</title><content type='html'>Throwing my hat into this one: A Generic &lt;a href=https://github.com/kristopolous/db.js&gt;Javascript Database&lt;/a&gt; for all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-6265133182450576851?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/6265133182450576851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/04/javascript-database.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6265133182450576851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6265133182450576851'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/04/javascript-database.html' title='Javascript Database'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-6649771483124713359</id><published>2011-03-19T16:31:00.000-07:00</published><updated>2011-03-19T16:32:01.720-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='fail'/><title type='text'>abusing php header redirect</title><content type='html'>header('location:confirm.php?error=true&amp;CN='.$_REQUEST['CNumber'].'&amp;EY='.$_REQUEST['ex&lt;br /&gt;pYear'].'&amp;EM='.$_REQUEST['expMonth'].'&amp;CHF='.$_REQUEST['CHolderFName'].'&amp;CHL='.$_REQUEST['CHolderLName'].'&amp;Cvv='.$_REQUEST['CV&lt;br /&gt;V2'].'&amp;CT='.$_REQUEST['CardType'].'&amp;Message='.$myRsMessage);&lt;br /&gt;&lt;br /&gt;Wow.  Just, wow.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-6649771483124713359?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/6649771483124713359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/03/abusing-php-header-redirect.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6649771483124713359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6649771483124713359'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/03/abusing-php-header-redirect.html' title='abusing php header redirect'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-2706841830786516644</id><published>2011-01-17T21:01:00.000-08:00</published><updated>2011-01-17T21:54:24.033-08:00</updated><title type='text'>horrible css again</title><content type='html'>&amp;lt;div class="clear"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;div class="text_center pad10"&amp;gt;- or -&amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;div class="clear"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;...&lt;br /&gt;.pad10 {&lt;br /&gt;padding:10px; &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.text_center {&lt;br /&gt;text-align:center; &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.text_right {&lt;br /&gt;text-align:right; &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.bg_white {&lt;br /&gt;background-color:white;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.show {&lt;br /&gt;display:block;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.hide {&lt;br /&gt;display:none; &lt;br /&gt;}&lt;br /&gt;...&lt;br /&gt;&lt;h1&gt;sigh&lt;/h1&gt; &lt;h3&gt;CSS is not a macro programming language.&lt;/h3&gt;&lt;br /&gt;Look, I know CSS is hard. That's why you get paid well; cause you are doing difficult things.  Now for the love of god, do it right.  Because all you are doing here is creating a mess.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-2706841830786516644?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/2706841830786516644/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/01/horrible-css-again.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/2706841830786516644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/2706841830786516644'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/01/horrible-css-again.html' title='horrible css again'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-12685755570641892</id><published>2011-01-16T18:22:00.001-08:00</published><updated>2011-01-16T18:25:55.851-08:00</updated><title type='text'>Crazy PHP round 2</title><content type='html'>&lt;tt&gt;function createARB($refId, $name, $length, $unit, $startDate, $totalOccurrences, $trialOccurrences, $amount, $trialAmount, $cardNumber,  $expirationDate, $firstName, $lastName,$loginname, $transactionkey, $host,$path,$address,$city,$state,$zip,$country,$phone,$email,$address2,$city2,$state2,$zip2,$country2) {&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;^^^ &lt;b&gt;THAT&lt;/b&gt; ^^^ has a bigger brother:&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;function fetchRequestString($login, $password, $trans_id, $x_first_name, $x_last_name, $x_address, $x_city, $x_state, $x_zip, $x_country, $x_phone, $x_email, $x_Amount, $x_card_num, $x_card_code, $x_exp_date, $desc, $merchantEmail, $transKey,$x_invoice_num,$x_ship_to_first_name,$x_ship_to_last_name,$x_ship_to_address,$x_ship_to_city,$x_ship_to_state,$x_ship_to_zip,$x_ship_to_country, $x_tax, $x_freight,$x_line_items = false){&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;You know, modern languages can pass in structured data, right?  We don't have to push things on to the stack like we did in 1965; you know this, right?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-12685755570641892?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/12685755570641892/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/01/crazy-php-round-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/12685755570641892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/12685755570641892'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/01/crazy-php-round-2.html' title='Crazy PHP round 2'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-3435599386976377766</id><published>2011-01-16T16:12:00.000-08:00</published><updated>2011-01-16T17:37:36.387-08:00</updated><title type='text'>USPS API is horrible</title><content type='html'>&lt;h3&gt;Garbage Names&lt;/h3&gt;&lt;br /&gt;&lt;blockquote&gt;On January 2nd, USPS changed shipment option names from things like &lt;br /&gt;&lt;br /&gt;&lt;tt&gt;First Class Mail International Package&lt;/tt&gt; &lt;br /&gt;&lt;br /&gt;to &lt;br /&gt;&lt;br /&gt;&lt;tt&gt;First-Class Mail&amp;amp;lt;sup&amp;amp;gt;&amp;amp;amp;reg;&amp;amp;lt;/sup&amp;amp;gt; International Package**&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;This is not a bug&lt;/b&gt;.  This is what USPS &lt;i&gt;intentionally wants to use&lt;/i&gt; going forward.  &lt;br /&gt;&lt;br /&gt;The solution suggested to fix the apis that break on this is to do something like &lt;tt&gt;"strip &amp;amp;lt;sup&amp;amp;gt;&amp;amp;amp;reg;&amp;amp;lt;/sup&amp;amp;gt; and the **".&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;That is to say, that programmers should now put in a data sanitizer because USPS has decided to supply a bunch of garbage tags in their latest API. The recommended solution is to drop the new garbage. &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Let me take some time and try to figure out how this could have ever possibly went down:&lt;br /&gt;&lt;br /&gt;In December there was a board meeting:&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;Manager: Our brand name needs to be protected.  Are we putting a &lt;sup&gt;&amp;reg;&lt;/sup&gt; everywhere that our brand "First-Class Mail" appears?&lt;br /&gt;Programmer: Well, not exactly.  Our programmer facing API...&lt;br /&gt;Manager (interrupts): I've heard enough.  When should we do this?  Now, or after we fire you?&lt;br /&gt;Programmer: B..but, this will break everything!&lt;br /&gt;Manager: Well then, we will find someone that will respect our brand.&lt;br /&gt;Programmer (under her breath): Holy fuck... &lt;br /&gt;Programmer: Alright ... no problem sir. We'll have to send an email out.&lt;br /&gt;Manager: The email has already been sent.  We can't send out a second.&lt;br /&gt;Programmer: Again, this will break everything, internatio... &lt;br /&gt;Manager (interrupts): One email only. It's already been sent.  People will adapt.&lt;br /&gt;Programmer: Let's at least update our documentation by that week.&lt;br /&gt;Manager: The documentation server are due for a scheduled downtime that week.  We can't change this - the policy has been set.&lt;/tt&gt; (yes, they went down that week)&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Really odd requirements&lt;/h3&gt;&lt;br /&gt;Ordering of things that probably ought to not matter, really do for USPS.  For instance, This is correct:&lt;br /&gt;&lt;tt&gt;&lt;br /&gt; &amp;lt;Length&amp;gt;12&amp;lt;/Length&amp;gt;&lt;br /&gt; &amp;lt;Height&amp;gt;8&amp;lt;/Height&amp;gt;&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;This is wrong:&lt;br /&gt;&lt;tt&gt;&lt;br /&gt; &amp;lt;Height&amp;gt;8&amp;lt;/Height&amp;gt;&lt;br /&gt; &amp;lt;Length&amp;gt;12&amp;lt;/Length&amp;gt;&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;You have to do Width, &lt;b&gt;then&lt;/b&gt; Length, &lt;b&gt;then&lt;/b&gt; Height ... and only in that order.    Similarly, you have to do Pounds, then Ounces, then Machinable, then MailType, then GXG, then ValueOfContents (mind the case), then Country, then Container, then Size, ... etc... in this order, and only this order.&lt;br /&gt;&lt;br /&gt;And when it says it's optional on the documentation, don't count on it.  It's required.&lt;br /&gt;&lt;br /&gt;Here's how this may have happened, maybe.&lt;br /&gt;&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;Programmer: Let's use XML for our API.&lt;br /&gt;Manager: What if someone specified Ounces first, then Pounds, instead of Pounds then Ounces?&lt;br /&gt;Programmer: The keys are unique, that ordering will not be a problem.&lt;br /&gt;Manager: What if it was a mistake?&lt;br /&gt;Programmer: XML shouldn't care.  The siblings orders should be interchangeable in the case of Key/Value assignment like this.&lt;br /&gt;Manager: There should be only one correct way?&lt;br /&gt;Programmer: We would have to go way out of our way to make this.&lt;br /&gt;Manager: We pay you well, right?&lt;br /&gt;Programmer: Ok Ok, let's at least state this in our documentation.&lt;br /&gt;Manager: What? That there is only one correct way?  Isn't this assumed? You are a programmer right?  Aren't computers &lt;i&gt;supposed to be&lt;/i&gt; this pedantic?&lt;br /&gt;Programmer: Yeah well ...&lt;br /&gt;Manager: We pay you well, don't worry about it.&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Horrid Documentation&lt;/h3&gt;&lt;br /&gt;And why on earth does &lt;a href=http://www.usps.com/webtools/htm/Rate-Calculators-v1-2a.htm&gt;http://www.usps.com/webtools/htm/Rate-Calculators-v1-2a.htm&lt;/a&gt; take sooo damned long to load?&lt;br /&gt;&lt;br /&gt;A peak at the source reveals:&lt;br /&gt;&amp;lt;meta name=ProgId content=Word.Document&amp;gt;&lt;br /&gt;&amp;lt;meta name=Generator content="Microsoft Word 11"&amp;gt;&lt;br /&gt;&lt;br /&gt;Yes.  They write there technical APIs in Microsoft Word and then just save them as HTML and post them directly to the site.  Genius.  At least we can scrape a few things:&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;  &amp;lt;o:Subject&amp;gt;Web Tools API Reference&amp;lt;/o:Subject&amp;gt;&lt;br /&gt;  &amp;lt;o:Author&amp;gt;john.f.johnson@hp.&amp;lt;/o:Author&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;  &amp;lt;o:LastAuthor&amp;gt;Amanda Loser&amp;lt;/o:LastAuthor&amp;gt;&lt;br /&gt;  ...&lt;br /&gt;  &amp;lt;o:_AuthorEmail dt:dt="string"&amp;gt;Sherry.McNeill@hp.com&amp;lt;/o:_AuthorEmail&amp;gt;&lt;br /&gt;  &amp;lt;o:_AuthorEmailDisplayName dt:dt="string"&amp;gt;McNeill, Sherry&amp;lt;/o:_AuthorEmailDisplayName&amp;gt;&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;My first tone of complaint will be the fact that they don't talk about the changes, although they seem to suggest there has been some.  You see stuff like this in there example code:&lt;br /&gt;&lt;tt&gt;&lt;br /&gt;First-Class Mail Interna&amp;lt;!--127 suppressed--&amp;gt;)&lt;br /&gt;&lt;/tt&gt;&lt;br /&gt;So their example code, isn't actually an example; it's a neutered copy and paste that doesn't actually illustrate a full exchange.  It fails to serve its most fundamental purpose; which is to illustratively show what one means.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-3435599386976377766?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/3435599386976377766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2011/01/usps-api-is-horrible.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/3435599386976377766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/3435599386976377766'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2011/01/usps-api-is-horrible.html' title='USPS API is horrible'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-3649081813133460640</id><published>2010-12-14T02:16:00.000-08:00</published><updated>2010-12-14T02:35:10.554-08:00</updated><title type='text'>Horrible CSS</title><content type='html'>This is wrong.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;div class="wid200 text_right border_top pad3"&amp;gt;&lt;br /&gt;  &amp;lt;div class="clear"&amp;gt;&lt;br /&gt;   ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Basically, authoring CSS like this is the same way people authored HTML before stylesheets.  You are explicitly itemizing style hierarchically and ignoring encapsulation and the semantic bridge that CSS is meant to provide.  If you prefer to code like this, You should probably actually write like this&lt;pre&gt;&lt;br /&gt;&amp;lt;big&amp;gt;&lt;br /&gt; &amp;lt;big&amp;gt;&lt;br /&gt;  &amp;lt;br&amp;gt;  &amp;lt;br&amp;gt;  &amp;lt;br&amp;gt;  &amp;lt;br&amp;gt;&lt;br /&gt;  &amp;lt;font color=red&amp;gt;&lt;br /&gt;   &amp;lt;strong&amp;gt;&lt;br /&gt;    Markup like this, in circa 1996 style --- because when you are explicit &lt;br /&gt;    with every style declaration, you are doing the &lt;b&gt;Exact&lt;/b&gt; &lt;u&gt;Same&lt;/u&gt;  &lt;br /&gt;    &lt;b&gt;Thing&lt;/b&gt;.&lt;br /&gt;   &amp;lt;/strong&amp;gt;&lt;br /&gt;  &amp;lt;/font&amp;gt; &lt;br /&gt;  and I wrote code like this, it was the mid 90s ... I used Navigator 3.04 gold,&lt;br /&gt;  and connected to the internet via 14400 bps. We've moved one.&lt;br /&gt; &amp;lt;/big&amp;gt; &lt;br /&gt; If you ever profess that you do "MVC" and then code like this, you are&lt;br /&gt; just using buzzwords and totally mistaken.  End of story.&lt;br /&gt;&amp;lt;/big&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here is what a good piece of CSS would look like&lt;br /&gt;&lt;pre&gt;&amp;lt;span class="profile cta container"&amp;gt;&lt;br /&gt; &amp;lt;button onclick=dosomething()&amp;gt;Something&amp;lt/button&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The Most Important Thing here is to notice that the class does not dictate a layout or a style - it dictates a higher level, encapsulated, semantic meaning for the content.  If you want consistency in layout, design, and theme; this is what it should look like.  Then when you do your JS coding, using your fancy jquery, you do&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$(".profile .cta button")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And you don't have to add an &lt;i&gt;additional&lt;/i&gt; id tag to reference the section semantically. The principle here is simple:&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;De-couple, but do not de-correlate&lt;/h1&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-3649081813133460640?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/3649081813133460640/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2010/12/horrible-css.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/3649081813133460640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/3649081813133460640'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2010/12/horrible-css.html' title='Horrible CSS'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-1274913979977729846</id><published>2010-12-05T16:13:00.000-08:00</published><updated>2010-12-05T16:24:07.329-08:00</updated><title type='text'>Enterprise Database is</title><content type='html'>Using a number in a state column that corresponds to a 5 field state table, that is cross referenced to a country table that has 8 fields so that you have to 3 table joins in order to get from "20183" to "CA".  Here? you want the billing address I know how to do that!&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;     select users.FirstName || ' ' || users.LastName, &lt;br /&gt;         Ship.AddressLine1, Ship.AddressLine2,&lt;br /&gt;         Country.State, State.PostalRegion, Country.name from&lt;br /&gt;       users as users&lt;br /&gt;         join ShippingAddress as Ship on users.ID = Ship.UserID&lt;br /&gt;         join State as state on Ship.StateCode = state.stateID&lt;br /&gt;         join Country as country on state.countryId = Country.code&lt;br /&gt;       where users.ID = '101';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That was so easy and totally necessary.  You know things are done Right&lt;sup&gt;&amp;trade;&lt;/sup&gt; when a 12-core machine takes 15 seconds to produce a page full of addresses; cause that's how long it took in 1975; when a kilobyte of memory set you back $10,000.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-1274913979977729846?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/1274913979977729846/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2010/12/enterprise-database-is.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1274913979977729846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1274913979977729846'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2010/12/enterprise-database-is.html' title='Enterprise Database is'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-6160022059878289596</id><published>2010-10-19T17:23:00.001-07:00</published><updated>2010-10-19T17:50:46.929-07:00</updated><title type='text'>What's revision control?</title><content type='html'>This is the css directory for one of my clients, just for one file:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; ++main.css&lt;br /&gt; __main.css&lt;br /&gt; main-17-october.css&lt;br /&gt; main-1st-nov.css&lt;br /&gt; main-23rdfeb.css&lt;br /&gt; main-3-8-9.css&lt;br /&gt; main-bk1.css&lt;br /&gt; main-extra.css&lt;br /&gt; main.css&lt;br /&gt; main.css.bk&lt;br /&gt; main14April2009.css&lt;br /&gt; main15April2009.css&lt;br /&gt; main_bk.css&lt;br /&gt; main_old.css&lt;br /&gt; main.css.bak&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Not only are their 14 versions of that file, but their are 5 separate conventions for assigning dates.  Truly remarkable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-6160022059878289596?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/6160022059878289596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2010/10/whats-revision-control.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6160022059878289596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6160022059878289596'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2010/10/whats-revision-control.html' title='What&apos;s revision control?'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-5077247442236902316</id><published>2010-10-19T16:58:00.000-07:00</published><updated>2010-10-19T17:17:38.469-07:00</updated><title type='text'>Horrible Javascript Code</title><content type='html'>&lt;pre&gt;      var class_schedules_text = '';&lt;br /&gt;       class_schedules.each(function() {&lt;br /&gt;               class_schedules_text =  class_schedules_text + $(this).html();&lt;br /&gt;       });&lt;br /&gt;       parts = class_schedules_text.split('&amp;lt;/strong&amp;gt;');&lt;br /&gt;       class_schedules_text = parts[1];&lt;br /&gt;       class_schedules_text = '&amp;lt;div style="width: 280px; margin-bottom: 10px; float: left; margin-left: &lt;br /&gt;       5px;font-size: 12px;"&amp;gt;'+class_schedules_text+'&amp;lt;/div&amp;gt;';&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;What it was replaced with&lt;/h3&gt;&lt;pre&gt;var class_schedules_text = class_schedules.html().replace(/&lt;[^b].*?&gt;/g,'');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Remember, there are two ways of doing layout&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Know what you are doing and do it&lt;br /&gt;&lt;li&gt;Use excessive markup to eventually coerce the elements into place&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;For instance,&lt;pre&gt;&lt;br /&gt;  box_content += "&amp;lt;p&amp;gt;&amp;lt;div style='overflow: auto;'&amp;gt;&lt;br /&gt;  &amp;lt;label style='float: left; margin-right:3px;font&lt;br /&gt;  -size: 12px;'&amp;gt;Schedule:&amp;lt;/label&amp;gt;&amp;lt;ul style='margin&lt;br /&gt;  :0; padding:0; float: left; font-size:12px;'&amp;gt;"+c&lt;br /&gt;  lass_schedules_text+"&amp;lt;/ul&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/p&amp;gt;";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Becomes:&lt;pre&gt;&lt;br /&gt;   box_content += "&amp;lt;p&amp;gt;"+class_schedules_text+"&amp;lt;/p&amp;gt;";&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-5077247442236902316?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/5077247442236902316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2010/10/horrible-javascript-code.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/5077247442236902316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/5077247442236902316'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2010/10/horrible-javascript-code.html' title='Horrible Javascript Code'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-7157816179872506470</id><published>2010-10-18T18:07:00.000-07:00</published><updated>2010-10-18T18:20:14.014-07:00</updated><title type='text'>Stupidity example: Whm</title><content type='html'>So you have this things "WHM" installed.  It looks like the default apache page.  All you need to do is put things into /usr/local/apache/htdocs/ and you are done right?  Override the default script and that's that.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;NO, Bitch, You Are Wrong&lt;/h1&gt;&lt;br /&gt;If you do this, then you will get a bunch of errors; apache is looking for sys_cpanel or something somewhere.  It will not actually feed the index.php file.  It will feed a subdirectory and it's content listings.  So if you wanted to look at /usr/local/apache/htdocs/mydocs, you will see the contents of the directory, but as soon as you click&lt;br /&gt;on a single file, KABOOM!&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;How the fuck do you make it work then?&lt;/h1&gt;&lt;br /&gt;Good questions.&lt;br /&gt;&lt;br /&gt;Let's back up&lt;br /&gt;&lt;h3&gt;The old way, clearly too difficult&lt;/h3&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;# touch /usr/local/apache/htdocs/index.html&lt;br /&gt;&lt;li&gt;Point your web browser to http://ip/&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt; The new way, clearly easier&lt;/h3&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Point web browser to http://ip_address/whm&lt;br /&gt;&lt;li&gt;Log in&lt;br /&gt;&lt;li&gt;Click on the 14th icon, "Account Functions" between "Account Information" and "Multi-Account Functions"&lt;br /&gt;&lt;li&gt;Click on the 2nd icon, "Create a New Account"&lt;br /&gt;&lt;li&gt;For the domain, give it the eventual domain you'd like to use&lt;br /&gt;&lt;li&gt;Enter a Username&lt;br /&gt;&lt;li&gt;Enter a Password&lt;br /&gt;&lt;li&gt;Retype the Password&lt;br /&gt;&lt;li&gt;Enter in an email and scroll down to the bottom&lt;br /&gt;&lt;li&gt;Click Create&lt;br /&gt;&lt;li&gt;SSH to the ip address using the new username/password pair&lt;br /&gt;&lt;li&gt;Run touch public_html/index.html&lt;br /&gt;&lt;li&gt;Go to the machine you need to access it on and open up your etc/hosts file.  On Windows its c:\%WINDOWS%\system32\etc\hosts, on MacOS and Linux is /etc/hosts.&lt;br /&gt;&lt;li&gt;Add the domain name you used in the above step and the ip address.  This is a temporary mapping so that you can see the empty file&lt;br /&gt;&lt;li&gt;Save the file&lt;br /&gt;&lt;li&gt;Restart your web browser to clear out your dns cache&lt;br /&gt;&lt;li&gt;Enter in the domain you used above&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;It's so much easier the new way, right?&lt;br /&gt;&lt;br /&gt;&lt;H3&gt;How did you figure this out?&lt;/h3&gt;&lt;br /&gt;It took days.  Literally.  Who would have thought that you needed to create an account through WHM in order to view a php file on the web server?  What kind of stupid is this?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-7157816179872506470?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/7157816179872506470/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2010/10/stupidity-example-whm.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/7157816179872506470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/7157816179872506470'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2010/10/stupidity-example-whm.html' title='Stupidity example: Whm'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-5304465596079930086</id><published>2010-10-18T17:27:00.000-07:00</published><updated>2010-10-18T18:30:01.270-07:00</updated><title type='text'>Fuck Cpanel</title><content type='html'>Is it really excessively hard to learn how your website stack works?  Really?  Do you realize that all the complexities of the site are just presented to you in different packaging through Cpanel?  It doesn't actually make things easier, all it does is rephrase the same shit in a new way.&lt;br /&gt;&lt;br /&gt;While, at the same time, overriding all of the traditional ways of doing things.&lt;br /&gt;&lt;br /&gt;If you have the slightest idea what you are doing, this bludgeoning piece of crap software will just randomly regenerate its wrong and broken configuration files over the ones that you manually configured.&lt;br /&gt;&lt;br /&gt;Furthermore, they insist on protecting me for some reason and requiring me to do things there way ... instead of doing things the way that has worked since about 1992 - no that wasn't good enough; finding a file through locate, and editing it directly just was &lt;b&gt;way too difficult&lt;/b&gt;.  Now we need 5 levels of colorful icons amongst a collection of 140 and I have to remember &lt;i&gt;"Services Panel" &amp;gt; "Web Services Panel" &amp;gt; "Web Server Configuration" &amp;gt; "Permissions for Web Server"&lt;/i&gt; or whatever the fuck they have decided to come up with.  &lt;br /&gt;&lt;br /&gt;It's called "httpd.conf" it's in the /usr/local/etc directory or the /etc directory. It's under the apache config, I use vim to edit it, just like I did in 2005, 2000, and 1995.  Why must you insist on splicing the file into a spewed out mess of 85 different menu options.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Why?&lt;/h1&gt;&lt;br /&gt;&lt;br /&gt;Because the old way didn't use a fucking mouse.  That's why.  It wasn't user friendly enough, I'm guessing because it didn't look like the Windows Explorer shell - the epitome of ease of use, of course.&lt;br /&gt;&lt;br /&gt;Now I need to find this shit that accesses that single fucking line of the file, and still type in the same &lt;b&gt;damn configuration directives&lt;/b&gt; as if I was editing it manually in vim; but now it's through a web app; That's Progress!&lt;br /&gt;&lt;br /&gt;I still actually have to have the knowledge of what to change to what; but now I need to know a bunch of additional information so that Cpanel won't overwrite it next time it decides to regenerate all the files from some stupid innocuous command, like an apache restart.&lt;br /&gt;&lt;br /&gt;What files does Cpanel like to rewrite?  &lt;br /&gt;&lt;br /&gt;Who the fuck knows! Really.  I don't know at all.  I'm thinking that the entire /etc directory is becoming a black box where I would need to start up KDE4 on tightvnc in order to edit like, /etc/hosts in a way that won't get reverted every 5 minutes.  If I knew any better, I'd know that I'd have to go into 6 configuration files and rewrite a bunch of Python and XML to disable it, along with running a bunch of distribution specific command line tools.  Because you know, putting 4 layers of abstraction on a key/value pair text file is totally awesome; and people are totally capable of modifying the value of two input boxes, but are totally incapable of modifying the value of a single line of a file.&lt;br /&gt;&lt;br /&gt;This shit is totally moronic.  What is wrong with people?&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;I see where you are going. But what, pray tell, does Cpanel actually do?&lt;/h1&gt;&lt;br /&gt;That's easy!&lt;br /&gt;&lt;br /&gt;All it does is that it takes a previously rather straight-forward Layout and piles shitpile after shitpile on it to create this crazy obfuscated interface where the obvious and important things are littered 4 menus deep and strewn about like some fucking 12 year old with ADHD and Photoshop decided to start making webpages last tuesday and then jizzed out some sorry excuse for a piece of software and called it Cpanel.&lt;br /&gt;&lt;br /&gt;It takes very straightforward technical models and tosses them out the window, instead opting for some exponentially more complex "natural model" which is actually still a model, thus an abstraction, thus providing a barrier to entry, thus requiring a learning curve, and thus being counterproductive and extraordinarily detrimental to the intended purpose of further trying to simplify an already simple task.&lt;br /&gt;&lt;br /&gt;&lt;H1&gt;Oh I see, what should I learn from this triage?&lt;/h1&gt;&lt;br /&gt;When webdevs get the rapt as being the stupidest, densest, dumbest programmers in the industry, I can clearly and emphatically agree when they turn to, and speak anything but with the most vile of contempt for this awful veneer that just smears and blurs otherwise obvious, straightforward processes.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;For the love of God, if you want to be a programmer, learn to use a fucking computer.&lt;/h3&gt; &lt;br /&gt;&lt;a href=http://kristopolous.blogspot.com/2010/10/stupidity-example-whm.html&gt;For a more detailed example of this type of mentality, check out this posting on WHM&lt;/a&gt;&lt;br /&gt;---&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-5304465596079930086?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/5304465596079930086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2010/10/fuck-cpanel.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/5304465596079930086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/5304465596079930086'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2010/10/fuck-cpanel.html' title='Fuck Cpanel'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-148419244451913953</id><published>2010-05-04T01:57:00.000-07:00</published><updated>2010-05-04T02:00:10.827-07:00</updated><title type='text'>Javascript CSV Viewer</title><content type='html'>I had a csv file, you know, the typical... but I didn't have a viewer installed.  I wanted something straight forward.  I ended up using google docs but really, I was looking for copy and paste, something that &lt;a href=http://qaa.ath.cx/javascript_csv_viewer.html&gt;would easily facilitate CSV files&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-148419244451913953?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/148419244451913953/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2010/05/javascript-csv-viewer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/148419244451913953'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/148419244451913953'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2010/05/javascript-csv-viewer.html' title='Javascript CSV Viewer'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-6707291186975505314</id><published>2010-04-22T12:46:00.000-07:00</published><updated>2010-04-22T13:48:21.350-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='opencv'/><category scheme='http://www.blogger.com/atom/ns#' term='imagemagick'/><title type='text'>Image Fading in linux</title><content type='html'>Please look here: &lt;a href=http://qaa.ath.cx/fade.html&gt;fade.html&lt;/a&gt;.  I'm going to move away from this horrible platform soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-6707291186975505314?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/6707291186975505314/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2010/04/image-fading-in-linux.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6707291186975505314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6707291186975505314'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2010/04/image-fading-in-linux.html' title='Image Fading in linux'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-3437459302397350574</id><published>2010-04-21T18:37:00.000-07:00</published><updated>2010-04-21T18:50:51.987-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>CPAN</title><content type='html'>&lt;pre&gt;&lt;br /&gt;I like CPAN.  Do you like it?&lt;br /&gt; Would you like to answer now? [yes]&lt;br /&gt; Is your answer in English? [yes]&lt;br /&gt; Is your answer in ASCII? [yes]&lt;br /&gt; Does UTF-8 look right to you? [yes]&lt;br /&gt; Would you like to answer via keyboard input? [yes]&lt;br /&gt; Would you like to continue? [yes]&lt;br /&gt;Checking if you have a computer ...... ok&lt;br /&gt;Checking if it is running ............ ok&lt;br /&gt;Checking if it is done booting ....... ok&lt;br /&gt;Checking if operating system loaded .. ok&lt;br /&gt;Checking if perl is installed ........ ok&lt;br /&gt;...&lt;br /&gt;Error: terminal type "Linux" unknown. Aborting.&lt;br /&gt;&lt;u&gt;cpan&amp;gt;&lt;/u&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-3437459302397350574?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/3437459302397350574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2010/04/cpan.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/3437459302397350574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/3437459302397350574'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2010/04/cpan.html' title='CPAN'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-728581386047042357</id><published>2010-03-27T16:24:00.001-07:00</published><updated>2010-03-27T16:40:28.768-07:00</updated><title type='text'>Apophnia, an image server</title><content type='html'>So I was presented with a problem like this:&lt;br /&gt;&lt;blockquote&gt;Hiya, I have a bazillion images and I want to um you know like:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Be able to use new resolutions on the fly&lt;br /&gt;&lt;li&gt;Have these dynamically created images cached&lt;br /&gt;&lt;li&gt;Incur almost zero overhead in the process&lt;br /&gt;&lt;li&gt;Have a dedicated image web server or a web server module to do it ... images are important&lt;/ul&gt;&lt;br /&gt;Basically, given file /myimage.jpg I want to do say, /myimage_500x500.jpg and then say,&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Look for myimage_500x500.jpg.&lt;br /&gt;&lt;li&gt;If not found, back up, try myimage.jpg&lt;br /&gt;&lt;li&gt;See that (_500x500) is a resize directive&lt;br /&gt;&lt;li&gt;Dynamically resize myimage.jpg to 500x500, serve that image&lt;br /&gt;&lt;li&gt;&lt;b&gt;Save a new file to disk myimage_500x500.jpg so that when it is requested again ... it's easy&lt;/b&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Oh, and I want some other things&lt;br /&gt;&lt;ol&gt;&lt;li&gt;When the image is resized the first time, I want it to be the fastest algorithm possible so that the user sees the resized image with minimal delay.&lt;br /&gt;&lt;li&gt;But I also want a different, slow, high quality algorithm to run to save it to disk&lt;/ol&gt;&lt;br /&gt;One more thing, if it's not too hard&lt;blockquote&gt;I want to specify things like this:&lt;br /&gt;&lt;pre&gt;"medium": {&lt;br /&gt;    "resize": [1024,1024],&lt;br /&gt;    "quality": 50,&lt;br /&gt;    "cropwhitespace": true&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;so I can do something stupid like request /myimage_medium.jpg&lt;br /&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;br /&gt;If only this existed! &lt;a href=http://github.com/kristopolous/apophnia&gt;&lt;b&gt;[ Download it here ]&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Current implementation details&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Written in C.&lt;br /&gt;&lt;li&gt;Uses Mongoose as a webserver&lt;br /&gt;&lt;li&gt;Uses Imagemagick for sizing&lt;br /&gt;&lt;li&gt;Doesn't actually do *everything* above yet, but that is the goal.&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-728581386047042357?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/728581386047042357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2010/03/apophnia-image-server.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/728581386047042357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/728581386047042357'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2010/03/apophnia-image-server.html' title='Apophnia, an image server'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-6938063924669409027</id><published>2010-02-24T23:52:00.000-08:00</published><updated>2010-02-24T23:53:50.352-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='yt'/><title type='text'>Youtube music searcher</title><content type='html'>&lt;a href=http://qaa.ath.cx/music.html&gt;http://qaa.ath.cx/music.html&lt;/a&gt;&lt;br&gt;&lt;br /&gt;Try to copy and paste a list like...&lt;br /&gt;&lt;pre&gt;+Run DMC - Peter Piper &lt;br /&gt;Salt N' Pepa - Push It&lt;br /&gt;Slick Rick - A Children’s Story&lt;br /&gt;Sugarhill Gang - Rapper’s Delight&lt;br /&gt;Sugarhill Gang - Apache&lt;br /&gt;Tone Loc - Funky Cold Medina &lt;br /&gt;Treacherous Three - Feel The Heart Beat &lt;br /&gt;Trouble Funk - Pump Me Up &lt;br /&gt;Ultramagnetic MC's - Ego Trippin' &lt;br /&gt;West Street Mob - Breakdance Electric Boogie &lt;br /&gt;Whodini - Freaks Come Out At Night &lt;br /&gt;Whodini - Friends&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-6938063924669409027?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/6938063924669409027/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2010/02/youtube-music-searcher.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6938063924669409027'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6938063924669409027'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2010/02/youtube-music-searcher.html' title='Youtube music searcher'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-4080626773525635452</id><published>2010-01-08T16:42:00.000-08:00</published><updated>2010-11-10T00:09:20.825-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Stemming'/><category scheme='http://www.blogger.com/atom/ns#' term='JS'/><category scheme='http://www.blogger.com/atom/ns#' term='IR'/><title type='text'>Online Porter Stemmer</title><content type='html'>I was looking for an online version of the Porter Stemming algorithm.  I couldn't find one, and then realized that I am the person most recently credited with the official JS version here: &lt;a href=http://tartarus.org/~martin/PorterStemmer/&gt;http://tartarus.org/~martin/PorterStemmer/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So I guess then, it's my responsibility to make a demo: &lt;a href=http://qaa.ath.cx/porter_js_demo.html&gt;http://qaa.ath.cx/porter_js_demo.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There it is.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-4080626773525635452?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/4080626773525635452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2010/01/porter-stemmer.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/4080626773525635452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/4080626773525635452'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2010/01/porter-stemmer.html' title='Online Porter Stemmer'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-6225243648524831967</id><published>2009-12-25T05:39:00.001-08:00</published><updated>2009-12-25T05:40:45.128-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='craigslist'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><category scheme='http://www.blogger.com/atom/ns#' term='youtube'/><title type='text'>yawn, merry christmas</title><content type='html'>&lt;a href=http://qaa.ath.cx/inj.html&gt;Starting a repository, as I always intended&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-6225243648524831967?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/6225243648524831967/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/yawn-merry-christmas.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6225243648524831967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6225243648524831967'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/yawn-merry-christmas.html' title='yawn, merry christmas'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-6992272608874397143</id><published>2009-12-17T05:00:00.000-08:00</published><updated>2009-12-17T05:06:34.818-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><title type='text'>JS Array to object</title><content type='html'>So I wanted to be able to use an object in JSON but transfer it as an array.&lt;br /&gt;&lt;br /&gt;The issue is that the syntax of el.name is nice, but the {name:"joe"} is longer then just ["joe"].&lt;br /&gt;&lt;br /&gt;The way around it is very simple actually.&lt;br /&gt;&lt;br /&gt;We'll start with a normal object&lt;pre&gt;{&lt;br /&gt; firstname: "Joe",&lt;br /&gt; lastname: "Shmoe",&lt;br /&gt; address: "123 Twiddledeedoo Lane",&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Now we do this in javacript:&lt;pre&gt;&lt;br /&gt;var keys = ["firstname", "lastname", "address"], obj = {};&lt;/pre&gt;&lt;br /&gt;And we transfer ["Joe","Shmoe","123 Twiddledeedoo Lane"] as the payload.&lt;br /&gt;&lt;br /&gt;Now the code is fairly straight forward.  Assuming:&lt;pre&gt;&lt;br /&gt;var values = ["Joe","Shmoe","123 Twiddledeedoo Lane"];&lt;/pre&gt;&lt;br /&gt;To efficiently get back to the object we do the following:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;do{&lt;br /&gt; obj[keys.pop()] = values.pop();&lt;br /&gt;} while (keys.length);&lt;/pre&gt;&lt;br /&gt;And that's it.  It's so straight forward ... I don't know why it was a mystery for so long...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-6992272608874397143?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/6992272608874397143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/js-array-to-object.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6992272608874397143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/6992272608874397143'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/js-array-to-object.html' title='JS Array to object'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-7414990452274737266</id><published>2009-12-15T22:26:00.002-08:00</published><updated>2009-12-15T22:27:07.132-08:00</updated><title type='text'>Easy HTML</title><content type='html'>Try it out: &lt;a href=http://qaa.ath.cx/easy.html&gt;http://qaa.ath.cx/easy.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-7414990452274737266?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/7414990452274737266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/easy-html_15.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/7414990452274737266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/7414990452274737266'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/easy-html_15.html' title='Easy HTML'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-2037996792739895678</id><published>2009-12-11T19:48:00.001-08:00</published><updated>2009-12-11T19:51:31.566-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='ssh'/><title type='text'>Stupid ssh script</title><content type='html'>I'm usually too lazy to go through the dance of sending over an auth key to the host.  So I wrote a dumb script to help me,  here it is: &lt;a href=http://qaa.ath.cx/authadd.txt&gt;http://qaa.ath.cx/authadd.txt&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There's a little bit of scary logic in there to avoid duplicates... You may want to take it out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-2037996792739895678?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/2037996792739895678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/stupid-ssh-script.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/2037996792739895678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/2037996792739895678'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/stupid-ssh-script.html' title='Stupid ssh script'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-1602918296587026199</id><published>2009-12-11T01:17:00.001-08:00</published><updated>2009-12-11T04:23:13.982-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><title type='text'>Journeys through PHP</title><content type='html'>Over the years I've used a bit of server side languages: C, Perl, C Shell; I've even wrote my own web server for kicks once.  Sounds very 1997, right?  &lt;br /&gt;&lt;br /&gt;Back to 2009...&lt;br /&gt;&lt;br /&gt;So I had to make this website for this company, a big idea company, from scratch. I was a systems programmer who wanted to become familiar with web stuff.&lt;br /&gt;&lt;br /&gt;The feasible options in my subjective mind were:&lt;ul&gt;&lt;li&gt;&lt;a href=http://www.python.org&gt;Python&lt;/a&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=http://perl.org&gt;Perl&lt;/a&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=http://php.net&gt;PHP&lt;/a&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=http://java.com&gt;Java&lt;/a&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=http://www.ruby-lang.org/en/&gt;Ruby&lt;/a&gt;&lt;br /&gt;&lt;li&gt;&lt;a href=http://www.scala-lang.org/&gt;Scala&lt;/a&gt;? &lt;a href=http://www.artima.com/scalazine/articles/twitter_on_scala.html&gt;Really&lt;/a&gt;? ok...&lt;br /&gt;&lt;/ul&gt;&lt;h3&gt;Java&lt;/h3&gt;Java was a pain to use in college, and I never really understood &lt;a href=http://tomcat.apache.org/&gt;Tomcat&lt;/a&gt;. Also, I just &lt;i&gt;personally feel&lt;/i&gt; like &lt;a href=http://www.eclipsezone.com/articles/williams-interview/images/uml_perspective1_annot.gif&gt;Java requires more thoughtful design and more work&lt;/a&gt;. I hate doing both those things.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Scala&lt;/h3&gt;&lt;a href=http://en.wikipedia.org/wiki/Scala_(programming_language)&gt;Too young still&lt;/a&gt;.  No really, I don't believe it has proven itself yet.  I'm sure it's full of crazy bugs. Would you consider twitter stable? It uses Scala.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Perl&lt;/h3&gt;Too old.  No I mean ... this would have been ok, I guess.  Slashdot is probably still in Perl ... as is, I dunno.  It's a good language - probably wouldn't have been a bad choice ... oh well.  So much for that.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Ruby&lt;/h3&gt;I don't know what is up with this language.  People love it one day then &lt;a href=http://www.radicalbehavior.com/5-question-interview-with-twitter-developer-alex-payne/&gt;hate it&lt;/a&gt; the next.  I don't think I've heard of anyone at like, the big 50 sites talking about it; so until that happens, until I see an article entitled something like&lt;br /&gt;&lt;blockquote&gt;How we reduced latency and increased load on ebay general search with a distributed Ruby based approach&lt;/blockquote&gt;Until that day, it's really not worth looking into.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Python&lt;/h3&gt;Oh a language where print had to be redesigned to be more 'pythonic'. These people actually get bent out of shape on some imaginary philosophy that constitute "Good Programming Language Design".  They are like the &lt;a href="http://www.clannhoran.com/images/wallpaper-images/Don't-Tread-On-Me-1024.jpg"&gt;Libertarians&lt;/a&gt; of the programming world.  Maybe there is some manifesto nobody has showed me or some magazine I'm not subscribed to.  &lt;br /&gt;&lt;br /&gt;It's a fine language, but when basic things require the runaround (like a switch statement), I'm told, "But this; this is 'proper'"; the language purists argue, referencing some invisible playbook from which all their assertions come.&lt;br /&gt;&lt;br /&gt;I have to give it some credit however; for when you want to do non-trivial advanced things Python handles them almost as well as Perl.  Only I guess using Python instead of Perl will make me more friends amongst the wine sipping, &lt;a href=http://en.wikipedia.org/wiki/Dining_philosophers_problem&gt;dining philosophers&lt;/a&gt; of the programming world.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;PHP&lt;/h3&gt;Ah, the 'bottom rung', 'used dishrag', 'tragically maldesigned' accident of computer science.  Why would anyone ever engage themselves in such a huge waste of time?&lt;br /&gt;&lt;br /&gt;Well,&lt;ul&gt;&lt;li&gt;It's easy&lt;br /&gt;&lt;li&gt;It's usually fast&lt;br /&gt;&lt;li&gt;It's relatively bug free&lt;br /&gt;&lt;li&gt;It's philosophy-free&lt;br /&gt;&lt;li&gt;It can do almost anything that takes less then a page of math to explain&lt;br /&gt;&lt;li&gt;It integrates nicely with webpages&lt;/ul&gt;That &lt;b&gt;sounds&lt;/b&gt; like a decent language.  But for some reason, it's totally uncool.&lt;br /&gt;&lt;br /&gt;&lt;img src=http://qaa.ath.cx/php.jpg&gt;&lt;br /&gt;&lt;br /&gt;Maybe because it's such an easy choice, the large amount of bad code from amateur programmers in PHP has given the language itself a bad reputation --- you know, like what happened with Java. Sorry Sun. :-(&lt;br /&gt;&lt;br /&gt;Some of the distaste for PHP however, is well-founded.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Bad Parts of PHP&lt;/h3&gt;Ok, so PHP is a fine language.  There. I said it. Go unfriend me on facebook if you want.  But really, it grabs things from a database and can easily emit html.  That usually covers it.&lt;br /&gt;&lt;br /&gt;The truth is, most of the time, if you are doing webpages, you can get by with any language that supports the following:&lt;ul&gt;&lt;li&gt;Conditionals (if/then/else)&lt;br /&gt;&lt;li&gt;Variables that vary (haha - take that Haskell)&lt;br /&gt;&lt;li&gt;Data structures (array)&lt;br /&gt;&lt;li&gt;Data resource connections (like pg_query)&lt;br /&gt;&lt;li&gt;Easy to use I/O routines (sorry Erlang)&lt;br /&gt;&lt;li&gt;Iterators (for, foreach, while, do)&lt;/ul&gt;And that's it.  You can totally make a huge ass website if you just have those things in your language.  This isn't asking much, and when you don't ask for much, PHP delivers!&lt;br /&gt;&lt;br /&gt;&lt;img src=http://qaa.ath.cx/phpdelivers.png&gt;&lt;br /&gt;&lt;br /&gt;Alas, their are some problems:&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Concurrency Support&lt;/h3&gt;Concurrency isn't something that is an after-thought. You can't just slap it on to a language like you can with &lt;a href=http://php.net/manual/en/function.sha1.php&gt;SHA1&lt;/a&gt; support.  Well, you can, but then you get a mess.  Ideally, you need to have a language that was carefully thought out (read Python) or something designed for this mess (read Erlang).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Overhead&lt;/h3&gt;Object memory overhead in PHP is obscene.  Just ridiculous.  Most web objects are small, like on the order of kilobytes --- which PHP happily translates into megabytes.   But if you want to do some Data Warehousing applications and you have a huge framework already in PHP, then PHP for the DW sounds like a reasonable choice.  Oh, my friend, be prepared for a surprise. &lt;ul&gt;&lt;li&gt;&lt;b&gt;PHP's hash tables don't scale well&lt;/b&gt;. &lt;a href=http://en.wikipedia.org/wiki/Hash_table#Performance_analysis&gt;Aggregated O(1)&lt;/a&gt; my ass --- yeah if 1 means 1 second.&lt;br /&gt;&lt;li&gt;&lt;b&gt;PHP's memory limit is a 32 bit signed int&lt;/b&gt; --- that wraps around and does some ABS or something on itself --- so if you make it like 2049M then you have a 1MB limit.  You can try it yourself if you like&lt;br /&gt;&lt;li&gt;&lt;b&gt;Object oriented-ness was tacked on&lt;/b&gt; ... once again, if it's going to be there, then it has to be a core language design feature, not an after-thought.  When you try to retrofit a traditional language into an object oriented syntax, you usually end up with something much more complex then need be, i.e. C++.  &lt;br /&gt;&lt;/ul&gt;As a result, doing anything more then C-style software engineering in PHP is just going to lead to bad news.  In PHP, you need to embrace globals, carefully name your variables, and sort your code like it's a C program from back in the day.  Then when you hit the scaling point of multiple databases spanning across multiple servers you realize a problem:&lt;br /&gt;&lt;h1&gt;No serious backend software is in PHP&lt;/h1&gt;Why does this matter?  Well let's look at the DW again.  If you are using a Java based system like say, &lt;a href=http://lucene.apache.org/solr/&gt;Solr&lt;/a&gt; (&lt;a href="http://lucene.apache.org/java/docs/index.html#Apache Lucene"&gt;Lucene&lt;/a&gt;), &lt;a href=http://hadoop.apache.org/hbase/&gt;HBase&lt;/a&gt; (&lt;a href="http://hadoop.apache.org/#What+Is+Hadoop%3F"&gt;Hadoop&lt;/a&gt;), or &lt;a href=http://incubator.apache.org/cassandra/&gt;Cassandra&lt;/a&gt;, then you have two options:&lt;ol&gt;&lt;li&gt;Use a restful API, or in the case of Cassandra, &lt;a href=http://incubator.apache.org/thrift/&gt;Thrift&lt;/a&gt;.&lt;br /&gt;&lt;li&gt;Program in Java&lt;/ol&gt;The problem with number 1, is that unless you have scaled your application over sooo many systems, so poorly, that your data is far away from your processing, then you are duplicating data in memory.  Sure it's fast, but it's also stupid.  What you are saying is this:&lt;blockquote&gt;As a matter of convenience and stubbornness and my decision to program in language X when using a library in language Y, I will now translate all the data from language Y to X through some crazy interface before I do my mapping and reducing steps.&lt;/blockquote&gt;And that, my dear, is horribly irresponsible.&lt;br /&gt;&lt;img src=http://qaa.ath.cx/shame200.png&gt;&lt;br /&gt;Despite all this, I'm guilty of all the above and use PHP extensively. :-p&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-1602918296587026199?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/1602918296587026199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/journeys-through-php.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1602918296587026199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1602918296587026199'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/journeys-through-php.html' title='Journeys through PHP'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-7496367694238450150</id><published>2009-12-09T05:06:00.000-08:00</published><updated>2009-12-09T05:12:44.339-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='craigslist'/><title type='text'>adding exclusionary search to craigslist</title><content type='html'>So I'm looking for a car, but craigslist doesn't support the - sign in search&lt;br /&gt;&lt;br /&gt;Try doing -salvage in the car search ... doesn't work.&lt;br /&gt;&lt;br /&gt;So I made a filter bar to exclude things from a craigslist search:&lt;br /&gt;&lt;br /&gt;&lt;a href=http://qaa.ath.cx/clbar.html&gt;Get it here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Use it to type in obvious things...&lt;br /&gt;Screen shot&lt;br /&gt;&lt;img src=http://qaa.ath.cx/clbar.png&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-7496367694238450150?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/7496367694238450150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/adding-exclusionary-search-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/7496367694238450150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/7496367694238450150'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/adding-exclusionary-search-to.html' title='adding exclusionary search to craigslist'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-5455533231555367771</id><published>2009-12-08T20:44:00.000-08:00</published><updated>2009-12-08T21:37:50.906-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='tcpdump'/><title type='text'>Simplifying libpcap filter creation</title><content type='html'>Making a capture filter for &lt;a href=http://www.tcpdump.org&gt;tcpdump&lt;/a&gt; from &lt;a href=http://wireshark.org&gt;wireshark&lt;/a&gt; has always been a pain in my mind.  Maybe there is a nice tool out there to do it for me --- but I really don't know.  So the &lt;a href=http://www.tcpdump.org/tcpdump_man.html&gt;useful syntax&lt;/a&gt; for tcpdump is basically:&lt;pre&gt;(network protocol)[offset] == (decimal value)&lt;/pre&gt;For instance:&lt;pre&gt;ether[100] == 123 and ether[102] == 124&lt;/pre&gt;I mean sure, some wankers probably want to do more with their packets but I'm not one of them.  I simply have a typical packet like this:&lt;br /&gt;&lt;pre style=font-size:8px&gt; 0000  02 00 00 00 45 00 02 8a  db 46 40 00 40 06 b0 6c   ....E... .F@.@..l&lt;br /&gt; 0010  43 7f e9 5a 4a 7d 35 64  fa 4c 00 50 a0 b6 33 f4   C..ZJ}5d .L.P..3.&lt;br /&gt; 0020  6b 36 b9 97 80 18 20 8a  ca 1e 00 00 01 01 08 0a   k6.... . ........&lt;br /&gt; 0030  5b 11 94 89 ca d6 48 ed  47 45 54 20 2f 20 48 54   [.....H. GET / HT&lt;br /&gt; 0040  54 50 2f 31 2e 31 0d 0a  48 6f 73 74 3a 20 67 6f   TP/1.1.. Host: go&lt;br /&gt; 0050  6f 67 6c 65 2e 63 6f 6d  0d 0a 55 73 65 72 2d 41   ogle.com ..User-A&lt;br /&gt; 0060  67 65 6e 74 3a 20 4c 69  6e 6b 73 20 28 32 2e 31   gent: Li nks (2.1&lt;br /&gt; 0070  70 72 65 33 37 3b 20 46  72 65 65 42 53 44 20 37   pre37; F reeBSD 7&lt;br /&gt; 0080  2e 30 2d 52 45 4c 45 41  53 45 20 69 33 38 36 3b   .0-RELEA SE i386;&lt;br /&gt; 0090  20 38 30 78 32 34 29 0d  0a 41 63 63 65 70 74 3a    80x24). .Accept:&lt;br /&gt; 00a0  20 2a 2f 2a 0d 0a 41 63  63 65 70 74 2d 45 6e 63    */*..Ac cept-Enc&lt;br /&gt; 00b0  6f 64 69 6e 67 3a 20 67  7a 69 70 2c 20 64 65 66   oding: g zip, def&lt;br /&gt; 00c0  6c 61 74 65 2c 20 62 7a  69 70 32 0d 0a 41 63 63   late, bz ip2..Acc&lt;br /&gt; 00d0  65 70 74 2d 43 68 61 72  73 65 74 3a 20 75 73 2d   ept-Char set: us-&lt;br /&gt; 00e0  61 73 63 69 69 2c 20 49  53 4f 2d 38 38 35 39 2d   ascii, I SO-8859-&lt;br /&gt; 00f0  31 2c 20 49 53 4f 2d 38  38 35 39 2d 32 2c 20 49   1, ISO-8 859-2, I&lt;br /&gt; 0100  53 4f 2d 38 38 35 39 2d  33 2c 20 49 53 4f 2d 38   SO-8859- 3, ISO-8&lt;br /&gt; 0110  38 35 39 2d 34 2c 20 49  53 4f 2d 38 38 35 39 2d   859-4, I SO-8859-&lt;br /&gt; 0120  35 2c 20 49 53 4f 2d 38  38 35 39 2d 36 2c 20 49   5, ISO-8 859-6, I&lt;br /&gt; 0130  53 4f 2d 38 38 35 39 2d  37 2c 20 49 53 4f 2d 38   SO-8859- 7, ISO-8&lt;br /&gt; 0140  38 35 39 2d 38 2c 20 49  53 4f 2d 38 38 35 39 2d   859-8, I SO-8859-&lt;br /&gt; 0150  39 2c 20 49 53 4f 2d 38  38 35 39 2d 31 30 2c 20   9, ISO-8 859-10, &lt;br /&gt; 0160  49 53 4f 2d 38 38 35 39  2d 31 33 2c 20 49 53 4f   ISO-8859 -13, ISO&lt;br /&gt; 0170  2d 38 38 35 39 2d 31 34  2c 20 49 53 4f 2d 38 38   -8859-14 , ISO-88&lt;br /&gt; 0180  35 39 2d 31 35 2c 20 49  53 4f 2d 38 38 35 39 2d   59-15, I SO-8859-&lt;br /&gt; 0190  31 36 2c 20 77 69 6e 64  6f 77 73 2d 31 32 35 30   16, wind ows-1250&lt;br /&gt; 01a0  2c 20 77 69 6e 64 6f 77  73 2d 31 32 35 31 2c 20   , window s-1251, &lt;br /&gt; 01b0  77 69 6e 64 6f 77 73 2d  31 32 35 32 2c 20 77 69   windows- 1252, wi&lt;br /&gt; 01c0  6e 64 6f 77 73 2d 31 32  35 36 2c 20 77 69 6e 64   ndows-12 56, wind&lt;br /&gt; 01d0  6f 77 73 2d 31 32 35 37  2c 20 63 70 34 33 37 2c   ows-1257 , cp437,&lt;br /&gt; 01e0  20 63 70 37 33 37 2c 20  63 70 38 35 30 2c 20 63    cp737,  cp850, c&lt;br /&gt; 01f0  70 38 35 32 2c 20 63 70  38 36 36 2c 20 78 2d 63   p852, cp 866, x-c&lt;br /&gt; 0200  70 38 36 36 2d 75 2c 20  78 2d 6d 61 63 2c 20 78   p866-u,  x-mac, x&lt;br /&gt; 0210  2d 6d 61 63 2d 63 65 2c  20 78 2d 6b 61 6d 2d 63   -mac-ce,  x-kam-c&lt;br /&gt; 0220  73 2c 20 6b 6f 69 38 2d  72 2c 20 6b 6f 69 38 2d   s, koi8- r, koi8-&lt;br /&gt; 0230  75 2c 20 6b 6f 69 38 2d  72 75 2c 20 54 43 56 4e   u, koi8- ru, TCVN&lt;br /&gt; 0240  2d 35 37 31 32 2c 20 56  49 53 43 49 49 2c 20 75   -5712, V ISCII, u&lt;br /&gt; 0250  74 66 2d 38 0d 0a 41 63  63 65 70 74 2d 4c 61 6e   tf-8..Ac cept-Lan&lt;br /&gt; 0260  67 75 61 67 65 3a 20 65  6e 2c 20 2a 3b 71 3d 30   guage: e n, *;q=0&lt;br /&gt; 0270  2e 31 0d 0a 43 6f 6e 6e  65 63 74 69 6f 6e 3a 20   .1..Conn ection: &lt;br /&gt; 0280  4b 65 65 70 2d 41 6c 69  76 65 0d 0a 0d 0a         Keep-Ali ve....  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And now I want to like, create a libpcap filter on the "GET" to detect whether it's a GET request.&lt;br /&gt;&lt;br /&gt;Now I know what the wankers are saying: &lt;br /&gt;&lt;blockquote&gt;"Well, what if this was some crazy ass packet over here with the boundary of one layer of the network stack just happening to translate into the ASCII character 'G' and then say, the signature or magic number of the next layer down translating into 'ET'.  THEN WHAT?  Then what?"&lt;/blockquote&gt;&lt;br /&gt;Um, then, I get those packets too; all zero of them.  Really.  I mean, get a life.  That shit doesn't happen.&lt;br /&gt;&lt;br /&gt;So let's go back to the real problem.  I want to use &lt;a href=http://wireshark.org&gt;wireshark&lt;/a&gt; and figure out how to write this ...&lt;br /&gt;&lt;br /&gt;So I fire up wireshark and then go to the three pane view.  I expand the "Hypertext Transfer Protocol" node, then the "GET" node and right click on "Request Method: GET".  I go up to apply as filter then click "selected":&lt;br /&gt;&lt;img src=http://qaa.ath.cx/wshark.png&gt;&lt;br /&gt;This seems quite reasonable.  After clicking on it I do indeed get something in the filter syntax:&lt;br /&gt;&lt;img src=http://qaa.ath.cx/filtersyntax.png&gt;&lt;br /&gt;Absolutely stunning.  I get this:&lt;br /&gt;&lt;pre&gt;http.request.method == "GET"&lt;/pre&gt;That's not &lt;a href=http://www.tcpdump.org&gt;libpcap&lt;/a&gt;.  Totally not it.  You totally lose.  I cannot pass that string to &lt;a href=http://www.tcpdump.org&gt;tcpdump&lt;/a&gt;.  Luckily, the wireshark people have a command line capture form of wireshark, called &lt;a href=http://www.wireshark.org/docs/man-pages/tshark.html&gt;tshark&lt;/a&gt;. Fantastic, let's see how to use it! :-)&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$ tshark -h&lt;br /&gt;TShark 1.0.3&lt;br /&gt;Dump and analyze network traffic.&lt;br /&gt;See http://www.wireshark.org for more information.&lt;br /&gt;&lt;br /&gt;Copyright 1998-2008 Gerald Combs (email withheld by me) and contributors.&lt;br /&gt;This is free software; see the source for copying conditions. There is NO&lt;br /&gt;warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&lt;br /&gt;&lt;br /&gt;Usage: tshark [options] ...&lt;br /&gt;&lt;br /&gt;Capture interface:&lt;br /&gt;  -i &amp;lt;interface&amp;gt;           name or idx of interface (def: first non-loopback)&lt;br /&gt;  -f &amp;lt;capture filter&amp;gt;      packet filter in libpcap filter syntax&lt;br /&gt;  -s &amp;lt;snaplen&amp;gt;             packet snapshot length (def: 65535)&lt;br /&gt;  -p                       don't capture in promiscuous mode&lt;br /&gt;  -y &amp;lt;link type&amp;gt;           link layer type (def: first appropriate)&lt;br /&gt;  -D                       print list of interfaces and exit&lt;br /&gt;  -L                       print list of link-layer types of iface and exit&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Great, just great.  You can't even accept your own &lt;a href=http://www.wireshark.org/docs/dfref/&gt;syntax&lt;/a&gt; as a capture filter, just as a display one.  I'm trying to reduce file size here...&lt;br /&gt;&lt;br /&gt;&lt;H1&gt;What's the point?&lt;/h1&gt;&lt;br /&gt;So anyway, to make life easy I did a nice javascript app, as I love to do sooooo much and &lt;a href=http://qaa.ath.cx/tcpdump_filter.html&gt;you can use it here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So we go back to my initial packet and copy and paste it in the gargantuan textarea and click the only button there 'process'.&lt;br /&gt;&lt;br /&gt;After you click on the obvious blue links, something magical starts to happen:&lt;br /&gt;&lt;img src=http://qaa.ath.cx/filter.png&gt;&lt;br /&gt;&lt;br /&gt;The filter syntax shows up for you.  You don't have to play CSI Miami and count the bytes with VB by hand or something any more.  Welcome to the 1980s ... you can use a mouse and construct a filter with ease. Enjoy.&lt;br /&gt;&lt;br /&gt;It's worth mentioning that there is actually no protocol level analysis being done.  If you have a radiotap header, the silly javascript app won't know.  If you are listening on a device without an ethernet layer, such as tun0 or tun1, it will also not know.  You basically need to be listening on wired ethernet.  But that isn't hard now, is it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-5455533231555367771?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/5455533231555367771/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/simplifying-libpcap-filter-creation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/5455533231555367771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/5455533231555367771'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/simplifying-libpcap-filter-creation.html' title='Simplifying libpcap filter creation'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-5993178836587277303</id><published>2009-12-06T07:38:00.000-08:00</published><updated>2009-12-06T07:45:43.039-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JS'/><category scheme='http://www.blogger.com/atom/ns#' term='Challenge'/><title type='text'>JS Challenge #1</title><content type='html'>&lt;span style="font-size:130%;"&gt;Self Evaluating JS&lt;/span&gt;&lt;br /&gt;Here is an example:&lt;br /&gt;&lt;pre&gt;&amp;lt;div id=toexec&amp;gt;&lt;br /&gt;"Hello World&amp;lt;!--".replace("Hello World",'"Goodbye World"');//--&amp;gt;"&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;button onclick=exec()&amp;gt;Exec&amp;lt;/button&amp;gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;&lt;br /&gt;function exec(){&lt;br /&gt;      var n = document.getElementById('toexec');&lt;br /&gt;      n.innerHTML = eval(n.innerHTML);&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;The Challenge&lt;/span&gt;&lt;br /&gt;Actually there isn't one.  I just really like that code&lt;br /&gt;&lt;br /&gt;&lt;a href="http://qaa.ath.cx/pexec.html"&gt;http://qaa.ath.cx/pexec.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-5993178836587277303?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/5993178836587277303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/js-challenge-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/5993178836587277303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/5993178836587277303'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/js-challenge-1.html' title='JS Challenge #1'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-382863239675702491</id><published>2009-12-06T07:14:00.001-08:00</published><updated>2009-12-06T07:20:08.463-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Challenge'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>CSS Challenge #3</title><content type='html'>No diagram for this.&lt;br /&gt;&lt;br /&gt;The challenge is to define some CSS so that you can do basic math operations.  I have a nice working example hidden away.&lt;br /&gt;&lt;br /&gt;The specs are &lt;br /&gt;&lt;br /&gt;class="number operator number"&lt;br /&gt;&lt;br /&gt;where number is &lt;b&gt;one of&lt;/b&gt; [one, two, three, four, five, six, seven, eight, nine]&lt;br /&gt;&lt;br /&gt;and operator is either [plus, minus]&lt;br /&gt;&lt;br /&gt;So that if you do&lt;br /&gt;&amp;lt;div class='three plus eight' /&amp;gt;&lt;br /&gt;&lt;br /&gt;you'll see say, 11 squares or some other kind of unit.&lt;br /&gt;&lt;br /&gt;Extra points if you can make negatives work too.&lt;br /&gt;&lt;br /&gt;You ought to be able to do it in 12 definitions or less...&lt;br /&gt;&lt;br /&gt;good luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-382863239675702491?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/382863239675702491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/css-challenge-3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/382863239675702491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/382863239675702491'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/css-challenge-3.html' title='CSS Challenge #3'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-9097166743491979130</id><published>2009-12-06T06:54:00.001-08:00</published><updated>2009-12-06T07:04:11.098-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Challenge'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>CSS Challenge #2</title><content type='html'>Same HTML as #1, but the CSS must be within this:&lt;pre&gt;&lt;br /&gt;div { /* You probably need at least this */ }&lt;br /&gt;body{ /* and you can use this too */ }&lt;br /&gt;&lt;/pre&gt;&lt;img src=http://qaa.ath.cx/cc2.png&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-9097166743491979130?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/9097166743491979130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/css-challenge-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/9097166743491979130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/9097166743491979130'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/css-challenge-2.html' title='CSS Challenge #2'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-1386076031243305182</id><published>2009-12-06T06:45:00.000-08:00</published><updated>2009-12-06T06:48:03.458-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Challenge'/><category scheme='http://www.blogger.com/atom/ns#' term='CSS'/><title type='text'>CSS Challenge #1</title><content type='html'>So I give you the HTML, you give me the CSS:&lt;br /&gt;&lt;img src=http://qaa.ath.cx/csschallenge1.png&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; &amp;lt;div style=border-color:lime /&amp;gt;&lt;br /&gt; &amp;lt;div style=border-color:yellow /&amp;gt;&lt;br /&gt; &amp;lt;div style=border-color:red /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-1386076031243305182?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/1386076031243305182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/css-challenge-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1386076031243305182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1386076031243305182'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/css-challenge-1.html' title='CSS Challenge #1'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-8377969729621232319</id><published>2009-12-06T06:27:00.000-08:00</published><updated>2009-12-06T06:30:33.230-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='Challenge'/><title type='text'>Programming Challenge #2</title><content type='html'>If you can solve 1, you can solve 2&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;main(){&lt;br /&gt;        char ByModifyingThis[]="What happened?";&lt;br /&gt;        char printThis[]="You won!";&lt;br /&gt;&lt;br /&gt;        // your space&lt;br /&gt;        &lt;br /&gt;        printf("%s",ByModifyingThis);&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-8377969729621232319?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/8377969729621232319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/programming-challenge-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/8377969729621232319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/8377969729621232319'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/programming-challenge-2.html' title='Programming Challenge #2'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-174079513976729578</id><published>2009-12-06T05:32:00.000-08:00</published><updated>2009-12-06T05:55:59.817-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='Challenge'/><title type='text'>Programming Challenge #1</title><content type='html'>Ok, first to post a correct 1 line solution wins... &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;void gettohere()&lt;br /&gt;{&lt;br /&gt;        printf("You win!");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(void) &lt;br /&gt;{&lt;br /&gt;        // From Here&lt;br /&gt;        // Without calling gettohere();&lt;br /&gt;&lt;br /&gt;        return 0;&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-174079513976729578?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/174079513976729578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/programming-challenge-1.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/174079513976729578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/174079513976729578'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/programming-challenge-1.html' title='Programming Challenge #1'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-9108080201069133155</id><published>2009-12-04T22:58:00.000-08:00</published><updated>2009-12-05T00:01:17.202-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON'/><title type='text'>Trimming JSON</title><content type='html'>&lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt; is a fairly succinct markup language.  For instance, say I have two people Bob and Alice, and I have very private records on them:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 255, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;blockquote  style="color: rgb(153, 255, 153);font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;"Bob":&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;"SSN": "502-80-2012",&lt;br /&gt;"CCNumber": "3842-4234-1023",&lt;br /&gt;"Mother's Maiden Name": "Swanson"&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-size:85%;"&gt;},&lt;br /&gt;&lt;br /&gt;"Alice":&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-size:85%;"&gt;"SSN": "312-45-1231",&lt;br /&gt;"CCNumber": "8481-3231-2234",&lt;br /&gt;"Mother's Maiden Name": "Swathmore"&lt;/span&gt;&lt;/blockquote&gt; &lt;span style="font-size:85%;"&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="color: rgb(153, 255, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Now say I wanted to put this imaginary pseudo structure in "JSON format"&lt;/span&gt;.  Conveniently enough, it already is.  No really.  I'm not kidding.  That's it. We are actually done.  Or, in a more compact form:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 255, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;{"Bob":{"SSN": "502-80-2012","CCNumber": "3842-4234-1023","Mother's Maiden Name": "Swanson"},"Alice":{"SSN": "312-45-1231","CCNumber": "8481-3231-2234","Mother's Maiden Name": "Swathmore"}}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:180%;"&gt;Unnecessary Syntax&lt;/span&gt;&lt;br /&gt;Now that's all gravy and really useful, but wait; did you know that there are only a &lt;a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Reserved_Words"&gt;few reserved words in Javascript&lt;/a&gt; and that everything else can safely be used as labels; as long as it doesn't have a space or some other reserved character.  The stuff above then could be:&lt;br /&gt;&lt;br /&gt;Before: (188b)&lt;br /&gt;&lt;span style="color: rgb(153, 255, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;{"Bob":{"SSN": "502-80-2012","CCNumber": "3842-4234-1023","Mother's Maiden Name": "Swanson"},"Alice":{"SSN": "312-45-1231",CCNumber": "8481-3231-2234","Mother's Maiden Name": "Swathmore"}}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After: (173b)&lt;br /&gt;&lt;span style="color: rgb(153, 255, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;{Bob:{SSN:"502-80-2012",CCNumber:"3842-4234-1023","Mother's Maiden Name": "Swanson"},Alice:{SSN:"312-45-1231",CCNumber:"8481-3231-2234","Mother's Maiden Name": "Swathmore"}}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Those extra bytes don't need to be transferred, really.  So don't do it.&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:180%;"&gt;Zero-information data&lt;/span&gt;&lt;br /&gt;Some information above offers Zero information.  I could, for example, specify that I will always get the fields in this order:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;SSN&lt;/li&gt;&lt;li&gt;CCNumber&lt;/li&gt;&lt;li&gt;Mother's Maiden Name&lt;/li&gt;&lt;/ol&gt;As I did above.  Given this then, those labels contain Zero information and ought to be eliminated if you care about space.  The datastructures then, could be converted into &lt;span style="font-family:courier new;"&gt;arrays&lt;/span&gt; as follows:&lt;br /&gt;&lt;br /&gt;Before: (173b)&lt;br /&gt;&lt;span style="color: rgb(153, 255, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;{Bob:{SSN:"502-80-2012",CCNumber:"3842-4234-1023","Mother's Maiden Name": "Swanson"},Alice:{SSN:"312-45-1231",CCNumber:"8481-3231-2234","Mother's Maiden Name": "Swathmore"}}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After: (101b)&lt;br /&gt;&lt;span style="color: rgb(153, 255, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;{Bob:["502-80-2012","3842-4234-1023","Swanson"],Alice:["312-45-1231","8481-3231-2234","Swathmore"]}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;There! Removing Zero-information data is quite a space saver - as long as you are competent enough to &lt;span style="font-weight: bold;"&gt;know how to keep your code and your data separate&lt;/span&gt;.&lt;span style="color: rgb(153, 255, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:180%;"&gt;&lt;br /&gt;Conceptual Run-time Analysis&lt;/span&gt;&lt;br /&gt;The above optimizations will cost you a few regular expressions on the server side before emitting it to the client but this will be saved on the client side a few ways&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Less data on the wire&lt;/li&gt;&lt;li&gt;Smaller string to parse&lt;/li&gt;&lt;li&gt;Array indexes are faster then hashmap lookups --- they just are.&lt;/li&gt;&lt;/ol&gt;So it's the cumulative time of &lt;span style="color: rgb(153, 153, 255);"&gt; &lt;span style="color: rgb(102, 102, 204);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(255, 153, 102);"&gt;(server) &lt;/span&gt;and&lt;span style="color: rgb(255, 153, 102);"&gt; &lt;/span&gt;&lt;span style="color: rgb(153, 153, 255);"&gt;&lt;span style="color: rgb(102, 102, 204);"&gt;(client)&lt;/span&gt;&lt;/span&gt;:&lt;blockquote  style="font-family:courier new;"&gt;&lt;span style="color: rgb(255, 153, 102);"&gt;extra regex - data transfer&lt;/span&gt; &lt;span style="color: rgb(102, 102, 204);"&gt;- parsing - hash overhead&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;And seeing as the server side environment is much more diverse and gives you much more options then clientside (where it's javascript) - there's probably more reason to believe that this is a feasible net gain then not.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Questionable Optimizations&lt;/span&gt;&lt;br /&gt;There are further steps that you can do for byte-count reduction --- but it is fairly questionable whether there will be a cumulative performance gain.  I've broken the further steps down to a few methods:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Data Structure Flattening&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Some background&lt;/span&gt;&lt;br /&gt;In C, when you declare a multi-dimensional array, say 50x50, you can either index the array as you defined it, say using something like [4][20]; or you could just ignore it and treat the datastructure as it exists in memory, just a sequence of 250 units.   You can cast the datastructure to the generic pointer type and then index it at [4 * 50 + 20] - sometimes it's easier, sometimes it isn't.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Flattening JSON&lt;/span&gt;&lt;br /&gt;Let's revisit our previous datastructure and the principles of Zero Information.  If we know that the structure will be something like this:&lt;br /&gt;&lt;span style="color: rgb(153, 255, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;{ name: [3 fields], name: [3 fields], ... name: [3 fields] }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then we &lt;span style="font-style: italic;"&gt;could&lt;/span&gt; utilize a trick very similar to the C one discussed above.  That is to say, just make the datastructure one gigantic array:&lt;br /&gt;&lt;br /&gt;Before: (101b)&lt;br /&gt;&lt;span style="color: rgb(153, 255, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(153, 255, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;{Bob:["502-80-2012","3842-4234-1023","Swanson"],Alice:["312-45-1231","8481-3231-2234","Swathmore"]}&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;After: (99b)&lt;br /&gt;&lt;span style="color: rgb(153, 255, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;["Bob","502-80-2012","3842-4234-1023","Swanson","Alice",&lt;br /&gt;"312-45-1231","8481-3231-2234","Swathmore"]&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;There's a few important things we have to give up: First we no longer have 'labels' so the quotes have to go back in, adding a few bytes.  But as a result, we can simplify the syntax a bit.  Iterating through this can be done in many ways and the optimal one depends largely on the context of the data usage.  It is however questionable, whether having to do additional math overhead is worth the extra 2 bytes.  But there is, however, one more optimization we can do in this field&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Stringifying&lt;br /&gt;&lt;/span&gt;If we are willing to take the math overhead in stride, why don't we just go all the way then and simply make the data CSV - wherein you only need to quote things that have the reserved characters:&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Before: (99b)&lt;br /&gt;&lt;span style="color: rgb(153, 255, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;["Bob","502-80-2012","3842-4234-1023","Swanson","Alice",&lt;br /&gt;"312-45-1231","8481-3231-2234","Swathmore"]&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After: (83b)&lt;br /&gt;&lt;span style="color: rgb(153, 255, 153);font-size:85%;" &gt;&lt;span style="font-family:courier new;"&gt;"Bob,502-80-2012,3842-4234-1023,Swanson,Alice,312-45-1231,8481-3231-2234,Swathmore"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Transferring the output into a place usable for Javascript is debatable.  You can't just split on the ',' since you need to accommodate for the escaped \'.&lt;br /&gt;&lt;br /&gt;So you make yourself a nice regex to do the split and come up with an array at the end.  But this is foolish. What you really ought to do is use the &lt;a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp/exec"&gt;exec&lt;/a&gt; method and work your way through the string.  This is of course, quite a bit more work then the code above.&lt;br /&gt;&lt;br /&gt;This more work means more javascript code, more lines to execute, more lines to compile, etc.  Is it worth it?  Eh, don't know ... really, I don't.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Tables&lt;br /&gt;&lt;/span&gt;Another thing we could do is to have substitution tables.  For instance, let's say that when you analyze your data-structure after you've done the Zero-information removal techniques above, you still see a lot of redundancy; simply because there is a user that is very active, or something else of that nature.  You can then make a static lookup table and implement it in JS and your server side scripting language of choice.  During the JSON generation you simply swap things out.  For instance, pretend we have this data set:&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;br /&gt;&lt;span style="color: rgb(153, 255, 153);"&gt;{Alice:["Marina Del Rey","California"],Bob:["Marina Del Rey","California"],Eve:["Playa Del Rey", "California"],Doug:["Playa Del Rey","California"]}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This would be likely say, if you are a local company and have local clients in these areas.  You already have the fancy gzip compression and decompression on the server and client side, so you think you are good there, but not really:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;gzip still needs to pass over the strings on both sides; parse them, create the tables, allocate the memory - etc.  It's real CPU time that you don't need to spend&lt;/li&gt;&lt;li&gt;Javascript needs to do the same stuff.&lt;/li&gt;&lt;/ol&gt;So you just make a simple table:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 255, 153);font-family:courier new;font-size:85%;"  &gt;var C = {&lt;br /&gt;  MDR:"Marina Del Rey",&lt;br /&gt;  CA:"California",&lt;br /&gt;  PDR:"Playa Del Rey"&lt;br /&gt;};&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Expose this on both ends and put it in your JSON encoder on the server side:&lt;br /&gt;&lt;br /&gt;Before: (149b)&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;span style="color: rgb(153, 255, 153);"&gt;{Alice:["Marina Del Rey","California"],Bob:["Marina Del Rey","California"],Eve:["Playa Del Rey", "California"],Doug:["Playa Del Rey","California"]}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After: (74b)&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;span style="color: rgb(153, 255, 153);"&gt;{Alice:[C.MDR,C.CA],Bob:[C.MDR,C.CA],Eve:[C.PDR,C.CA],Doug:[C.PDR,C.CA]}&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Not only have you saved significant bytes, but now those entries are just pointers to pre-existing strings in a table, so JS doesn't have to allocate new memory for it.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;Dynamic Tables&lt;/span&gt;&lt;br /&gt;If you really enjoy hitting your server CPU hard, you could create dynamic tables:&lt;span style="color: rgb(153, 255, 153);font-family:courier new;font-size:85%;"  &gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Before: (149b)&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;span style="color: rgb(153, 255, 153);"&gt;{Alice:["Marina Del Rey","California"],Bob:["Marina Del Rey","California"],Eve:["Playa Del Rey", "California"],Doug:["Playa Del Rey","California"]}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After: (136b)&lt;br /&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;span style="color: rgb(153, 255, 153);"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(153, 255, 153);font-family:courier new;font-size:85%;"  &gt;C:{MDR:"Marina Del Rey",CA:"California",PDR:"Playa Del Rey"}&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;span style="color: rgb(153, 255, 153);"&gt;&lt;br /&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;&lt;span style="color: rgb(153, 255, 153);"&gt;Alice:[C.MDR,C.CA],Bob:[C.MDR,C.CA],Eve:[C.PDR,C.CA],Doug:[C.PDR,C.CA]}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But this is not recommended.  Because you aren't doing the zero-information principle which is to remove, not just rearrange.  What you have done above is just complicate things for a what may actually work out to be no byte gain at all, and will certainly be more CPU intensive to generate and parse on both the client and the server side.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-9108080201069133155?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/9108080201069133155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/trimming-json-in-php.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/9108080201069133155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/9108080201069133155'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/trimming-json-in-php.html' title='Trimming JSON'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8573056240198184825.post-1088230669200693986</id><published>2009-12-04T21:43:00.001-08:00</published><updated>2012-02-07T13:02:52.873-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='sysadmin'/><category scheme='http://www.blogger.com/atom/ns#' term='analytics'/><title type='text'>Geoiplookup script</title><content type='html'>I found a syntax error in one of our javascript files for the insertion of Google Analytics. This of course meant that the results were flatlined:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_vZwPDmFhwUw/Sxnzx49zIPI/AAAAAAAAAAM/4_ndkSH3RdU/s1600-h/flatline.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 142px;" src="http://2.bp.blogspot.com/_vZwPDmFhwUw/Sxnzx49zIPI/AAAAAAAAAAM/4_ndkSH3RdU/s320/flatline.png" alt="" id="BLOGGER_PHOTO_ID_5411624465693090034" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;On December 4th, however we officially 'launched'.  Their are now two problems:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;How much traffic did we get on Dec 2 - 4?&lt;/li&gt;&lt;li&gt;Where did this traffic come from?&lt;/li&gt;&lt;/ol&gt;The first question is relatively easy to answer. Since we use &lt;a href="http://nginx.net/"&gt;nginx &lt;/a&gt;as a proxy for apache, I went over to &lt;span style="font-family:courier new;"&gt;/var/log/nginx&lt;/span&gt; and gunzip'd a few log files... nothing fancy.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;How much traffic did we get on Dec 2 - 4&lt;/span&gt;&lt;br /&gt;To find out how many unique visitors there were over the span of four log files we do the following pseudo-code:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(0,0,0);font-size:85%;" &gt;print logs | show only the ip address for each line | find the unique ones | give me the count&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;This becomes&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0,0,0);font-size:85%;" &gt;$ &lt;span style="font-weight: bold;"&gt;cat www.izuu.com.access.log www.izuu.com.access.log.[1-3] |  awk ' { print $1 } ' | sort | uniq | wc -l&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-size:85%;" &gt;315&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Not bad.  To do it date based, we just add a grep line in the stack:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-size:100%;"&gt;December 2nd:&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-size:85%;" &gt;$ &lt;span style="font-weight: bold;"&gt;cat www.izuu.com.access.log www.izuu.com.access.log.[1-3] &lt;span style="color: rgb(0,0,0);"&gt;| grep 02\/Dec&lt;/span&gt; | awk ' { print $1 } ' | sort | uniq | wc -l&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-size:85%;" &gt;52&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;December 3rd:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;$ &lt;span style="font-weight: bold;"&gt;cat www.izuu.com.access.log www.izuu.com.access.log.[1-3] &lt;span style="color: rgb(0,0,0);"&gt;| grep 03\/Dec&lt;/span&gt; | awk ' { print $1 } ' | sort | uniq | wc -l&lt;/span&gt;&lt;br /&gt;59&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;December 4th:&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;$ &lt;span style="font-weight: bold;"&gt;cat www.izuu.com.access.log www.izuu.com.access.log.[1-3] &lt;span style="color: rgb(0,0,0);"&gt;| grep 04\/Dec&lt;/span&gt; | awk ' { print $1 } ' | sort | uniq | wc -l&lt;/span&gt;&lt;br /&gt;204&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Nice healthy jump there.  But wait, there's more.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;Where did this traffic come from?&lt;/span&gt;&lt;br /&gt;In order to do this I found a tool called &lt;span style="font-family:courier new;"&gt;geoiplookup&lt;/span&gt; - which is available in the apt repositories.&lt;br /&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;&lt;br /&gt;$ &lt;span style="font-weight: bold;"&gt;apt-cache search geo | grep IP&lt;/span&gt;&lt;br /&gt;libgeoip-dev - Development files for the GeoIP library&lt;br /&gt;libgeoip1 - A non-DNS IP-to-country resolver library&lt;br /&gt;python-geoip - python bindings for the GeoIP IP-to-country resolver library&lt;br /&gt;python-geoip-dbg - python bindings for the GeoIP IP-to-country resolver library (debug extension)&lt;br /&gt;geoip-bin - IP lookup command line tools that use the GeoIP library&lt;br /&gt;kipi-plugins - image manipulation/handling plugins for KIPI aware programs&lt;br /&gt;libapache2-mod-geoip - GeoIP support for apache2&lt;br /&gt;libgeo-ip-perl - Perl bindings for GeoIP library&lt;br /&gt;php5-geoip - GeoIP module for php5&lt;br /&gt;tclgeoip - Tcl extension implementing GeoIP lookup functions&lt;br /&gt;tor-geoipdb - geoIP database for Tor&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;$ &lt;span style="font-weight: bold;"&gt;sudo apt-get install &lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0); font-weight: bold;font-family:courier new;font-size:85%;"  &gt;geoip-bin&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-family:courier new;"&gt;geoiplookup&lt;/span&gt; tool &lt;span style="font-style: italic;"&gt;only comes with a database that narrows the IP address to a specific country&lt;/span&gt; --- which is not very interesting.  However, &lt;a href="http://www.google.com/search?q=geoip+city+database"&gt;using the magic oracle&lt;/a&gt;, I discovered a much more specific &lt;span style="font-weight: bold;"&gt;city-based database&lt;/span&gt; at &lt;a href="http://geolite.maxmind.com/download/geoip/database/"&gt;http://geolite.maxmind.com/download/geoip/database/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;so then I did a nice:&lt;br /&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;$ &lt;span style="font-weight: bold;"&gt;cd&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;$ &lt;span style="font-weight: bold;"&gt;wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Thought a few seconds... then gave up:&lt;br /&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;&lt;br /&gt;$ &lt;span style="font-weight: bold;"&gt;man geoiplookup&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold; color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;OPTIONS&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;      &lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt; -f Specify a custom path to a single GeoIP datafile.&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="color: rgb(0,0,0);font-size:85%;" &gt;       -d Specify a custom directory containing GeoIP datafile(s).  By default geoiplookup looks in /usr/share/GeoIP&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;Wow, that's damn confusing. Is this right?:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;$ &lt;span style="font-weight: bold;"&gt;mkdir geo&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;$ &lt;span style="font-weight: bold;"&gt;mv GeoLiteCity.dat.gz geo&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;$ &lt;span style="font-weight: bold;"&gt;cd geo&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;$ &lt;span style="font-weight: bold;"&gt;gunzip GeoLiteCity.dat.gz&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;$ &lt;span style="font-weight: bold;"&gt;geoiplookup -f ~/geo/ 4.2.2.4&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;Error Traversing Database for ipnum = 67240452 - Perhaps database is corrupt?&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;Segmentation fault&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;$&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Lovely.  So the next step&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;$ &lt;span style="font-weight: bold;"&gt;strace !! |&amp;amp; less&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;...&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;brk(0)                                  = 0x603000&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;brk(0x624000)                           = 0x624000&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;open("/home/chris/geo/", O_RDONLY)      = 3&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;fstat(3, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f866a21f000&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;fstat(3, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It's rather pathetic when strace gives you better documentation then the man page.  It clearly wants the full path.&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;$ &lt;span style="font-weight: bold;"&gt;geoiplookup -f ~/geo/GeoLiteCity.dat 4.2.2.4&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;GeoIP City Edition, Rev 1: US, (null), (null), (null), 38.000000, -97.000000, 0, 0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Final Packaging&lt;/span&gt;&lt;br /&gt;Ok, that's the ticket.  Now we just do a little bit of xargs:&lt;br /&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;font-size:85%;"  &gt;$ &lt;span style="font-weight: bold;"&gt;cat www.izuu.com.access.log www.izuu.com.access.log.[1-3] | grep 04\/Dec | awk ' { print $1 } ' | sort | uniq &lt;span style="color: rgb(0,0,0);"&gt;| xargs -n 1 geoiplookup -f ~/geo/GeoLiteCity.dat&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;That does the trick, but now we have this huge ass "&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:arial;"&gt;GeoIP City Edition, Rev 1:" in front of everything.  That's ok, I know sed ... let's make it ordered by country too:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0,0,0);font-size:85%;" &gt;$ &lt;span style="font-weight: bold;"&gt;cat www.izuu.com.access.log www.izuu.com.access.log.[1-3] | grep 04\/Dec | awk ' { print $1 } ' | sort | uniq | xargs -n 1 geoiplookup -f ~/geo/GeoLiteCity.dat &lt;span style="color: rgb(0,0,0);"&gt; | sort | sed s/^.\*:\ //g&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ah, almost complete.  Now we just need to mail it off so I can forward it to the boss&lt;br /&gt;&lt;span style="color: rgb(0,0,0);font-family:courier new;" &gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;$ &lt;/span&gt;&lt;span style="font-weight: bold;font-size:85%;" &gt;cat www.izuu.com.access.log www.izuu.com.access.log.[1-3] | grep 04\/Dec | awk ' { print $1 } ' | sort | uniq | xargs -n 1 geoiplookup -f ~/geo/GeoLiteCity.dat  | sort | sed s/^.\*:\ //g &lt;span style="color: rgb(0,0,0);"&gt;| mail cmckenzie&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And there.  Then I have a nice list of stuff to give to the boss that albeit, not graphical, is still digestible and better then a line at 0... sw33t.&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8573056240198184825-1088230669200693986?l=kristopolous.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://kristopolous.blogspot.com/feeds/1088230669200693986/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://kristopolous.blogspot.com/2009/12/roll-your-own-geo-ip-location.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1088230669200693986'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8573056240198184825/posts/default/1088230669200693986'/><link rel='alternate' type='text/html' href='http://kristopolous.blogspot.com/2009/12/roll-your-own-geo-ip-location.html' title='Geoiplookup script'/><author><name>kristopolous</name><uri>http://www.blogger.com/profile/03488643479825208921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_vZwPDmFhwUw/Sxnzx49zIPI/AAAAAAAAAAM/4_ndkSH3RdU/s72-c/flatline.png' height='72' width='72'/><thr:total>0</thr:total></entry></feed>
