<?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:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Ryan Robitaille</title>
	
	<link>http://ryrobes.com</link>
	<description>Site Fabricator, Data Welder, Heavy Metal Systems Integrator | I.Make.Shit.Work.</description>
	<lastBuildDate>Fri, 20 Aug 2010 02:43:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Ryrobes" /><feedburner:info uri="ryrobes" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>Ryrobes</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Developers, IT Nerds, Useless Tech People – stop wielding “knowledge” like it was Geek Bravado weaponry</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/6iLST15KUPA/</link>
		<comments>http://ryrobes.com/random/developers-it-nerds-useless-tech-people-stop-wielding-knowledge-like-it-was-geek-bravado-weaponry/#comments</comments>
		<pubDate>Fri, 20 Aug 2010 02:43:43 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[Lifestyle]]></category>
		<category><![CDATA[Passion]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ramble]]></category>
		<category><![CDATA[Random]]></category>
		<category><![CDATA[angry]]></category>
		<category><![CDATA[babble]]></category>
		<category><![CDATA[IT staff]]></category>
		<category><![CDATA[pretentious programmers]]></category>
		<category><![CDATA[random]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=13568</guid>
		<description><![CDATA[I&#8217;m sorry &#8211; but who the fuck cares that you can recite X, Y, and Z off the top of your head. Is its relevant and useful? Generally, no. Are you helping the situation, project or issue? No. There is a word for out-of-context over-information like that&#8230; Banal Minutiae. Google search makes glorified know-it-alls obsolete. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fryrobes.com%2Frandom%2Fdevelopers-it-nerds-useless-tech-people-stop-wielding-knowledge-like-it-was-geek-bravado-weaponry%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fryrobes.com%2Frandom%2Fdevelopers-it-nerds-useless-tech-people-stop-wielding-knowledge-like-it-was-geek-bravado-weaponry%2F&amp;source=ryrobes&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;m sorry &#8211; but who the fuck cares that you can recite X, Y, and Z off the top of your head. Is its relevant and useful? Generally, no. Are you helping the situation, project or issue? No.</p>
<p>There is a word for out-of-context over-information like that&#8230;</p>
<h2>Banal Minutiae.</h2>
<h4>Google search makes glorified know-it-alls obsolete.</h4>
<p>I just don&#8217;t get why so many IT / tech-types are obsessed with specific pointless bullshit in their particular development niche or language &#8211; instead of just focusing on SOLVING PROBLEMS? Why spend your whole career &#8220;stuck in the weeds&#8221;? </p>
<h4>Technology changes, programming languages change&#8230;<br />
Helping people kick ass in business? That&#8217;s always in style.</h4>
<p>Anything I talk about tech-wise <em>(even if its lots of Python lately)</em> &#8211; is used as a TOOL to solve a PROBLEM. We all know that next year there will be different tools. We </p>
<p>might solve them differently. Marrying yourself to one technology, language or approach is just crippling your usefulness as far as I&#8217;m concerned.</p>
<h4>Use the right tool for the job, and move on to the next one.</h4>
<p><strong>End rant.</strong></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=6iLST15KUPA:pPJ-vZappYI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=6iLST15KUPA:pPJ-vZappYI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=6iLST15KUPA:pPJ-vZappYI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=6iLST15KUPA:pPJ-vZappYI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=6iLST15KUPA:pPJ-vZappYI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=6iLST15KUPA:pPJ-vZappYI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/6iLST15KUPA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/random/developers-it-nerds-useless-tech-people-stop-wielding-knowledge-like-it-was-geek-bravado-weaponry/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ryrobes.com/random/developers-it-nerds-useless-tech-people-stop-wielding-knowledge-like-it-was-geek-bravado-weaponry/</feedburner:origLink></item>
		<item>
		<title>Mortgage Software Hack: Importing Contacts automatically into Encompass WITHOUT the SDK (just with SQL)</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/Hlzw4hP69qk/</link>
		<comments>http://ryrobes.com/sql/mortgage-software-hack-importing-contacts-into-encompass-properly-without-the-sdk-using-just-the-sql-backend/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 16:18:46 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Hack]]></category>
		<category><![CDATA[Integration]]></category>
		<category><![CDATA[Microsoft SQL Server]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[backend hacks]]></category>
		<category><![CDATA[crappy software]]></category>
		<category><![CDATA[encompass]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[mortgage software]]></category>
		<category><![CDATA[saving man hours]]></category>
		<category><![CDATA[solutions]]></category>
		<category><![CDATA[sql server]]></category>
		<category><![CDATA[when life gives you lemons]]></category>
		<category><![CDATA[workflow automation]]></category>
		<category><![CDATA[workflow optimization]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=13525</guid>
		<description><![CDATA[Anyone who has ever dealt with the mortgage software package &#8220;Encompass&#8221; from Ellie Mae &#8211; from any kind of support / IT standpoint knows the pain. It just&#8230; well, doesn&#8217;t behave as you would assume. Seemingly simple things (from an integration / workflow standpoint) just don&#8217;t play nice, help in the web forums is laughable, [...]]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://ryrobes.com/wp-content/uploads/2010/08/mort-icon.jpg" width="240" />
		</p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fryrobes.com%2Fsql%2Fmortgage-software-hack-importing-contacts-into-encompass-properly-without-the-sdk-using-just-the-sql-backend%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fryrobes.com%2Fsql%2Fmortgage-software-hack-importing-contacts-into-encompass-properly-without-the-sdk-using-just-the-sql-backend%2F&amp;source=ryrobes&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p>Anyone who has ever dealt with the <a href="http://www.elliemae.com/">mortgage software package &#8220;Encompass&#8221; from Ellie Mae</a> &#8211; from any kind of support / IT standpoint knows the pain. It just&#8230; well, doesn&#8217;t behave as you would assume. Seemingly simple things <em>(from an integration / workflow standpoint)</em> just don&#8217;t play nice, help in the web forums is laughable, its slow, ugly, and so on. Yet, Encompass (360 even) is still an indispensable tool for many mortgage shops. </p>
<p>From an outside integration standpoint I had 2 initial hurdles &#8211; importing fresh data and decent reporting. I&#8217;ll tackle the first one today; In terms of getting new contacts and prospects imported into the system &#8211; there has to be built-in ways to do that, right? Sure, but there are (at the very least) 3 serious problems with them &#8220;out-of-the-box&#8221;: </p>
<ul>
<li>Loan Officers don&#8217;t want to type in prospect data every time</li>
<li>The Outlook &#8220;address book sync&#8221; thing is a total joke</li>
<li>and Importing them manually via CSV files? </li>
</ul>
<h4>Yeah, right. Fuck all that.</h4>
<p>If all of your Loan Officers got their perfect contacts / prospects over the phone and typed them in by hand into your beautiful Encompass Software &#8211; AND they always did it properly and consistently (chuckle) &#8211; well than that&#8217;s fine. However, we all know that isn&#8217;t how things work. Let&#8217;s say you get 90% of your incoming apps via your webpage&#8230; now unless you have the SDK and build some custom apps in-house to take care of these applications <em>(or buy some RIDICLOUSLY expensive 3rd party ones to do it)</em> its going to be quite an effort &#8211; most likely of manual <em>(and seemingly endless)</em> importing&#8230;</p>
<p>Thankfully, there IS another easier and quicker way. Encompass is built on a <a href="http://www.microsoft.com/sqlserver/2008/en/us/default.aspx">SQL Server database</a> backend. We can safely insert all new apps DIRECTLY into the Encompass backend Database as contacts.</p>
<p>This is what *I* do &#8211; your mileage may vary &#8211; it works with the latest version of Encompass (as of this writing &#8211; Aug 2010). ALWAYS TAKE A SQL SERVER backup before fucking around with the database <strong>(READ: <em>I am not responsible for your hosing your installation</em>)</strong>, however, I&#8217;ve never had a problem doing this &#8211; even DELETING contact records didn&#8217;t cause any damage.</p>
<blockquote><p>Disclaimer: This maybe look like a &#8220;dirty&#8221; solution, but you&#8217;re only seeing a fraction of the whole &#8220;integrated solution&#8221; &#8211; this is just a teaser to solve a simple problem that I faced many months ago and found very little help on the web for.</p></blockquote>
<p><strong>Step 1</strong> &#8211; The INITIAL insert into the Borrower table via a built-in Encompass stored procedure.</p>
<blockquote><p><strong>NOTE:</strong> For this example, I&#8217;m just using static data for the Application info &#8211; this SQL would have to be dynamically generated with each new app obviously (from PHP, Python, ASP, .NET, etc. etc. etc). Also, note that not ALL of these fields are required (obviously), but some WILL be &#8211; give it a few tests first. You might have to put in dummy NULLs or empty strings for fields that Encompass requires, but your web app does not (as I did).</p></blockquote>
<div class="codecolorer-container sql vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:575px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">/* This is just the bare shell of the <br />
contact / prospect - more detailed shit comes later */</span><br />
<span style="color: #993333; font-weight: bold;">USE</span> <span style="color: #66cc66;">&#91;</span>emdb<span style="color: #66cc66;">&#93;</span> <br />
DECLARE @NewContactId int<br />
EXEC <span style="color: #66cc66;">&#91;</span>emdbuser<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">.</span><span style="color: #66cc66;">&#91;</span>InsertBorrower<span style="color: #66cc66;">&#93;</span><br />
@FirstName <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'First'</span><span style="color: #66cc66;">,</span><br />
@LastName <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'LastName'</span><span style="color: #66cc66;">,</span><br />
@HomeAddress1 <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'123 Encompass Way'</span><span style="color: #66cc66;">,</span><br />
@HomeAddress2 <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@HomeCity <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Mapleopolis'</span><span style="color: #66cc66;">,</span><br />
@HomeState <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'IN'</span><span style="color: #66cc66;">,</span><br />
@HomeZip <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'34256'</span><span style="color: #66cc66;">,</span><br />
@BizAddress1 <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@BizAddress2 <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@BizCity <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@BizState <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@BizZip <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@BizWebUrl <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@EmployerName <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@JobTitle <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@WorkPhone <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'5555555555'</span><span style="color: #66cc66;">,</span><br />
@HomePhone <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'5555555555'</span><span style="color: #66cc66;">,</span><br />
@MobilePhone <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'5555555555'</span><span style="color: #66cc66;">,</span><br />
@FaxNumber <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@PersonalEmail <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'testytesterson@gmail.com'</span><span style="color: #66cc66;">,</span><br />
@BizEmail <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@Birthdate <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@Married <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span><br />
@SpouseContactID <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@SpouseName <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@Anniversary <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><br />
@CustField1 <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Custom Field 1'</span><span style="color: #66cc66;">,</span> <span style="color: #808080; font-style: italic;">--maybe originating state</span><br />
@CustField2 <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Custom Field 2'</span><span style="color: #66cc66;">,</span> <span style="color: #808080; font-style: italic;">--maybe web id number?</span><br />
@CustField3 <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Custom Field 3'</span><span style="color: #66cc66;">,</span> <span style="color: #808080; font-style: italic;">--etc</span><br />
@CustField4 <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Custom Field 4'</span><span style="color: #66cc66;">,</span><br />
@PrimaryEmail <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'testytesterson@gmail.com'</span><span style="color: #66cc66;">,</span><br />
@PrimaryPhone <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'5555555555'</span><span style="color: #66cc66;">,</span><br />
@NoSpam <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span><br />
<span style="color: #993333; font-weight: bold;">SET</span> @NewContactId <span style="color: #66cc66;">=</span> @@IDENTITY<br />
<span style="color: #808080; font-style: italic;">/* saving @NewContactId identity number somewhere <br />
so I can reference it in the next step... */</span></div></div>
<p><strong>Step 2</strong> &#8211; Now that we&#8217;ve started the contact process, we&#8217;ve got a unique contact ID (saved in a whole SQL script as I did, or saved in an external application to be re-used througout the transaction) and its time to put a bit more info in. The &#8216;Opportunity&#8217; table has important things like Loan Amount Requested, Credit Rating, etc. Pretty important stuff.</p>
<div class="codecolorer-container sql vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:575px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">--remember when I pulled out the IDENTITY </span><br />
<span style="color: #808080; font-style: italic;">--of the initial insert earlier? Yeeeesss.</span><br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> emdbuser<span style="color: #66cc66;">.</span>Opportunity <br />
<span style="color: #66cc66;">&#40;</span>ContactId<span style="color: #66cc66;">,</span> LoanAmount<span style="color: #66cc66;">,</span> CreditRating<span style="color: #66cc66;">,</span> <br />
PropertyAddress<span style="color: #66cc66;">,</span> PropertyCity<span style="color: #66cc66;">,</span> PropertyState<span style="color: #66cc66;">,</span> PropertyZip<span style="color: #66cc66;">&#41;</span> <br />
&nbsp; <span style="color: #993333; font-weight: bold;">VALUES</span> <br />
<span style="color: #66cc66;">&#40;</span>@NewContactId<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'CreditProfile'</span><span style="color: #66cc66;">,</span><br />
<span style="color: #ff0000;">'PropertyAddress1'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'PropertyCity'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'PropertyState'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'PropertyZip'</span><span style="color: #66cc66;">&#41;</span></div></div>
<p><strong>Step 3</strong> &#8211; (optional) This next one I do just for audit-trail. It basically adds a contact &#8220;history&#8221; record telling the LOs where the record came from &#8211; this is especially important if you&#8217;ve got apps coming from many sources or multiple websites.</p>
<div class="codecolorer-container sql vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:575px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">--again original IDENTITY required</span><br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> emdbuser<span style="color: #66cc66;">.</span>borrowerhistory <br />
<span style="color: #66cc66;">&#40;</span>contactid<span style="color: #66cc66;">,</span> timeofhistory<span style="color: #66cc66;">,</span> EventType<span style="color: #66cc66;">,</span> ContactSource<span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #993333; font-weight: bold;">VALUES</span> <br />
<span style="color: #66cc66;">&#40;</span>@NewContactId<span style="color: #66cc66;">,</span> getdate<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'First Contact'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'From Web App #1'</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>Incorporating this type of automation in your mortgage workflow could save you TONS of time and help increase conversions and reduce wasted administrative time. Obviously this is just the SQL Server side of the import &#8211; it would FIRST have to come from its original source and THEN be inserted&#8230; that small journey is up to your IT staff, <a href="http://ryrobes.com/consulting/">a data consultant</a>, or web team &#8211; but for the value it delivers&#8230; its well worth it.</p>
<h4>Questions, Problems, Fixes? Let me know.</h4>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=Hlzw4hP69qk:5MCktbqQ0yk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=Hlzw4hP69qk:5MCktbqQ0yk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=Hlzw4hP69qk:5MCktbqQ0yk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=Hlzw4hP69qk:5MCktbqQ0yk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=Hlzw4hP69qk:5MCktbqQ0yk:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=Hlzw4hP69qk:5MCktbqQ0yk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/Hlzw4hP69qk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/sql/mortgage-software-hack-importing-contacts-into-encompass-properly-without-the-sdk-using-just-the-sql-backend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ryrobes.com/sql/mortgage-software-hack-importing-contacts-into-encompass-properly-without-the-sdk-using-just-the-sql-backend/</feedburner:origLink></item>
		<item>
		<title>Running Python script(s) as a Windows Service – Keep your Python Mojo Engines Running while you Sleep!</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/IK7McHqGIgU/</link>
		<comments>http://ryrobes.com/python/running-python-scripts-as-a-windows-service/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 19:57:00 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Cut-n-Paste Code]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[Hack]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[code template]]></category>
		<category><![CDATA[cut-n-paste code]]></category>
		<category><![CDATA[integrate]]></category>
		<category><![CDATA[python service]]></category>
		<category><![CDATA[random]]></category>
		<category><![CDATA[win32]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[windows service]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=12744</guid>
		<description><![CDATA[Now any Python duct-taper integrate-anything junkie like me has a need to schedule their things (in production) every once in awhile. Usually this is not a problem &#8211; Unix / Linux cron jobs handle this nicely &#8211; but for a client or job that runs on a Windows server &#8211; the built-in &#8220;Scheduled Tasks&#8221; just [...]]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://ryrobes.com/wp-content/uploads/2010/08/jennypython.jpg" width="240" />
		</p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fryrobes.com%2Fpython%2Frunning-python-scripts-as-a-windows-service%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fryrobes.com%2Fpython%2Frunning-python-scripts-as-a-windows-service%2F&amp;source=ryrobes&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p>Now any <a href="http://ryrobes.com/featured-articles/using-a-simple-python-script-for-end-to-end-data-transformation-and-etl-part-1/"><strong>Python duct-taper <em>integrate-anything</em></strong> junkie</a> like me has a need to schedule their things <em>(in production)</em> every once in awhile. Usually this is not a problem &#8211; Unix / Linux cron jobs handle this nicely &#8211; but for a client or job that runs on a Windows server &#8211; the built-in &#8220;Scheduled Tasks&#8221; just never really cut it for me &#8211; in fact, I&#8217;ve always though that it was pretty Mickey-Mouse and not super reliable <em>(just my opinion &#8211; don&#8217;t flame me, you wily Windows Dudes &#8211; I know that there are 1,000 ways to skin a cat, here&#8217;s mine!)</em>&#8230; </p>
<p>It honestly gave me the creeps to put production stuff on there that NEEDED to be run every X minutes, hours, etc. Besides, making a batch file to fire off a python scripts feels so&#8230; well, unpolished &#8211; and pretty much of a lazy hack that made it into prod&#8230;</p>
<blockquote><p><strong>Disclaimer: </strong>Hey, I love hacks &#8211; they make the IT world go around, but I don&#8217;t like delivering shit to clients that have loose feeling triggers like that. Especially, if some smart ass IT dickface <em>(who COULDN&#8217;T pull off what I did, or else I wouldn&#8217;t have been paid to do it)</em> is going to dig into them one day and bad mouth me about it <em>(rightfully so)</em>. </p>
<p>Besides, I&#8217;ll find you! :)</p></blockquote>
<p>Enough blather &#8211; here is the whole script. Modify and distribute where you see fit &#8211; parts of it were written by others that I can&#8217;t recall <em>(so if its you &#8211; please accept my apology and an expired gift card)</em>.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">### Run Python scripts as a service example (ryrobes.com)</span><br />
<span style="color: #808080; font-style: italic;">### Usage : python aservice.py install (or / then start, stop, remove)</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">import</span> win32service<br />
<span style="color: #ff7700;font-weight:bold;">import</span> win32serviceutil<br />
<span style="color: #ff7700;font-weight:bold;">import</span> win32api<br />
<span style="color: #ff7700;font-weight:bold;">import</span> win32con<br />
<span style="color: #ff7700;font-weight:bold;">import</span> win32event<br />
<span style="color: #ff7700;font-weight:bold;">import</span> win32evtlogutil<br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">sys</span>, <span style="color: #dc143c;">string</span>, <span style="color: #dc143c;">time</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">class</span> aservice<span style="color: black;">&#40;</span>win32serviceutil.<span style="color: black;">ServiceFramework</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;_svc_name_ = <span style="color: #483d8b;">&quot;MyServiceShortName&quot;</span><br />
&nbsp; &nbsp;_svc_display_name_ = <span style="color: #483d8b;">&quot;My Serivce Long Fancy Name!&quot;</span><br />
&nbsp; &nbsp;_svc_description_ = <span style="color: #483d8b;">&quot;THis is what my crazy little service does - aka a DESCRIPTION! WHoa!&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, args<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;win32serviceutil.<span style="color: black;">ServiceFramework</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, args<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008000;">self</span>.<span style="color: black;">hWaitStop</span> = win32event.<span style="color: black;">CreateEvent</span><span style="color: black;">&#40;</span><span style="color: #008000;">None</span>, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span>, <span style="color: #008000;">None</span><span style="color: black;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
<br />
&nbsp; &nbsp;<span style="color: #ff7700;font-weight:bold;">def</span> SvcStop<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008000;">self</span>.<span style="color: black;">ReportServiceStatus</span><span style="color: black;">&#40;</span>win32service.<span style="color: black;">SERVICE_STOP_PENDING</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;win32event.<span style="color: black;">SetEvent</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">hWaitStop</span><span style="color: black;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;<span style="color: #ff7700;font-weight:bold;">def</span> SvcDoRun<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">import</span> servicemanager &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; servicemanager.<span style="color: black;">LogMsg</span><span style="color: black;">&#40;</span>servicemanager.<span style="color: black;">EVENTLOG_INFORMATION_TYPE</span>,servicemanager.<span style="color: black;">PYS_SERVICE_STARTED</span>,<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>._svc_name_, <span style="color: #483d8b;">''</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#self.timeout = 640000 &nbsp; &nbsp;#640 seconds / 10 minutes (value is in milliseconds)</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span> = <span style="color: #ff4500;">120000</span> &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#120 seconds / 2 minutes</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># This is how long the service will wait to run / refresh itself (see script below)</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff4500;">1</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #808080; font-style: italic;"># Wait for service stop signal, if I timeout, loop again</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;rc = win32event.<span style="color: black;">WaitForSingleObject</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">hWaitStop</span>, <span style="color: #008000;">self</span>.<span style="color: black;">timeout</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #808080; font-style: italic;"># Check to see if self.hWaitStop happened</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff7700;font-weight:bold;">if</span> rc == win32event.<span style="color: black;">WAIT_OBJECT_0</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Stop signal encountered</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; servicemanager.<span style="color: black;">LogInfoMsg</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SomeShortNameVersion - STOPPED!&quot;</span><span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;">#For Event Log</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">break</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff7700;font-weight:bold;">else</span>:<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #808080; font-style: italic;">#Ok, here's the real money shot right here.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #808080; font-style: italic;">#[actual service code between rests]</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff7700;font-weight:bold;">try</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;file_path = <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\w</span>hereever<span style="color: #000099; font-weight: bold;">\m</span>y_REAL_py_work_to_be_done.py&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008000;">execfile</span><span style="color: black;">&#40;</span>file_path<span style="color: black;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#Execute the script</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;inc_file_path2 = <span style="color: #483d8b;">&quot;C:<span style="color: #000099; font-weight: bold;">\w</span>hereever<span style="color: #000099; font-weight: bold;">\M</span>ORE_REAL_py_work_to_be_done.py&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #008000;">execfile</span><span style="color: black;">&#40;</span>inc_file_path2<span style="color: black;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #808080; font-style: italic;">#Execute the script</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff7700;font-weight:bold;">except</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #ff7700;font-weight:bold;">pass</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #808080; font-style: italic;">#[actual service code between rests]</span><br />
<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> ctrlHandler<span style="color: black;">&#40;</span>ctrlType<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp;<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">True</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>: &nbsp; <br />
&nbsp; &nbsp;win32api.<span style="color: black;">SetConsoleCtrlHandler</span><span style="color: black;">&#40;</span>ctrlHandler, <span style="color: #008000;">True</span><span style="color: black;">&#41;</span> &nbsp; <br />
&nbsp; &nbsp;win32serviceutil.<span style="color: black;">HandleCommandLine</span><span style="color: black;">&#40;</span>aservice<span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Done! Lets go out and get some dinner, bitches!</span></div></div>
<p>As you can see above between the <strong>[actual service code between rests]</strong> text &#8211; THAT&#8217;S the real meat of this script &#8211; since that is the ACTION that will be executed within the service with each iteration (regardless of the timing). </p>
<p>So it doesn&#8217;t matter if you&#8217;re:</p>
<ul>
<li>Running some Python ETL processes</li>
<li>Scraping some data off the web</li>
<li>Sending emails and reading IMAP accounts</li>
<li>Updating a Data warehouse</li>
<li>EMail your Grandmother the latest news from Blabbermouth.net</li>
</ul>
<p>Hell, it can be and do virtually anything! Hey, its YOUR service after all.</p>
<p>Don&#8217;t want to Cut-N-Paste? I don&#8217;t blame you &#8211; download <a href="http://ryrobes.com/stuff/py_service.py">the whole she-bang here</a>.</p>
<h4>Questions, Comments, Corrections? Comment me below!</h4>
<p><em>(especially corrections &#8211; sometimes things get mangled in cut-n-paste)</em></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=IK7McHqGIgU:ZSbBBcfBj4A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=IK7McHqGIgU:ZSbBBcfBj4A:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=IK7McHqGIgU:ZSbBBcfBj4A:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=IK7McHqGIgU:ZSbBBcfBj4A:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=IK7McHqGIgU:ZSbBBcfBj4A:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=IK7McHqGIgU:ZSbBBcfBj4A:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/IK7McHqGIgU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/python/running-python-scripts-as-a-windows-service/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ryrobes.com/python/running-python-scripts-as-a-windows-service/</feedburner:origLink></item>
		<item>
		<title>Business Intelligence, Tools, Dirty Caveman Sex, Open-Source – Part 1</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/jLjbY4UEfn4/</link>
		<comments>http://ryrobes.com/etl/business-intelligence-tools-dirty-caveman-sex-open-source-part-1/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 05:13:39 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[BizDev]]></category>
		<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Business Intelligence]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[ETL]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[Microsoft SQL Server]]></category>
		<category><![CDATA[Reporting]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[BI basics]]></category>
		<category><![CDATA[business intelligence]]></category>
		<category><![CDATA[data analysis]]></category>
		<category><![CDATA[data collection]]></category>
		<category><![CDATA[data management]]></category>
		<category><![CDATA[data warehouse]]></category>
		<category><![CDATA[open-source BI]]></category>
		<category><![CDATA[open-source business intelligence]]></category>
		<category><![CDATA[reporting tools]]></category>
		<category><![CDATA[rockstar data monkey]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=3259</guid>
		<description><![CDATA[Business Intelligence. I hate the term as an IT buzzword. So sick of hearing Business Intelligence-this, Business Intelligence-that, Business Intelligence-expert-my-ass. But, hate it or not "Business Intelligence" shiz isn't going anywhere - in fact, its been here in one way, shape, or form since the first caveman traded a sharp rock for some unsanctioned cave-nookie.]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://ryrobes.com/wp-content/uploads/2010/08/geico-caveman-relaxing.jpg" width="240" />
		</p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fryrobes.com%2Fetl%2Fbusiness-intelligence-tools-dirty-caveman-sex-open-source-part-1%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fryrobes.com%2Fetl%2Fbusiness-intelligence-tools-dirty-caveman-sex-open-source-part-1%2F&amp;source=ryrobes&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>Part 1 </strong>- Before we all start examining tools like <a href="http://en.wikipedia.org/wiki/Nick_Riviera">seconds rate doctors</a> &#8211; lets cover the <a href="http://en.wikipedia.org/wiki/Business_intelligence">Business Intelligence</a> (<em>Wikipedia for you skeptics</em>) basics, shall we?</p>
<p><strong>Business Intelligence</strong>. <strong>Business Intelligence Solution</strong>. <strong>Business Intelligence Data Analysis Tool</strong>. BI-this. BI-That. God <em>Damn</em>. </p>
<p>How often do we have to have that phrase shoved down our throats by faceless corporate product snake-oil salesmen, unscrupulous consultants, random shithead &#8220;experts&#8221; and brainless middle managers who just read about it in last months issue of Wired. I hate the term as an IT buzzword, but the underlying concept is essential these days in any industry and at every step on the big-money biz ladder. Hate it or not &#8220;Business Intelligence&#8221; isn&#8217;t going anywhere &#8211; in fact, <strong>its been here in one way, shape, or form since the first caveman traded one of his <em>stone axe blades</em> for some otherwise <em>unsanctioned cave-nookie</em>. </strong></p>
<p><a href="http://ryrobes.com/wp-content/uploads/2010/08/cavemen-million-years-bc.jpg"><img src="http://ryrobes.com/wp-content/uploads/2010/08/cavemen-million-years-bc.jpg" alt="Cave Babes = WIN." title="cavemen-million-years-bc" width="300" height="300" class="size-full wp-image-3386" /></a><br/><br/></p>
<p>Since those pioneering days of seeking more profitable cave transactions, the amount of data that has become available and stored about almost every aspect of a company&#8217;s business is just freaking staggering. Now its more important than ever to try and figure your shit out &#8211; and FAST. No time to wait for some slacker to come in to slowly generate those quarterly TPS reports. I mean, gee, who DOESN&#8217;T want to be able to constantly make sense of their data, identify trends, optimize their approach, and just generally decode the data hieroglyphics of yesterday to kick more ass tomorrow? </p>
<h4><em>&#8220;Good Enough&#8221;</em> isn&#8217;t going <strong>to cut it anymore</strong>. </h4>
<p>Doesn&#8217;t matter if we&#8217;re talking about sales, crimes, advertising campaign conversions, seasonal product performance, spice potency, or @<a href="http://twitter.com/ed">Ed&#8217;s &#8220;re-tweetability&#8221;</a>. Whatever it is that you measure / Whatever is important to you &#8211; make sure you&#8217;re always making the best possible decisions to get there based on the historical knowledge at hand. A good Business Intelligence solution <em>(Ok, read that as &#8220;Business Intelligence IMPLEMENTATION&#8221; since, much to my dismay, nothing ever configures itself)</em> can put you on the road to finally getting the big picture of your business data at any given moment and therefore being able to respond quicker, be more proactive, and generally avoid becoming putrid bizdev roadkill <em>(or getting fired by some monopoly guy from the 10th floor)</em>.</p>
<blockquote><h4>&#8220;In 2010 &#8211; not having a solid Business Intelligence reporting framework in place is like driving blindfolded with a skunk on your lap and a trunk full of dead hookers. </p>
<p>You may be able to stall off disaster for a while by swinging the wheel wildly and honking the horn but you&#8217;re bound to get totally douched in the end.&#8221;</h4>
</blockquote>
<p>I could go on and on like a self-indulgent geek-asshole about the importance of meta-data in BI, post flow charts about &#8220;<em>Business Intelligence Implementation Best Practices</em>&#8220;, the importance of proper data warehousing, star schema, and other bullshit that won&#8217;t ever get you a date &#8211; but on a high-level all you REALLY need to know is this&#8230; </p>
<h2>Business Intelligence will help you SEE WHATS GOING ON in your business, and THIS will enable you to make changes that SAVE money &#8211; or make MORE money. </h2>
<p>Word. Actually, in THIS of economy we might as well say that a solid view of your data can mean the difference between being IN business and being OUT of business. Ouch. The truth hurts, don&#8217;t it? Anyways, let&#8217;s put that nasty thought behind us for now&#8230;</p>
<p><em>Moving on&#8230;</em></p>
<p>Most small to medium size companies (regardless of industry) have these 3 things in common:</p>
<ul>
<li><strong>Boat-loads of data</strong> (sales, stats, operational metrics, etc)</li>
<li><strong>No boat-loads of cash</strong> (More like a McDonalds Dollar-Menu boat)</li>
<li><strong>No <a href="http://ryrobes.com/marketing/what-sookie-stackhouse-can-teach-you-about-being-a-better-blogger/">cute blond telepath</a> to siphon key metrics out of your staff daily</strong> (oh, behave!)</li>
</ul>
<p>Assuming that you&#8217;ve been living under a rock and vacationing in a tree for a few years &#8211; just take a look at a quick Google search for business intelligence or business intelligence tools. The top paid and unpaid results are pretty much what you&#8217;d expect: IBM, Oracle, Microsoft <em>(who is actually doing some REALLY cool stuff these days)</em>, SAP / BusinessObjects, Cognos, etc. You the idea. What do all these tools and &#8220;solutions&#8221; have in common? They all cost many thousands <em>(if not millions)</em> of dollars to license &#8211; and THEN you still have to figure out how to use and implement the damn things anyways.</p>
<blockquote><p><em>I have to mention &#8211; you don&#8217;t really need any fancy product (free or otherwise) to help you with your BI woes &#8211; in fact, I&#8217;ve done it several times before using some custom (and clever &#8211; if I do say so myself) PHP, <a href="http://ryrobes.com/featured-articles/using-a-simple-python-script-for-end-to-end-data-transformation-and-etl-part-1/">Python</a>, and a variety of databases &#8211; but that was after I already had an intimate familiarity with the data, business logic, and desired results. Meaning that I had already mapped out what I wanted (aka &#8220;the questions I wanted to ask the system&#8221;) / what was there (&#8220;where to find my answers&#8221;) and THEN built it to these specs. So if you&#8217;ve got <a href="http://ryrobes.com/featured-articles/it-battle-of-the-ages-specialization-vs-wide-open-solutions/">some rouge IT genius / data hacker on your staff</a> &#8211; throw him a months supply of RedBull and go for it &#8211; <strong>OR you <a href="http://ryrobes.com/consulting/">could just hire me</a> (besides I&#8217;m affordable, funny, and probably sexier than your IT staffers)</strong>, but I digress. :) Barring that, a decent &#8220;BI Tool&#8221; can usually make the exploration / building / troubleshooting process much easier.</em></p></blockquote>
<h4>Stick around for Part 2 &#8211; when we will look at a couple BI Tool sets that won&#8217;t break the bank (or even require one at all &#8211; can&#8217;t argue with that!).</h4>
<p><strong>[ Subscribe to the mailing list to make sure you don't miss it! Hint: Its in the upper right corner! ]</strong></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=jLjbY4UEfn4:3ET0RCH7Z6Y:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=jLjbY4UEfn4:3ET0RCH7Z6Y:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=jLjbY4UEfn4:3ET0RCH7Z6Y:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=jLjbY4UEfn4:3ET0RCH7Z6Y:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=jLjbY4UEfn4:3ET0RCH7Z6Y:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=jLjbY4UEfn4:3ET0RCH7Z6Y:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/jLjbY4UEfn4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/etl/business-intelligence-tools-dirty-caveman-sex-open-source-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ryrobes.com/etl/business-intelligence-tools-dirty-caveman-sex-open-source-part-1/</feedburner:origLink></item>
		<item>
		<title>Fuck, sales, leads, &amp; sign-ups. You know what has the BEST conversion rate ever?</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/bmXa-EAtyIU/</link>
		<comments>http://ryrobes.com/marketing/fuck-sales-leads-sign-ups-you-know-what-has-the-best-conversion-rate-ever/#comments</comments>
		<pubDate>Fri, 06 Aug 2010 01:49:39 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Authenticity]]></category>
		<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Random]]></category>
		<category><![CDATA[Reporting]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=1380</guid>
		<description><![CDATA[Smile at people. Oh, that&#8217;s right &#8211; I just dropped a feel-good knowledge bomb on you of EPIC proportions. I guarantee that if you look people in the eyes and smile at them &#8211; regardless if its a cashier, toll booth worker, random ass-pony on the street, cute girls (or dudes) at a bar, or [...]]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://ryrobes.com/wp-content/uploads/2010/08/happy_girl.jpg" width="240" />
		</p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fryrobes.com%2Fmarketing%2Ffuck-sales-leads-sign-ups-you-know-what-has-the-best-conversion-rate-ever%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fryrobes.com%2Fmarketing%2Ffuck-sales-leads-sign-ups-you-know-what-has-the-best-conversion-rate-ever%2F&amp;source=ryrobes&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<h2>Smile at people.</h2>
<p>Oh, that&#8217;s right &#8211; I just dropped a feel-good knowledge bomb on you of EPIC proportions. I guarantee that if you look people in the eyes and smile at them &#8211; regardless if its a cashier, toll booth worker, random ass-pony on the street, cute girls (or dudes) at a bar, or even the fuggin&#8217; mailman &#8211; they will smile back in a genuine fashion probably 92.5% of the time <em>(the remaining 7.5% are probably just miserable douchebags)</em>. Try it. Its an easy experiment that has a really &#8220;human&#8221; payoff.</p>
<h4>We&#8217;re social animals by nature. <br/>Communication. Communication. Commnuication.</h4>
<p>Think about that the next time you&#8217;re in a meeting where the talking heads are trying to figure out how to <em>&#8220;make big money on this social media thing&#8221;</em>. If you&#8217;re still thinking like that you&#8217;ve (almost) already lost. Drink a Diet Coke and reboot. Just communicate genuinely with people and they&#8217;ll commnuicate back. Think small-town hardware store / except on an online, global scale. THAT&#8217;S how business is going to be done 2010 and beyond. </p>
<h3>The so-called &#8216;Big box&#8217; store mentality is OUT. </h3>
<h4>Smiles and handshakes (even virtual ones) are in.</h4>
<p>That&#8217;s real fucking shit. I&#8217;m sorry <a href="http://twitter.com/garyvee">@garyvee</a> &#8211; but its true.</p>
<h2>Its a culture thing. Get on it.</h2>
<p>What do you think?</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=bmXa-EAtyIU:tG1wJPDWa2w:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=bmXa-EAtyIU:tG1wJPDWa2w:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=bmXa-EAtyIU:tG1wJPDWa2w:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=bmXa-EAtyIU:tG1wJPDWa2w:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=bmXa-EAtyIU:tG1wJPDWa2w:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=bmXa-EAtyIU:tG1wJPDWa2w:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/bmXa-EAtyIU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/marketing/fuck-sales-leads-sign-ups-you-know-what-has-the-best-conversion-rate-ever/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ryrobes.com/marketing/fuck-sales-leads-sign-ups-you-know-what-has-the-best-conversion-rate-ever/</feedburner:origLink></item>
		<item>
		<title>What Sookie Stackhouse can teach you about being a better blogger</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/hTfwJiOfqA0/</link>
		<comments>http://ryrobes.com/marketing/what-sookie-stackhouse-can-teach-you-about-being-a-better-blogger/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 04:22:02 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Authenticity]]></category>
		<category><![CDATA[Blogging]]></category>
		<category><![CDATA[Featured Articles]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[Irreverence]]></category>
		<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Passion]]></category>
		<category><![CDATA[Random]]></category>
		<category><![CDATA[Awesome]]></category>
		<category><![CDATA[Fake]]></category>
		<category><![CDATA[Sookie Stackhouse]]></category>
		<category><![CDATA[TrueBlood]]></category>
		<category><![CDATA[TV]]></category>
		<category><![CDATA[Vampires]]></category>
		<category><![CDATA[Werewolves]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=393</guid>
		<description><![CDATA[TrueBlood. Killer show. Let&#8217;s face it. It really is a weird-ass perfect storm of timing, promotion, and just straight up quality storytelling. Don&#8217;t even dare to compare it with those Justin-Beiber-esque-Saved-by-the-Bell-type-Vampire-Twilight-Movies that are currently sweeping the minds and loins of young teens these days. They are an inferior product &#8211; vamprires (fictional or not) do [...]]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://ryrobes.com/wp-content/uploads/2010/08/sookie-eric.jpg" width="240" />
		</p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fryrobes.com%2Fmarketing%2Fwhat-sookie-stackhouse-can-teach-you-about-being-a-better-blogger%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fryrobes.com%2Fmarketing%2Fwhat-sookie-stackhouse-can-teach-you-about-being-a-better-blogger%2F&amp;source=ryrobes&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://www.hbo.com/true-blood">TrueBlood</a>. Killer show. Let&#8217;s face it. It really is a weird-ass perfect storm of timing, promotion, and just straight up quality storytelling. Don&#8217;t even dare to compare it with those Justin-Beiber-esque-Saved-by-the-Bell-type-Vampire-Twilight-Movies that are currently sweeping the minds and loins of young teens these days. They are an inferior product &#8211; vamprires (fictional or not) do not &#8220;sparkle like diamonds&#8221; in the sunlight (no matter HOW blatantly gay they might be), its just Nickelodeon brand bullshit. (Damn kids these days!)</p>
<p>Anyways, the highly-accliamed HBO show is in its 3rd season now and has been a huge success (and hasn&#8217;t really even &#8220;jumped the shark&#8221; yet). The wicked popularity and ratings can be attributed to many reasons I think &#8211; but I&#8217;ll just boil them down to a few simple ones&#8230;</p>
<h3>Its Edgy, Sexy, Graphic, Funny, and just plain Fucked Up.</h3>
<p>Its not exactly the most polically correct &#8220;safe&#8221; choice for Sunday night viewing. Honestly, that&#8217;s why we LOVE the hell out of it. I&#8217;ll admit, it took a few for me to &#8220;get into&#8221; it &#8211; but once you&#8217;ve acclimated yourself to their world and particular brand of southern Lousiana beastiality &#8211; you&#8217;re HOOKED.</p>
<p>How does that relate to your blogging (or lack thereof)? Who are you talking TO, who are you talking LIKE? What are you afraid of?</p>
<h3>Be interesting. Be abrasive. Be yourself. Be REAL.</h3>
<h4>There is no point in trying to sound all &#8216;professional&#8217; these days unless you&#8217;re a Doctor, Lawyer, or BP Executive. </h4>
<blockquote>
<h2>People don&#8217;t have to be cute, blonde telepaths to be able to smell bullshit.</h2>
</blockquote>
<p>No sir. You&#8217;ll be much more interesting to your target audience when you stop posing as something that you probably are not. We&#8217;re more like the characters in the show than you think (well, minus most of the murdering and mythical abilities anyways) &#8211; each very unique, troubled, and has a different story to tell. We are taught growing up to tell people what they want to hear, say what we&#8217;re supposed to say, don&#8217;t color outside the lines. Bound by Status quo &#8211; Social contract &#8211; and Baby Boomer expectations. All this is supposed to be that glue that holds &#8220;society&#8221; together. Bullshit. Its social manipulation. Its the glue that keeps us from moving forward.</p>
<p>All Generation X and Generation Y &#8211; we&#8217;re all a bit &#8220;off&#8221; to begin with. Us Gen-Xers are slowly taking the reigns away from the retiring Baby Boomers, and we don&#8217;t need to get &#8216;pitched to&#8217; the same way. Be a damn human, talk to us, if your shit is good and we like you &#8211; we buy. Its as simple as that. No need for 3-piece suits, dazzlingly clean copywriting full of $13 adjectives, or Hard Sell verbage. </p>
<p>Give it a try &#8211; let your fans get to know you, trust you, and (ultimately) maybe even buy from you. Feed them like little baby birds. <em>Mmmm freshly regurgitated worms&#8230;</em><br/><br />
<a href="http://ryrobes.com/wp-content/uploads/2010/08/ericsook-full.jpg"><img src="http://ryrobes.com/wp-content/uploads/2010/08/ericsook-full.jpg" alt="" title="Eric and Sookie" width="491" height="290" class="aligncenter size-full wp-image-405" /></a></p>
<h4>Hell, we LOVE buying stuff &#8211; especially if it has anything to do with Vampires, Werewolves, Zombies, gratuitious toplessness, sexy Vikings, or sweet accents.</h4>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hTfwJiOfqA0:Hq8pZV59-14:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hTfwJiOfqA0:Hq8pZV59-14:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=hTfwJiOfqA0:Hq8pZV59-14:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hTfwJiOfqA0:Hq8pZV59-14:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=hTfwJiOfqA0:Hq8pZV59-14:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hTfwJiOfqA0:Hq8pZV59-14:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/hTfwJiOfqA0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/marketing/what-sookie-stackhouse-can-teach-you-about-being-a-better-blogger/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://ryrobes.com/marketing/what-sookie-stackhouse-can-teach-you-about-being-a-better-blogger/</feedburner:origLink></item>
		<item>
		<title>IT Battle of the Ages: Specialization vs Wide-Open Solutions</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/hvaBUQ3GstA/</link>
		<comments>http://ryrobes.com/featured-articles/it-battle-of-the-ages-specialization-vs-wide-open-solutions/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 02:11:01 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Featured Articles]]></category>
		<category><![CDATA[Lifestyle]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[baseball]]></category>
		<category><![CDATA[consultants]]></category>
		<category><![CDATA[experts]]></category>
		<category><![CDATA[featured]]></category>
		<category><![CDATA[IT]]></category>
		<category><![CDATA[jack-of-all-trades]]></category>
		<category><![CDATA[Pirates]]></category>
		<category><![CDATA[problem solving]]></category>
		<category><![CDATA[programmers]]></category>
		<category><![CDATA[skillsets]]></category>
		<category><![CDATA[Spring Training]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=233</guid>
		<description><![CDATA[I once had a boss who was an ex-professional Baseball player. A catcher. That's right, I said "professional". He was drafted and everything, but never fully got called up to the active roster from his farm team (for the Pittsburgh Pirates). He spent over 3 years in the organization - outlasting many players, seeing others get called up, and playing against dozens who would go on to be greats in the Major Leagues. When he finally did get cut he was told this...]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://ryrobes.com/thumbs/baseball-glove.jpg" width="240" />
		</p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fryrobes.com%2Ffeatured-articles%2Fit-battle-of-the-ages-specialization-vs-wide-open-solutions%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fryrobes.com%2Ffeatured-articles%2Fit-battle-of-the-ages-specialization-vs-wide-open-solutions%2F&amp;source=ryrobes&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<h2>Its Story Time, kids.</h2>
<p>I once had a boss <i>(who I respect and looked up to probably more than any I&#8217;ve had since)</i> who was an ex-professional Baseball player. A catcher. That&#8217;s right, I said <em>&#8220;professional&#8221;</em>. He was officially drafted and everything, but never fully got called up to the active roster from his farm team (for the Pittsburgh Pirates). He spent over 3 years in the organization &#8211; outlasting many players, seeing others get called up, and playing against dozens who would go on to be greats in the Major Leagues.<br />
<span id="more-233"></span><br />
When he finally did get cut, he was given this nugget of gut wrenching &#8220;advice&#8221;&#8230;</p>
<blockquote><h3>&#8220;You&#8217;re an all around good player.. good fielder, good behind the plate, good at bat &#8211; but you aren&#8217;t TRULY GREAT at any one thing.&#8221;</h3>
</blockquote>
<p>Even then <em>(at the time he told me his story)</em>, years later &#8211; with him being a partner in a boomingly successful consultancy company, he was still haunted by the ghosts of those words. So much so that he equated it directly to his experience and expertise in the IT industry. He hated being a &#8220;jack of all trades&#8221; and was a go-to guy for many things, since his tenacity and creative problem solving abilities allowed him to accomplish pretty much anything that we set out to prove&#8230;</p>
<p><em>At least thats how I remember it all anyways, and hey, and isn&#8217;t that all that matters?</em></p>
<p>At the time we had similar skill sets, so that idea stuck with me and hung over my head a bit as well. </p>
<p>Now, it&#8217;s 10+ years later and we&#8217;ve both moved on to different things (which is a whole story in itself) &#8211; and for the longest time I carried that proverbial weight on my shoulders too &#8211; the idea that somehow if you decided to specialize and become an expert at ONE thing &#8211; you&#8217;ll always have work, you&#8217;ll always make bucket-loads of money, and the sun god will always smile upon thee with radiant jubilation&#8230;</p>
<p>Right?</p>
<p>Nah.</p>
<h3>Eventually, I realized that that mentality is just straight-up fucking wrong. </h3>
<p>I&#8217;ll tell you why &#8211; its because it seems like 95% of people who are grand-high masters in one area (be it a programming language, a IT disipline, a sub-department, a specific proprietary customizable application, etc) know hardly anything about the &#8220;Big Picture&#8221;. Whats even worse is that not only do they NOT know, but they are totally fine with not knowing &#8211; and don&#8217;t give a shit about it either. Complete and Utter FAIL.</p>
<p>Maybe that&#8217;s what a true &#8220;programmer&#8221; is supposed to do. You tell it to make &#8220;1 + 3 = 6&#8243;, and it&#8217;ll do it. Garbage in, garbage out &#8211; right? Hey, at my day job blind and mindless button-pushing consultant like this outnumber me 3 to 1. Pumping out hours &#8211; but doing work for the sake of doing work. But enough of that&#8230;</p>
<p>Hey, maybe its because of my old school days of being a VW mecanic (another story), but, I love using a &#8220;toolbox&#8221; analogy when it comes to technology and IT in general. Why? Because with enough tools, you can pretty much fix or build just about anything in 100 different ways depending on what we want the outcome to be. But, if all you own is a really good hammer &#8211; after awhile everything is going to start to look like a freaking nail.<br />
<br/><br/></p>
<h3>If you&#8217;re the highly paid hammer expert and I&#8217;m the east coast&#8217;s more prolific screwdriver master we MIGHT be able to get together just enough to make a really heinous looking spice rack &#8211; but it will take forever and be full of disagreements. </p>
<p>What you REALLY needed was a fucking carpenter!</h3>
<p>How many projects have you been involved in where in the end it looks like someone tried to hammer in a bunch of screws. It happens way too much.</p>
<p>What&#8217;s the best &#8220;expertise&#8221; to have? Well, I&#8217;ll tell you. Have the biggest toolbox anyone has ever seen, and add more to it every day.<br />
<br/></p>
<h3>There isn&#8217;t any tech / IT problem we can&#8217;t solve, upgrade, or re-invent with a wide skillset and a decent basic problem solving mentality. </h3>
<p>You want a guy like me on the mound when your competition is up to bat. Roger Clemens was good, but we can throw every pitch ever invented &#8211; and then some. </p>
<blockquote><h3>I&#8217;d rather be a resourceful and multi-faceted &#8220;hacker&#8221; (in the business sense, not the lame traditional way) than a one-trick-pony-expert any day.</h3>
</blockquote>
<p><i>(Yes, I&#8217;m being a bit of an ass, but you get the picture)</i></p>
<p><strong>Thoughts, Comments, Hate Mail, Burning Crosses on my Lawn?</strong></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hvaBUQ3GstA:KNurq8sUK_s:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hvaBUQ3GstA:KNurq8sUK_s:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=hvaBUQ3GstA:KNurq8sUK_s:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hvaBUQ3GstA:KNurq8sUK_s:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=hvaBUQ3GstA:KNurq8sUK_s:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hvaBUQ3GstA:KNurq8sUK_s:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/hvaBUQ3GstA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/featured-articles/it-battle-of-the-ages-specialization-vs-wide-open-solutions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://ryrobes.com/featured-articles/it-battle-of-the-ages-specialization-vs-wide-open-solutions/</feedburner:origLink></item>
		<item>
		<title>Get Clicky Android Widget = Awesomely Convenient</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/hYwKEa35Qgc/</link>
		<comments>http://ryrobes.com/random/get-clicky-android-widget-awesomely-convenient/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 08:28:29 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Featured Articles]]></category>
		<category><![CDATA[Random]]></category>
		<category><![CDATA[Widgets]]></category>
		<category><![CDATA[clicky]]></category>
		<category><![CDATA[droid]]></category>
		<category><![CDATA[getclicky]]></category>
		<category><![CDATA[mororola]]></category>
		<category><![CDATA[verizon]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=191</guid>
		<description><![CDATA[If you&#8217;re like me (exactly maybe, as scary as that might be) and have a Motorola Droid, and use Clicky for awesome and simple web analytics &#8211; you&#8217;ll want this. Its only 1 dollar &#8211; which is the same as a double cheeseburger at McDonalds (if you local vendors participate &#8211; since we all know [...]]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://ryrobes.com/wp-content/uploads/2009/12/android-widget.jpg" width="240" />
		</p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fryrobes.com%2Frandom%2Fget-clicky-android-widget-awesomely-convenient%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fryrobes.com%2Frandom%2Fget-clicky-android-widget-awesomely-convenient%2F&amp;source=ryrobes&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><img src="http://ryrobes.com/wp-content/uploads/2009/12/android-widget.jpg" alt="android-widget" title="android-widget" width="350" height="623" class="alignleft size-full wp-image-193" />If you&#8217;re like me <em>(exactly maybe, as scary as that might be)</em> and have a <strong>Motorola Droid</strong>, and use <a href="http://getclicky.com/111541">Clicky</a> for <a href="http://getclicky.com/111541">awesome and simple web analytics</a> &#8211; you&#8217;ll want this. </p>
<p>Its only 1 dollar &#8211; which is the same as a double cheeseburger at McDonalds <em>(if you local vendors participate &#8211; since we all know that &#8220;participation may vary&#8221;)</em> if you want to make a dollar-for-dollar comparison&#8230;</p>
<p><img src="http://ryrobes.com/wp-content/uploads/2009/12/qrcode-clickywidget.png" alt="qrcode-clickywidget" title="qrcode-clickywidget" width="186" height="186" class="alignright size-full wp-image-201" /><br />
<br/><br/><br/><br/><br/><br/><br/><br/><br/></p>
<p>It uses the Clicky API to grab the unique visitors and actions from a given site that you are monitoring on a hourly basis <em>(ie &#8211; it get refreshed hourly)</em>, and show the data as a daily, hourly, weekly and monthly aggregate count &#8211; plus an extra click takes you right to the Android-optimized Clicky Report page.. Who can argue with that?</p>
<div style="clear:both;"></div>
<p>Enjoy. <br/><br />
Original developers <a href="http://bit.ly/6zo5Nl">post is here</a>, he also runs <a href="http://phillyconcerthub.com/">http://phillyconcerthub.com/</a>. </p>
<p><br/>Check it out.<br />
<br/><em>BTW, that screenshot was very much reduced. The DPI of the Droid is so sexy that it looks absolutely massive on most 72 DPI computer monitors&#8230; Take that, iPhone kids. ;)</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hYwKEa35Qgc:El01RUA0Efk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hYwKEa35Qgc:El01RUA0Efk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=hYwKEa35Qgc:El01RUA0Efk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hYwKEa35Qgc:El01RUA0Efk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=hYwKEa35Qgc:El01RUA0Efk:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hYwKEa35Qgc:El01RUA0Efk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/hYwKEa35Qgc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/random/get-clicky-android-widget-awesomely-convenient/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://ryrobes.com/random/get-clicky-android-widget-awesomely-convenient/</feedburner:origLink></item>
		<item>
		<title>Using XLWT and Python to export an Oracle dataset to Excel (Python Simple ETL Part 2)</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/SsZ1xF2ogNA/</link>
		<comments>http://ryrobes.com/featured-articles/using-xlwt-and-python-to-export-an-oracle-dataset-to-excel-python-simple-etl-part-2/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 04:31:22 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[ETL]]></category>
		<category><![CDATA[Featured Articles]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Reporting]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[data transformation]]></category>
		<category><![CDATA[dts]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[excel export]]></category>
		<category><![CDATA[extract transform and load]]></category>
		<category><![CDATA[featured]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[overpriced dickheads]]></category>
		<category><![CDATA[pyExcelerator]]></category>
		<category><![CDATA[reporting services]]></category>
		<category><![CDATA[reports]]></category>
		<category><![CDATA[ryrobes]]></category>
		<category><![CDATA[xlwt]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=176</guid>
		<description><![CDATA[A few months ago, I showed how you can do simple back and forth ETL task with python scripts &#8211; this time I&#8217;m going to take it one step further and show how with an extra python module we can actually export data to a usable Excel format as well. I often use this method [...]]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="thumbs/gears2.jpg" width="240" />
		</p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fryrobes.com%2Ffeatured-articles%2Fusing-xlwt-and-python-to-export-an-oracle-dataset-to-excel-python-simple-etl-part-2%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fryrobes.com%2Ffeatured-articles%2Fusing-xlwt-and-python-to-export-an-oracle-dataset-to-excel-python-simple-etl-part-2%2F&amp;source=ryrobes&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p>A few months ago, I showed how you can do simple back and forth ETL task with python scripts &#8211; this time I&#8217;m going to take it one step further and show how with an extra python module we can actually export data to a usable Excel format as well. I often use this method for automated data extracts <strong>AS WELL AS doing full blown Excel reports</strong> <em>(yes, that&#8217;s right &#8211; with formula calculations, formatting and everything &#8211; its pretty sweet &#8211; that&#8217;ll come later though)</em>.</p>
<blockquote><p>I always say that &#8220;ease of use&#8221; and &#8220;flexibility&#8221; are at opposite ends of the spectrum &#8211; when one goes up, the other goes down. WYSIWYG applications have their place (I suppose), I prefer coding by hand in a text editor anyday.</p></blockquote>
<p>Anyways, today we&#8217;re going to make a simple Excel data export with pythons xlwt module <em>(which is a more updated fork of the old pyExcelerator module)</em>. I&#8217;ll try and comment well so you can cut-n-paste to your hearts content. As well all know, there&#8217;s nothing better than Googling for a solution and finding one that is 90% what you need and being able to just hack that last 10% in &#8211; saves time and sanity. Some purists would argue that its wrong&#8230; maybe, but there is a time and place for everything.</p>
<p>Anyways, here we go &#8211; as always, you can go step-by-step <em>(like the Full House theme song)</em> with me through the code, or skip to the bottom and just download the whole file. Its small, but at least this saves you from having to do a ton of Ctrl-C and Ctrl-V&#8230;</p>
<p>Ok, Lets get <em>(motherfuckin&#8217;)</em> steppin&#8217;&#8230; <em>(pardon me &#8211; its a live Metallica reference, can&#8217;t help it, I&#8217;m a product of the 80s and 90s whether I like it or not)</em></p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># 12/7/2009 - Ryan Robitaille [ryrobes.com]</span><br />
<span style="color: #808080; font-style: italic;"># http://ryrobes.com/featured-articles/using-xlwt-and-python-to-export-an-oracle-dataset-to-excel-python-simple-etl-part-2/</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">import</span> cx_Oracle, <span style="color: #dc143c;">time</span>, <span style="color: #dc143c;">string</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> xlwt <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span> &nbsp;<span style="color: #808080; font-style: italic;">#formerly &quot;pyExcelerator&quot;</span></div></div>
<p>Standard stuff &#8211; just loading some modules that we&#8217;re going to need. Time and String are part of the standard Python distriution <em>(I&#8217;m using 2.6 in this example)</em>, cx_Oracle I <a href="http://ryrobes.com/featured-articles/using-a-simple-python-script-for-end-to-end-data-transformation-and-etl-part-1/">already discussed HERE</a>, and xlwt can be found HERE (<a href="http://pypi.python.org/pypi/xlwt">http://pypi.python.org/pypi/xlwt</a>) grab the packages for your platform of choice and go nuts.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># set oracle login variables</span><br />
OraUid=<span style="color: #483d8b;">&quot;scott&quot;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#Oracle User &nbsp;</span><br />
OraPwd=<span style="color: #483d8b;">&quot;tiger&quot;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#Oracle password</span><br />
OraService=<span style="color: #483d8b;">&quot;TNS_EETFUK&quot;</span> &nbsp; &nbsp; &nbsp;<span style="color: #808080; font-style: italic;">#Oracle Service name From Tnsnames.ora file</span><br />
<br />
<span style="color: #808080; font-style: italic;"># do a timestamp for being able to track execution time (if you want)</span><br />
startscript = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># we will use this later</span><br />
&nbsp;<br />
db = cx_Oracle.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>OraUid + <span style="color: #483d8b;">&quot;/&quot;</span> + OraPwd + <span style="color: #483d8b;">&quot;@&quot;</span> + OraService<span style="color: black;">&#41;</span> &nbsp; &nbsp;<span style="color: #808080; font-style: italic;">#Connect to database</span><br />
dev_cursor_select = db.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#Allocate a cursor</span><br />
<br />
dev_cursor_select.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;&quot;&quot;SELECT DBMS_RANDOM.STRING('P',40) field1, <br />
&nbsp; &nbsp; &nbsp; &nbsp; DBMS_RANDOM.STRING('X',30) field2, ROUND(DBMS_RANDOM.VALUE(1000, 9999)) field3, <br />
&nbsp; &nbsp; &nbsp; &nbsp; DBMS_RANDOM.STRING('A',20) field4 &nbsp;FROM DUAL CONNECT BY LEVEL&lt;=3000&quot;&quot;&quot;</span><span style="color: black;">&#41;</span><br />
<span style="color: #808080; font-style: italic;"># 3,000 rows of random garbage seems good</span><br />
<br />
result_set = dev_cursor_select.<span style="color: black;">fetchall</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></div>
<p>There is a bit more going on here, but nothing really complex &#8211; setting up our Oracle connection, timestamping the START of the script, creating our Oracle cursor, defining our SQL query (just some random Oracle generated nonsense for the sake of this demo using the awesome and under-used &#8216;DBMS_RANDOM&#8217; functions), and getting that result set into a python object.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># Start some Excel magic</span><br />
wb = Workbook<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
ws0 = wb.<span style="color: black;">add_sheet</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'My New Worksheet'</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Grey background for the header row</span><br />
BkgPat = Pattern<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
BkgPat.<span style="color: black;">pattern</span> = Pattern.<span style="color: black;">SOLID_PATTERN</span><br />
BkgPat.<span style="color: black;">pattern_fore_colour</span> = <span style="color: #ff4500;">22</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Bold Fonts for the header row</span><br />
font = Font<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
font.<span style="color: black;">name</span> = <span style="color: #483d8b;">'Calibri'</span><br />
font.<span style="color: black;">bold</span> = <span style="color: #008000;">True</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Non-Bold fonts for the body</span><br />
font0 = Font<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
font0.<span style="color: black;">name</span> = <span style="color: #483d8b;">'Calibri'</span><br />
font0.<span style="color: black;">bold</span> = <span style="color: #008000;">False</span><br />
<br />
<span style="color: #808080; font-style: italic;"># style and write field labels</span><br />
style = XFStyle<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
style.<span style="color: black;">font</span> = font<br />
style.<span style="color: black;">pattern</span> = BkgPat<br />
<br />
style0 = XFStyle<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
style0.<span style="color: black;">font</span> = font0</div></div>
<p>Here we start some Excel formatting. Formatting is optional, but I figured that I&#8217;d throw in a little bit for some flavor. I can&#8217;t stand when older Excel uses that horrible &#8220;OCR A&#8221; font as the default. So what I&#8217;m doing is defining &#8220;styles&#8221; that can applied to each cell as we write data out to them. I&#8217;m using the same font throughout (in this case Calibri), but I&#8217;m making the header row bold and having a grey cell background. </p>
<p>Confused? Don&#8217;t worry &#8211; It will make a lot more sense in a moment.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">row_number=<span style="color: #ff4500;">1</span>&nbsp; &nbsp; <br />
<br />
<span style="color: #ff7700;font-weight:bold;">for</span> row <span style="color: #ff7700;font-weight:bold;">in</span> result_set:<br />
&nbsp; &nbsp; column_num=<span style="color: #ff4500;">0</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> item <span style="color: #ff7700;font-weight:bold;">in</span> row: <span style="color: #808080; font-style: italic;">#i.e. for each field in that row</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ws0.<span style="color: black;">write</span><span style="color: black;">&#40;</span>row_number,column_num,<span style="color: #008000;">str</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span>,style0<span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;">#write excel cell from the cursor at row 1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; column_num=column_num+<span style="color: #ff4500;">1</span> &nbsp;<span style="color: #808080; font-style: italic;">#increment the column to get the next field</span><br />
<br />
&nbsp; &nbsp; row_number=row_number+<span style="color: #ff4500;">1</span> <span style="color: #808080; font-style: italic;">#increment the row number so the next row goes below it...</span></div></div>
<p>Here we are looping through the result set. I&#8217;m starting the rows at &#8220;row 1&#8243;, which is actually row number 2 in Excel &#8211; we need the space in row number 1 in order to put our header row at. Otherwise we would start the output on row_number 0.</p>
<p>For each row in out result set, we have to write out all the fields in their individual columns. It sounds like a lot of work, but Python makes it easy. Just remember to increment your column numbers out and then reset them to 0 (aka literal column 1) when you start the next row. </p>
<p>If we wanted to get a little more tricky and &#8220;automatically&#8221; set the column width too. That takes a bit of finesse though, since not all field string lengths are created equally&#8230;</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">col_width_dict = <span style="color: #008000;">dict</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># create a dictionary var</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>: <span style="color: #808080; font-style: italic;"># fill it up with 0s first so Python doesn't complain</span><br />
&nbsp; &nbsp; col_width_dict<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span> = <span style="color: #ff4500;">0</span><br />
<br />
row_number=<span style="color: #ff4500;">1</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">for</span> row <span style="color: #ff7700;font-weight:bold;">in</span> result_set:<br />
&nbsp; &nbsp; column_num=<span style="color: #ff4500;">0</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> item <span style="color: #ff7700;font-weight:bold;">in</span> row:<br />
&nbsp; &nbsp; &nbsp; &nbsp; ws0.<span style="color: black;">write</span><span style="color: black;">&#40;</span>row_number,column_num,<span style="color: #008000;">str</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span>,style0<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># write the excel row from the cursor - starting at row 1 (literal row 2)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> col_width_dict<span style="color: black;">&#91;</span>column_num<span style="color: black;">&#93;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># only redefine the column width if we need it to be bigger</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; col_width_dict<span style="color: black;">&#91;</span>column_num<span style="color: black;">&#93;</span> = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ws0.<span style="color: black;">col</span><span style="color: black;">&#40;</span>column_num<span style="color: black;">&#41;</span>.<span style="color: black;">width</span> = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #ff4500;">256</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># set the width of the column depending on incoming string</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; column_num=column_num+<span style="color: #ff4500;">1</span><br />
<br />
&nbsp; &nbsp; row_number=row_number+<span style="color: #ff4500;">1</span></div></div>
<p>Still with me? Good. <em>(if not, let me know in the comments and I&#8217;ll try and clarify things more)</em>.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ws0.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">0</span>,<span style="color: #483d8b;">'Field 1'</span>,style<span style="color: black;">&#41;</span><br />
ws0.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">1</span>,<span style="color: #483d8b;">'Field 2'</span>,style<span style="color: black;">&#41;</span><br />
ws0.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">2</span>,<span style="color: #483d8b;">'Field 3'</span>,style<span style="color: black;">&#41;</span><br />
ws0.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">3</span>,<span style="color: #483d8b;">'Field 4'</span>,style<span style="color: black;">&#41;</span><br />
<br />
wb.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'sample_output.xls'</span><span style="color: black;">&#41;</span><br />
<br />
endscript = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
endtime = endscript - startscript<br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'script run in '</span> + <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>endscript - startscript<span style="color: black;">&#41;</span> + <span style="color: #483d8b;">' seconds or '</span> + <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>endscript - startscript<span style="color: black;">&#41;</span>/<span style="color: #ff4500;">60</span><span style="color: black;">&#41;</span> + <span style="color: #483d8b;">' minutes'</span></div></div>
<p>Here we are writing the header row (with our fancy &#8220;style&#8221; attribute), we are explicitly writing it on the first column (the one we skipped earlier when writing out the data).</p>
<p>Then we save our excel file as &#8216;sample_output.xls&#8217; or &#8216;angry_beavers.xls&#8217; or &#8216;chiminny_changa.xls&#8217;, whatever floats your boat. Just for shits and giggles, I&#8217;m taking the start timestamp and and the end timestamp and showing how long the script too to execute, but its pretty much useless in this case and olney serves to have some (not so) interesting output for me to look at.</p>
<p>Is anyone confused, angry, irate, excited? Let me know in the comments!</p>
<p>Here is the <a title="http://ryrobes.com/using-xlwt-and-python-to-export-to-excel.py" href="http://ryrobes.com/using-xlwt-and-python-to-export-to-excel.py">entire commented script file</a> for downloading. </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=SsZ1xF2ogNA:SVtMjY0PNtc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=SsZ1xF2ogNA:SVtMjY0PNtc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=SsZ1xF2ogNA:SVtMjY0PNtc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=SsZ1xF2ogNA:SVtMjY0PNtc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=SsZ1xF2ogNA:SVtMjY0PNtc:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=SsZ1xF2ogNA:SVtMjY0PNtc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/SsZ1xF2ogNA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/featured-articles/using-xlwt-and-python-to-export-an-oracle-dataset-to-excel-python-simple-etl-part-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://ryrobes.com/featured-articles/using-xlwt-and-python-to-export-an-oracle-dataset-to-excel-python-simple-etl-part-2/</feedburner:origLink></item>
		<item>
		<title>Cut-N-Paste Corner: Microsoft SQL Server 2000, 2005, 2008 Simple Loop Template</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/dz_ivccjey4/</link>
		<comments>http://ryrobes.com/geek/cut-n-paste-corner-microsoft-sql-server-2000-2005-2008-simple-loop-template/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 01:01:23 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[Microsoft SQL Server]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[cursors]]></category>
		<category><![CDATA[Data Warehousing]]></category>
		<category><![CDATA[dts]]></category>
		<category><![CDATA[ETL]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[rambling]]></category>
		<category><![CDATA[simple]]></category>
		<category><![CDATA[snippets]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=157</guid>
		<description><![CDATA[I think that &#8216;data wrangling&#8217; takes a special kind of problem solving mentality. Keeping data current, cleaning it, merging it, aggregating it, and creating summary (or data warehouse) tables for reporting purposes&#8230; For MANY years I used Express installations of SQL Server 2000 as my ultimate data Swiss Army knife. It was like a secret [...]]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="thumbs/sql_screen_image.jpg" width="240" />
		</p><div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fryrobes.com%2Fgeek%2Fcut-n-paste-corner-microsoft-sql-server-2000-2005-2008-simple-loop-template%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fryrobes.com%2Fgeek%2Fcut-n-paste-corner-microsoft-sql-server-2000-2005-2008-simple-loop-template%2F&amp;source=ryrobes&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p>I think that &#8216;data wrangling&#8217; takes a special kind of problem solving mentality. Keeping data current, cleaning it, merging it, aggregating it, and creating summary (or data warehouse) tables for reporting purposes&#8230; For MANY years I used Express installations of SQL Server 2000 as my ultimate data Swiss Army knife. It was like a secret weapon. You can crank out a couple of databases, make a DTS package, add some SQL flavor, ODBC connections to whatever you need &#8211; and viola &#8211; have a working and update-able consolidated data source in no time flat.</p>
<p>It never really mattered what kind of beast you were up against &#8211; Access, Paradox, Oracle, MySQL, Excel, delimited files, or just text files with shitty formatting. Say what you want about SQL Server 2000 and DTS &#8211; but it was hella flexible <em>(probably unmatched in ease and flexibility still to this day, IMHO)</em>.</p>
<p>Although I spend a good deal of time with Oracle these days &#8211; I have recently taken on some large migrations using SQL Server 2008, which pushed me to dig up my archaic library of SQL code I used to cut-n-paste back and forth in the 2000 days in order to get just-about-anythinhg done. I&#8217;m going to be posting some of the more useful and interesting ones</p>
<p>It may be simple, or it may be complicated &#8211; but when you&#8217;re searching for a hammer &#8211; the last thing you want is a bunch of meat tenderizers. Its damned close, but not exactly what you need. Today I&#8217;m posting a simple SQL Server cursor loop statement that you can add to your collection of templates.</p>
<blockquote><p><em><strong>Disclaimer:</strong></em> Now some of you might be asking: Isn&#8217;t this pretty elementary? Yes, but maybe not everyone reading this has your <strong>&#8220;l33t hax0r skillz&#8221;</strong>, ok there, Captain Ahab?</p></blockquote>
<p>Screw that noise. I&#8217;m all about creating specific solutions to specific problems &#8211; and nothing is more usable, extensible, and straight-up customizable than a simple T-SQL cursor loop. It doesn&#8217;t matter if youre updating rows on a separate table, doing a complicated INSERT INTO, doing some multi-variable lookups, or hell &#8211; maybe all of the above. Use your imagination. A good starting point prevents you from getting &#8220;code-blocked&#8221; and staring at a blank text editor or query screen as your jaws hangs open like a common mouth breather.</p>
<p>I write complicated ass SQL all day, and I open templates like this to modify all the time. I&#8217;ve got a whole library of them just for that purpose. I mean, c&#8217;mon lets get real, who actually sits down and writes stuff from scratch EVERY time? I&#8217;m all about the self-plagiarism, especially if it saves me time at the end of the day.</p>
<p>This example is supposed to be a simple as possible, while also being semi-plausible. Hypothetically, lets say you were building a summary table of all employees broken down by office, salary, department, etc. What we are doing is setting a True flag in a field on the summary table for the employee who has the highest salary for that particular office <em>(I know it sounds odd &#8211; but like I said, its hypothetical, this could just as easily be doing a top flag based on department, or number of sales, seniority, etc. &#8211; I just thought that using salary by office is an easily understood one)</em>.</p>
<p>Here is an explanation in English about what the example is doing &#8211; data-wise&#8230;</p>
<p>First, we grab all the individual Office Ids &#8211; then go one by one through each of the different offices ranking the employees by salary, taking the highest paid Employee ID and then updating that same tables &#8220;Top Salary in the Office&#8221; field for that particular employee.</p>
<div class="codecolorer-container sql vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:575px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">--Simple Cursor-based Loop for Microsoft SQL Server (2000+)</span><br />
<span style="color: #808080; font-style: italic;">--Ryan Robitaille (ryrobes.com) 12/1/2009</span><br />
<br />
<span style="color: #808080; font-style: italic;">--First define our return variable for the cursor and other misc vars</span><br />
DECLARE @top_paid_in_office_emp_id varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">15</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> @office_id varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">15</span><span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;">--here is the actual cursor select statement</span><br />
DECLARE all_offices_cursor CURSOR <span style="color: #993333; font-weight: bold;">FOR</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">DISTINCT</span> office_id <span style="color: #993333; font-weight: bold;">FROM</span> coded_offices<br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> office_id<br />
<br />
<span style="color: #808080; font-style: italic;">--open that beast so we can use it</span><br />
OPEN all_offices_cursor<br />
<br />
<span style="color: #808080; font-style: italic;">--start iterating through the cursor result set</span><br />
FETCH NEXT <span style="color: #993333; font-weight: bold;">FROM</span> all_offices_cursor<br />
<span style="color: #993333; font-weight: bold;">INTO</span> @office_id<br />
<br />
<span style="color: #808080; font-style: italic;">--only pull in rows that we havent seen yet, else stop</span><br />
WHILE @@FETCH_STATUS <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span><br />
BEGIN<br />
<br />
<span style="color: #808080; font-style: italic;">--start actual looping statement using our cursor variables</span><br />
<span style="color: #993333; font-weight: bold;">SET</span> @top_paid_in_office_emp_id <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> top <span style="color: #cc66cc;">1</span> employee_id<br />
<span style="color: #993333; font-weight: bold;">FROM</span> office_roster_summary<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> office_id <span style="color: #66cc66;">=</span> @office_id<br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> salary <span style="color: #993333; font-weight: bold;">DESC</span><span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #993333; font-weight: bold;">UPDATE</span> office_roster_summary <span style="color: #993333; font-weight: bold;">SET</span> top_paid_flag <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'T'</span><br />
<span style="color: #993333; font-weight: bold;">WHERE</span> employee_id <span style="color: #66cc66;">=</span> @top_paid_in_office_emp_id<br />
<span style="color: #993333; font-weight: bold;">AND</span> office_id <span style="color: #66cc66;">=</span> @office_id<br />
<span style="color: #808080; font-style: italic;">--end looping statement</span><br />
<br />
FETCH NEXT <span style="color: #993333; font-weight: bold;">FROM</span> all_offices_cursor<br />
<span style="color: #993333; font-weight: bold;">INTO</span> @office_id<br />
<span style="color: #808080; font-style: italic;">--grab the next var(s) from the cursor and repeat, baby!</span><br />
END<br />
<br />
CLOSE all_offices_cursor<br />
DEALLOCATE all_offices_cursor<br />
<br />
<span style="color: #808080; font-style: italic;">--Close the cursor, and deallocate it for good housekeeping sake...</span><br />
<span style="color: #808080; font-style: italic;">--Booya</span></div></div>
<p>Depending on your data &#8211; when building a summary table (or Data Warehouse Fact table, or Analysis Services Cube for that matter) these types of &#8220;flag&#8221; fields often make reporting on such items much easier.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=dz_ivccjey4:DMu01i03h80:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=dz_ivccjey4:DMu01i03h80:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=dz_ivccjey4:DMu01i03h80:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=dz_ivccjey4:DMu01i03h80:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=dz_ivccjey4:DMu01i03h80:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=dz_ivccjey4:DMu01i03h80:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/dz_ivccjey4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/geek/cut-n-paste-corner-microsoft-sql-server-2000-2005-2008-simple-loop-template/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ryrobes.com/geek/cut-n-paste-corner-microsoft-sql-server-2000-2005-2008-simple-loop-template/</feedburner:origLink></item>
	</channel>
</rss>
