<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>ghcoders dot net &#187; ddipaolo</title>
	<atom:link href="http://blog.ghcoders.net/author/ddipaolo/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ghcoders.net</link>
	<description></description>
	<pubDate>Fri, 21 Dec 2007 17:02:41 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>Adding UI to make up for your UI</title>
		<link>http://blog.ghcoders.net/2007/12/21/adding-ui-to-make-up-for-your-ui/</link>
		<comments>http://blog.ghcoders.net/2007/12/21/adding-ui-to-make-up-for-your-ui/#comments</comments>
		<pubDate>Fri, 21 Dec 2007 17:02:41 +0000</pubDate>
		<dc:creator>ddipaolo</dc:creator>
		
		<category><![CDATA[microsoft]]></category>

		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.ghcoders.net/2007/12/21/adding-ui-to-make-up-for-your-ui/</guid>
		<description><![CDATA[Sometimes applications don&#8217;t respond because, well, they&#8217;re busy.  But only the most special of apps treat this not as a bug, but something to put up a &#8220;nothing to see here, move along&#8221; notification:

I mean, the sad part is I actually understand why they likely implemented this instead.  At this point in Visual [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes applications don&#8217;t respond because, well, they&#8217;re busy.  But only the most special of apps treat this not as a bug, but something to put up a &#8220;nothing to see here, move along&#8221; notification:</p>
<p><a href='http://blog.ghcoders.net/wp-content/uploads/2007/12/visual-studio-is-busy.png' title='Microsoft Visual Studio is Busy'><img src='http://blog.ghcoders.net/wp-content/uploads/2007/12/visual-studio-is-busy.png' alt='Microsoft Visual Studio is Busy' /></a></p>
<p>I mean, the sad part is I actually understand why they likely implemented this instead.  At this point in Visual Studio&#8217;s lifecycle, it&#8217;s easier just to poll to check if the UI is unresponsive than to actually root out the cause of the unresponsiveness.  It&#8217;s sad, actually.  And the fun part is, in preparation for this blog article I didn&#8217;t even have to try very hard to get that little balloon to pop up.  Took me about 30 seconds (and no I&#8217;m not going through the trouble of reporting it to Microsoft because it&#8217;s not entirely repeatable and I&#8217;m skeptical of what the results would be anyway).  Go Visual Studio.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ghcoders.net/2007/12/21/adding-ui-to-make-up-for-your-ui/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Another SSIS Wart</title>
		<link>http://blog.ghcoders.net/2007/11/16/another-ssis-wart/</link>
		<comments>http://blog.ghcoders.net/2007/11/16/another-ssis-wart/#comments</comments>
		<pubDate>Fri, 16 Nov 2007 16:39:54 +0000</pubDate>
		<dc:creator>ddipaolo</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.ghcoders.net/2007/11/16/another-ssis-wart/</guid>
		<description><![CDATA[As I get more and more educated on SSIS, I&#8217;m becoming more appreciative of what it does (or in some cases, intends to do) overall but I&#8217;m also finding some of the weirdest things that are just a little &#8220;off&#8221;.  Most are just the kind of things that make you go &#8220;huh, that&#8217;s strange&#8221;, [...]]]></description>
			<content:encoded><![CDATA[<p>As I get more and more educated on <abbr title="SQL Server Integration Services">SSIS</abbr>, I&#8217;m becoming more appreciative of what it does (or in some cases, intends to do) overall but I&#8217;m also finding some of the weirdest things that are just a little &#8220;off&#8221;.  Most are just the kind of things that make you go &#8220;huh, that&#8217;s strange&#8221;, but I found one yesterday that made me seriously stop and scratch my head because I was just completely lost as to why things would be done this way.  In fact, if it weren&#8217;t for the <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&#038;location=http%3A%2F%2Fwww.amazon.com%2FProfessional-Server-Integration-Services-Programmer%2Fdp%2F0764584359%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1195227945%26sr%3D8-1&#038;tag=baycitspoblo-20&#038;linkCode=ur2&#038;camp=1789&#038;creative=9325">Wrox SSIS book</a><img src="http://www.assoc-amazon.com/e/ir?t=baycitspoblo-20&amp;l=ur2&amp;o=1" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> that I got, I probably wouldn&#8217;t have figured out the answer.</p>
<p>I&#8217;ll start this off with a quick question for you to ponder the answer to before I go into the details &mdash; What is a &#8220;property&#8221; on an object other than essentially just a variable defined only within the scope of that object?  Rather than answer that question just yet, here&#8217;s the problem I was scratching my head over.  In SSIS, they have some nifty pre-defined events which you can easily attach event handlers to.  Thanks to <a href="http://blogs.conchango.com/jamiethomson/archive/2005/06/11/SSIS_3A00_-Custom-Logging-Using-Event-Handlers.aspx">Jamie Thomson&#8217;s blog post entitled &#8220;Custom Logging Using Event Handlers&#8221;</a> I&#8217;ve been happily coding away logging routines using the <b>OnPreExecute</b> and <b>OnPostExecute</b> event handlers (among a few others).  But, I soon ran into a problem that wasn&#8217;t addressed in the blog post, and that was that every event that fires <em>propagates up the call chain, regardless of whether or not the event is handled</em><sup>[<a name="foo" href="#ftn.foo">*</a>]</sup>.  That is to say, if I have an SSIS package that has (&#8221;contains&#8221;) a task which loads a file into a database, and I define an event handler for <b>OnPreExecute</b> that simply writes a row to an event log that says &#8220;Started: <whatever>&#8220;, then once it gets to the file load task, the database will contain the following:</p>
<ol>
<li>Started: Main package</li>
<li>Started: File load</li>
<li><strong>Started: Main package</strong></li>
</ol>
<p>Obviously that last row is a bit silly because the main package didn&#8217;t just start, it&#8217;s in the middle of executing all of its tasks.  That&#8217;s because the <b>PreExecute</b> event propagated up from the file load task.  Now, one might argue that propagating that particular event doesn&#8217;t make a lot of sense because you only ever <b>PreExecute</b> once for each task, and it certainly has nothing to do with when the child tasks do anything.  But, for the sake of consistency I can forgive that.  If that was the wart, then that&#8217;d just be a &#8220;huh, thats strange&#8221; kind of wart.  After all, you certainly <em>do</em> want <b>Error</b> and <b>Warning</b> events to propagate up so you can just define event handlers for those in the parents.</p>
<p>So, at this point I figure there <em>has</em> to be some way to prevent the upward propagation of some events, even if I have to specify it per event handler.  The first place I looked was in the properties for the event handler.  The only thing that looked mildly promising was the <b>LoggingMode</b> property, but that was limited to &#8220;Use Parent Setting&#8221;, &#8220;Enabled&#8221;, or &#8220;Disabled&#8221; - nothing about &#8220;handle and stop propagating&#8221;.  So, the next place I checked was the &#8220;expressions&#8221; for the event handler.  Expressions in SSIS are basically ways of setting properties that are dynamic (ie, can change at/during runtime), and they&#8217;re very useful and generally contain most of the properties anyway, plus an occasional extra tidbit.  Well, no extra helpful tidbits in this case, though I was positive that was where it would be.</p>
<p>What does any good programmer do when they&#8217;ve exhausted their available local resources?  Google it, of course.  Unfortunately no matter what search string I used (and my Google-fu is pretty good), I couldn&#8217;t find anything that would tell me how to do what I want.  Plus, the only other <abbr title="Subject Matter Expert">SME</abbr> on SSIS in the company that I&#8217;m aware of was unavailable to ask, and I&#8217;m about to outgrow using him as a reference anyway.    Then I remembered the aforementioned book, and sure enough one of the <em>first</em> things in the index under <b>events</b> was &#8220;bubbling&#8221;.  And in less than 2 minutes of reading, I had my solution.</p>
<p>Now for the solution and then a quick revisit to the question I kicked this story off with.  The solution:  there is a &#8220;system variable&#8221; defined at the error handler scope level entitled <b>Propagate</b>, which if you set it to <b>False</b> will not propagate the event to its parent(s).  How the heck is a system variable defined only within the scope of a single object (and obviously only useful within that scope) a better choice than a property?  Properties are displayed in a nice little grid that&#8217;s easily accessible.  System variables are hidden behind several clicks in the interface.  I&#8217;d wager that 95% or more of SSIS packages never have to muck about with them, and none of the dozen or more packages I&#8217;ve worked on have ever needed to do so (until now!), in spite of all the functionality I&#8217;ve included.  Thankfully, <a href="http://www.developerdotstar.com/community/node/334">I&#8217;m not the only one</a> who had such an issue (I didn&#8217;t find that blog post until I started writing this one, and he doesn&#8217;t have the solution in his post, but <a href="http://blogs.conchango.com/jamiethomson/archive/2006/01/19/2671.aspx">Jamie Thomson posted a response</a> which he found).</p>
<p>And to make matters worse I just realized that this means I&#8217;ll have to define that variable for <em>all</em> children within a package otherwise I&#8217;ll get a lot of &#8220;Started: Main package&#8221; messages, one for each sub-task (which is a lot, including checking for input, truncating tables, etc.).  According to the blog post and response linked at the end of the last paragraph, there&#8217;s no way to tell an event handler to not listen to propagated events either.  Sigh.</p>
<p><sup>[<a name="ftn.foo" href="#foo">*</a>]</sup> - it also doesn&#8217;t help that <a href="http://technet.microsoft.com/en-us/library/ms140223.aspx">Microsoft&#8217;s documentation</a> has a very misleading/incorrect diagram showing event propagation stopping at the first handled event</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ghcoders.net/2007/11/16/another-ssis-wart/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Nerd Handbook</title>
		<link>http://blog.ghcoders.net/2007/11/13/the-nerd-handbook/</link>
		<comments>http://blog.ghcoders.net/2007/11/13/the-nerd-handbook/#comments</comments>
		<pubDate>Tue, 13 Nov 2007 19:36:48 +0000</pubDate>
		<dc:creator>ddipaolo</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.ghcoders.net/2007/11/13/the-nerd-handbook/</guid>
		<description><![CDATA[So that we don&#8217;t get into too deep of a posting morass, here&#8217;s a good link that was posted on reddit (though I found it via the SomethingAwful forums):

http://www.randsinrepose.com/archives/2007/11/11/the_nerd_handbook.html
]]></description>
			<content:encoded><![CDATA[<p>So that we don&#8217;t get into too deep of a posting morass, here&#8217;s a good link that was posted on reddit (though I found it via the SomethingAwful forums):<br />
<a href="http://www.randsinrepose.com/archives/2007/11/11/the_nerd_handbook.html"><br />
http://www.randsinrepose.com/archives/2007/11/11/the_nerd_handbook.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ghcoders.net/2007/11/13/the-nerd-handbook/feed/</wfw:commentRss>
		</item>
		<item>
		<title>RFC: Gearing an Open Source talk to a Microsoft heavy crowd</title>
		<link>http://blog.ghcoders.net/2007/10/25/rfc-gearing-an-open-source-talk-to-a-microsoft-heavy-crowd/</link>
		<comments>http://blog.ghcoders.net/2007/10/25/rfc-gearing-an-open-source-talk-to-a-microsoft-heavy-crowd/#comments</comments>
		<pubDate>Thu, 25 Oct 2007 20:34:30 +0000</pubDate>
		<dc:creator>ddipaolo</dc:creator>
		
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.ghcoders.net/2007/10/25/rfc-gearing-an-open-source-talk-to-a-microsoft-heavy-crowd/</guid>
		<description><![CDATA[When I was hired on at my new job, I was apparently referred to internally as &#8220;the open source guy&#8221;.  Now, that&#8217;s a moniker I don&#8217;t really mind because I do espouse the open source/free software philosophy and I definitely see it as being useful both from a personal standpoint and as a professional [...]]]></description>
			<content:encoded><![CDATA[<p>When I was hired on at <a href="http://www.parivedasolutions.com">my new job</a>, I was apparently referred to internally as &#8220;the open source guy&#8221;.  Now, that&#8217;s a moniker I don&#8217;t really mind because I do espouse the open source/free software philosophy and I definitely see it as being useful both from a personal standpoint and as a professional developer.  Well the new gig heavily encourages knowledge-sharing and building of &#8220;intellectual capital&#8221; via presentations and such, so I thought that open source as a community, development strategy, and philosophy might be a worthwhile thing to share.  So, this is my request for comments on ideas for what to present.  But rather than just asking that question, here&#8217;s sort of what I had in mind.</p>
<p>First I&#8217;d have to do some definition/demystifying up front:  answering the who/what/why&#8217;s and all that, because this is a heavy Microsoft crowd, though not so much that they are fanboys or anything like that (well, some might be but they likely won&#8217;t attend) it&#8217;s just what they know and that&#8217;s what the clients run on.  I know at least a few people, including some of the partners, are genuinely interested in open source not only as a business strategy but as a community.  So I think the first few big talking points in this section would be:</p>
<ul>
<li>What is open source?  (I&#8217;d like to stick mostly with definitions here and not delve too much into history and/or the fractious issue of what constitues &#8220;free&#8221; or &#8220;open source&#8221; software)</li>
<li>What open source projects they might be aware of, even if they don&#8217;t know they are open source (Linux, Mozilla, Java (yes, <a href="http://open.itworld.com/4915/070508opsjava/page_1.html">Java</a>), PHP, Subversion, etc.)</li>
<li>What open source projects affect them that they are likely unaware of (Apache, Python, MySQL, Mediawiki (wikipedia))</li>
<li>Why open source?  (Why do developers give away code?  Why use it?)</li>
</ul>
<p>And that would be the bulk of the presentation.  From there I can come up with a more directed approach talking about how my company can leverage the advantages of open source to help increase productivity/add value/etc.  Really I just wanted to hear what people thought about the first part and whether or not I was missing anything or perhaps should take some stuff out.  Though if anyone has any feedback for what open source could mean for a small IT consulting firm, then by all means, fire away <img src='http://blog.ghcoders.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ghcoders.net/2007/10/25/rfc-gearing-an-open-source-talk-to-a-microsoft-heavy-crowd/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Not a WTF, but certainly a wart</title>
		<link>http://blog.ghcoders.net/2007/10/15/not-a-wtf-but-certainly-a-wart/</link>
		<comments>http://blog.ghcoders.net/2007/10/15/not-a-wtf-but-certainly-a-wart/#comments</comments>
		<pubDate>Mon, 15 Oct 2007 19:17:07 +0000</pubDate>
		<dc:creator>ddipaolo</dc:creator>
		
		<category><![CDATA[microsoft]]></category>

		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.ghcoders.net/2007/10/15/not-a-wtf-but-certainly-a-wart/</guid>
		<description><![CDATA[As you may know, I&#8217;m not that much of a fan of Microsoft technology, but understand that it&#8217;s somewhat unavoidable and allowing for the use of MS products greatly opens the prospects of employment/work.  So, at my new gig I&#8217;m aware that a healthy chunk of time spent doing development will be using Microsoft [...]]]></description>
			<content:encoded><![CDATA[<p>As you may know, I&#8217;m not that much of a fan of Microsoft technology, but understand that it&#8217;s somewhat unavoidable and allowing for the use of MS products greatly opens the prospects of employment/work.  So, at my new gig I&#8217;m aware that a healthy chunk of time spent doing development will be using Microsoft tools and all the quirks that go along with them.  Sometimes I&#8217;m pleasantly surprised, sometimes I&#8217;m reminded of why I dislike Microsoft products in general.  Lately it&#8217;s been more of the latter.</p>
<p>On the current client I&#8217;m designing stuff for, we&#8217;re using MS SQL Server 2005&#8217;s <abbr title="SQL Server Integration Services">SSIS</abbr> toolchain, which is a great idea with mediocre execution.  For those who are unfamiliar with SSIS, it&#8217;s basically the evolution of their <abbr title="Data Transformation Services">DTS</abbr> package that came with SQL Server 2000, which is designed to simplify the <abbr title="Extract, Transform, and Load">ETL</abbr> process of getting data from a source (or various sources) into the destination database after all sorts of cleansing and transformation.  The DTS package that shipped with SQL Server 2000 was apparently pretty warty, a trait that is common amongst first-gen Microsoft products, and so SSIS is apparently notably cleaner and nicer.  But, as most of us are aware, that doesn&#8217;t mean it&#8217;s wart-free, and I&#8217;ve found a nasty wart or two.<br />
<span id="more-15"></span></p>
<p>So, for the product I&#8217;m working on we have to load lots of files into the database, sometimes batches at a time.  They&#8217;re segregated into different folders based on what kind of input files they are, and you need to be able to load all of the files in the folder that match a specific file pattern.  Great, Microsoft provides a nice &#8220;control flow item&#8221; named the &#8220;Foreach Loop Container&#8221; which does exactly that.  It looks just like a box with a little label on it where you can place other &#8220;control flow items&#8221;, and in my case I just use the &#8220;Data Flow Task&#8221; control item, because that&#8217;s what takes data from one place and transforms it and ships it to another.  So, since Foreach Loop Containers are necessarily looping over files in a given folder (really it&#8217;s not as generic as the name sounds, it&#8217;s a &#8220;Foreach File in a Folder Container&#8221; really), you&#8217;d figure that there&#8217;d be a sensible way to hook up any file sources within it to, you know, the current file being processed.  Well, there&#8217;s not.  To get to it, you have to define a local variable for the container in the container definitions, and that will be re-set each time it starts a new file.  That by itself wouldn&#8217;t be so bad if there was a straightforward way to make a data source that simply looked at that variable and was usable that way, but there&#8217;s not.  In fact, to make it even worse, there is a specific &#8220;connection&#8221; type called the &#8220;Multiple File Connection&#8221;, which would work perfectly with this if it were designed to work cooperatively with the Foreach container, but no.  The way <a href="http://msdn2.microsoft.com/en-us/library/ms169800.aspx">Microsoft wants you to accomplish it</a> is to set that local variable and then configure a flat file connection pointing to any random file (you have to point it to a file first to configure the output columns), and then tell it to ignore the actual file location you used in setup by overriding the <b>ConnectionString</b> property of the connection object.  Of note is that if you should decide that you want to go back and change some of the output column formatting you have to once again go through the whole process of picking one of the files (even though it doesn&#8217;t actually use that file, it uses the <b>ConnectionString</b> property which we&#8217;ve overriden), then modifying it and then saving it.  Luckily you don&#8217;t have to re-edit the property again.</p>
<p>All this discussion over what should be a pretty simple task.  And another quick, but equally ugly wart is:  in SSIS you can&#8217;t have a delimited input file that has a variable number of columns that will get parsed nicely for each line (and fill in blank/null outputs for the columns it fails to see).  So if I have a CSV file with only 4 columns on the first line and 8 on the next, then my only option in SSIS is to set the number of columns to 4 and then write a script to process the lines that have separators still left in them.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ghcoders.net/2007/10/15/not-a-wtf-but-certainly-a-wart/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Back into the Django fray for a bit</title>
		<link>http://blog.ghcoders.net/2007/10/01/back-into-the-django-fray-for-a-bit/</link>
		<comments>http://blog.ghcoders.net/2007/10/01/back-into-the-django-fray-for-a-bit/#comments</comments>
		<pubDate>Mon, 01 Oct 2007 22:10:57 +0000</pubDate>
		<dc:creator>ddipaolo</dc:creator>
		
		<category><![CDATA[personal]]></category>

		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.ghcoders.net/2007/10/01/back-into-the-django-fray-for-a-bit/</guid>
		<description><![CDATA[To sort of go along with the fantasy football related programming post from earlier, I also like to do a set of &#8220;power rankings&#8221; for the NFL using a fairly simple but data-heavy formula that I derived via a bit of trial and error and really just some thought exercises.  For the past season [...]]]></description>
			<content:encoded><![CDATA[<p>To sort of go along with the fantasy football related programming post from earlier, I also like to do a set of &#8220;power rankings&#8221; for the NFL using a fairly simple but data-heavy formula that I derived via a bit of trial and error and really just some thought exercises.  For the past season or so I just maintained it using a simple spreadsheet (at first Excel, then <a href="http://www.gnome.org/projects/gnumeric/">Gnumeric</a> once I converted my laptop to Linux after getting the new job), but even when I was doing it I noticed data inconsistency which almost definitely resulted from data entry errors on my part.  For example, part of the formula involves a teams &#8220;points for&#8221; (points they score against other teams) and &#8220;points against&#8221; (points other teams score against them).  Well, when you sum up the &#8220;points for&#8221; for all the teams, and when you sum up the &#8220;points against&#8221; for all of the teams, you should get the same number.  But sometimes I wouldn&#8217;t.  Those errors weren&#8217;t quite as nefarious to track down as other things like in my strength of schedule calculations the total W-L record of one component should be the mirror opposite of another, but it would be missing some wins somewhere.<br />
<span id="more-10"></span><br />
So, rather than set up some crazy macros or extensive conditional formatting that will simply alert me when I had data inconsistencies I figured, &#8220;hey, hunting down these inconsistencies will be a lot easier if it&#8217;s bucketed into individual games and has a structure I can efficiently query.&#8221;  So, I figured I&#8217;d cram the data into a database, and since I&#8217;ve had pleasant experiences with <a href="http://djangoproject.com">Django</a> in the past, and I wanted an easier way to view/extract/modify the data than just via DB queries I decided to use it to build a quick and ugly web interface to it.</p>
<p>Most of the initial work was doable within an hour or two, just laying out the models and such.  The built in admin interface is really nice, though there was one case where I thought I could use the <code>edit_inline</code> property on some of the <code><a href="http://www.djangoproject.com/documentation/model-api/#many-to-one-relationships">ForeignKey</a></code> fields I had, but it doesn&#8217;t look like I can flex it like that.  Basically, I was hoping the admin interface would allow me to add in the relevant game results/statistics for this model:<br />
<code>
<pre>
class Game(models.Model):
    week = models.ForeignKey(Week)
    home = models.ForeignKey(TeamGame, related_name='home')
    away = models.ForeignKey(TeamGame, related_name='away')
</pre>
<p></code></p>
<p>with the <code>TeamGame</code> class being the individual representation of how a team performed in a given game:</p>
<p><code>
<pre>
class TeamGame(models.Model):
    team = models.ForeignKey(Team)
    points = models.IntegerField()
    yards = models.IntegerField()
    turnovers = models.IntegerField()
</pre>
<p></code></p>
<p>I used a similar data model for the poker league tracking site I wrote in Django about a year ago, only since it was a less-strict &#8220;many-to-one&#8221; (in that case, PlayerGame to Game) relationship instead of the strict one home, one away &#8220;two-to-one&#8221; relationship we have here, it makes using <code>edit_inline</code> unworkable, at least the way I understand it and the way I used it on the other site.  But, writing a custom view to add the data was relatively simple, and I think I could have even just used the generic CRUD views provided, but I just wrote my own instead.</p>
<p>What makes me wonder if this data model/schema is the &#8220;right way&#8221; to do it is the fact that extracting some of the necessary data to do the rankings gets kind of cumbersome, probably because of all the normalization (though really normalization is supposed to be the big win here, remember).  For example, the next page I wrote after the &#8220;add a game&#8217;s stats&#8221; page was one to view the year-to-date statistics of a given team for each week.  And it&#8217;s not as clean and pretty as I&#8217;d like it to be.  In fact, it&#8217;s kind of warty-looking, though it&#8217;s not too bad in the actual ORM syntax, even though I did resort to using the <a href="http://www.djangoproject.com/documentation/db-api/#complex-lookups-with-q-objects"><code>Q()</code></a> method, because remember, I want the <em>opponent</em> info as well as the actual team&#8217;s info from each game that they&#8217;re in, which is what the <code>Game</code> objects are pulled for (and then I assign the current team&#8217;s <code>TeamGame</code> for that particular <code>Game</code> in the <code>my_tg</code> variable, and the opponent&#8217;s <code>TeamGame</code> in <code>opp_tg</code>):<br />
<code>
<pre>
def display_team(request, team_id):
    team = get_object_or_404(Team, pk=team_id)
    teamgames = TeamGame.objects.filter(team=team)
    games = Game.objects.filter(Q(home__in=teamgames) | Q(away__in=teamgames))
    tmp_games = []
    totals = {'pts_for': 0, 'pts_against': 0,
              'yds_for': 0, 'yds_against': 0,
              'to_margin': 0}
    for game in games:
        if team == game.home.team:
            opp_tg = game.away
            my_tg = game.home
        else:
            opp_tg = game.home
            my_tg = game.away
        if my_tg.points > opp_tg.points:
            result = 'W'
        else:
            result = 'L'
        tmp_games.append({'opponent': opp_tg.team,
                          'result': '%s, %s - %s' % (result, my_tg.points,
                                                      opp_tg.points),
                          'pts_for': my_tg.points,
                          'pts_against': opp_tg.points,
                          'yds_for': my_tg.yards,
                          'yds_against': opp_tg.yards,
                          'to_margin': opp_tg.turnovers - my_tg.turnovers,})
        totals['pts_for'] += my_tg.points
        totals['pts_against'] += opp_tg.points
        totals['yds_for'] += my_tg.yards
        totals['yds_against'] += opp_tg.yards
        totals['to_margin'] += (opp_tg.turnovers - my_tg.turnovers)
    num_games = float(games.count())
    averages = {'pts_for': totals['pts_for']/num_games,
                'pts_against': totals['pts_against']/num_games,
                'yds_for': totals['yds_for']/num_games,
                'yds_against': totals['yds_against']/num_games,}
    return render_to_response('rankings/team.html',
                              {'team': team, 'games': tmp_games,
                               'totals': totals, 'averages': averages})
</pre>
<p></code><br />
Granted, a good portion of that is all that dict assignment junk so that I can have a much cleaner looking template file with less &#8220;business logic&#8221; in it and more pure iteration over results.  But it just seems like an unhealthy amount of logic for what is pretty darn simple.  But it does make for a pretty simple/clean template:<br />
<code>
<pre>
&lt;h2&gt;{{ team }}&lt;/h2&gt;

Games
&lt;table&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;td&gt;Opponent&lt;/td&gt;
            &lt;td&gt;Result&lt;/td&gt;
            &lt;td&gt;Yards For&lt;/td&gt;
            &lt;td&gt;Yards Against&lt;/td&gt;
            &lt;td&gt;TO Margin&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tfoot&gt;
        &lt;tr&gt;
            &lt;td&gt;TOTALS&lt;/td&gt;
            &lt;td&gt;{{ totals.pts_for }} - {{ totals.pts_against }}&lt;/td&gt;
            &lt;td&gt;{{ totals.yds_for }}&lt;/td&gt;
            &lt;td&gt;{{ totals.yds_against }}&lt;/td&gt;
            &lt;td&gt;{{ totals.to_margin }}&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;AVERAGES&lt;/td&gt;
            &lt;td&gt;{{ averages.pts_for }} - {{ averages.pts_against }}&lt;/td&gt;
            &lt;td&gt;{{ averages.yds_for }}&lt;/td&gt;
            &lt;td&gt;{{ averages.yds_against }}&lt;/td&gt;
            &lt;td&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tfoot&gt;
    &lt;tbody&gt;
    {% for game in games %}
        &lt;tr&gt;
            &lt;td&gt;{{ game.opponent }}&lt;/td&gt;
            &lt;td&gt;{{ game.result }}&lt;/td&gt;
            &lt;td&gt;{{ game.yds_for }}&lt;/td&gt;
            &lt;td&gt;{{ game.yds_against }}&lt;/td&gt;
            &lt;td&gt;{{ game.to_margin }}&lt;/td&gt;
        &lt;/tr&gt;
        &lt;/tr&gt;
    {% endfor %}
    &lt;/tbody&gt;
&lt;/table&gt;
</pre>
<p></code></p>
<p>So I like the result on the template side, but seeing as how I had to do something very similar with my poker site in order to get all the game data for the &#8220;display player info&#8221; page on that site (that is, aggregate stuff into a temp list or dict and churn a lot of data basically), I&#8217;m wondering if there&#8217;s a better way to do the view without making the template code crazy complex.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ghcoders.net/2007/10/01/back-into-the-django-fray-for-a-bit/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Screen-scraping made .. kind of easier, I guess</title>
		<link>http://blog.ghcoders.net/2007/09/28/screen-scraping-made-kind-of-easier-i-guess/</link>
		<comments>http://blog.ghcoders.net/2007/09/28/screen-scraping-made-kind-of-easier-i-guess/#comments</comments>
		<pubDate>Fri, 28 Sep 2007 16:31:42 +0000</pubDate>
		<dc:creator>ddipaolo</dc:creator>
		
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://blog.ghcoders.net/?p=7</guid>
		<description><![CDATA[Screen scraping is a somewhat still common technique that script-writers use to take the output of a web page (which wasn&#8217;t designed to be consumed by anything but a person viewing it in a web browser), grabs the portions relevant to their purposes, and spits out the parts that it wants.  In fact, one [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Screen-scraping">Screen scraping</a> is a somewhat still common technique that script-writers use to take the output of a web page (which wasn&#8217;t designed to be consumed by anything but a person viewing it in a web browser), grabs the portions relevant to their purposes, and spits out the parts that it wants.  In fact, one of the first plugins for the old <a href="http://moobot.sf.net">moobot</a> project that I wrote was a Google plugin which I thought I was so clever to write using the <a href="http://google.com/ie">IE search results</a> version of Google since it was much lighter and easier to parse.  It has no ads, no real formatting to speak of, and it was pretty much 80% data to 20% &#8220;other crap&#8221;, making it easy to scrape out the bits I wanted.  Thankfully they started providing an API until, well, see the below post <img src='http://blog.ghcoders.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>But, Google has plenty of great web designers at work there, so they don&#8217;t have horribly malformed HTML or tons of inline style crap.  Most other websites out there aren&#8217;t quite in the same boat.  In fact, looking at the source of the vast majority of sites will make most competent web designers wince if not cry.  Even well-formed HTML is not that easy to parse, and folks often resort to imprecise string matching or nasty regular expressions to get the job done.  If only there was a way to get that nasty HTML into a more nicely-parseable format&#8230;</p>
<p>Well, I saw <a href="http://geekswithblogs.net/mparsons/archive/2007/03/21/109421.aspx">this blog post</a> on <a href="http://programming.reddit.com">programming.reddit.com</a> (highly recommended, btw), and apparently he has set up a service that will fetch webpages and <a href="http://progressiveboink.com/nick/images/calvinandhobbes/CH870328.JPG">transmogrify</a> them into either (presumably well-formed) XML or JSON output, two flavors of output that have become popular with the rise of <abbr title="Asynchronous Javascript And XmlHttpRequest">AJAX</abbr>.  Unfortunately, you still get a lot of crap because, hey, <a href="http://en.wikipedia.org/wiki/GIGO">Garbage In, Garbage Out</a>.  But, at least it&#8217;s crap that&#8217;s in a somewhat prettier outfit.  Or if not prettier, at least, easier to dig through.  However, take heed in the authors plea at the end and don&#8217;t hammer the crap out of this.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ghcoders.net/2007/09/28/screen-scraping-made-kind-of-easier-i-guess/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Google APIs:  No SOAP key?  No problem.</title>
		<link>http://blog.ghcoders.net/2007/09/07/google-apis-no-soap-key-no-problem/</link>
		<comments>http://blog.ghcoders.net/2007/09/07/google-apis-no-soap-key-no-problem/#comments</comments>
		<pubDate>Fri, 07 Sep 2007 17:06:39 +0000</pubDate>
		<dc:creator>ddipaolo</dc:creator>
		
		<category><![CDATA[google]]></category>

		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://blog.ghcoders.net/?p=6</guid>
		<description><![CDATA[So, as one of the maintainers (using that term somewhat loosely as I haven&#8217;t touched a significant amount of code in there for quite sometime) of Supybot, I&#8217;ve heard a lot of complaining about the inability to get new SOAP search API keys.  Though there are (were?) some ways around this, by and large [...]]]></description>
			<content:encoded><![CDATA[<p>So, as one of the maintainers (using that term somewhat loosely as I haven&#8217;t touched a significant amount of code in there for quite sometime) of <a href="http://supybot.com">Supybot</a>, I&#8217;ve heard a lot of complaining about the inability to get new <a href="http://code.google.com/apis/soapsearch/">SOAP search API</a> keys.  Though there are (were?) <a href="http://www.hackszine.com/blog/archive/2006/12/get_a_google_search_soap_api_k.html">some ways around this</a>, by and large most folks who have wanted to use our Google plugin but don&#8217;t already have a SOAP search API key were basically out of luck.</p>
<p>To wit, I <strong>did</strong> write a  <a href="http://supybot.com/Members/Strike/plugins/Yahoo/plugin_view">Yahoo search plugin</a> that people have used and like using.  Thankfully they actually actively <a href="http://developer.yahoo.com/python/">embrace Python programmers</a> using their APIs and just provide a nice <abbr title="REpresentational State Transfer">REST</abbr>ful way of doing things without any domain specific junk.  It&#8217;s really quite a good plugin and a fairly good search engine and I encourage Supybot users to use it if they don&#8217;t have a Google SOAP key.</p>
<p>However, that said, people still want their Google.  Unfortunately simply &#8220;updating&#8221; the Supybot Google plugin isn&#8217;t as simple as transliterating things from one API to the other, you see.  Instead of providing a nice API like Yahoo did, Google replaced the SOAP API with an AJAX one.  That&#8217;s fantastic for embedding search boxes on web pages and for ease of rolling out updates (just update the script that everyone&#8217;s &lt;script&gt; element points to), but really crappy for the IRC bot plugin authors!  Fortunately, behind the scenes of the <a href="http://www.google.com/uds/js/uds_compiled.js">nasty obfuscated JavaScript</a> there is a RESTful service as well, and it too (like Yahoo&#8217;s) returns a <abbr title="JavaScript Object Notation">JSON</abbr>-formatted resultset (with a catch that I&#8217;ll get to later).</p>
<p>So, what to do if you want to use this nice (invisible to most) service?  Here&#8217;s the skinny.<br />
<span id="more-6"></span></p>
<p>The &#8220;new&#8221; search system is called &#8220;UDS&#8221; for  &#8220;User Distributed Search&#8221;.  I don&#8217;t know what that&#8217;s supposed to mean, but man am I tired of seeing the UDS acronym all over that JavaScript file I linked to above.  I&#8217;m actually in the process of untangling/de-obfuscating it at the moment, but that&#8217;s only tangentially relevant to this post.  Really all you need to know to use this service is how to construct the proper URL and what the results mean.  But first things first, you&#8217;re going to need one of the AJAX keys to do it so <a href="http://code.google.com/apis/ajaxsearch/signup.html">go grab one </a>first.</p>
<p>Now, the URL structure is pretty simple, the &#8220;base URL&#8221; is just:</p>
<p><code>http://www.google.com/uds/GwebSearch?</code></p>
<p>In fact, that in and of itself is a valid search URL.  Go ahead and <a href="http://www.google.com/uds/GwebSearch?">try it</a> if you want, and you&#8217;ll see an example of an error result.  For real application uses, you&#8217;ll want to construct the proper query string that goes next.  Here&#8217;s what you need to put in:</p>
<ul>
<li><code>callback</code> = for now just use <code>GwebSearch.RawCompletion</code> here, though once I detangle the JavaScript I may figure out other possible values here <strong>(required)</strong></li>
<li><code>context</code> = not sure about this yet either, but using <code>0</code> as the value has worked for me pretty well <strong>(required)</strong></li>
<li><code>hl</code> = the &#8220;locale&#8221; you want to search in, for English-speaking folks, it&#8217;s <code>en</code>.  For any other locale I&#8217;m guessing it matches <a href="http://www.google.com/apis/adwords/developer/adwords_api_languages.html">this listing</a>.  Entries that aren&#8217;t on that listing seem to use some sensible default (likely <code>en</code>).</li>
<li><code>key</code> = this is the big API key you got when you signed up <strong>(required)</strong></li>
<li><code>v</code> = the &#8220;version&#8221; code, I just use <code>1.0</code> <strong>(required)</strong></li>
<li><code>q</code> = the actual query string, formatted for URLs (replace spaces with + signs, etc.) <strong>(required)</strong></li>
<li><code>rsz</code> = the &#8220;result size&#8221; you want, the valid values I see are <code>large</code> and <code>small</code>, with the default being <code>small</code>.  Small returns 4 results, large returns 8 results. <strong>(optional)</strong></li>
</ul>
<p>There are various other arguments that you can add, but those are the most relevant and the ones I understand best.  So, a quick example URL for a search for &#8220;moo&#8221; would be:</p>
<p><code>http://www.google.com/uds/GwebSearch?callback=GwebSearch.RawCompletion&amp;context=0&amp;hl=en&amp;key=&lt;key&gt;&amp;v=1.0&amp;q=moo&amp;rsz=large</code></p>
<p>Obviously, you&#8217;d put your key in instead of just <code>&lt;key&gt;</code>, but the rest is all exactly what you&#8217;d put in for a search for &#8220;moo&#8221; where you wanted the most results.  One important thing to note though is that the <strong>order</strong> of these arguments does <em>not</em> matter.  As long as they are all <code>key=value</code> pairs separated by <code>&amp;</code> there should be no problem.</p>
<p>Great, so now what?  Well, the result you get back from a GET (note: this is important, it must be a GET and not a POST) on that URL, it looks something like this:</p>
<p><code>GwebSearch.RawCompletion('0',{"results": &lt;stuff&gt;}, 200, null, 200)</code></p>
<p>Of course, it&#8217;ll be much longer because <code>&lt;stuff&gt;</code> will actually be the important stuff we&#8217;re looking for.  But this is the catch I spoke of earlier.  Yes, this is a properly-formatted JSON response.  But, most JSON parsers will choke on it, because while it does represent a JavaScript object, it doesn&#8217;t know what the heck a <code>GwebSearch.RawCompletion</code> is without a little context!  Fortunately, basically all we are interested in is the dictionary &#8220;results&#8221;, and we can just parse that out and give that to our JSON parser instead.</p>
<p>So, let&#8217;s look at what the &#8220;results&#8221; dictionary looks like for this search:</p>
<p><code><br />
{"results":<br />
[<br />
{"GsearchResultClass":"GwebSearch",<br />
"unescapedUrl":"http://www.moo.com/",<br />
"url":"http://www.moo.com/",<br />
"visibleUrl":"www.moo.com",<br />
"cacheUrl":"http://www.google.com/search?q\u003Dcache:DsfEzWoDcLoJ:www.moo.com",<br />
"title":"\u003Cb\u003EMOO\u003C/b\u003E | We love to print",<br />
"titleNoFormatting":"MOO | We love to print",<br />
"content":"\u003Cb\u003EMOO\u003C/b\u003E Print Limited, registered in England; company number 5121723; registered   office 6 Bakers Yard, Bakers Row, London, EC1R 3DD \u003Cb\u003E...\u003C/b\u003E"<br />
},<br />
{"GsearchResultClass":"GwebSearch",<br />
"unescapedUrl":"http://en.wikipedia.org/wiki/MOO",<br />
"url":"http://en.wikipedia.org/wiki/MOO",<br />
"visibleUrl":"en.wikipedia.org",<br />
"cacheUrl":"http://www.google.com/search?q\u003Dcache:O-LNoqQLso8J:en.wikipedia.org",<br />
"title":"\u003Cb\u003EMOO\u003C/b\u003E - Wikipedia, the free encyclopedia",<br />
"titleNoFormatting":"MOO - Wikipedia, the free encyclopedia",<br />
"content":"A \u003Cb\u003EMOO\u003C/b\u003E (MUD object oriented) is a type of MUD and is a text-based online virtual   reality system to which multiple users are connected at the same time. \u003Cb\u003E...\u003C/b\u003E"<br />
},<br />
&lt;6 more similar results here, snipped for brevity&gt;<br />
],<br />
&#8220;cursor&#8221;:{}<br />
}<br />
</code></p>
<p>So basically it&#8217;s a dictionary with two elements:  <code>results</code> and <code>cursor</code>.  We&#8217;re not interested in the <code>cursor</code>, just the <code>results</code>, which maps to a list of dictionaries itself.  In each of those dictionaries you&#8217;ve got several fields:</p>
<ul>
<li><code>GSearchResultClass</code> = for web searches, it looks like this will always be <code>GwebSearch</code></li>
<li><code>unescapedUrl</code> = it is what it sounds like</li>
<li><code>url</code> = also what it sounds like</li>
<li><code>visibleUrl</code> = not entirely sure what precisely this is supposed to be other than the main site URL</li>
<li><code>cacheUrl</code> = a link to the URL for the search result as cached by Google, very cool</li>
<li><code>title</code> = <strong>duh</strong></li>
<li><code>titleNoFormatting</code> = duh  (see what I did there?)</li>
<li><code>content</code> = The standard 2-line-or-so block of text describing the URL</li>
</ul>
<p>Now, with this in mind, with any handy JSON parsing library, you can code up your very own Google search app that uses the new AJAX keys instead of the SOAP API keys.  In an upcoming post I&#8217;ll do a Python example.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ghcoders.net/2007/09/07/google-apis-no-soap-key-no-problem/feed/</wfw:commentRss>
		</item>
		<item>
		<title>New jorb</title>
		<link>http://blog.ghcoders.net/2007/09/07/new-jorb/</link>
		<comments>http://blog.ghcoders.net/2007/09/07/new-jorb/#comments</comments>
		<pubDate>Fri, 07 Sep 2007 15:35:40 +0000</pubDate>
		<dc:creator>ddipaolo</dc:creator>
		
		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://blog.ghcoders.net/?p=5</guid>
		<description><![CDATA[So I landed a position as a consultant at Pariveda Solutions and I start in a little over a week!  Hopefully that means there will be more programming talk to be had.  In fact, I&#8217;m almost sure of it.
]]></description>
			<content:encoded><![CDATA[<p>So I landed a position as a consultant at <a href="http://parivedasolutions.com">Pariveda Solutions</a> and I start in a little over a week!  Hopefully that means there will be more programming talk to be had.  In fact, I&#8217;m almost sure of it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ghcoders.net/2007/09/07/new-jorb/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Fantasy football site - DB schema design issues</title>
		<link>http://blog.ghcoders.net/2007/08/30/fantasy-football-site-db-schema-design-issues/</link>
		<comments>http://blog.ghcoders.net/2007/08/30/fantasy-football-site-db-schema-design-issues/#comments</comments>
		<pubDate>Thu, 30 Aug 2007 17:06:35 +0000</pubDate>
		<dc:creator>ddipaolo</dc:creator>
		
		<category><![CDATA[db]]></category>

		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://blog.ghcoders.net/?p=4</guid>
		<description><![CDATA[I&#8217;ve had the dream of building a better fantasy sports site for a while now, one where I could do all sorts of wacky data manipulation and feature addition.  Unfortunately, getting such a site up and running seems to have two conflicting steps:  1. I want to have something up and running that [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had the dream of building a better fantasy sports site for a while now, one where I could do all sorts of wacky data manipulation and feature addition.  Unfortunately, getting such a site up and running seems to have two conflicting steps:  1. I want to have something up and running that I can dig into relatively quickly, but 2. I want it to be incredibly flexible and extensible.  So, I&#8217;ve decided that #1 is the more important one, but that doesn&#8217;t mean I can&#8217;t continue to think about how to do #2.  And a lot of #2 is going to require DB schema changes, because obviously if you want a site to be more dynamic/flexible and to allow the users to control more things, then you need more fields in the database to store these changes.</p>
<p>The specific example this time is in dealing with what statistics to track and how to score them.  Most popular fantasy leagues only track a very small subset of the available stats on a given sport.  In football, it&#8217;s typically a list like:</p>
<ul>
<li>QB: pass yds, pass TDs, interceptions</li>
<li>RB/WR/TE: rec yds, rec TDs</li>
<li> QB/RB/WR/TE: rush yds, rush TDs, fumbles lost, 2pt conversions</li>
<li>K: FG made/missed in specified ranges (0-19 yds, 20-29 yds, &#8230; up to 50 yards or more)</li>
<li>DEF: fumble recoveries, defensive touchdowns, sacks, interceptions</li>
</ul>
<p>But there are still plenty of other stats out there, especially in leagues that use different positions (like ones that use <abbr title="Individual Defensive Players">IDPs</abbr> instead of team defenses).  So, my ultimate end would be to have a flexible place to store each statistic and its info, though for now I&#8217;m happy with something that just the ones I need to run my leagues.</p>
<p>The question is, how exactly would such a structure look in the database?  Keeping in mind that some of these stats are fundamentally different, and some have some scoring quirks, I&#8217;ve come up with three separate stat &#8220;types&#8221;:  the Range Stat, the Rate Stat, and the Rate Stat With Bonuses.</p>
<p>The Range Stat would be something like &#8220;Points Allowed&#8221; for a team defense or &#8220;FG Made&#8221; for a kicker.  I think, rather than having specific stats like &#8220;FG1-19&#8243; (number of field goals made that were between 1 and 19 yards), I should just be able to say &#8220;he made an 18 yard field goal&#8221; and let the scoring rules for each individual league adjust it accordingly, instead of shoe-horning it into the FG1-19 stat for one league and the FG1-29 for another.  Same thing with defensive points allowed, I&#8217;d like to just be able to enter each team&#8217;s scores for a game and then have it slot accordingly.</p>
<p>Rate Stats are the bread and butter of fantasy.  They are the &#8220;6 pts per rush TD&#8221; and &#8220;0.1 pts per rush yd&#8221; stats.  There&#8217;s not much magic here, really.</p>
<p>Rate Stats With Bonuses are less common, but useful.  Some leagues choose to offer a bonus for big games like instead of just &#8220;0.1 pts per rush yd&#8221; they&#8217;ll have &#8220;0.1 pts per rush yd, +5 pts at 100 yds&#8221;.  Not a whole lot of magic here either, as the bonus is applied during the score evaluation and not stored in the database itself.</p>
<p>But the question is, how do I represent these in the DB without having static columns for each possible stat?  Is that possible?  I&#8217;d like to be able to potentially add new stats without having to alter table structures.  I&#8217;d rather not have to just have a huge table with nothing but default values for things that I&#8217;m not using at the moment.  I&#8217;m wondering if there&#8217;s some sort of generic pattern for doing this or maybe I just haven&#8217;t thought hard enough about it.  I&#8217;ll post details about the current schema in a later post, perhaps.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ghcoders.net/2007/08/30/fantasy-football-site-db-schema-design-issues/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
