tag:blogger.com,1999:blog-189662332009-03-05T08:26:35.625-08:00IT Groundhogwoodworking, home life, software development, quality assurance,and occasionally nibbling at the roots of information technology...aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.comBlogger51125tag:blogger.com,1999:blog-18966233.post-21272201012995888482008-07-02T08:54:00.000-07:002008-07-02T09:06:14.711-07:00On linuxA friend recently forwarded me<a href="http://artlung.com/smorgasborg/C_R_Y_P_T_O_N_O_M_I_C_O_N.shtml"> Neil Stephenson's essay "In the beginning was the command line"</a>. It includes, among other things, an amusing comparison of operating systems as if they were car dealerships. MS windows OS=station wagons, mac is a nice sleek eurosedan, and BeOS - it's an old essay - is a Batmobile. Linux is...well, see below.<br /><br />I read this years ago and found it vastly entertaining. I even printed it out and had it in the bathroom for "quality time" reading. It was well worded. Persuasive. And I believed it. (well, mostly)<br /><br />Re-reading it this time, with the jaded eye of a few more years of pain..err, experience, I particularly like this bit:<br /><br /><i>With one exception, that is: Linux, which is right next door, and which is not a business at all. It's a bunch of RVs, yurts, tepees, and geodesic domes set up in a field and organized by consensus. The people who live there are making tanks. These are not old-fashioned, cast-iron Soviet tanks; these are more like the M1 tanks of the U.S. Army, made of space-age materials and jammed with sophisticated technology from one end to the other. But they are better than Army tanks. They've been modified in such a way that they never, ever break down, are light and maneuverable enough to use on ordinary streets, and use no more fuel than a subcompact car. These tanks are being cranked out, on the spot, at a terrific pace, and a vast number of them are lined up along the edge of the road with keys in the ignition. Anyone who wants can simply climb into one and drive it away for free.</i><br /><br />HA! In a word (or four) I beg to differ.<br /><br />Just like the M1 abrams, linux requires a dedicated team of specialized technicians to change a bloody tire. The literature states that they never, ever break down but in reality they do. (however, given that they're usually run by said highly trained technicians this troubleshooting is not seen as a drawback, but part of the fun of driving the beast!)<br /><br />You can drive them on most roads, but you do need a drivers manual at hand at all times, and it contains such cryptic instructions as "if the street is composed of < 64% composite asphalt mix with a 3/4 minus gravel substrate at a 3' depth you will incur a 20% damage likelyhood to the road as well as wear the ball joints prematurely. Recommended procedure is to install track upgrade 3.41, but make sure you're running wheel guidance rods 2.11 (the titanium coated pre-graphite charged ones) else you'll completely burn up the gearbox and the treads will fall off and the tank will blow up."<br /><br />The keys are in the ignition...if you can find the frickin' ignition. The control panel is covered in lights and switches that let you control every last bit of the innards of the beast and keep you informed of the relative humidity of the thermo-coupled rheostat junction...which is located right next to the speedometer. But instead of reporting speed, it has the rpm of each individual crankshaft and you're expected to extrapolate that (on the fly, in your head) to actual speed since you might be running the .301 diameter driver wheels or the .278 driver wheels...<br /><br />Put your grandma in one of those and ask her to drive to church. What do you get? Smashed roads. Fire hydrants knocked off. Terrified pedestrians. And one ticked off granny.<br /><br />(and %diety% help you if she found the main bore's autoloading mechanism and accidentally let loose a few sabot rounds...)<br /><br />Don't get me wrong. I like the M1. It totally rocks. It's an unparalleled piece of modern weaponry. In it's context it totally rocks. <br /><br />I like linux. It is absolutely appropriate for certian kinds of folks, in certain kinds of situations.<br /><br />But use one as my daily driver...you know, when I just want to be able to drive on the local interstate and get to work? Maybe if I was a complete military nut, owned my own UNIMOG and restored tanks for fun. But otherwise, no.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-2127220101299588848?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-41357552269348132692008-05-19T09:10:00.000-07:002008-05-19T09:32:14.360-07:00The real difference between mac and PCSo my parents were down for the weekend. And Ruth, my oh-so-awesomely-technical stepmom brought her new macbook.<br /><br />It was (is) a thing of beauty.<br /><br />It's been a good 10 years since I've regularly used macs. Yet they're still consistently touted as "better" than PC's. Easier to use. Of course, the mac faithful take that to a bit of an extreme but still.<br /><br />As I used her OS 10.5 (?) Leopard system, I was struck by just how...organic...the whole experience was. 1001 things, all of them subtle.<br /><br />A few examples...when you "minimize" in the system, the page kinda-sorta squishes into a "down the drain" shape and slurps down to the mac-equivilent-of-a-taskbar. But it's not linear...it speeds up through the process. Slower as it starts, and then faster as it slips down the drain. Subtle. Very, very subtle.<br /><br />I launched Front Row and dinked around with it, showing "Nana Ruth" (that's what my kids call her) how to navigate. And I marvelled at how the highlight moved from button to button. It didn't blink off one, and onto another. It somehow slid ~ again, in a nonlinear fashion ~ from one to the next. Not "ok now I'm still...now moving...now still." It started slow, then sped up, then slowed down.<br /><br />Again, supremely subtle. I seriously doubt any casual user would have noticed. And this is A Good Thing. They're not supposed to notice. They're just supposed to feel, at some subconscious level, that the mac just "fits" better. Is smoother. "Feel", "fits", "smooth"...all these are subjective, squishy, difficult to measure qualities.<br /><br />I've also been tweaking my father-in-law's new Dell quad-core for the last 2 weeks. It's running Vista Home Premium. This has been my first real extended use of Vista and while it's taken some getting used to, overall it's nice. The system is certainly fast enough. And it "does" all the same things.<br /><br />But it's not a Mac. I could be objective and comment on where Redmond decided to use transparency. How Media Center's selection works just fine. But in the end it just doesn't "flow" as well.<br /><br />Is the mac more stable? No. Is it "more" secure? Not likely. Does it "feel better"? <br /><br />Hell yeah.<br /><br />I have a few theories as to why. All of them paint with a pretty broad stroke. So I'll leave that for another post.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-4135755226934813269?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-65614573566707652642008-03-08T15:55:00.000-08:002008-03-10T12:22:56.061-07:00Regex presentation from Boise Code Camp 2008Thank you all those that showed up for code camp 2008. 370 folks at last count. It warmed the cockles of our collective hearts to have so many geeks wandering, learning, and eating pizza.<br /><br />As promised, here are links to the <a href="http://www.aaronbacker.net/RegexDemo1.zip">code </a>and the <a href="http://www.aaronbacker.net/Regex101_ppt.zip">powerpoint </a>from the session. Enjoy!<br /><br />Here are the tools/tutorial I referenced during the talk:<br />RegexDesigner.NET<br /><a href="http://www.sellsbrothers.com/tools/">http://www.sellsbrothers.com/tools/</a><br /><br />30 Min Regex Tutorial:<br /><a href="http://www.codeproject.com/KB/dotnet/regextutorial.aspx">http://www.codeproject.com/KB/dotnet/regextutorial.aspx</a><br /><br />Cheers!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-6561457356670765264?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-10370410416056302282008-02-21T20:20:00.000-08:002008-02-21T20:35:42.303-08:00Boise Code Camp 2008<a href="http://www.boisecodecamp.org/">Boise Code Camp 2008</a> is happening this coming Saturday, March 8th. Visit the site. Sign up.<br /><br />Why should you come?<br /><br /><ul><li>It's free</li><li>beginner & advanced asp, .net stuff</li><li>free pizza</li><li>NJM*: There are presentations on ruby, java, oracle</li><li>Currently 57 presentations (as of tonight's tally @ <a href="http://www.netdug.com/">netdug</a>)<br /></li><li>they feed us</li><li>"just for fun" tracks like hardware hacking</li><li>great swag</li><li>demos on tools that'll make you faster, better, more likely to get dates.**<br /></li><li>Rub shoulders with other like-minded geeks in the Treasure Valley (and beyond)</li><li>Awesome value</li><li>Some dude named <a href="http://www.hanselman.com/blog/">Hanselman </a>will be presenting too<br /></li><li>They're feeding us</li></ul>*Not Just Microsoft<br />**Ok, I stretched on that last bit.<br /><br />And yes, I am doing a session on "intro to regular expressions". But don't come for me.<br /><br />Then again, if it'll get you there, come for me!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-1037041041605630228?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-79657681642287143652007-12-14T09:00:00.000-08:002007-12-14T09:57:21.202-08:00Undo...undo d##n you!There are times when I just have to laugh at myself.<br /><br />(insert obligatory self deprecating comment about that being most of the time)<br /><br />But seriously.<br /><br />I'm sketching out (on paper. in pencil.) the data access layer for a project. Trying to figure out all the access methods I'll need.<br /><br />I erase one to better fit another in.<br /><br />I suddenly realize that I completely forgot what I'd just erased. <br /><br />And it's erased thoroughly...<br /><br />The first thing to run through my mind was the completely sincere thought: "Not a problem. I'll just undo.."<br /><br />(ok. it was funny to me)<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-7965768164228714365?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-83494008790345489192007-12-07T09:47:00.000-08:002007-12-28T09:43:11.137-08:00Internal notebook ATA100 vs USB2 vs eSATAHoly hot hannah, batman.<br /><br />I requested an external drive for my poor-little 1.6ghz pentium m notebook. (Dell Latitude D610 w/2gigs of RAM)<br /><br />The internal drive (upgraded from a 4200rpm 30gig model to a 120gig 5400rpm 8mb cache seagate) was still slow. And when I tried to run a vm onboard...look out. Empires rose and crumbled to dust in the time it took to boot 'em. Everything else slowed to a crawl as the host OS and VM duked it out for access to the drive.<br /><br />So I wanted an external drive. Well, for virtual machines as well as local backup.<br /><br />At first I thought a nice, simple (big honkin) usb2. Then I thought "hmm...wonder how much faster an external SATA (eSATA) drive would be?)<br /><br />After a bit of research, I selected the following. (all hail newegg!)<br /><a href="http://www.newegg.com/product/product.asp?item=N82E16817145167">VANTEC NST-360SU-BK 3.5" eSATA + USB2.0 Enclosure</a><br /><a href="http://www.newegg.com/product/product.asp?item=N82E16822148136"> Seagate Barracuda 7200.10 (500GB 7200 RPM 16MB Cache SATA Hard Drive</a><br /><a href="http://www.newegg.com/product/product.asp?item=N82E16839113007">VANTEC UGT-ST350CB SATA PCMCIA Card</a><br /><br />Everything went together like a charm. On a whim, I decided to run <a href="http://www.simplisoftware.com/Public/index.php?request=main">Simpli Software's</a> awesome <a href="http://www.simplisoftware.com/Public/index.php?request=HdTach">HDTach </a>against my internal drive, the external drive using it's eSATA connection, and the external drive using it's USB2 option.<br /><br />Note the cpu utilization differences (as well as the fact that the eSATA option is faster than the internal...guess that PCMCIA bus can move some data..!)<br /><br />Internal drive (<a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16822148222&Tpk=ST9120821A">Seagate ST9120821A</a> - ATA100, 120gig, 5400rpm, 8mb cache):<br />Average read speed: 31.4MB/sec<br />CPU Utilization: 5%<br /><br />External Drive, (7200rpm, 16mb cache) using usb2 (onboard)<br />Average read speed: 27.3MB/sec<br />CPU Utilization: 29%<br /><br />External Drive, (7200rpm, 16mb cache) using eSATA interface<br />Average read speed: 56.2MB/sec<br />CPU Utilization: 0%<br /><br /><br />HDTach results:<br /><br />The notebook's internal drive:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_giL3BvszLnY/R1mMY8hji5I/AAAAAAAABkw/iqQ02yNM4Ug/s1600-h/drivespeed_internal.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_giL3BvszLnY/R1mMY8hji5I/AAAAAAAABkw/iqQ02yNM4Ug/s400/drivespeed_internal.jpg" alt="" id="BLOGGER_PHOTO_ID_5141294809811749778" border="0" /></a><br /><br /><br />The external drive, USB2:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_giL3BvszLnY/R1mMrchji6I/AAAAAAAABk4/TA1LbNC1eZg/s1600-h/drivespeed_USB2.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_giL3BvszLnY/R1mMrchji6I/AAAAAAAABk4/TA1LbNC1eZg/s400/drivespeed_USB2.jpg" alt="" id="BLOGGER_PHOTO_ID_5141295127639329698" border="0" /></a><br /><br /><br />The external drive, eSATA<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_giL3BvszLnY/R1mNM8hji8I/AAAAAAAABlE/zPx-3o7G-Fs/s1600-h/drivespeed_eSATA.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_giL3BvszLnY/R1mNM8hji8I/AAAAAAAABlE/zPx-3o7G-Fs/s400/drivespeed_eSATA.jpg" alt="" id="BLOGGER_PHOTO_ID_5141295703164947394" border="0" /></a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-8349400879034548919?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com2tag:blogger.com,1999:blog-18966233.post-8910895902539945752007-11-15T08:53:00.000-08:002007-11-16T07:46:34.026-08:00Doing the proxy picking pickle polkaHas this ever happened to you?<br /><br /><strong>Minute 0:</strong> Take your corporate laptop home (to, you know, do some MORE work…) connect to your home broadband, launch IE (or firefox) and…awww crud.<br /><br /><strong>Minute 1:</strong> Tools-Options-Advanced-Network-No !$@#$!# Proxy-ok-ok.Or (for IE) Tools-Internet Options-Connections-Lan Settings(That’s six clicks (best case) for Firefox and seven for IE.)<br /><br /><strong>Minute 5:</strong> Whoops. Need to get into email. Launch the corporate VPN.<br /><br /><strong>Minute 7:</strong> Get back into Firefox.<br /><br /><strong>Minute 7.1:</strong> WTH?! Ahh. that’s right. Need to turn the !!W$!W# proxy back ON. (six more clicks)<br /><br /><strong>Minute 15:</strong> Hmm...need that file on the wife’s computer. Whoops...can’t get to it because we’re CONNECTED TO THE CORPORATE VPN!<br /><br /><strong>Minute 17:</strong> Disconnect from the vpn.<br /><br /><strong>Minute 18:</strong> Copy the file.<span style="font-weight: bold;"><br /><br /></span><strong>Minute 19:</strong> Go back to the knowledge base article on the browser..aw crap. Proxy back off. (six more clicks)<br /><br />(queue inspirational music)<br /><br />There is a better way!<br /><br />(no, it’s not [auto detect settings] as that spins and spins and takes a good long time to decide if there’s a proxy or not.)<br />(waaaaay too slow)<br />(At least for me.)<br />(because I’m impatient)<br /><br /><span style="font-size:180%;">For IE:</span> <a href="http://www.bayden.com/ietoys/proxypick.asp">ProxyPick</a><br /><br />Follow the link. Grab the exe. Install it.<br />After install:<br /><br />Click #1:<br /><a href="http://4.bp.blogspot.com/_giL3BvszLnY/Rzx7ETjYTwI/AAAAAAAABkA/3xwh6djp8xE/s1600-h/proxypick1.bmp"><img id="BLOGGER_PHOTO_ID_5133112989193883394" style="margin: 0px auto 10px; display: block; text-align: center;" alt="" src="http://4.bp.blogspot.com/_giL3BvszLnY/Rzx7ETjYTwI/AAAAAAAABkA/3xwh6djp8xE/s320/proxypick1.bmp" border="0" /></a><br /><br />Click Two and Three<br /><a href="http://3.bp.blogspot.com/_giL3BvszLnY/Rzx7ODjYTxI/AAAAAAAABkI/FgxHREt5KvM/s1600-h/proxypick2.bmp"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_giL3BvszLnY/Rzx7ODjYTxI/AAAAAAAABkI/FgxHREt5KvM/s320/proxypick2.bmp" alt="" id="BLOGGER_PHOTO_ID_5133113156697607954" border="0" /></a><br /><br />That's all it takes. Three quick clicks, about 1/10th the mouse travel. (no, I didn't measure it. <a href="http://www.modometer.com/">But I could.</a> If, you know, I was that retentive. Come to think of it...)<br /><br /><br /><span style="font-size:180%;">Firefox </span>is (naturally) EVEN EASIER.<br /><br /><a href="https://addons.mozilla.org/en-US/firefox/addon/1557">Quickproxy </a>has your number…<br /><br />It adds a little button to the status bar (down there in the bottom right hand corner)<br /><a href="http://3.bp.blogspot.com/_giL3BvszLnY/Rzx7UDjYTyI/AAAAAAAABkQ/IGKI4VWFD-Y/s1600-h/proxypick3.bmp"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_giL3BvszLnY/Rzx7UDjYTyI/AAAAAAAABkQ/IGKI4VWFD-Y/s320/proxypick3.bmp" alt="" id="BLOGGER_PHOTO_ID_5133113259776823074" border="0" /></a><br />One click toggles between proxy on and proxy off.<br /><br />Enjoy!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-891089590253994575?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com1tag:blogger.com,1999:blog-18966233.post-12606087855605186042007-11-06T14:55:00.000-08:002007-11-06T15:40:30.189-08:00Of pivot tables, named ranges and excel tantrumsI love excel. Really I do.<br /><br />And I love pivot tables.<br /><br />But what I don't love is that !%$!@#$!$@#!@#$ "Can't group by that selection. (nyah nyah nyah!)" dialogue box.<br /><br />It most often pops up when I want to group by a date range. You know - aggregate by months or days or somesuch.<br /><br />The good thing is that there is a way around it.<br /><br />The bad thing is that I do it so infrequently that I'm constantly forgetting how. And, for some reason, 99.99% of the google results are poorly formatted tutorials that have so many ads intersperced, ya can't read the !$#!$#!@#$ advice.<br /><br /><br />Today I got sick of it. So now, for Your Reading Pleasure (and my forever future reference) I present:<br /><br />"The Almost Totally (in)Complete Guide to Getting Past the Can't Group By Pivot table error dialogue in Excel 2003"<br />"At least for grouping dates."<br /><br />Step 1:<br />Make sure you ain't selecting blank lines.<br /><br />I know, I know. If you've "Imported" your excel data, it's soooo much easier to select the columns when you're creating your pivot table.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_giL3BvszLnY/RzDzWygS3TI/AAAAAAAABZc/8SUyayPSNsE/s1600-h/wizard.PNG"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://4.bp.blogspot.com/_giL3BvszLnY/RzDzWygS3TI/AAAAAAAABZc/8SUyayPSNsE/s320/wizard.PNG" alt="" id="BLOGGER_PHOTO_ID_5129867548414893362" border="0" /></a>This is a Bad Thing.<br /><br />Why? Because when you create the pivot table you won't be able to group by ANY FIELD!!<br /><br />That's right. For some reason yet unknown to man (but probably obvious to those smarties who regularly develop in multi-dimensional database technology) if a field has blank rows, Excel's pivot table engine barfs.<br /><br />So...how do we make sure we're not getting blanks?<br /><br />We can do this one of two ways, either select the explicit range of cells (ie, A1:F23135) OR use a named range.<br /><br />If this is a one-off, I'd use the range of cells. If this is a table that's going to be updated semi-regularly, I'd suggest using a named range as the source for the pivot table.<br /><br />The super-niftyness of a named range is simply, you can use a formula to determine how big you want it to be. (ok, ok, I think technically it's a "dynamic named range"...)<br /><br />To wit, assuming you're a normal human being and your data (or, more properly, it's header) starts at cell A1 of a given sheet, here's how you create a named range that only allows non-blank rows:<br /><br />1) From the Insert menu, choose Name=>Define<br /><br />2) You'll get something like this. Well, kinda like this. (you won't have any ranges named yet)<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_giL3BvszLnY/RzD4uygS3VI/AAAAAAAABZs/-a7DZ_b14nY/s1600-h/definenamerange.PNG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_giL3BvszLnY/RzD4uygS3VI/AAAAAAAABZs/-a7DZ_b14nY/s320/definenamerange.PNG" alt="" id="BLOGGER_PHOTO_ID_5129873458289892690" border="0" /></a><br /><br />3) In the <span style="font-weight: bold;">Names in workbook</span>: section, name your range.<br /><br />(Get it? You give your range a name so now it's a named ra...nevermind.)<br /><br />Ok, got the name? Good. Now, in the "refers to:" section, type the following:<br /><br /><br /><span style="color: rgb(255, 0, 0);">*********</span><span style="color: rgb(255, 0, 0);">CautionCautionCautionCaution</span><span style="color: rgb(255, 0, 0);">*********</span><span style="color: rgb(255, 0, 0);"></span><span style="color: rgb(255, 0, 0);"></span><br /><br />Weird stuff happens in this particular dialogue box. <br /><br />Arrows don't work...quite...right.<br /><br />Yes, arrows. You know, those plebeian controls you use to back up when you type "shetname" and correct it<br /><br />If you use them, whatever the active cell is on the worksheet, it's address gets put in the box.<br /><br />So use the mouse and the delete keys...but watch out for them arrows. <br /><br />You have been warned.<br /><br /><span style="color: rgb(255, 0, 0);">*********</span><span style="color: rgb(255, 0, 0);"></span><span style="color: rgb(255, 0, 0);"></span><span style="color: rgb(255, 0, 0);">/endCaution</span><span style="color: rgb(255, 0, 0);">*********</span><span style="color: rgb(255, 0, 0);"></span><br /><br /><br />(resuming where we left off...)<br /><br /><span style="font-style: italic;">in the "refers to:" section, type the following:</span><br /><br />=OFFSET<span style="font-weight: bold;">(</span><span style="color: rgb(51, 102, 255); font-weight: bold;">sheetname</span>!<span style="color: rgb(255, 0, 0); font-weight: bold;">$A$1</span>,<span style="color: rgb(51, 204, 0); font-weight: bold;">0,0</span>,<span style="font-weight: bold; color: rgb(204, 51, 204);">COUNTA(sheetname!$A$A)</span>,<span style="font-weight: bold; color: rgb(51, 0, 153);">14</span>)<br /><br /><ul><li><span style="color: rgb(51, 102, 255); font-weight: bold;">sheetname </span>= the name of the worksheet your data is on</li><li><span style="color: rgb(255, 0, 0);"><span style="font-weight: bold;">$A$1</span> </span>= the first cell in your range (think, top left corner)</li><li><span style="color: rgb(0, 153, 0); font-weight: bold;">0,0</span> = the horizontal and vertical offset you want from this cell.</li><li>(So if you put in 5, 8...we'd actually start the range 5 cells to the right and 8 cells below A1. Funky. I know.) No human has ever actually had a use for this bit, but if I hear of anything I'll let you know.</li><li><span style="color: rgb(204, 51, 204); font-weight: bold;">COUNTA(sheetname!$A$A)</span> = This could be a static number (it actually refers to the number of rows we want) but we're using a formula. Counta returns a count of the nonblank rows in a range...so this essentially says "look at column A and give me a count of how many rows are non-blank for this cell"<br /></li><ul><li>The more astute of you have caught the assumption...what if a few rows don't have a value for a? Will they be included? Maybe. Remember...this returns a "count", so if you have 10 rows and 2 of them don't have a value in the A column, you'll only get the first 8 rows. Bummer. So best tag a column that's always populated.</li></ul><li>Where was I? Oh yeah. The last item <span style="font-weight: bold; color: rgb(51, 0, 153);">14</span>. This is the number of columns you want included in the range. This can also be made dynamic, but in this case I know how many columns. (so there)</li></ul>4) Now click the Add button.<br /><br />That's all there is to it.<br /><br />Now, when you're defining your hypothetical pivot table, when they ask you to define the range, just type the name of the...err...named range you created above and "POOF". (literally - "your spreadsheet will be, like, smokin dude!")<br /><br /><br />What is that you say? What if your data contains rows that SOME are blank and some are not? How do you deal with grouping incomplete data?<br /><br />Yes, it's possible. Maybe I'll write that one up tomorrow. Until then, cheerio!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-1260608785560518604?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com12tag:blogger.com,1999:blog-18966233.post-74381617942015939672007-10-30T15:49:00.000-07:002007-10-30T15:59:40.249-07:00There is never a substitute for a full system backup...What did I learn today? There's <span style="font-weight: bold;">always </span>something you miss when rebuilding a system....<br /><br />After about a year, my corp issued laptop was dog slow. Though I'm sure a large part of it was the <a href="http://www.codinghorror.com/blog/archives/000803.html">anti-virus performance vampire</a>, (we use Mcafee Enterprise) the system was due for a rebuild.<br /><br />I've done this a few times. In the past I've usually either done a straight filesystem dump or (if I'm feeling paranoid) imaged the system with something like Ghost before starting over.<br /><br />This time I didn't. I was backing up across a 100mbit network link with limited space on the destination, and so tried to pick and choose. And, of course, I missed something.<br /><br />Mydocs? Check.<br />Everything checked into subversion (so I don't have to copy the working copy)? check.<br />desktop junk culled and saved? Yup.<br />Itunes? Pod synced up.<br />Download directory? copied.<br />Bookmarks? Heh...I use <a href="http://www.google.com/tools/firefox/browsersync/">google's browser sync for firefox</a>...so all my bookmarks are backed up and synced between all my machines, all the time.<br />Putty settings? Had to remember <a href="http://www.downloadsquad.com/2007/02/01/howto-transfer-your-putty-settings-between-computers/">where it stores them</a> (super-secret registry location), but check.<br />Winscp settings...winscp settings?!! Awww...crud.<br /><br />Ah well. If I had to pick something to miss, that'd probably have been it.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-7438161794201593967?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-26451395523372412772007-10-30T09:00:00.000-07:002007-10-30T10:05:08.684-07:00Perfectionism:1, Aaron:0Ok, so I wanted to fire off an entry every day for 10 days.<br /><br />Didn't make it.<br /><br />Crud.<br /><br />So we try again.<br /><br />I think it had something to do with the fact that my designated timeframe was a whopping 15 minutes (yes, I really am that naive sometimes) at the end of the day. Logically, it made sense because I'd be able to reflect on what I'd learned for the day. Practically, it meant that either my brain was fried or I was in a groove and didn't want to get out.<br /><br />Well, that or I'd start on a post (I have one half completed) that'd go on. And on. And on. And I'd realize that for it to be a high quality post I'd have to put more time into researching my wild generalizations and casual proclamations.<br /><br />Hmm.<br /><br />Maybe a shorter, more doable goal. Instead of subtly thinking I'm going to deliver a highly polished .net 2.0 tutorial on whatever-the-heck-I-found-out that day, perhaps just two paragraphs. Just...two.<br /><br />And if I only do one, so be it.<br /><br />So what have I learned the last week?<br /><br />Storing hierarchical data in a sql database isn't straightforward. I started off with what's called <a href="http://dev.mysql.com/tech-resources/articles/hierarchical-data.html">an "adjacency list" model</a>. (I found that out when it blew up) That's essentially where each row of the relationship table stores the childID and the parentID (and the child name, in my case).<br /><br />There is an <a href="http://www.evolt.org/article/Four_ways_to_work_with_hierarchical_data/17/4047/index.html">extremely elegant way to parse</a> this. Unfortunately, it's recursive. With ~ 100 rows it returned lickety split. With about 500 rows it ran the sql server's (unlimited) connection pool out of connections.<br /><br />Ow.<br /><br />Err. <br /><br />Yeah. <br /><br />So back to the drawing board. There's one called "modified tree order traversal". After drawing it out on paper, I think I got my head around it. But it's a little bit more work (?!!) when inserting and deleting nodes. <br /><br />Not sure what to do at this point. I want a quick and easy solution (don't we all!) I'm not dealing with millions of rows of data (more like about 3-4000). So I think I'll need to do some more thinking.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-2645139552337241277?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-33356548841226805372007-10-17T14:34:00.000-07:002007-10-17T14:48:34.885-07:00From the "I can't believe I did that" dept....net is a wonderful thing.<br /><br />The Visual Studio 2005 IDE is a wonderful thing.<br /><br />All those easily settable properties, intellisense...all are (repeat after me) Very Good Things.<br /><br />Of course, they still don't always save the occasional bonehead miss.<br /><br />So I've been trying to get (for a day and a half) a footer to display in an asp.net gridview.<br /><br />You know the drill...gridviews don't allow you to create (insert) records by default. Given that this is a pretty common theme, there are <a href="http://www.google.com/search?q=insert+record+from+gridview&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a">quite a few</a> <a href="http://www.asp.net/learn/data-access/tutorial-53-cs.aspx">tutorials </a>out there on how to do it.<br /><br />Ok, now get this. In the app I'm working on? I already had done this for a different gridview. (a week or two ago.) Worked great.<br /><br />Followed the same steps. Compile. Run.<br /><br />No footer.<br /><br />Records show up. Paging numbers. All that good stuff.<br /><br />No footer.<br /><br />Hmm...maybe I need to change ALL the columns to template fields.<br /><br />Nope.<br /><br />Umm...put in a text field bound to the identity and make it hidden?<br /><br />Uh-uh.<br /><br />Oh yeah...I need to embed a formview in the footer, bind it to the same data source and...uh...<br /><br />No.<br /><br />Crap. What the confounded tarnation of all that is good and ... oh. Wait.<br /><br />Maybe you just need to set the "showfooter" property of the gridview to "true".<br /><br />Yeah. That'll do it.<br /><br />[blushes furiously]<br /><br />On the plus side, the odds of me EVER repeating this mistake (and the attendant pounding of the head on formica) is now pretty minuscule. Pain. It's a wonderful teacher.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-3335654884122680537?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-54557809691722695002007-10-12T14:40:00.001-07:002007-10-12T15:20:24.525-07:00Pivot tableness is next to godlinessToday was a metrics day. A couple of years ago I did a bunch of work pulling data from our OpenView service desk application at the request of my hiring manager. (the schema - or lack thereof - would have been enough to scare me off otherwise)<br /><br />Anyway. I managed to puzzle out a rough idea of what I was after using a data dictionary and after much weeping, wailing, and gnashing of teeth pulled some very unique data. (unique as in "they couldn't get it anywhere else", not as in "hmm..that's a...unique...data set. No relation to reality but definately unique.")<br /><br />I've done a few small commando jobs for my current manager. So back into the fray I go. Fortunately, past experience and a hefty library of already-configured DTS jobs (to pull from the oracle back end) made it the work of only one day.<br /><br />Pop the saved data out to a .csv. Load up excel. Create the pivot table.<br /><br />Curse at the few odd lines that don't have valid dates and therefore muck with the grouping functionality.<br /><br />Fix the description fields that have embedded carriage returns and therefore totally muck up the text export.<br /><br />**the following perlscript snippit from the DTS transform does a marvelous job fixing the above issue, by the way:<br /><br />Original line (referencing the field in question with the embedded returns)<br /> $DTSDestination->Item("SER_DESCRIPTION")->{Value} = $DTSSource->Item("SER_DESCRIPTION")->Value;<br /><br />Modified perl transformation script line:<br /> $temp = $DTSSource->Item("SER_DESCRIPTION")->Value;<br /> $temp =~ s/\n//g;<br /> $temp =~ s/\r//g;<br /> $DTSDestination->Item("SER_DESCRIPTION")->{Value} = $temp;<br /><br />Simple. Nifty. Works.<br /><br />Where was I? Oh yeah. Finally get the raw data into a pivot table and within 5 minutes the data is singing. (what, I don't know) Want to know how many raw tickets we processed, broken down by month, with a 12 month moving average?<br /><br />BOOM! POOF! ALAKAZAAAAAMMMM!! (well, about six clicks, actually)<br />Average time to resolve tickets over the same period, broken out by Tier 1, 2, and 3 groups? <br /><br />FHAWOOMPUS! (three clicks)<br /><br />No, I'm not showing my work. You'll just have to trust me on this one.<br /><br />Come to think of it, I actually happen to have a pivot table tutorial (disguised as instructions on how to pull VSS metrics) that might be helpful. I'll have to get on that...<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-5455780969172269500?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-17811954788335523312007-10-11T15:06:00.000-07:002007-10-11T15:56:01.087-07:00What did I learn today?I'd like to say that today I picked up some new ultra-snazzy techno skill. I successfully refactored the web app I'm doing to use <a href="http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx">LINQ</a>. Or <a href="http://nunitasp.sourceforge.net/">NunitAsp</a>. Maybe got the back end to multi-thread successfully.<br /><br />Alas. No luck. Today was much more pedestrian. Requirements and test data.<br /><br />Requirements:<br />Shadow IT development is a kick. In the pants. (The trick is for it not to be a kick in YOUR pants.) I'm guessing a fair number of developers got their start in <a href="http://codebetter.com/blogs/jeremy.miller/archive/2005/07/18/129330.aspx">shade tree IT development</a>. (Hey, that's my foot in the door too, so please don't slam it!)<br /><br />I want to do the best job I can. And I'm blessed (no, really) with both the perspective of a few years of QA ("is it testable? did you build it to spec?!") as well as systems administration. ("Whaddaya mean there's no support?! Who do I call when this breaks? Where's the documentation on how it's supposed to work? No...1/4 page of fragmented english and a screenshot of a dos command window doesn't cut it..")<br /><br />And I realized today that, while I've been functioning well enough with some 10,000 foot fuzzy requirements for the proof of concept it's time for some more detailed stuff.<br /><br />(also because I'm floundering like a beached carp wondering what to do next.)<br /><br />Should I tackle<br /><ul><li>The parser for the peoplesoft-generated text file containing user location data?</li><li>The multi-threading back end so the .exe called by the web app (on the web server) doesn't hog response time.</li><li>Ooohhh...or the user authentication piece. Gotta get that in.</li><li>What about a command-creation factory?<br /></li><li>Umm...logging functionality to record what the users did?</li><li>Oh yeah, and I need to make sure I get some sort of reconciliation doohicky to pull data from VistaPlus (the reports distribution tool), parse it, and compare it to the (several) other "sources of truth" we have available.</li></ul><br />Yeah. What's most important?<br /><br />What do I do _now_? (analysis paralysis, anyone?)<br /><br />So I started augmenting and cleaning up the <a href="http://www.joelonsoftware.com/articles/fog0000000245.html">schedule </a>I started several weeks ago. And as my fingers wandered aimlessly across the keyboard, I actually managed to see patterns of responsibility and logical progression.<br /><br />And the logjam in my head started to free. Imagine.<br /><br />On to testing.<br /><br />Ahhh....test data. We hardly knew ye.<br /><br />Well, actually we know ye too d### well.<br /><br />My current assignment is a web app to help folks manage permissions in our corporate reports distribution tool. We use this for everything from Oracle Financials data to Peoplesoft reports to...well, a lot of stuff.<br /><br />Anyway. When store managers move around (I work for a large retail organization) or their mgrs, etc, it's not uncommon for it to be weeks or longer before they can get their financials for their newly assigned post.<br /><br />This is a Bad Thing.<br /><br />The process by which the tool is updated evolved (you guessed it) in a rather organic fashion. As these things do. Folks did the best with what they knew and had. So we have a process by which emails are forwarded between 3-5 people, in no standard format, and get processed in a batch when there's time.<br /><br />Where was I? Test data. Oh yeah.<br /><br />I'm getting to the bit where I actually make the (7-10) changes necessary when someone moves, and I realize I have no data.<br /><br />None. Nada. Zip. Zilch. Zeeero.<br /><br />And developing a solution against a "test" database that's populated with 10 records...well...it's just not where I want to go.<br /><br />So today was spent exporting a copy of (safe!) data from our production server and getting it imported into my little-ol test server.<br /><br />What did I learn? I (re)learned just how valuable my "keep everthing INCLUDING the kitchen sink in <a href="http://subversion.tigris.org/">subversion</a>!" habit can be. Instead of being a multi-day process, I just hitched on over there, looked in a few previous project directories (I've worked with this app before) and before you know it, I had found scripts I'd written long (1.5 years or so) ago. Specifically to pull data from this app and load it into another system.<br /><br />It still took a little tinkering, but in the end it was a couple hours vs. a couple days.<br /><br />Life is good.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-1781195478833552331?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-1878604601311655352007-10-10T09:55:00.000-07:002007-10-10T21:17:02.131-07:00What did I learn today?Ever have one of those days? Days that ... well ... you struggle to find motivation to do much beyond reading the Onion?<br /><br />I do. So in the spirit of keeping my brain kickstarted and engaged, I thought I'd try to do a "what did I learn today?" post. For about a week and a half. We'll see how it goes.<br /><br />today..<br /><br />Yesterday while searching for a canned logging solution that's more robust than my liberal system.diagnostics.debug.writeline's....I came across a couple of things. <a href="http://logging.apache.org/log4net/">log4net </a>was developed by the apache group. Big. Robust. Configurable n^n different ways. I'd run across it before and, frankly, run screaming the other way. (at that point my problem was a fly and log4net a howitzer)<br /><br />Enter <a href="http://www.nlog-project.org/introduction.html">NLog</a>. Short. Sweet. To the point. It "Just Works". Add a reference, define your targets in a (blessedly simple) .config file, and you good to go baby! No fuss, no muss, no reinventing the wheel.<br /><br />Today's learning:<br /><br />A word to the not-so-wise. (ie, others like me) If you're following along the tutorial (very straightforward and well done, btw), and you decide to create a windows form app instead of a console app. (because. You know. You're not really thinking..) And then you wonder why the "log to console" bit of the tutorial just isn't working...<br /><br /><turns red="" here=""><br /><br />Yeah. You got it. Console output doesn't just magically pop up in a windows forms app.<br /><br />(bonus question: why not? Three minutes of googling didn't find me the answer, so I'll table it for now..)</turns><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-187860460131165535?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-41967662911609075742007-09-27T12:02:00.001-07:002007-09-27T13:02:36.638-07:00Rubber meets the roadWe now redirect you from our standard programming to something slightly more interesting.<br /><br />Welding.<br /><br />No really. Stick with me here. (heh. Stick. Welding. nevermind)<br /><br />When I was a kid, I always wanted one of those cool ride-on electric cars. You know, the ones that are $300, two seats, and a cheesy plastic key. They were, like, soooo cool. And expensive. Ahh, the materialism of youth.<br /><br />Fast forward to now. I've been ruminating for a while about my itch to build. Create. And frankly, while software (sometimes) scratches that itch, sometimes it just doesn't. I've done a little bit of woodworking, enough to discover I'm a utilitarian woodworker vs. a finish carpenter. I love building simple shelves, toys. Repairing drawers. Making jigs that make it easier to make things better and more precisely.<br /><br />And while I'm no master, I can pretty much get done what I need to do.<br /><br />I started wondering a while back, how difficult it would be to <a href="http://buggies.builtforfun.co.uk/index.php">make one of those backyard cars</a>. I began <a href="http://www.aaroncake.net/projects/elecscoot.htm">looking at electric scooter motors</a>. And batteries. And started reading up on <a href="http://www.coolrobots.com/builders/newbie.html">how battle bots are powered.</a> (because you never know when you'll want to <a href="http://www.gizmology.net/tanks.htm">add armourment to your kiddie car</a>)<br /><br />In a perfect storm (and thanks to the beneficent benevolence of ebay) I found a lot of 10 350 watt 12v motors for $100 on e-bay. And <a href="http://cgi.ebay.com/New-12V-7AH-Volt-Schwinn-Sealed-Lead-Acid-Battery-Bike_W0QQitemZ120165210518QQihZ002QQcategoryZ36323QQssPageNameZWDVWQQrdZ1QQcmdZViewItem">$7 7amp hour sealed lead acid batteries</a>.<br /><br />And next week Harbor Freight will have their <a href="http://www.harborfreight.com/cpi/ctaf/displayitem.taf?Itemnumber=94056">110v 80amp wire-feed flux-core welder</a> on sale for $99. I've never welded before, so I'm stoked. Ok, I've welded once. With a stick welder. You know, the kind that you strike and it's kinda supposed to go "zshzzshszitzitzit". But with me it was more of the "zzzssshhmmmmmmmmmm!@#$!@$#!#".<br /><br />(the stick welds itself to what you're trying to weld.)<br /><br />Needless to say, my creative juices are flowing as they rarely have in recent months. The last time I was this excited was when I was starting on the <a href="http://legodefenseindustries.blogspot.com/">lego interceptor</a>. It really does put a spark in everything else.<br /><br />I've lined up a friend who does metalwork to let me dig through his scrap bin for practice fodder. I'm looking forward to what's next!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-4196766291160907574?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-71128974899628908352007-04-11T08:42:00.000-07:002007-04-11T13:59:22.525-07:00It's an Integration of Continuous JoyIt's a continuous integration love-fest, baby!<br /><br />That may be an unfortunate choice of words, but you get the idea.<br /><br />After spending too much time banging my head trying to get the ol <a href="http://legodefenseindustries.blogspot.com/">Lego Interceptor</a> to track objects correctly, I decided to back off and put into place another key piece of the learning that I've (purportedly) wanted to do. That is, figure out how to set up a continuous integration server.<br /><br />In a previous life, the QA group was also responsible for providing builds. This was a Good Thing, as we could keep things scrupulously clean, archive the "blessed" versions of external libraries required for the build, make sure the builds we were testing came from a known code label, etc etc. (QA is a great career choice for control freaks)<br /><br />And I did this gleefully.<br /><br />There was only one problem. The [da dum] BUILD SERVER. As a former sys admin, I happily configured server after server after server...(dedicated servers, you see) in order to insure clean environments. Each server built for a very particular project.<br /><br />Somewhat wasteful of resources (now), but this was in the late 90's. Oh, and I had a whole QA lab chock full of desktop systems to pull from when I needed a new box. And we rarely had more than 2-3 projects running at any one time.<br /><br />But there were problems. Like...how do you archive the build machine?<br /><br />When I started, the team often just used swappable hard drives and labeled each with the project name. This wasn't, unfortunately, duplicatable as those hard drives themselves got rather crufty and weren't documented particularly well. And if the original machine that had done the build wasn't available, it wasn't like you could just pop it into another and you were off to the races. No, these were the days of Windows NT4.0, 95, and plug-n-pray.<br /><br />I remember one particularly painful experience, as I was asked to find and rebuild the source code for a video codec that had gone into production. I found the source (after much mucking about) but the hard drive assigned to the product was unbootable. Oh, and the external libraries that we needed? Nope. Needed the OLD versions to link against and did we have those? (this is when I learned to check EVERYTHING needed for the build into source control. Yes, even if it's VSS. <a href="http://www.developsense.com/testing/VSSDefects.html">Well, maybe</a>.)<br /><br />Nonetheless, we suffered through. I would carefully build stock NT 4 images, run <a href="http://www.serverwatch.com/tutorials/article.php/2194021">sysdiff </a>/snap to grab a snapshot, install the compilers, libraries, etc. Configure everything just right and run sysdiff /diff to grab a "diff" image. Not only did this give us all the file differences, it actually diff'ed registry entries too, so anything and everything changed in the registry could be saved.<br /><br />(I later used this technique + batch build scripts for our White Room Build process with wild-happy success. A completely separate group could reproduce our gold binaries with only a base NT system and my image cd. I soo.o thought I was the cat's pajamas)<br /><br />Of course, if we changed a library mid-project. Or I forgot and added something unnecessary. Or compiler setup changed. I'd have to redo the whole process. (later revs included me ghosting the system at various intervals for minimal rebuild time...but it was still a pain)<br /><br />Fast foward about five years. I'm introduced to VirtualPC. And the old wheels get to turning.<br /><br />"Hmm....everything's emulated. Which means you could run this image on ANY system."<br /><br />And then I ran across <a href="http://www.obishawn.com/archive/2006/03/27/11.aspx">an article on Build Machine Virtualization</a>.<br /><br />Eureka!<br /><br />Now where was I...oh yeah, continuous integration. I didn't want to burn resources setting up a static CI server...I just wanted to play around with it a bit. Take it home if I was so inclined. So I fired up VirtualPC 2007, built a Windows Server 2003 image, and to make an already-too-long story short, used this guide on "<a href="http://weblogs.asp.net/jdanforth/pages/How-to-Hook-Up-a-VS.NET-2005-Solution-With-CruiseControl.NET-in-a-Few-Minutes.aspx">How to Hook UP a VS.NET 2005 Solution with CruiseControl.NET in a Few Minutes</a>".<br /><br />And you know...it WORKED!<br /><br />I was also afraid that I'd be spending days mucking about with configuration files, service ports, and IIS configs. Nope.<br /><br />As a matter of fact, I didn't even have to use <a href="http://nant.sourceforge.net/">NAnt</a>...(the .net version of the auto build tool, <a href="http://ant.apache.org/">ANT</a>.) <br /><br />CruiseControl.net has built-in support for building with both the msbuild.exe tool (which allows building withOUT having the full IDE on the box...I believe this is part of the sdk) as well as the msdev method. (which is what I used in the above former-life) Just feed either one the .sln file, and they happily compile<br /><br />So lessee...in a nutshell, to get Continuous Integration working with a virtual build server:<br /></da><ol><li>Download VirtualPC 2007 and install it</li><li><da dum="">Created a new Windows Server 2003 system<br /></da></li><ul><li><da dum="">XP Pro would probably have worked just as well</da></li><li><da dum="">It took a loooooong time to patch the system running on my 1.6ghz notebook.</da></li><li><da dum="">I highly recommend putting the virtual machine hard disk file on a USB2 or firewire external drive if you need to use the host machine while building the CI virtual machine. A 30gig iPod with disk use enabled will do in a pinch. ;^)<br /></da></li></ul><li><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_giL3BvszLnY/Rh0KZ0pVEBI/AAAAAAAAAg8/3orqdRAmeg8/s1600-h/manageYourServer.PNG"><img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://4.bp.blogspot.com/_giL3BvszLnY/Rh0KZ0pVEBI/AAAAAAAAAg8/3orqdRAmeg8/s320/manageYourServer.PNG" alt="" id="BLOGGER_PHOTO_ID_5052205795724562450" border="0" /></a>Configure the CI machine as an app server. The sys admin in me wanted to do it the hard way, but the "just get 'er done" piece won out and used the "Manage Your Server" wizard. Slick. Easy. Told it I wanted ASP.NET enabled and it Just Worked.</li><li>Download and install Subversion (using the nifty installer)<br /></li><li>Download and install Nunit (using the nifty installer)</li><li>Download and install CruiseControl.Net (using the nifty installer)</li><li>Create your "working directory" (in my case c:\svn\NXTTest)<br /></li><li>Grab the ThoughtWorks.CruiseControl.MSBuild.dll and copied it to c:\svn\NXTTest</li><li>As I was using apache to serve subversion vs. the svn daemon (in the "few minutes" example above), I changed my config just a bit. This configuration file will check the repository for changes every 5 minutes (300 seconds), rebuild if there are any changes, and run all the unit tests.</li></ol><cruisecontrol><br /> <project><br /> <name>NXTTest</name><br /> <triggers><br /> <intervaltrigger seconds="300" buildcondition="IfModificationExists"><br /> </intervaltrigger><br /> <sourcecontrol type="svn"><br /> <trunkurl>http://mysubversionserver/svn/trunk/source/tutorials/NXTTest/</trunkurl><br /><executable>C:\Program Files\Subversion\bin\svn.exe</executable><br /><workingdirectory>C:\svn\NXTTest</workingdirectory><br /></sourcecontrol><br /><tasks><br /><msbuild><br /> <executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable><br /> <workingdirectory>c:\svn\NXTTest</workingdirectory><br /> <projectfile>NXTTest.sln</projectfile><br /> <buildargs>/noconsolelogger /p:Configuration=Debug /v:diag</buildargs><br /> <targets>Build</targets><br /> <timeout>15</timeout><br /> <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,ThoughtWorks.CruiseControl.MsBuild.dll</logger><br /></msbuild><br /><nunit path="C:\Program Files\NUnit 2.4\bin\nunit-console.exe"><br /> <assemblies><br /> <assembly>C:\svn\NXTTest\NXTtest\bin\Debug\NXTTest.exe</assembly><br /> </assemblies><br /></nunit><br /></tasks><br /></triggers><br /></project><br /></cruisecontrol><br /><br />Bummer...the <a href="http://www.stanford.edu/%7Ebsuter/js/convert.html">converter I used</a> for the XML didn't seem to manually enter spacing info. And I'm not seeing easy ways to format code snippets within blogger.<br /><br />Lessee...what else. I think that about covered it.<br /><br />I then launched the CruiseControl.net service from the icon on my desktop, it grabbed everything and I was off to the races.<br /><br />I then fired up http://127.0.0.1/ccnet/ on said build box and lo-n-behold...beautiful build goodness!<br /><br />For whatever reason the box's name wasn't resolving via wins (or whatever it's morphed into) so I had to hit the CI server via it's ip address from the host. But it worked too with the ip.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_giL3BvszLnY/Rh0ZHkpVEDI/AAAAAAAAAhM/vvDXRC-P11U/s1600-h/ci+success.PNG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_giL3BvszLnY/Rh0ZHkpVEDI/AAAAAAAAAhM/vvDXRC-P11U/s400/ci+success.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5052221974866366514" /></a><br /><br />I also installed the super-noofty ccTray tool. Pointed it at the CI server's IP (ie: http://192.168.0.44/ccnet/) and it too just worked.<br /><br />I'm just positively giddy!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-7112897489962890835?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com2tag:blogger.com,1999:blog-18966233.post-79955456498994165372007-03-23T08:35:00.000-07:002007-03-23T08:52:08.743-07:00Wisdom for the young grasshopper...<a href="http://www.taylor.se/reddit.html">Top ten things ten years of professional software development has taught me</a><br />( http://www.taylor.se/reddit.html )<br /><br />I especially liked #4 and #5:<br /><br /><span style="font-style: italic;">4. If everything is equally important, then nothing is important<br />The business likes to say that all the features are as crucial. They are not. Push back and make them commit. It's easier if you don't force them to pick what to do and what not to do. Instead, let them choose what you should do this week. This will let you produce the stuff that brings value first. If all else goes haywire, at least you've done that.</span><br /><br />This shares the "do something useful today" feel of agile-ish practices. (ie, always have a ready-to-ship version that's working available in source).<br /><br />Even more goodness, this neatly gets around the tenancy (and I've never done this) of "we can't do ALL THAT!!" and/or "You're the customer, YOU tell me what order to build this entire thing!" It neatly chunks out prioritization choices in a non-threatening way.<br /><br />(I'm really strongly resisting the urge to use phrases like "empowers the customer" and "value add". You can thank me later.)<br /><br />I'd like to think that I could have diffused some tense-ness (is that a word?) in past projects if I'd used this approach.<br /><br /><br /><span style="font-style: italic;">5. Don't over-think a problem</span><br /><span style="font-style: italic;">I can spend whole days designing things in front of the white board. That doesn't mean it will be any better, it just means it will be more complicated. I don't mean to say you shouldn't design at all, just that the implementation will quickly show me stuff I didn't think of anyway, so why try to make it perfect? Like Dave Farley says: "The devil is in the details, but exorcism is in implementation, not theory."</span><br /><br />On this <a href="http://legodefenseindustries.blogspot.com/">last "learning project" I'm doing</a>, I spent several monday lunchtimes with a friend as we hashed out (on a whiteboard) how control should flow, what objects we needed, etc etc. It was a useful exercise. But when the rubber met the road in implementation, much of that went out the window. The code, in a way, became the teacher.<br /><br />(I like that. Very zen.)<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-7995545649899416537?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-48122008475953214422007-03-06T08:28:00.000-08:002007-03-06T08:54:48.913-08:00There is nothing new under the sun...It never fails. I have an absolutely FANTASTIC idea for a blog post. (usually in the shower)<br /><br />So I try and capture it.<br /><br />(note: dry-erase + shower = cranky wife)<br /><br />Of course, in the next 3 days of net wandering I inevitably run across someone who's written up the same thing. And of course it's all dolled up, cuter, wittier, and with better supporting arguments than I would ever have dreamed up.<br /><br />I'm sure this has something to do with the brain kicking the idea around in the <span class="blsp-spelling-corrected" id="SPELLING_ERROR_1">subconscious</span> and when it finds something kinda-sorta similar it's all sweetness and roses and fireworks.<br /><br />(This is also known as the "I found it in the last place I looked" phenomenon. Of COURSE you did...what kind of idiot continues looking after they've found the object of their search...)<br /><br />I could be depressed about this. (insert obligatory "we're not worthy!" chant) But I'm not. Well, not really. Because, you see, I can now put my brainpower into thinking about something new.<br /><br />We've all got a finite amount of brainpower. Let's call it X. Or Q. Or I. (heh...I.Q...nevermind)<br /><br />Kathy Sierra <a href="http://headrush.typepad.com/creating_passionate_users/2007/02/its_lunchtime_a.html">recently asked "Are our tools making us dumber?"</a> <ref> Ie tools that "do it all for us" shortcutting the process to learn what you _need_ to learn to do your job better.<br /><br />My thoughts on that subject were summed up neatly when she said "How many graphics designers feel the need to "hand tweak" their generated postscript files?" (or something like that) That's right...what comes out of Quark or Pagemaker (oops, InDesign) is good enough.<br /><br />These computer doohickeys are damn complicated. And we all like to think that everyone should have expertise in whatever area we ourselves already have experience in. Because, you know, you could tweak out 1/n additional performance if they just did "it" right. But if they'd spent their time learning what we know, they wouldn't know what THEY know.<br /><br />So they use our tool/plug in/whatever to "just get it done", and they can produce something cool. They can build on top of a whole pile of abstractions, and the sum that's spit out at the end is greater than it's parts.<br /><br />Of course, all this goes without saying that when the performance/accuracy of said part is of primary importance to the product you're producing, rolling your own and/or <a href="http://www.joelonsoftware.com/articles/fog0000000026.html">having control over it's implementation is a good idea</a>. <ref:> id Software outsourcing the 3d code for Quake would be a "bad thing". Or the network code. But maybe they could have used a 3rd party tool to convert text to bitmaps for displaying status messages. (I don't know...I'm reaching here)<br /><br />You get the idea. The tools keep getting more complex because the environments we're working in keep getting more complex. Accept it. The old adage of "we're standing on the shoulders of giants" may be true...but I think it's more often "we're balancing precariously on the top of a pile of good to excellent folks who themselves were building on other's works..."<br /><br />That's not as eloquent as I'd like, but it'll do.</ref:></ref><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-4812200847595321442?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-15195585561307997632007-02-28T10:23:00.000-08:002007-02-28T12:16:27.880-08:00insert snappy title about reading hereI like to read though I seem to have less and less time to do so. Yet inevitably when I find something that catches my interest I manage to finish it. (if it really catches my interest, my wife comments on how much time I've spent in the bathroom recently.)<br /><br />After having it recommended awhile back by a good friend, I've plowed through about 3/4 of <a href="http://www.amazon.com/Its-Your-Ship-Management-Techniques/dp/0446529117/sr=8-1/qid=1172687165/ref=pd_bbs_sr_1/002-9032258-1332811?ie=UTF8&s=books">It's Your Ship: Management Techniques from the Best Damn Ship in the Navy</a> in a blistering 3 days.<br /><br />(I could have gone faster, but the legs go numb...)<br /><br />It rocks. Seriously. While it's simple, (seemingly) common sense stuff I almost found myself crying (that's right - real <span class="blsp-spelling-error" id="SPELLING_ERROR_0"><span class="blsp-spelling-error" id="SPELLING_ERROR_0">bona</span></span> <span class="blsp-spelling-error" id="SPELLING_ERROR_1"><span class="blsp-spelling-error" id="SPELLING_ERROR_1">fide</span></span> aqueous duct activity) over how much this guy "gets it". Kinda like <span class="blsp-spelling-error" id="SPELLING_ERROR_2"><span class="blsp-spelling-error" id="SPELLING_ERROR_2">Peopleware</span></span> for the Navy. And as the captain of the ship, this guy practiced what he preached. And had the authority to <span class="blsp-spelling-corrected" id="SPELLING_ERROR_3">implement</span>. Found creative ways around, over and (sometimes) through the rather <span class="blsp-spelling-corrected" id="SPELLING_ERROR_3">moribund</span> Navel hierarchy.<br /><br />Go read it.<br /><br />And then scratch your head and ask "if this guy got such exceptional performance out of 'the <span class="blsp-spelling-error" id="SPELLING_ERROR_4">averagest</span>'...how does it apply to software development and the tech sector in general?"<br /><br />"How does it apply to me as a leader/parent?"<br /><br />"How does it apply to me as an aspiring developer?"<br /><br />"It's got to be a kick to write software that controls those <a href="http://en.wikipedia.org/wiki/Phalanx_CIWS">Phalanx <span class="blsp-spelling-error" id="SPELLING_ERROR_5">CIWS</span></a> systems.."<br /><br />cheers!<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-1519558556130799763?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-28274210449250384332007-02-28T09:55:00.000-08:002007-02-28T10:18:10.856-08:00When is "the right way" too much?It feels good when you know stuff. And knowing "stuff" lets you get things done.<br /><br />Case in point: the manager of the group I've been lent to needs some metrics for the performance of the app his group has care-and-feeding responsibilities for. The metrics are available on an existing series of web pages...formatted in a nice table.<br /><br />Unfortunately, said format does not lend itself to data analysis. And he (the manager) as an old <span class="blsp-spelling-error" id="SPELLING_ERROR_0">sql</span> <span class="blsp-spelling-error" id="SPELLING_ERROR_1">slinger</span> wants it in a format he can analyze. (preferably excel...of course)<br /><br />As a proof-of-concept I whipped up a batch script using <a href="http://users.ugent.be/%7Ebpuype/wget/"><span class="blsp-spelling-error" id="SPELLING_ERROR_2">wget</span> </a>and <a href="http://gnuwin32.sourceforge.net/packages/sed.htm"><span class="blsp-spelling-error" id="SPELLING_ERROR_3">sed</span> </a>to determine if it was possible. (and work out the <span class="blsp-spelling-error" id="SPELLING_ERROR_4">regex</span> kinks) This took about 1.5 hours. <br /><br />(I was happy...given that I think I've used <span class="blsp-spelling-error" id="SPELLING_ERROR_5">sed</span> maybe once before. The thorniest part was figuring out the differences in command line syntax/quoting between all the <span class="blsp-spelling-error" id="SPELLING_ERROR_6">sed</span> tutorials and the gnu-for-windows version of <span class="blsp-spelling-error" id="SPELLING_ERROR_7">sed</span>..)<br /><br />After verifying the data was useful, I wrapped the functionality (using C#'s native <span class="blsp-spelling-error" id="SPELLING_ERROR_8">regex</span> capability) into a nice little windows form app. Two hours later, I had an excel spreadsheet with snazzy pivot table. Data source when "updated" looks in the default location that the forms app dumps the <span class="blsp-spelling-error" id="SPELLING_ERROR_9">csv</span>. Time, about 2 hours.<br /><br />This was a quick one off app <span class="blsp-spelling-error" id="SPELLING_ERROR_10">that'll</span> be used by one person, 1-2x/month, but I did get to thinking what I would do to make it "more robust". To wit:<br /><br /><span style="font-weight: bold;"><span class="blsp-spelling-error" id="SPELLING_ERROR_11">csv</span> file</span><br />overwrites existing (no option to overwrite/append/rename/etc)<br /><span class="blsp-spelling-error" id="SPELLING_ERROR_12">filesystem</span> space check (is there enough space?)<br /><span class="blsp-spelling-error" id="SPELLING_ERROR_13">filesystem</span> directory check (exception if specified directory doesn't exist)<br /><br /><span style="font-weight: bold;">metrics http source</span><br />no specification of server or source page (if it changes, the path'll probably change)<br />somewhat brittle <span class="blsp-spelling-error" id="SPELLING_ERROR_14">regex</span> I'm guessing<br />no handling of "if the server goes away" (.net exception)<br /><br /><span style="font-weight: bold;">architecture</span><br />downloads whole whack of data each and every time (but only takes about 30 sec...seemed a good <span class="blsp-spelling-error" id="SPELLING_ERROR_15">tradeoff</span>)<br /><br />But...all those things considered...I wouldn't change it given my requirements. The user was very happy. It's something that's used infrequently. It's unobtrusive and quick.<br /><br />Does it make the user happy? Yes. Does the solution raise them to a higher plane of <span class="blsp-spelling-corrected" id="SPELLING_ERROR_16">consciousness</span>? No. I think it's probably more along the lines of "hey, I couldn't get this data before. I can now do it in 30 seconds." The solution got out of the way of what the guy wanted to do - namely, analyze performance metrics.<br /><br />I'm happy. He's happy.<br /><br />Life is good.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-2827421044925038433?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-84249108146366669442007-02-21T09:50:00.000-08:002007-02-21T10:04:28.111-08:00Inspiration provided free...Alas I am not the inspiring one, but like a true master (uhh...yeah) I try point you to those who can and do inspire.<br /><br /><a href="http://mail.google.com/mail/Seven%20steps%20to%20remarkable%20customer%20service">Seven steps to remarkable customer service</a><br />Joel blogged a bit on customer service. It was nothing earth shattering for him...just the usual humorous, insightful, dead-on-target truth. And some funny bits about New York locksmiths and delis.<br /><br /><a href="http://headrush.typepad.com/creating_passionate_users/2007/02/what_tail_is_wa.html">What tail is wagging the "user happiness" dog?</a><br />Kathy Sierra's witty and entertaining insight on who wags whom. (with some unapologetically snarky remarks on six sigma. Mmmm...)<br /><br /><a href="http://blog.guykawasaki.com/2007/02/ten_questions_w.html">Guy Kawasaki - Ten questions with Michael Raynor.</a><br />Micahel wrote The Stragegy Paradox. And while it asks smart questions and gives very gristly answers (gristly = answers with grist to chew on) it doesn't fall into the "follow me, I've found the truth!" trap. From Guy's intro:<br /><br /><span style="font-style: italic;">I don’t know about you, but there are many companies that succeed, and I can’t figure out why. And there are also many companies that fail (some of which I invested in), and I can’t figure out why. </span> <p style="font-style: italic;">This book goes a long way in explaining how strategy makes or breaks a company. To put it another way, I won’t think I’m so smart if a company that I invest in succeeds, and I won’t think I’m so dumb if it tanks.</p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-8424910814636666944?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-43088854404769521262007-02-12T09:37:00.000-08:002007-02-12T10:13:20.105-08:00Management by ROIOr "Management By the Numbers". It's quick, it's easy, no fuss and no muss!<br /><br />Please note, I'm all for understanding if what you're doing is adding value (or not). However, it does seem that:<br /><br />0.) It's always and forever all about $$.<br />1.) Walstreet shareholder-driven managers are often terminally shortsighted when it comes to value<br />2.) Value is always equated to money, and quick money at that (see #1). No mention of customer goodwill (unless it immediately translates to cashflow. This quarter.) Little beyond lip service for much beyond the next three quarters.<br /><br />No mention of a company's higher mission/purpose. (assuming it has one)<br /><br />Jim Collins/Jerry Porras <a href="http://www.amazon.com/Built-Last-Successful-Visionary-Companies/dp/0060566108/sr=8-1/qid=1171302498/ref=pd_bbs_sr_1/103-0169817-0679006?ie=UTF8&s=books">Built to Last</a> has a great bit in it where all the execs of Boeing were sitting around a table discussing the upcoming (I think) 747 project. It was to be a revolutionary project. A huge gamble. What Collins/Porras called a BHAG. (Big Hairy Audacious Goal).<br /><br />One of the execs asked if they had figures on the ROI.<br /><br />The response? Essentially "We're not sure."<br /><br />The exec was incredulious. "Then why would you do it?!!"<br /><br />"Because we are Boeing. This is what we do."<br /><br />(Notice a pointed lack of any words relating to "maximizing shareholder value".)<br /><br />Seems that the pendulum has swung far, far too far into the territory of: “Hey, this management thing isn’t so hard! Just calculate the ROI and if it’s not high enough don’t do it! If anyone calls you on it, you've got numbers to back you up!” Make the most cash possible. And CYA while you're at it.<br /><br />No insight. No gambles. No spirit. Just dull plodding along to make money. (geez...I think I've just slipped into "diatribe against The Man" territory...)<br /><br />As with any organic organization, that attitude rolls down...down...down to the downtrodden Rodney Dangerfield of the corporate set, IT. Like a whimpering puppy, IT wants to please it's master and show that I'm good enough, I'm nice enough, and doggone it people LIKE me!<br /><br />"Validate me!" IT cries to each and every customer. "You use me every day, I try and cater to your every whim, yet still you fume and stomp when email isn't delivered on time. Well...so tell me how much it's worth to you to get your Blond Joke -o- the Day delivered to Outlook on time?!! How much money did you save by getting to your files this morning? I resolved your help ticket and got your MSN communicator working in record speed - that adds bucks to our bottom line, right?"<br /><br />Gotta track those numbers. Translate everything to dollar signs. Metrics to show how fast email is delivered, tickets resolved speedily and servers humming with uptime.<br /><br />Metrics are all good and well…but can we really reduce the art of management and leadership to number crunching and CYA justifications?<br /><br />Even as clueless as I often am, I know there’s more to good management then that.<br /><br />In a fit of pique awhile back, my mind drifted into an alternate (but not too alternate) universe...<br /><br />***************************<br /><ring><br />[helpdesk:]“Hello, This is the helpdesk”<br /><br />[caller:]“This is Stan from payroll. Our file server is down.”<br /><clickety><br />[hd:]“Hmm…Stan, I see from our metrics that you’re utilization of the server is only at 18.732%. That corresponds to a space costs us approximately $386.62/month.”<br /><br />[caller:]“Umm..ooohh kaaay. When will it be back up?”<br /><br />[hd:]“Well sir, according to our tracked metrics and ROI calculation, you obviously don’t need the space that bad.”<br /><br />[caller:]“WTF?!! <expletives> We USE that file space!”<br /><br />[hd:]“I completely understand sir. However, IT now has to justify all our resources to the CIO and CFO. If an asset’s usage falls below a certain point it’s determined that the resource isn’t contributing enough to the bottom line."<br /><br />[caller:]“Wha? But… Ho… What am I going to do now? That server had figures I need!”<br /><br />[hd:]“Well sir, we do have one alternative. Can you tell me how much they’re worth?”<br /><br />[caller:]“What?!”<br /><br />[hd:]“How much they’re worth.”<br /><br />[caller:]“Worth?!! They’re worth a LOT! I can’t do my JOB without them!!”<br /><br />[hd:]“<confidentally>Ah sir, I wouldn’t use that argument. After all, your job is an <span style="font-style: italic;">expense </span>on the balance sheet. <tsking>If the only consequence of losing the data is you losing your job, that’s…well…that’s an easy win for IT metrics. We look good, because we've just reduced expenses and all that. Just between you and me I’d try a different tack…”<br /><stunned><br />[caller:] <stunned><br /><br />[hd:]“If we can put a $$ figure on the data, I can put forth a request to have the server brought online. Of course, you’ll want to estimate high as the techs are only authorized to expend 80% of their cost time in the recovery effort.”<br /><br />[caller:]“80 percent…uh…ok....”<br /><br />[hd:]“Oh, and you’ll need to show your calculations. It’s a new SOX requirement. Transparency and accountability and all that.”<br /><br />[caller:]“……..”<br /><br />[hd:]“Sir..? Sir….?”</stunned></tsking></expletives></clickety></ring><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-4308885440476952126?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-70220791598750655372007-02-07T08:12:00.000-08:002007-02-07T08:29:19.261-08:00Test Driving Test Driven DevelopmentAsk and ye shall receive. Kvetch and ye shall be hit upside the head with a wet fish.<br /><br />(something like that)<br /><br />Anyway, as I've been <a href="http://www.itgroundhog.com/2007/01/so-hows-that-learning-thing-going.html">bemoaning my lack of insight</a> into how really to effectively utilize unit tests beyond the simplest things, what do I find but <a href="http://www.testdriven.com/modules/newbb/viewtopic.php?topic_id=4375&forum=6">a wonderful tutorial on exactly that!</a><br /><br />(<a href="http://www.testdriven.com/modules/newbb/viewtopic.php?topic_id=4375&forum=6">http://www.testdriven.com/modules/newbb/viewtopic.php?topic_id=4375&forum=6 )</a><br /><br />Gishu, by his own admission, started to write a 10 page "How to do Test Driven Development" in response to the <ah-hem> whiners <like> who said "it can't be done!"<br /><br />(more specifically, "You can't really do TDD with a UI app".)<br /><br />"Phiffle", cried Gishu. (I'm taking literary licence here) "Indeed it can!"<br /><br />And lo and behold his 10 pager grew into a 200 page document that walks the newbie through his stream-of-consiousness development of a complete UI app and it's attendant tests. And not just dry "this is the principle" stuff, we get to see the nitty gritty code, laugh as he muses tradeoffs, and weep as his unit tests go from red to green.<br /><br />I'm about 17 pages into it, and I'm loving it. The scales are falling from my eyes. The heavens are opening up and angels are singing. I'm spontaneously dropping into lotus and humming the almighty "om......."<br /><br />No, really. Or maybe it's just the lack of caffine in my bloodstream. Or the koolaid I drank. Whatever.<br /><br />It's written <a href="http://headrush.typepad.com/creating_passionate_users/2005/09/conversational_.html">informally, but that just keeps my brain engaged</a>.<br /><br />Thank you Gishu!!!!! Kudos!</like></ah-hem><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-7022079159875065537?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com1tag:blogger.com,1999:blog-18966233.post-8065570641484865392007-01-23T07:49:00.000-08:002007-01-23T08:26:11.352-08:00We're not worthy! We're not worth! We're scum!...<br /><br /><span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_0">Ok</span>, not really. But every so often this groundhog pops his head out of the dirt and goes "eh. That big world, <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_1">thingie</span>. It's big. Like, really, really big. Like, I thought I was pretty hip to that whole "big world" concept, but once again I realize I'm really a very small, small animal and there's a whole lot more outside of me than inside me."<br /><br />What brought this on, you ask? <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_2">Ok</span>, you didn't ask but I've been drinking. Coffee. Been drinking coffee. Good coffee, mind you.<br /><br />Where was I? Good coffee. Yeah. Anyway, as I'm showering this morning (too much information) I have this sudden flash of inspiration. I'm going on, congratulating myself on how well this whole developer thing is going when I'm hit with the cold realization that I really don't know squat.<br /><br />(or maybe it was my 6 year old flushing)<br /><br />Anyway, while yes - I do feel pretty good about what I've learned - it was with a thrill of dread that I realized (a sliver of) just how much I don't know. <br /><br />Yeah, I can "go figure it out and make it work" (and maybe that's all that matters?) but I want my solutions to be elegant. Well crafted. Compelling, <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_3">damnit</span>. <a href="http://www.codinghorror.com/blog/archives/000773.html">I want to write applications that people want to use. </a> (Mr. Atwood said it better than I.)<br /><br />And it's chafing me, that I know so little. Maybe kinda sorta like an apprentice woodworker watching the master craft a beautiful <a href="http://images.google.com/images?q=chippendale%20highboy&ie=UTF-8&oe=UTF-8&client=firefox&rls=org.mozilla:en-US:official&sa=N&tab=wi">Chippendale highboy</a>, while he himself struggles to <a href="http://home.nj.rr.com/afoust/dovetails.html">cut dovetails that don't slop</a>. Perfectionism paired with impatience. A recipe for unhappiness.<br /><br />When it comes to systems administration, <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_4">QA</span> work, stress and load testing, I have a reasonably large toolbox. I've done it a few times, I've put in some time, and so I have a bunch of different <span onclick="BLOG_clickHandler(this)" class="blsp-spelling-error" id="SPELLING_ERROR_5">toolsets</span> I can use to solve the problem. And I feel pretty competent at it. (well, I think so, anyway)<br /><br />When it comes to development I guess I just feel...well...naked. <br /><br />(did I mention I had this revelation in the shower?) <br /><br />Deep breath. Learn one thing at a time. Realized that I just need to work on me and I don't have to be a guru tomorrow. I just have to learn something that I didn't know today. Incremental improvement.<br /><br />Kinda "iterative agile life" vs. the waterfall model. It ain't a big splash where you reveal yourself as the grandmaster wizard of all time. <br /><br />Learn. Test. Keep what works.<br /><br />Rinse, lather, repeat.<br /><br />And make sure to have a towel handy.<br /><br />(Fortunately I know for a fact that <a href="http://www.secretgeek.net/depression_is_easy.asp">I'm not the only neurotic developer.</a> And I seem to be in pretty good company. =^) )<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-806557064148486539?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0tag:blogger.com,1999:blog-18966233.post-536281090608390822007-01-21T11:08:00.000-08:002007-01-22T11:00:36.061-08:00So how's that learning thing going, anyway?I realize I've been somewhat remiss (read: ignored completely) any dumping of progress on how the whole learning thing has been going.<br /><br />Not that there haven't been flashes of irritation as the muse of inspiration poked my behind with the proverbial arrow. (maybe cupid was just having an off day?) But it seemed that inevitably as I made time to sit down said muse would run off, giggling and chortling. And I was stuck staring at the monitor with a bit of drool coming out of my mouth.<br /><br />In short: really smashingly fantastically well. I haven't yet passed through the glass ceiling of guru yet (do you ever?) but I'm moving along at a good pace. Well, good for me. Well, good _enough_ for me, right now.<br /><br />It would be absolutely fantastically awesome if I had the likes of <a href="http://www.joelonsoftware.com/">Joel</a>, <a href="http://www.secretgeek.com/">Leon</a>, and <a href="http://www.codinghorror.com/blog/">Jeff </a>coaching me along. (with curricula designed by <a href="http://headrush.typepad.com/creating_passionate_users/">Kathy</a>, comic inspiration by <a href="http://steve-yegge.blogspot.com/">Steve </a>and general get-off-yer-ass inspiration by <a href="http://www.gapingvoid.com/">Hugh</a>.)*. In that situation, I'm sure I'd be absolutely flying.<br /><br />Or...would I?<br /><br />I'll be the first to admit that I'm not always the fastest tack on the block. I absorb information at a pretty steady (heh. slow.) rate. I like to chew thoughtfully as it goes through.<br /><br />(improved mastication = less gas)<br /><br />And while we're at it, being an independently wealthy single trillionaire would help. And one of those Matrix-direct-brain upload thingies, that'd be good too.<br /><br />But I don't have those things. That's ok. Do what you can with what you have. Progress, not perfection.<br /><br />So what _have_ I done in the last 2-4 months?<br /><br />Started and finished an app for work. (this makes my #2 official in-production app! Oh happy day!)<br /><br />Conveniently enough, I had to pick up quite a few new things to get things humming. And managed to hone some general "good disciplines" too.<br /><br />Nope, didn't manage to pair program the unit tests linked into the continuous integration solution that built, packaged, and distributed the app updating the project website with hyperlinked defects into the bug tracking solution and requirements db.<br /><br />(Maybe next go-round)<br /><br />But I did learn a lot/improve in my understanding of...<br /><br />threading<br /><ul><li>had to re-learn this early on<br /></li><li>keep the GUI happy and responsive</li><li>manage an arbitrary number of worker threads that pulled job information from a common queue structure </li><li>figuring out the best way to make logging and queue access thread safe</li><li>investigated the background worker thread component in VS 2005. (mostly AFTER I'd already worked out doing it the "hard way") Ah well.<br /></li></ul><br />delegates<br /><ul><li>Getting status messages back to the main UI</li><li>understanding the whole message passing architecture (delegate prototype, instantiation of delegate, event declaration, tying the event TO the delegate, identifying the actual function to call, making the function threadsafe if you're trying to update the GUI on a thread that isn't the main UI thread...) Good stuff, but admittedly it took me a while to get my head around it all.<br /></li><li>catching app events and dealing with them (like, disallowing the app close if the app was actively running a job - and prompting the user to cancel first)</li></ul><br />code profiling<br /><ul><li>not a whole heaping lot, but I did poke about a bit with Intel's vtune. I'd used this years ago in my QA life with Visual C++ 6.0, and I remembered it being much simpler back then to instrument and profile an app. Perhaps I'm just having a rose-colored senior moment..</li><li>gave the performance profiler built into VS 2005 a whirl. It was somewhat helpful. I'm sure if I had a bit more education and direction in what I was looking at, it'd have been even moreso.</li></ul><br />unit testing (NUnit)<br /><ul><li>Got further this time, but still didn't keep it up through the whole app</li><li>still struggling with much beyond simple tests...need to do more reading on mock objects? Or maybe I just need to accept that writing the tests isn't always just a quick, trivial, exercise.</li></ul><br />source control<br /><ul><li>still need to figure out how to auto-version with subversion</li><li>getting better about commenting checkins.</li><li>commented and labeled all beta and release candidates</li><li>used AnkSVN with vs2005...discovered why SCM integration into the IDE is a Good Thing. (previously had been using TortoiseSVN)</li></ul><br />design patterns<br /><ul><li>actually understood quite a bit more this go-round. </li><li>saw quicker (in retrospect) where I could have used factory patterns. (I think...complex instantiation process should have been handed off/encapsulated better)</li><li>thought a LOT more about loose coupling and abstraction before starting coding. Better overall design because of it.<br /></li><li>used the strategy pattern successfully to decouple a disk-based storage implementation and a memory-based storage implementation. There was much rejoicing when the memory based implementation (which I'd been dreading) took all of about 20 minutes because of the nice design abstraction. Interfaces rock.<br /></li><li>physically winced when I tightly coupled classes together. Promised myself that this was the "last time". Banged head on keyboard when it began to snowball. Finally abstracted pieces out and was much happier with the result. (easier to debug, too)</li></ul>general practices<br /><ul><li>hardcoding file names IN CODE is bad, bad, bad, bad. Naughty developer. Thought I'd learned by now, but got bit in the hiney again.</li><li>I really like the ability to collapse code down in VS 2005's IDE...much easier to hunt and find stuff</li><li>Did a much better job commenting and labeling functions </li></ul> (//helper function to provide UI checks before job start)<br /> vs<br /> (//check everything and make sure it's copacetic)<br /><br />My brain is fair to bursting with all the "stuff" I've had to absorb to make this work. I didn't get everything quite just perfectly right, but I got all the "must have" features in, a UI that doesn't look like I barfed on the screen, and a user experience that's helpful. (I think) Did my best to make sure error messages were helpful.<br /><br />(I did resist the urge for: "The index has overflowed! Grab the Depends!")<br /><br />Initial estimate I provided my manager was 8 weeks. I was testing by 4, had it in user hands at 6, and have RC something-or-other in their hands as of 8.<br /><br />Nice, short, clean.<br /><br />*Come to thing of it, they have been coaching me. First thing in the morning is checking on the RSS feed and greedily devouring any and everything I can from these nice folks.<br /><span style="font-weight: bold;"><br />Leon</span>, you're a gentleman's developer ~ gentle with your rebukes and lavish in your praise.<br /><span style="font-weight: bold;"><br />Jeff</span>, your passion and overall desire for truth really do shine through your cynicism. Mostly.<br /><span style="font-weight: bold;"><br />Kathy</span>, I can't tell you how much milage I've gotten out of asking "and how will this help the users kick ass?" It even inspired me to update my resume with said spirit (though not letter) and start looking for an ass-kicking company to work for.<br /><span style="font-weight: bold;"><br />Hugh</span>, I laughed. I cried. It moved me. Your oft-linked-to "How to be Creative" was a good solid wake up call. I'm not sure if becoming a bona-fide developer is my personal Mt. Everest, but it's the biggest (professional) mountian in front of me right now...<br /><span style="font-weight: bold;"><br />Joel</span>, the Joel Test is now something of my "development 10 commandments". "(+ 2)". I could be effusive and garish in my praise, but...well, hell with it. I love you, man. Someone pointed me your direction back in about 2002, and you're perspective has provided sanity (well, mostly) ever since. (I can't tell you how much joy I got in pointing out to a group of self-serious developers that they were using a "schlemiel the painter" algorithm...somehow I don't think they appreciated the humor...)<br /><span style="font-weight: bold;"><br />Steve</span>, you had me before the "exploding whale" bit in Tour De Babel, and after I was too much doubled over in spasms of laughter to register much. Thank you ~ thank you for the gift of your "Practicing Programming" post. Affirmation that we don't need to know everything, right now.<br /><br />None of you need my accolades, but, damn it, you get them anyway. Thank you for your giving back with blog postings ~ this is one person for whom they've given cheer, inspiration, not a little bit of laughter, and more than a little (wandering?) direction.<br /><br />Ok, everyone off the pedestals now. =^)<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18966233-53628109060839082?l=www.itgroundhog.com'/></div>aaronhttp://www.blogger.com/profile/17810303501299623878noreply@blogger.com0