<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
	<channel>
		<title>McArthur GFX</title>
		<link>http://mcarthurgfx.com</link>
		<description>notes from a web developer</description>
		<pubDate>Wed, 10 Mar 2010 15:19:00 -0800</pubDate>
		<generator>http://www.blazonco.com/</generator>
		<language>en</language>
				<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/mcarthurgfx" /><feedburner:info uri="mcarthurgfx" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>mcarthurgfx</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
			<title>The Search for a Decent Windows Twitter App</title>
			<link>http://feedproxy.google.com/~r/mcarthurgfx/~3/HLclTqXe-ZQ/the-search-for-a-decent-windows-twitter-app</link>
			<comments>http://mcarthurgfx.com/blog/article/the-search-for-a-decent-windows-twitter-app#comments</comments>
			<pubDate>Wed, 10 Mar 2010 15:19:00 -0800</pubDate>
			<dc:creator>Sean</dc:creator>
						<category><![CDATA[Blogging]]></category>
						<category><![CDATA[Tools]]></category>
						
			<guid isPermaLink="false">http://mcarthurgfx.com/blog/article/the-search-for-a-decent-windows-twitter-app</guid>
			<description><![CDATA[<p>
<p>I kinda like&nbsp;<a href="http://twitter.com/seanmonstar" target="_blank">Twitter</a>. It&rsquo;s a fun place to leave&nbsp;<a href="http://mcarthurgfx.com/blog/article/i-m-a-twitter-monstar" target="_blank">occasional comments</a>. It&rsquo;s also a great way to find links to interesting information I would normally miss from my feeds. But being a Windows user, I have yet to find&nbsp;<strong>that</strong>&nbsp;Twitter application that is a joy to use.</p>
<p>I&rsquo;ve tried out a couple applications, and found each one lacking:</p>
<ul>
<li><a href="http://www.tweetdeck.com/" target="_blank">Tweetdeck</a></li>
<li><a href="https://destroytwitter.com/" target="_blank">DestroyTwitter</a></li>
<li><a href="http://seesmic.com/seesmic_desktop/windows/" target="_blank">Seesmic</a></li>
</ul>
<p>There might be a decent application out there that I haven&rsquo;t found, but these are the most popular ones available to Windows. It almost feels like people only want to make cool stuff for Macs.</p>
</p>]]></description>
			<content:encoded><![CDATA[<p>I kinda like <a href="http://twitter.com/seanmonstar" target="_blank">Twitter</a>. It&rsquo;s a fun place to leave <a href="http://mcarthurgfx.com/blog/article/i-m-a-twitter-monstar" target="_blank">occasional comments</a>. It&rsquo;s also a great way to find links to interesting information I would normally miss from my feeds. But being a Windows user, I have yet to find <strong>that</strong> Twitter application that is a joy to use.</p>
<p>I&rsquo;ve tried out a couple applications, and found each one lacking:</p>
<ul>
<li><a href="http://www.tweetdeck.com/" target="_blank">Tweetdeck</a> </li>
<li><a href="https://destroytwitter.com/" target="_blank">DestroyTwitter</a> </li>
<li><a href="http://seesmic.com/seesmic_desktop/windows/" target="_blank">Seesmic</a></li>
</ul>
<p>There might be a decent application out there that I haven&rsquo;t found, but these are the most popular ones available to Windows. It almost feels like people only want to make cool stuff for Macs.</p>
<h4>Tweetdeck</h4>
<p>Although it&rsquo;s hugely popular by many, I can&rsquo;t help but get annoyed at parts of Tweetdeck. To be fair, it&rsquo;s the closest I have found that meets my needs, but that&rsquo;s not good enough for me. It can easily handle auto-completing of replies, inserting photos and shortening links. It&rsquo;s built with the idea of lists in mind, which I particularly like. I&rsquo;ve currently got a list about MooTools and a list about games. Unfortunately, I have no option of telling the main list to ignore tweets from anyone in a separate list. I don&rsquo;t want my main list filled with tweets about stuff I&rsquo;ve already put into it&rsquo;s own list. I just want a list of &ldquo;everyone else&rdquo;, but without having to create such a list and add every new person I follow to it.</p>
<p><img src="http://mcarthurgfx.com/images/blog/tweetdeck.png" alt="" /></p>
<p>I also have gripes about it&rsquo;s UI. Marking Tweets as &ldquo;Read&rdquo; requires <em>clicking individually on this tiny, 5px wide circle</em>. And then after doing that, I must click at the bottom of the list of a tiny icon to &ldquo;Clear Read&rdquo;. And I often accidentally click on &ldquo;Clear All&rdquo;, since they&rsquo;re right next to each other, and they&rsquo;re so small it takes to long to visually register what each icon is.</p>
<p>The notifications system is buggy. Sometimes it hides the summary behind a window, sometimes not. Clicking the notification will bring up Tweetdeck. But sometimes, the notification won&rsquo;t dismiss itself. Ever. You can hide Tweetdeck again and have a frozen notification sitting in the corner of your screen. The only way to dismiss it is to click it again. The usual behavior is that it should dismiss regardless after a few seconds.</p>
<p>And it&rsquo;s an AIR application. Now, granted, AIR is pretty cool. It lets front-end developers create apps for the desktop. But given a choice, why would I want to run something in a Flash player all the time? <strong>It chews on my memory like a puppy that is teething</strong>. It lacks plenty of things that I&rsquo;m used to having in a Windows app. And it&rsquo;s integration is buggy (see above about notifications). Next.</p>
<h4>DestroyTwitter</h4>
<p>While it&rsquo;s also an AIR app, which means I have similar complaints in that regard, it&rsquo;s actually less buggy than Tweetdeck. Notifications don&rsquo;t stick. I still miss my normal Windows feel though.</p>
<p>It has a much nicer way of handling Mark as Read: just check the option in settings to Mark as Read on rollover. And overall, the UI feels much nicer to use than Tweetdeck. You don&rsquo;t have to hover over the avatar to find your common actions like replying or retweeting.</p>
<p><img src="http://mcarthurgfx.com/images/blog/destroy-twitter.png" alt="" /></p>
<p>However, it doesn&rsquo;t support lists at all. None. Just a single stream of tweets. No thanks.</p>
<h4>Seesmic</h4>
<p>A native Windows client, and it doesn&rsquo;t have the Windows XP look either. It generally looks sweet, feels rather Windows-y. I like that it has useful context menus when I right click on things. It&rsquo;s design is <span style="text-decoration: line-through;">decent</span> excellent. But <strong>it&rsquo;s severally lacking in features</strong>. Severely.</p>
<p><img src="http://mcarthurgfx.com/images/blog/seesmic-windows.jpg" alt="" /></p>
<p>It can&rsquo;t load images from common sources like yfrog, it just launches the browser. While it doesn&rsquo;t have automatic URL shortening, it does have an Insert Link ability. But my attempts to use it show that it handles errors poorly:</p>
<pre class="html">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;bitly&gt;
	&lt;errorCode&gt;0&lt;/errorCode&gt;
	&lt;errorMessage&gt;&lt;/errorMessage&gt;
	&lt;results&gt;
		&lt;nodeKeyVal&gt;
			&lt;errorCode&gt;101&lt;/errorCode&gt;
			&lt;errorMessage&gt;Unknown error&lt;/errorMessage&gt;
			&lt;nodeKey&gt;&lt;![CDATA[http://google.com]]&gt;&lt;/nodeKey&gt;
			&lt;statusCode&gt;ERROR&lt;/statusCode&gt;
		&lt;/nodeKeyVal&gt;
	&lt;/results&gt;
	&lt;statusCode&gt;OK&lt;/statusCode&gt;
&lt;/bitly&gt;</pre>
<p><small>Seesmic just dumped that straight into my message. And then it kindly warns me that I&rsquo;m 282 characters over the limit.</small></p>
<p>While it supports lists, it has the same issues as Tweetdeck in that regard. But, clearing the timelines can also be wonky. I&rsquo;ve clear my MooTools list timeline, and then added a new person to the list, and it just went out and refilled the entire timeline. Er, thanks.</p>
<p><strong>And it&rsquo;s bugtastic</strong>. Maximizing the window hides away the normal minimize/close buttons. You have to just click in the area and hope you guessed correctly. Even with notifications turned on, I have yet to see a single notification. It regularly errors when trying to get more tweets, and leaves me without updates for long periods of time.</p>
<h4>web</h4>
<p>Ultimately, at home, it&rsquo;s just easier to use the web client. None of the clients I have found are good enough to do light browsing with. I do most of my reading at work, so when I bother to log on at home, I just want the latest part that I haven&rsquo;t read yet. <strong>None of the applications I&rsquo;ve tried seemed to have syncing</strong>. Loading one up at home would just dump the whole days worth of tweets into my timeline, and that&rsquo;s useless to me.</p>
<p>Since the web application defaults to showing me the latest tweets, that&rsquo;s usually all the ones I want to see anyways. Replying and retweeting are easy enough, although it would be great if it automatically shortened URLs for me.</p>
<h4>&ldquo;That&rdquo; Twitter App</h4>
<p>The application I&rsquo;m looking for is a native client to Windows, doesn&rsquo;t look like it came from the year 2000 in terms of UI, and has many of the features you&rsquo;d hope to have in a Twitter client: <em>URL shortening, image loading, notifications, and lists</em>. I&rsquo;d love the option to remove all listed people from my main timeline, but whatever. <strong>If it has those features, looks pretty (and is intuitive), and isn&rsquo;t the buggiest piece of code in the world, I&rsquo;d like to use it</strong>. But it really seems like so many developers only like making things for Macs now. There&rsquo;s got to be developers who still work on Windows&hellip; or maybe I should just break out the C#-fu&hellip;.</p><hr />
<h3>Follow me on Twitter</h3>
<p>I have little spurts of ingenuity on Twitter, follow me: <a href="http://twitter.com/seanmonstar">@seanmonstar</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=HLclTqXe-ZQ:zaGYgqUmids:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=HLclTqXe-ZQ:zaGYgqUmids:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?i=HLclTqXe-ZQ:zaGYgqUmids:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/mcarthurgfx/~4/HLclTqXe-ZQ" height="1" width="1"/>]]></content:encoded>
		<feedburner:origLink>http://mcarthurgfx.com/blog/article/the-search-for-a-decent-windows-twitter-app</feedburner:origLink></item>
				<item>
			<title>A Less-Random Generator</title>
			<link>http://feedproxy.google.com/~r/mcarthurgfx/~3/_PwqEb3BtFA/a-less-random-generator</link>
			<comments>http://mcarthurgfx.com/blog/article/a-less-random-generator#comments</comments>
			<pubDate>Wed, 03 Mar 2010 13:52:00 -0800</pubDate>
			<dc:creator>Sean</dc:creator>
						<category><![CDATA[Opinion]]></category>
						<category><![CDATA[Python]]></category>
						
			<guid isPermaLink="false">http://mcarthurgfx.com/blog/article/a-less-random-generator</guid>
			<description><![CDATA[<p>In game development, it's very common to want a random number. Maybe you want to determine damage done, if there was a critical, or what slot on the board to insert your piece at. And surprisingly (or perhaps, not), programmers are often looking to make this random number a little less...&nbsp;<em>random.</em></p>
<p><a href="http://mcarthurgfx.com/blog/article/a-less-random-generator"><img style="border: 0px initial initial;" src="http://monstar.blazonco.com/images/blog/dice-o-matic.jpg" alt="dice-o-matic" /></a></p>]]></description>
			<content:encoded><![CDATA[<p>In game development, it's very common to want a random number. Maybe you want to determine damage done, if there was a critical, or what slot on the board to insert your piece at. And surprisingly (or perhaps, not), programmers are often looking to make this random number a little less... <em>random.</em></p>
<h4>Less Random, you say?</h4>
<p>Yea, seriously. We really don't want a real random number, because <strong>random is too random</strong>. Backgammon players rage on about how un-random virtual dice rolls are, and programmers can go to <a href="http://gamesbyemail.com/News/DiceOMatic" target="_blank">extreme circumstances to provide the right kind of random</a>.</p>
<p><a href="http://gamesbyemail.com/News/DiceOMatic"><img src="http://monstar.blazonco.com/images/blog/dice-o-matic.jpg" alt="dice-o-matic" /></a></p>
<p>Role playing games have to overcome this too-random problem as well. In an RPG, you might be getting a random number to determine if the player character hit the monster. And considering the situations you find yourself in when playing an RPG, this dramatic but randomly generated experience can really suck:</p>
<blockquote>
<p>A blade spider is at your throat. It hits and you miss. It hits again and you miss again. And again and again, until there's nothing left of you to hit. You're dead and there's a two-ton arachnid gloating over your corpse. Impossible? No. Improbable? Yes. But given enough players and given enough time, the improbable becomes almost certain. It wasn't that the blade spider was hard, it was just bad luck. How frustrating. It's enough to make a player want to quit.</p>
<p><cite><a href="http://www.gamedev.net/reference/design/features/randomness/">&mdash;Randomness without Replacement</a></cite></p>
</blockquote>
<p>It&rsquo;s really quite interesting how much we really don&rsquo;t want real randomness. Because real randomness is not biased. Pure randomness doesn&rsquo;t care if that&rsquo;s your 20th "1" in a row. It can lead to frustration, and cause people to blame the game for sucking, when really it was just a bad sequence of random numbers.</p>
<h4>How We Perceive Random</h4>
<p>It turns out, when we say random, as a player, we actually mean controlled random. Compare these images of dots plotted on a grid:</p>
<p><img src="http://monstar.blazonco.com/images/blog/random-vs-distributed.png" alt="" /></p>
<p>Which picture looks like the random we want? Apparently, the first is too random for humans. What I mean is, it doesn't look random. We quickly identify patterns in the truly random picture. We see groupings and think there must have been numbers that were favored to get that result. We want to believe that randomness will evenly distribute it&rsquo;s results across the spectrum. No patterns, no missed numbers, no repeats. Even.</p>
<p>The truth behind these 2 images is that the left image is a true random plot. The image on the right was controlled.</p>
<blockquote>
<p>The plot on the right is [&hellip;] composed of 64 smaller squares, each of which has 4 points placed at random. People don't like the leftmost plot because it has several clumps of points that seem non-random. In fact, true randomness consists of a mixture of clumps and non-clumps. <strong>Randomness is different from homogeneity.</strong></p>
<p><cite><a href="http://norvig.com/experiment-design.html">&mdash;Warning Signs in Experimental Design and Interpretation</a></cite></p>
</blockquote>
<h4>A programmers solution</h4>
<p>The way to handle controlled randomness is actually pretty simple. It&rsquo;s commonly called a <strong>shuffle bag</strong>. The principle is that you take a bunch of tokens and put them in a bag. Then when you need another value, you pull a token out of the bag, and use that. Once the bag is empty, you fill it back up again.</p>
<p>You can control the percentage of a positive or negative result by setting the ratio of tokens you insert into the bag. You can also control what sort of &ldquo;sprees&rdquo; you can get from you bag by inserting duplicate values.</p>
<p>For example, with 1 hit value and 1 miss value, you have a 50% (1/2) chance of hitting. You also have the possibility of getting 2 misses or hits in a row. If you changed that to contain 5 hits and 5 misses in the bag, you could possibly end up with 10 in a row.</p>
<pre><code>import random

class ShuffleBag(object):
	
	def __init__(self, values):
		self.values = values
		self.list = None
	
	def next(self):
		if (self.list is None) or (len(self.list) == 0):
			self.shuffle()
		return self.list.pop()
	
	def shuffle(self):
		self.list = self.values[:]
		random.shuffle(self.list)</code></pre>
<p>The usage would be pretty simple. If I want a 20% chance of getting a critical hit on a damage roll, I would implement that like so:</p>
<pre><code>bag = ShuffleBag([1, 0, 0, 0, 0])

while attacking:
	is_critical = bag.next()
	if is_critical:
		dmg = MAX_DMG
	
	doDmg(dmg)</code></pre>
<p>Who&rsquo;d have thought that you needed to do something special just to get "fun" random numbers? I think the root of it has to do with how <strong>statistics are all just a lie</strong>.</p><hr />
<h3>Follow me on Twitter</h3>
<p>I have little spurts of ingenuity on Twitter, follow me: <a href="http://twitter.com/seanmonstar">@seanmonstar</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=_PwqEb3BtFA:2fiIYSEp-us:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=_PwqEb3BtFA:2fiIYSEp-us:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?i=_PwqEb3BtFA:2fiIYSEp-us:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/mcarthurgfx/~4/_PwqEb3BtFA" height="1" width="1"/>]]></content:encoded>
		<feedburner:origLink>http://mcarthurgfx.com/blog/article/a-less-random-generator</feedburner:origLink></item>
				<item>
			<title>Iterating Global Variables in Internet Explorer</title>
			<link>http://feedproxy.google.com/~r/mcarthurgfx/~3/eAxMobGQYT0/iterating-global-variables-in-internet-explorer</link>
			<comments>http://mcarthurgfx.com/blog/article/iterating-global-variables-in-internet-explorer#comments</comments>
			<pubDate>Wed, 24 Feb 2010 08:02:00 -0800</pubDate>
			<dc:creator>Sean</dc:creator>
						<category><![CDATA[Javascript]]></category>
						
			<guid isPermaLink="false">http://mcarthurgfx.com/blog/article/iterating-global-variables-in-internet-explorer</guid>
			<description><![CDATA[<p>There's a couple ways you can define globally accessible variables in Javascript. And it turns out that in JScript, they actually mean different things (as opposed to all other implementations, where they're the same). This meant my <a href="http://monstar.blazonco.com/blog/article/get-class-of-an-instance">GetClass implementation</a> just plain wouldn't work for Internet Explorer. Well, that's no good, since that's a basic building block of my <a href="http://github.com/seanmonstar/MonstarLab-MVC" target="_blank">MooTools MVC framework</a>. Now, I could require all classes be created explicitly, like <code>window.Task</code>, but that makes for a very inflexible pattern. And there's no reasonable way to explain to users why I'm requiring that.</p>
<p>So instead, I delved into JScript to find a way to let me iterate all global variables.</p>]]></description>
			<content:encoded><![CDATA[<p>There's a couple ways you can define globally accessible variables in Javascript. And it turns out that in JScript, they actually mean different things (as opposed to all other implementations, where they're the same). This meant my <a href="http://monstar.blazonco.com/blog/article/get-class-of-an-instance">GetClass implementation</a> just plain wouldn't work for Internet Explorer. Well, that's no good, since that's a basic building block of my <a href="http://github.com/seanmonstar/MonstarLab-MVC" target="_blank">MooTools MVC framework</a>. Now, I could require all classes be created explicitly, like <code>window.Task</code>, but that makes for a very inflexible pattern. And there's no reasonable way to explain to users why I'm requiring that.</p>
<p>So instead, I delved into JScript to find a way to let me iterate all global variables. But first, here's a few ways you could declare a global variable.</p>
<pre><code>var a = 1;
window.b = 2;
c = 3;
(function(global) {
    this.d = 4;
    global.e = 5;
})(window)</code></pre>
<p><strong>Only if you specifically set the property of the window object does it get attached</strong>. The cases that are declaring variables instead of properties get added to a Variables Host object instead. Frankly, this is awful. But we come to expect this kind of shenanigans from IE.</p>
<p>This causes this iteration bug:</p>
<pre><code>for(var i in window) {
	i; //besides the usual, we'll only get
	   //b, d, and e.
}</code></pre>
<p>Thankfully, some other people have noticed this before me. <a href="http://blogs.msdn.com/ericlippert/archive/2005/05/04/414684.aspx" target="_blank">Eric Lippert</a> did much more extensive research than I needed to fix the issue. But his research assisted Thomas Frank in a way that solved my problem as well.</p>
<blockquote>
<p>This should get all our global variables, but doesn't in JScript/IE.</p>
<pre><code>var x=[];
for (var i in windows){x.push(i)};
alert(x.join("\n"));</code></pre>
<p>Well, it turns out this doesn't work in JScript/IE at all, because non-native variables are not found when we try to enumerate the window object.</p>
<p><cite><a href="http://www.thomasfrank.se/global_namespace.html" target="_blank">&mdash;Find your global namespace</a></cite></p>
</blockquote>
<p>This might not necessarily be the best solution, but using a cache, I only have to eat the execution cost once. Thomas' solution was to search all script tags for all variable declarations. This works because even though <code>a</code> in my first example doesn't get iterated through, it can still be found through a property lookup on the window global object (<code>window['a']</code>).</p>
<blockquote>
<p>The first thing I had to do was to write a workaround for IE browsers. In IE it is possible to get the complete script source for a page by looking at the <code>document.scripts</code> array.</p>
<p>If an element has no <code>innerHTML</code> value, then it is an external script and we can load the source with a simple AJAX request. We then use a little bit a regular expression magic to extract every "word" from the source(s) and check if these words exists as global variables. This works suprisingly well.</p>
</blockquote>
<p>Using his approach, modified to store all the "word" possibilities in a cache so I don't have do more ajax requests, I've cooked up the following bit to implement a sort of <code>indexOf</code> (or <code>keyOf</code>) for the window object.</p>
<pre><code>var keyOf = (Browser.Engine.trident) ? (function() {
	var xhr = function(path) {
		var request = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
		request.open('GET', path, false); //asynchronous = false
		try {
			request.send();
		} catch(e) { return null; }
		if (request.status == 500 || 
			request.status == 404 || 
			request.status == 2 ||
			(request.status == 0 &amp;&amp; request.responseText == '')) 
			return null;
			
		return request.responseText;
	}
	
	var cash = {};
	
	var ie_search = function(obj) {
		var key = search(obj) || search(obj, cash); //search does a for..in loop on window.
		if(!key) {
			//IE doesn't enumerate `var a = 'x';`, so we need to explicitly
			//declare those vars on the window object
			// credit: http://www.thomasfrank.se/downloadableJS/globalVars.js
			var scripts = document.scripts,
				src = '';
				
			for(var s = 0, len = scripts.length; s &lt; len; s++) {
				if(!scripts[s]._lookedUp) {
					if(scripts[s].innerHTML) {
						src += scripts[s].innerHTML;
					} else if (scripts[s].src) {
						src += xhr(scripts[s].src);				
					}
					scripts[s]._lookedUp = true;
				}
			}
			var idents = src.replace(/\W/g, ' ').replace(/(function|if|for|while|true|false|null|typeof|var|new|try|catch|return|prototype|this)/g, '').split(' ');
			
			for(var i = 0; i &lt; idents.length; i++) {
				var iden = idents[i].trim();
				cash[iden] = true;
				if(!key &amp;&amp; (iden in window) &amp;&amp; window[iden] == obj) {
					
					key = idents[i];
				}
			}
		}
		return key;
	}
	return ie_search;
})() : search;</code></pre>
<p>The first time you call <code>keyOf</code>, it will collect all the Javascript source for the page, and then store every possible identifier that was declared. On subsequent calls, only new scripts will be gotten and parsed. Since the values of the global variables could change at any time, I could only store in the cache their names. The search function tries all those names on the window object.</p>
<p>A definite downside I see to this method is since it uses XHR to collect the source, it wouldn't work on scripts that aren't from the same domain. But for <a href="http://github.com/seanmonstar/MonstarLab-MVC/blob/master/src/mvc/GetClass.js" target="_blank">my framework</a>, since it uses a loader anyways, it's sufficient for me.</p><hr />
<h3>Follow me on Twitter</h3>
<p>I have little spurts of ingenuity on Twitter, follow me: <a href="http://twitter.com/seanmonstar">@seanmonstar</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=eAxMobGQYT0:GuEK7Y0qau0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=eAxMobGQYT0:GuEK7Y0qau0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?i=eAxMobGQYT0:GuEK7Y0qau0:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/mcarthurgfx/~4/eAxMobGQYT0" height="1" width="1"/>]]></content:encoded>
		<feedburner:origLink>http://mcarthurgfx.com/blog/article/iterating-global-variables-in-internet-explorer</feedburner:origLink></item>
				<item>
			<title>MGFX.Tabs 1.2.0 - Show a Random Tab</title>
			<link>http://feedproxy.google.com/~r/mcarthurgfx/~3/8-CdktCNoHM/mgfx-tabs-1-2-0-show-a-random-tab</link>
			<comments>http://mcarthurgfx.com/blog/article/mgfx-tabs-1-2-0-show-a-random-tab#comments</comments>
			<pubDate>Thu, 18 Feb 2010 10:52:00 -0800</pubDate>
			<dc:creator>Sean</dc:creator>
						<category><![CDATA[Javascript]]></category>
						
			<guid isPermaLink="false">http://mcarthurgfx.com/blog/article/mgfx-tabs-1-2-0-show-a-random-tab</guid>
			<description><![CDATA[<p>I've updated MGFX.Tabs to have a random slide function. It just uses <code>Math.random</code>, and a slight modifier to insure the random number isn't already the current index. Since I believe in <a href="http://semver.org/" target="_blank">semantic versioning</a>, and this is a feature update (not a bug fix), but not breaking, its should be a new minor version.</p>
<pre><code>var tabs = new MGFX.Tabs($$('.tabs li a'), $$('.tabs .content'));
tabs.random();</code></pre>]]></description>
			<content:encoded><![CDATA[<p>I've updated MGFX.Tabs to have a random slide function. It just uses <code>Math.random</code>, and a slight modifier to insure the random number isn't already the current index. Since I believe in <a href="http://semver.org/" target="_blank">semantic versioning</a>, and this is a feature update (not a bug fix), but not breaking, its should be a new minor version.</p>
<pre><code>var tabs = new MGFX.Tabs($$('.tabs li a'), $$('.tabs .content'));
tabs.random();</code></pre>
<p><strong>So <a href="http://mootools.net/forge/p/mgfx_tabs">MGFX.Tabs 1.2.0</a> is available on the Forge.</strong></p><hr />
<h3>Follow me on Twitter</h3>
<p>I have little spurts of ingenuity on Twitter, follow me: <a href="http://twitter.com/seanmonstar">@seanmonstar</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=8-CdktCNoHM:QDwDNZJf0ZE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=8-CdktCNoHM:QDwDNZJf0ZE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?i=8-CdktCNoHM:QDwDNZJf0ZE:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/mcarthurgfx/~4/8-CdktCNoHM" height="1" width="1"/>]]></content:encoded>
		<feedburner:origLink>http://mcarthurgfx.com/blog/article/mgfx-tabs-1-2-0-show-a-random-tab</feedburner:origLink></item>
				<item>
			<title>Make the DOM Update Faster</title>
			<link>http://feedproxy.google.com/~r/mcarthurgfx/~3/gNOGYLMj8QY/make-the-dom-update-faster</link>
			<comments>http://mcarthurgfx.com/blog/article/make-the-dom-update-faster#comments</comments>
			<pubDate>Fri, 12 Feb 2010 08:45:00 -0800</pubDate>
			<dc:creator>Sean</dc:creator>
						<category><![CDATA[Javascript]]></category>
						
			<guid isPermaLink="false">http://mcarthurgfx.com/blog/article/make-the-dom-update-faster</guid>
			<description><![CDATA[<p>&nbsp;</p>
<p>We've already learned that to make our Javascript load faster, we should be listening for a&nbsp;<a href="http://mootools.net/docs/core/Utilities/DomReady" target="_blank">domready event</a>&nbsp;instead othe window onload event. However, sometimes, you can actually make too much Javascript reliant on that sacred event. And when you do that, you can get quite the jump or flicker in older browsers.</p>
<p>We use a proprietary text replacement program instead of sIFR or Cufon or anything else out there. We call it Typostream. On one of my recent projects, we had several features of the web-site requiring extra Javascript functionality, along with a good portion of text being replaced. Originally, I had all of this Javascript being executed on DOM ready event, as best practices recommend. However, viewing the site in Internet Explorer revealed some amazingly laggy results.</p>
<p>&nbsp;</p>
<pre class="console">LOG: Total: 244, Since Last: 244
LOG: Total: 1992, Since Last: 1748</pre>]]></description>
			<content:encoded><![CDATA[<p>We've already learned that to make our Javascript load faster, we should be listening for a <a href="http://mootools.net/docs/core/Utilities/DomReady" target="_blank">domready event</a> instead othe window onload event. However, sometimes, you can actually make too much Javascript reliant on that sacred event. And when you do that, you can get quite the jump or flicker in older browsers.</p>
<p>We use a proprietary text replacement program instead of sIFR or Cufon or anything else out there. We call it Typostream. On one of my recent projects, we had several features of the web-site requiring extra Javascript functionality, along with a good portion of text being replaced. Originally, I had all of this Javascript being executed on DOM ready event, as best practices recommend. However, viewing the site in Internet Explorer revealed some amazingly laggy results.</p>
<h4>Doing a lot at domready can suck</h4>
<p>In IE (even IE8), the time it took to execute all the Javascript was way too long, in the realm of a several seconds too long. Now, the ultimate cuplrit was that we had over 100 elements on the page that needed to be swapped out for images of the same text. Eventually, we wear able to alter the design to require only a couple parts of the page to be replaced. But I discovered a more immediate fix for such a big flicker of content.</p>
<pre class="console">LOG: Total: 244, Since Last: 244
LOG: Total: 1992, Since Last: 1748
</pre>
<p><small>The timer was started at the top of of the Javascript file. The first profile call was at the start of the DOM ready event, and the second call was after the Typostream call.</small></p>
<p>Basically, <strong>with some logging, I found out where the big beasty functions were</strong>. On the inside, the common mechanism for dom ready implementations, is that every function you add as a "listener" to dom ready, just gets pushed into an array. Once dom ready fires, <a href="http://github.com/mootools/mootools-core/blob/master/Source/Element/Element.Event.js#L96" target="_blank">it loops through the array and executes all the functions</a>. So basically, the dom ready event firing can become one giant function that needs to finish.</p>
<pre><code>var $log = function() {
	if(window.console &amp;&amp; console.log) {
		for(var i = 0; i &lt; arguments.length; i++) {
			console.log(arguments[i]);
		}
	}
};

var $profile = (function() {
	var _start = new Date(),
		_last = new Date();

	return function(msg) {
		var now = new Date();
		msg = (msg || '') +' ,';
		$log(msg + 'Total: '+  (now - _start) +', Since Last: ' + (now - _last));
		_last = now;
	};
})();</code></pre>
<p><small>This was my method of profiling. You could also use <code>console.time</code> and <code>console.timeEnd</code>, but this works in a pinch (and in older browsers).</small></p>
<p>Now, many things we do in Javascript are setting up event listeners and timers, so the major work at dom ready is usually fairly small. But the amount of work that was needed to swap out all those elements (and having to do slow selector lookups in the older versions of IE) was all trying to execute at dom ready. And while the DOM was being accessed and changed during that time period, the Javascript hadn't given up its execution to allow the browser to update the DOM.</p>
<p><strong>The DOM was only able to update itself after that Javascript had executed</strong>. So even the smaller part at the start, like collapsing an accordion, wasn't happening until several seconds later. The solution was to remove how much Javascript was happening on the DOM ready event. I wanted to break it up, giving the DOM the ability to do all the changes for the accordion and modal boxes, <em>before trying to do the heavy lifting of running up and down the DOM tree a hundred times</em>.</p>
<h4>Well, then move out of current execution</h4>
<p>Along comes <code>setTimeout</code>. By wrapping the typographical replacement into a timeout call, I gave the browser an opportunity to run other browser stuff. It does its thing (like fixing most of the page immediately), and then calls my big function afterwards. Sure, that big function will still take a couple seconds to execute, making the text flicker, but at least its not as glaring as the section navigation collapsing 5 seconds in. And like I said above, we were able to drastically reduce the number of elements to change, thus fixing the problem even more.</p>
<p>But it's useful to know that you can actually clog up your <code>domready</code> event, and how to clean it out again. If you had a <strong>ton of things that needed to happen</strong>, you could probably set up a simple queue system that will execute everything you want in order, but setting a timeout for each one. Or you could try out web workers, if that fits your bill.</p><hr />
<h3>Follow me on Twitter</h3>
<p>I have little spurts of ingenuity on Twitter, follow me: <a href="http://twitter.com/seanmonstar">@seanmonstar</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=gNOGYLMj8QY:8evJod8Fzlc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=gNOGYLMj8QY:8evJod8Fzlc:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?i=gNOGYLMj8QY:8evJod8Fzlc:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/mcarthurgfx/~4/gNOGYLMj8QY" height="1" width="1"/>]]></content:encoded>
		<feedburner:origLink>http://mcarthurgfx.com/blog/article/make-the-dom-update-faster</feedburner:origLink></item>
				<item>
			<title>Import * Considered Harmful</title>
			<link>http://feedproxy.google.com/~r/mcarthurgfx/~3/DCMpoeUmOC8/import-star-considered-harmful</link>
			<comments>http://mcarthurgfx.com/blog/article/import-star-considered-harmful#comments</comments>
			<pubDate>Wed, 27 Jan 2010 08:02:00 -0800</pubDate>
			<dc:creator>Sean</dc:creator>
						<category><![CDATA[Opinion]]></category>
						
			<guid isPermaLink="false">http://mcarthurgfx.com/blog/article/import-star-considered-harmful</guid>
			<description><![CDATA[<p>Something a Java programmer learns first is that there is this big, amazing library already built-in to Java, and you can easily use plenty of useful classes by using an <code>import</code> statement. Possibly the first thing you want to do is pop open a box to prompt your name, or say hello, and thus starts this terrible habit:</p>
<pre class="java"><code>import javax.swing.*;</code></pre>
<p><a href="http://mcarthurgfx.com/blog/article/import-star-considered-harmful"><img src="http://mcarthurgfx.com/images/blog/think-of-the-kittens-dont-import-star.jpg" alt="" /></a></p>]]></description>
			<content:encoded><![CDATA[<p>Something a Java programmer learns first is that there is this big, amazing library already built-in to Java, and you can easily use plenty of useful classes by using an <code>import</code> statement. Possibly the first thing you want to do is pop open a box to prompt your name, or say hello, and thus starts this terrible habit:</p>
<pre class="java"><code>import javax.swing.*;</code></pre>
<p>I'm guilty of it too. You don't really know what you're doing is all that bad. You know what you want from Swing. You only need the <code>JOptionPane</code>. And sure, the compiler shouldn't be stupid enough to pack the rest of the Swing package into your jar file. In Java, at least, it won't. There's talk about whether certain bulk imports in Python will cause things to be included multiple times.</p>
<h4>Collisions, or which List did you want?</h4>
<p>However, in Java, you <em>can</em>&nbsp;get namespace collisions. <a href="http://stackoverflow.com/questions/1983435/eclipse-java-is-it-harmful-to-import-java-namespace/1983539#1983539" target="_blank">coobird on Stack Overflow gives an excellent example</a>:</p>
<blockquote>
<p>Now, if we were to use a wildcard in the package import, we'd have the following.</p>
<pre class="java">import java.awt.*;
import java.util.*;</pre>
<p>However, now we will have a problem!</p>
<p>There is a <code>java.awt.List</code> class and a <code>java.util.List</code>, so referring to the List class would be ambiguous. One would have to refer to the List with a fully-qualified class name if we want to remove the ambiguity:</p>
<pre class="java">import java.awt.*;
import java.util.*;

// 'List' from java.awt -- need to use a fully-qualified class name.
java.awt.List listComponent = new java.awt.List()</pre>
</blockquote>
<p>This problem is exactly what I was trying to avoid when doing working with some Java, and prompted my need to let people know <strong>never to do this</strong> again. I was trying to call a class from the <a href="http://developer.yahoo.com/yui/compressor/" target="_blank">YUI Compressor</a> jar, and the constructor required several classes. Unfamiliar with a couple of the names, I didn't simply want to copy their import statements, since I already had written my own File class that was far more basic than Java's. <em>No need for conflicts, please</em>.</p>
<p>Your code doesn't have this problem? You're only importing from one package, you say? What about the future of your code? Your class is still auto-importing the rest of your class' residing package. What happens when someone creates a class called List? Or something else? <em>Conflicted</em>.</p>
<p>This leads to another frustrating reason not to use import star.</p>
<h4>It screws Discoverability</h4>
<p>Specifically, I was unsure which <code>ErrorReporter</code> was needed for the <code>JavaScriptCompressor</code>. The import statements at the top list 3 packages it could come from, and the only way for me to find out it to search each package.</p>
<pre class="java"><code>package com.yahoo.platform.yui.compressor;
 
import org.mozilla.javascript.*;
import java.util.*;</code></pre>
<p>ErrorReporter could be a class defined in this package (<code>com.yahoo.platform.yui.compressor</code>), or it could be <code>java.util</code>, or <code>org.mozilla.javascript</code>. It turns out it's in the latter, but discovering that took longer than it ever should have. Even the few minutes I had to spend to lookup which package contained the class so I could import it into my class file was minutes wasted. It's effortless to have to used a more specific import statement instead. Especially if you're using an IDE like Eclipse (which you are if you're doing Java development, just press Ctrl + Shift + O).</p>
<p>Flex Builder is an extension of Eclipse, so no excuses there either. I imagine Flash has a similar shortcut, though even if it didn't, just like in Python, it's really not that hard. Honestly, it takes <strong>no extra effort</strong>&nbsp;to write the name of a specific class instead of importing the whole dang package or module.</p>
<p>This reason is what I feel is the more important reason why <strong>you shouldn't use import * ever again</strong>. The more time it takes another programmer (or even yourself) to understand what in the world was going on inside your head at the time of writing, that's time (and thus money) you're costing your company.</p>
<p><img src="http://mcarthurgfx.com/images/blog/think-of-the-kittens-dont-import-star.jpg" alt="Every Time You Import *, A Kitten Dies" /></p>
<p><strong>Save a kitten: Don't write import * again.</strong></p><hr />
<h3>Follow me on Twitter</h3>
<p>I have little spurts of ingenuity on Twitter, follow me: <a href="http://twitter.com/seanmonstar">@seanmonstar</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=DCMpoeUmOC8:vp2Aqhk5FIE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=DCMpoeUmOC8:vp2Aqhk5FIE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?i=DCMpoeUmOC8:vp2Aqhk5FIE:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/mcarthurgfx/~4/DCMpoeUmOC8" height="1" width="1"/>]]></content:encoded>
		<feedburner:origLink>http://mcarthurgfx.com/blog/article/import-star-considered-harmful</feedburner:origLink></item>
				<item>
			<title>Get the Method Caller in MooTools</title>
			<link>http://feedproxy.google.com/~r/mcarthurgfx/~3/QeSpWdF3pB8/get-the-method-caller-in-mootools</link>
			<comments>http://mcarthurgfx.com/blog/article/get-the-method-caller-in-mootools#comments</comments>
			<pubDate>Tue, 19 Jan 2010 09:48:00 -0800</pubDate>
			<dc:creator>Sean</dc:creator>
						<category><![CDATA[Javascript]]></category>
						
			<guid isPermaLink="false">http://mcarthurgfx.com/blog/article/get-the-method-caller-in-mootools</guid>
			<description><![CDATA[<p>As I continue to work on my <a href="http://github.com/seanmonstar/MonstarLab-MVC">MVC implementation</a> in MooTools, I continue to find new hidden features in MooTools. This weekend, I was adding a view method to the controller, as a shortcut to creating a new View and rendering it. One of the arguments is the view file name, but I also wanted some automagic like CakePHP. It'd be great if the view function could determine the file name based on the function that called it.</p>
<p>Here's what I mean:</p>
<pre><code>var ItemsController = new Class({
	view: function(view_name) {
		if(!view_name) {
			//viewname should default to 'controller/method'
		}
	},
	list: function() {
		$(this).grab(this.view()); // 'items/list'
	}
});</code></pre>]]></description>
			<content:encoded><![CDATA[<p>As I continue to work on my MVC implementation in MooTools, I continue to find new hidden features in MooTools. This weekend, I was adding a view method to the controller, as a shortcut to creating a new View and rendering it. One of the arguments is the view file name, but I also wanted some automagic like CakePHP. It'd be great if the view function could determine the file name based on the function that called it.</p>
<p>Here's what I mean:</p>
<pre><code>var ItemsController = new Class({
view: function(view_name) {
if(!view_name) {
//viewname should default to 'controller/method'
}
},
list: function() {
$(this).grab(this.view()); // 'items/list'
}
});</code></pre>
<p>Every method in a MooTools Class is wrapped in some decorators, that set the caller on the function object when called. By staring and counting how many methods back I needed to collect, I've accomplished my goal. However, <strong>this won't work if a standard function calls this method</strong>. It might be a good idea to <a href="http://mcarthurgfx.com/blog/article/protected-methods-in-mootools-classes">protect this method</a>, now that I think about it.</p>
<pre><code>//inside view function
view_name = arguments.callee.caller.caller.caller._name;</code></pre>
<p>Don't believe me? Test it right here. As neat as this is, <em>I don't gaurantee this will work in every situation</em>, and I haven't tested if any browsers break using this.</p>
<iframe style="width: 100%; height: 300px" src="http://mootools.net/shell/9QDKe/embedded/"></iframe><hr />
<h3>Follow me on Twitter</h3>
<p>I have little spurts of ingenuity on Twitter, follow me: <a href="http://twitter.com/seanmonstar">@seanmonstar</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=QeSpWdF3pB8:V7aaw2UxpOU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=QeSpWdF3pB8:V7aaw2UxpOU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?i=QeSpWdF3pB8:V7aaw2UxpOU:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/mcarthurgfx/~4/QeSpWdF3pB8" height="1" width="1"/>]]></content:encoded>
		<feedburner:origLink>http://mcarthurgfx.com/blog/article/get-the-method-caller-in-mootools</feedburner:origLink></item>
				<item>
			<title>3 Tips When Switching to Python</title>
			<link>http://feedproxy.google.com/~r/mcarthurgfx/~3/sUpHQrR1f7k/3-tips-when-switching-to-python</link>
			<comments>http://mcarthurgfx.com/blog/article/3-tips-when-switching-to-python#comments</comments>
			<pubDate>Thu, 14 Jan 2010 12:30:00 -0800</pubDate>
			<dc:creator>Sean</dc:creator>
						<category><![CDATA[Python]]></category>
						
			<guid isPermaLink="false">http://mcarthurgfx.com/blog/article/3-tips-when-switching-to-python</guid>
			<description><![CDATA[<p>If you write a lot of Javascript or PHP, there are a couple of habits you might be used to that need to change a bit when you switch over to Python.</p>
<ol>
<li>Accessing a property in a dictionary with a variable</li>
<li>Setting properties on objects with a variable</li>
<li>Using While with a function call</li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>If you write a lot of Javascript or PHP, there are a couple of habits you might be used to that need to change a bit when you switch over to Python.</p>
<ol>
<li>Accessing a property in a dictionary with a variable</li>
<li>Setting properties on objects with a variable</li>
<li>Using While with a function call</li>
</ol>
<h4>Check in first</h4>
<p>When looping through a list or dictionary, it's not uncommon to compare the current indexed value to a value in a different list or dictionary. However, doing that will quickly teach you that trying to access a key that doesn't exist will raise a <code>KeyError</code>.</p>
<p>After my first <code>KeyError</code>, I first tried to wrap the comparison in a <code>try</code> block. But that can start to look unwieldly:</p>
<pre><code>try:
	val = params[key]
except KeyError:
	val = None
	
if val:
	#...</code></pre>
<p>Alternatively, we can use the <code>in</code> keyword to check that a key exists. And similar to other languages, using the <code>and</code> operator will prevent the second expression from being evaluated if the first one is false. Hence we do this, and it's all pretty!</p>
<pre><code>if (key in params) and (params[key]):
	# ...</code></pre>
<h4>You can just setattr</h4>
<p>A while ago, when doing some <a href="http://mcarthurgfx.com/blog/article/extending-django-models-managers-and-querysets">initial Django development</a>, I tried to naively handle submission of forms the same way I do in PHP. I loop through each key value pair in the POST dictionary, and assign it to an instance of the model I want to insert. No worries if extra information has been submitting, the model will send data that we have specifically set at fields in the <code>class</code> definition. However, objects in Python don't allow item assignment like PHP or Javascript. Every object does have a personal <code>__dict__</code> that I could access, but then I can get <code>KeyErrors</code> as the above example shows.</p>
<p><a href="http://stackoverflow.com/questions/1614804/copying-values-from-a-dictionary-into-an-object-in-python" target="_blank">Denis Otkidach showed me</a> Python's <a href="http://docs.python.org/library/functions.html#setattr" target="_blank">setattr function</a>, which lets me do exactly what I wanted.</p>
<pre><code>for key, value in POST.iteritems():
    setattr(my_model, key, value)</code></pre>
<h4>While True, loop foreverrrrr</h4>
<p>Often times, when you don't have a predetermined length of something, you'll use <code>while</code> to do your looping. A common occurrence of this is when reading in a file. You call a function, and store its return value, and as long as that value is usable, do your loopity loop stuff. However, in Python you can't do assignment inside a condition for a control structure like <code>while</code>, probably because Guido likes to prevent bad practices from being possible in his language, and that is usually a bad practice unless you know what you're doing.</p>
<p>There maybe a more elegant way of handling this, but i resorted to making an infinite loop that breaks on a bad condition:</p>
<pre><code>while True:
	val = func()
	if val:
		pass
	else:
		break</code></pre><hr />
<h3>Follow me on Twitter</h3>
<p>I have little spurts of ingenuity on Twitter, follow me: <a href="http://twitter.com/seanmonstar">@seanmonstar</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=sUpHQrR1f7k:bszGyWakpf4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=sUpHQrR1f7k:bszGyWakpf4:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?i=sUpHQrR1f7k:bszGyWakpf4:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/mcarthurgfx/~4/sUpHQrR1f7k" height="1" width="1"/>]]></content:encoded>
		<feedburner:origLink>http://mcarthurgfx.com/blog/article/3-tips-when-switching-to-python</feedburner:origLink></item>
				<item>
			<title>Tablets Will Replace Everything</title>
			<link>http://feedproxy.google.com/~r/mcarthurgfx/~3/utJO-fUU540/tablets-will-replace-everything</link>
			<comments>http://mcarthurgfx.com/blog/article/tablets-will-replace-everything#comments</comments>
			<pubDate>Thu, 07 Jan 2010 16:16:00 -0800</pubDate>
			<dc:creator>Sean</dc:creator>
						<category><![CDATA[Opinion]]></category>
						<category><![CDATA[Tools]]></category>
						
			<guid isPermaLink="false">http://mcarthurgfx.com/blog/article/tablets-will-replace-everything</guid>
			<description><![CDATA[<p>Recently, there has been a bit of talk about upcoming tablets like the&nbsp;<a href="http://www.techcrunch.com/2009/06/03/crunchpad-the-launch-prototype/" target="_blank">CrunchPad</a>&nbsp;and the&nbsp;<a href="http://gizmodo.com/5335942/an-insider-on-the-apple-tablet" target="_blank">iSlate</a>, and whether we need them, how useful they'll be, or if<a href="http://daringfireball.net/2009/12/the_tablet" target="_blank">they're only use</a>&nbsp;is&nbsp;<a href="http://xkcd.com/646/" target="_blank">browsing the web on the toilet</a>. Many people are of the opinion that we don't need one. Or that only gadget enthusiasts would buy it for couch web browsing. Well, I'll go out and say it:&nbsp;<strong>Tablets will replace everything</strong>.</p>
<p><a href="http://mcarthurgfx.com/blog/article/tablets-will-replace-everything" target="_blank"><img style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; " src="http://mcarthurgfx.com/images/blog/crunchpad_prototype.jpg" alt="Crunchpad prototype" /></a></p>]]></description>
			<content:encoded><![CDATA[<p>Recently, there has been a bit of talk about upcoming tablets like the <a href="http://www.techcrunch.com/2009/06/03/crunchpad-the-launch-prototype/" target="_blank">CrunchPad</a> and the <a href="http://gizmodo.com/5335942/an-insider-on-the-apple-tablet" target="_blank">iSlate</a>, and whether we need them, how useful they'll be, or if <a href="http://daringfireball.net/2009/12/the_tablet" target="_blank">they're only use</a> is <a href="http://xkcd.com/646/" target="_blank">browsing the web on the toilet</a>. Many people are of the opinion that we don't need one. Or that only gadget enthusiasts would buy it for couch web browsing. Well, I'll go out and say it: <strong>Tablets will replace everything</strong>.</p>
<h4>Crazy people think we don't need tablets</h4>
<blockquote>
<p>I can imagine something like the iPhone with a much bigger screen being a gorgeous device with great capacity, but I don&rsquo;t know where I would fit that into my life</p>
</blockquote>
<blockquote>
<p>Another former Apple executive who was there at the time said the tablets kept getting shelved at Apple because Mr. Jobs, whose incisive critiques are often memorable, asked, in essence, what they were good for besides surfing the Web in the bathroom.</p>
</blockquote>
<p><cite><a href="http://www.nytimes.com/2009/10/05/technology/05tablet.html?_r=1">&mdash;Just a Touch Away, the Elusive Tablet PC</a></cite></p>
<h4>The Eventuality</h4>
<p><a href="http://www.techcrunch.com/2009/06/03/crunchpad-the-launch-prototype/" target="_blank"><img style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; " src="http://mcarthurgfx.com/images/blog/crunchpad_prototype.jpg" alt="Crunchpad prototype" /></a></p>
<p>Eventually, everyone will carry a tablet for all their needs, technological or otherwise.</p>
<ul>
<li><strong>As a phone</strong>: We already use programs for telephony like Skype, and others access phone programs using touch screens via iPhones and Androids. If we're already carrying around 1 piece of technology, why be bothered carrying two. We could talk similar to speakerphone, or an ear piece can easily be worn that will let us talk using the tablet via Bluetooth or some other means.</li>
<li><strong>As a computer</strong>: Many people use their iPhones to access their e-mail, browse the web, and organize their life. It's just a plausible on a tablet. The reason for using the iPhone is it's portability; something the tablet will solve as well. With an on-screen, even typing comments, documents, and the like will be easily and portable.</li>
<li><strong>As a reader</strong>: Surely, people enjoy reading blogs and their RSS feeds portably, such as on an iPhone. And with readers like the Kindle, we see people enjoy reading books, magazines, and newspapers the same way. It only makes sense to want your one personal device to do both. Another plus: students will forget lugging around text books. The backpack will become redundant. The tablet will let you look at the material for class, and also let you write notes with a touch screen keyboard.</li>
<li><strong>As identification</strong>: Eventually, we'll use digital identification over our driver's licenses (or passport, etc). We'll have some sort of encrypted file that we can pop open for showing when need be. And likely a way to broadcast it, like the public side of a private ssh key. I would be surprised if we didn't take it further: our homes unlocking when we broadcast our ID near the door, our cars opening when we're nearby, and the like.</li>
<li><strong>As money</strong>: Paper money and even credit cards can be a hassle. Credit cards especially suck at letting us split the bill at a restaurant with 20 people. It'd be to everyone's advantage if a vendor could broadcast a bill (or a money request), and we could accept on our device. Or if a friend needs to borrow a couple hundred or a thousand dollars. Sure, here you go [press button]. It will happen.</li>
</ul><hr />
<h3>Follow me on Twitter</h3>
<p>I have little spurts of ingenuity on Twitter, follow me: <a href="http://twitter.com/seanmonstar">@seanmonstar</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=utJO-fUU540:W-F48ZuX75w:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=utJO-fUU540:W-F48ZuX75w:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?i=utJO-fUU540:W-F48ZuX75w:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/mcarthurgfx/~4/utJO-fUU540" height="1" width="1"/>]]></content:encoded>
		<feedburner:origLink>http://mcarthurgfx.com/blog/article/tablets-will-replace-everything</feedburner:origLink></item>
				<item>
			<title>2009 in Review</title>
			<link>http://feedproxy.google.com/~r/mcarthurgfx/~3/DEsIapOMXdE/2009-in-review</link>
			<comments>http://mcarthurgfx.com/blog/article/2009-in-review#comments</comments>
			<pubDate>Tue, 29 Dec 2009 08:43:00 -0800</pubDate>
			<dc:creator>Sean</dc:creator>
						<category><![CDATA[Blogging]]></category>
						
			<guid isPermaLink="false">http://mcarthurgfx.com/blog/article/2009-in-review</guid>
			<description><![CDATA[

<p>It's amazing that this decade is finishing off already. Time really does get faster the longer I feel it. Anyways, here's a summary of the activity on this blog for the year.</p>
<ol>
<li>I started the year off with sharing a <a href="http://mcarthurgfx.com/blog/article/getting-private-variables-in-a-mootools-class">Privates Mutator</a> for MooTools prior to v1.2.3.&nbsp;</li>
<li>Next, I shared a <a href="http://mcarthurgfx.com/blog/article/make-draggable-items-dockable">Drag.Dock class</a> to ...</li>
</ol>

<p><a href="/blog/article/2009-in-review">Read more</a>]]></description>
			<content:encoded><![CDATA[<p>It's amazing that this decade is finishing off already. Time really does get faster the longer I feel it. Anyways, here's a summary of the activity on this blog for the year.</p>
<ol>
<li>I started the year off with sharing a <a href="http://mcarthurgfx.com/blog/article/getting-private-variables-in-a-mootools-class">Privates Mutator</a> for MooTools prior to v1.2.3.&nbsp;</li>
<li>Next, I shared a <a href="http://mcarthurgfx.com/blog/article/make-draggable-items-dockable">Drag.Dock class</a> to allow draggable elements to dock to a side, and I asked people to share answers to an interview question: <a href="http://mcarthurgfx.com/blog/article/interview-question-palindromic-words">write a function that determines if a word is palindromic</a>.</li>
<li>In March, I released the bare bones of super <a href="http://mcarthurgfx.com/blog/article/rich-text-editor-in-mootools">light-weight Rich Text Editor in MooTools</a> that doesn't use iframes.</li>
<li>I wrote a&nbsp;controversial&nbsp;article stating if you don't want to understand CSS, <a href="http://mcarthurgfx.com/blog/article/tables-vs-css-really-">maybe you shouldn't be in the web industry</a>. I followed that up with some tutorials on how to <a href="http://mcarthurgfx.com/blog/article/use-css-borders-for-3d-effects">use CSS to&nbsp;achieve&nbsp;3D effects</a>.</li>
<li>In May, I needed a way to tell from inside a class, the name of the class. Kind of like calling <code>__CLASSNAME__</code> in PHP. So I rigged together a <a href="http://mcarthurgfx.com/blog/article/get-class-of-an-instance">GetClass mixin</a>.</li>
<li>I explored and explained how MooTools <code>$unlink</code> function lets you <a href="http://mcarthurgfx.com/blog/article/copy-objects-and-arrays-with-unlink">safely copy objects</a> in June.</li>
<li>July saw my write-up of <a href="http://mcarthurgfx.com/blog/article/a-basic-lesson-in-password-hashing">basic password hashing</a>, as well as a great article on the <a href="http://mcarthurgfx.com/blog/article/4-ways-functions-mess-with-this">ways you can call a function</a>, and how the binding affects the context.</li>
<li>In the summer time, I started to work on a MVC framework for MooTools. I wrote about my first attempts for <a href="http://mcarthurgfx.com/blog/article/simple-templating-with-mootools-substitute">templating for Views</a> usings String#substitute. Then, I ranted against an outrageous claim that <a href="http://mcarthurgfx.com/blog/article/web-developers-are-stupid">web developers are stupid</a>.</li>
<li>With MooTools 1.2.3, my Privates Mutator broke. However, a new feature was added to Classes: <a href="http://mcarthurgfx.com/blog/article/protected-methods-in-mootools-classes">protected methods</a>.</li>
<li>October was a little slow, but I still snuck in an article on <a href="http://mcarthurgfx.com/blog/article/geocoding-addresses-with-google">geocoding addresses thanks to Google</a>.</li>
<li>In November, I picked up the pace in my blogging. First, I updated my <a href="http://mcarthurgfx.com/blog/article/mgfx-tabs-1-1-on-github">MGFX.Tabs plugin, and put it on github</a>. Afterwards, I wrote up an interesting opinion on <a href="http://mcarthurgfx.com/blog/article/why-must-lamp-setup-suck">how LAMP setup currently sucks</a>, followed by a tutorial on the various <a href="http://mcarthurgfx.com/blog/article/extending-django-models-managers-and-querysets">ways you can extend Models in Django</a>. I quite enjoyed exploring Python, and I hope I can find other projects to play with it more.</li>
<li>In December, the MooTools Forge launched, and I <a href="http://mcarthurgfx.com/blog/article/mgfx-in-the-mootools-forge">added some of my classes to the Forge</a>.</li>
</ol>
<h4>Next Year, Next Decade</h4>
<p>I've been finding it easier to write about interesting topics, and working out a better schedule. I hope to have more and more interesting articles for you consume every week. If you're new here, <a href="http://mcarthurgfx.com/rss">subscribe to the feed</a>, or <a href="http://twitter.com/seanmonstar">follow me on Twitter</a> to here some of <a href="http://mcarthurgfx.com/blog/article/i-m-a-twitter-monstar">my other micro opinions</a>.</p><hr />
<h3>Follow me on Twitter</h3>
<p>I have little spurts of ingenuity on Twitter, follow me: <a href="http://twitter.com/seanmonstar">@seanmonstar</a>.</p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=DEsIapOMXdE:FNRK0eUnwyI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/mcarthurgfx?a=DEsIapOMXdE:FNRK0eUnwyI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/mcarthurgfx?i=DEsIapOMXdE:FNRK0eUnwyI:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/mcarthurgfx/~4/DEsIapOMXdE" height="1" width="1"/>]]></content:encoded>
		<feedburner:origLink>http://mcarthurgfx.com/blog/article/2009-in-review</feedburner:origLink></item>
				
	</channel>
</rss>
