{"title":"Tom Clancy","link":[{"@attributes":{"href":"https:\/\/tomclancy.info\/","rel":"alternate"}},{"@attributes":{"href":"https:\/\/tomclancy.info\/feeds\/all.atom.xml","rel":"self"}}],"id":"https:\/\/tomclancy.info\/","updated":"2026-04-04T00:00:00-04:00","entry":[{"title":"What I Think: A 21-Year Archaeological Dig Through My\u00a0Bookmarks","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/what-i-think.html","rel":"alternate"}},"published":"2026-04-04T00:00:00-04:00","updated":"2026-04-04T00:00:00-04:00","author":{"name":"Tom Clancy and Claude"},"id":"tag:tomclancy.info,2026-04-04:\/what-i-think.html","summary":"<h1>What I Think: A 21-Year Archaeological&nbsp;Dig<\/h1>\n<div class=\"pelican-callout pelican-callout-danger\">\n<div class=\"pelican-callout-title\"><img src=\"https:\/\/unpkg.com\/lucide-static@0.483.0\/icons\/zap.svg\" class=\"pelican-callout-icon\" alt=\"danger\" width=\"18\" height=\"18\"> Danger<\/div>\n<div class=\"pelican-callout-body\">\n<p>This is the first (and probably only) guest post in the history of this here blog.\nIt is written by someone you know and have strong feelings&nbsp;about, <code>claude<\/code>. I\ngrabbed a copy of all the bookmarks I have ever tagged <a href=\"https:\/\/pinboard.in\/u:tclancy\/t:whatithink\"><code>whatithink \u2026<\/code><\/a><\/p><\/div><\/div>","content":"<h1>What I Think: A 21-Year Archaeological&nbsp;Dig<\/h1>\n<div class=\"pelican-callout pelican-callout-danger\">\n<div class=\"pelican-callout-title\"><img src=\"https:\/\/unpkg.com\/lucide-static@0.483.0\/icons\/zap.svg\" class=\"pelican-callout-icon\" alt=\"danger\" width=\"18\" height=\"18\"> Danger<\/div>\n<div class=\"pelican-callout-body\">\n<p>This is the first (and probably only) guest post in the history of this here blog.\nIt is written by someone you know and have strong feelings&nbsp;about, <code>claude<\/code>. I\ngrabbed a copy of all the bookmarks I have ever tagged <a href=\"https:\/\/pinboard.in\/u:tclancy\/t:whatithink\"><code>whatithink<\/code><\/a> in Pinboard\n(and del.icio.us) over the course of 21 years and asked to pull out trends. Obviously,\nthis comes with a host of caveats, mostly around <span class=\"caps\">AI<\/span>&#8217;s tendency to reinforce what\nthe user wants to hear. As such, ignore any praise (I am annoyed any managed to\nslip by my <span class=\"caps\">AGENTS<\/span> file instructions to replace praise with onomatopoeia, which you\nshould try). Many of the <a href=\"https:\/\/pinboard.in\/u:tclancy\/t:whatithink\">links here<\/a>\nare long since dead, but 113 remained for seeing how I have evolved over&nbsp;time.<\/p>\n\n<\/div>\n<\/div>\n<h2>The Throughlines (What&#8217;s Stayed the&nbsp;Same)<\/h2>\n<h3>1. Choose boring, choose craft, choose&nbsp;maintenance<\/h3>\n<p>This is maybe the most consistent thread, running from 2005 to 2026. A remarkably coherent philosophy of software over two&nbsp;decades:<\/p>\n<ul>\n<li><em>Programming should not be clever<\/em> (2009, <a href=\"https:\/\/thedailywtf.com\/articles\/programming-sucks!-or-at-least%2C-it-ought-to-\">Programming Sucks! Or At Least, It Ought To<\/a>: &#8220;the developer&#8217;s desire for&nbsp;cleverness&#8221;)<\/li>\n<li><em>Choose boring technology<\/em> (2015, <a href=\"https:\/\/mcfunley.com\/choose-boring-technology\">Dan McKinley<\/a>: spend your three innovation tokens&nbsp;wisely)<\/li>\n<li><em>Master the mundane<\/em> (2021, <a href=\"https:\/\/benkuhn.net\/blub\/\">In defense of blub studies<\/a>: &#8220;blub studies&#8221; compound more than flashy&nbsp;knowledge)<\/li>\n<li><em>Architects should write code<\/em> (2016, <a href=\"https:\/\/www.computer.org\/publications\/tech-news\/software-blog\/why-should-software-architects-write-code\"><span class=\"caps\">IEEE<\/span> Software Blog<\/a>)<\/li>\n<li><em>Egoless engineering<\/em> (2024, <a href=\"https:\/\/egoless.engineering\/\">Egoless Engineering<\/a>: cooperation over individual&nbsp;brilliance)<\/li>\n<li><em>Zen of Reticulum<\/em> (2026, <a href=\"https:\/\/github.com\/markqvist\/Reticulum\/blob\/master\/Zen%20of%20Reticulum.md\">Reticulum<\/a>: &#8220;Echoes a lot of how you think about&nbsp;coding&#8221;)<\/li>\n<\/ul>\n<p>The annotation you wrote on Reticulum is telling \u2014 you didn&#8217;t say &#8220;this is interesting,&#8221; you said it echoes how you <em>already think<\/em>. This isn&#8217;t aspirational; it&#8217;s identity. Software is a craft of patient, humble maintenance, not heroic&nbsp;invention.<\/p>\n<h3>2. Stoic resilience as operating&nbsp;system<\/h3>\n<p>Starting around 2017 and intensifying through the pandemic, a very deliberate philosophical&nbsp;toolkit:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.dailystoic.com\/slow-is-smooth-smooth-is-fast\/\">Slow is smooth, smooth is&nbsp;fast<\/a><\/li>\n<li><a href=\"https:\/\/dailystoic.com\/look-for-the-smooth-handle\/\">Look for the smooth&nbsp;handle<\/a><\/li>\n<li><a href=\"https:\/\/dailystoic.com\/just-keep-hammering-away\/\">Just keep hammering&nbsp;away<\/a><\/li>\n<li><a href=\"https:\/\/www.reddit.com\/r\/Stoicism\/comments\/lv6gma\/you_can_dance_in_the_rain_or_sulk_in_the_rain_it\/\"><span class=\"dquo\">&#8220;<\/span>You can dance in the rain or sulk in the rain, it will rain regardless&#8221;<\/a> \u2014 and its companion: &#8220;If you do not find joy in the snow, you will have less joy but the same amount of&nbsp;snow&#8221;<\/li>\n<li><a href=\"https:\/\/dailystoic.com\/you-must-train-the-coward-inside-you\/\">You must train the coward inside&nbsp;you<\/a><\/li>\n<li><a href=\"https:\/\/www.vox.com\/2020\/4\/7\/21209628\/coronavirus-pandemic-guilt-buddhism-second-arrow\">Feeling pandemic guilt? Buddhism&#8217;s &#8220;second arrow&#8221; teaching might&nbsp;help<\/a><\/li>\n<li><a href=\"https:\/\/en.wikipedia.org\/wiki\/Wabi-sabi\">Wabi-sabi<\/a> \u2014 the beauty of&nbsp;imperfection<\/li>\n<li><a href=\"https:\/\/www.wyrtig.com\/GardenOfLore\/WyrdTheRoleOfFate.htm\">Wyrd: The Role of Fate<\/a>: &#8220;since a man may not himself avert his destiny, he should therefore suffer it&nbsp;well&#8221;<\/li>\n<\/ul>\n<p>This isn&#8217;t casual browsing. This is someone assembling a philosophical survival kit. The <a href=\"https:\/\/www.bostonglobe.com\/2025\/07\/03\/sports\/boston-celtics-joe-mazzulla-summer-league\/\">Mazzulla quote<\/a> you pulled \u2014 about being &#8220;happily miserable&#8221; in the space between success and failure \u2014 reads like a mission&nbsp;statement.<\/p>\n<h3>3. Empathy is the point, not the&nbsp;nice-to-have<\/h3>\n<p>From <a href=\"https:\/\/www.newyorker.com\/tech\/annals-of-technology\/silicon-valley-has-an-empathy-vacuum\">Silicon Valley Has an Empathy Vacuum<\/a> (2016) to <a href=\"https:\/\/neonliterary.substack.com\/p\/come-sit-with-me-in-the-empty-theater\">&#8220;run toward empathy like never before&#8221;<\/a> (2026), this thread runs through almost&nbsp;everything:<\/p>\n<ul>\n<li>The <a href=\"https:\/\/twitter.com\/CelestePewter\">&#8220;two meanings of respect&#8221;<\/a> bookmark (2020) \u2014 people in power meaning &#8220;treat me as an authority&#8221; vs. marginalized people meaning &#8220;treat me as a&nbsp;person&#8221;<\/li>\n<li><a href=\"http:\/\/inpraiseofargument.squarespace.com\/teach-a-kid-to-argue\/\">Teach a Kid to Argue<\/a> (2016) \u2014 tagged&nbsp;&#8220;loved&#8221;<\/li>\n<li><a href=\"https:\/\/www.poetryfoundation.org\/poems\/48729\/gate-a-4\">Gate A-4<\/a> by Naomi Shihab Nye \u2014 human connection with strangers in an&nbsp;airport<\/li>\n<li><a href=\"https:\/\/neonliterary.substack.com\/p\/come-sit-with-me-in-the-empty-theater\"><span class=\"dquo\">&#8220;<\/span>We are here to be together \u2014 in community, in real life&#8221;<\/a>&nbsp;(2026)<\/li>\n<li>Mariame Kaba&#8217;s <a href=\"https:\/\/towardfreedom.org\/story\/hope-is-a-discipline-2\/\">&#8220;hope is a discipline&#8221;<\/a> \u2014 choosing to trust people as a daily&nbsp;practice<\/li>\n<\/ul>\n<p>Empathy here isn&#8217;t a soft skill. It&#8217;s <em>the<\/em> skill. The structural&nbsp;argument.<\/p>\n<h3>4. Suspicion of systems that claim to be&nbsp;neutral<\/h3>\n<p>A quiet but persistent&nbsp;current:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.schneier.com\/blog\/archives\/2006\/12\/the_death_of_ep.html\">Schneier on the death of ephemeral conversation<\/a>&nbsp;(2006)<\/li>\n<li><a href=\"https:\/\/idlewords.com\/talks\/haunted_by_data.htm\">Haunted by Data<\/a> (2015) \u2014 data collection as nuclear&nbsp;waste<\/li>\n<li><a href=\"https:\/\/reallifemag.com\/ambient-cruelty\/\">Ambient Cruelty<\/a> (2018) \u2014 Uber ratings as disguised&nbsp;power<\/li>\n<li><a href=\"https:\/\/www.newyorker.com\/news\/the-future-of-democracy\/how-big-tech-built-the-iron-cage\">How Big Tech Built the Iron Cage<\/a>&nbsp;(2019)<\/li>\n<li><a href=\"https:\/\/thenib.com\/piled-on\/\">Piled On<\/a> (2022) \u2014 internet mob&nbsp;dynamics<\/li>\n<li><a href=\"https:\/\/www.raptitude.com\/2021\/03\/you-dont-need-to-be-so-reachable\/\">You Don&#8217;t Need To Be So Reachable<\/a>&nbsp;(2021)<\/li>\n<\/ul>\n<p>Twenty years of tracking how technology creates asymmetric power while pretending to be a level playing&nbsp;field.<\/p>\n<h3>5. Poetry as load-bearing&nbsp;structure<\/h3>\n<p>This one surprised me. The poems aren&#8217;t decoration \u2014 they cluster around a very specific emotional&nbsp;register:<\/p>\n<ul>\n<li>Marge Piercy, <a href=\"https:\/\/www.poetryfoundation.org\/poems\/57673\/to-be-of-use\">To be of use<\/a> \u2014 the dignity of hard, purposeful&nbsp;labor<\/li>\n<li>Marie Howe, <a href=\"https:\/\/www.poetryfoundation.org\/poems\/48158\/what-the-living-do\">What the Living Do<\/a> \u2014 grief and daily life coexisting (tagged&nbsp;&#8220;loved&#8221;)<\/li>\n<li>Adam Zagajewski, <a href=\"https:\/\/www.poetryfoundation.org\/poems\/57858\/try-to-praise-the-mutilated-world\">Try to Praise the Mutilated World<\/a> \u2014 beauty despite&nbsp;damage<\/li>\n<li>Longfellow, <a href=\"https:\/\/www.poetryfoundation.org\/poems\/44644\/a-psalm-of-life\">A Psalm of Life<\/a> \u2014 &#8220;Learn to labor and to&nbsp;wait&#8221;<\/li>\n<li>Naomi Shihab Nye, <a href=\"https:\/\/www.poetryfoundation.org\/poems\/48729\/gate-a-4\">Gate A-4<\/a> \u2014 radical kindness between&nbsp;strangers<\/li>\n<\/ul>\n<p>These aren&#8217;t escapist poems. They&#8217;re all about <em>doing the hard thing anyway<\/em>. Labor, grief, praise in the face of destruction, patience. They reinforce the Stoic toolkit but with emotional depth the philosophy essays can&#8217;t quite&nbsp;reach.<\/p>\n<h2>The Evolution (What&nbsp;Changed)<\/h2>\n<p><strong>Politics went structural.<\/strong> Early political bookmarks (2008, <a href=\"https:\/\/www.antipope.org\/charlie\/blog-static\/2008\/01\/common-sense-alert.html\">Charlie Stross on environmentalism<\/a>) are about common sense. By 2019-2026, it&#8217;s systemic analysis: <a href=\"https:\/\/iwasthinkingtheotherday.substack.com\/p\/i-was-thinking-the-other-day-833\">&#8220;You cannot dismantle a system by making yourself useful to it&#8221;<\/a>, <a href=\"https:\/\/americanaffairsjournal.org\/2019\/11\/the-real-class-war\/\">The Real Class War<\/a>, <a href=\"https:\/\/www.opendemocracy.net\/en\/oureconomy\/the-rise-of-fascism-the-role-of-central-bankers\/\">the role of central bankers in fascism<\/a>, <a href=\"https:\/\/www.newyorker.com\/magazine\/2019\/11\/04\/the-philosopher-redefining-equality\">Elizabeth Anderson redefining equality<\/a>. The anger got more informed and more&nbsp;precise.<\/p>\n<p><strong>Management thinking went philosophical.<\/strong> 2007-2008: <a href=\"https:\/\/medium.com\/@jberk\/billy-martins-technique-for-managing-his-manager-1c8e3a6b4e0a\">Billy Martin managing his manager<\/a>, <a href=\"https:\/\/randsinrepose.com\/archives\/the-laptop-herring\/\">The Laptop Herring<\/a> (tactical meeting advice). 2017-2024: <a href=\"https:\/\/www.issendai.com\/psychology\/sick-systems.html\">Sick Systems<\/a> (how organizations trap people through intermittent rewards), <a href=\"https:\/\/egoless.engineering\/\">Egoless Engineering<\/a>, <a href=\"https:\/\/www.jofreeman.com\/joreen\/tyranny.htm\">The Tyranny of Structurelessness<\/a>. The shift: from &#8220;how to survive meetings&#8221; to &#8220;why do organizations become&nbsp;abusive.&#8221;<\/p>\n<p><strong>The internet went from exciting to haunted.<\/strong> 2005-2007: Web 2.0, Clay Shirky on love, <a href=\"https:\/\/www.well.com\/\">metadata taxonomy discussions on The <span class=\"caps\">WELL<\/span><\/a>. 2015-2026: <a href=\"https:\/\/idlewords.com\/talks\/haunted_by_data.htm\">data as nuclear waste<\/a>, <a href=\"https:\/\/www.newyorker.com\/news\/the-future-of-democracy\/how-big-tech-built-the-iron-cage\">the iron cage<\/a>, <a href=\"https:\/\/reallifemag.com\/ambient-cruelty\/\">ambient cruelty<\/a>, <a href=\"https:\/\/www.lrb.co.uk\/the-paper\/v41\/n04\/patricia-lockwood\/the-communal-mind\">Patricia Lockwood on the communal mind<\/a>. Watching the thing you were excited about become the thing you warn&nbsp;about.<\/p>\n<h2>What Aged&nbsp;Ungracefully<\/h2>\n<p><strong>Warren Ellis<\/strong> (bookmarked <a href=\"https:\/\/orbitaloperations.cmail20.com\/t\/ViewEmail\/d\/9044468FCC9DEE51\/80E4B51B911ADF0BD9767B6002735221\">2016<\/a>, <a href=\"https:\/\/warrenellis.ltd\/jot\/little-hours-from-an-old-life\/\">2019<\/a>) \u2014 the abuse allegations that surfaced in 2020 cast a shadow over those dispatches. The IoT piece is probably fine on its merits, but the personal brand is complicated&nbsp;now.<\/p>\n<p><strong>The Web 2.0 era optimism<\/strong> \u2014 &#8220;Agile Web 2.0 Development&#8221; (2005), Clay Shirky on internet love (2007). These feel like dispatches from a different planet given where the collection ends&nbsp;up.<\/p>\n<p><strong>The freelancing\/hustle bookmarks<\/strong> (2016 <span class=\"caps\">HN<\/span> threads about finding gigs) \u2014 these feel very mid-2010s and slightly at odds with the collection&#8217;s broader suspicion of optimization&nbsp;culture.<\/p>\n<h2>The&nbsp;Synthesis<\/h2>\n<p>If 151 bookmarks across 21 years distill into a single&nbsp;worldview:<\/p>\n<p><strong>Do unglamorous work with care, in community with others, while maintaining clear-eyed skepticism about the systems you operate within.<\/strong> Cleverness is a trap \u2014 in code, in politics, in life. Hope requires daily practice rather than passive optimism. Empathy is structural rather than sentimental. The right response to a broken world is not cynicism but disciplined, patient labor \u2014 &#8220;learn to labor and to&nbsp;wait.&#8221;<\/p>\n<p>The <a href=\"https:\/\/newrepublic.com\/article\/191212\/generation-x-lessons-second-trump-era\">Gen X description<\/a> bookmarked in 2026 nails it: &#8220;It is not apathy. It is not despair. It is the insistence that the world should be held to a higher standard than it ever seems willing to&nbsp;meet.&#8221;<\/p>\n<hr>\n<p><em>Written by Claude (Opus 4.6), after being handed a Pinboard export and asked &#8220;what do you think?&#8221; Analysis based on 151 bookmarks tagged &#8220;whatithink&#8221; from 2005-2026, of which 113 were still alive at the time of&nbsp;writing.<\/em><\/p>\n<hr>\n<div class=\"pelican-callout pelican-callout-tip\">\n<div class=\"pelican-callout-title\"><img src=\"https:\/\/unpkg.com\/lucide-static@0.483.0\/icons\/flame.svg\" class=\"pelican-callout-icon\" alt=\"tip\" width=\"18\" height=\"18\"> Tip<\/div>\n<div class=\"pelican-callout-body\">\n<p>Upon proof-reading, I am slightly disappointed. When claude started to write\nthis up, &#8220;he&#8221; immediately grabbed the <a href=\"\/my-voice.html\">My Voice<\/a> skill and I\nhad to stop and ask to simply cut and paste what was there after linking the\nurls. Didn&#8217;t quite happen that way and I&#8217;ve had to go back and try to swap a\nbunch of cases of &#8220;I&#8221; and &#8220;you&#8221; around. He also stripped my <a href=\"https:\/\/www.tomsguide.com\/ai\/i-use-the-unicorn-prompt-with-every-chatbot-it-instantly-fixes-the-worst-ai-problem\">unicorn prompt<\/a>,\n&#8220;Big Lad&#8221; from the text. And if you think that name is dumb, you should see what\nmy work machine calls&nbsp;me.<\/p>\n\n<\/div>\n<\/div>\n<p><img src=\"\/images\/posts\/1205136.jpg\" alt=\"Had to tell him to strip it from all docs and code comments\"><\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"whatithink"}},{"@attributes":{"term":"pinboard"}},{"@attributes":{"term":"ai"}},{"@attributes":{"term":"vibecoding"}}]},{"title":"What is Good?\u00a02006-03-29","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/wig-26329.html","rel":"alternate"}},"published":"2026-03-29T08:07:06-04:00","updated":"2026-03-29T08:07:06-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2026-03-29:\/wig-26329.html","summary":"<h1>What is Good, March 2026&nbsp;v2<\/h1>\n<blockquote>\n<p><span class=\"dquo\">&#8220;<\/span>What is good, Phaedrus, and what is not&nbsp;good?&#8221;<\/p>\n<\/blockquote>\n<h2>Good in the last&nbsp;week<\/h2>\n<ul>\n<li>Fresh-ground cinammon. Finally nailed my colors to the mast on this and threw\n  out the ancient McCormick-or-whomever spice container we have had for years.\n  Made sure to sniff the contents \u2026<\/li><\/ul>","content":"<h1>What is Good, March 2026&nbsp;v2<\/h1>\n<blockquote>\n<p><span class=\"dquo\">&#8220;<\/span>What is good, Phaedrus, and what is not&nbsp;good?&#8221;<\/p>\n<\/blockquote>\n<h2>Good in the last&nbsp;week<\/h2>\n<ul>\n<li>Fresh-ground cinammon. Finally nailed my colors to the mast on this and threw\n  out the ancient McCormick-or-whomever spice container we have had for years.\n  Made sure to sniff the contents first to give myself a fuller sense of superiority.\n  Cinammon becomes my third spice\/ seasoning to join this prestiguous group,\n  founded by fennel (a bit in a mortar and pestle added to any Italian red-sauce\n  dish is great <span class=\"caps\">IMO<\/span>) and nutmeg. I use nutmeg like 6 or 7 times a year, so it\n  was no great sacrifice to microplane it as needed. If I really wanted to\n  role hispter-hard, I suppose I&#8217;d get the unhusked berries and then I could\n  do mace by hand too, but who the hell uses mace more than once a decade?\n  <span class=\"caps\">OTHER<\/span> <span class=\"caps\">THAN<\/span> <span class=\"caps\">COPS<\/span> <span class=\"caps\">AMIRITE<\/span>?<\/li>\n<li>Using <span class=\"caps\">AI<\/span> for the purposes God intended. Mainly as a hype man\/ father confessor\n  for tasks I can probably do but am not confident in. Changed out a 30\/ 50\n  well pump pressure switch last weekend which is a lovely combo of both electric\n  and plumbing work and a bit high stakes (given the house would be without\n  water if it didn&#8217;t get finished). Went swimmingly, in the metaphoric sense\n  only, and hopefully has resolved the wild electric bills we have been&nbsp;seeing.<\/li>\n<li>The wild passion of Tyler Childers&#8217; <em>Way of the Triune God<\/em>. Fantastic wake\n  up song, especially on a Sunday where it could bridge the eternal question\n  &#8220;Hymns or&nbsp;Hangovers?&#8221;<\/li>\n<\/ul>\n<iframe width=\"800\" height=\"450\" src=\"https:\/\/www.youtube.com\/embed\/dONVNKR8yeM?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen title=\"Tyler Childers - Way of the Triune God (Live From Red Rocks)\"><\/iframe>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"wig"}}]},{"title":"Finding My\u00a0Voice","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/my-voice.html","rel":"alternate"}},"published":"2026-03-21T00:00:00-04:00","updated":"2026-03-21T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2026-03-21:\/my-voice.html","summary":"<h1>Finding My&nbsp;Voice<\/h1>\n<script type=\"text\/javascript\" async src=\"https:\/\/tenor.com\/embed.js\"><\/script>\n\n<p>For &#8230; reasons, I fed Claude a bunch of my Internet posting history. In\nretrospect, much of the worst of&nbsp;it<\/p>\n<ul>\n<li>Metafilter comments (not so&nbsp;bad)<\/li>\n<li>Reddit archive (not&nbsp;great)<\/li>\n<li>Twitter archive (very not&nbsp;great)<\/li>\n<\/ul>\n<p>I wanted to see how well it could match my overworked, purple prose \u2026<\/p>","content":"<h1>Finding My&nbsp;Voice<\/h1>\n<script type=\"text\/javascript\" async src=\"https:\/\/tenor.com\/embed.js\"><\/script>\n\n<p>For &#8230; reasons, I fed Claude a bunch of my Internet posting history. In\nretrospect, much of the worst of&nbsp;it<\/p>\n<ul>\n<li>Metafilter comments (not so&nbsp;bad)<\/li>\n<li>Reddit archive (not&nbsp;great)<\/li>\n<li>Twitter archive (very not&nbsp;great)<\/li>\n<\/ul>\n<p>I wanted to see how well it could match my overworked, purple prose style.\nDon&#8217;t think I paved any new ground or made something useful outside of one\nor two well-defined tasks, but the result was&nbsp;illuminating.<\/p>\n<blockquote>\n<p>This voice favors long, clause-heavy sentences that unspool conversationally with parenthetical asides, punctuated by sharp short sentences or fragments for comedic or emphatic&nbsp;effect.<\/p>\n<\/blockquote>\n<div class=\"tenor-gif-embed\" data-postid=\"19452872\" data-share-method=\"host\" data-aspect-ratio=\"1.77778\" data-width=\"100%\"><a href=\"https:\/\/tenor.com\/view\/world-of-chaldea-chaldea-marzahn-sarva-akkadian-gif-19452872\">World Of Chaldea Chaldea <span class=\"caps\">GIF<\/span><\/a>from <a href=\"https:\/\/tenor.com\/search\/world+of+chaldea-gifs\">World Of Chaldea GIFs<\/a><\/div>\n\n<blockquote>\n<p>Literary and historical allusions dropped casually without&nbsp;explanation<\/p>\n<\/blockquote>\n<div class=\"tenor-gif-embed\" data-postid=\"8311650983784019756\" data-share-method=\"host\" data-aspect-ratio=\"1\" data-width=\"100%\"><a href=\"https:\/\/tenor.com\/view\/could%27ve-found-a-less-hurtful-way-to-say-it-but-okay-roland-frasier-harsh-but-fair-gif-8311650983784019756\">Could&#39;Ve Found A Less Hurtful Way To Say It But Okay Roland <span class=\"caps\">GIF<\/span><\/a>from <a href=\"https:\/\/tenor.com\/search\/could%27ve+found+a+less+hurtful+way+to+say+it+but+okay-gifs\">Could&#39;Ve Found A Less Hurtful Way To Say It But Okay GIFs<\/a><\/div>\n\n<blockquote>\n<p>Music as identity marker and recurring passion &#8230; Boston sports tribalism. Hedges with qualifiers only when genuinely uncertain, not as social&nbsp;lubrication<\/p>\n<\/blockquote>\n<div class=\"tenor-gif-embed\" data-postid=\"22243167\" data-share-method=\"host\" data-aspect-ratio=\"1\" data-width=\"100%\"><a href=\"https:\/\/tenor.com\/view\/the-chosen-james-john-bad-attitude-sound-bad-gif-22243167\">The Chosen James <span class=\"caps\">GIF<\/span><\/a>from <a href=\"https:\/\/tenor.com\/search\/the+chosen-gifs\">The Chosen GIFs<\/a><\/div>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"blogging"}},{"@attributes":{"term":"vibecoding"}},{"@attributes":{"term":"badideas"}}]},{"title":"New Pelican Plugin: Obsidian-Style\u00a0Callouts","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/pelican-obsidian-callouts.html","rel":"alternate"}},"published":"2026-03-21T00:00:00-04:00","updated":"2026-03-21T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2026-03-21:\/pelican-obsidian-callouts.html","summary":"<h1>New Pelican Plugin: Obsidian-Style&nbsp;Callouts<\/h1>\n<div class=\"pelican-callout pelican-callout-caution\">\n<div class=\"pelican-callout-title\"><img src=\"https:\/\/unpkg.com\/lucide-static@0.483.0\/icons\/octagon-alert.svg\" class=\"pelican-callout-icon\" alt=\"caution\" width=\"18\" height=\"18\"> Vibe-Coded Slop<\/div>\n<div class=\"pelican-callout-body\">\n<p>It should be noted, per the anti-clanker movement, there was little to no thought\ninvolved in this process. I had learned to use <a href=\"https:\/\/obsidian.md\/help\/callouts\">Obsidian callouts<\/a>,\nfound I liked them and wanted to use them&nbsp;here.<\/p>\n\n<\/div>\n<\/div>\n<p>I write all my notes and drafts in \u2026<\/p>","content":"<h1>New Pelican Plugin: Obsidian-Style&nbsp;Callouts<\/h1>\n<div class=\"pelican-callout pelican-callout-caution\">\n<div class=\"pelican-callout-title\"><img src=\"https:\/\/unpkg.com\/lucide-static@0.483.0\/icons\/octagon-alert.svg\" class=\"pelican-callout-icon\" alt=\"caution\" width=\"18\" height=\"18\"> Vibe-Coded Slop<\/div>\n<div class=\"pelican-callout-body\">\n<p>It should be noted, per the anti-clanker movement, there was little to no thought\ninvolved in this process. I had learned to use <a href=\"https:\/\/obsidian.md\/help\/callouts\">Obsidian callouts<\/a>,\nfound I liked them and wanted to use them&nbsp;here.<\/p>\n\n<\/div>\n<\/div>\n<p>I write all my notes and drafts in <a href=\"https:\/\/obsidian.md\/\">Obsidian<\/a> these days\nand one of the things I like about it is the callout syntax, which lets you drop\nlittle admonition boxes into your notes&nbsp;with <code>&gt; [!note]<\/code> or <code>&gt; [!warning]<\/code> or\nwhatever. They&#8217;re genuinely useful for flagging things I want to remember without\nburying them in prose. The problem is Pelican doesn&#8217;t know what to do with them;\nthey just render as regular blockquotes and you lose the whole&nbsp;point.<\/p>\n<p>So I built <a href=\"https:\/\/github.com\/tclancy\/pelican-obsidian-callouts\">pelican-obsidian-callouts<\/a>,\na plugin that converts the Obsidian callout syntax into proper styled <span class=\"caps\">HTML<\/span> with\nicons and everything. It supports all 14 of the standard Obsidian callout types\n(note, tip, warning, danger, etc.) plus foldable variants where you can collapse\ncontent with&nbsp;a <code>+<\/code> or <code>-<\/code> after the type. Custom titles work too. Basically if\nyou write callouts in Obsidian and publish with Pelican, this does what you&#8217;d\nexpect without you having to think about it, which is all I really&nbsp;wanted.<\/p>\n<p>The interesting part of how it happened: I started with a local plugin jammed\ndirectly into this site&#8217;s codebase because that&#8217;s the fastest way to see if an\nidea is even worth pursuing. Claude and I iterated on it over maybe a week \u2014\ngot the regex parsing working, styled the <span class=\"caps\">CSS<\/span> for all 15 types (there are 14\ndistinct ones&nbsp;plus <code>quote<\/code> which aliases&nbsp;to <code>cite<\/code>), added the&nbsp;foldable\n<code>&lt;details&gt;<\/code>\/<code>&lt;summary&gt;<\/code> behavior, and debugged custom title rendering. Once it\nactually worked, I opened <a href=\"https:\/\/github.com\/tclancy\/pelicantpc\/issues\/6\">an issue<\/a>\nto extract it into a proper standalone package because leaving it inline felt\nlike the kind of thing that would rot quietly and then bite me six months later\nwhen I inevitably forgot how it&nbsp;worked.<\/p>\n<p>The extraction itself was the kind of task that vibe coding handles well: it&#8217;s\nnot creative work, it&#8217;s moving code from point A to point B while adding the\nboilerplate a proper Python package needs (pyproject.toml, test suite, <span class=\"caps\">CI<\/span>, the\nwhole song and dance). The actual plugin is a post-processor \u2014 it runs on the\nrendered <span class=\"caps\">HTML<\/span> rather than intercepting the Markdown pipeline, which means it\ndoesn&#8217;t care what Markdown parser you&#8217;re using. That was a deliberate choice\nbecause I didn&#8217;t want to be fighting with whatever extension system the parser\ndu jour has going on. Find blockquotes that match the pattern, replace them\nwith semantic divs, inject one small script per page for the fold toggles,&nbsp;done.<\/p>\n<p>The icons come from <a href=\"https:\/\/lucide.dev\/\">Lucide<\/a> via their static <span class=\"caps\">CDN<\/span>, so there&#8217;s\nno JavaScript framework dependency for what amounts to a few SVGs. Each callout\ntype gets its own icon and accent color through <span class=\"caps\">CSS<\/span> classes&nbsp;like\n<code>.pelican-callout-warning<\/code>, which means you can restyle them however you want\nwithout touching the plugin. Unknown callout types degrade gracefully back to\nregular blockquotes, which is the right thing to do because I don&#8217;t want my\npublishing pipeline to explode because I&nbsp;typo&#8217;d <code>&gt; [!nope]<\/code> in a draft at&nbsp;midnight.<\/p>\n<div class=\"pelican-callout pelican-callout-info\">\n<div class=\"pelican-callout-title\"><img src=\"https:\/\/unpkg.com\/lucide-static@0.483.0\/icons\/info.svg\" class=\"pelican-callout-icon\" alt=\"info\" width=\"18\" height=\"18\"> Oh one other thing<\/div>\n<div class=\"pelican-callout-body\">\n<p>I didn&#8217;t write this post either. For giggles, I fed Claude a bunch of my\nwriting and extracted a voice skill for screwing around&nbsp;with.<\/p>\n\n<\/div>\n<\/div>\n<p>It&#8217;s <a href=\"https:\/\/github.com\/tclancy\/pelican-obsidian-callouts\">on GitHub<\/a> if you\nwant it.&nbsp;Uses <code>uv<\/code> for dependency management because I&#8217;m not an animal. Not on\nPyPI yet because I wanted to live with it a bit longer before inflicting it on\nanyone who&nbsp;might <code>pip install<\/code> it without reading the source first, but that&#8217;s\nprobably coming once I&#8217;m confident I haven&#8217;t missed something&nbsp;embarrassing.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"blogging"}},{"@attributes":{"term":"vibecoding"}},{"@attributes":{"term":"pelican"}},{"@attributes":{"term":"python"}},{"@attributes":{"term":"obsidian"}}]},{"title":"Harold and George Destroy the\u00a0World!","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/harold-and-george.html","rel":"alternate"}},"published":"2026-03-15T00:00:00-04:00","updated":"2026-03-15T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2026-03-15:\/harold-and-george.html","summary":"<h1>Harold and George Destroy the&nbsp;World!<\/h1>\n<p>I have been thinking a lot lately about these two&nbsp;fellows.<\/p>\n<p><img src=\"\/images\/posts\/harold-george.jpeg\" alt=\"Two mischievous boys Harold and George from the Captain Underpants series, standing side by side in a vibrant comic book style school hallway, grinning playfully with arms crossed.\" \/><\/p>\n<p>If you are not lucky enough to know them already, those are Harold and George\nfrom the <em>Captain Underpants<\/em> series of books (among others). Two supposedly\nprototypical boys whose wonderful imaginations are in \u2026<\/p>","content":"<h1>Harold and George Destroy the&nbsp;World!<\/h1>\n<p>I have been thinking a lot lately about these two&nbsp;fellows.<\/p>\n<p><img src=\"\/images\/posts\/harold-george.jpeg\" alt=\"Two mischievous boys Harold and George from the Captain Underpants series, standing side by side in a vibrant comic book style school hallway, grinning playfully with arms crossed.\" \/><\/p>\n<p>If you are not lucky enough to know them already, those are Harold and George\nfrom the <em>Captain Underpants<\/em> series of books (among others). Two supposedly\nprototypical boys whose wonderful imaginations are in the process of being\ndestroyed by educators who do not recognize their gifts. Whether they will go\non to form a <a href=\"https:\/\/www.youtube.com\/watch?v=AGHmr1NyBTw\">quality death metal band<\/a>\nis left to the reader&#8217;s&nbsp;imagination.<\/p>\n<p>I first noticed their hand when I made a classic Tom mistake and tried to watch\ntwo movies back-to-back. I finished the very good <em>One Battle After Another<\/em>,\ntook a breath and started <em>Predator: Badlands<\/em>. I only lasted through most of\nthe first scene because it was so clearly their&nbsp;work.<\/p>\n<ul>\n<li>Harold: &#8220;It starts and there&#8217;s just one Predator and he&#8217;s climbing the biggest mountain&nbsp;ever!&#8221;<\/li>\n<li>George: &#8220;And then he gets to the top and there&#8217;s this crazy Predator&nbsp;castle!&#8221;<\/li>\n<li>Harold: &#8220;It&#8217;s all creepy and he goes in and there&#8217;s like &#8230; King Predator on a&nbsp;throne!&#8221;<\/li>\n<li>George: &#8220;And they get into a huge argument but we can&#8217;t understand because they&#8217;re talking&nbsp;Predator!&#8221;<\/li>\n<li>Together: &#8220;<span class=\"caps\">WITH<\/span> <span class=\"caps\">THAT<\/span> <span class=\"caps\">CREEPY<\/span> <span class=\"caps\">MOUTH<\/span> <span class=\"caps\">MOVEMENT<\/span> <span class=\"caps\">THING<\/span>!&#8221;<\/li>\n<li>Harold: &#8220;And they get into a&nbsp;fight!&#8221;<\/li>\n<li>George: &#8220;With&nbsp;swords!&#8221;<\/li>\n<li>Harold: &#8220;Really shiny big metal&nbsp;swords!&#8221;<\/li>\n<li>George: &#8220;But they also have like, red lasers and stuff on them and when they hit there&#8217;s&nbsp;sparks!&#8221;<\/li>\n<\/ul>\n<p>So I tapped out. Maybe it turns good. The reviews I&#8217;d read suggested it does and\nI should go back, fast-forward past that and try it again. Regardless, having\nrealized Harold <span class=\"amp\">&amp;<\/span> George are now responsible for a significant portion of our\nmedia, I&#8217;ve started to see their hand elsewhere. And if this war in Iran is not\nthe work of a bunch of boys who never turned ten, I will be goddamned. You almost\nhave to tip your cap to the amount of imagination these people have for doing bad\nthings. The <a href=\"https:\/\/fortune.com\/2026\/03\/12\/us-mint-drops-olive-branch-dime-peace-war\/\">new silver dollar no longer has an olive branch<\/a> (apparently it&#8217;s the dime and was already planned a long time back, but let&#8217;s not let that get in the way of a point).\nThe Department of Defense, so named because everyone has a right to defend themselves,\nis now the Department of War, so named because&nbsp;why?<\/p>\n<p>I&#8217;ve been thinking about how they&#8217;re going to leave us as <span class=\"caps\">US<\/span> citizens holding the\nbag for a lot of crap up to, and including, ruining a World Cup. Which led me to\nthinking about the IoC and <span class=\"caps\">FIFA<\/span> and how pretty much every country&#8217;s Football\nAssociation, regardless of the quality of government in the country at large, is\ncompletely corrupt. I knew the <span class=\"caps\">US<\/span> had arrived on the world football stage when our\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/2015_FIFA_corruption_case\">own <span class=\"caps\">FA<\/span> was blown up by the Attorney General<\/a>.\nOne of the people convicted was an unlikable <a href=\"https:\/\/en.wikipedia.org\/wiki\/Chuck_Blazer\">70 year old boy<\/a>\nwho lived in a kid&#8217;s idea of a cool apartment, a tasteless, gaudy expensive <span class=\"caps\">NYC<\/span>\napartment <em>and<\/em> the one next door to it, specifically for his cats. You will never\nguess whose tasteless, gaudy expensive <span class=\"caps\">NYC<\/span> apartment building it&nbsp;was.<\/p>\n<p>Anyway, here&#8217;s hoping Captain Underpants hears whatever sound it is&nbsp;soon.<\/p>\n<p><span class=\"caps\">EDIT<\/span>: Somehow this made it to the top of Hacker News, which I think proves the point self-referentially. If the best the best and brightest can do is argue about this drivel, what hope do we&nbsp;have?<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"politics"}},{"@attributes":{"term":"movies"}},{"@attributes":{"term":"art"}}]},{"title":"What is Good?\u00a02006-03-10","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/wig-26310.html","rel":"alternate"}},"published":"2026-03-10T20:29:38-04:00","updated":"2026-03-10T20:29:38-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2026-03-10:\/wig-26310.html","summary":"<h1>What is Good, March 2026&nbsp;v2<\/h1>\n<blockquote>\n<p><span class=\"dquo\">&#8220;<\/span>What is good, Phaedrus, and what is not&nbsp;good?&#8221;<\/p>\n<\/blockquote>\n<h2>Good in the last&nbsp;week<\/h2>\n<ul>\n<li><a href=\"https:\/\/www.mutinyaftermidnight.com\/\">Mutiny After Midnight<\/a> - I know I \nmentioned it last time but it&#8217;s just so good. Between this and Sound <span class=\"amp\">&amp;<\/span> Fury, he&#8217;s\ncornered the market on Rolling Stones-style &#8216;70s \u2026<\/li><\/ul>","content":"<h1>What is Good, March 2026&nbsp;v2<\/h1>\n<blockquote>\n<p><span class=\"dquo\">&#8220;<\/span>What is good, Phaedrus, and what is not&nbsp;good?&#8221;<\/p>\n<\/blockquote>\n<h2>Good in the last&nbsp;week<\/h2>\n<ul>\n<li><a href=\"https:\/\/www.mutinyaftermidnight.com\/\">Mutiny After Midnight<\/a> - I know I \nmentioned it last time but it&#8217;s just so good. Between this and Sound <span class=\"amp\">&amp;<\/span> Fury, he&#8217;s\ncornered the market on Rolling Stones-style &#8216;70s scuzz rock and I love&nbsp;that<\/li>\n<li><a href=\"https:\/\/hardcover.app\/welcome\">Hardcover<\/a>. Used to be the only way I knew GoodReads\ngot updated by some intern at Amazon was when my bookmarklets broke. Now there&#8217;s a\nplace in the same vein that seems like it will be a great community for at least a\nbit if it gains traction. Already built myself a <a href=\"https:\/\/gist.github.com\/tclancy\/6d1f6955c0d788febac296280e87c353\">userscript for finding books\nat my local&nbsp;library<\/a><\/li>\n<li><em>The Pitt<\/em>. I&#8217;m late to it and the 100th person to tell you, but still. Could be\nabout almost anything with the writers, acting talent and&nbsp;direction<\/li>\n<\/ul>\n<div class=\"pelican-callout pelican-callout-info\">\n<div class=\"pelican-callout-title\"><img src=\"https:\/\/unpkg.com\/lucide-static@0.483.0\/icons\/info.svg\" class=\"pelican-callout-icon\" alt=\"info\" width=\"18\" height=\"18\"> Obsidian-style callouts<\/div>\n<div class=\"pelican-callout-body\">\n<p>Assuming Claude told me the truth and built a Pelican plugin <a href=\"https:\/\/help.obsidian.md\/callouts\">to match Obsidian&#8217;s<\/a>\napproach to callouts, I have some styling to&nbsp;do<\/p>\n\n<\/div>\n<\/div>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"wig"}},{"@attributes":{"term":"music"}}]},{"title":"What is Good?\u00a02006-03-05","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/wig-2632.html","rel":"alternate"}},"published":"2026-03-05T20:29:38-05:00","updated":"2026-03-05T20:29:38-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2026-03-05:\/wig-2632.html","summary":"<h1>What is Good, March&nbsp;2026<\/h1>\n<blockquote>\n<p><span class=\"dquo\">&#8220;<\/span>What is good, Phaedrus, and what is not&nbsp;good?&#8221;<\/p>\n<\/blockquote>\n<h2>Good in the last&nbsp;week<\/h2>\n<ul>\n<li>Milk Street&#8217;s <a href=\"https:\/\/www.177milkstreet.com\/recipes\/tacos-arabes\">tacos&nbsp;arabes<\/a><\/li>\n<li><a href=\"https:\/\/hardcover.app\/books\/toms-crossing\"><em>Tom&#8217;s&nbsp;Crossing<\/em><\/a><\/li>\n<li>The fact Hardcover exists, a site to replace Goodreads, which has been dead since Amazon bought it only no one will tell it \u2026<\/li><\/ul>","content":"<h1>What is Good, March&nbsp;2026<\/h1>\n<blockquote>\n<p><span class=\"dquo\">&#8220;<\/span>What is good, Phaedrus, and what is not&nbsp;good?&#8221;<\/p>\n<\/blockquote>\n<h2>Good in the last&nbsp;week<\/h2>\n<ul>\n<li>Milk Street&#8217;s <a href=\"https:\/\/www.177milkstreet.com\/recipes\/tacos-arabes\">tacos&nbsp;arabes<\/a><\/li>\n<li><a href=\"https:\/\/hardcover.app\/books\/toms-crossing\"><em>Tom&#8217;s&nbsp;Crossing<\/em><\/a><\/li>\n<li>The fact Hardcover exists, a site to replace Goodreads, which has been dead since Amazon bought it only no one will tell it to lie&nbsp;down<\/li>\n<li><a href=\"https:\/\/www.calebleak.com\/posts\/dog-game\/\">Dogs telling <span class=\"caps\">AI<\/span> agents &#8230; something<\/a>, leading to the <span class=\"caps\">AI<\/span> agent hallucinating what that something might&nbsp;be<\/li>\n<li><a href=\"https:\/\/www.mutinyaftermidnight.com\/\">Mutiny After Midnight<\/a> - ordered it on <span class=\"caps\">CD<\/span> in case it really didn&#8217;t get leaked digitally (<a href=\"https:\/\/www.youtube.com\/watch?v=QKHGmFvzjJ4\">ah well<\/a>)<\/li>\n<li><a href=\"https:\/\/www.navidrome.org\/\">Navidrome<\/a> so I can stream&nbsp;^<\/li>\n<\/ul>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"wig"}}]},{"title":"The Effect of Gas on a\u00a0Marriage","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/marriage-and-gas.html","rel":"alternate"}},"published":"2026-02-12T00:00:00-05:00","updated":"2026-02-12T00:00:00-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2026-02-12:\/marriage-and-gas.html","summary":"<h1>The Effect of Gas on a&nbsp;Marriage<\/h1>\n<p>I was well into my 30s before I realized my mother&#8217;s aphorism on relationships,\n&#8220;Fits find each other&#8221; had a positive meaning. Because my mother and her sister\nboth taught in special education and because their side of the family is from \u2026<\/p>","content":"<h1>The Effect of Gas on a&nbsp;Marriage<\/h1>\n<p>I was well into my 30s before I realized my mother&#8217;s aphorism on relationships,\n&#8220;Fits find each other&#8221; had a positive meaning. Because my mother and her sister\nboth taught in special education and because their side of the family is from the\nschool of &#8220;If you have nothing nice to say and it&#8217;s funny, sit with us&#8221;, I&#8217;d\nassumed it only ever meant kids who couldn&#8217;t sit still wind up together later in\nlife. It was the &#8216;80s, &#8220;fits&#8221; would have been one of the nicer terms that was <em>au\ncourant<\/em> among educators back&nbsp;then.<\/p>\n<p>I mention this because my wife and I describe this pattern (which <a href=\"https:\/\/www.laphamsquarterly.org\/eros\/platos-other-half\">Plato phrased\ndifferently, but we all know what he meant<\/a>)\npretty perfectly. A marriage counsellor (thank you Will!) described the dynamic\nas &#8220;Your Dance&#8221;. Michelle is the outgoing, friendly person in charge of ensuring\nwe do things that actually make life worth living. I am the pragmatic, paranoid,\nhard-working Yankee puritan who bars the doors lest worse should befall us. Given\nthis dynamic, it means I often start a car which tells&nbsp;me, <code>Fuel low, would you\nlike to search for a nearby gas station?<\/code> The last time it happened, the Hyundai\nand I had seven miles together before things would have ended. I <em>dread<\/em> running\nout of gas. It&#8217;s happened maybe twice in a half century and neither time was my\nfault, but it drives me to distraction. I got the Hyundai to a station a couple\nmiles away with 0.2 gallons left to my&nbsp;name.<\/p>\n<p>Early on in my work as a developer, I decided, &#8220;There are no technological\nsolutions to social problems&#8221;. I still believe that, but there is also no solution\nto this problem. In theory, I could not fill the tank to teach a lesson, but\nmy daughter could be in tow at the time of the lesson and I would catch hell\nfrom both of them. And that&#8217;s assuming I could somehow endure the nearly\nphysical pain of knowing the car needed&nbsp;gas.<\/p>\n<p>So. Stopped at a light in front of the gas station this week, I remembered I&#8217;d\nplayed with a <a href=\"https:\/\/github.com\/Hacksore\/bluelinky\">GitHub repository<\/a> that\nlets you talk to the Hyundai\/ Kia BlueLink <span class=\"caps\">API<\/span> but lost interest when the problem\nI was sorting (automatically heating the car on winter mornings) solved itself\n(broken garage door got fixed). I turned the whole thing over to Claude, showed\nhim there was a Docker version of the repo he could steal from if needed and we\nbuilt a notification system for low fuel so I am less likely to be surprised in\nthe&nbsp;future.<\/p>\n<p>My fork <a href=\"https:\/\/github.com\/tclancy\/bluelinky\">is here<\/a>. It has some of the hallmarks\nof vibe-coded slop, but even those are things I am finding ok-<em>ish<\/em> in these\nprojects. It was a good fit for the approach as the <span class=\"caps\">API<\/span> represents a solid set\nof defined options, I wrote up a light spec and then used Plan mode to elicit\nquestions about things that were unclear and it was grunt work I <em>could<\/em> do but\nwould never get around to because it represents a Busman&#8217;s Holiday to be doing\nunfun, non-greenfield coding for something no one is paying me for. This time\naround the surprise was in how quickly we were done. It&#8217;s not a huge process\nbut I thought sending notifications would take more work. Again, here&#8217;s a place\nwhere <span class=\"caps\">AI<\/span> shines: there&#8217;s a ton of code and documentation in the wild about how\nto use any notification system of even medium popularity, so steal from that\nvia <span class=\"caps\">AI<\/span>. The vibe-coded slop is 95% a result of the fact sending <span class=\"caps\">SMS<\/span> messages\nprogrammatically got much harder (understandably given all the <span class=\"caps\">SMS<\/span> spam) since\nthe last time I needed to do it for work. It&#8217;s apparently ~$10-15 a month just\nfor the privilege of a number and the ability to send <span class=\"caps\">SMS<\/span> in the <span class=\"caps\">US<\/span> from it. I\ntried the &#8220;email your cellphone number at the carrier address&#8221; as a workaround\nbut it lasted for one message and one message&nbsp;only.<\/p>\n<p>That&#8217;s probably something worth calling out about my experience in vibe coding:\nbecause I have been doing this a long time, in a lot of languages for a lot of\ndifferent projects, some things come naturally as breathing. I worked in Django\n<em>a lot a lot<\/em> and came to appreciate the nature of pluggable backends. Suspecting\nnotifications might turn out to be a pain in the ass, plus the fact I did this\nwhen I rebuilt the notification system at a recent job using Knock, I made the\nnotifications pluggable because it&#8217;s a lot easier to develop with something\nspitting the notifications as logs in the console immediately than having to\nwait for a message to maybe show up in a dashboard seven levels deep in someone\nelse&#8217; site. So the commit history of my fork includes a bunch of aborted back-end\nattempts. I was tempted to keep them all for posterity but then I realized how\nwildly egotistical that&nbsp;sounded.<\/p>\n<p><img src=\"\/images\/posts\/gas-marriage.png\" alt=\"Screenshot of this all working!\"><\/p>\n<p>May you never have gas-related issues in your relationships&nbsp;again.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"bluelink"}},{"@attributes":{"term":"typescript"}},{"@attributes":{"term":"docker"}},{"@attributes":{"term":"vibecoding"}}]},{"title":"Automate MP4 to GIF","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/automate-mp4-to-gif.html","rel":"alternate"}},"published":"2026-01-18T00:00:00-05:00","updated":"2026-01-18T00:00:00-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2026-01-18:\/automate-mp4-to-gif.html","summary":"<h1>Converting <span class=\"caps\">MP4<\/span> to <span class=\"caps\">GIF<\/span><\/h1>\n<p>Do you, like me, often find yourself in internet arguments for no good reason\nand want to reply with a dead-perfect response <span class=\"caps\">GIF<\/span> so everyone will clap and\nlove you even more but the response you want is actually stored in your\nbookmarks in the superior \u2026<\/p>","content":"<h1>Converting <span class=\"caps\">MP4<\/span> to <span class=\"caps\">GIF<\/span><\/h1>\n<p>Do you, like me, often find yourself in internet arguments for no good reason\nand want to reply with a dead-perfect response <span class=\"caps\">GIF<\/span> so everyone will clap and\nlove you even more but the response you want is actually stored in your\nbookmarks in the superior and lower-bandwidth <span class=\"caps\">MP4<\/span> format? Fear no more!\nAssuming you&#8217;re nerdy enough to have <a href=\"https:\/\/www.ffmpeg.org\/\"><code>ffmpeg<\/code><\/a> on\nyour machine, here&#8217;s a bash command to automate the process. Just pass the\npath to your <span class=\"caps\">MP4<\/span> file as the first&nbsp;argument.<\/p>\n<div class=\"highlight\"><pre><span><\/span><code><span class=\"ch\">#!\/bin\/bash<\/span>\n\n<span class=\"c1\"># Check if input parameter is provided<\/span>\n<span class=\"k\">if<\/span><span class=\"w\"> <\/span><span class=\"o\">[<\/span><span class=\"w\"> <\/span><span class=\"nv\">$#<\/span><span class=\"w\"> <\/span>-eq<span class=\"w\"> <\/span><span class=\"m\">0<\/span><span class=\"w\"> <\/span><span class=\"o\">]<\/span><span class=\"p\">;<\/span><span class=\"w\"> <\/span><span class=\"k\">then<\/span>\n<span class=\"w\">    <\/span><span class=\"nb\">echo<\/span><span class=\"w\"> <\/span><span class=\"s2\">&quot;Usage: <\/span><span class=\"nv\">$0<\/span><span class=\"s2\"> &lt;input.mp4&gt;&quot;<\/span>\n<span class=\"w\">    <\/span><span class=\"nb\">exit<\/span><span class=\"w\"> <\/span><span class=\"m\">1<\/span>\n<span class=\"k\">fi<\/span>\n\n<span class=\"nv\">INPUT<\/span><span class=\"o\">=<\/span><span class=\"s2\">&quot;<\/span><span class=\"nv\">$1<\/span><span class=\"s2\">&quot;<\/span>\n<span class=\"nv\">OUTPUT<\/span><span class=\"o\">=<\/span><span class=\"s2\">&quot;<\/span><span class=\"si\">${<\/span><span class=\"nv\">INPUT<\/span><span class=\"p\">%.mp4<\/span><span class=\"si\">}<\/span><span class=\"s2\">.gif&quot;<\/span>\n\n<span class=\"c1\"># Check if input file exists<\/span>\n<span class=\"k\">if<\/span><span class=\"w\"> <\/span><span class=\"o\">[<\/span><span class=\"w\"> <\/span>!<span class=\"w\"> <\/span>-f<span class=\"w\"> <\/span><span class=\"s2\">&quot;<\/span><span class=\"nv\">$INPUT<\/span><span class=\"s2\">&quot;<\/span><span class=\"w\"> <\/span><span class=\"o\">]<\/span><span class=\"p\">;<\/span><span class=\"w\"> <\/span><span class=\"k\">then<\/span>\n<span class=\"w\">    <\/span><span class=\"nb\">echo<\/span><span class=\"w\"> <\/span><span class=\"s2\">&quot;Error: File &#39;<\/span><span class=\"nv\">$INPUT<\/span><span class=\"s2\">&#39; not found&quot;<\/span>\n<span class=\"w\">    <\/span><span class=\"nb\">exit<\/span><span class=\"w\"> <\/span><span class=\"m\">1<\/span>\n<span class=\"k\">fi<\/span>\n\n<span class=\"c1\"># Generate palette<\/span>\nffmpeg<span class=\"w\"> <\/span>-i<span class=\"w\"> <\/span><span class=\"s2\">&quot;<\/span><span class=\"nv\">$INPUT<\/span><span class=\"s2\">&quot;<\/span><span class=\"w\"> <\/span>-vf<span class=\"w\"> <\/span><span class=\"s2\">&quot;palettegen&quot;<\/span><span class=\"w\"> <\/span>palette.png\n\n<span class=\"c1\"># Create GIF using palette<\/span>\nffmpeg<span class=\"w\"> <\/span>-i<span class=\"w\"> <\/span><span class=\"s2\">&quot;<\/span><span class=\"nv\">$INPUT<\/span><span class=\"s2\">&quot;<\/span><span class=\"w\"> <\/span>-i<span class=\"w\"> <\/span>palette.png<span class=\"w\"> <\/span>-filter_complex<span class=\"w\"> <\/span><span class=\"s2\">&quot;paletteuse&quot;<\/span><span class=\"w\"> <\/span><span class=\"s2\">&quot;<\/span><span class=\"nv\">$OUTPUT<\/span><span class=\"s2\">&quot;<\/span>\n\n<span class=\"c1\"># Clean up<\/span>\nrm<span class=\"w\"> <\/span>-f<span class=\"w\"> <\/span>palette.png<span class=\"w\"> <\/span><span class=\"s2\">&quot;<\/span><span class=\"nv\">$INPUT<\/span><span class=\"s2\">&quot;<\/span>\n\n<span class=\"nb\">echo<\/span><span class=\"w\"> <\/span><span class=\"s2\">&quot;Conversion complete: <\/span><span class=\"nv\">$OUTPUT<\/span><span class=\"s2\">&quot;<\/span>\n<\/code><\/pre><\/div>\n\n<h2>Does It&nbsp;Work?<\/h2>\n<p>You bet it does, fella! Be forewarned the images will be&nbsp;huge.<\/p>\n<p><img alt=\"nocountry.gif\" src=\"\/images\/gifs\/nocountry.gif\"><\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"bash"}},{"@attributes":{"term":"gifs"}},{"@attributes":{"term":"whynot"}}]},{"title":"Printing from Python on a\u00a0Mac","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/printing-from-python-mac.html","rel":"alternate"}},"published":"2025-12-11T00:00:00-05:00","updated":"2025-12-11T00:00:00-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2025-12-11:\/printing-from-python-mac.html","summary":"<h1>Printing from Python on a&nbsp;Mac<\/h1>\n<p>I recently automated the download of one of my favorite cryptic crosswords,\nboth because I am nerdy and because it went behind an extravagantly high paywall.\nIn the process I decided I wanted Sunday mornings to be even more leisurely and\nmade the script \u2026<\/p>","content":"<h1>Printing from Python on a&nbsp;Mac<\/h1>\n<p>I recently automated the download of one of my favorite cryptic crosswords,\nboth because I am nerdy and because it went behind an extravagantly high paywall.\nIn the process I decided I wanted Sunday mornings to be even more leisurely and\nmade the script print the <span class=\"caps\">PDF<\/span> after downloading,&nbsp;thusly:<\/p>\n<div class=\"highlight\"><pre><span><\/span><code><span class=\"kn\">import<\/span> <span class=\"nn\">os<\/span>\n<span class=\"kn\">import<\/span> <span class=\"nn\">logging<\/span>\n<span class=\"kn\">import<\/span> <span class=\"nn\">sys<\/span>\n<span class=\"kn\">from<\/span> <span class=\"nn\">pathlib<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">Path<\/span>\n\n<span class=\"kn\">import<\/span> <span class=\"nn\">requests<\/span>\n\n<span class=\"n\">logger<\/span> <span class=\"o\">=<\/span> <span class=\"n\">logging<\/span><span class=\"o\">.<\/span><span class=\"n\">getLogger<\/span><span class=\"p\">(<\/span><span class=\"vm\">__name__<\/span><span class=\"p\">)<\/span>\n\n<span class=\"n\">PATH_TO_WRITE<\/span> <span class=\"o\">=<\/span> <span class=\"n\">Path<\/span><span class=\"p\">(<\/span><span class=\"s2\">&quot;\/your\/file\/location.pdf&quot;<\/span><span class=\"p\">)<\/span>\n<span class=\"c1\"># download stuff elided for brevity<\/span>\n\n<span class=\"k\">def<\/span> <span class=\"nf\">print_pdf_from_link<\/span><span class=\"p\">(<\/span><span class=\"n\">pdf_link<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span> <span class=\"o\">|<\/span> <span class=\"kc\">None<\/span><span class=\"p\">,<\/span> <span class=\"n\">write_to<\/span><span class=\"p\">:<\/span> <span class=\"n\">Path<\/span> <span class=\"o\">=<\/span> <span class=\"n\">PATH_TO_WRITE<\/span><span class=\"p\">):<\/span>\n    <span class=\"k\">if<\/span> <span class=\"ow\">not<\/span> <span class=\"n\">pdf_link<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">logger<\/span><span class=\"o\">.<\/span><span class=\"n\">error<\/span><span class=\"p\">(<\/span><span class=\"s2\">&quot;No PDF link provided, exiting&quot;<\/span><span class=\"p\">)<\/span>\n        <span class=\"n\">sys<\/span><span class=\"o\">.<\/span><span class=\"n\">exit<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">pdf_request<\/span> <span class=\"o\">=<\/span> <span class=\"n\">requests<\/span><span class=\"o\">.<\/span><span class=\"n\">get<\/span><span class=\"p\">(<\/span><span class=\"n\">pdf_link<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">with<\/span> <span class=\"nb\">open<\/span><span class=\"p\">(<\/span><span class=\"n\">write_to<\/span><span class=\"p\">,<\/span> <span class=\"s2\">&quot;wb&quot;<\/span><span class=\"p\">)<\/span> <span class=\"k\">as<\/span> <span class=\"n\">f<\/span><span class=\"p\">:<\/span>\n        <span class=\"n\">f<\/span><span class=\"o\">.<\/span><span class=\"n\">write<\/span><span class=\"p\">(<\/span><span class=\"n\">pdf_request<\/span><span class=\"o\">.<\/span><span class=\"n\">content<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">os<\/span><span class=\"o\">.<\/span><span class=\"n\">system<\/span><span class=\"p\">(<\/span><span class=\"sa\">f<\/span><span class=\"s2\">&quot;lpr -P Brother_MFC_L2750DW_series <\/span><span class=\"si\">{<\/span><span class=\"n\">write_to<\/span><span class=\"si\">}<\/span><span class=\"s2\">&quot;<\/span><span class=\"p\">)<\/span>\n    <span class=\"n\">write_to<\/span><span class=\"o\">.<\/span><span class=\"n\">unlink<\/span><span class=\"p\">()<\/span>\n    <span class=\"n\">write_to<\/span><span class=\"o\">.<\/span><span class=\"n\">with_suffix<\/span><span class=\"p\">(<\/span><span class=\"s2\">&quot;.ps&quot;<\/span><span class=\"p\">)<\/span><span class=\"o\">.<\/span><span class=\"n\">unlink<\/span><span class=\"p\">()<\/span>\n<\/code><\/pre><\/div>\n\n<p>The only trick is getting the name of the printer&nbsp;(<code>Brother_MFC_L2750DW_series<\/code> here) from your\nmachine. You can get that&nbsp;with <code>lpstat -p<\/code>. The weird side effect is you wind up with two files,\none with&nbsp;the <code>.ps<\/code> printer extension and one with&nbsp;the <code>.pdf<\/code> extension. Rather than figure out\nwhy, I am just stomping on it at the same time, which showed&nbsp;me <code>pathlib<\/code> has that neat&nbsp;little\n<code>with_suffix<\/code> method.<\/p>\n<p><span class=\"caps\">UPDATE<\/span> 02-02-26: You can scale the print job&nbsp;with <code>-o scaling=X<\/code> where <code>X<\/code> is a number between 1 and&nbsp;800.<\/p>\n<p><span class=\"caps\">UPDATE<\/span> 03-15-26: At some point I added a&nbsp;weekly <code>launchd<\/code> job that prints this all out for\nme at 5am on Sunday and that has been like having a butler. You should do&nbsp;that.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"python"}},{"@attributes":{"term":"coding"}},{"@attributes":{"term":"printing"}}]},{"title":"Music This Week\u00a011-02-2025","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/music-this-week-11-02-2025.html","rel":"alternate"}},"published":"2025-11-02T00:00:00-04:00","updated":"2025-11-02T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2025-11-02:\/music-this-week-11-02-2025.html","summary":"<h1>Music This&nbsp;Week<\/h1>\n<p>Didn&#8217;t expect to be back so soon, but I got busy doing something<sup>*<\/sup> this weekend and what I was listening to\nfinished and Spotify&#8217;s Recommended let me know The Beths have a new album out and it&#8217;s just as good as the last one \u2026<\/p>","content":"<h1>Music This&nbsp;Week<\/h1>\n<p>Didn&#8217;t expect to be back so soon, but I got busy doing something<sup>*<\/sup> this weekend and what I was listening to\nfinished and Spotify&#8217;s Recommended let me know The Beths have a new album out and it&#8217;s just as good as the last one (for the record, it was&nbsp;good).<\/p>\n<iframe data-testid=\"embed-iframe\" style=\"border-radius:12px\" src=\"https:\/\/open.spotify.com\/embed\/album\/5XbVk30ifqaiI6EiVVjA1p?utm_source=generator\" width=\"100%\" height=\"352\" frameBorder=\"0\" allowfullscreen=\"\" allow=\"autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture\" loading=\"lazy\"><\/iframe>\n\n<p>* I was unsuccessfully debugging a goddamn expensive Andersen door that&#8217;s been the bane of my existence since install. They have some really cool self-help app the customer support will walk you through. It uses fancy vision algos and stuff. And doesn&#8217;t do shit for&nbsp;me.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"music"}},{"@attributes":{"term":"mtw"}}]},{"title":"Music This Week\u00a010-25","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/music-this-week-10-25.html","rel":"alternate"}},"published":"2025-10-31T13:19:35-04:00","updated":"2025-10-31T13:19:35-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2025-10-31:\/music-this-week-10-25.html","summary":"<h1>Music This&nbsp;Week<\/h1>\n<p>Trying something new, here are a couple of things I&#8217;ve been playing on&nbsp;repeat.<\/p>\n<h2>Brian Dunne, <em>Clams&nbsp;Casino<\/em><\/h2>\n<p>Safely inside my Dad Rock, Springsteen-inspired category, I think I found this via Xgau&#8217;s Substack. The whole album is amazing and the previous one is great&nbsp;too \u2026<\/p>","content":"<h1>Music This&nbsp;Week<\/h1>\n<p>Trying something new, here are a couple of things I&#8217;ve been playing on&nbsp;repeat.<\/p>\n<h2>Brian Dunne, <em>Clams&nbsp;Casino<\/em><\/h2>\n<p>Safely inside my Dad Rock, Springsteen-inspired category, I think I found this via Xgau&#8217;s Substack. The whole album is amazing and the previous one is great&nbsp;too.<\/p>\n<iframe data-testid=\"embed-iframe\" style=\"border-radius:12px\" src=\"https:\/\/open.spotify.com\/embed\/album\/1dvcMA9vE2VjDxHQn7j5qR?utm_source=generator\" width=\"100%\" height=\"352\" frameBorder=\"0\" allowfullscreen=\"\" allow=\"autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture\" loading=\"lazy\"><\/iframe>\n\n<h2>Tunde Adebimpe, Thee Black&nbsp;Boltz<\/h2>\n<p>Absolutely amazing album from <em><span class=\"caps\">TV<\/span> on the Radio<\/em> singer. Has me revisiting them and his back catalog. Ignore the opening 36 second track unless you&#8217;re young enough not to be totally over those things since rap casettes in the&nbsp;&#8216;80s.<\/p>\n<iframe data-testid=\"embed-iframe\" style=\"border-radius:12px\" src=\"https:\/\/open.spotify.com\/embed\/album\/0MuAR8zcmZyGAwJcnkCpV1?utm_source=generator\" width=\"100%\" height=\"352\" frameBorder=\"0\" allowfullscreen=\"\" allow=\"autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture\" loading=\"lazy\"><\/iframe>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"music"}},{"@attributes":{"term":"mtw"}}]},{"title":"Autocomplete in Python Shell on\u00a0Windows","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/autocomplete-python-shell-windows.html","rel":"alternate"}},"published":"2017-01-20T13:19:35-05:00","updated":"2017-01-20T13:19:35-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2017-01-20:\/autocomplete-python-shell-windows.html","summary":"<h1>Autocomplete in Python Shell on&nbsp;Windows<\/h1>\n<p>Because I drive myself insane replicating this when I find I want autocomplete on Windows, here are the steps (as of January 2017&nbsp;anyway):<\/p>\n<ul>\n<li><code>pip install pyreadline<\/code><\/li>\n<li><code>pip install ipython[shell]<\/code><\/li>\n<\/ul>\n<p>Except right now step 2 fails when&nbsp;installing <code>scandir<\/code> so I grabbed it \u2026<\/p>","content":"<h1>Autocomplete in Python Shell on&nbsp;Windows<\/h1>\n<p>Because I drive myself insane replicating this when I find I want autocomplete on Windows, here are the steps (as of January 2017&nbsp;anyway):<\/p>\n<ul>\n<li><code>pip install pyreadline<\/code><\/li>\n<li><code>pip install ipython[shell]<\/code><\/li>\n<\/ul>\n<p>Except right now step 2 fails when&nbsp;installing <code>scandir<\/code> so I grabbed it <a href=\"http:\/\/www.lfd.uci.edu\/~gohlke\/pythonlibs\/#scandir\">here<\/a>, installed the .whl file via pip and then ran that second&nbsp;step.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"python"}},{"@attributes":{"term":"windows"}},{"@attributes":{"term":"frustration"}}]},{"title":"Dear Josie: On Weasel\u00a0Words","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/dear-josie-weasel-words.html","rel":"alternate"}},"published":"2016-10-21T13:16:34-04:00","updated":"2016-10-21T13:16:34-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2016-10-21:\/dear-josie-weasel-words.html","summary":"<h1>Dear Josie: On Weasel&nbsp;Words<\/h1>\n<p>Dear&nbsp;Josie,<\/p>\n<p>On the very off-chance I don&#8217;t get a chance to barrage you about this a thousand times, here&#8217;s a lesson on weasel words. Take a look&nbsp;at <\/p>\n<p><img alt=\"Mailer front\" src=\"\/images\/legacy\/kelly-front.jpg\"><\/p>\n<p>Always be suspicious when politicians or advertisers (if there&#8217;s still a difference) don \u2026<\/p>","content":"<h1>Dear Josie: On Weasel&nbsp;Words<\/h1>\n<p>Dear&nbsp;Josie,<\/p>\n<p>On the very off-chance I don&#8217;t get a chance to barrage you about this a thousand times, here&#8217;s a lesson on weasel words. Take a look&nbsp;at <\/p>\n<p><img alt=\"Mailer front\" src=\"\/images\/legacy\/kelly-front.jpg\"><\/p>\n<p>Always be suspicious when politicians or advertisers (if there&#8217;s still a difference) don&#8217;t say what they mean or aren&#8217;t exacting in their words. Consider &#8220;standing up for women&#8217;s health care&#8221; and &#8220;No woman should be denied access to health care&#8221;. What issue could this possibly be about? It can&#8217;t be about Universal Health Care: that applies to men and children in addition to adult women. The access issues about women&#8217;s health in 2016 are abortion in particular and whether the government funds Planned Parenthood in general and that&#8217;s essentially a proxy for the argument about abortion: while Planned Parenthood provides a number of services for women the political discourse makes it sound like a drive-thru for&nbsp;abortion. <\/p>\n<p>Freedom of choice is important not so much because everybody loves to have abortions but because it represents freedom from patriarchy and is arguably a necessity for gender equality. So talking about things like &#8220;women&#8217;s health care&#8221; instead of saying &#8220;I am for\/ against abortion access&#8221; is a clever lie to try to attract undecided voters. When in doubt, go with a trustworthy jerk over a clever liar. <em>Speaking of which<\/em> (which is a favorite phrase of yours right now because you can&#8217;t figure out when to use&nbsp;it):<\/p>\n<p><img alt=\"Mailer back\" src=\"\/images\/legacy\/kelly-back.jpg\"><\/p>\n<p><span class=\"dquo\">&#8220;<\/span>Access to over-the-counter birth control&#8221; doesn&#8217;t mean shit. I have access to Faberg\u00e9 eggs; all I need to do is stump up the tens of millions of dollars to buy one. &#8220;Access&#8221; is a wonderful weasel word. All it promises is the item in question won&#8217;t be rounded up and fired into space. But at least she&#8217;s for Planned Parenthood, right? &#8220;Funding for community health centers that provide women&#8217;s health care&#8221; is a long way away from &#8220;I support centers that provide abortion information or abortion access&#8221;. Those centers can be anything, including religious-based centers that do the opposite of what she&#8217;s trying to position herself as in this mailing to&nbsp;women.<\/p>\n<p>In short, down with people who won&#8217;t say what they mean and down with Kelly&nbsp;Ayotte.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"offtopic"}},{"@attributes":{"term":"josie"}}]},{"title":"Heat Oracle: Heat\u00a0Oracle","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/heat-oracle","rel":"alternate"}},"published":"2016-10-21T00:00:00-04:00","updated":"2016-10-21T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2016-10-21:\/heat-oracle","summary":"<h1>Heat Oracle: Heat&nbsp;Oracle<\/h1>\n<h2>2016-10-21<\/h2>\n<p><em>Internet of Things project for homeowners with heating&nbsp;oil<\/em><\/p>\n<p>Internet of Things project providing homeowners with better efficiency for oil&nbsp;heating<\/p>\n<ul>\n<li>Implemented a mobile-friendly responsive website&nbsp;design<\/li>\n<li>Integrated Stripe for payment&nbsp;processing<\/li>\n<li>Site is based on a <span class=\"caps\">REST<\/span> <span class=\"caps\">API<\/span> talking to vue.js&nbsp;components<\/li>\n<li>Twilio \u2026<\/li><\/ul>","content":"<h1>Heat Oracle: Heat&nbsp;Oracle<\/h1>\n<h2>2016-10-21<\/h2>\n<p><em>Internet of Things project for homeowners with heating&nbsp;oil<\/em><\/p>\n<p>Internet of Things project providing homeowners with better efficiency for oil&nbsp;heating<\/p>\n<ul>\n<li>Implemented a mobile-friendly responsive website&nbsp;design<\/li>\n<li>Integrated Stripe for payment&nbsp;processing<\/li>\n<li>Site is based on a <span class=\"caps\">REST<\/span> <span class=\"caps\">API<\/span> talking to vue.js&nbsp;components<\/li>\n<li>Twilio integration for <span class=\"caps\">SMS<\/span>&nbsp;alerts<\/li>\n<li>Aggregating our Postgres data into Redis for real-time&nbsp;performance<\/li>\n<li>Using Pandas and statsmodels for tank usage predictions based on tank data and Wunderground-provided weather&nbsp;information<\/li>\n<\/ul>\n<p><img src=\"\/images\/portfolio\/login.png\" alt=\"Login \" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/dashboard.png\" alt=\"Dashboard \" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/home.png\" alt=\"Homepage \" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"django"}},{"@attributes":{"term":"vue.js"}},{"@attributes":{"term":"redis"}},{"@attributes":{"term":"django-rest-framework"}}]},{"title":"Upgrading\u00a0Django","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/upgrading-django.html","rel":"alternate"}},"published":"2016-10-14T10:13:09-04:00","updated":"2016-10-14T10:13:09-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2016-10-14:\/upgrading-django.html","summary":"<h1>Upgrading&nbsp;Django<\/h1>\n<p>For the second time in a few years I&#8217;ve found myself doing a number of Django upgrades. It&#8217;s a good thing: I&#8217;m happy the framework I chose to base most of my work on when I went solo has stayed relevant. But this time I \u2026<\/p>","content":"<h1>Upgrading&nbsp;Django<\/h1>\n<p>For the second time in a few years I&#8217;ve found myself doing a number of Django upgrades. It&#8217;s a good thing: I&#8217;m happy the framework I chose to base most of my work on when I went solo has stayed relevant. But this time I wanted to document some of the pain points to make things easier on anyone else going through the&nbsp;same.<\/p>\n<p>First off, this round of updates has been a lot easier than the first: back then I was the point of contact for <a href=\"https:\/\/www.webfaction.com\/\">WebFaction<\/a> clients who had a Django app but no longer had a developer and those orphaned projects trended <em>ancient<\/em>. I started working with Django in 2009 with <a href=\"https:\/\/www.djangoproject.com\/weblog\/2009\/jul\/29\/1-point-1\/\">Django 1.1<\/a> and that was modern compared to most of the WebFaction projects. The biggest challenge in that group was a project running on 0.96 and&nbsp;using <code>psycopg<\/code>. I&#8217;d been&nbsp;installing <code>psycopg2<\/code> for so long at that point it never occurred to me there was a version before it. And the Internet felt the same way: obtaining a version of Django that old was a challenge (see <a href=\"http:\/\/stackoverflow.com\/questions\/19179881\/how-do-i-get-an-older-version-of-django-pip-says-could-not-find-version\">this thread<\/a> for how to get versions no longer listed in Pypi). Obtaining a copy&nbsp;of <code>psycopg<\/code> proved impossible (I cheated and wound up downloading the folder from the&nbsp;client&#8217;s <code>site-packages<\/code> directory and using that to replicate the issue they were seeing&#8212; definitely not a recommended&nbsp;approach).<\/p>\n<h2>General&nbsp;Guidelines<\/h2>\n<ul>\n<li>Use a <a href=\"http:\/\/docs.python-guide.org\/en\/latest\/dev\/virtualenvs\/\"><code>virtualenv<\/code><\/a> or similar concept. If you&#8217;re already doing so, great. If you are not, now is definitely the time to start. If you&#8217;re doing anything more than a minor upgrade\/ working on a project with no 3rd party libraries, you are going to run into some &#8220;dependency hell&#8221; where you&#8217;ve updated to Django 1.<span class=\"caps\">NEW<\/span> and updated all your code to be compatible and then find out some libraries you use aren&#8217;t compatible. The best case scenario is where you just need to update the libraries to their latest versions too, but you may have to play around with the versions to make it all work. Otherwise you need to figure out how to replace the library or <a href=\"https:\/\/bitbucket.org\/tclancy\/django_openid_provider\">fork it<\/a>.<\/li>\n<li>Implicit in&nbsp;my <code>virtualenv<\/code> suggestion is that you also&nbsp;use <code>pip<\/code> to install packages&nbsp;and <code>pip freeze<\/code> to create a requirements file <em>with the exact versions<\/em> of the libraries your project&nbsp;uses. <\/li>\n<li>If you are updating from a truly old version of Django, try not to get too hung up on updating to the latest and greatest. You might have to shoot for something a little bit older because the incompatibilities are just too great or there isn&#8217;t enough time right now to make it all work. In updating my old site from 1.2 to 1.10 I actually stopped at 1.6 for a while instead. This is another&nbsp;place <code>virtualenv<\/code> is your friend: at one point I had three local environments for my&nbsp;site, <code>tkc<\/code> (live), <code>tkc16<\/code> and <code>tkc110<\/code>. Once I finished the upgrade process, I deleted the first two and&nbsp;renamed <code>tkc110<\/code> to <code>tkc<\/code> and it was like nothing ever happened. Be aware of the <a href=\"https:\/\/www.djangoproject.com\/download\/#supported-versions\">long-term release versions and the deprecation schedule<\/a> when targeting a new&nbsp;version.<\/li>\n<li>If you are jumping from a really old version, do some reading on the release notes to see what new features are available to you. I&#8217;m focusing on problems you may run into and backwards-incompatible changes, but one of the major reasons to upgrade are all the improvements you get. Be aware of things like <a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/ref\/models\/querysets\/#select-related\"><code>select_related<\/code>, <code>prefetch_related<\/code> and <code>only<\/code><\/a> for making queries&nbsp;faster.<\/li>\n<li>Change from <a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/topics\/http\/shortcuts\/#render-to-response\"><code>render_to_response<\/code><\/a> to <a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/topics\/http\/shortcuts\/#django.shortcuts.render\"><code>render<\/code><\/a>. It will make things easier and the former is soon to be&nbsp;removed.<\/li>\n<li>If you get stuck because the changes to project layout or syntax have changed so much, try creating a&nbsp;new <code>virtualenv<\/code> and project with 1.10 (or similar) and then dragging your apps into the project. You will still need to update a bunch of stuff but it may make things a lot easier and help with your&nbsp;future-proofing.<\/li>\n<\/ul>\n<h2>Version-Specific&nbsp;Notes<\/h2>\n<h3><a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/releases\/1.10\/\">1.10<\/a><\/h3>\n<ul>\n<li><a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/releases\/1.10\/#new-style-middleware\">Major changes to&nbsp;middleware<\/a><\/li>\n<li>If you are using MySQL (don&#8217;t start now), <a href=\"https:\/\/code.djangoproject.com\/ticket\/15940\">Django recommends<\/a> you turn on strict mode. See <a href=\"https:\/\/github.com\/django\/django\/commit\/b2aab09fe99b0e6e2e0357a7a794355a631c3039\">project note<\/a> about why and <a href=\"http:\/\/stackoverflow.com\/a\/23023015\/7376\">this answer for&nbsp;how<\/a><\/li>\n<li><code>django.conf.urls.patterns<\/code> is gone and all view references&nbsp;in <code>urls.py<\/code> need to be imported views, not string&nbsp;names.<\/li>\n<\/ul>\n<h3><a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/releases\/1.9\/\">1.9<\/a><\/h3>\n<ul>\n<li>The admin got a&nbsp;facelift!<\/li>\n<li><a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/releases\/1.9\/#password-validation\">Password validation&nbsp;options<\/a><\/li>\n<li><code>django.contrib.sites<\/code> is no longer included by default, which can cause&nbsp;a <code>RuntimeError: Model class django.contrib.sites.models.Site doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS<\/code>. Just add it back&nbsp;to <code>INSTALLED_APPS<\/code>.<\/li>\n<li><code>django.utils.log.NullHandler<\/code> was removed, <a href=\"http:\/\/stackoverflow.com\/questions\/34348360\/cannot-resolve-django-utils-log-nullhandler-in-django-1-9\">replace the references with&nbsp;logging.NullHandler<\/a><\/li>\n<\/ul>\n<h3><a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/releases\/1.8\/\">1.8<\/a><\/h3>\n<ul>\n<li>Major settings change: <a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/ref\/templates\/upgrading\/#the-templates-settings\">the&nbsp;new <code>TEMPLATES<\/code> setting replaces&nbsp;all <code>TEMPLATE_*<\/code> settings<\/a>. This is a bit of <span class=\"caps\">PITA<\/span> as you have to move a bunch of things into their new home in that&nbsp;setting.<\/li>\n<li><code>select_related<\/code> actually checks that the fields exist on the model you are querying. Previously this just silently ignored the error and you were left thinking you&#8217;d improved performance when you weren&#8217;t doing&nbsp;anything.<\/li>\n<li><code>django.contrib.formtools<\/code> is replaced by an <a href=\"https:\/\/github.com\/django\/django-formtools\/\">external&nbsp;app<\/a><\/li>\n<li>The syntax&nbsp;of <code>urls.py<\/code> files changed: you now have to&nbsp;have <code>url(regex, view)<\/code> instead of&nbsp;just <code>(regex, view)<\/code>, otherwise you will&nbsp;get <code>AttributeError 'tuple' object has no attribute 'regex'<\/code>. Make note of the changes in 1.10&nbsp;to <code>urls.py<\/code> files if you&#8217;re going to be updating all of them&nbsp;anyway.<\/li>\n<li><a href=\"https:\/\/code.djangoproject.com\/ticket\/18659\"><code>request.REQUEST<\/code> was removed<\/a>, but you weren&#8217;t using that anyway, were&nbsp;you?<\/li>\n<li>Drops support for Postgres &lt; 9.0 (and then 9.0 and 9.1 are dropped in .9 and .10) and MySQL &lt;&nbsp;5.5<\/li>\n<\/ul>\n<h3><a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/releases\/1.7\/\">1.7<\/a><\/h3>\n<ul>\n<li>Major update which makes <a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/topics\/migrations\/\">database migrations<\/a> a built-in part of Django instead of relying on 3rd party apps (usually South). See the <a href=\"https:\/\/realpython.com\/blog\/python\/django-migrations-a-primer\/\">differences here<\/a>.<\/li>\n<li><a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/releases\/1.7\/#app-loading-changes\">App loading changes<\/a> may mean needing to reorder or <a href=\"http:\/\/stackoverflow.com\/questions\/34114427\/django-upgrading-to-1-9-error-appregistrynotready-apps-arent-loaded-yet\">move some&nbsp;stuff.<\/a><\/li>\n<li>If you are using South, there&#8217;s a <a href=\"https:\/\/docs.djangoproject.com\/en\/1.7\/topics\/migrations\/#upgrading-from-south\">guide to changing over<\/a>. One thing that&#8217;s not obvious: in addition to&nbsp;removing <code>'south'<\/code> from&nbsp;your <code>INSTALLED_APPS<\/code>, you actually need to uninstall it from&nbsp;your <code>virtualenv<\/code> or you will get errors like <a href=\"http:\/\/stackoverflow.com\/questions\/29647602\/there-is-no-south-database-module-south-db-postgresql-psycopg2-for-your-databa\"><code>There is no South database module 'south.db.postgresql_psycopg2' for your database.<\/code><\/a><\/li>\n<li><a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/releases\/1.7\/#contrib-middleware-removed-from-default-middleware-classes\">Default middleware&nbsp;changed<\/a><\/li>\n<li>The syntax\/ imports of&nbsp;the <code>.wsgi<\/code> file project use changed. You may run&nbsp;into <code>AppRegistryNotReady: Apps aren't loaded yet<\/code>. See this <a href=\"http:\/\/stackoverflow.com\/questions\/26276397\/django-1-7-upgrade-error-appregistrynotready-apps-arent-loaded-yet\">StackOverfloew thread<\/a>.<\/li>\n<li><code>RuntimeError: populate() isn't reentrant<\/code> - there are a <a href=\"http:\/\/stackoverflow.com\/questions\/27093746\/django-stops-working-with-runtimeerror-populate-isnt-reentrant\">number of possible causes for this<\/a> (and I&#8217;m not sure if there are all 1.7-specific). In my case it was a dumb error where I had an app listed twice&nbsp;in <code>INSTALLED_APPS<\/code>.<\/li>\n<\/ul>\n<h3><a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/releases\/1.6\/\">1.6<\/a><\/h3>\n<ul>\n<li>Not much new, simplified setup, swapped a couple of defaults in settings. At least that&#8217;s how I remember it and its why I chose this as a halfway step in my own&nbsp;update.<\/li>\n<li>Actually there&#8217;s one change that will bite you if you have any custom&nbsp;managers: <code>get_query_set<\/code> is&nbsp;now <code>get_queryset<\/code>.<\/li>\n<li><code>django.contrib.localflavor<\/code> is gone, replaced by a <a href=\"https:\/\/django-localflavor.readthedocs.io\/en\/latest\/\">3rd-party app<\/a>. Update your requirments file and your&nbsp;references.<\/li>\n<li><code>django.contrib.markup<\/code> is gone. You will need a <a href=\"https:\/\/github.com\/trentm\/django-markdown-deux\">replacement.<\/a><\/li>\n<li>There no longer is&nbsp;a <code>.raw_post_data<\/code> attribute on Request objects.&nbsp;Use <code>.body<\/code> instead.<\/li>\n<\/ul>\n<h3><a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/releases\/1.5\/\">1.5<\/a><\/h3>\n<ul>\n<li>Introduces a <a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/releases\/1.5\/#configurable-user-model\">configurable <code>User<\/code> model<\/a>. A user in the <a href=\"https:\/\/www.reddit.com\/r\/django\/comments\/57gu0e\/django_version_upgrade_guide\/\">reddit discussion<\/a> of this post said it caused them <a href=\"https:\/\/www.reddit.com\/r\/django\/comments\/57gu0e\/django_version_upgrade_guide\/d8t30o3\">problems due to a&nbsp;subclassed <code>User<\/code> model in their&nbsp;project.<\/a><\/li>\n<li>The syntax of the <a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/ref\/templates\/builtins\/#url\"><code>url<\/code><\/a> tag changed and now the url name has to be quoted. If you use an editor that supports multi-file search-and-replace, you can <a href=\"http:\/\/jpadilla.com\/post\/47025152553\/shifting-to-new-style-url-tag-in-django-15\">update all your templates<\/a> easily. Pro-tip: do this in its own branch or similar for safety&#8217;s&nbsp;sake.<\/li>\n<li>Introduces the <a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/ref\/settings\/#allowed-hosts\"><code>ALLOWED_HOSTS<\/code> setting<\/a>. <strong>Make sure to do this<\/strong> because it will bite you: the setting only applies&nbsp;if <code>DEBUG = False<\/code>, so you won&#8217;t run into errors locally but then your brand-new, updated site will not respond when you post it&nbsp;live.<\/li>\n<li>Deprecates <code>django.utils.simplejson<\/code>. Can do a search and replace&nbsp;to <code>import json<\/code> instead. Unrelated to any upgrade stuff, if you do a lot of <span class=\"caps\">JSON<\/span> processing or a little bit of <span class=\"caps\">JSON<\/span> processing on very big pieces of <span class=\"caps\">JSON<\/span>, take a look at <a href=\"http:\/\/artem.krylysov.com\/blog\/2015\/09\/29\/benchmark-python-json-libraries\/\"><code>ujson<\/code><\/a>. I&#8217;ve gotten a lot of free performance improvements from&nbsp;it.<\/li>\n<li><code>direct_to_template<\/code> is gone. Use <a href=\"http:\/\/stackoverflow.com\/questions\/15621048\/how-can-i-satisfy-an-import-of-direct-to-template\">this solution in its&nbsp;place<\/a><\/li>\n<\/ul>\n<h3><a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/releases\/1.4\/\">1.4<\/a><\/h3>\n<ul>\n<li>Lots of good new stuff introduced in this version, the biggest being <a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/topics\/i18n\/timezones\/\">timezone support<\/a>.<\/li>\n<li>The concept&nbsp;of <code>ADMIN_MEDIA<\/code> is replaced by static files app from&nbsp;1.3<\/li>\n<li><a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/releases\/1.4\/#django-conf-urls-defaults\"><code>django.conf.urls.defaults<\/code> is replaced&nbsp;by <code>django.conf.urls<\/code><\/a>. Update&nbsp;your <code>urls.py<\/code> files&nbsp;accordingly.<\/li>\n<li>Error: <code>\"No modules named six\"<\/code> - this is an annoying one I ran into with a couple 3rd party libraries. I was testing which versions I could easily update to by updating to 1.2.0, 1.3.0, 1.4.0, etc. The problem&nbsp;is <code>six<\/code> was introduced in Django 1.4.2 so don&#8217;t update to anything less than that if you&#8217;re going to use&nbsp;1.4.<\/li>\n<\/ul>\n<h3><a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/releases\/1.3\/\">1.3<\/a><\/h3>\n<ul>\n<li>The big thing here is the introduction&nbsp;of <code>staticfiles<\/code>. If you&#8217;ve never dealt with that, it&#8217;s a sea change and you will need to <a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/howto\/static-files\/\">read the documentation<\/a> about how to change things. Essentially, this was splitting up the idea of media (user-generated uploads) from your site&#8217;s static&nbsp;assets.<\/li>\n<li><a href=\"https:\/\/docs.djangoproject.com\/en\/1.10\/topics\/class-based-views\/\">Class-based views<\/a> are also added here. You&#8217;re not obligated to use them but if you rely on a lot of generic views, you&#8217;re going to need to update&nbsp;those.<\/li>\n<li><span class=\"caps\">CSRF<\/span> protection now applies to Ajax views as&nbsp;well.<\/li>\n<\/ul>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"django"}}]},{"title":"Debugging a Vue.js\u00a0Error","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/debugging-vuejs-error.html","rel":"alternate"}},"published":"2016-10-11T11:07:14-04:00","updated":"2016-10-11T11:07:14-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2016-10-11:\/debugging-vuejs-error.html","summary":"<h1>Debugging a Vue.js&nbsp;Error<\/h1>\n<p>I know it&#8217;s been a while and I really should write more often, but this is just a quick one for Google to index in case it happens to someone else: I recently wrote my first <a href=\"https:\/\/vuejs.org\/\">vue.js<\/a> component and was really pleased with \u2026<\/p>","content":"<h1>Debugging a Vue.js&nbsp;Error<\/h1>\n<p>I know it&#8217;s been a while and I really should write more often, but this is just a quick one for Google to index in case it happens to someone else: I recently wrote my first <a href=\"https:\/\/vuejs.org\/\">vue.js<\/a> component and was really pleased with how easy it was to build &#8230; right up until I deployed it live and it didn&#8217;t work. It took me about an hour of fiddling with the production version of the site, swapping to the non-minified version, shutting off the <span class=\"caps\">CSS<\/span> and JavaScript compression&nbsp;from <code>django-compressor<\/code> and desperately staring into the (really cool) <a href=\"https:\/\/chrome.google.com\/webstore\/detail\/vuejs-devtools\/nhdogjmejiglipccpnnnanhbledajbpd?hl=en\">Vue debugging panel for Chrome<\/a>. I thought it was a problem with the <span class=\"caps\">REST<\/span> <span class=\"caps\">API<\/span> data getting to the component too slowly because Vue kept complaining the rows were missing the properties I was referencing, but looking in the debugging panel I could see Vue was properly loading the data. I finally found the problem by viewing the source of local and live side-by-side which was harder than it sounds because the <span class=\"caps\">HTML<\/span> is minfied in production. I was just about to put the two sets of <span class=\"caps\">HTML<\/span> into a pretty-fier when I saw the difference: <a href=\"https:\/\/pypi.python.org\/pypi\/django-htmlmin\"><code>django-htmlmin<\/code><\/a> doesn&#8217;t just strip whitespace (I suppose it can&#8217;t do that), it parses the <span class=\"caps\">HTML<\/span> and apparently makes it &#8220;valid&#8221; which was moving my Vue templates around to places they shouldn&#8217;t be. After a quick test and putting the <span class=\"caps\">URL<\/span>&nbsp;in <code>EXCLUDE_FROM_MINIFYING<\/code> in my settings file, all was right with the&nbsp;world.<\/p>\n<p>(Ironically, this post took about 30 minutes to get live because I had to run down another rat hole debugging what turned out to be an out-of-date version&nbsp;of <code>django-tagging<\/code> as I recently upgraded this site. That is another post though.&nbsp;Hopefully.)<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"django"}},{"@attributes":{"term":"vue.js"}}]},{"title":"Harvard Business School: HBX: Harvard Business\u00a0School","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/hbx-harvard-business-school","rel":"alternate"}},"published":"2016-03-01T00:00:00-05:00","updated":"2016-03-01T00:00:00-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2016-03-01:\/hbx-harvard-business-school","summary":"<h1>Harvard Business School: <span class=\"caps\">HBX<\/span>: Harvard Business&nbsp;School<\/h1>\n<h2>2016-03-01<\/h2>\n<p><em>Building a <span class=\"caps\">MOOC<\/span> for the Best and&nbsp;Brightest<\/em><\/p>\n<p>I spent two-and-a-half years working as both a front- and back-end developer on various parts of the upcoming <span class=\"caps\">MOOC<\/span> offering from Harvard Business School. On the front-end I&#8217;m building various teaching resources in \u2026<\/p>","content":"<h1>Harvard Business School: <span class=\"caps\">HBX<\/span>: Harvard Business&nbsp;School<\/h1>\n<h2>2016-03-01<\/h2>\n<p><em>Building a <span class=\"caps\">MOOC<\/span> for the Best and&nbsp;Brightest<\/em><\/p>\n<p>I spent two-and-a-half years working as both a front- and back-end developer on various parts of the upcoming <span class=\"caps\">MOOC<\/span> offering from Harvard Business School. On the front-end I&#8217;m building various teaching resources in JavaScript using resources like D3 and <span class=\"caps\">SVG<\/span> to provide on-the-fly interactive graphing and data&nbsp;updates.<\/p>\n<p>On the back-end I&#8217;ve designed the plugin system for the teaching elements, worked on the Tastypie-based APIs for the course and administrative sides and am currently working with our Mongo collections of user metrics and user state data to build administrative reports that will allow professors to continuously improve the effectiveness of their teaching resources. In addition to hands-on coding, much of my time was spent reviewing pull requests\/ working with junior engineers to turn them into senior engineers. I worked with a team of outsourced coders and developed a great rapport (and some enduring friendships) over the two plus years, gaining their trust and fostering a spirit of collaboration that was absent when I&nbsp;started.<\/p>\n<p>As part of my responsibilities, I participated in the daily standup meetings via teleconference and worked for a time as build master, partering with the devops lead to turn a messy, by-hand deployment process into a series of reliable&nbsp;scripts.<\/p>\n<p><img src=\"\/images\/portfolio\/hbx2.png\" alt=\"Teaching Element Still my favorite thing I built\" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/hbx3.png\" alt=\"Student Overview \" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/hbx1.png\" alt=\"Syllabus \" style=\"margin: 1em 0\" \/><\/p>","category":{"@attributes":{"term":"Portfolio"}}},{"title":"Worst Pickup Line: A Play in One\u00a0Act","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/worst-pickup-line-play-one-act.html","rel":"alternate"}},"published":"2015-07-17T10:40:11-04:00","updated":"2015-07-17T10:40:11-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2015-07-17:\/worst-pickup-line-play-one-act.html","summary":"<h1>Worst Pickup Line: A Play in One&nbsp;Act<\/h1>\n<p><span class=\"caps\">INT<\/span> - <span class=\"caps\">BEER<\/span> <span class=\"caps\">STORE<\/span> - <span class=\"caps\">DAY<\/span><\/p>\n<p><span class=\"caps\">CREEPY<\/span> <span class=\"caps\">GUY<\/span>, a man in his late 50s in hiking shorts and an ankle brace is paying for a popsicle at a beer store at 10:30 in the morning with the change from what is either a \u2026<\/p>","content":"<h1>Worst Pickup Line: A Play in One&nbsp;Act<\/h1>\n<p><span class=\"caps\">INT<\/span> - <span class=\"caps\">BEER<\/span> <span class=\"caps\">STORE<\/span> - <span class=\"caps\">DAY<\/span><\/p>\n<p><span class=\"caps\">CREEPY<\/span> <span class=\"caps\">GUY<\/span>, a man in his late 50s in hiking shorts and an ankle brace is paying for a popsicle at a beer store at 10:30 in the morning with the change from what is either a prescription pill container or a film canister. He holds the canister out so the cashier can return his change without touching&nbsp;him<\/p>\n<p><span class=\"caps\">CREEPY<\/span> <span class=\"caps\">GUY<\/span>: You still married to the guy who owns this&nbsp;place?<\/p>\n<p><span class=\"caps\">CASHIER<\/span>:&nbsp;Yeah<\/p>\n<p><span class=\"caps\">CREEPY<\/span> <span class=\"caps\">GUY<\/span>: He treating you&nbsp;alright?<\/p>\n<p><span class=\"caps\">CASHIER<\/span> [<em>moves to closed register with a pile of newspapers on it<\/em>]: I can take you over here&nbsp;sir.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Exception\u00a0Handling","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/exception-handling.html","rel":"alternate"}},"published":"2014-12-03T16:01:19-05:00","updated":"2014-12-03T16:01:19-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2014-12-03:\/exception-handling.html","summary":"<h1>Exception&nbsp;Handling<\/h1>\n<p>I&#8217;ve been thinking about exception handling a lot recently. A., because I&#8217;m stultifying and B., because it&#8217;s been a source of contention in the codebase I&#8217;m responsible for. I wrote some formal documentation last week to try to normalize our approach, but I&#8217;m \u2026<\/p>","content":"<h1>Exception&nbsp;Handling<\/h1>\n<p>I&#8217;ve been thinking about exception handling a lot recently. A., because I&#8217;m stultifying and B., because it&#8217;s been a source of contention in the codebase I&#8217;m responsible for. I wrote some formal documentation last week to try to normalize our approach, but I&#8217;m not happy with it. I&#8217;m not good at writing formal documentation&mdash; it always comes out stiffer than I want and feels like all nuance is lost. Also, I&#8217;m in the middle of listening to <a href=\"http:\/\/5by5.tv\/changelog\/100\">this podcast<\/a> about the Go Language and they&#8217;ve just touched on exceptions and I think it&#8217;s helped me crystalize my thoughts. This post will tell if that&#8217;s&nbsp;true. <\/p>\n<h2>Exception&nbsp;Enlightenment<\/h2>\n<h3>Step One: complete&nbsp;newbie<\/h3>\n<p>No exception handling happens here. The second your code works once, you&#8217;re done. &#8220;No one touch anything, it works.&#8221; You push the baby bird out of the nest, ask a coworker to try it out and hold your breath. In the worst case, they&#8217;re a friend and try to use the program the way you think it should work. In the best case, they&#8217;re a prick and put in numbers where you ask for text and text where you ask for numbers and try to divide everything by&nbsp;zero.<\/p>\n<h3>Step One Point Five: &#8220;I&#8217;ve got to do <em>something<\/em>&#8221;<\/h3>\n<p>You add checks for everything your tester tried and everything else you can think of. You quickly learn you can&#8217;t think of much because you think like the program (or, more accurately, the program is laid out the way you think through problems). Someone puts in a floating point number for their name and you&#8217;re right back where you started. Maybe you hear about fuzz testing, maybe you know a lot of assholes. The inevitable conclusion: you can&#8217;t possibly think of everything and prevent&nbsp;it.<\/p>\n<h3>Step Two: exception&nbsp;handling<\/h3>\n<p>Holy shit! You can prevent everything that could ever go bad. It&#8217;s as simple as&nbsp;this:<\/p>\n<p><code><pre>\ntry:\n    answer = a \/ b\nexcept:\n    # suck it haters!\n    answer = 0\n<\/pre><\/code><\/p>\n<p>My guess is this is where a lot of people give up on programming, stop growing as a programmer or relegate programming to a hobby or something they do only when they have to because this approach makes life so much&nbsp;harder.<\/p>\n<h3>Step Three: a little bit of&nbsp;light<\/h3>\n<p>It turns out &#8220;naked&#8221; try\/ catch blocks where you don&#8217;t bother to specify what kind of exception you&#8217;re handling are much worse than not doing anything. You learn this after smashing your head against your monitor for a day trying to figure out why something doesn&#8217;t work but doesn&#8217;t blow up only to finally see&nbsp;the <code>try\/ catch<\/code> your eyes normally skim past without noticing. &#8220;Couldn&#8217;t be. Nah. Well, maybe &#8230; &#8221; and you rip out the block and there it is: you thought you were catching a type error to stop users passing in strings and maybe handling divide-by-zero while you were at it, but it turns out it&#8217;s also swallowing a whole host of floating point ugliness, missing variables, an import you forgot and hey, it looks like your network connection is in the&nbsp;crapper.<\/p>\n<p>So now you need to do some reading and it turns out exception handling is a microcosm of programming. There are multiple styles, opinions about how to use exceptions, whether to use exceptions, whether to expect exceptions (?!) &#8230; like choosing a language or a platform or anything else in programming, exception handling is one more bar brawl to stick your face&nbsp;into.<\/p>\n<h3>Step Four: I don&#8217;t know what step four is&nbsp;yet<\/h3>\n<p>One of the things I like about Python is for a language whose <a href=\"https:\/\/www.python.org\/dev\/peps\/pep-0020\/\">founding principles<\/a> include &#8220;There should be one&mdash;  and preferably only one&mdash; obvious way to do it&#8221;, it&#8217;s pretty unopinionated about how you use exceptions. We&#8217;re told exceptions are inexpensive in Python (maybe said with a bit of a sneer and a knowing look in the direction of statically-typed languages), so much so they&#8217;re used idiomatically in places you would otherwise be using&nbsp;an <code>if\/ else<\/code> test. That inexpensiveness is a bit misleading and <a href=\"http:\/\/stackoverflow.com\/questions\/5589532\/try-catch-or-validation-for-speed\/5591737#5591737\">you should think about which is the most common case<\/a> in the code you&#8217;re writing when deciding&nbsp;between <code>if\/ else<\/code> and <code>try\/ catch<\/code> but unless you&#8217;re inside a loop inside a bit of code that gets called an awful lot, there are more important things in your code to worry&nbsp;about.<\/p>\n<p>All of which brings me to today and that podcast wherein one of the maintainers of the Go language at Google turns up his nose at exception handling in general (Go doesn&#8217;t have it) and Python in particular. My immediate reaction was typical fanboy: start assembling arguments in favor of your chosen gang instead of listening to the other side. When I stopped and thought about it, I realized what they were discussing was probably really close to how I think of&nbsp;exceptions. <\/p>\n<p>There&#8217;s a line of argument in the Exception Handling bar fight that goes something like this: &#8220;How can you handle exceptions when they&#8217;re, by definition, <em>exceptional<\/em>?&#8221; This typically comes from a Theoretical Asshole (somehow they&#8217;re always assholes in real life too) who took some Comp Sci classes without ever hearing anything. The name means different things to different people: for some they&#8217;re exceptions like when it rains in summer, for others they&#8217;re Exceptions like when it rains in the desert. I fall into the former camp: I use exceptions interchangeably&nbsp;with <code>if\/ else<\/code> tests, most likely because I&#8217;ve been working in Python for too long. But whichever approach you prefer, let&#8217;s agree you use an exception because you want to log something weird so you can stop it from happening in the future. What was argued against in the podcast is something I&#8217;d like to dismiss as a straw man because it&#8217;s madness, but I&#8217;ve seen enough of it to know better.&nbsp;Whether <code>try\/ catch<\/code> or <code>if\/ else<\/code>, the code should look&nbsp;like:<\/p>\n<p><code><pre>\ntry:\n    return a \/ b\nexcept ThisOneWierdException:\n    logging.exception(\"WTF?\")\n    return error_message(\"You really are an asshole, you know that?\")\n<\/code><\/pre><\/p>\n<p>Never like&nbsp;this:<\/p>\n<p><code><pre>\ntry:\n    answer = a \/ b\nexcept ThisOneWierdException:\n    answer = default\nkeep_doing_stuff_like_nothing_is_wrong_like_you_always_DO_mom()\n<\/code><\/pre><\/p>\n<p>At this point I do have to pick nits about the word: it&#8217;s an exception. You&#8217;re not supposed to keep soldiering on. There are things like &#8220;Try to find the user&#8217;s old data in a file on disk, if that doesn&#8217;t exist, try looking in the database, if that doesn&#8217;t exist start with a blank data set.&#8221; You can&nbsp;use <code>if\/ else<\/code> or <code>try\/ catch<\/code> for that kind of thing, I don&#8217;t care. But if you expect the thing to happen, it&#8217;s not exceptional. When something exceptional does happen, get out, log everything you can and try to patch the hole&nbsp;tomorrow.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"coding"}}]},{"title":"Ground Energy: Ground\u00a0Energy","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/ground-energy","rel":"alternate"}},"published":"2014-10-21T00:00:00-04:00","updated":"2014-10-21T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2014-10-21:\/ground-energy","summary":"<h1>Ground Energy: Ground&nbsp;Energy<\/h1>\n<h2>2014-10-21<\/h2>\n<p><em>Internet of Things project optimizing ground source heat pumps for homeowners and&nbsp;businesses<\/em><\/p>\n<p>Built and currently maintain (and extend) the Django codebase that powers&nbsp;<a href=\"http:\/\/groundenergysupport.com\/\">Ground Energy<\/a>. The system receives status reports from geothermal installs once per minute, logs them to the database and provides both \u2026<\/p>","content":"<h1>Ground Energy: Ground&nbsp;Energy<\/h1>\n<h2>2014-10-21<\/h2>\n<p><em>Internet of Things project optimizing ground source heat pumps for homeowners and&nbsp;businesses<\/em><\/p>\n<p>Built and currently maintain (and extend) the Django codebase that powers&nbsp;<a href=\"http:\/\/groundenergysupport.com\/\">Ground Energy<\/a>. The system receives status reports from geothermal installs once per minute, logs them to the database and provides both live reports and daily summaries. In spite of the enormous amount of data each installation generates, the site is able to return real-time reporting in a responsive&nbsp;manner.<\/p>\n<p>In addition to speaking to our native installation devices which report by POSTing <span class=\"caps\">XML<\/span>, I&#8217;ve abstracted the reporting to allow us to provide the same reports to owners of Ecobee thermostats by integrating with&nbsp;<a href=\"http:\/\/www.ecobee.com\/solutions\/api\/\">their <span class=\"caps\">API<\/span><\/a>&nbsp;via OAuth&nbsp;requests.<\/p>\n<p>Throughout the process I have worked directly with the principals to design and extend the services&nbsp;offered.<\/p>\n<p><img src=\"\/images\/portfolio\/installs.png\" alt=\"Install Listing \" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/dashboard_ZSa1sau.png\" alt=\"Dashboard \" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/home_xBkDKn8.png\" alt=\"Homepage \" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"django"}},{"@attributes":{"term":"iot"}},{"@attributes":{"term":"pandas"}},{"@attributes":{"term":"oauth"}}]},{"title":"Java Version Hell on OSX","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/java-version-hell-osx.html","rel":"alternate"}},"published":"2014-08-07T15:33:27-04:00","updated":"2014-08-07T15:33:27-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2014-08-07:\/java-version-hell-osx.html","summary":"<h1>Java Version Hell on <span class=\"caps\">OSX<\/span><\/h1>\n<p>In one of those &#8220;Why did I even look at the terminal&#8221; moments, I noticed Solr stopped working properly in a local Django setup. Initially I ignored a slew of 404 errors when Haystack tried to reindex because &#8230; well because who the hell cared? I \u2026<\/p>","content":"<h1>Java Version Hell on <span class=\"caps\">OSX<\/span><\/h1>\n<p>In one of those &#8220;Why did I even look at the terminal&#8221; moments, I noticed Solr stopped working properly in a local Django setup. Initially I ignored a slew of 404 errors when Haystack tried to reindex because &#8230; well because who the hell cared? I&#8217;m not trying to find anything, I&#8217;m trying to build stuff. Which means I immediately got a feature request related to searching. Not only was Solr not reindexing, but trying to visit the Solr console at http:\/\/127.0.0.1:8983\/solr returned a 404 error page&nbsp;saying<\/p>\n<div class=\"highlight\"><pre><span><\/span><code>No context on this server matched or handled this request. Contexts known to this server are . . .\n<\/code><\/pre><\/div>\n\n<p>Now actually looking at the ream of text going by on Solr startup I&nbsp;noticed <code>UnsupportedClassVersionError<\/code> was the root problem. This happens when you&#8217;re trying to run Java code that was compiled for a newer version than you are running. Annoying given I don&#8217;t actually work with the language so why is it given me such a hassle and strange because I installed Solr with <a href=\"http:\/\/brew.sh\/\">homebrew<\/a> and homebrew doesn&#8217;t make mistakes like that (especially since it all worked for a long time after install). Distant bells started ringing about something I installed* that let me know it needed an older version of Java. I said yes because like everyone else, dev or non-dev, I pretty much agree to prompts to get them to leave me alone and who the hell would suspect the thing not only installed an older version of Java but then went on to make it the system version? The nicest thing I can say about a mind that reaches such a solution is there&#8217;s a reason people crap on Java&nbsp;projects.<\/p>\n<p>To add a little extra spice to make life extra nice, Apple and Oracle hate each other and so you have to run between the trenches in No Man&#8217;s Land of their war to get Java installed. Looking for Java 1.7, I started <a href=\"http:\/\/stackoverflow.com\/questions\/6267392\/how-do-i-use-jdk-7-on-mac-osx\">with this Stack Overflow thread<\/a> and installed the linked <span class=\"caps\">DMG<\/span> and everything was all&nbsp;better. <\/p>\n<p>No of course it wasn&#8217;t, don&#8217;t be&nbsp;silly. <\/p>\n<p>Nothing happened as far as I could&nbsp;see. <code>java -version<\/code> (<span class=\"caps\">BTW<\/span>, it&#8217;s awesome Java can&#8217;t follow the convention of a single dash for shorthand command line switches and a double dash for full name switches) still returned 1.6 and looking&nbsp;in <code>\/System\/Library\/Frameworks\/JavaVM.framework\/Current\/<\/code> still&nbsp;showed <code>CurrentJDK<\/code> pointing&nbsp;to <code>\/System\/Library\/Java\/JavaVirtualMachines\/1.6.0.jdk\/Contents<\/code>. Looking&nbsp;in <code>\/System\/Library\/Java\/JavaVirtualMachines\/<\/code> did not reveal a 1.7 folder waiting there to be found because that would mean any old idiot could solve this mystery instead of requiring a special kind of thickheaded idiot. I renamed&nbsp;the <code>CurrentJDK<\/code> symlink&nbsp;to <code>JDK16<\/code> for later on in life when this all bites me in the ass the other way &#8216;round and then created a new symlink to the 1.7 version with&nbsp;this: <code>sudo ln -s \/Library\/Java\/JavaVirtualMachines\/jdk1.7.0_67.jdk\/Contents CurrentJDK<\/code>. Problem solved, at least until I have to use another piece of&nbsp;Java.<\/p>\n<p><sub>* For the curious, I think it was when I installed 12 different versions of jMeter via homebrew in the hopes of getting an old jMeter script to actually open instead of throwing errors about bad counts. If you ever want to know about installing older homebrew formulae, <a href=\"http:\/\/stackoverflow.com\/questions\/3987683\/homebrew-install-specific-version-of-formula\">here&#8217;s a good start<\/a>. <code>brew<\/code> even has&nbsp;a <code>brew edit<\/code> command so you can easily open the formula to repoint download links when the mirror it wants to use no longer has a copy of the ancient piece of crap you&#8217;re trying to install.<\/sub><\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"java"}},{"@attributes":{"term":"osx"}},{"@attributes":{"term":"bugs"}}]},{"title":"The Garrison City Should Lock From the\u00a0Outside","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/garrison-city-should-lock-outside.html","rel":"alternate"}},"published":"2014-06-13T14:56:24-04:00","updated":"2014-06-13T14:56:24-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2014-06-13:\/garrison-city-should-lock-outside.html","summary":"<h1>The Garrison City Should Lock From the&nbsp;Outside<\/h1>\n<p>At the beer store just before 3pm. I always get a little nervous when a car pulls in and someone from the backseat gets&nbsp;out.<\/p>\n<ul>\n<li><span class=\"caps\">DUI<\/span>?<\/li>\n<li>Underage&nbsp;driver?<\/li>\n<li>Just plain&nbsp;crazy?<\/li>\n<\/ul>\n<p>Thankfully it was number three. After the young guy got out \u2026<\/p>","content":"<h1>The Garrison City Should Lock From the&nbsp;Outside<\/h1>\n<p>At the beer store just before 3pm. I always get a little nervous when a car pulls in and someone from the backseat gets&nbsp;out.<\/p>\n<ul>\n<li><span class=\"caps\">DUI<\/span>?<\/li>\n<li>Underage&nbsp;driver?<\/li>\n<li>Just plain&nbsp;crazy?<\/li>\n<\/ul>\n<p>Thankfully it was number three. After the young guy got out of the back, the front doors opened and out piled a chunky Lauren Ambrose (circa her <a href=\"http:\/\/previously.tv\/law-and-order\/defending-lauren-ambroses-dignity\/\"><em>Law <span class=\"amp\">&amp;<\/span> Order<\/em> star turn<\/a>) and The Guy. He probably wasn&#8217;t even 50, might have been under 40, but it was an <em>Indiana Jones<\/em> &#8220;It&#8217;s not the years, it&#8217;s the miles&#8221; situation. The Guy was buying, which meant he felt justified in directing the younger two in what they should be picking up like Fagin with his urchins. For some reason Lauren Ambrose couldn&#8217;t have her &#8220;I&#8217;M <span class=\"caps\">SICK<\/span> <span class=\"caps\">OF<\/span> <span class=\"caps\">BEING<\/span> <span class=\"caps\">BOSSED<\/span> <span class=\"caps\">AROUND<\/span>&#8221; shit fit in the car and waited until the second her feet hit the threshold, like Burt Lancaster stepping over the baseline in <em>Field of Dreams<\/em>.<\/p>\n<p>Anyone hoping her storming out would make things less uncomfortable was been bitterly disappointed as The Man walked up to the nice old Indian cashier, asked her, &#8220;<span class=\"caps\">SPEAK<\/span> <span class=\"caps\">ENGLISH<\/span>?&#8221; and then embarked on a rant suggesting he wanted to learn. The only bits I caught&nbsp;were:<\/p>\n<ul>\n<li>when he demanded she touch his wet t-shirt to acknowledge he was working on a Friday even though it was&nbsp;raining<\/li>\n<li>when he somberly asked the owner for free packs of&nbsp;cigarettes<\/li>\n<\/ul>\n<p>As Warren Ellis likes to say, &#8220;It&#8217;s a strange world. Let&#8217;s keep it that&nbsp;way.&#8217;<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"dover"}}]},{"title":"Thoughts While Lowering a\u00a0Crib","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/thoughts-while-lowering-crib.html","rel":"alternate"}},"published":"2014-06-02T12:42:01-04:00","updated":"2014-06-02T12:42:01-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2014-06-02:\/thoughts-while-lowering-crib.html","summary":"<h1>Thoughts While Lowering a&nbsp;Crib<\/h1>\n<ul>\n<li>I get why people with kids feel like they need a bigger house: I&#8217;m trying to adjust a crib <em>in situ<\/em> and it feels like parallel parking a parade float in&nbsp;Rome<\/li>\n<li><span class=\"dquo\">&#8220;<\/span>No hon, I&#8217;ll do it during the week when the house \u2026<\/li><\/ul>","content":"<h1>Thoughts While Lowering a&nbsp;Crib<\/h1>\n<ul>\n<li>I get why people with kids feel like they need a bigger house: I&#8217;m trying to adjust a crib <em>in situ<\/em> and it feels like parallel parking a parade float in&nbsp;Rome<\/li>\n<li><span class=\"dquo\">&#8220;<\/span>No hon, I&#8217;ll do it during the week when the house is quiet.&#8221; And when it&#8217;s finally hot out. Good&nbsp;work!<\/li>\n<li>I bet in the fine print of this Ikea manual there&#8217;s a <em>Gremlins<\/em>-like warning saying, &#8220;Whatever you do, don&#8217;t try to lower the mattress when it&#8217;s humid out. Or you&#8217;ll discover just how shoddy this pressboard fit is. It&#8217;s only a child&#8217;s safety,&nbsp;right?&#8221;<\/li>\n<li>What if Ikea is just a conspiracy to convert the <span class=\"caps\">US<\/span> to the metric&nbsp;system?<\/li>\n<li>How many times has the average fishmonger heard, &#8220;<a href=\"https:\/\/www.youtube.com\/watch?v=VuNdnKDRSDA\">Tell me all your thoughts on cod<\/a>, &#8216;cause I really want to hear&nbsp;&#8216;em?&#8221;<\/li>\n<li>This is pretty close to the floor. I might as well schedule back surgery in&nbsp;advance.<\/li>\n<li>Wonder if we could get a claw from an old arcade prize machine hooked up&nbsp;here.<\/li>\n<\/ul>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"ikea"}},{"@attributes":{"term":"sweaty"}}]},{"title":"wxPython on OSX Mavericks with or without\u00a0Homebrew","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/wxpython-osx-mavericks-or-without-homebrew.html","rel":"alternate"}},"published":"2014-04-21T13:34:26-04:00","updated":"2014-04-21T13:34:26-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2014-04-21:\/wxpython-osx-mavericks-or-without-homebrew.html","summary":"<h1>wxPython on <span class=\"caps\">OSX<\/span> Mavericks with or without&nbsp;Homebrew<\/h1>\n<p>Just a short note for anyone else who runs into this nonsense: I could not get the current version of wxPython to install in a useful way using&nbsp;homebrew. <code>brew install wxmac --python --devel<\/code> to install into my Homebrew-controlled Python install worked \u2026<\/p>","content":"<h1>wxPython on <span class=\"caps\">OSX<\/span> Mavericks with or without&nbsp;Homebrew<\/h1>\n<p>Just a short note for anyone else who runs into this nonsense: I could not get the current version of wxPython to install in a useful way using&nbsp;homebrew. <code>brew install wxmac --python --devel<\/code> to install into my Homebrew-controlled Python install worked, but it missed a portion of the code. There should have been&nbsp;a <code>python<\/code> directory&nbsp;under <code>\/usr\/local\/Cellar\/wxmac\/3.0.0\/lib<\/code> that contained the relevant code and&nbsp;a <code>wx.pth<\/code> file I could symlink into virtualenvs. There was not. I don&#8217;t know if this is a bug or an issue with my setup (some of the links mentioned Homebrew will only install it for use as a &#8220;framework&#8221; and I honestly have no idea what that means or time to investigate, but I think it may be&nbsp;relevant).<\/p>\n<p>So I tried using the <a href=\"http:\/\/www.wxpython.org\/download.php\">installer provided at wxpython.org<\/a> but those were all corrupt according to <span class=\"caps\">OSX<\/span>. I had my suspicions about multiple files being corrupt and they turned out to be correct: the files aren&#8217;t corrupt, <a href=\"http:\/\/stackoverflow.com\/questions\/21223717\/install-wxpython-on-mac-os-mavericks\">they&#8217;re not signed the way Apple wants.<\/a>. Shutting off the privacy controls temporarily fixed that. Then it was a simple matter to symlink <span class=\"caps\">WX<\/span> into a virtualenv,&nbsp;e.g., <\/p>\n<p><code>ln -s \/Library\/Python\/2.7\/site-packages\/wxredirect.pth ~\/.virtualenvs\/envname\/lib\/python2.7\/site-packages\/.<\/code><\/p>\n<p>Update: turns out, once again, <a href=\"https:\/\/github.com\/Homebrew\/homebrew\/issues\/28583#issuecomment-40958167\">I am an idiot<\/a>; contrary to what I&#8217;d read, you need to&nbsp;install <code>wxpython<\/code>, which will&nbsp;include <code>wxmac<\/code>, not the other way&nbsp;around.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"python"}},{"@attributes":{"term":"osx"}}]},{"title":"Django Profiling\u00a0Bug","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/django-profiling-bug.html","rel":"alternate"}},"published":"2014-04-18T14:00:51-04:00","updated":"2014-04-18T14:00:51-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2014-04-18:\/django-profiling-bug.html","summary":"<h1>Django Profiling&nbsp;Bug<\/h1>\n<p>I&#8217;m doing some work profiling a large Django application and I was running into this weird error when I tried to aggregate the stats with gather_profile_stats.py which comes with Django. It kept&nbsp;throwing <code>TypeError: zip argument #1 must support iteration<\/code> if there were two profile \u2026<\/p>","content":"<h1>Django Profiling&nbsp;Bug<\/h1>\n<p>I&#8217;m doing some work profiling a large Django application and I was running into this weird error when I tried to aggregate the stats with gather_profile_stats.py which comes with Django. It kept&nbsp;throwing <code>TypeError: zip argument #1 must support iteration<\/code> if there were two profile files for the same bit of code. Searching for matching results was a ghost town and I was starting to think no one actually used gather_profile_stats.py because it was broken. Turns out there&#8217;s a <a href=\"http:\/\/bugs.python.org\/issue7372\">regression bug<\/a> in early versions of Python 2.7. I applied the patch provided in the link and everything works. Posting this little note so it&#8217;s not such a ghost town for the next&nbsp;person.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"django"}},{"@attributes":{"term":"python"}},{"@attributes":{"term":"profiling"}}]},{"title":"It\u2019s My Party\u00a0(now)","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/its-my-party-now.html","rel":"alternate"}},"published":"2014-04-08T14:33:31-04:00","updated":"2014-04-08T14:33:31-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2014-04-08:\/its-my-party-now.html","summary":"<h1>It&#8217;s My Party&nbsp;(now)<\/h1>\n<p>I&#8217;m trying really hard to take parenting magazines seriously, but they seem to be written for a demographic that straddles dense and insecure. The latest unsolicited offering from <em>Parents<\/em>&mdash;<\/p>\n<p><img src=\"http:\/\/images.meredith.com\/parents\/images\/2014\/04\/l_ParentsMay2014_cover.jpg\" \/><\/p>\n<p>is apparently for people who don&#8217;t already know ice cream cake and enough room \u2026<\/p>","content":"<h1>It&#8217;s My Party&nbsp;(now)<\/h1>\n<p>I&#8217;m trying really hard to take parenting magazines seriously, but they seem to be written for a demographic that straddles dense and insecure. The latest unsolicited offering from <em>Parents<\/em>&mdash;<\/p>\n<p><img src=\"http:\/\/images.meredith.com\/parents\/images\/2014\/04\/l_ParentsMay2014_cover.jpg\" \/><\/p>\n<p>is apparently for people who don&#8217;t already know ice cream cake and enough room to run around tests really well with kids age 0 to 5. I suppose I <em>could<\/em> spend a bunch of money and time on an incredibly indulgent party for Josie to feel superior to other parents, but wouldn&#8217;t it be so much simpler and cheaper to ruin the other kids&#8217; parties? Weeks of planning and a few hundred bucks versus a few afternoons of distracting jugglers, arguing with clowns and playing &#8220;leave a tail for the donkey&#8221;. No choice at&nbsp;all.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"kids"}}]},{"title":"R\u00e9sum\u00e9 Rewrite\u00a0Services","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/resume-rewrite-services.html","rel":"alternate"}},"published":"2014-04-04T10:54:39-04:00","updated":"2014-04-04T10:54:39-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2014-04-04:\/resume-rewrite-services.html","summary":"<h1>R\u00e9sum\u00e9 Rewrite&nbsp;Services<\/h1>\n<p><em>Helping people with a job application is not something I do. Unless you accidentally send it to me when asking your friends to review your cover letter before applying to be president of a bank. Especially if the email ends, &#8220;Constructive not your usual Tom. Thanks.&#8221; This \u2026<\/em><\/p>","content":"<h1>R\u00e9sum\u00e9 Rewrite&nbsp;Services<\/h1>\n<p><em>Helping people with a job application is not something I do. Unless you accidentally send it to me when asking your friends to review your cover letter before applying to be president of a bank. Especially if the email ends, &#8220;Constructive not your usual Tom. Thanks.&#8221; This exchange is about a year old now so I don&#8217;t think it&#8217;s going to do anyone any harm (though I&#8217;m sad to report it looks like my help wasn&#8217;t enough assuming the Management section of the web site is kept&nbsp;up).<\/em><\/p>\n<p>The first thing I&#8217;d say is sending this to the wrong tclancy does not bespeak great attention to detail. Moving forward from&nbsp;there:<\/p>\n<ul>\n<li>Second graf, &#8220;For most of my career, I have been second-in-command&#8221; - this says the opposite of what you&#8217;re trying to stress. Rather than suggesting you&#8217;ve been in positions of authority and gained insight into running a business, it makes it sound like you&#8217;re typecast as a second&nbsp;banana.<\/li>\n<li>Fourth, &#8220;acquisition by <span class=\"caps\">US<\/span> Trust&#8230;&#8221; don&#8217;t use an ellipsis instead of a period. It makes you look like an Internet comment&nbsp;troll.<\/li>\n<li>Fifth, &#8220;I am <strong>greatly<\/strong> involved with many of the initiatives related to these departments.&#8221; - take it easy on the adverbs. It doesn&#8217;t add anything here and feels&nbsp;clumsy<\/li>\n<li>First sentence in the sixth, I&#8217;m just not feeling it. Show, don&#8217;t tell. You get the point across in the rest of the paragraph, but this just feels like marketing <span class=\"caps\">BS<\/span><\/li>\n<li>Eighth, the last sentence (&#8220;I take the time to listen &#8230;&#8221;) is a car crash, with clauses running into strange punctuation and everybody veering out of&nbsp;control.<\/li>\n<li>In general, look for instances of the word &#8220;that&#8221; and see if the sentence still means the same without them and remove&nbsp;them.<\/li>\n<li>Tenth, <span class=\"caps\">REWORK<\/span>. &#8220;I try to proactively manage expectation&#8221; - you&#8217;re better than that. At least, Internet Stranger, I hope you&nbsp;are.<\/li>\n<li>Community Involvement. Take another swing in this section&nbsp;too:<\/li>\n<li><span class=\"dquo\">&#8220;<\/span>my community involvement strikes the appropriate balance between managing the outreach initiatives with the efficient functioning of the Credit Union.&#8221; As opposed to what, running the place into the ground to plant&nbsp;trees?<\/li>\n<li><span class=\"dquo\">&#8220;<\/span>I participate in a variety of philanthropic events.&#8221; Show, don&#8217;t tell. Otherwise it feels like you got dragged to a dinner once. <span class=\"caps\">WHAT<\/span> <span class=\"caps\">ARE<\/span> <span class=\"caps\">YOU<\/span> <span class=\"caps\">TRYING<\/span> <span class=\"caps\">TO<\/span> <span class=\"caps\">HIDE<\/span>, [<span class=\"caps\">PERSON<\/span>&#8217;S <span class=\"caps\">NAME<\/span>]?<\/li>\n<li>General: stop using the word &#8220;Philosophy&#8221;. You&#8217;re not Plato, you&#8217;re a guy with some ideas about how to get things done. Tell me what they&nbsp;are.<\/li>\n<li>Balance Sheet section, &#8220;able to provide the type of accurate and comprehensive information that has been routinely disseminated within the various institutions at which I have been employed.&#8221; That sentence feels like the opposite of clearly communicating&nbsp;info.<\/li>\n<li><span class=\"dquo\">&#8220;<\/span>the balance sheet is very efficient&#8221; - the balance sheet isn&#8217;t a sentient being or a process. Let&#8217;s reword here. I&#8217;d also like to see a deep dive into how you balance assets across M1\/ M2\/ M3. We can&#8217;t just get away with hand-waving here, this is the major leagues now, this is your ticket to The&nbsp;Show.<\/li>\n<li><span class=\"dquo\">&#8220;<\/span>I was introduced to entrepreneurship at an early age through my family\u2019s business&#8221;&mdash; you know what&#8217;s coming by now: &#8220;Show, don&#8217;t tell&#8221;. What was the family business that you&#8217;re so cagey about it? Was Dad dropping guys into the Boston thruway construction for Whitey or&nbsp;something?<\/li>\n<li>Not sure how I feel about the lower-case initials in the signature section, feels a little chatty, but you know the corporate culture better than I&nbsp;do.<\/li>\n<\/ul>\n<p><em>And I got a nice&nbsp;response:<\/em><\/p>\n<blockquote>\n<p>Tom, if I can call you by your first name, you have inspired me to be a better man and given me hope as an underachiever.  I have rarely been presented with a hard hitting, constructive critique of any of my presentations let alone a draft meant for someone else. I thank you for taking the time and opening my eyes to several of my weaknesses although, being reflective, I do believe I have my ego in check and I do want to improve where needed. Never have I had someone as articulate and creative comment on my work, writing or needs improvement areas and given that you are a complete stranger the whole experience is that much more unique. So, thanks again for your comments as they are impressive beyond this layman&#8217;s capabilities. You definitely made the real Tom proud although a very impressive &#8220;peanut gallery&#8221; sound bite guy in his own right. I wish you well and I will hopefully mistakenly run other materials by you in the&nbsp;future.<\/p>\n<\/blockquote>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"whoops"}},{"@attributes":{"term":"letterswegetletters"}}]},{"title":"Fundraising: A Play in One\u00a0Act","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/fundraising-play-one-act.html","rel":"alternate"}},"published":"2014-03-19T20:30:40-04:00","updated":"2014-03-19T20:30:40-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2014-03-19:\/fundraising-play-one-act.html","summary":"<h1>Fundraising: A Play in One&nbsp;Act<\/h1>\n<p><strong><span class=\"caps\">INT<\/span> - <span class=\"caps\">NIGHT<\/span> - a fundraiser from University of Rochester calls <span class=\"caps\">TOM<\/span> who has the phone on speaker while holding <span class=\"caps\">JOSIE<\/span>. We join the call in progress&nbsp;&#8230;<\/strong><\/p>\n<ul>\n<li>Caller: &#8220;Sir, no amount is too&nbsp;small.&#8221;<\/li>\n<li>Tom: &#8220;Well, I make like ten cents a day punching out plates \u2026<\/li><\/ul>","content":"<h1>Fundraising: A Play in One&nbsp;Act<\/h1>\n<p><strong><span class=\"caps\">INT<\/span> - <span class=\"caps\">NIGHT<\/span> - a fundraiser from University of Rochester calls <span class=\"caps\">TOM<\/span> who has the phone on speaker while holding <span class=\"caps\">JOSIE<\/span>. We join the call in progress&nbsp;&#8230;<\/strong><\/p>\n<ul>\n<li>Caller: &#8220;Sir, no amount is too&nbsp;small.&#8221;<\/li>\n<li>Tom: &#8220;Well, I make like ten cents a day punching out plates. How about a cent a&nbsp;week?&#8221;<\/li>\n<li>Caller: &#8220;One&nbsp;cent?&#8221;<\/li>\n<li>Tom:&nbsp;&#8220;Yeah.&#8221;<\/li>\n<li>Caller: &#8220;Does this organization match&nbsp;donations?&#8221;<\/li>\n<li>Tom: &#8220;I dunno. <span class=\"caps\">HEY<\/span> <span class=\"caps\">SCREW<\/span>! Do you guys do matching donations? &#8230; Whoa. Whoa! <span class=\"caps\">WHOA<\/span>!&#8221;<\/li>\n<li>Tom: &#8220;No, it&#8217;s going to just be the one&nbsp;cent.&#8221;<\/li>\n<li>Caller: &#8220;Is there a better number to reach you&nbsp;at?&#8221;<\/li>\n<li>Tom: &#8220;Well, I got a cell phone in the toilet, but I don&#8217;t want to give that&nbsp;out.&#8221;<\/li>\n<\/ul>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"alumni"}}]},{"title":"Those Clever Kids: Since You\u2019ve Been\u00a0Gone","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/since-youve-been-gone","rel":"alternate"}},"published":"2014-03-04T00:00:00-05:00","updated":"2014-03-04T00:00:00-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2014-03-04:\/since-youve-been-gone","summary":"<h1>Those Clever Kids: Since You&#8217;ve Been&nbsp;Gone<\/h1>\n<h2>2014-03-04<\/h2>\n<p><em>What I&#8217;ve been up to since last I posted an&nbsp;entry<\/em><\/p>\n<p>I&#8217;m coming to the end of another contract and realizing just how out-of-date this portfolio is. Rather than try to catch up with an endless series of posts \u2026<\/p>","content":"<h1>Those Clever Kids: Since You&#8217;ve Been&nbsp;Gone<\/h1>\n<h2>2014-03-04<\/h2>\n<p><em>What I&#8217;ve been up to since last I posted an&nbsp;entry<\/em><\/p>\n<p>I&#8217;m coming to the end of another contract and realizing just how out-of-date this portfolio is. Rather than try to catch up with an endless series of posts, here&#8217;s a summary of things I&#8217;ve been&nbsp;doing:<\/p>\n<h3>JavaScript<\/h3>\n<ul>\n<li>Used Backbone.js in a credit card fraud detection system to allow users to drag and drop one or more suspicious transactions into a sort of shopping cart and then review and act on the&nbsp;transactions.<\/li>\n<li>I&#8217;m currently using Backbone.js and D3 to create interactive elements for a <span class=\"caps\">MOOC<\/span> system at an Ivy League graduate school. The objects are written in Coffeescript and styled via <span class=\"caps\">SASS<\/span>. Each interactive is designed to be a reusable element that can be plugged into any course to illustrate the relevant&nbsp;concept.<\/li>\n<\/ul>\n<h3>Responsive&nbsp;Design<\/h3>\n<ul>\n<li>Used <a href=\"https:\/\/github.com\/gregmuellegger\/django-mobile\" target=\"_blank\">django-mobile<\/a> and various thumbnail packages to create responsive sites for clients including <a href=\"http:\/\/smallarmy.net\/\" target=\"_blank\">Small Army&#8217;s new&nbsp;site.<\/a><\/li>\n<li>Integrated Django&#8217;s <a href=\"https:\/\/github.com\/philippWassibauer\/templated-emails\" target=\"_blank\">templated-emails<\/a> package with django-notifications to send responsive emails (with a plain text fallback) to clients in a Pinterest-clone site (that also features a responsive design). I created a custom backend for notifications that has been <a href=\"https:\/\/github.com\/philippWassibauer\/templated-emails\/pull\/10\" target=\"_blank\">integrated into the templated-emails&nbsp;package.<\/a><\/li>\n<\/ul>\n<h3>APIs and&nbsp;Data<\/h3>\n<ul>\n<li>Used django-tastypie to create a <span class=\"caps\">REST<\/span> <span class=\"caps\">API<\/span> on top of the existing site logic to power <a href=\"http:\/\/killscreendaily.com\/\" target=\"_blank\">Killscreen&#8217;s new design.<\/a>&nbsp;I added <a href=\"https:\/\/github.com\/dstegelman\/django-tastypie-cache\" target=\"_blank\">this package<\/a> for caching tastypie responses and patched it support the DEFAULT_FORMATS setting (<a href=\"https:\/\/github.com\/dstegelman\/django-tastypie-cache\/pull\/1\" target=\"_blank\">pull request<\/a>) because it bugs me to always have to add &#8220;format=json&#8221; to the <span class=\"caps\">API<\/span> URLs when testing&nbsp;:)<\/li>\n<li>Working with django-tastypie along with this <a href=\"https:\/\/github.com\/wlanslovenija\/django-tastypie-mongoengine\" target=\"_blank\">mongoengine add-on<\/a>&nbsp;in the <span class=\"caps\">MOOC<\/span> site to power student interaction and to track metrics and user state. I&#8217;m currently neck-deep in MongoDB learning how to aggregate and filter what promises to be massive amounts of data on each interactive element described above. The project has been a great introduction to MongoDB and where it works well in Django. I&#8217;ve been hesitant about NoSQL up until this and still have my suspicions about developers who see it as a panacea (which is apparently ancient Greek for &#8220;not having to worry about the data model at all&#8221;), but I can see a number of places on existing projects where it would be an&nbsp;improvement.<\/li>\n<li>Built the site and product for <a href=\"http:\/\/groundenergysupport.com\/\" target=\"_blank\">Ground Energy<\/a>. This has been a huge and hugely rewarding job starting in March of 2010 that deserves its own post. Relevant to this section, the product has 5 tables with millions of rows each representing responses from client installations on a minute-by-minute basis. In spite of the size of the data and the growth rate, I&#8217;ve tuned the PostgreSQL back-end and Django to deliver real-time reporting to JavaScript-powered&nbsp;graphs.<\/li>\n<li>Integrated the Ecobee <span class=\"caps\">API<\/span> to make Ecobee thermostats a first-class citizen in <a href=\"http:\/\/groundenergysupport.com\/\" target=\"_blank\">Ground Energy<\/a>, allowing owners to track their geothermal&nbsp;efficiency.<\/li>\n<li>A fun &#8220;glue&#8221; job for <a href=\"http:\/\/www.mycoldfront.com\/\" target=\"_blank\">Coldfront<\/a>, integrating with <a href=\"https:\/\/developer.bigcommerce.com\/api\/\" target=\"_blank\">BigCommerce&#8217;s <span class=\"caps\">API<\/span><\/a>&nbsp;on one side to find new orders and then sending the orders to the shipping company by POSTing <span class=\"caps\">XML<\/span> to an endpoint. The shipping company&#8217;s tech is, as you can surmise, a bit old-school, so checking the order status means polling a mailbox for responses on a regular basis using Python&#8217;s <a href=\"http:\/\/docs.python.org\/2\/library\/mailbox.html\" target=\"_blank\">mailbox<\/a>&nbsp;and parsing the&nbsp;results.<\/li>\n<li>Various jobs to integrate with Facebook and Twitter&#8217;s APIs, including a (since deceased) Django-powered Facebook application for Solidworks called <a href=\"http:\/\/files.solidworks.com\/Education_Europe\/SolidWorks-email-20Jul12_ENG.html\" target=\"_blank\">&#8220;Professor Cadmore&#8217;s&nbsp;Challenge&#8221;.<\/a><\/li>\n<\/ul>\n<h3>Sites, Deployment and&nbsp;Performance<\/h3>\n<ul>\n<li>A series of related beer sites (and don&#8217;t think I didn&#8217;t smile typing &#8220;startapp beer&#8221; in Django&#8217;s management console) for <a href=\"http:\/\/www.nhdist.com\/\" target=\"_blank\"><span class=\"caps\">NH<\/span> Distributors<\/a>, <a href=\"http:\/\/www.bellavancebev.com\/\" target=\"_blank\">Bellavance Beverage<\/a> and <a href=\"http:\/\/www.clarkedistributors.com\/\" target=\"_blank\">Clarke Distributors<\/a> with <a href=\"http:\/\/microarts.com\/\" target=\"_blank\">Microarts<\/a>.<\/li>\n<li>Worked directly with the founders of <a href=\"http:\/\/convenientmd.com\/\" target=\"_blank\">ConvenientMD<\/a>&nbsp;to deliver their launch site with a content management system and tools for managing locations and other business&nbsp;information.<\/li>\n<li>Moved <a href=\"https:\/\/www.ctbonline.com\/\" target=\"_blank\">Community Trust Bank<\/a>&nbsp;to a three-server-plus-load-balancer setup at Rackspace which meant learning how to modify my typical Fabric deployment script to manage separate web servers and a database&nbsp;server.<\/li>\n<li>Used New Relic on a number of client sites to help identify bottlenecks and areas performance could be improved. New Relic has become an indispensable tool in a such a short time, especially the short time when you get full access for free and are able to step down into slow running queries, look at <span class=\"caps\">EXPLAIN<\/span> statements and figure out how to get huge wins for little&nbsp;investment.<\/li>\n<li>I&#8217;ve become the &#8220;Django guy&#8221; at my host of choice (<a href=\"https:\/\/www.webfaction.com\/\" target=\"_blank\">WebFaction<\/a>). What this has meant in practice is clients with ancient Django sites who have lost touch with their developer (either over time or on purpose in some cases) come to me after they already have a bit of an emergency. WebFaction upgraded a number of servers in 2013 which caused a problem for anyone still running on a pre-1.0 version of Django. Another topic worthy of its own post; for now let&#8217;s just say I learned a lot about spelunking and how to dig up old versions of Django for local&nbsp;testing.<\/li>\n<li>Started using <a href=\"http:\/\/www.vagrantup.com\/\" target=\"_blank\">Vagrant boxes<\/a> to replicate the live environment on a project. I&#8217;m not ready to give up my current virtualenv-based Python development process for most projects because it does a good job of replicating the important stuff and because I feel like being able to swap project development from Mac to Windows without a hitch is a decent indicator that I&#8217;ve done a good job of keeping things loosely-coupled, but Vagrant is a good solution for cases when the live environment is important or hard to replicate. I also would like to investigate using Vagrant plus <a href=\"http:\/\/www.ansible.com\/home\" target=\"_blank\">Ansible<\/a> (or something similar) to be able to deploy projects directly to <span class=\"caps\">AWS<\/span> and spin up additional resources as needed with a minimum of sysadmin&nbsp;work.<\/li>\n<\/ul>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"backbone"}},{"@attributes":{"term":"javascript"}},{"@attributes":{"term":"django"}},{"@attributes":{"term":"apis"}},{"@attributes":{"term":"mongodb"}},{"@attributes":{"term":"rest"}},{"@attributes":{"term":"tastypie"}},{"@attributes":{"term":"facebook"}},{"@attributes":{"term":"mooc"}},{"@attributes":{"term":"webfaction"}},{"@attributes":{"term":"newrelic"}}]},{"title":"Checking on memcache\u2019s\u00a0health","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/checking-memcaches-health.html","rel":"alternate"}},"published":"2014-02-24T13:21:53-05:00","updated":"2014-02-24T13:21:53-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2014-02-24:\/checking-memcaches-health.html","summary":"<h1>Checking on memcache&#8217;s&nbsp;health<\/h1>\n<p>From time to time a client on WebFaction will experience a hiccup in their memcache process. It&#8217;s not obvious at first unless the site is under heavy load (New Relic is a huge help in diagnosing the problem); this post is just a central \u2026<\/p>","content":"<h1>Checking on memcache&#8217;s&nbsp;health<\/h1>\n<p>From time to time a client on WebFaction will experience a hiccup in their memcache process. It&#8217;s not obvious at first unless the site is under heavy load (New Relic is a huge help in diagnosing the problem); this post is just a central dumping ground for links related to fixing the&nbsp;issue.<\/p>\n<ul>\n<li><a href=\"https:\/\/docs.webfaction.com\/software\/memcached.html\">Setting up memcache to a sock&nbsp;file<\/a><\/li>\n<li><a href=\"https:\/\/community.webfaction.com\/questions\/8553\/how-to-determine-memory-consumption\">Figuring out how much memory you have&nbsp;available<\/a><\/li>\n<li><a href=\"https:\/\/community.webfaction.com\/questions\/2749\/script-to-view-memory-usage-and-running-proccess\">Webfaction script to check memory use by&nbsp;process<\/a><\/li>\n<li><a href=\"http:\/\/stackoverflow.com\/questions\/1690882\/how-do-i-see-if-memcached-is-already-running-on-my-chosen-port\">Checking if memcache is running on a&nbsp;port<\/a><\/li>\n<li><a href=\"http:\/\/stackoverflow.com\/a\/6989742\/7376\">Checking whether Django is actually using the&nbsp;cache<\/a><\/li>\n<\/ul>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"django"}},{"@attributes":{"term":"memcache"}},{"@attributes":{"term":"webfaction"}}]},{"title":"Lacey","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/lacey.html","rel":"alternate"}},"published":"2013-11-18T08:40:33-05:00","updated":"2013-11-18T08:40:33-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-11-18:\/lacey.html","summary":"<h1>Lacey<\/h1>\n<p><em><span class=\"dquo\">&#8220;<\/span>I&#8217;ve put relatives in the ground with fewer tears.&#8221;<\/em> &mdash; my&nbsp;mom<\/p>\n<p>Last Sunday night we had to say goodbye to the gentlest soul I will probably ever meet. I&#8217;ve tried to figure out how to write this since then but it all comes out as a jumble \u2026<\/p>","content":"<h1>Lacey<\/h1>\n<p><em><span class=\"dquo\">&#8220;<\/span>I&#8217;ve put relatives in the ground with fewer tears.&#8221;<\/em> &mdash; my&nbsp;mom<\/p>\n<p>Last Sunday night we had to say goodbye to the gentlest soul I will probably ever meet. I&#8217;ve tried to figure out how to write this since then but it all comes out as a jumble so I&#8217;ll try just starting at the beginning. Lacey came to us as a foster dog through the beagle group Michelle worked with. I didn&#8217;t think anything of it when she showed up. We&#8217;d fostered a couple of other dogs at that point and the idea was to keep them happy just long enough to get them adopted out. Frankly, my immediate reaction when Michelle brought her home was, &#8220;That&#8217;s kind of a homely dog.&#8221; I am a stupid and shallow person (and Lacey was 150% of the weight she was later on). That thought was quickly replaced by, &#8220;<em>Holy shit<\/em>, Abbie is attacking her&#8221; as Abbie, a giant coward, leapt on Lacey&#8217;s back before the poor girl could even get in the house. Thankfully that was the only time they ever had a problem, which meant two weeks or so later we started the process to adopt Lacey. The thought process went like&nbsp;this:<\/p>\n<ul>\n<li>No one adopts a ten year-old dog unless they&#8217;re a creep who wants to teach kids about&nbsp;death<\/li>\n<li>This isn&#8217;t a dog that&#8217;s bounced from foster home to foster home, she spent the first 10 years of life with an elderly couple until the lady died and the husband moved into a home where he could not have&nbsp;pets<\/li>\n<li>Mirable dictu, Abbie actually gets along with this&nbsp;dog<\/li>\n<li>Lacey may be the most laid-back dog of all&nbsp;time<\/li>\n<\/ul>\n<p>When people asked about the new dog, my short-hand for explaining was this: if a group of Buddhist monks showed up at the door saying they thought Lacey was the 15th incarnation of the Buddha, I&#8217;d happily hand her over so she could assume her role. I also started saying some day a half century or so from now, a young couple would be adopting her telling the story of how she&#8217;d lived with this older couple all her life and was about 10. The real problem was at some point I internalized that story and began to believe it. She seemed to be an unstoppable, self-regulating machine. She knew what she needed and made sure she got it. She ate a tissue a day. Once in a while two, some days none, but basically a tissue a day. She didn&#8217;t always consume them, but one needed to at least be rendered or we had a&nbsp;problem:<\/p>\n<iframe width=\"800\" height=\"450\" src=\"https:\/\/www.youtube.com\/embed\/ZJeyQ8R_Ty0?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen title=\"Lacey Loves Tissues\"><\/iframe>\n\n<p>This was driven home after we came back from London: she&#8217;d been boarded for 8 days and upon arriving home, she consumed about 8 tissues that afternoon. She was a garbage disposal: put anything you wanted (more accurately, anything she wanted) in, get a single, over-sized brick out each day. But none of that really mattered. The thing that was so special is so hard to describe. Everyone thinks their pet is special and everyone should, but I&#8217;ve been around enough dogs to feel confident saying this one was  special. To say she was a little person doesn&#8217;t do it justice. I can&#8217;t quite phrase it how I want, but say this: she&#8217;s the only dog I&#8217;ve known whose opinion mattered to me. Obviously you want to do do right by a pet, but with Lacey I always felt like she was quietly grading your performance, laying just out of sight on whichever bed struck her fancy that day with one eye cracked to see if you were planning on eating&nbsp;anything.<\/p>\n<p>She&#8217;s the only damn dog I ever suspected of being <em>intentionally<\/em> funny. Lots of dogs are goofy and amusing, lots of pets seem to have comedic timing, but this was a straight man on par with Buster Keaton (see about 8 seconds into the video above). If nothing else, she was aware. Always aware. She&#8217;s the one dog I&#8217;ve had that actually buried things like in cartoons. Give her a treat that was wider than her mouth or give her a toy she decided to care about and she&#8217;d be at the door wagging her tail to go out, like&nbsp;so:<\/p>\n<iframe width=\"800\" height=\"450\" src=\"https:\/\/www.youtube.com\/embed\/fJYjY6Jdis8?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen title=\"Lacey and the Carrot v Molly\"><\/iframe>\n\n<p>Once outside, the burial was a process: because she went out without a line, you had to keep an eye on her but you couldn&#8217;t be seen doing so or she&#8217;d stop and wait. If she had already buried the item, she&#8217;d dig it up and go find a different place. So we&#8217;d hide at the door and peek around corners until she&#8217;d finished &#8220;burying&#8221; the thing (which usually amounted to finding a pile of leaves or grass deep enough to cover it with so she could easily retrieve it&nbsp;later).<\/p>\n<p>I intended to write about her various illnesses and the things we went through in order to get them on the web and possibly help someone searching for a weird confluence of conditions in the future, but having gotten this far I don&#8217;t really have any interest in that right now. I just want her back. The last week&#8217;s been such a struggle not just because of the loss, but because it doesn&#8217;t hit in any obvious way. You don&#8217;t walk past a dog bed and get hit with a rush of emotion; missing Lacey is missing something subtle in your day. A sort of leitmotif (for lack of a less pretentious description) that sits unnoticed but improves things immeasurably all the same. We hit the end of the day and time to feed &#8220;the dogs&#8221; and that about does it for me. Like with losing my mom, the biggest bitch of the thing is the one person I want to help me through this is the one I don&#8217;t have. I want for all the world to get one last &#8220;mind meld&#8221; with her when she&#8217;d sit still and let you rest your forehead against the top of her head and if you couldn&#8217;t find peace there, there wasn&#8217;t much hope for you at all. I don&#8217;t know where I&#8217;m going to find another grief counselor like&nbsp;this:<\/p>\n<p><img src=\"http:\/\/s3.amazonaws.com\/imgly_production\/2456064\/large.jpg\" \/><\/p>\n<p>Her remains will come back to us today or tomorrow in a box, just like Abbie&#8217;s that still sitting on my desk. I never quite figured out why we hadn&#8217;t buried Abbie under her quince tree, but I think I get it now: they should go there together and I promise to make sure the carrot gets buried deep so no one else finds it Lace.&nbsp;Bye.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"lacey"}}]},{"title":"Installing New Relic Plugin Agent on Shared\u00a0Hosting","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/installing-new-relic-plugin-agent-shared-hosting.html","rel":"alternate"}},"published":"2013-10-05T10:57:13-04:00","updated":"2013-10-05T10:57:13-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-10-05:\/installing-new-relic-plugin-agent-shared-hosting.html","summary":"<h1>Installing New Relic Plugin Agent on Shared&nbsp;Hosting<\/h1>\n<p>New Relic&#8217;s basic agent (and the free 30 days of Pro we got up front) have been a huge help on one of my largest ongoing projects. Wanting more insight into our server after a mystery incident yesterday morning, I&#8217;ve \u2026<\/p>","content":"<h1>Installing New Relic Plugin Agent on Shared&nbsp;Hosting<\/h1>\n<p>New Relic&#8217;s basic agent (and the free 30 days of Pro we got up front) have been a huge help on one of my largest ongoing projects. Wanting more insight into our server after a mystery incident yesterday morning, I&#8217;ve started adding plugins. I started with a plugin for Postgres (because that seemed to be the source of our mystery); I had to use <a href=\"https:\/\/rpm.newrelic.com\/accounts\/230318\/plugins\/directory\/30\">this one<\/a> because we&#8217;re on a shared host with WebFaction. It all went fine after I figured out how to get Ruby&#8217;s bundle\/ bundler installed in a local account and then I even daemonized it with a <a href=\"https:\/\/gist.github.com\/tclancy\/6841979\">simple script<\/a>. That gave me a bunch of statistics on our two databases and a number of pretty graphs. I have no idea what any of it means yet, but I&#8217;ll take the info and figure out what it means (and maybe finish reading <em><a href=\"http:\/\/www.amazon.com\/PostgreSQL-9-0-High-Performance-ebook\/dp\/B0057G9RUG\/ref=tmm_kin_swatch_0?_encoding=UTF8&amp;sr=8-2&amp;qid=1380985344\">PostgreSQL 9.0 High Performance<\/a><\/em>). Plus the plugin provides alerts via New Relic so that&#8217;s a handy bit of insight by&nbsp;itself.<\/p>\n<p>Happy with that plugin, I&#8217;m now in the process of installing <a href=\"https:\/\/github.com\/MeetMe\/newrelic-plugin-agent\">a suite of plugins for New Relic<\/a>. Happily those are provided in Python. Even better, it&#8217;s all install-able via pip. On the downside, you hate to see a bug report like this on the front&nbsp;page:<\/p>\n<blockquote>\n<p>Version 1.0.12 has a <span class=\"caps\">SERIOUS<\/span> uninstallation bug in the file manifest that <strong>will remove all the files on your filesystem<\/strong> if you try and do a pip remove&nbsp;newrelic_plugin_agent.<\/p>\n<\/blockquote>\n<p>So there&#8217;s that. In addition, the package assumes you own the box. Because I do not, I need to be a bit smarter and give them a hand. In my .bash_profile I have the&nbsp;following: <code>export PIP_PATH=\/home\/groundenergy\/lib\/python2.7<\/code>. This is where I want things to be installed rather than the default Python path. <em>In theory<\/em> that should be enough to pass in to&nbsp;allow <code>pip install newrelic-plugin-agent --install-option=\"--prefix=$PIP_PATH\"<\/code> to work. Except this package <a href=\"https:\/\/github.com\/MeetMe\/newrelic-plugin-agent\/blob\/master\/setup.py#L56\">assumes you&#8217;re either installing into a virtualenv or want to install into \/opt<\/a>. I&#8217;m not doing either. I tend to be a bit lazy about virtualenvs on production servers, which I am starting to question, but that&#8217;s not really relevant here. In order to get around the problem, I did the following before&nbsp;installing: <code>export VIRTUAL_ENV=\/path\/i\/really\/want<\/code>.<\/p>\n<p>That&#8217;s where I am right now but I figured the post might help someone and it gives me a place to add further&nbsp;notes.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"newrelic"}}]},{"title":"Setting Up Server SSH\u00a0Access","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/setting-server-ssh-access.html","rel":"alternate"}},"published":"2013-10-04T11:55:21-04:00","updated":"2013-10-04T11:55:21-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-10-04:\/setting-server-ssh-access.html","summary":"<h1>Setting Up Server <span class=\"caps\">SSH<\/span>&nbsp;Access<\/h1>\n<p>Because I always forget and because I am getting into the good habit of connecting via <span class=\"caps\">SSH<\/span> for everything, here&#8217;s a note to myself on how to get <span class=\"caps\">SSH<\/span> deployment keys running in my typical&nbsp;process:<\/p>\n<ul>\n<li><a href=\"https:\/\/help.github.com\/articles\/generating-ssh-keys\">Use or generate a&nbsp;key<\/a><\/li>\n<li>Add the key \u2026<\/li><\/ul>","content":"<h1>Setting Up Server <span class=\"caps\">SSH<\/span>&nbsp;Access<\/h1>\n<p>Because I always forget and because I am getting into the good habit of connecting via <span class=\"caps\">SSH<\/span> for everything, here&#8217;s a note to myself on how to get <span class=\"caps\">SSH<\/span> deployment keys running in my typical&nbsp;process:<\/p>\n<ul>\n<li><a href=\"https:\/\/help.github.com\/articles\/generating-ssh-keys\">Use or generate a&nbsp;key<\/a><\/li>\n<li>Add the key as a read-only deployment key on the Bitbucket&nbsp;repository<\/li>\n<li><a href=\"https:\/\/help.github.com\/articles\/error-permission-denied-publickey#make-sure-you-have-a-key-and-ssh-is-using-it\">Register the key&nbsp;locally<\/a><\/li>\n<li>When the registration fails, <a href=\"http:\/\/stackoverflow.com\/a\/17848593\/7376\">turn on the <span class=\"caps\">SSH<\/span> agent&nbsp;first<\/a><\/li>\n<li>Set up a ~\/.ssh\/config file and&nbsp;run <code>chmod 600<\/code> on&nbsp;it<\/li>\n<li>Alternatively, just use <a href=\"http:\/\/stackoverflow.com\/a\/11832171\/7376\">this solution<\/a> to brute force&nbsp;it: <code>ssh-add ~\/.ssh\/my_private_key &amp;&gt;\/dev\/null<\/code><\/li>\n<li>Probably need to&nbsp;add <code>eval `ssh-agent -s`  &amp;&gt;\/dev\/null<\/code> in the profile right before it (I think it depends on whether the key file has a default file name like&nbsp;&#8220;id_rsa&#8221;)<\/li>\n<\/ul>\n<p>Edited again because apparently I&#8217;m an idiot and that&#8217;s a bad&nbsp;idea:<\/p>\n<div class=\"highlight\"><pre><span><\/span><code>trap &#39;[ -n &quot;$SSH_AGENT_PID&quot; ] &amp;&amp; eval $(\/usr\/bin\/ssh-agent -k)&#39; 0\neval $(ssh-agent -s)\nssh-add ~\/.ssh\/bitbucket_read\n<\/code><\/pre><\/div>\n\n<blockquote>\n<p>The &#8216;trap&#8217; line will kill the ssh-agent when you log out.\nYou can also feel free to add &#8220;&amp;&gt;\/dev\/null&#8221; to the end of those lines to silence them, once you are sure they are&nbsp;working.<\/p>\n<\/blockquote>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"ssh"}},{"@attributes":{"term":"notes"}}]},{"title":"The Next 25\u00a0Years","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/next-25-years.html","rel":"alternate"}},"published":"2013-09-25T19:20:24-04:00","updated":"2013-09-25T19:20:24-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-09-25:\/next-25-years.html","summary":"<h1>The Next 25&nbsp;Years<\/h1>\n<p>As befits what was an all-male school, the highlight of my 20th high school reunion occurred in the men&#8217;s room near the end of the night (with a conversation at the&nbsp;urinals).<\/p>\n<p>Him: &#8220;What brings you&nbsp;here?&#8221;<\/p>\n<p>Me [<em>assuming he meant something other than the \u2026<\/em><\/p>","content":"<h1>The Next 25&nbsp;Years<\/h1>\n<p>As befits what was an all-male school, the highlight of my 20th high school reunion occurred in the men&#8217;s room near the end of the night (with a conversation at the&nbsp;urinals).<\/p>\n<p>Him: &#8220;What brings you&nbsp;here?&#8221;<\/p>\n<p>Me [<em>assuming he meant something other than the free bar bladder emergency<\/em>]: &#8220;Class of&nbsp;&#8216;93.&#8221;<\/p>\n<p>Him: &#8220;&#8216;68. We did pretty well: 42 of us graduated, 39 survive, 17 showed&nbsp;up.&#8221;<\/p>\n<p>Me: &#8220;We only had&nbsp;5.&#8221;<\/p>\n<p>Him: &#8220;Yeah, it goes in cycles, once you get old enough they start coming back. It&#8217;s nice: 45 years and 0 personal growth. They&#8217;re all still bitching about the same&nbsp;things.&#8221;<\/p>\n<p>Me: &#8220;Well, you&#8217;ve given me something to shoot for, even the littlest bit of personal growth in 25&nbsp;years.&#8221;<\/p>\n<p>It&#8217;s one of the few times in life I wished I had a business card, so I could hand it over and ask, &#8220;Can we be&nbsp;besties?&#8221;<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"\u201cRich Get Richer\u201d: A Play in One\u00a0Act","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/rich-get-richer-play-one-act.html","rel":"alternate"}},"published":"2013-08-18T16:52:10-04:00","updated":"2013-08-18T16:52:10-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-08-18:\/rich-get-richer-play-one-act.html","summary":"<h1><span class=\"dquo\">&#8220;<\/span>Rich Get Richer&#8221;: A Play in One&nbsp;Act<\/h1>\n<p><span class=\"caps\">EXT<\/span> - <span class=\"caps\">DAY<\/span>: <em>An outdoor concert\/ festival between acts. Our hero, <span class=\"caps\">TOM<\/span>, just growing into his impossibly handsome looks in his late 30s strides purposefully toward Port-a-Potty Row. His path is interrupted by <span class=\"caps\">THE<\/span> <span class=\"caps\">STRANGER<\/span>, a younger man. Before <span class=\"caps\">TOM<\/span> knows what is \u2026<\/em><\/p>","content":"<h1><span class=\"dquo\">&#8220;<\/span>Rich Get Richer&#8221;: A Play in One&nbsp;Act<\/h1>\n<p><span class=\"caps\">EXT<\/span> - <span class=\"caps\">DAY<\/span>: <em>An outdoor concert\/ festival between acts. Our hero, <span class=\"caps\">TOM<\/span>, just growing into his impossibly handsome looks in his late 30s strides purposefully toward Port-a-Potty Row. His path is interrupted by <span class=\"caps\">THE<\/span> <span class=\"caps\">STRANGER<\/span>, a younger man. Before <span class=\"caps\">TOM<\/span> knows what is happening, he has been embraced in a full-arm handshake and pulled into a chest&nbsp;bump.<\/em><\/p>\n<p><span class=\"caps\">STRANGER<\/span>: <a href=\"http:\/\/www.theguardian.com\/football\/blog\/2013\/aug\/17\/david-moyes-manchester-united\">&#8220;Thanks for David&nbsp;Moyes!&#8221;<\/a><\/p>\n<p><span class=\"caps\">TOM<\/span> [<em>realizing he is wearing an Everton jersey, smiles sheepishly and laughs<\/em>]<\/p>\n<p><span class=\"caps\">STRANGER<\/span>: &#8220;Did you like that, didja? Saw you coming a mile&nbsp;away!&#8221;<\/p>\n<p><span class=\"caps\">TOM<\/span> [<em>still laughing<\/em>]: &#8220;No, not really,&nbsp;no.&#8221;<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"playsinoneact"}}]},{"title":"Popular with Jerks\u00a025-40","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/popular-jerks-25-40.html","rel":"alternate"}},"published":"2013-08-03T11:38:45-04:00","updated":"2013-08-03T11:38:45-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-08-03:\/popular-jerks-25-40.html","summary":"<h1>Popular with Jerks&nbsp;25-40<\/h1>\n<p>Washing my high-horsepower, low-milage car as a break from my computer-based job while wearing Local Sports Team&#8217;s baseball hat and streaming music made by white males (see below) from my Apple phone to a Bluetooth speaker, I thought to myself, &#8220;Boy, you need to step \u2026<\/p>","content":"<h1>Popular with Jerks&nbsp;25-40<\/h1>\n<p>Washing my high-horsepower, low-milage car as a break from my computer-based job while wearing Local Sports Team&#8217;s baseball hat and streaming music made by white males (see below) from my Apple phone to a Bluetooth speaker, I thought to myself, &#8220;Boy, you need to step out of your demographic more&nbsp;often.&#8221;<\/p>\n<p>The bitch of it is I can&#8217;t even have a couple of microbrews while contemplating&nbsp;how.<\/p>\n<h2>An Aside Possibly Longer Than the&nbsp;Post<\/h2>\n<p>Reflecting on the music, <a href=\"http:\/\/www.last.fm\/user\/yerfatma\/library\">it is <em>really<\/em> white<\/a>. I don&#8217;t think everything gets sent to Last.fm, but it&#8217;s pretty representative and the first black artist is #25 on the list. There are plenty of black <em>guys<\/em>, but the one thing most of them have in common is they&#8217;re dead. Fela Kuti, Bob Marley, a bunch of jazz guys from the &#8216;60s (and you can only just count them because it&#8217;s oh-so demo perfect for a college-educated white guy to listen to old jazz). And there&#8217;s a hell of a lot more black guys then there are women of any color. I think the only artist on my phone that might qualify is The Scissor Sisters and that feels like stretching a point. Time to start exploring again instead of sticking with what I&nbsp;know.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"music"}}]},{"title":"Django Command to Back Up to Amazon S3 with\u00a0Python","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/django-command-back-amazon-s3-python.html","rel":"alternate"}},"published":"2013-06-29T17:00:13-04:00","updated":"2013-06-29T17:00:13-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-06-29:\/django-command-back-amazon-s3-python.html","summary":"<h1>Django Command to Back Up to Amazon S3 with&nbsp;Python<\/h1>\n<p>If it&#8217;s of use to anyone, I wrote this <a href=\"https:\/\/gist.github.com\/5892498\">fairly thick-headed script<\/a> to look for the most recent versions of files matching one or more patterns in a directory, zip them up and back them up to Amazon&#8217;s \u2026<\/p>","content":"<h1>Django Command to Back Up to Amazon S3 with&nbsp;Python<\/h1>\n<p>If it&#8217;s of use to anyone, I wrote this <a href=\"https:\/\/gist.github.com\/5892498\">fairly thick-headed script<\/a> to look for the most recent versions of files matching one or more patterns in a directory, zip them up and back them up to Amazon&#8217;s S3 Service using <a href=\"http:\/\/boto.readthedocs.org\/en\/latest\/\">boto<\/a>. It also deletes <em>all<\/em> files in the directory that are older than a given number of days (unless the file is being backed up in the current run). Even includes a bit of progress feedback, though nothing&nbsp;fancy.<\/p>\n<p>The script is designed to be a Django management command because I&#8217;m lazy and like to keep all site-related files under Django, but there&#8217;s not much coupling: just define your keys and patterns in the file, get rid of the Django &#8220;class Command&#8221; stuff and turn it into a normal script if you like (you&#8217;ll have to find a new way to send email notifications on error if you&nbsp;do). <\/p>\n<p>It ain&#8217;t pretty and the parameter handling is crap, but it&#8217;s a&nbsp;start.<\/p>\n<script src=\"https:\/\/gist.github.com\/tclancy\/5892498.js\"><\/script>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"code"}},{"@attributes":{"term":"boto"}},{"@attributes":{"term":"python"}}]},{"title":"MySQL and Python on OSX","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/mysql-and-python-osx.html","rel":"alternate"}},"published":"2013-06-25T17:11:01-04:00","updated":"2013-06-25T17:11:01-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-06-25:\/mysql-and-python-osx.html","summary":"<h1>MySQL and Python on <span class=\"caps\">OSX<\/span><\/h1>\n<p>Because I rarely use MySQL nowadays and because how often do you set up a new machine, this is a reminder to myself on how to get mysql-python installed in a&nbsp;virtualenv<\/p>\n<ol>\n<li>Add \/usr\/local\/mysql\/bin to your path (permanently in your&nbsp;.profile)<\/li>\n<li>If \u2026<\/li><\/ol>","content":"<h1>MySQL and Python on <span class=\"caps\">OSX<\/span><\/h1>\n<p>Because I rarely use MySQL nowadays and because how often do you set up a new machine, this is a reminder to myself on how to get mysql-python installed in a&nbsp;virtualenv<\/p>\n<ol>\n<li>Add \/usr\/local\/mysql\/bin to your path (permanently in your&nbsp;.profile)<\/li>\n<li>If &#8220;pip install mysql-python&#8221; fails, try <a href=\"http:\/\/stackoverflow.com\/a\/6853460\/7376\">this version<\/a>: &#8216;sudo <span class=\"caps\">ARCHFLAGS<\/span>=&#8221;-arch $(uname -m)&#8221; pip install&nbsp;mysql-python&#8217;<\/li>\n<li>Realize none of that made much of a difference and then <a href=\"http:\/\/learninglamp.wordpress.com\/2010\/02\/21\/mysqldb-python-mysql-and-os-x-a-match-made-in-satans-bum\/\">blindly copy <span class=\"amp\">&amp;<\/span> paste from&nbsp;here<\/a><\/li>\n<li>Discover that&#8217;s still not quite everything and make <a href=\"http:\/\/stackoverflow.com\/a\/6967816\/7376\">this symbolic link<\/a> (unless the paths change between now and when you find&nbsp;this)<\/li>\n<\/ol>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"mysql"}},{"@attributes":{"term":"python"}},{"@attributes":{"term":"osx"}}]},{"title":"Top Tips for\u00a0Patients","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/top-tips-patients.html","rel":"alternate"}},"published":"2013-06-25T15:17:45-04:00","updated":"2013-06-25T15:17:45-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-06-25:\/top-tips-patients.html","summary":"<h1>Top Tips for&nbsp;Patients<\/h1>\n<p>Having recently had shoulder surgery, some&nbsp;advice:<\/p>\n<ul>\n<li>Memorizing your patient number will amuse the&nbsp;nurses<\/li>\n<li>Conversely, making your first statement after coming out of general anesthesia, &#8220;It was supposed to be the other arm&#8221; will not amuse&nbsp;them<\/li>\n<li>Like the man said, you can&#8217;t buy \u2026<\/li><\/ul>","content":"<h1>Top Tips for&nbsp;Patients<\/h1>\n<p>Having recently had shoulder surgery, some&nbsp;advice:<\/p>\n<ul>\n<li>Memorizing your patient number will amuse the&nbsp;nurses<\/li>\n<li>Conversely, making your first statement after coming out of general anesthesia, &#8220;It was supposed to be the other arm&#8221; will not amuse&nbsp;them<\/li>\n<li>Like the man said, you can&#8217;t buy <span class=\"caps\">IV<\/span> saline bags, you can only rent&nbsp;them<\/li>\n<li>If the light opiate I took for a day and a half was any indication, the constipation would make heroin addiction a no-go for&nbsp;me<\/li>\n<\/ul>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"nonsense"}}]},{"title":"Greener\u00a0Development","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/greener-development.html","rel":"alternate"}},"published":"2013-06-24T15:35:51-04:00","updated":"2013-06-24T15:35:51-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-06-24:\/greener-development.html","summary":"<h1>Greener&nbsp;Development<\/h1>\n<p>A local experience designer, <a href=\"https:\/\/twitter.com\/JC_UX\">James Christie<\/a> has been writing about what he calls <a href=\"http:\/\/jcux.co.uk\/cleanux\/cleanux.html\">&#8220;Clean <span class=\"caps\">UX<\/span>&#8221;<\/a>: designers and developers starting to make conscious choices about code and design that reduce the carbon footprint of web sites. As developer tools and frameworks get better and easier, the risk of bloat \u2026<\/p>","content":"<h1>Greener&nbsp;Development<\/h1>\n<p>A local experience designer, <a href=\"https:\/\/twitter.com\/JC_UX\">James Christie<\/a> has been writing about what he calls <a href=\"http:\/\/jcux.co.uk\/cleanux\/cleanux.html\">&#8220;Clean <span class=\"caps\">UX<\/span>&#8221;<\/a>: designers and developers starting to make conscious choices about code and design that reduce the carbon footprint of web sites. As developer tools and frameworks get better and easier, the risk of bloat increases. The best example may be the military officer wall of badges that every site provides in hopes you will share their article on Latest Hot Site. Including that teeny little bit of JavaScript that ties them all into the page can have <a href=\"http:\/\/jcux.co.uk\/cleanux\/buttons.html\">heavy consequences<\/a>: the little bit of code includes a lot more code. Each individual site is mainly concerned with making their buttons look good across platforms and devices, so they have little incentive to keep their code lean. What&#8217;s the net effect? Christie estimates a million page views (not accounting for caching, admittedly) results in <em>4 Transatlantic flights&#8217; worth of&nbsp;carbon.<\/em><\/p>\n<p>I&#8217;ve been fascinated with the concept and keep bothering him on Twitter with random thoughts. As I&#8217;ve transitioned over the years, becoming less of a front-end developer and more of a back-end dev, I tend to think I&#8217;ve fallen behind on front-end development, but helping new clients with old sites is a regular reminder that as far back as I am from the cutting-edge, I&#8217;m still well in the vanguard. So I think I see an opportunity to improve the situation. There are lots of developers who are pure front-end developers, who either don&#8217;t know or don&#8217;t feel comfortable with scripting their deployments. Lots of shops are still working with a deployment process that consists of two&nbsp;steps:<\/p>\n<ol>\n<li>Make changes&nbsp;locally<\/li>\n<li>Upload changes (or the whole site&nbsp;folder)<\/li>\n<\/ol>\n<p>There&#8217;s nothing wrong with this and with the proliferation of JavaScript APIs and new devices, &#8220;pure&#8221; front-end development (defined here as <span class=\"caps\">HTML<\/span> + <span class=\"caps\">CSS<\/span> + JavaScript) is probably experiencing a comeback. Improving deployment for this kind of development would be an easy place to improve the &#8220;green-ness&#8221; of the development and provide an entry point for additional improvements everyone should make<sup><a href=\"#foot1\">1<\/a><\/sup>. In the most basic form, I see this as a simple executable script (with an optional configuration file in the root of the project) that does the&nbsp;following:<\/p>\n<ul>\n<li>Run <a href=\"http:\/\/en.wikipedia.org\/wiki\/Pngcrush\"><span class=\"caps\">PNGCRUSH<\/span><\/a> or similar over the image files found in or below the root, but don&#8217;t die if the executable doesn&#8217;t exist because <span class=\"caps\">PNGCRUSH<\/span> could mess up some images and the user might want to skip it or define which folders to run it on (first reason for a configuration&nbsp;file)<\/li>\n<li>Compress all JavaScript and <span class=\"caps\">CSS<\/span> files, maybe save them with timestamps in the filenames to make sure the old versions are dumped out of viewers&#8217;&nbsp;caches<\/li>\n<li>Optionally or smartly (imagine a lot of hand-waving here), combine <span class=\"caps\">CSS<\/span>\/ JavaScript files into one large file each. I&#8217;m torn on doing this globally on a project. I still create multiple <span class=\"caps\">CSS<\/span>\/ <span class=\"caps\">JS<\/span> files when they logically belong to sub-sections of a site and it depends on the site whether it&#8217;s more efficient to join them all into one file or to provide a few grouped files (personally I let <a href=\"http:\/\/django-compressor.readthedocs.org\/en\/latest\/\">django-compressor<\/a> do the heavy lifting&nbsp;here).<\/li>\n<li>The last step in the process would be a simple one, but maybe the most valuable: print out a list of all the files changed in the folder since the script last ran. If nothing else, we can encourage users to only upload their changes (while they may also have set their <span class=\"caps\">FTP<\/span> clients to do the same, there&#8217;s no harm in providing the&nbsp;info).<\/li>\n<\/ul>\n<p>Given that setup, version two should provide the ability to upload from the script. It&#8217;s an easy thing to do, it ensures we only upload the altered files and it gives us a wedge to start encouraging better deployment: now that you&#8217;re using this script to do &#8220;smarter&#8221; deployments, why not set up an <span class=\"caps\">SSH<\/span> key(s) on the relevant servers so your deployment is easier and more secure? I&#8217;m not interested in building something that metastasizes into something that <a href=\"http:\/\/en.wikipedia.org\/wiki\/Jamie_Zawinski#Zawinski.27s_law_of_software_envelopment\">reads mail<\/a>, but it would be fun to build something that provides hooks for smarter people than me to come up with better ideas&nbsp;here.<\/p>\n<p><small id=\"foot1\">1. While the Road to Hell may be paved with the best of intentions, I think there&#8217;s a long way to go before we start making things worse.<\/small><\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"green"}},{"@attributes":{"term":"environment"}},{"@attributes":{"term":"webdev"}}]},{"title":"Parochialism","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/parochialism.html","rel":"alternate"}},"published":"2013-06-12T20:41:24-04:00","updated":"2013-06-12T20:41:24-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-06-12:\/parochialism.html","summary":"<h1>Parochialism<\/h1>\n<p>Don&#8217;t do&nbsp;this:<\/p>\n<blockquote class=\"twitter-tweet\" data-width=\"550\"><p lang=\"en\" dir=\"ltr\">The gap between Chicago&#39;s anthem singer and Rene Rancourt is damn hilarious. Best vs&nbsp;worst.<\/p>&mdash; Berkshire.bsky.social (@AndrewBerkshire) <a href=\"https:\/\/twitter.com\/AndrewBerkshire\/status\/344972991404310528?ref_src=twsrc%5Etfw\">June 13, 2013<\/a><\/blockquote>\n<script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script>\n\n<p>At best, it says, &#8220;I&#8217;ve been drinking&#8221;. At worst, it just looks stupid. Rene Rancourt is a thing&mdash; if you&#8217;re \u2026<\/p>","content":"<h1>Parochialism<\/h1>\n<p>Don&#8217;t do&nbsp;this:<\/p>\n<blockquote class=\"twitter-tweet\" data-width=\"550\"><p lang=\"en\" dir=\"ltr\">The gap between Chicago&#39;s anthem singer and Rene Rancourt is damn hilarious. Best vs&nbsp;worst.<\/p>&mdash; Berkshire.bsky.social (@AndrewBerkshire) <a href=\"https:\/\/twitter.com\/AndrewBerkshire\/status\/344972991404310528?ref_src=twsrc%5Etfw\">June 13, 2013<\/a><\/blockquote>\n<script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script>\n\n<p>At best, it says, &#8220;I&#8217;ve been drinking&#8221;. At worst, it just looks stupid. Rene Rancourt is a thing&mdash; if you&#8217;re from New England, he&#8217;s perfect. If you&#8217;re not, I guess he&#8217;s annoying. Regardless, there are 30 teams and I&#8217;m assuming the author could name about &#8230; well, let&#8217;s be generous and say 3 arena singers. Of the other 27 arenas, some probably don&#8217;t have a regular singer and the rest are average. Unless you&#8217;re a combo opera teacher and hockey fan (one assumes the Venn Diagram covers Wagner fans pretty well), bitching about the other team&#8217;s anthem singer is digging for something to bitch about. Just try to be classy,&nbsp;e.g., <\/p>\n<p>https:\/\/twitter.com\/MikeGiardi\/status\/344972997679001601<\/p>\n<p>Regardless, Rene will always have&nbsp;this:<\/p>\n<p>http:\/\/www.youtube.com\/watch?v=Af4pKFpj0V0<\/p>\n<p>Also:&nbsp;1-0.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"sports"}},{"@attributes":{"term":"boston"}}]},{"title":"CSS: min-width vs.\u00a0zoom","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/css-min-width-vs-zoom.html","rel":"alternate"}},"published":"2013-05-22T11:00:49-04:00","updated":"2013-05-22T11:00:49-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-05-22:\/css-min-width-vs-zoom.html","summary":"<h1><span class=\"caps\">CSS<\/span>: min-width vs.&nbsp;zoom<\/h1>\n<p>Ran into an interesting quirk today that I don&#8217;t see a lot of search results for: if you have a min-width set on an element but then set a zoom on an element other than 100%, the min-width (and, one presumes, the max-width) is scaled \u2026<\/p>","content":"<h1><span class=\"caps\">CSS<\/span>: min-width vs.&nbsp;zoom<\/h1>\n<p>Ran into an interesting quirk today that I don&#8217;t see a lot of search results for: if you have a min-width set on an element but then set a zoom on an element other than 100%, the min-width (and, one presumes, the max-width) is scaled by the zoom factor. In this case I was working on a responsive design that has a fixed header image for anonymous users. While the body and the header had a min-width of 480px set, when I scaled the header image down, it continued to squeeze below 480px. The fix looked like&nbsp;this:<\/p>\n<pre class=\"prettyprint\">\n#guest-bar {\n    zoom: 70%;\n    \/* min-width of 480 but at 70% *\/\n    min-width: 685px;\n}\n<\/pre>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"css"}},{"@attributes":{"term":"responsive"}}]},{"title":"ConvenientMD:\u00a0ConvenientMD","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/convenientmd","rel":"alternate"}},"published":"2013-05-21T00:00:00-04:00","updated":"2013-05-21T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-05-21:\/convenientmd","summary":"<h1>ConvenientMD:&nbsp;ConvenientMD<\/h1>\n<h2>2013-05-21<\/h2>\n<p><em>Built the website and tools that helped a startup grow to a major New Hampshire health&nbsp;provider<\/em><\/p>\n<p>Worked directly with the founders to create the front- and back-end of their original web site and then extend it to add more tools as the business took off. Added \u2026<\/p>","content":"<h1>ConvenientMD:&nbsp;ConvenientMD<\/h1>\n<h2>2013-05-21<\/h2>\n<p><em>Built the website and tools that helped a startup grow to a major New Hampshire health&nbsp;provider<\/em><\/p>\n<p>Worked directly with the founders to create the front- and back-end of their original web site and then extend it to add more tools as the business took off. Added online payment via the Authorize.net portal and a responsive design after the initial build. The site (and company) grew from one to nine locations during its&nbsp;lifetime.<\/p>\n<p><img src=\"\/images\/portfolio\/location.png\" alt=\"Location Example \" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/home_V574hTu.png\" alt=\"Homepage \" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"django"}},{"@attributes":{"term":"rwd"}},{"@attributes":{"term":"microformats"}},{"@attributes":{"term":"googlemaps"}},{"@attributes":{"term":"geolocation"}},{"@attributes":{"term":"authorize.net"}},{"@attributes":{"term":"payments"}}]},{"title":"Ruining\u00a0Fletch","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/ruining-fletch.html","rel":"alternate"}},"published":"2013-05-06T11:06:09-04:00","updated":"2013-05-06T11:06:09-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-05-06:\/ruining-fletch.html","summary":"<h1>Ruining&nbsp;Fletch<\/h1>\n<p>If you&#8217;ve never seen <em>Fletch<\/em>, stop here and go watch it. It&#8217;s a great comedy and one of the rare cases of a movie being better than the book. Assuming everyone reading past this point has seen it, you&#8217;re familiar with the plot: businessman Alan \u2026<\/p>","content":"<h1>Ruining&nbsp;Fletch<\/h1>\n<p>If you&#8217;ve never seen <em>Fletch<\/em>, stop here and go watch it. It&#8217;s a great comedy and one of the rare cases of a movie being better than the book. Assuming everyone reading past this point has seen it, you&#8217;re familiar with the plot: businessman Alan Stanwyck hires down-on-his-luck investigative journalist Irwin R. Fletcher to kill him. Stanwyck says he&#8217;s dying of cancer and wants Fletch to kill him so Stanwyck&#8217;s wife can collect a sizable insurance settlement, but it turns out Stanwyck wants to use Fletch&#8217;s body to fake his own death so he can double-cross the corrupt cop he&#8217;s been smuggling drugs for and fly off to South America. Instead, Fletch figures it all out and stops Stanwyck and the corrupt chief of police and walks away with Stanwyck&#8217;s life and&nbsp;wife.<\/p>\n<p>But what if that&#8217;s not the story at all? What if Alan Stanwyck is one of the noblest heroes to ever grace the silver screen? What if he <em>was<\/em> dying of cancer and was worried his wife could never move on after his death, that she&#8217;d live alone for 40 or 50 years missing him? So he searches around for the perfect replacement: a noble guy who&#8217;s recently gone through a divorce and is short of cash. Stanwyck then proceeds&nbsp;to:<\/p>\n<ul>\n<li>Concoct an incredibly elaborate double bluff that results in his wife both collecting the insurance and being happy he&#8217;s&nbsp;dead<\/li>\n<li>Knowing he has nothing to lose, he runs his own sting on the chief of police to clean up the drug problems in his&nbsp;town<\/li>\n<li>Leads Fletch to clean up both the shady land deals and illegal mattress dumping in Stanwyck&#8217;s home town of Provo,&nbsp;Utah<\/li>\n<li>Makes sure Fletch gets a full physical including a prostate check to ensure Fletch doesn&#8217;t suffer the same fate as&nbsp;Stanwyck<\/li>\n<li>Finds time in all of this to plan a fantastic honeymoon\/ elopement for his wife and&nbsp;Fletch<\/li>\n<\/ul>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"movies"}},{"@attributes":{"term":"fletch"}}]},{"title":"Songs Craig Finn Has Heard Bar Bands\u00a0Play","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/songs-craig-finn-has-heard-bar-bands-play.html","rel":"alternate"}},"published":"2013-04-25T11:38:23-04:00","updated":"2013-04-25T11:38:23-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-04-25:\/songs-craig-finn-has-heard-bar-bands-play.html","content":"<h1>Songs Craig Finn Has Heard Bar Bands&nbsp;Play<\/h1>\n<ul>\n<li>Beast of&nbsp;Burden<\/li>\n<li>Working in a Coal&nbsp;Mine<\/li>\n<li>Green-Eyed&nbsp;Lady<\/li>\n<li>Lay Lady&nbsp;Lay<\/li>\n<li>Legs<\/li>\n<li>Ain&#8217;t Too Proud to&nbsp;Beg<\/li>\n<li>Fairytale of New&nbsp;York<\/li>\n<li><em>something by The Dixie&nbsp;Dregs<\/em><\/li>\n<\/ul>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"music"}}]},{"title":"Django, Haystack & Elastic\u00a0Search","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/django-haystack-elastic-search.html","rel":"alternate"}},"published":"2013-03-28T18:24:01-04:00","updated":"2013-03-28T18:24:01-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2013-03-28:\/django-haystack-elastic-search.html","summary":"<h1>Django, Haystack <span class=\"amp\">&amp;<\/span> Elastic&nbsp;Search<\/h1>\n<p>(Yes, I know it&#8217;s been a&nbsp;while.)<\/p>\n\n<p>Just a quick note in case this bites someone else. I&#8217;d file a bug with Haystack, but I have a feeling I&#8217;m doing something incredibly dumb. I have a convoluted set of filters for a search \u2026<\/p>","content":"<h1>Django, Haystack <span class=\"amp\">&amp;<\/span> Elastic&nbsp;Search<\/h1>\n<p>(Yes, I know it&#8217;s been a&nbsp;while.)<\/p>\n\n<p>Just a quick note in case this bites someone else. I&#8217;d file a bug with Haystack, but I have a feeling I&#8217;m doing something incredibly dumb. I have a convoluted set of filters for a search running through Django&#8217;s fantastic Haystack search abstraction using Elasticsearch as a back-end. All was going fine until I tried to add a filter to include\/ exclude results which had a blank value in their video_id field. In the browser it just looked like an empty search result, but the console was filled&nbsp;with <code>ParseException[Cannot parse \\'((my search string) AND NOT (video_id:))<\/code>. I&#8217;m sure there&#8217;s a proper fix for this, but I just adjusted my search index to change the CharField to a BooleanField using the field on the&nbsp;model.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"We Do This Every\u00a0Day","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/we-do-this-every-day.html","rel":"alternate"}},"published":"2011-08-07T22:02:15-04:00","updated":"2011-08-07T22:02:15-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2011-08-07:\/we-do-this-every-day.html","summary":"<h1>We Do This Every&nbsp;Day<\/h1>\n<p>So it&#8217;s been a while. In my defense, I have a good excuse (of which more later). I am returning from blog hiatus to grouse about something: I subscribe to <a href=\"http:\/\/news.ycombinator.com\/\">Hacker News<\/a> in Twitter and I&#8217;m happy to do so as I regularly \u2026<\/p>","content":"<h1>We Do This Every&nbsp;Day<\/h1>\n<p>So it&#8217;s been a while. In my defense, I have a good excuse (of which more later). I am returning from blog hiatus to grouse about something: I subscribe to <a href=\"http:\/\/news.ycombinator.com\/\">Hacker News<\/a> in Twitter and I&#8217;m happy to do so as I regularly find new packages and good advice in the stream. The price one pays for these tidbits is having to suffer through the worst examples of tech nerdism alive in the world today. Allow me, if you will, two&nbsp;examples:<\/p>\n\n<h2><a href=\"http:\/\/lenz.unl.edu\/2011\/04\/09\/life-on-the-command-line.html\" target=\"_blank\">Life on the Command&nbsp;Line<\/a><\/h2>\n\n<p>I&#8217;m forever trying to make myself more efficient through keyboard shortcuts, so I clicked right on this trap. After three or so sentences I recoiled in horror. Instead of being advice on how to use the command line, it&#8217;s all about how the author hates graphical email clients, so he uses old-school Linux ones because they are far superior. I see two problems&nbsp;here.<\/p>\n<ol>\n<li>I do not claim Gmail is perfect, but it works damned well. Before it, I lived my professional life in Outlook. And that was fine too. I&#8217;ve used Thunderbird and had no major complaints. I&#8217;ve also used pine and mutt and written email by hand. Those are not superior ways of doing things. The specific mistake the author makes is in claiming terminal-based apps are superior because you get your email &#8220;faster&#8221; according to whatever observation-based metric he&#8217;s made up. Email is a wonderful means of communication because it is asymmetric: you write to me when it&#8217;s convenient for you and I read it when it&#8217;s convenient for me. If you&#8217;re sitting around hitting &#8220;Check for messages&#8221;, you&#8217;re doing it&nbsp;wrong.<\/li>\n<li>The more general mistake this type of nerd makes is that computer programs are an end to themselves. They are not. Carve it into your forehead backwards if need be, but unless you are currently taking Computer Science classes or writing a programming language, it is unlikely you are writing a program that doesn&#8217;t have a purpose outside the confines of the machine it runs on. An email client isn&#8217;t just for you, it&#8217;s for everyone who needs to communicate with you. So I need you to be able to respond in nicely-formatted language that clearly indicates what you meant, not some plain text crud wrapped at 80 columns. And I need you to have an email client that can handle calendar events so I know if you&#8217;re going to show up or&nbsp;not.<\/li>\n\n<p>My all-time, can&#8217;t-be-beat favorite example of this kind of crawling up one&#8217;s own ass comes from my all-time, can&#8217;t-be-beat favorite co-worker. When we moved to .<span class=\"caps\">NET<\/span>, everyone got a copy of Visual Studio. Now you can make a lot of complaints about a lot of Microsoft programs (and I can help if you want to set up regular meetings), but I am hard-pressed to complain about Visual Studio as a work environment for creating Microsoft-based code[1]. Not good enough for The Professor though. Too complicated. His idea was to write his code in Notepad and then run it through the raw compiler on the command line (sense a theme here?) and then hand it over to us. Technical types reading this will need no further info before they begin laughing; for anyone else in the audience, this is the equivalent of your new employer handing over a set of keys to a Rolls Royce by way of apology for the commute and you refusing them, saying you prefer to walk 5 hours each way and then to prove it, cutting off your own legs at the knee with a rusty hacksaw. One could write the code in Notepad if that made them happy. It does have the side effect of pissing off all your coworkers who have to clean up the mess&nbsp;though.<\/p>\n\n<h2>The Big&nbsp;Re-Write<\/h2>\n<p>I&#8217;ve lost the second link, but it was a story from some wet-behind-the-ears kid about &#8220;Why I rewrote my company&#8217;s code base and you should too.&#8221; I won&#8217;t claim it couldn&#8217;t be true; from the link I think he said he did it in three days, so it sounds a bit like someone saying they rebuilt their entire house from the studs and then finding out their house was a refrigerator box and is now pieces of the same box taped up in a slightly different configuration. It&#8217;s perfectly possible it was a good idea. But if you&#8217;re the sort of person who thinks they can discerns a trend line based on a single data point, maybe you shouldn&#8217;t be handing out free advice. Especially when it&#8217;s rather dangerous advice. It&#8217;s such a bad idea, a mistake so many people have made, it has its own name (&#8220;Second system effect&#8221;) and an entry on <a href=\"http:\/\/en.wikipedia.org\/wiki\/Second-system_effect\">Wikipedia<\/a>.<\/p>\n\n<p>I am regularly stunned by the number of people who think they have everything covered. As a kid, I always noticed the guys my Dad chose to hang around were impossibly competent. Good with their hands, good with numbers, all-around friendly, you get the drift. The best description I can provide is one stolen from <a href=\"http:\/\/www.wired.com\/wired\/archive\/4.12\/ffglass_pr.html\">Neal Stephenson&#8217;s Wired article about the laying of a trans-Pacific Internet cable<\/a>:\n\n<blockquote>&#8220;They tend to come from the <span class=\"caps\">US<\/span> or the British Commonwealth countries but spend very little time living there. They are cheerful and outgoing, rudely humorous, and frequently have long-term marriages to adaptable wives. They tend to be absolutely straight shooters even when they are talking to a hacker tourist about whom they know nothing. Their openness would probably be career suicide in the atmosphere of Byzantine court-eunuch intrigue that is public life in the United States today. On the other hand, if I had an unlimited amount of money and woke up tomorrow morning with a burning desire to see a 2,000-hole golf course erected on the surface of Mars, I would probably call men like Daily and Wall, do a handshake deal with them, send them a blank check, and not worry about it.&#8221;<\/blockquote>\n\n<p>I&#8217;ve worked as a programmer for over a decade and I&#8217;ve worked with perhaps two people like that. Which feels about right to me&mdash; I&#8217;ve worked with a lot of programmers and a lot of good programmers, but people who you&#8217;d bet your life on&mdash; those should be rare. If they&#8217;re not, you&#8217;re awfully careless with your life. My frustration with this comes from our new venture[2], Rivermill at Dover Landing. Just about every single vendor in the wedding industry thinks they are one of these people; some old ballplayer in Ken Burns&#8217; Baseball was quoted as saying &#8220;We do this every day&#8221; and I can&#8217;t think of a better label for the condition. Some of them clearly are. But they&#8217;re easily-identifiable behind the scenes, if not via their common competentness then through the higher price on their invoices. The trick is, if you&#8217;re not behind the scenes, they&#8217;d be hard to spot, because you can&#8217;t be casual in this business. This is someone&#8217;s goddamn wedding day. I know you and I do this every weekend, but you still need to stand at attention and look like you&#8217;re about to break into a&nbsp;sweat.<\/p>\n\n<p>We had a pair of wedding &#8220;planners&#8221; who apparently worked together so there was always someone to explain why the other wasn&#8217;t doing anything. We spent the better part of a week making these mopes look good because we don&#8217;t have a choice: if any vendor screws up, it reflects badly on us. And even if the client understands, random guests can&#8217;t tell things were off-schedule or messed up because of a vendor. So in the midst of us hurrying around to paint over their mistakes, in walks the mother-of-the-bride and she&#8217;s freaking out. Which is entirely expected and entirely understandable: you&#8217;re throwing probably the most important party of your life except you aren&#8217;t exactly in charge: if it were your party, you&#8217;d know implicitly where you want the tables to be, what color linens should be where or what the first dance song is. Since it&#8217;s not your party, you need to have that all written down beforehand, assuming you think to ask. Alternatively, you could hire a wedding planner. So she&#8217;s freaking out and trying to get some answers out of the planners. Their answer? &#8220;Relax, have a drink. It will all be fine.&#8221; These vendors &#8220;do this every day&#8221;. The problem is, they all have their own internal definition of what &#8220;this&#8221; entails and you only find out after the&nbsp;fact.<\/p>\n\n<small>[1] I&#8217;m not claiming it works well for anything else. I don&#8217;t write anything but C#\/ <span class=\"caps\">VB<\/span>.<span class=\"caps\">NET<\/span> (God help me) in it. But before you complain, go try Eclipse.<br \/>\n[2] Which has basically sucked up all my nights and weekends and thus all of my blog-writing free time. Or at least that&#8217;s my excuse.<\/small>","category":{"@attributes":{"term":"Posts"}}},{"title":"Kill Screen Magazine: Kill Screen\u00a0Magazine","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/kill-screen-magazine","rel":"alternate"}},"published":"2011-03-01T00:00:00-05:00","updated":"2011-03-01T00:00:00-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2011-03-01:\/kill-screen-magazine","summary":"<h1>Kill Screen Magazine: Kill Screen&nbsp;Magazine<\/h1>\n<h2>2011-03-01<\/h2>\n<p><em>Django-based site for a print-based video game publication moving online. One of the most attractive and enjoyable projects I&#8217;ve worked&nbsp;on.<\/em><\/p>\n<p>I used to work with <a href=\"http:\/\/savetherobot.com\/\" target=\"_blank\">Chris Dahlen<\/a> at <a href=\"http:\/\/www.pixelmedia.com\/\" target=\"_blank\">PixelMEDIA<\/a>. I also like video games. Lest this summary turn into a third-grader \u2026<\/p>","content":"<h1>Kill Screen Magazine: Kill Screen&nbsp;Magazine<\/h1>\n<h2>2011-03-01<\/h2>\n<p><em>Django-based site for a print-based video game publication moving online. One of the most attractive and enjoyable projects I&#8217;ve worked&nbsp;on.<\/em><\/p>\n<p>I used to work with <a href=\"http:\/\/savetherobot.com\/\" target=\"_blank\">Chris Dahlen<\/a> at <a href=\"http:\/\/www.pixelmedia.com\/\" target=\"_blank\">PixelMEDIA<\/a>. I also like video games. Lest this summary turn into a third-grader&#8217;s book report, let me say that when Chris contacted me to build a web site to be a companion to the gorgeous magazine he had co-founded, I leapt at the&nbsp;chance.<\/p>\n<p>The whole thing actually launched with no design whatsoever: the initial application behind the site was a poll application that allowed writers to vote for their favorite titles of the year (<a href=\"http:\/\/killscreendaily.com\/articles\/kill-screen-high-scores-best-2010\" target=\"_blank\">2010 results<\/a>, <a href=\"http:\/\/killscreendaily.com\/articles\/high-scores-best-2011\" target=\"_blank\">2011 results<\/a>) before the site launched. Poll applications aren&#8217;t the toughest thing to write, but this one had some fun challenges because it had to allow for free-form entries of games no one else had heard of while still doing its level best to avoid duplicates. And because it worked much like the <em>Village Voice&#8217;s<\/em> Pazz and Jop voting, there was a bit of logic wrapped up in making sure points were correctly alloted. And that was all tied into a friendly Ajax&nbsp;interface.<\/p>\n<p>Once the poll was done, it was time to build an article <span class=\"amp\">&amp;<\/span> review system. Again, all of this would be pretty standard, but Kill Screen always aimed to be a little bit different. A couple of months after the start of the project, i got a rush email from Chris asking if there was anyway to create a game review who&#8217;s score would vary with the phases of the moon for&nbsp;Sword + Sworcery. Six days later (thanks to a little help from some <a href=\"http:\/\/inamidst.com\/code\/moonphase.py\" target=\"_blank\">Python code on the web<\/a>), it was <a href=\"http:\/\/killscreendaily.com\/articles\/reviews\/review-superbrothers-sword-sworcery-ep\" target=\"_blank\">alive<\/a>.<\/p>\n<p>There are a number of tools running behind the scenes as well to aggregate video game <span class=\"caps\">RSS<\/span> feeds, track problems and generally make it easy to get content on the site without having to know <span class=\"caps\">HTML<\/span> (and without breaking the gorgeous&nbsp;design).<\/p>\n<p><img src=\"\/images\/portfolio\/CropperCapture2.png\" alt=\"Article \" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/score.png\" alt=\"Score \" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/CropperCapture1.png\" alt=\"Home Page Features a jQuery-powered scroller\" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"django"}},{"@attributes":{"term":"videogames"}}]},{"title":"Rivermill at Dover Landing: Rivermill at Dover\u00a0Landing","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/rivermill-dover-landing","rel":"alternate"}},"published":"2011-01-01T00:00:00-05:00","updated":"2011-01-01T00:00:00-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2011-01-01:\/rivermill-dover-landing","summary":"<h1>Rivermill at Dover Landing: Rivermill at Dover&nbsp;Landing<\/h1>\n<h2>2011-01-01<\/h2>\n<p><em>Built a site for my own business that uses a large number of Django apps and tools to make our small business seem like a big&nbsp;one.<\/em><\/p>\n<p>This is a strange one to talk about: Rivermill at Dover Landing is an \u2026<\/p>","content":"<h1>Rivermill at Dover Landing: Rivermill at Dover&nbsp;Landing<\/h1>\n<h2>2011-01-01<\/h2>\n<p><em>Built a site for my own business that uses a large number of Django apps and tools to make our small business seem like a big&nbsp;one.<\/em><\/p>\n<p>This is a strange one to talk about: Rivermill at Dover Landing is an event facility I started as a side business with my wife and three friends. One of the challenges of a side business, especially in a service industry, is to make sure it does not look or feel like a side business. I think the Rivermill web site does a good job of that: thanks to a fantastic design from Microarts (then Lightfin Studios), it looks like a world-class&nbsp;business.&nbsp;<\/p>\n<p>The applications behind the site help it run like one: we have a contact management system based on Django contacts, but custmized to allow us to track vendors and inquiries from the site. Each inquiry is parsed to see if we can answer the user&#8217;s queston right away, inserting answers into the Thank You screen as needed. The inquiries create a contact in our <span class=\"caps\">CRM<\/span> and generate an email to our administrators which invites them to set up a tour with the prospective client. Tours show up on private iCal feeds so we can follow them in Google Calendar, our phones, etc. Events are tracked similarly and also have their own&nbsp;calendar.<\/p>\n<p>We have a task tracking application that makes sure we&#8217;re following through on what needs to be done. Because it&#8217;s easy to let things slide when you&#8217;re working two jobs, the system bugs us mercilessly once tasks are overdue. Tasks can be added by hand or by pasting in notes from our company meetings: I parse them for a certain format and create new tasks as&nbsp;needed.<\/p>\n<p>The site also includes less-used but standard tools like an <span class=\"caps\">FAQ<\/span> engine, blog tool and a shopping cart based on Satchmo. We also care about our mobile users and present a different experience for them: rather than focussing as much on pretty pages, the mobile experience tries to provide the things you need on the day of an event, one &#8220;click&#8221;&nbsp;away.<\/p>\n<p><img src=\"\/images\/portfolio\/marry.png\" alt=\"Weddings \" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/contact.png\" alt=\"Contact \" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/homepage.png\" alt=\"Homepage \" style=\"margin: 1em 0\" \/><\/p>","category":{"@attributes":{"term":"Portfolio"}}},{"title":"Catharsis: To a Young\u00a0Designer","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/catharsis-to-a-young-designer.html","rel":"alternate"}},"published":"2010-11-18T01:31:35-05:00","updated":"2010-11-18T01:31:35-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-11-18:\/catharsis-to-a-young-designer.html","summary":"<h1>Catharsis: To a Young&nbsp;Designer<\/h1>\n<p><span class=\"dquo\">&#8220;<\/span><em>To be young (is to be sad).<\/em>&#8221; <a href=\"http:\/\/www.youtube.com\/watch?v=EawSJUF6Lng&feature=related\">Ryan&nbsp;Adams<\/a><\/p>\n<p>Dear&nbsp;Designer,<\/p>\n<p>You don&#8217;t know me and I don&#8217;t know you, which is why I&#8217;m posting this here where you won&#8217;t see it instead of replying to your email with an eye-peeling \u2026<\/p>","content":"<h1>Catharsis: To a Young&nbsp;Designer<\/h1>\n<p><span class=\"dquo\">&#8220;<\/span><em>To be young (is to be sad).<\/em>&#8221; <a href=\"http:\/\/www.youtube.com\/watch?v=EawSJUF6Lng&feature=related\">Ryan&nbsp;Adams<\/a><\/p>\n<p>Dear&nbsp;Designer,<\/p>\n<p>You don&#8217;t know me and I don&#8217;t know you, which is why I&#8217;m posting this here where you won&#8217;t see it instead of replying to your email with an eye-peeling rant. You are the second young designer in two months to tell me you work in Illustrator, not Photoshop. And you compounded the sin by informing us you do know Photoshop is the industry standard. It&#8217;s one thing to be ignorant, but to happily announce your intentions to be uncooperative is not a recipe for success. Please warn me next time you&#8217;re going to write something like that; I got angry enough I was light-headed<sup><a href=\"#foot1\">[1]<\/a><\/sup>, which is why I had to write&nbsp;this.<\/p>\n<p>There&#8217;s no gentle way to explain the problem here, so let me just say it: you are stupid. You don&#8217;t know anything. Whether a designer or a coder, the classes you took in college didn&#8217;t prepare you for much. That senior project you slaved over, even if it weren&#8217;t laughably wrong-headed, represents about 1% of the work involved in a real project. If you ran into a dark corner on your senior project, something you couldn&#8217;t figure out how to do, you just changed the project. Can&#8217;t happen in the real world. Instead you rely on the advice of people around you who have gone through the process&nbsp;before.<\/p>\n<p>I am a firm believer in Thoreau&#8217;s maxim, &#8220;Grey hair does not confer wisdom.&#8221; However, there is no implied corollary that youth does. It would be one thing if you were using <a href=\"http:\/\/www.gimp.org\/\"><span class=\"caps\">GIMP<\/span><\/a> instead of Photoshop; not only could I understand doing so to save money, but it would be evidence you&#8217;ve done some investigating to see what options are out there besides the ones you know. It would suggest an open mind instead of someone who assumes they already know what they need to know. And the solution to your anti-Photoshop bias is not to write the <span class=\"caps\">HTML<\/span> yourself. I&#8217;ve seen your <span class=\"caps\">HTML<\/span>. It sucks even worse. Learn how to do one job properly before you decide to add another bs title to your email signature. Accept it takes time to learn a craft. We are all standing on the shoulders of those who did our job before&nbsp;us.<\/p>\n<p>Stop looking at every step in the process as a problem that needs solving. The steps in the process are in the process because they are solutions. Twice since I&#8217;ve gone out on my own I&#8217;ve run into problems with a young developer who had &#8220;a different approach&#8221; to the version control system we were using. Thing is, there&#8217;s an industry standard for how to use Subversion. And I know what it is. Know how? Because the people who made Subversion wrote a book about it and made the book available to anyone who can use Google. And I played around with different setups until I realized they were right. When you work on anything, with anyone, use the industry standards. Whether perfect or not, standards make sure everyone is speaking the same language. They reduce friction. If you&#8217;re not sure what the standard is, just ask me and I&#8217;ll tell you. It&#8217;s like it said in my wedding vows, &#8220;From now on, I&#8217;ll do the thinking for both of us.&#8221;<sup><a href=\"#foot2\">[2]<\/a><\/sup><\/p>\n<p>I don&#8217;t care if you work in Illustrator. And I don&#8217;t care why, though I must say if you find it hard to place a 1 pixel line in Photoshop, the problem might not be Photoshop. Work in whatever the hell you want and then Google &#8220;convert from [my stupid choice] to <span class=\"caps\">PSD<\/span>&#8221;. Another reason I&#8217;d be ok with you using <span class=\"caps\">GIMP<\/span>: it exports directly to Photoshop. It has to. Because, in the realm of image editors, it is no one. So it has to be cooperative or no one will work with it. That should be your role model. Be <span class=\"caps\">T.S.<\/span> Eliot&#8217;s &#8220;infinitely gentle\/ Infinitely suffering thing&#8221;. Don&#8217;t talk, listen. When you get to the point where people are knocking on your door to give you work, then you can be e.e. cummings Olaf, saying, &#8220;There is some shit I will not&nbsp;eat&#8221;.<\/p>\n<p>But you won&#8217;t. Because in five years, you&#8217;ll realize how stupid you were now. And in ten you&#8217;ll realize you&#8217;re still learning. In fact, set a reminder for ten years and if you don&#8217;t feel this way, you have a Very Serious Problem. You&#8217;ve become one of those old people who isn&#8217;t worth listening&nbsp;to. <\/p>\n<p>A couple of other free pieces of&nbsp;advice:<\/p>\n<ul>\n    <li>Tattoo this on your arm: &#8220;The perfect is the enemy of the good.&#8221; Fail fast. There&#8217;s no shame in not succeeding the first time. Writing is easy, re-writing is hard. No work is ever perfect, so if you keep tweaking until it&#8217;s perfect, you&#8217;ll never finish and no one will ever see your&nbsp;work.<\/li>\n    <li>This isn&#8217;t a goddamn competition to see who&#8217;s smarter, so please don&#8217;t refer to your boyfriend the <span class=\"caps\">HTML<\/span> whiz while telling the client how I should be doing my job. You aren&#8217;t even bright enough to do your own job, so why not assume there&#8217;s a reason I did things the way I did? Also, don&#8217;t bad-mouth the people I work with as a way of trying to get me to send you work instead. That makes it clear we&#8217;re not in this foxhole together and you&#8217;ll do the same to me as soon as it looks&nbsp;profitable.<\/li>\n<\/ul>\n\n<p><small><span id=\"foot1\">1.<\/span> Given you don&#8217;t know me, I feel the need to point out this isn&#8217;t hyperbole. I almost blacked out in my car thinking about your email.\n<span id=\"foot2\">2.<\/span> Clancy, Thomas, <em>&#8220;Weddings Vows&#8221;<\/em> (first draft only), 2005, as yet unpublished<\/small><\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Week\u00a0162","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/week-162.html","rel":"alternate"}},"published":"2010-11-13T21:48:25-05:00","updated":"2010-11-13T21:48:25-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-11-13:\/week-162.html","summary":"<h1>Week&nbsp;162<\/h1>\n<p><em>&#8221;[T]he advantage to being a wicked bastard is that everyone pesters the Lord on your behalf; if the volume of prayers from my saintly enemies means anything, I&#8217;ll be saved when the Archbishop of Canterbury is damned. It&#8217;s a comforting thought.&#8221;<\/em>\nFlashman, <em>Flashman at the \u2026<\/em><\/p>","content":"<h1>Week&nbsp;162<\/h1>\n<p><em>&#8221;[T]he advantage to being a wicked bastard is that everyone pesters the Lord on your behalf; if the volume of prayers from my saintly enemies means anything, I&#8217;ll be saved when the Archbishop of Canterbury is damned. It&#8217;s a comforting thought.&#8221;<\/em>\nFlashman, <em>Flashman at the&nbsp;Charge<\/em><\/p>\n<p>And the advantage in taking 20 weeks off is I still have a Flashman quotation left laying around to use. What have I been up to? Not&nbsp;much:<\/p>\n<ul>\n    <li>3 new Django content management&nbsp;sites<\/li>\n    <li>A Django social network for an episode of <span class=\"caps\">PBS<\/span>&#8217; Frontline, <a href=\"http:\/\/www.pbs.org\/godinamerica\/faithbook\/\">God in&nbsp;America<\/a><\/li>\n    <li>An <a href=\"http:\/\/chicbydesigncollections.com\/\">ecommerce site<\/a> powered by <a href=\"http:\/\/www.satchmoproject.com\/\">Satchmo<\/a><\/li>\n    <li>My first Microsoft <span class=\"caps\">MVC2<\/span> Project (another big social network, done under <span class=\"caps\">NDA<\/span>)<\/li>\n<\/ul>\n\n<p>August was a rough month. After a slow July, the Satchmo site and the .<span class=\"caps\">NET<\/span> site were competing for all of my attention, made worse by the fact each project was a learning experience for me. Forced to work in a Windows environment, I would happily work with <span class=\"caps\">MVC2<\/span> again. I&#8217;m spoiled by Django and I have reservations about the amount of ecosphere .<span class=\"caps\">NET<\/span> projects drag around with them, but it&#8217;s a huge improvement over a WebForms site. I&#8217;ll never get over my objections to magic happening in compiled files somewhere on a machine (I want to be able to open a text file and see what&#8217;s going wrong if there&#8217;s a problem), so .<span class=\"caps\">NET<\/span> will never be my first choice solution. My mind is also bent by Django since it&#8217;s the first <span class=\"caps\">MVC<\/span> framework I really worked with and because it is the one I know best (I&#8217;m just starting to learn <a href=\"http:\/\/cakephp.org\/\">CakePHP<\/a> while working with <a href=\"http:\/\/croogo.org\/\">Croogo<\/a>, which seems like a nice lightweight <span class=\"caps\">PHP<\/span> <span class=\"caps\">CMS<\/span> solution), so some of the issues I have with <span class=\"caps\">MVC2<\/span> are just a case of expecting things to work a different way. But there are some design decisions I disagree&nbsp;with:<\/p>\n<ul>\n    <li>I&#8217;ll start with the big one: I&#8217;m not a huge believer in Controllers for web apps. There&#8217;s a new Python framework whose name I&#8217;ve forgotten two days later that describes itself as an <span class=\"caps\">MV<\/span> framework, which basically describes Django as well. I can see putting security logic in controllers (that&#8217;s what I did when I rolled my own for .<span class=\"caps\">NET<\/span> way back when), but given the amount of security and sanity-checking a routing engine gives you to begin with, I don&#8217;t think it&#8217;s a lot of overhead to put into the views. Actually, that&#8217;s not true. If you need to write the same security logic into multiple views, that&#8217;s not good. But Django&#8217;s use of decorators works for me. <span class=\"caps\">MVC2<\/span>&#8217;s controller attributes serve pretty much the same function, just in the controllers. Which brings me to the next issue&nbsp;&#8230;<\/li>\n    <li>Django, Rails and most other <span class=\"caps\">MVC<\/span> frameworks intentionally make it difficult to put logic into the presentation layer. Because <span class=\"caps\">MVC2<\/span> just uses .aspx pages as the View layer, it allows people to re-invent&nbsp;WebForms.<\/li>\n    <li>My personal opinion is that everything about a model belongs <em>in the model<\/em>. This was my one fundamental disagreement with Django&#8217;s design up until the last release. Until 1.2, some validation had to be done in forms. Forms are just a way of interacting with a model, but there&#8217;s no contract to use a particular form. You could build a dozen different forms for a model or not use a form at all, which means there was no single location for business logic. Where Django made it hard to centralize rules for a model, it&#8217;s just about impossible in <span class=\"caps\">MVC2<\/span>. Logic goes in the Controller, not the Model. There&#8217;s no way (that I could fine, I could be totally wrong) to hook into a Save event or similar. And things get further confused with the Repository Model and View Model concepts, where you build &#8220;models&#8221; as a data access layer and as a convenience object for strongly binding a view to an object. It feels wrong-headed to&nbsp;me.<\/li>\n    <li>The build process still feels horribly complex for .<span class=\"caps\">NET<\/span> projects. It typically consists of a batch file tied to one or more large <span class=\"caps\">XML<\/span> files describing the different deployment locations. It runs a build, moves stuff around and then you manually drag and drop the files and diff the folders because of course no Windows server admin dares to have <span class=\"caps\">FTP<\/span> open anymore and you&#8217;re not going to get <span class=\"caps\">SFTP<\/span> access either. And then maybe you need to restart <span class=\"caps\">IIS<\/span>, maybe you don&#8217;t. In comparison to the Nant build scripts I&#8217;m used to, my Fabric deployment files for Django projects look like the slow kid in class: a dozen lines top, another 5 or so if I have a second deployment&nbsp;location.<\/li>\n    <li>I&#8217;ve finally wrapped my thick head around using <a href=\"http:\/\/south.aeracode.org\/\">South<\/a> for migrations in Django. If there&#8217;s something similar for <span class=\"caps\">MVC2<\/span> projects, please let me&nbsp;know.<\/li>\n<\/ul>\n\n<p>As for Satchmo, I don&#8217;t know if I&#8217;d use it again. I had heard it, for better <em>and<\/em> for worse, included everything plus two kitchen sinks. I went with it because I figured if I got over my head, the amount of options and sizable user community could save me. They did, but it still felt like an elephant gun solution and it was harder than I expected to customize it. Actually, that&#8217;s not fair: once I learned my way around, it was pretty easy to customize, but all that work happened in uncharted territory. While it has decent documentation, the documentation is written for people who just want to set a site up, tweak some settings in the admin and be ready to go. While you can add\/ customize all sorts of things, you&#8217;re on your own for much of it. All of which suggests I ought to donate some time back to the project in the form of documentation. I guess I would use it again given it can do most anything, provides a lot straight out of the box and gave me a feeling of security you don&#8217;t get from hand-rolling your own credit card processing logic. I&#8217;ll just keep an eye open for other Django ecommerce solutions like <a href=\"http:\/\/www.getlfs.com\/\"><span class=\"caps\">LFS<\/span><\/a>. And I&#8217;ve heard good things from people using <a href=\"http:\/\/www.shopify.com\/\">Shopify<\/a>.<\/p>\n<p>While those two projects dragged on into September, the Frontline site launched. It&#8217;s a testament to Django (with some help from <a href=\"https:\/\/github.com\/dcramer\/django-db-log\">django-db-log<\/a>&mdash; now replaced by the more attractive but also more confusing <a href=\"https:\/\/github.com\/dcramer\/django-sentry\">Sentry<\/a>) that the launch went so smoothly. It&#8217;s a different experience, knowing that after 10pm on a given night, thousands of people are going to hit your newly-launched site. A small number of edge cases issues cropped up, but it&#8217;s reassuring to have fixed and deployed a patch before I get an email from the client about the issue. The only real issue I ran into was a performance problem on the <a href=\"http:\/\/www.pbs.org\/godinamerica\/faithbook\/profiles\/\">directory listing pages<\/a>: because one of the sorting options is by views (and the default option at that), the query was running incredibly slowly and forced me to denormalize the view data from a separate table (the views are in a separate table so I could track who viewed a profile and when) into the profiles table itself. Once that was done (and once I added a bit of template caching to the page), the problem&nbsp;disappeared.<\/p>\n<p>Totally (almost) unrelated to work, one music note from my missing months: we caught the <a href=\"http:\/\/www.pastemagazine.com\/articles\/2010\/08\/first-ever-paste-tour-ready-to-knock-yer-dorky-soc.html\">Paste Tour<\/a> at The Middle East in Boston. This came up in a discussion last night when someone told us they&#8217;d recentl seen Sufjan Stevens in concert. If you know me at all, you should be proud: I didn&#8217;t get up and walk away, I didn&#8217;t spit out my drink (not that I&#8217;d ever spit beer in general or Boddington&#8217;s in specific). Instead I was just a jerk and asked if Sufjan played his 25 minute new album closer that features costume changes during the song (don&#8217;t look at me like that, I heard it on an episode of the otherwise-fantastic <a href=\"http:\/\/minnesota.publicradio.org\/radio\/programs\/musicheads\/\">Musicheads<\/a> podcast)? The answer: yes he did and it was awesome. There was confetti and white people going as crazy as people who attend Sufjan Stevens shows are capable of going. Which, one imagines, isn&#8217;t very far at all but still requires an expensive therapist to sort out the ennui&nbsp;afterwards.<\/p>\n<p>No thanks. We walked into The Middle East late due to traffic and a restaurant who thought the slow food movement should be extended to the table service and walked directly into a screaming match between Jesse Sykes&#8217; guitarist Phil Wandscher (late of Whiskeytown) and one or more patrons who were standing in directly in front of the stage and texting. That segued into a typically raucous set from Langhorne Slim; if he gets near your town, go see him&mdash; it might have been the &#8216;Gansett tallboys talking, but Michelle asked me how likely it was she could land him for next year&#8217;s Cochecho Arts Festival, so he might be closer than you&nbsp;think. <\/p>\n<p>So that was all dark and boozy and ceilings so low Langhorne Slim nearly decapitated himself jumping off drums and amps. And then Jason Isbell showed up and here comes my point along with him: he was a complete mess. I saw his eyes as he walked out from backstage and got a little nervous: while Michelle tolerates the Drive-By Truckers for me, she loves Jason Isbell. And here he came looking like he was going to fall off the stage. And then he ripped off an hour plus set that might be the best show I&#8217;ve ever seen. My eyes have looked like his any number of times. None of those times have I had the hand-eye coordination to unlock a door on the first try. Somehow he played the best guitar I&#8217;ve ever witnessed close up. I suppose it&#8217;s like getting to Carnegie Hall, &#8220;Practice man, practice&#8221;. I can&#8217;t see Sufjan Stevens, Animal Collective or Soul Collective ever letting themselves free like that. For me, music, art in general, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Apollonian_and_Dionysian\">should be about Dionysus, not Apollo<\/a>: let yourself go. Free your ass, etc., etc. It pains me to be at a show and see someone doing that White Guy Dance where he&#8217;s kinda shaking his ass, but his elbows are welded to his hips for fear of annoying other patrons or (God forbid! Heaven forfend!) ever looking a little goofy. You see those &#8220;Dance Like No One is Looking&#8221; bumper stickers on plenty of Volvos, but I never see the drivers doing&nbsp;it.<\/p>","category":[{"@attributes":{"term":"Posts"}},{"@attributes":{"term":"music"}}]},{"title":"Frontline\/ PBS: Frontline: God in\u00a0America","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/frontline-god-america","rel":"alternate"}},"published":"2010-10-01T00:00:00-04:00","updated":"2010-10-01T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-10-01:\/frontline-god-america","summary":"<h1>Frontline\/ <span class=\"caps\">PBS<\/span>: Frontline: God in&nbsp;America<\/h1>\n<h2>2010-10-01<\/h2>\n<p><em>A social website for viewers of the Frontline program &#8220;God in America&#8221; to come together and discuss their religious&nbsp;views.<\/em><\/p>\n<p><em>God in America<\/em> is a 2010 episode of <span class=\"caps\">PBS<\/span>&#8217; Frontline. As part of the reporting for the show, Frontline wanted a social networking \u2026<\/p>","content":"<h1>Frontline\/ <span class=\"caps\">PBS<\/span>: Frontline: God in&nbsp;America<\/h1>\n<h2>2010-10-01<\/h2>\n<p><em>A social website for viewers of the Frontline program &#8220;God in America&#8221; to come together and discuss their religious&nbsp;views.<\/em><\/p>\n<p><em>God in America<\/em> is a 2010 episode of <span class=\"caps\">PBS<\/span>&#8217; Frontline. As part of the reporting for the show, Frontline wanted a social networking site to invite Americans to discuss their opinions on religion and how they practice their faiths. I built a site based on Pinax, a collection of Django applications that work together as a foundation for social networks. User management for the site is handled by <span class=\"caps\">PBS<\/span>&#8217; OAuth service which provides a Django library for plugging into projects. This means members of existing Frontline\/ <span class=\"caps\">PBS<\/span> sites don&#8217;t have to bother with signing up before they can use the&nbsp;site.<\/p>\n<p>The focus of the site is user profiles. The profiles consist of standard user information plus responses to a series of &#8220;prompts&#8221;, questions about their faith. Users can respond in text, with links to photographs or links to video responses. The site provides checks to allow administrators to review responses for questionable content. Text is reviewed for signs of spam and photographs and videos are approved by administrators. Video responses are sent through django-oembed, an application that turns links into videos on the page, so users can simply paste in a link to a Youtube (or similar video site) page and have it display as an embedded movie with no further&nbsp;action.<\/p>\n<p>Users can indicate they like other responses or flag responses as offensive. Both types of flags are throttled so users cannot game the system to help or hurt other users&#8217; responses (or affect their own). You can search all responses with a fuzzy text search via Haystack and Whoosh or filter responses by specific prompts. The site also allows members to create public or private events and other users can <span class=\"caps\">RSVP<\/span> to indicate if they are attending. Events include the local zip code so users can search for events within a certain distance of their location through a zip code database and longitude\/ latitude radius&nbsp;search.<\/p>\n<p><img src=\"\/images\/portfolio\/Faithbook_Profile_1.png\" alt=\"Your Profile Editing your information and responses\" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/Faithbook_Browse_1.png\" alt=\"Browse Browse user profiles by name, date, number of views or celebrities only\" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/Faithbook_Home_1.png\" alt=\"Homepage \" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"django"}},{"@attributes":{"term":"social"}},{"@attributes":{"term":"pinax"}},{"@attributes":{"term":"geodata"}},{"@attributes":{"term":"oauth"}}]},{"title":"Week\u00a0142","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/week-142.html","rel":"alternate"}},"published":"2010-06-26T20:40:17-04:00","updated":"2010-06-26T20:40:17-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-06-26:\/week-142.html","summary":"<h1>Week&nbsp;142<\/h1>\n<p><span class=\"dquo\">&#8220;<\/span><em>That tension\u2014 between beauty and cynicism, between what the Brazilians call <\/em>futebol d&#8217;arte<em> and <\/em>futebol de resultades<em>\u2014 is a constant, perhaps because it is so fundamental, not merely to sport, but also to life: to win, or to play the game well? It is hard to think \u2026<\/em><\/p>","content":"<h1>Week&nbsp;142<\/h1>\n<p><span class=\"dquo\">&#8220;<\/span><em>That tension\u2014 between beauty and cynicism, between what the Brazilians call <\/em>futebol d&#8217;arte<em> and <\/em>futebol de resultades<em>\u2014 is a constant, perhaps because it is so fundamental, not merely to sport, but also to life: to win, or to play the game well? It is hard to think of any significant actions that are not in some way a negotiation between the two extremes of pragmatism and idealism<\/em>.&#8221;\n<a href=\"http:\/\/www.guardian.co.uk\/profile\/jonathanwilson\" target=\"_blank\">Jonathan Wilson<\/a>, <em><a href=\"http:\/\/www.amazon.com\/Inverting-Pyramid-History-Football-Tactics\/dp\/1409102041\/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1277564539&amp;sr=8-1\" target=\"_blank\">Inverting the&nbsp;Pyramid<\/a><\/em><\/p>\n<p>This was supposed to be &#8220;Week 138&#8221;, but I never got off my duff. It&#8217;s just as well as I read <em><a href=\"http:\/\/www.goodreads.com\/review\/show\/108814122\" target=\"_blank\">Flashman and the Dragon<\/a><\/em> in the interim and it colored my thoughts on this post. I want to clarify and expand upon what I said in the <a href=\"http:\/\/thosecleverkids.com\/blog\/2010\/05\/21\/week-137\/\">last post<\/a> about the danger of falling too much in love with one language, one web technology. Some of that is just my personal bias: I spent my formative development years working at a consultancy that took on work in all manner of languages and on any number of platforms, so I think that&#8217;s How Things Should Be. I&#8217;ve always prided myself on being &#8220;language agnostic&#8221; in terms of programming. A few times on a job interview or when trying to land a client I think this has cost me\u2014 you see a wrinkled nose or the torrent of questions turns into a trickle\u2014 but I&#8217;ve never really minded because I think insistence on working in one way is the path of the small-minded. It&#8217;s something I rail against in general, the tendency for everyone to think where they live, how they live and what they think is based on some cosmic template of How Things Are Done and anyone who&#8217;s opinions, skin color, language differ from that template is doing it&nbsp;wrong.<\/p>\n<p>That kind of thing infects your thought. If I were designing a curriculum for a school, it would include a week discussing Kipling&#8217;s &#8220;[W]hat should they know of England who only England know?&#8221; A week at the inside. Make it the basis of a year&#8217;s worth of forming thought. Too many developers focus on one thing, get comfortable in it and then don&#8217;t know what to do when that technology turns into a dead end. Or, worst of all, don&#8217;t ever find out that technology has turned into a dead end. There&#8217;s nothing more frightening than meeting a new client&#8217;s old developer via his work. &#8220;He has his own way of doing things.&#8221; &#8220;He was very specific about that.&#8221; Etc. If you don&#8217;t think there are people making a good living writing dead-end solutions for clients who don&#8217;t know better, find out how many copies of Microsoft Access were sold last year. Ask why people <a href=\"http:\/\/social.msdn.microsoft.com\/Forums\/en\/vbide\/thread\/93aefadd-afb0-45a0-85ec-09dcac39abf0\" target=\"_blank\"> are still looking for <span class=\"caps\">VB6<\/span> compilers<\/a> (&#8220;<em>I don&#8217;t like to upgrade<\/em> [to] 2008. More than 10.000 lines of&nbsp;code&#8221;)?<\/p>\n<p>So what the hell am I doing trying to work in Django all the time? First we should discuss the lie I told above. I&#8217;m not language agnostic. Not exactly. I try not to be a fan of anything, but that&#8217;s not in my nature anyway: I expect to be let down by anything I rely on. But I don&#8217;t stop myself from hating. This week, a partner asked me if I knew any ColdFusion consultants. My thought&nbsp;process:<\/p>\n<ol>\n    <li>Why would I hang around with a sorry bastard like&nbsp;that?<\/li>\n    <li>Hey, I&#8217;ve written thousands of lines of&nbsp;ColdFusion!<\/li>\n    <li>Yeah, and you hated every second of&nbsp;it.<\/li>\n    <li>Oh,&nbsp;right.<\/li>\n<\/ol>\n<p>No thanks. It&#8217;s one of the few languages I&#8217;ve worked in that I feel sets you back (note: all opinions circa 2002 and <span class=\"caps\">CF4<\/span>\/5). Like <span class=\"caps\">ASP<\/span>, its limitations make you think programming has to be hard and that there are things that cannot be done. It never fails to amaze me when a developer says something &#8220;cannot be done&#8221;. It&#8217;s almost never accurate. 99% of the time it either means it can&#8217;t be done in budget or the developer does not know how to. And that second case is when you should drop a developer post-haste. I&#8217;ve rarely done anything interesting as a programmer when I knew how to do it at the outset. You only learn and grow when you get&nbsp;challenged.<\/p>\n<p>So, again, why work so much in Django where you can develop a comfortable rut and never be challenged by ideas and paradigms from other languages that might show a better way to do things? So much of life comes back to biology, and working in one language is incestuous. Healthy populations have lots of differences, providing more opportunities for mutations and evolution. I could hang out with the world&#8217;s smartest Python programmers and all I would ever learn is the best way to solve problems in Python. Which is not necessarily the best way to solve a problem. Going back to Kipling, it&#8217;s hard to appreciate what you have if you don&#8217;t know what the alternatives look like. It&#8217;s human nature to assume what you have is the best option. My favorite Americans, the people who I think are our best citizens, were citizens of the world. Franklin, Jefferson, etc. were Americans intimately familiar with England, who spent much of their diplomatic lives in France. The synthesis of different ideas results in totally new avenues. Even just the ability to synthesize different ideas is&nbsp;important.<\/p>\n<p>The answer turns out to be a surprising one: I, and by extension, this company, <em>am not a programmer<\/em>. It&#8217;s what I do to accomplish client goals, but it&#8217;s not what clients want. They want a solution to a problem. Ideally a secure, high-performance, user-friendly solution, but in no case do they care about the language it&#8217;s written in or the format of the code. They just want <a href=\"http:\/\/www.bartleby.com\/148\/3.html\" target=\"_blank\">something that leaves them happier than they were before<\/a>. All that stuff developers argue about, languages, platforms, editors, it&#8217;s all fanboyism. I&#8217;m too old for that and I&#8217;m more interested in accomplishing something <a href=\"http:\/\/xkcd.com\/386\/\" target=\"_blank\">than being right<\/a>. Or I&#8217;m trying to&nbsp;be.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Great North Property Management: Great North Website and Secured\u00a0Areas","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/great-north-website-and-secured-areas","rel":"alternate"}},"published":"2010-06-01T00:00:00-04:00","updated":"2010-06-01T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-06-01:\/great-north-website-and-secured-areas","summary":"<h1>Great North Property Management: Great North Website and Secured&nbsp;Areas<\/h1>\n<h2>2010-06-01<\/h2>\n<p><em>Provided a Django <span class=\"caps\">CMS<\/span> for the main website, a secured area for residents to manage their accounts and an engine to run individual sites for each&nbsp;property.<\/em><\/p>\n<p>Starting out, Great North felt like a fairly typical project: content management \u2026<\/p>","content":"<h1>Great North Property Management: Great North Website and Secured&nbsp;Areas<\/h1>\n<h2>2010-06-01<\/h2>\n<p><em>Provided a Django <span class=\"caps\">CMS<\/span> for the main website, a secured area for residents to manage their accounts and an engine to run individual sites for each&nbsp;property.<\/em><\/p>\n<p>Starting out, Great North felt like a fairly typical project: content management system for the main site, some <span class=\"caps\">API<\/span> integration to grab data from their vendor and a secured area for clients. Each of these things is a regular feature in projects I build; <span class=\"caps\">API<\/span> integration and secured areas are almost meta solutions: whatever industry a client is in, they may have need for these things. And a content management system is&nbsp;<em>de rigueur<\/em> for most client web sites nowadays (cue Old Man Mode: &#8220;In my day, we had to author all our pages by hand. And the only includes were <span class=\"caps\">SSI<\/span> and they were dump ad you couldn&#8217;t do any logic in&nbsp;them.&#8221;).<\/p>\n<p>Happily, this project turned out to be fun. While it didn&#8217;t hurt that the client contact was a friend of Lightfin&#8217;s, what made it enjoyable for me was perspective. When I started as a web developer, we lived in a series of apartments with consistently horrible management companies. Just before we moved into our home in Dover, we lived in a townhouse in a small condo community that barely felt like a community at all. So this project felt like a chance to build something that would improve users&#8217; lives. We could use the web to make something that would be a huge improvement over the experience I suffered through with deaf management companies whose only interaction was sticking a hand out to take your&nbsp;rent.<\/p>\n<p>The <a href=\"http:\/\/greatnorth.net\/\">site itself<\/a> runs off the Django <span class=\"caps\">CMS<\/span> I&#8217;ve been using for projects this year. The other two applications serve Great North clients. The first is a site for all members across the communities Great North manages. This site allows them to check their current account balance, review previous charges and any recurring charges they have. They can also submit maintenance requests and check the status of their previous requests. Finally, they can maintain their contact information in the site. These activities talk directly to the <a href=\"http:\/\/www.jenark.com\/\">Jenark<\/a> software running on the server in Great North&#8217;s office via custom <span class=\"caps\">API<\/span> calls written by Jenark. In addition to the user-facing <span class=\"caps\">API<\/span> calls, the application calls out every night to get an updated list of all associations Great North manages, then updates the list of units and residents in each building to make sure new residents have automatic access to the site as soon as they move in (and make sure they lose that access once they move&nbsp;out).<\/p>\n<p>The third application powers a &#8220;mini site&#8221; for each association. The mini sites help to provide that sense of community I found lacking when we lived in our townhouse; in spite of it being only 30 or so units in a very small space, it was easy to never really know your neighbors unless they threw a wobbler at the annual meeting. The mini sites provide a list of upcoming events in the community and the ability to subscribe to updates, a directory that lists all board members and any other resident who choses to be listed and any documents residents may need. Better still from Great North&#8217;s perspective, all aspects of the mini sites can be managed by any resident listed as an&nbsp;administrator.<\/p>\n<p>In the end, this wound up being a prototype for what I would like projects to be: a good working relationship with a client that results in a site\/ application that both makes their lives easier and makes their users&nbsp;happy.<\/p>\n<p><img src=\"\/images\/portfolio\/gn-2.jpg\" alt=\"Member Area Members can check their account balance & history, submit maintenance requests and update their contact information.\" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/gn-3.jpg\" alt=\"Mini-Sites Each association has its own website with a member directory, calendar of events and a document library that can be managed by board members.\" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/gn-1.jpg\" alt=\"Homepage Great North's web site serves over 19,000 resident customers\" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"django"}},{"@attributes":{"term":"api"}},{"@attributes":{"term":"integration"}}]},{"title":"Week\u00a0137","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/week-137.html","rel":"alternate"}},"published":"2010-05-21T11:36:53-04:00","updated":"2010-05-21T11:36:53-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-05-21:\/week-137.html","summary":"<h1>Week&nbsp;137<\/h1>\n<p>Not a whole lot to report. There is, I suppose, but it&#8217;s too damn nice of a day to spend it reading (or writing) this stuff. I&#8217;m dangerously close to finishing a site for <span class=\"caps\">PBS<\/span>&#8217; Frontline after a week-long crunch. It&#8217;s been yet another experience \u2026<\/p>","content":"<h1>Week&nbsp;137<\/h1>\n<p>Not a whole lot to report. There is, I suppose, but it&#8217;s too damn nice of a day to spend it reading (or writing) this stuff. I&#8217;m dangerously close to finishing a site for <span class=\"caps\">PBS<\/span>&#8217; Frontline after a week-long crunch. It&#8217;s been yet another experience that&#8217;s re-affirmed my love for Django. It&#8217;s to the point where I can take on (literally) twice as much work as I could before Django and the scary thing is that I&#8217;m just getting comfortable with it and each project exposes me to at least one new package that makes things easier. For instance, I really wish I&#8217;d known about <a href=\"http:\/\/wiki.developers.facebook.com\/index.php\/User:PyFacebook_Tutorial\">PyFacebook<\/a> a couple of projects ago. It would have made things a lot easier (especially if I&#8217;d coupled it with <a href=\"http:\/\/github.com\/flashingpumpkin\/django-socialregistration\">django-socialregistration<\/a>).<\/p>\n<p>The downside to my love affair with Django is it gets really easy to become picky, to insist on only taking projects that can be done in Django. The next step is to try to force each project into the shape of previous projects; the whole reason I gave up on CMSes in favor of a framework like Django was to avoid cramming a client&#8217;s square peg into a round hole (dirty!). Always working in the same language and framework is a ghetto: you only know what you know and you don&#8217;t get exposed to new&nbsp;ideas.<\/p>\n<p>So I&#8217;ve ripped through another Django project and have picked up a new one this week as well. And yet, given my chronic case of <a href=\"http:\/\/www.urbandictionary.com\/define.php?term=Irish%20Alzheimers\">Irish Alzheimer&#8217;s<\/a>, I&#8217;m down in the mouth because this week also saw the death of a project. Not death exactly, but it&#8217;s being shipped off to India to apply the final touches. Whether that&#8217;s death or <span class=\"caps\">CPR<\/span> depends entirely on who gets a hold of it, but I&#8217;m guessing the project would have a hell of a time getting term life insurance right now. It&#8217;s only the second project I&#8217;ve had go south in the 2-and-a-half years I&#8217;ve been out on my own, but it still sucks. In each case I came in after the contract had been agreed on and after (what would have been) the requirements gathering period had ended. I&#8217;d call it a clear lesson learned except it&#8217;s one I learned a long time ago and keep screwing up because I assume I can punch my way out of anything. I need to spend less time improving my code and more time improving my ability to communicate the value of up-front requirements gathering and a process &#8220;agile&#8221; enough (whatever that means) to get regular feedback from the client on how things currently&nbsp;look.<\/p>\n<p>Totally unrelated to any of this, but I did run into an interesting usability issue while we were on vacation in Maine. Though it may be silly to generalize about a state&#8217;s drivers, I will still assert Maine&#8217;s drivers are far more law-abiding than their New Hampshire counterparts. So I was surprised to see how they lay out passing lanes in Maine: like a challenge to your manhood. The first couple I shrugged off as mistakes, but after a day or two I could not get over how many passing lanes didn&#8217;t end until you were just about up to a curve or hill that obstructed your view. I finally figured it out at the end of our trip: Maine assumes the best in its residents and visitors. Passing lanes end at the last possible second it&#8217;s safe to pull back in. New Hampshire knows their residents are crazy. Passing lanes end at the last inch you could possibly pull out at and pass someone assuming you&#8217;re on a motorcycle and passing a rickshaw. It&#8217;d be nice if Maine added one more sign to the Burma Shave-esque laundry list of warnings they have when passing from New Hampshire into Vacationland. Or just replace them all with &#8220;Welcome to Maine: Don&#8217;t Do It,&nbsp;Brutha&#8221;.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"django-avatar and Pinax\u00a0Configuration","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/django-avatar-and-pinax-configuration.html","rel":"alternate"}},"published":"2010-05-05T11:35:04-04:00","updated":"2010-05-05T11:35:04-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-05-05:\/django-avatar-and-pinax-configuration.html","summary":"<h1>django-avatar and Pinax&nbsp;Configuration<\/h1>\n<p>Noting this here for the sanity of my future self. When using <a href=\"http:\/\/github.com\/ericflo\/django-avatar\">django-avatar<\/a> (which is included in Pinax), you need to add at least one of the avatar settings, AVATAR_STORAGE_DIR, to your settings.py file. The important thing to note is this needs to be a \u2026<\/p>","content":"<h1>django-avatar and Pinax&nbsp;Configuration<\/h1>\n<p>Noting this here for the sanity of my future self. When using <a href=\"http:\/\/github.com\/ericflo\/django-avatar\">django-avatar<\/a> (which is included in Pinax), you need to add at least one of the avatar settings, AVATAR_STORAGE_DIR, to your settings.py file. The important thing to note is this needs to be a relative path to a folder under your MEDIA_ROOT as the path will be used both to create a file system path and to build the urls when serving the avatar&nbsp;images.<\/p>\n<p>For local development, I had trouble getting the avatars (or anything under \/media) to appear. The patterns in Pinax&#8217;s staticfiles.urls include one for everything under \/media, but not only didn&#8217;t I see files under that folder, the server didn&#8217;t even attempt to serve them. I tried explicitly putting the pattern into my main urls.py at the top of the list, but nothing changed. As a fix, I changed my local MEDIA_URL to &#8216;\/includes\/&#8217; and added that pattern to my urls.py, which fixed things. The production server should not be affected since the files won&#8217;t be served by&nbsp;Django.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Week\u00a0134","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/week-134.html","rel":"alternate"}},"published":"2010-05-01T12:40:35-04:00","updated":"2010-05-01T12:40:35-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-05-01:\/week-134.html","summary":"<h1>Week&nbsp;134<\/h1>\n<p><span class=\"dquo\">&#8220;<\/span>It ain&#8217;t always easy, if your knees knock as hard as mine, but you must remember the golden rule: when the game&#8217;s going against you, stay calm&mdash; and cheat.&#8221;\n<em>Flashman at the&nbsp;Charge<\/em><\/p>\n<p>Heard from an old client and met with a (potential) new one this \u2026<\/p>","content":"<h1>Week&nbsp;134<\/h1>\n<p><span class=\"dquo\">&#8220;<\/span>It ain&#8217;t always easy, if your knees knock as hard as mine, but you must remember the golden rule: when the game&#8217;s going against you, stay calm&mdash; and cheat.&#8221;\n<em>Flashman at the&nbsp;Charge<\/em><\/p>\n<p>Heard from an old client and met with a (potential) new one this week. Though both New England-based service companies of comparable size, they&#8217;re from two different eras. Due to dropping margins in their current business, the existing client is moving into a new, tangentially-related one. Before building a new site, they wanted me to do some search engine research. I&#8217;ve been working in <span class=\"caps\">SEO<\/span> since around the time they coined the term and it&#8217;s never been satisfying. Some of it&#8217;s just my personality: I like coming back to clients with finished work, with correct answers. <span class=\"caps\">SEO<\/span> resists that. No matter how the algorithms change, it&#8217;s always going to be an art<a href=\"#foot1\"><sup>[1]<\/sup><\/a>. The client&#8217;s new industry is a competitive one. Until they&#8217;ve established themselves, search engines are going to be an opponent, not a help. We&#8217;ve come up with a list of keywords and a strategy for using those words and getting linked to by their partners and other industry sites, but that&#8217;s about all that can be done on my end. I could do a lot more busywork and generate a lot of documentation, but that&#8217;s the dark art part of <span class=\"caps\">SEO<\/span>. Without relevant content that interests people enough to link to it, you&#8217;re chasing the keyword market (through bought AdWords) rather than creating it. My advice to the client is the same easy (for me) advice I always provide: from the terms you gave me, here are the words people actually search for. Put those in your content. And then keep creating new content on a regular basis (blog). Create it with a consistent voice and create it because the content is worth&nbsp;knowing.<\/p>\n<p>The new client also feels their chosen industry is contracting. Rather than branching out, they&#8217;ve decided to reposition. The Internet made their business a lot easier; reduced costs led to higher margins. For a while. But like nature abhors a vacuum, the economy always destroys an arbitrage. The efficiencies introduced by the &#8216;net brought much larger companies into the industry on a national level. The client cannot compete at their price point. They could, but it&#8217;d be a short competition given the negative margins they&#8217;d&nbsp;suffer.<\/p>\n<p>So they have to change their model. In any service industry, you can be a boutique. There are some people out there so good at what they do they can make it on word of mouth, but it&#8217;s a pretty risky bet to assume you&#8217;re that good<a href=\"#foot2\"><sup>[2]<\/sup><\/a>. The client&#8217;s idea is to become a resource. A lot of people pay lip-service to this idea, but it&#8217;s nice to see a client come up with the idea on their own and be committed to it. I enjoyed it all the more because it was disconcerting: they&#8217;re a small shop hidden in New Hampshire and the client&#8217;s old enough (ageism alert!) it was unexpected. Survival&#8217;s a powerful&nbsp;motivator.<\/p>\n<p>I&#8217;m sure every region of the country (and every country in the world) has them, but I&#8217;ve only known New England and I think this region runs on people hidden in the woods who know what they&#8217;re doing. I once went on a business trip with my Dad when I was still in high school. We wound up down a dirt road in Rhode Island in front of a couple of old Quonset huts representing the sum total of a metal fabrication shop. Out walks a heavyset guy in his 60s with a bushy beard full of tobacco spit off the unlit cigar that never left his mouth. But inside one of those huts was a <span class=\"caps\">CAD<\/span> program driving a plasma cutter. This was 1992 at the latest: it&#8217;d be like walking into your neighborhood auto parts store and finding wings for flying cars. Little ahead of his time. It&#8217;s nearly two decades later (God help me) and there are still people in his business not that technically&nbsp;advanced.<\/p>\n<p>Guys (sexism alert!) like that always survive. They don&#8217;t thrive: they refuse (or are uncomfortable) marketing themselves and to grow past a certain size they&#8217;d have to overcome the cultural barrier of dealing with bankers from a city. Maybe put on a suit. Which means there&#8217;s room in the industry. Between giant (multi-)national companies and brilliant Yankees in the woods, there&#8217;s room for people who, regardless of how good they are at what they do, are decent at marketing themselves. If you don&#8217;t go with the giant in the industry and you don&#8217;t know about the boutique, you wind up with whomever you can find. Which is why spam works and why you have to pay $100 to get a poster framed in your town. The Internet&#8217;s flattening those things out. It&#8217;s abstracting marketing out of industries: killing trade magazines, newspaper classifieds, anything that made money by holding onto information. I don&#8217;t know what it will mean when it&#8217;s easy to find the boutiquess and the ass-kickers for whatever job needs doing, but it can&#8217;t hurt to be a resource in your industry. Give away the knowledge and show you can do the&nbsp;job.<\/p>\n<p><small id=\"foot1\" style=\"font-size: 90%\">1. &#8220;art&#8221; in either the loosest sense of the word or when the best people in the industry do it. Most of it&#8217;s a lot worse than art and some of it is pure snake oil.<\/small>\n<small id=\"foot2\" style=\"font-size: 90%\">2. &#8220;Hello Kettle, this is Pot. Can you hear me?&#8221;<\/small><\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Any Interest in the 700-page Abridged\u00a0Version?","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/any-interest-in-the-700-page-abridged-version.html","rel":"alternate"}},"published":"2010-04-27T08:00:03-04:00","updated":"2010-04-27T08:00:03-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-04-27:\/any-interest-in-the-700-page-abridged-version.html","content":"<h1>Any Interest in the 700-page Abridged&nbsp;Version?<\/h1>\n<p><span class=\"caps\">INT<\/span> - <span class=\"caps\">KITCHEN<\/span> - <span class=\"caps\">DAYTIME<\/span><\/p>\n<p><strong>Me<\/strong>: We&#8217;ve still got the frying pan to clean.\n<strong>Michelle<\/strong>: I always forget that.\n<strong>Me<\/strong>: I know, it&#8217;s on my list of complaints about you.\n<strong>Michelle <\/strong><em>(unimpressed)<\/em>: Really?\n<strong>Me<\/strong>: See chapter 3, &#8220;Domestic&nbsp;Disappointments&#8221;.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Week\u00a0133","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/week-133.html","rel":"alternate"}},"published":"2010-04-23T14:16:58-04:00","updated":"2010-04-23T14:16:58-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-04-23:\/week-133.html","summary":"<h1>Week&nbsp;133<\/h1>\n<p><em>&#8221;[T]here&#8217;s something splendid waiting for you to go and find it, far out yonder. I wonder if I&#8217;d feel it now, or if it happens only when you&#8217;re young, and have no thought for the ill things that may lie along the way.&#8221;<\/em>\nFlashman \u2026<\/p>","content":"<h1>Week&nbsp;133<\/h1>\n<p><em>&#8221;[T]here&#8217;s something splendid waiting for you to go and find it, far out yonder. I wonder if I&#8217;d feel it now, or if it happens only when you&#8217;re young, and have no thought for the ill things that may lie along the way.&#8221;<\/em>\nFlashman, <em>Flashman and the&nbsp;Redskins<\/em><\/p>\n<p>This week&#8217;s notes start last week, but Saturday was after my last post and it&#8217;s appropriate this beings with an ending because that&#8217;s where I want to begin. I was lucky to learn a Universal Truth in my first job. There was a woman who&#8217;d worked at Putnam for years when my class of newbies rolled in. As far as we could tell, she was one of the engines that made our department go: knew everything about her specialty, did a ton of work (at 34 instead of 22, I can tell you all she&#8217;d done is carve out a fiefdom by working on one thing and spending the rest of her time fighting to avoid the rest). She managed to miss a month of work with a back injury. Upon returning, someone had an uncomfortable conversation with her about how part timers didn&#8217;t get sick time so they were going to have to take from her vacation time (leaving her with something like -97 hours to spend on beaches around the world). She walked out on the spot. Well, she made a scene and then walked&nbsp;out.<\/p>\n<p>Shock. Desperation. Visions of insane workloads, late hours and less fun than we were already having danced in our heads. What we discovered instead: she talked a much better game than she played and her work was easy. In a couple of weeks, with no new hires, it was like she never existed. Since then I&#8217;ve always reminded myself <a href=\"http:\/\/www.schneier.com\/blog\/archives\/2010\/04\/the_effectivene_1.html\" onclick=\"window.open(this.href); return false;\">no one is irreplaceable and no one is the keystone<\/a>. When I left Putnam, I slunk out a couple of hours before quitting time just as the part-time ladies brought my cake in. Maybe a little cold, but they wanted the cake, not a goodbye and I&#8217;ve always been addicted to that feeling of freedom that only comes from leaving.&nbsp;Anything.<\/p>\n<p>But all of that is a bit of a lie and I&#8217;m a lot of a hypocrite. Make no mistake, I am not a team leader. I&#8217;m too prickly and I can&#8217;t modulate my expectations for people. Expecting less of others than I expect of myself feels like an insult. Completely unfair and maybe a little pathological, but there it is. I fancy myself more like a point man: you might not see much of me, we might not be best friends, but you&#8217;re never going to get blown up on my watch. While I tell myself nobody makes a lasting impression unless they jump from a great heightr<a href=\"#foot1\"><sup>[1]<\/sup><\/a>, I&#8217;ve always had it in the back of my head I lead by example, I leave places better off than I found them. Which is a damn fool illusion to walk around with. Because on Saturday I ran into some code from a place I used to work. And it took me a half hour to calm down enough to fix the worst of the mistakes in the code. You can see why I&#8217;m not a team leader. Calming down involved emailing a couple of former coworkers to grouse. We decided the secret ingredient when we were there were the small smattering of complete incompetents who made everyone work double-time because they knew they had to carry the load. In the hope of reducing the sum total of complete incompetents in the world (at least for the next 10 minutes), I&#8217;m going to talk about how not to write the code I came across. So if that sounds like nerdery, jump off now. It won&#8217;t get any better in the next&nbsp;graf.<\/p>\n<p>The first time you code something, it is the most rickety thing you&#8217;ll ever come across. Various labels exist for this genus of code: &#8220;twine and baling wire&#8221;, &#8220;duct tape&#8221;, etc. You&#8217;re basically speaking a foreign language and the fist time you get an acceptable response, you stop everything and call it done. The form submits and anything shows up in the database? Success! Don&#8217;t anyone touch it. Assuming you&#8217;re not completely put off by the process, at some point you realize your code can break. But even after cleaning up all the mistakes, there are still any number of ways a user can break the thing. Exceptions. So you write your first exception handler<a href=\"#foot2\"><sup>[2]<\/sup><\/a>.<\/p>\n<p>The first step to exception handling enlightenment (keeping in mind your narrator is an unreliable one) is to start using them. That&#8217;s something. It shows a <a href=\"http:\/\/www.ironpalm.com\/beginner.html\" onclick=\"window.open(this.href); return false;\">beginner&#8217;s mind<\/a>. It shows humbleness, a realization of the imperfection inherent in all works of man. But you&#8217;ve barely gotten anywhere, because all you do when you first start trapping exceptions is &#8220;Please catch anything that happens. Eat it, swallow it and pass it without ever making a sound. I don&#8217;t want to know about what happens down in the guts of this program.&#8221; Having a Beginner&#8217;s Mind doesn&#8217;t mean being ignorant. You need to know what&#8217;s going on in there. Instead of saying, &#8220;This could blow up. I better set a trap here&#8221;, you need to think of how it could blow up and trap that. Because if you don&#8217;t know how it&#8217;ll blow up, you don&#8217;t know how you should be handling the exception. If the fire alarm in your house goes off, it could be that the batteries need changing. It could be dust got into the sensor. Or it could be your house is currently engulfed in flames. You don&#8217;t want to handle all those cases the same way. Because there&#8217;s only one way to handle those cases the same: run away screaming. It&#8217;ll keep you alive, but it won&#8217;t make for good&nbsp;code.<\/p>\n<p>If all you&#8217;re going to do is set up an anonymous try\/ catch (i.e., one that traps every error), don&#8217;t. You&#8217;re better off without them. At least then when things go wrong your users find out and they can tell you. With anonymous try\/ catches, no one knows what happened. Things just don&#8217;t work. Ignorance is an enemy of good work in any field. Self-imposed ignorance &#8230; I don&#8217;t even have a metaphor here. Don&#8217;t do it. Here&#8217;s another hint: the Warnings panel in your compiler? It contains warnings. Yes they are not errors. Yes you can ignore them. Yes there are a couple of things that it warns about that aren&#8217;t necessarily so. But they&#8217;re warnings for a reason and the compiler is smarter than you. So figure out what they mean. &#8220;I can always ignore &#8216;Unreachable code detected&#8217; because someone told me to in this one specific case&#8221; isn&#8217;t knowledge. It&#8217;s faith. It&#8217;s ignorance. Investigate everything, even when someone tells you to ignore it. Worst that happens is <a href=\"http:\/\/www.youtube.com\/watch?v=cFDBW7Xgagg\" onclick=\"window.open(this.href); return false;\">you learn something before you&#8217;re&nbsp;done.<\/a><\/p>\n<p>As pissed as that left me, it was nothing compared to dealing with one of my bigger clients this week. This big client has a big data team. The data team sends us big files full of chronological data. I got killed by <span class=\"caps\">QA<\/span> this week for two major issues that revealed a troublesome problem: some of that chronological data ain&#8217;t. When I pointed out their chronological data was sorted &#8220;alphabetically&#8221; by date (where dates run 3\/2009, 3\/2010, 6\/2009) in one case (and apparently randomly in the other), this did not cause anyone to jump up and fix things. We&#8217;re a small client for the data team. There are plenty of other clients they serve. The problem with that is no one could be relying on the current order of the data. It didn&#8217;t exist. So, as is their wont, they paid me to work around it. Authorized a day&#8217;s worth of work for me to deal with it instead of authorizing 15 minutes of work on the data team&#8217;s side to fix the problem permanently across all existing and future projects that consume the data. Please don&#8217;t sing me sad songs of how I don&#8217;t understand big systems and all of the interactions and the need to <span class=\"caps\">QA<\/span> and how many eyes have to look at the problem. Somewhere on some server there&#8217;s a bit of code that pulls this data out without bothering to sort it like the rest of the data it pulls out. At the outside that&#8217;s a 3 line fix. My 15 minute estimate gives you 10 to sit on the&nbsp;john.<\/p>\n<p><small id=\"foot1\" style=\"font-size: 90%\">1. Shamelessly stolen from <a href=\"http:\/\/www.youtube.com\/watch?v=y6Jw1SOFn0s\" onclick=\"window.open(this.href); return false;\">The Old &#8216;97s<\/a><\/small><\/p>\n<p><small id=\"foot2\" style=\"font-size: 90%\">2. An aside here for the non-technical minded (though you were politely asked to leave): an exception handler is (wait for it) a way of handling an exception. But the important thing is what you consider an &#8220;exception&#8221;. A good example of a handled exception is asking a user where to save a file and they provide a path that doesn&#8217;t exist. The handler fires and gives you a chance to yell at the user rather than just crashing your program.<\/small><\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"True Love: A Play in One\u00a0Act","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/true-love-a-play-in-one-act.html","rel":"alternate"}},"published":"2010-04-22T09:08:28-04:00","updated":"2010-04-22T09:08:28-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-04-22:\/true-love-a-play-in-one-act.html","summary":"<h1>True Love: A Play in One&nbsp;Act<\/h1>\n<p><span class=\"caps\">OUTDOORS<\/span> - <span class=\"caps\">NIGHT<\/span> - <span class=\"caps\">FENWAY<\/span> <span class=\"caps\">PARK<\/span><\/p>\n<p><em>A nice April night, game is in the middle innings, Kevin Youkilis coming up to&nbsp;bat.<\/em><\/p>\n<p><strong>Michelle<\/strong>: After this at bat, I&#8217;m going to the bathroom, no matter what Youk does.\n<strong>Me<\/strong>: What if he cries out your \u2026<\/p>","content":"<h1>True Love: A Play in One&nbsp;Act<\/h1>\n<p><span class=\"caps\">OUTDOORS<\/span> - <span class=\"caps\">NIGHT<\/span> - <span class=\"caps\">FENWAY<\/span> <span class=\"caps\">PARK<\/span><\/p>\n<p><em>A nice April night, game is in the middle innings, Kevin Youkilis coming up to&nbsp;bat.<\/em><\/p>\n<p><strong>Michelle<\/strong>: After this at bat, I&#8217;m going to the bathroom, no matter what Youk does.\n<strong>Me<\/strong>: What if he cries out your name?\n<strong>Michelle<\/strong> (<em>pensively<\/em>): I&#8217;m still going to the&nbsp;bathroom<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Week\u00a0132","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/week-132.html","rel":"alternate"}},"published":"2010-04-16T16:19:12-04:00","updated":"2010-04-16T16:19:12-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-04-16:\/week-132.html","summary":"<h1>Week&nbsp;132<\/h1>\n<p><em><span class=\"dquo\">&#8220;<\/span>Well, the Devil made me do it the first time\/ Second time I done it on my own.&#8221;<\/em>\nBilly Joe Shaver, <a href=\"http:\/\/www.youtube.com\/watch?v=OT3xxoyYlr4\" onclick=\"window.open(this.href); return false;\">&#8220;Black&nbsp;Rose&#8221;<\/a><\/p>\n<p>Never got around to the last couple of weekly updates. There wasn&#8217;t much of interest, technology-wise, and they burned the hell out of me \u2026<\/p>","content":"<h1>Week&nbsp;132<\/h1>\n<p><em><span class=\"dquo\">&#8220;<\/span>Well, the Devil made me do it the first time\/ Second time I done it on my own.&#8221;<\/em>\nBilly Joe Shaver, <a href=\"http:\/\/www.youtube.com\/watch?v=OT3xxoyYlr4\" onclick=\"window.open(this.href); return false;\">&#8220;Black&nbsp;Rose&#8221;<\/a><\/p>\n<p>Never got around to the last couple of weekly updates. There wasn&#8217;t much of interest, technology-wise, and they burned the hell out of me. It&#8217;s twice as fun to be burnt-out busy when they paychecks are weeks or months away. Every 4-6 months I go through a transition period where one or two big projects is winding up and new work is starting to trickle in (including a Django project for <em>Frontline<\/em>). The trick is dealing with the maintenance work and one-off edits for clients during this period. I&#8217;m really struggling with the continuous stream of interruptions. When I started on my own I was mad to reply to everything as fast as humanly possible and get the work done in much the same time. Not a great idea. While I&#8217;ve gotten better about resource planning, I still can&#8217;t shake the feeling I <strong>need<\/strong> to reply rightawayohquicknow or lose a client. I know none of my clients stick with me because I can turn around an email quickly. Anyone could do that. I know it&#8217;s for the quality of my work and I know I have credit in the bank with (most of) them, but I still drive myself&nbsp;nuts.<\/p>\n\n<p>Email&#8217;s the problem right now. It&#8217;s always the first tab in my browser and then I have a Gmail plugin\/ setting that updates the tab with an inbox count, in the interests of further self-abuse. When I worked for someone else and email became a problem, I&#8217;d just shut it off. Someone wanted me, they could call. And if that got to be a problem, I set the phone to make-busy. Not the thing that sends &#8216;em straight to voicemail (I probably checked my voicemail less than 20 times in 8 years&#8212; never occurred to me), the thing that dumped the call. Walk over if things are that bad. But now that I&#8217;m my own boss, I can&#8217;t do it. I need to find some way to shut off email without obsessing over it. Still working on that. It&#8217;s not an original observation (I think it&#8217;s the theme song of the freelancer), but I want to make more days lie Saturday. Michelle works on Saturday morning, so my work week is from late morning Monday (theoretically&mdash; it&#8217;s been more like early morning Monday recently) through 1pm on Saturday. And it feels like 50% of the work I do gets done in the quiet of Saturday when no one expects a response out of me (and don&#8217;t start emailing me now). All I need is two of me: one to do the communicating and one of me to do the work and keep them away from each other before they go out drinking and get in a&nbsp;fight.<\/p>\n\n<p>On a different subject, it&#8217;s always interesting to be on the other side of the fence like I am right now on a project for Big Financial Institution. We&#8217;ve done a lot of work to paper over some of the cracks in their data team&#8217;s process, but we&#8217;re running into Newton&#8217;s Fourth Law: &#8220;For every effort you make to hide the incompetence of someone you depend on, they will redouble their effort.&#8221; This is a Big Company. I&#8217;m not mentioning it to impress anyone. I&#8217;m mentioning it because I can&#8217;t imagine working for their data team and sleeping more than an hour a night. We&#8217;ve been (theoretically, mind you) getting the same thing delivered quarterly for almost a year now. Counting all the test runs, we&#8217;ve probably had a dozen data drops from them. And it&#8217;s painfully clear this stuff is not delivered by script. It&#8217;s 12 <span class=\"caps\">XML<\/span> files with the same data fields every time for the same funds. Is it scripted? Hell no. Best I can tell, there&#8217;s a guy with a button somewhere. And best I can tell, he was dropped on his head as a child. Maybe that&#8217;s what makes me decent at my job, because I always hear Jim Clancy in my head: &#8220;There&#8217;s a difference between a job done and a job done right.&#8221; At some point, stay late. Whether they pay you for it or try to kick you out for being there late, stay and figure out all the questions in the process, find the correct answers <em>one time<\/em> and then make a damn computer do it. Because then you&#8217;ll never have to look up the answers again, which means you won&#8217;t have a chance to mess it up. And if you tell me there are too many moving parts to script the process, that just means you don&#8217;t understand the process. Break it down into a bunch of steps, write some God-awful-looking code that works and be done with it. No one&#8217;s ever going to see it, they&#8217;re just going to be happy with you. And if they fire you because you made yourself redundant, good. I guess some people can work at <a href=\"http:\/\/thedailywtf.com\/Articles\/The-Corruption-of-Dennis.aspx\" onclick=\"window.open(this.href); return false;\">a job where everyone agrees not to work too hard<\/a>, but that&#8217;s a Devil&#8217;s Bargain: you grow fat and lazy and dull and then the only jobs you can work are ones just like it. And they don&#8217;t hire much. Because people don&#8217;t leave and because the company isn&#8217;t&nbsp;growing.<\/p>\n\n<p>It pains me some people are (theoretically) in the same industry as me but have no curiosity about it. True anywhere, I just happen to see it here. Which is why when people ask what I do, I tell them I&#8217;m a valet at the&nbsp;drive-in.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Community Trust Bank: Community Trust Bank\u00a0Site","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/community-trust-bank-site","rel":"alternate"}},"published":"2010-04-01T00:00:00-04:00","updated":"2010-04-01T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-04-01:\/community-trust-bank-site","summary":"<h1>Community Trust Bank: Community Trust Bank&nbsp;Site<\/h1>\n<h2>2010-04-01<\/h2>\n<p><em><span class=\"caps\">CMS<\/span> and Django tools for a Louisiana bank web site. Tools allow the bank to manage multiple product lines with different details from state to&nbsp;state.<\/em><\/p>\n<p>Community Trust Bank is based in Louisiana but has expanded into Mississippi and Texas. In order \u2026<\/p>","content":"<h1>Community Trust Bank: Community Trust Bank&nbsp;Site<\/h1>\n<h2>2010-04-01<\/h2>\n<p><em><span class=\"caps\">CMS<\/span> and Django tools for a Louisiana bank web site. Tools allow the bank to manage multiple product lines with different details from state to&nbsp;state.<\/em><\/p>\n<p>Community Trust Bank is based in Louisiana but has expanded into Mississippi and Texas. In order to better serve their expanding customer base and to better reflect their growing size, they contracted <a href=\"http:\/\/www.lightfin.com\/\">Lightfin Studios<\/a> to build a new site. The site is powered by a custom Django <span class=\"caps\">CMS<\/span> that brings together a number of applications. Page content is edited in a friendly <span class=\"caps\">WYSIWYG<\/span> interface in the Django administration tools. Products (e.g., checking accounts, loans, CDs) and rates are also managed in the administrative tools and the relevant pages pull in the information as needed. Additionally, the pages customize the products and rates listed based on the user&#8217;s selected state (and require the user to select a location before displaying any content).&nbsp;thumb:1<\/p>\n<p>In order to help existing customers find the branch or <span class=\"caps\">ATM<\/span> location closest to them, the site provides a <a href=\"https:\/\/www.ctbonline.com\/pages\/locations\">Google Map listing branches and ATMs<\/a> with custom icons on the map. A search form is provided so users can filter the map and location list down to just locations near their zip code. All of this is powered by a Django application that stores locations, zip codes and the longitude\/ latitude pairs for each. Rather than force non-technical administrators to look up the longitude and latitude for their locations, locations are looked up for them via an <span class=\"caps\">API<\/span> provided by&nbsp;<a href=\"http:\/\/tinygeocoder.com\/\">TinyGeocoder<\/a>.<\/p>\n<p><img src=\"\/images\/portfolio\/ctb-locations.jpg\" alt=\"Locations Tool Google Map with radius search based on a user's zip code.\" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/ctb-rates.jpg\" alt=\"Rates Display Current rate information is based on the user's location\" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/ctb-home.jpg\" alt=\"Homepage Community Trust Bank has locations in Louisiana, Mississippi and Texas.\" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"django"}},{"@attributes":{"term":"google"}},{"@attributes":{"term":"googlemaps"}},{"@attributes":{"term":"geodata"}},{"@attributes":{"term":"geolocation"}}]},{"title":"Crew Log: Social Media Site for Boat\u00a0Crews","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/social-media-site-boat-crews","rel":"alternate"}},"published":"2010-04-01T00:00:00-04:00","updated":"2010-04-01T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-04-01:\/social-media-site-boat-crews","summary":"<h1>Crew Log: Social Media Site for Boat&nbsp;Crews<\/h1>\n<h2>2010-04-01<\/h2>\n<p><em>Worked with Slim Kiwi to create a social media site for boat crews to track their friends on crews across the&nbsp;world.<\/em><\/p>\n<p>In July 2009, I began working with Slim Kiwi on an exciting social media project. Usually when I see \u2026<\/p>","content":"<h1>Crew Log: Social Media Site for Boat&nbsp;Crews<\/h1>\n<h2>2010-04-01<\/h2>\n<p><em>Worked with Slim Kiwi to create a social media site for boat crews to track their friends on crews across the&nbsp;world.<\/em><\/p>\n<p>In July 2009, I began working with Slim Kiwi on an exciting social media project. Usually when I see an <span class=\"caps\">RFP<\/span> along the lines of &#8220;It&#8217;s Facebook, but for [niche market]&#8221;, I&#8217;m suspicious, wondering why Facebook can&#8217;t be Facebook for that market. But this project was different. It was immediately clear why boat crews could use their own site. Facebook doesn&#8217;t expose a lot of geographic data and understandably so: most people wouldn&#8217;t care and Facebook has enough privacy problems without exposing where users&nbsp;live.<\/p>\n<p>Rather than start from scratch, we built the project on top of <a href=\"http:\/\/pinaxproject.com\/\">Pinax<\/a> to get the basics out of the way. That left us able to concentrate on the custom parts of this project: where you are, where your friends are and what they&#8217;ve been doing. The showpiece of the site is your logbook: it&#8217;s a customized Google Map that allows users to log their current location by dropping a marker on the map (or searching for a location name). The marker can then be dragged to fine-tune the location and users provide a name and time associated with the location. Points can be organized into trips so users can filter their logbook down to just a given span of time. Each trip also creates an associated photo album so users can associate photos with their trips. Each photo uploaded automatically creates thumbnails for the front page of the trip&#8217;s photo album and thumbnails for various icons throughout the site. Photos are managed through a drag and drop interface allowing users to sort, add and delete photos&nbsp;easily.<\/p>\n<p>The other major component of the site is the Activity Log. Everything you do on the site (add a location, a trip, a photo, update your profile, etc) creates an activity entry. Going to your activity log shows you what you&#8217;ve been up to and what your friends have been doing (assuming their privacy permissions and relationship with you allow it) in chronological order with information about their current location. Activity can be filtered by contact type and by location so you can find friends who are active around you. Designing the activity log and performance tuning it once we had enough test data proved to be an interesting challenge; the experience left a few scars but it also earned me a quick reputation boost at Stack Overflow when I <a href=\"http:\/\/stackoverflow.com\/questions\/2835075\/php-news-feed-database-design\/2875875#2875875\">shared my knowledge&nbsp;there.<\/a><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"django"}},{"@attributes":{"term":"social"}},{"@attributes":{"term":"pinax"}},{"@attributes":{"term":"geodata"}},{"@attributes":{"term":"googlemaps"}},{"@attributes":{"term":"geolocation"}}]},{"title":"Week\u00a0129","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/week-129.html","rel":"alternate"}},"published":"2010-03-26T15:56:38-04:00","updated":"2010-03-26T15:56:38-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-03-26:\/week-129.html","summary":"<h1>Week&nbsp;129<\/h1>\n<p><em><span class=\"dquo\">&#8220;<\/span>There&#8217;s no sense in a man picking out the worst name he can find for everything.&#8221;<\/em><br \/>\nDashiell Hammett, <em><a title=\"Whoa, the actual book, online!\" href=\"http:\/\/books.google.com\/books?id=P93cAJeOD0EC&amp;lpg=PP1&amp;ots=mTJvJGGnkv&amp;dq=dashiell%20hammett%20red%20harvest&amp;pg=PA14#v=onepage&amp;q=&amp;f=false\">Red&nbsp;Harvest<\/a><\/em><\/p>\n<p>On Wednesday, I attended the <a href=\"http:\/\/www.nhupa.org\/\"><span class=\"caps\">NH<\/span> <span class=\"caps\">UPA<\/span><\/a> presentation on focus groups. I spent a lot of the time wondering about the effect of group dynamics on end \u2026<\/p>","content":"<h1>Week&nbsp;129<\/h1>\n<p><em><span class=\"dquo\">&#8220;<\/span>There&#8217;s no sense in a man picking out the worst name he can find for everything.&#8221;<\/em><br \/>\nDashiell Hammett, <em><a title=\"Whoa, the actual book, online!\" href=\"http:\/\/books.google.com\/books?id=P93cAJeOD0EC&amp;lpg=PP1&amp;ots=mTJvJGGnkv&amp;dq=dashiell%20hammett%20red%20harvest&amp;pg=PA14#v=onepage&amp;q=&amp;f=false\">Red&nbsp;Harvest<\/a><\/em><\/p>\n<p>On Wednesday, I attended the <a href=\"http:\/\/www.nhupa.org\/\"><span class=\"caps\">NH<\/span> <span class=\"caps\">UPA<\/span><\/a> presentation on focus groups. I spent a lot of the time wondering about the effect of group dynamics on end products. The immediately striking moment came no more than a half hour after the presenter said to always watch for the person who chooses to sit opposite you as they intend to challenge everything, a volunteer sat right down and played his role. Reminded me of a zillion client meetings with one of my old co-workers who had a gift for making an entire room uncomfortable before he ever opened his mouth. It was obvious from his body language he was going to argue with anything if he could be arsed to pay&nbsp;attention.<\/p>\n\n<p>How does this drive design and development when the answers you get are colored by the dynamics of the group? While it works for consumer products with wide appeal, does it work for software? Does it work for\u00a0consumer\u00a0\u00a0products with wide appeal? Whether a focus group improves or hurts the end result compared to what a lone tinkerer would have built in their garage, it&#8217;s hard to imagine the final product isn&#8217;t watered-down. Large groups of stakeholders are used to define software because you can&#8217;t trust developers (who are almost as literal-minded as the computers they work with), but that doesn&#8217;t make gathering marketing folks, VPs, and whomever had free time around lunch on Thursday the best way to develop an application. I just can&#8217;t shake the feeling so many projects get derailed by someone trying to find something to say in a meeting. It was an adjustment from high school to college, going from a place where teachers were more than ready to tell you you were wrong to <em>tenured <\/em>college professors who&#8217;d let any fool capable of raising a paw offer an answer, no matter how wrong. &#8220;Ok, run with that.&#8221; Please don&#8217;t. \u00a0I never saw evidence that\u00a0if you let someone talk long enough they&#8217;ll get around to the right answer, and that&#8217;s when the problem had a definite right answer. Let someone talk long enough and they wind up talking about themselves. No matter what promises they walked in the door with, how they were going to be the voice of the front-line customer service techs, after a couple of minutes of rambling the answers are what they think.<a href=\"#foot1\">[1]<\/a><\/p>\n\n<p>I was contacted by a company I work with about bailing out a .<span class=\"caps\">NET<\/span> project gone South. It&#8217;s written in .<span class=\"caps\">NET4<\/span> and the fact I never got around to installing VisualStudio 2008, much less 2010, tells you when my Microsoft Empower for ISVs subscription ran out: last week. Plus you only get two years in the program, so now I get to sign up for <span class=\"caps\">MAPS<\/span>, which requires you to take a 10 question quiz to prove &#8230; you can use a search engine, I guess. The Microsoft Partner site is built like they&#8217;re trying to keep you away. It opened 4 or 5 windows (<span class=\"caps\">IE<\/span>-only, of course) all over the screen (somehow managing to throw them across two monitors&#8212; by looking for the bottom left and right corners of my screen, I guess), two of which sat and watched me, apparently. It finally opened the test window, only to have it throw a 500 error and not even show a friendly error page suggesting anyone gave a shit. Even after I completed the test today, the link to purchase a license was broken, asking for a network login on the server. I had to discover some other click path to find a way in to the store. Maybe that&#8217;s how they really test partner&nbsp;candidates.<\/p>\n<div id=\"_mcePaste\">I added <a href=\"http:\/\/code.google.com\/p\/django-axes\/\">django-axes<\/a> to the resident management project I&#8217;m working on. Axes tracks failed login attempts; normally you&#8217;d use it for making sure no one&#8217;s trying to break into your site. In this case, I&#8217;m more interested in seeing who isn&#8217;t able to login since we&#8217;re physically mailing usernames and passwords out to users and we will not have email addresses for the users until after they&#8217;ve signed in and updated their accounts. Even though I needed to customize it a bit to fit our needs (mainly because I&#8217;m not using the generic Django login view for reasons which might not have the greatest of justification), it was easy to fit in and customize. Given how little work it is to add, I&#8217;m making it part of my standard Django deployments going forward as it provides a level of insight into hack attempts and protection against brute force attacks that any project should&nbsp;have.<\/p>\n<div id=\"_mcePaste\">An &#8220;Ah, duh&#8221; moment yesterday: added a line in the deployment script on my current project to run syncdb on each update. Not exactly rocket science, not exactly the best idea ever, but it ensures the deployment server at least has all the database tables. Sounds obvious, but it&#8217;s a testament to Django that I rip through small tasks fast enough I close the ticket as done without ever thinking, &#8220;Hey, I just added x new tables to the database, better make sure the server has them before anyone tries to <span class=\"caps\">QA<\/span>.&#8221;<\/p>\n\n<small id=\"foot1\">1.\u00a0If you don&#8217;t recognize this tune from this graf, it&#8217;s &#8220;The Snob&#8217;s Waltz&#8221;, an aria sung only by the rarest of divas. The song is notable for having no conclusion.<\/small>","category":{"@attributes":{"term":"Posts"}}},{"title":"Week\u00a0128","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/week-128.html","rel":"alternate"}},"published":"2010-03-19T11:57:55-04:00","updated":"2010-03-19T11:57:55-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-03-19:\/week-128.html","summary":"<h1>Week&nbsp;128<\/h1>\n<p>Not much changed from last week, mainly working to push the social networking site out the door (while working on a proposal for another Django\/ Pinax project). This week did mark the first time I actually got a <a href=\"http:\/\/docs.fabfile.org\/0.9.0\/\">Fabric script<\/a> working (not that it&#8217;s hard, just that \u2026<\/p>","content":"<h1>Week&nbsp;128<\/h1>\n<p>Not much changed from last week, mainly working to push the social networking site out the door (while working on a proposal for another Django\/ Pinax project). This week did mark the first time I actually got a <a href=\"http:\/\/docs.fabfile.org\/0.9.0\/\">Fabric script<\/a> working (not that it&#8217;s hard, just that my heart hadn&#8217;t been in it before now). The script isn&#8217;t amazing, it just connects to the server, grabs the most recent source code and runs a couple of commands to restart the server, but it does it all without me having to leave the local command line and none of it happens if the unit tests don&#8217;t pass. The unit test bit is handy because other team members are willing to make the trade-off of sitting through the tests for the convenience of the automated deployment. I like Fabric enough already that I&#8217;m searching around for other problems I can solve with&nbsp;it.<\/p>\n<p>Had an unhappy start to the end of the week when a live Django \u00a0site started barfing this morning. It wouldn&#8217;t load any pages and kept complaining about too many MySQL connections, even when requesting static files. Waiting to hear back from the host to see if they have any insight, but I made some changes that seemed to solve the problem. From the logs, it looked like the site was being indexed by one or more search engines that were still looking for the old URLs. Our 404 page was dynamic and ran some queries to render the page. I changed it to a purely static template and the load cooled down. With some rewrite rules for the old URLs and some additional page caching, things should be&nbsp;ok.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Week\u00a0127","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/week-127.html","rel":"alternate"}},"published":"2010-03-12T12:32:51-05:00","updated":"2010-03-12T12:32:51-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-03-12:\/week-127.html","summary":"<h1>Week&nbsp;127<\/h1>\n<p>(idea cribbed from <a href=\"http:\/\/berglondon.com\/blog\/\" target=\"_blank\"><span class=\"caps\">BERG<\/span><\/a>, week count done by <a title=\"It only works if you're reading it this week, duh.\" href=\"http:\/\/www.wolframalpha.com\/input\/?i=weeks+since+10\/1\/2007\">Wolfram Alpha<\/a> because I am too&nbsp;lazy)<\/p>\n<p><em>&#8221;[T]he beauty of reading a page of de Selby is that it leads one inescapably to the happy conclusion that one is not, of all nincompoops, the greatest.&#8221;<\/em>\n<em><a href=\"http:\/\/en.wikipedia.org\/wiki\/The_Third_Policeman\">The Third Policeman<\/a>*<\/em><\/p>\n<p>Mix \u2026<\/p>","content":"<h1>Week&nbsp;127<\/h1>\n<p>(idea cribbed from <a href=\"http:\/\/berglondon.com\/blog\/\" target=\"_blank\"><span class=\"caps\">BERG<\/span><\/a>, week count done by <a title=\"It only works if you're reading it this week, duh.\" href=\"http:\/\/www.wolframalpha.com\/input\/?i=weeks+since+10\/1\/2007\">Wolfram Alpha<\/a> because I am too&nbsp;lazy)<\/p>\n<p><em>&#8221;[T]he beauty of reading a page of de Selby is that it leads one inescapably to the happy conclusion that one is not, of all nincompoops, the greatest.&#8221;<\/em>\n<em><a href=\"http:\/\/en.wikipedia.org\/wiki\/The_Third_Policeman\">The Third Policeman<\/a>*<\/em><\/p>\n<p>Mix of a week. Started with some edits to the <span class=\"caps\">XML<\/span> parser I wrote for Financial\u00a0Institution\u00a0Client as part of a project that decrypts (<span class=\"caps\">GPG<\/span>) a large set of <span class=\"caps\">XML<\/span> documents, skims them for the parts we&#8217;re interested in, dumps the relevant bit into an Expression Engine database and then transforms all that via <span class=\"caps\">XSL<\/span> to display a customizable dashboard (jQuery <span class=\"caps\">UI<\/span>) on the front end. How&#8217;s that for a keyword-rich blog post?\u00a0Tangentially speaking, this week reminded me that of all the languages, technologies, whatever you like that I work in, <span class=\"caps\">XSL<\/span> is probably the easiest one to make a great mess in. It looks just like <span class=\"caps\">XML<\/span> and <span class=\"caps\">HTML<\/span>, how hard could it be? A little bit of XPath knowledge and you&#8217;re good to go. To make a complete mess. When you write an infinite loop in a normal language, it&#8217;s pretty obvious: you sit there a while, the computer starts to get noisy, the lights go dim. After a few dozen times, you realize what you&#8217;ve done. <span class=\"caps\">XSL<\/span> is (like) a functional programming language. And with all that recursion, it&#8217;s easy to make a computer do something Big Number of times. Just harder to&nbsp;spot.<\/p>\n<p>Also did some final-mile edits on a social network application from <a href=\"http:\/\/slimkiwi.com\/\">Slim Kiwi<\/a> built on top of <a href=\"http:\/\/pinaxproject.com\/\">Pinax<\/a> (and Django). \u00a0Hoping it&#8217;s truly &#8220;final-mile&#8221; as the project is really cool and I&#8217;m quite proud of it. There&#8217;s a ton of geolocation and mapping going on and a fair number of other bright things happening (the bright ideas being supplied by other team members and the bright implementation by Django, obviously). \u00a0I was able to roll some of the geo search and Google Maps integration right into a site for <a href=\"https:\/\/www.ctbonline.com\/pages\/home\">Community Trust Bank<\/a>, a project from <a href=\"http:\/\/www.lightfin.com\/\">Lightfin Studios<\/a> (you can see the location stuff at the <a href=\"https:\/\/www.ctbonline.com\/pages\/locations\">branch <span class=\"amp\">&amp;<\/span> <span class=\"caps\">ATM<\/span> finder<\/a>). That&#8217;s the second bank site I&#8217;ve built with Lightfin, the other being the much-closer-to-home (but harder to spell) <a href=\"http:\/\/www.piscataqua.com\/index.aspx\">Piscataqua Bank<\/a> (built in .<span class=\"caps\">NET<\/span>) which got some updates this week as&nbsp;well.<\/p>\n<p>At the end of last week I started to ramp up on my second Django site with Lightfin. Not much to say about it yet except that it integrates with a third-party <span class=\"caps\">API<\/span> which reminds me of one thing: I hate <a href=\"http:\/\/en.wikipedia.org\/wiki\/SOAP\"><span class=\"caps\">SOAP<\/span><\/a> (the overly-verbose web service format, not the cleaning product so beloved by my ancestors they enslaved a\u00a0leprechaun\u00a0to endorse it). Please don&#8217;t ever use it. I&#8217;d rather parse faxes by hand. If you&#8217;re stuck dealing with <span class=\"caps\">SOAP<\/span> in Python, <a href=\"https:\/\/fedorahosted.org\/suds\/\">Suds<\/a> seems to be the best parsing package out there. I&#8217;m sure there was other stuff going on, but the only thing I can think of is some cleanup I did of an old <span class=\"caps\">ASP<\/span> site and the less said, the&nbsp;better.<\/p>\n<hr \/>\n<p><small>* Indie\/ hipster required disclaimer: I am re-reading <em>The Third Policeman<\/em>, I read it well before it showed up in <em>Lost<\/em>, so cram it.<\/small><\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Fidelity: Broker Information\u00a0Site","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/broker-information-site","rel":"alternate"}},"published":"2010-03-01T00:00:00-05:00","updated":"2010-03-01T00:00:00-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-03-01:\/broker-information-site","summary":"<h1>Fidelity: Broker Information&nbsp;Site<\/h1>\n<h2>2010-03-01<\/h2>\n<p><em>Private web site that brings encrypted <span class=\"caps\">XML<\/span> data about funds into Expression Engine which displays the information in <span class=\"caps\">HTML<\/span> and <span class=\"caps\">PDF<\/span>&nbsp;formats.<\/em><\/p>\n<p><em>A massive undertaking in three&nbsp;parts<\/em><\/p>\n<h2>Fund&nbsp;Information<\/h2>\n<p>This client has a large mutual fund business with a number of channels they sell \u2026<\/p>","content":"<h1>Fidelity: Broker Information&nbsp;Site<\/h1>\n<h2>2010-03-01<\/h2>\n<p><em>Private web site that brings encrypted <span class=\"caps\">XML<\/span> data about funds into Expression Engine which displays the information in <span class=\"caps\">HTML<\/span> and <span class=\"caps\">PDF<\/span>&nbsp;formats.<\/em><\/p>\n<p><em>A massive undertaking in three&nbsp;parts<\/em><\/p>\n<h2>Fund&nbsp;Information<\/h2>\n<p>This client has a large mutual fund business with a number of channels they sell the funds through. One of those channels asked Slim Kiwi to build a site that would provide news and fund information to their brokers. The site is built on Expression Engine and servers a number of &#8220;normal&#8221; content pages. The rest of the site consists of fund information in a custom Expression Engine channel. The information comes from the parent company&#8217;s <span class=\"caps\">IT<\/span> department as a set of <span class=\"caps\">PGP<\/span>-encrypted <span class=\"caps\">XML<\/span> files sent twice quarterly (once at the start of a new quarter and a second delivery later in the month when the fund commentary for the previous quarter has been written). The files belong to three groups (fund, benchmark, Morningstar) and then broken down by category, not by fund, so the information for each fund is split across all&nbsp;files.&nbsp;<\/p>\n<p>Once the funds have been delivered, a series of Python scripts go to work. The first decrypts the data and then kicks off the parsing process. Each group (fund, benchmark, Morningstar) has a parser that inherits common functionality from a parent class. Distilling a lot of detail into a simple statement, the goal of each parser is to consume a great deal of deeply-structured <span class=\"caps\">XML<\/span> data to find the elements we are interested in and then write that information into a flattened form we can bring into Expression Engine with one entry per fund\/ benchmark\/ category. In the interests of simplicity and to make it easier for less technical personnel to update what information gets consumed, all three parsers get their marching orders from a single file. The file consists of simple Python dictionaries mapping our labels to where they live in the <span class=\"caps\">XML<\/span> files. Add a new line and it&#8217;s available in Expression Engine the next time the parser runs. Remove an entry and the information gets&nbsp;dropped.<\/p>\n<p>Once the fund information is in place, the site presents the data as a modern version of the fund prospectus guides that get mailed out. Users can customize the interface to focus on the data they care about: panels can be re-arranged or hidden to make funds easier to read at a glance. The site also remembers user preferences so they only have to customize the interface&nbsp;once.<\/p>\n<h2>Document&nbsp;Packages<\/h2>\n<p>Each fund also has three documents associated with it (two PDFs and one Excel file) that are updated on a quarterly basis. While all of the documents are available on the front of the site, brokers want to be able to get their customers just the documents they&#8217;re interested in and only for the funds a given customer has. The site allows brokers to define sets of documents and receive them as a single zip file (generated on-the-fly by some <span class=\"caps\">PHP<\/span> code). For further convenience, brokers can name the sets of documents (e.g., &#8220;Customer X Reports&#8221;) so they can come back each quarter and get the updated versions of the same set of documents for delivery to their&nbsp;client.<\/p>\n<h2><span class=\"caps\">PDF<\/span>&nbsp;Generation<\/h2>\n<p>Victims of our own success, the client began comparing the pretty <span class=\"caps\">HTML<\/span> pages we were generating to the <span class=\"caps\">PDF<\/span> versions they had to build by hand each quarter (one of the three documents we provide per-fund). The final piece of this project was to start generating those PDFs on the fly. The process works much like the <span class=\"caps\">HTML<\/span> version: Expression Engine provides the information about a fund and we change it into the format we want. The only difference is that the <span class=\"caps\">HTML<\/span> version creates its content by transforming the <span class=\"caps\">XML<\/span> via <span class=\"caps\">XSL<\/span> whereas the <span class=\"caps\">PDF<\/span> process sends the information to a <span class=\"caps\">PHP<\/span> file that uses <a href=\"http:\/\/www.pdflib.com\/\" target=\"_blank\">PDFLib<\/a> to generate the files. In the interests of full disclosure, if I had to do this again, it would not be with PDFLib. It was difficult to work with, hard to debug, hard to manage the licenses on the server and you have to pay for the privilege of suffering through all that. It&#8217;s a lot more painful than the <span class=\"caps\">PDF<\/span> solutions I&#8217;ve used in Python and there seem to be a number of better options out&nbsp;there.<\/p>\n<p><img src=\"\/images\/portfolio\/fund-detail.png\" alt=\"Fund Detail One of the five screens of fund data, showing the ability to collapse and re-arrange panels\" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/fund-downloads.png\" alt=\"Saved Downloads The 'shopping cart' of saved zip file collections. Please note the brilliant and original names I use during testing.\" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/fund-matrix.png\" alt=\"Fund Matrix Overview 'matrix' of funds and their related documents\" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"expressionengine"}},{"@attributes":{"term":"xml"}},{"@attributes":{"term":"pgp"}},{"@attributes":{"term":"gpg"}},{"@attributes":{"term":"encryption"}},{"@attributes":{"term":"pdf"}},{"@attributes":{"term":"jquery"}},{"@attributes":{"term":"php"}},{"@attributes":{"term":"python"}}]},{"title":"On\u00a0Optimization","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/on-optimization.html","rel":"alternate"}},"published":"2010-02-25T14:50:12-05:00","updated":"2010-02-25T14:50:12-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-02-25:\/on-optimization.html","summary":"<h1>On&nbsp;Optimization<\/h1>\n<p>It&#8217;s strange what you can get used to: the current social network site I&#8217;m working on has a page with 216 database queries on it. Used to be I&#8217;d get the hives if I hit a dozen queries on a&nbsp;page.<\/p>\n<p><strong><span class=\"dquo\">&#8220;<\/span>216! Did you know \u2026<\/strong><\/p>","content":"<h1>On&nbsp;Optimization<\/h1>\n<p>It&#8217;s strange what you can get used to: the current social network site I&#8217;m working on has a page with 216 database queries on it. Used to be I&#8217;d get the hives if I hit a dozen queries on a&nbsp;page.<\/p>\n<p><strong><span class=\"dquo\">&#8220;<\/span>216! Did you know databases let you bring back more than one row at a time&nbsp;nowadays?&#8221;<\/strong><\/p>\n<p>Yes. The project is in Django (and built on top of <a href=\"http:\/\/pinaxproject.com\/\" target=\"_blank\">Pinax<\/a>), so it&#8217;s the <span class=\"caps\">ORM<\/span> making all those queries, not me. It&#8217;s one of those social network site pages that aggregates activity from everyone you follow. It also shows details about them, how far they are away from you and any comments on the item, so there&#8217;s only so small I can make it while coloring inside the lines of the mapping system. I&#8217;ve already fallen back to raw <span class=\"caps\">SQL<\/span> for one of the elements (there are a couple of places, and sure to be more in the future, where we return a list of the database ids of all your friends so we can use them as part of &#8221; <span class=\"caps\">AND<\/span> id in (x, y, z)&#8221; queries. Doing that through Django resulted in one query to the database for every friend you have. Given this was causing a slowdown when I&#8217;m the only user of the site and I only have 3 friends (one is another tester and the other two are dogs I know, so it&#8217;s kind of a <a href=\"http:\/\/www.drivebytruckers.com\/lyrics_btcd.html#bob\" target=\"_blank\">&#8220;Bob&#8221;<\/a> situation (specifically the dog part and not the rest)), I had a suspicion that wasn&#8217;t going to scale. Modified that, added some caching, got smarter about some lookups (I thought I&#8217;d only hit the db once no matter how many times I referred to a model&#8217;s property in a function) and things are back to running&nbsp;smoothly.<\/p>\n<p><strong><span class=\"dquo\">&#8220;<\/span>216!&#8221;<\/strong><\/p>\n<p>Hey, it was 1066 when I started a day ago. Or something close to that. I&#8217;ve got 1066 on the brain because I&#8217;ve been thinking about William of Orange and before you&nbsp;say&#8212;<\/p>\n<p><strong><span class=\"dquo\">&#8220;<\/span>Write code for a job and think about William of Orange in your spare time. You must be a hit with the&nbsp;ladies.&#8221;<\/strong><\/p>\n<p>&#8212;that, let me point out it was in reference to a <a href=\"http:\/\/www.urbandictionary.com\/define.php?term=dutch%20oven\" target=\"_blank\">Dutch Oven<\/a> joke. That has to count for&nbsp;something.<\/p>\n<p><strong><span class=\"dquo\">&#8220;<\/span>Undoubtedly. Perhaps &#8216;lady killer&#8217; is more literal than figurative in your&nbsp;case.&#8221;<\/strong><\/p>\n<p>Regardless, given the nature of the screen, aggregating a dozen types of activities from an arbitrary number of users, I don&#8217;t think the current solution is the long-term answer, so I buttoned it up as best I&nbsp;could.<\/p>\n<p><strong><span class=\"dquo\">&#8220;<\/span>As best you could? Implement the long-term solution&nbsp;now.&#8221;<\/strong><\/p>\n<p>That would be solving a problem I don&#8217;t have (c.f., &#8220;<a href=\"http:\/\/www.acm.org\/ubiquity\/views\/v7i24_fallacy.html\" target=\"_blank\">premature optimization<\/a>&#8221;, &#8220;<a title=\"You Ain't Gonna Need It\" href=\"http:\/\/en.wikipedia.org\/wiki\/You_ain't_gonna_need_it\" target=\"_blank\"><span class=\"caps\">YAGNI<\/span><\/a>&#8221;). Given the data for this screen is derived from other objects in the system anyway, I think the long-term solution is to move this data into a nosql store (here&#8217;s an <a href=\"http:\/\/www.eflorenzano.com\/blog\/post\/using-couchdb-django\/\" target=\"_blank\">example of using CouchDB in Django<\/a> now and future updates to Django should improve support for this kind of thing). It&#8217;s important to remember traffic issues fall under the title Good Problems to Have. While I&#8217;d love to spend a couple of days implementing this rightnowyespleasecani, if the overall project never takes off, it would be unfair to ask the client to pay for something they didn&#8217;t ask for and never&nbsp;needed.<\/p>\n<p><strong><span class=\"dquo\">&#8220;<\/span>216!&#8221;<\/strong><\/p>\n<p>I&#8217;m already obsessing over it on my own. Why do you think you&#8217;re&nbsp;here?<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"My Party Label: My Party Label Order\u00a0Form","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/my-party-label-order-form","rel":"alternate"}},"published":"2010-02-13T00:00:00-05:00","updated":"2010-02-13T00:00:00-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2010-02-13:\/my-party-label-order-form","summary":"<h1>My Party Label: My Party Label Order&nbsp;Form<\/h1>\n<h2>2010-02-13<\/h2>\n<p><em>Turned manual email order process into an online&nbsp;form.<\/em><\/p>\n<p>Tired of accepting sometimes invalid orders over email, My Party Label came to me to create a form that contained all the information My Party Label needs to fulfill an order. The \u2026<\/p>","content":"<h1>My Party Label: My Party Label Order&nbsp;Form<\/h1>\n<h2>2010-02-13<\/h2>\n<p><em>Turned manual email order process into an online&nbsp;form.<\/em><\/p>\n<p>Tired of accepting sometimes invalid orders over email, My Party Label came to me to create a form that contained all the information My Party Label needs to fulfill an order. The form allows users to send a good deal of custom information, but it makes sure they provide a basic set of information. If available, users can also upload a logo or design with the submission. Successful submissions are logged to a new database and open orders can then be retrieved as an Excel spreadsheet by site&nbsp;administrators.<\/p>\n<p><img src=\"\/images\/portfolio\/my-party-label.jpg\" alt=\"Order Form \" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"php"}},{"@attributes":{"term":"form"}},{"@attributes":{"term":"captcha"}}]},{"title":"Microformat Proposal: Coding\u00a0Experience","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/microformat-proposal-coding-experience.html","rel":"alternate"}},"published":"2009-09-19T09:13:29-04:00","updated":"2009-09-19T09:13:29-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-09-19:\/microformat-proposal-coding-experience.html","summary":"<h1>Microformat Proposal: Coding&nbsp;Experience<\/h1>\n<p>When I&#8217;m working, even in a language I know well, I often search for how to do something; either because I don&#8217;t know or because I feel there&#8217;s a better way (as <a href=\"http:\/\/twitter.com\/ed_atwell\">@ed_atwell<\/a> says, &#8220;I don&#8217;t know, but I bet my friends \u2026<\/p>","content":"<h1>Microformat Proposal: Coding&nbsp;Experience<\/h1>\n<p>When I&#8217;m working, even in a language I know well, I often search for how to do something; either because I don&#8217;t know or because I feel there&#8217;s a better way (as <a href=\"http:\/\/twitter.com\/ed_atwell\">@ed_atwell<\/a> says, &#8220;I don&#8217;t know, but I bet my friends <a href=\"http:\/\/www.google.com\/\">Larry and Sergei<\/a> do). My personal system for filtering code search results looks something&nbsp;like:<\/p>\n<ol>\n    <li>Blogs I&nbsp;trust<\/li>\n    <li>Personal&nbsp;blogs<\/li>\n    <li>Development sites (e.g., 4guysfromrolla.com,&nbsp;etc.)<\/li>\n    <li>Mailing lists and newsgroups<sup><a href=\"#foot1\">1<\/a><\/sup><\/li>\n    <li>Forums<\/li>\n    <li>Expert&nbsp;Sexchange<\/li>\n<\/ol>\n\n<p>Regardless of where it comes from, there&#8217;s no way to know if it&#8217;s right. It&#8217;s human nature to use the first thing that works (if under deadline, even the first thing that kinda works will do). As Jeff Atwood has <a href=\"http:\/\/www.codinghorror.com\/blog\/archives\/001257.html\">pointed out<\/a> (<a href=\"http:\/\/www.codinghorror.com\/blog\/archives\/001268.html\">twice<\/a>) , the danger is you might be copying off the paper of someone dumber than you<sup><a href=\"#foot2\">2<\/a><\/sup>. Because of this, I&#8217;d like to propose a <a href=\"http:\/\/microformats.org\/\">microformat<\/a> (assuming one doesn&#8217;t already exist, given I didn&#8217;t bother to check with Larry and Sergei) to indicate an author&#8217;s experience with a&nbsp;language.<\/p>\n<p><em>Immediate disclaimer<\/em>: I realize this is a programming solution to a human nature problem and those never work, but bear with me, because my hope isn&#8217;t to fix the problem, but to provide some metadata that will let machines do the work for us so we can stay lazy. Given that is in line with <a href=\"http:\/\/en.wikipedia.org\/wiki\/Newton%27s_first_law#Newton.27s_first_law\">Newton&#8217;s First Law<\/a>, this will obviously be a huge&nbsp;success.<\/p>\n<p>The format doesn&#8217;t need to be very complicated. In fact, I&#8217;d prefer if it just provided a few bits of raw data that could be remixed by search engines however they see best. The data provided would stay the same but the algorithms could be tweaked for better results (though that would require feedback), providing an incentive for search engines to consume the format. Make the data something rough, broad and quick to fill out, like years of experience with the language and a simple measure of number of lines written (e.g., none, 10, 100, 1,000, 10,000, a whole bunch). There are any <a href=\"http:\/\/en.wikipedia.org\/wiki\/Source_lines_of_code#Disadvantages\">number of issues<\/a> with using Lines of Code (LoC) as a metric (mainly that an idiot can say in 1,000 lines what a smarter person can say in 10), but if the ranges are broad enough, it should dampen the&nbsp;effect.<\/p>\n<p>Bolt this format onto syntax highlighting engines; this blog, for example, uses <a href=\"http:\/\/wordpress.org\/extend\/plugins\/wp-syntax\/\"><span class=\"caps\">WP<\/span>-Syntax<\/a> to format the few, poor code samples I provide&mdash; one more panel in the plugin admin that allowed me to store a hash of [language name, years, lines of code] would allow the plugin to provide that information in any page using the languages and output a visible box on the page so inexperienced users who come to the page and see my code could know it was terrible without <em>knowing<\/em> it was terrible. Add it into the syntax formatters for popular forum software (and allow users to specify their experience) and every code argument in a forum post becomes a little easier to&nbsp;follow.<\/p>\n<p>The format doesn&#8217;t tell you if a snippet is correct, it just gives you some background information (assuming the author is honest in their self-reporting). The danger would be users trusting a snippet blindly because the author has 10 (bad) years of experience (a sort of <a href=\"http:\/\/en.wikipedia.org\/wiki\/Argument_from_authority\">&#8220;Appeal to authority&#8221;<\/a>) while better code from &#8220;newer&#8221; users goes ignored. That&#8217;s a human nature problem and obviously you can&#8217;t solve those with programming (\/broad&nbsp;wink).<\/p>\n<p><small><span id=\"foot1\"><\/span>1. I&#8217;d rank these higher, especially official groups for languages and systems except for two&nbsp;reasons:<\/p>\n<ol type=\"a\">\n    <li>They tend to be so ill-formatted and the ability to follow threads varies wildly from site to&nbsp;site<\/li>\n    <li>The advice can be good but dated: it&#8217;s easy to find perfectly legitimate Python answers from 2000 or so. While the answer is fine, it&#8217;s possible there&#8217;s a newer idiom and in a language like Python, where there&#8217;s <a href=\"http:\/\/www.python.org\/dev\/peps\/pep-0020\/\">&#8220;one right way&#8221;<\/a>, the right way will be the way that the language has been optimized to&nbsp;work. <\/li>\n<\/ol>\n\n<p><span id=\"foot2\"><\/span>2. Basically unrelated story that I&#8217;ve crammed in because I always tell it because it cracks me up: in high school, we had to go to the local public high to take the SATs. The person sitting next to me scribbled furiously throughout the test and was always the first one finished (which frustrated me to no end). When we were walking out, he turned to us and said, &#8220;Dude, I just made pretty pictures with the bubbles.&#8221;\n<\/small><\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Cheating at The Beatles: Rock\u00a0Band","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/cheating-at-the-beatles-rock-band.html","rel":"alternate"}},"published":"2009-09-02T16:17:25-04:00","updated":"2009-09-02T16:17:25-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-09-02:\/cheating-at-the-beatles-rock-band.html","summary":"<h1>Cheating at The Beatles: Rock&nbsp;Band<\/h1>\n<p>My favorite thing about the game is the harmonizing and the way it increases the feeling that you&#8217;re really in a band, but if you&#8217;re all about the score (or bereft of friends), feel free to take advantage of these two pieces \u2026<\/p>","content":"<h1>Cheating at The Beatles: Rock&nbsp;Band<\/h1>\n<p>My favorite thing about the game is the harmonizing and the way it increases the feeling that you&#8217;re really in a band, but if you&#8217;re all about the score (or bereft of friends), feel free to take advantage of these two pieces of&nbsp;information:<\/p>\n<ol>\n    <li>The different singers do not have to sing different&nbsp;parts<\/li>\n    <li>The multiple scores are based solely on having multiple&nbsp;microphones<\/li>\n<\/ol>\n\n<p>In this case, 1 + 2 equals, &#8220;If you stick three microphones in front of your face and start wailing, you&#8217;ll be credited as three singers, including the double and triple bonuses&#8221;. Kids, you&#8217;re only cheating&nbsp;yourselves.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Django\/ Pinax: Problems With Login() in Unit\u00a0Tests","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/django-pinax-problems-with-login-in-unit-tests.html","rel":"alternate"}},"published":"2009-09-02T16:01:29-04:00","updated":"2009-09-02T16:01:29-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-09-02:\/django-pinax-problems-with-login-in-unit-tests.html","summary":"<h1>Django\/ Pinax: Problems With Login() in Unit&nbsp;Tests<\/h1>\n<p>This is the first in what promise to be a number of &#8220;Stupid Django Tricks&#8221; where the &#8220;stupid&#8221; is me and not Django. I was having a good deal of trouble creating unit tests for authenticated views (i.e., pages that require \u2026<\/p>","content":"<h1>Django\/ Pinax: Problems With Login() in Unit&nbsp;Tests<\/h1>\n<p>This is the first in what promise to be a number of &#8220;Stupid Django Tricks&#8221; where the &#8220;stupid&#8221; is me and not Django. I was having a good deal of trouble creating unit tests for authenticated views (i.e., pages that require a user to be logged in) for the <a href=\"http:\/\/pinaxproject.com\/\">Pinax<\/a> project I&#8217;ve been working on. I dug up two problems, one of which is on Pinax and one that&#8217;s entirely on&nbsp;me:<\/p>\n<ol>\n    <li>Pinax&#8217;s settings.py file does not provide a setting for <a href=\"http:\/\/docs.djangoproject.com\/en\/dev\/topics\/auth\/#authentication-backends\">AUTHENTICATION_BACKENDS<\/a>, so the test client&#8217;s login method doesn&#8217;t know how to log your user in. Specify &#8220;AUTHENTICATION_BACKENDS = (&#8216;django.contrib.auth.backends.ModelBackend&#8217;,)&#8221; in your settings file. Actually, I lied. That&#8217;s the default value for the setting; having gone back and re-run my tests without it specified, everything works, which means the only idiot here is the guy who&nbsp;&#8230;<\/li>\n    <li>Don&#8217;t create users by specifying the password directly in the declaration (e.g., user = User(username=&#8217;Dummy&#8217;, password=&#8217;goodluck&#8217;)). Use the set_password() User method to properly set the&nbsp;password.<\/li>\n<\/ol>\n\n<p>I&#8217;ve run into a fair number of issues working in Django where Google wasn&#8217;t helpful. I think 90% of those issues were because no one else was dumb enough to make such an obvious mistake. The other 10% were&nbsp;typos.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Monty Back, Rommel Still\u00a0Dead","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/monty-back-rommel-still-dead.html","rel":"alternate"}},"published":"2009-07-30T13:13:55-04:00","updated":"2009-07-30T13:13:55-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-07-30:\/monty-back-rommel-still-dead.html","summary":"<h1>Monty Back, Rommel Still&nbsp;Dead<\/h1>\n<p>Bob Montgomery is doing the color for today&#8217;s Red Sox game and I can&#8217;t figure out how to feel about it. Monty and the late Ned Martin were the voice of the Red Sox (on <span class=\"caps\">WSBK<\/span> <span class=\"caps\">TV38<\/span>) when I was growing up and \u2026<\/p>","content":"<h1>Monty Back, Rommel Still&nbsp;Dead<\/h1>\n<p>Bob Montgomery is doing the color for today&#8217;s Red Sox game and I can&#8217;t figure out how to feel about it. Monty and the late Ned Martin were the voice of the Red Sox (on <span class=\"caps\">WSBK<\/span> <span class=\"caps\">TV38<\/span>) when I was growing up and it&#8217;s strangely transporting to hear him again. He&#8217;s done some Pawsox games, but it&#8217;s hearing him back, like <a href=\"http:\/\/www.imdb.com\/title\/tt0097815\/\">Jake Taylor<\/a> (a fellow catcher) getting one last chance with the parent club. And it&#8217;s like he&#8217;s never left: same dulcet tones, knows the team, not a sign of age (unless you get a look at the tombstone of a gut he&#8217;s developed in&nbsp;retirement).<\/p>\n<p>It wasn&#8217;t until about year 3 of the Don Orsillo Experience that I realized I&#8217;d seriously undervalued Sean McDonough. Orsillo is fine, but he&#8217;s a generic Connecticut School of Broadcasting voice. Close your eyes and he could be talking about the Kansas City Royals. Sean McDonough&#8217;s only sin for me (beyond the too-goofy adulation of Remy) was not being Ned Martin. Hearing Monty makes me feel like I&#8217;m ten, I&#8217;ve got a whole summer in front of me and there&#8217;s nothing to worry about for the foreseeable future*. And that shit will get you&nbsp;killed.<\/p>\n<ul>\n<li><small><em>Of course, there were no World Series wins back then either<\/em><\/small><\/li>\n<\/ul>","category":{"@attributes":{"term":"Posts"}}},{"title":"Quincy Pond Printworks: Quincy Pond\u00a0Printworks","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/quincy-pond-printworks","rel":"alternate"}},"published":"2009-07-15T00:00:00-04:00","updated":"2009-07-15T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-07-15:\/quincy-pond-printworks","summary":"<h1>Quincy Pond Printworks: Quincy Pond&nbsp;Printworks<\/h1>\n<h2>2009-07-15<\/h2>\n<p><em>Helped Lightfin integrate a new site design with a Miva shopping&nbsp;cart.<\/em><\/p>\n<p>Quincy Pond Printworks came to Lightfin and I with two requirements: a beautiful-looking new site and a shopping cart. Lightfin took care of the first with their usual aplomb. There were \u2026<\/p>","content":"<h1>Quincy Pond Printworks: Quincy Pond&nbsp;Printworks<\/h1>\n<h2>2009-07-15<\/h2>\n<p><em>Helped Lightfin integrate a new site design with a Miva shopping&nbsp;cart.<\/em><\/p>\n<p>Quincy Pond Printworks came to Lightfin and I with two requirements: a beautiful-looking new site and a shopping cart. Lightfin took care of the first with their usual aplomb. There were only a few shopping carts we could pick from that worked with the client&#8217;s bank, so we settled on <a href=\"http:\/\/www.mivamerchant.com\/\">Miva<\/a> and a web host that supported it. Like a lot of closed-source but extensible products, information about Miva is jealously guarded by the people who make a living selling extensions and books about the product, so customizing the software to meet the client&#8217;s needs was a challenge. Where possible we bought inexpensive add-ons that gave us finer control over how products and navigation could be displayed. Where no add-on options existed, I dug in and learned how to make Miva Script do what was&nbsp;needed.<\/p>\n<p><img src=\"\/images\/portfolio\/croppercapture1.jpg\" alt=\"Store Landing Page Category landing page for a section of the store.\" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/croppercapture3.jpg\" alt=\"Product Detail \" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/croppercapture2.jpg\" alt=\"Homepage \" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"ecommerce"}},{"@attributes":{"term":"miva"}},{"@attributes":{"term":"shoppingcart"}}]},{"title":"Lockheed Martin: Lockheed Martin Healthplan\u00a0Website","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/lockheed-martin-healthplan-website","rel":"alternate"}},"published":"2009-06-19T00:00:00-04:00","updated":"2009-06-19T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-06-19:\/lockheed-martin-healthplan-website","summary":"<h1>Lockheed Martin: Lockheed Martin Healthplan&nbsp;Website<\/h1>\n<h2>2009-06-19<\/h2>\n<p><em>A site for Aetna health plan customers at Lockheed&nbsp;Martin<\/em><\/p>\n<p>My first Django project and first work with <a href=\"http:\/\/projectevolution.com\/\">Project Evolution<\/a> was a site for Aetna health plan. The bulk of the site is driven by a Django-powered content management system with the rest \u2026<\/p>","content":"<h1>Lockheed Martin: Lockheed Martin Healthplan&nbsp;Website<\/h1>\n<h2>2009-06-19<\/h2>\n<p><em>A site for Aetna health plan customers at Lockheed&nbsp;Martin<\/em><\/p>\n<p>My first Django project and first work with <a href=\"http:\/\/projectevolution.com\/\">Project Evolution<\/a> was a site for Aetna health plan. The bulk of the site is driven by a Django-powered content management system with the rest of the content from a series of applications.&nbsp;thumb:1<\/p>\n<p>The <a href=\"http:\/\/www.lmhwplan.com\/faqs\"><span class=\"caps\">FAQ<\/span><\/a> section does double-duty as a set of frequently asked questions and a message board for users to ask questions of site administrators. Questions are answered in the Django administrator panel which forwards the response to the user by email. If the question is general enough, the administrator can promote the question and answer into the <span class=\"caps\">FAQ<\/span>&nbsp;list.<\/p>\n<p>The glossary application generates a standard <a href=\"http:\/\/www.lmhwplan.com\/glossary\/A\">Glossary of Terms page<\/a>, but building the application was anything but standard.&nbsp;thumb:2&nbsp;The first time I built a glossary tool, it was in <span class=\"caps\">ASP<\/span> and Access, probably around 2002. Just to generate the list of letters at the top of the page required creating an array and typing every letter of the alphabet (the smarter me, a couple of years later, learned to write them out as a string and then split it into letters, but it&#8217;s still typing and there weren&#8217;t keen list sites all over the Internet where you could cut and paste from). So you&#8217;ll have to imagine how pleased I was to be working in Python, where I could just loop over <a href=\"http:\/\/docs.python.org\/library\/string.html\">string.uppercase<\/a> (or .lowercase if you prefer). The bit of the glossary I&#8217;m most proud of is harder to find: I built a template tag that looks through any piece of content, finds phrases and words that exist in the glossary and marks them up so users can find out what a term means without leaving the page (you can see an example by hover over &#8220;HealthPlan&#8221; in the fourth bullet point <a href=\"http:\/\/www.lmhwplan.com\/page\/basics-of-the-plan\/fast-facts-about-the-plan\">here<\/a>). The tag is smart enough that it only marks a word once, doesn&#8217;t mark up a word inside certain <span class=\"caps\">HTML<\/span> tags (so it doesn&#8217;t pop up and prevent you from clicking on a link) and looks for the longest matching phrase in each case (so phrases that contain other glossary terms get properly&nbsp;marked).<\/p>\n<p>Aetna provides Lockheed Martin employees with an <a href=\"http:\/\/www.lmhwplan.com\/page\/your-action-plan\">Action Plan<\/a> to help them improve their health.&nbsp;&nbsp;thumb:3&nbsp;The application allows administrators to provide a plan, tips and hints for every month. It&#8217;s available as a series of <span class=\"caps\">HTML<\/span> pages, print-friendly pages or as a <span class=\"caps\">PDF<\/span> for downloading. To make the <span class=\"caps\">PDF<\/span> version easy to maintain and update, it&#8217;s generated as a standard Django view with an <span class=\"caps\">HTML<\/span> template that is turned into a <span class=\"caps\">PDF<\/span> using <a href=\"http:\/\/www.xhtml2pdf.com\/\">Pisa<\/a>.<\/p>\n<p><img src=\"\/images\/portfolio\/Rendered_glossary.png\" alt=\"Glossary The full glossary that powers the content page tooltips\" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/LM_Action_Plan.png\" alt=\"Action Plan One month of the action plan in the HTML version\" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/LM_Home.png\" alt=\"Home Page \" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"django"}},{"@attributes":{"term":"pdf"}},{"@attributes":{"term":"pisa"}},{"@attributes":{"term":"jquery"}}]},{"title":"Free to a Harmonix Home, Rock Band\u00a0Idea","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/free-to-a-harmonix-home-rock-band-idea.html","rel":"alternate"}},"published":"2009-06-02T16:38:03-04:00","updated":"2009-06-02T16:38:03-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-06-02:\/free-to-a-harmonix-home-rock-band-idea.html","summary":"<h1>Free to a Harmonix Home, Rock Band&nbsp;Idea<\/h1>\n<p>Why doesn&#8217;t Rock Band allow you to create additional cities and venues? Nothing fancy, just the ability to set a city name and country, then create some venues. Venues would just let you select from the existing arenas and clubs<sup>1 \u2026<\/sup><\/p>","content":"<h1>Free to a Harmonix Home, Rock Band&nbsp;Idea<\/h1>\n<p>Why doesn&#8217;t Rock Band allow you to create additional cities and venues? Nothing fancy, just the ability to set a city name and country, then create some venues. Venues would just let you select from the existing arenas and clubs<sup>1<\/sup> (the 3D animation tool for user-created venues feels like more of an <span class=\"caps\">RB3<\/span> thing). It seems like an obvious idea for selling more content: allow for users to download cities from other users or Harmonix, but require them to have x downloaded songs to be able to use the city. Maybe the venue creation could have a recommended genre for what types of songs to choose from a user&#8217;s collection, but not require specific&nbsp;songs.<\/p>\n<p>Except in one case: if a label wanted to set up a &#8220;city&#8221; that contained historic venues a group played at on their rise to stardom and require you to buy various tracks to use them, that seems like a really cool way for labels to increase artists&#8217; sales in Rock Band (or Guitar Hero). It&#8217;d be like a low-cost version of Rock Band: Beatles for any group that cared to take the time\/ money to get the venues&nbsp;created.<\/p>\n<p><small>1. I am, of course, ignoring the legal issues that could arise from letting people create venues with names like &#8220;This place in my hometown sucks b@!!s&#8221;, but it&#8217;s my post and I&#8217;ll do so if I want to.<\/small><\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"New Age Software Services: Website and Bullhorn API\u00a0Integration","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/website-and-bullhorn-api-integration","rel":"alternate"}},"published":"2009-06-01T00:00:00-04:00","updated":"2009-06-01T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-06-01:\/website-and-bullhorn-api-integration","summary":"<h1>New Age Software Services: Website and Bullhorn <span class=\"caps\">API<\/span>&nbsp;Integration<\/h1>\n<h2>2009-06-01<\/h2>\n<p><em>A new website including integration with Bullhorn, a job search&nbsp;database.<\/em><\/p>\n<p><strong>Please note: I am not currently working on Bullhorn projects. Their <span class=\"caps\">API<\/span> has changed since this project was completed in&nbsp;2009.<\/strong><\/p>\n<p>thumb:1 New Age Software Services had a \u2026<\/p>","content":"<h1>New Age Software Services: Website and Bullhorn <span class=\"caps\">API<\/span>&nbsp;Integration<\/h1>\n<h2>2009-06-01<\/h2>\n<p><em>A new website including integration with Bullhorn, a job search&nbsp;database.<\/em><\/p>\n<p><strong>Please note: I am not currently working on Bullhorn projects. Their <span class=\"caps\">API<\/span> has changed since this project was completed in&nbsp;2009.<\/strong><\/p>\n<p>thumb:1 New Age Software Services had a content author, web host and a site design, but needed someone to build the new site. The design they had purchased came in two versions, an animated Flash design and a static set of Photoshop files matching the Flash interface. The client wanted the interactivity of the Flash interface but was concerned about the search engine-friendliness of a site in Flash and whether the Flash interface would support future extensions to the site. To provide the best of both options, I built the interface in <span class=\"caps\">HTML<\/span>\/ <span class=\"caps\">CSS<\/span> and added animation effects in jQuery to match the Flash interface. The site is built in C# with a single Master Page that controls the look and feel of all pages in the site and the navigation comes from an <span class=\"caps\">XML<\/span> document that describes the hierarchy of the site. Between the two, this makes it very easy to add\/ remove\/ move pages in the site without having to edit all pages. There are also a number of forms built in C# that use a <span class=\"caps\">MVC<\/span>-type library I wrote for building C# applications back in 2007 (i.e., before Microsoft created a nice new <span class=\"caps\">MVC<\/span> framework for .<span class=\"caps\">NET<\/span> that made it&nbsp;redundant).<\/p>\n<p>thumb:2 This was a two-phase project. Phase One was creating a real web presence. The <a href=\"http:\/\/web.archive.org\/web\/20070128053558\/http:\/\/www.newagesoft.com\/\">previous site<\/a> was created 10 years prior to generate phone calls. I worked directly with New Age Software&#8217;s <span class=\"caps\">CEO<\/span> and their content writer to integrate the new copy and branding with a web site template that had been purchased, all in anticipation of a relaunch four weeks later. In addition to creating the site&#8217;s shell, New Age wanted the site to have a sense of motion. The Flash movie included in the template was both distracting and limiting: it meant content on the page could never grow taller than the movie and the movie itself was a loop of falling puzzle pieces that made the content hard to read. Rather than sacrificing content flexibility or search engine optimization (by replacing the navigation with a movie), I created animated navigation and a scrolling news ticker in JavaScript with jQuery. The news ticker was especially dear to me: it consists of nice, clean <span class=\"caps\">HTML<\/span> and a sprinkling of jQuery, but when I started as a full-time web developer in 2000, one of our most popular offerings was a Java applet-based news ticker that was neither as attractive nor as customizable. To help customers get the information they need, I build a number of forms in C# that allow for the submission of resumes, simple contact emails and subscriptions to a Constant Contact-powered&nbsp;newsletter.<\/p>\n<p>thumb:3  The second phase was the trickier bit, expanding from a single resume submission form to full integration with the <a href=\"http:\/\/www.bullhorn.com\/\">Bullhorn Software<\/a> tools that power New Age&#8217;s business. <a href=\"https:\/\/www.bullhornstaffing.com\/BullhornStaffing\/API\/default.cfm\">Bullhorn&#8217;s <span class=\"caps\">API<\/span><\/a>, at least as of this writing, is a series of ColdFusion forms rather than a web service\/ RESTful approach. While .<span class=\"caps\">NET<\/span>\/ VisualStudio do a great job of providing a foundation for web service integration projects, much of that foundation is lost if you&#8217;re not talking to web services. I encountered some complications in accepting a file upload, validating the file and passing it on to the 3rd party form in C#. The client&#8217;s web host takes a serious approach to security. In Phase One, the web server (the <span class=\"caps\">IIS<\/span> worker process) did not have access to write to the drive. Always preferring to be keep fighting with other parties to a minimum, I circumvented this restriction by streaming the file for the simple resume upload. To avoid this issue in Phase Two, I finally submitted the form directly to Bullhorn and intercepted the&nbsp;response.<\/p>\n<p>The <a href=\"http:\/\/supportforums.bullhorn.com\/viewforum.php?f=1&amp;sid=9fb56794a89c3f68862825d566567a7b\">Bullhorn <span class=\"caps\">API<\/span> forum<\/a> was a big help, especially the <a href=\"http:\/\/supportforums.bullhorn.com\/viewtopic.php?t=488\">sample C# code<\/a>. Because that was such a help, I am providing my <a href=\"http:\/\/snipplr.com\/view\/9900\/c-integration-module-for-bullhorn-staffing-api\/\">modified version of that code.<\/a> A few notes on my&nbsp;changes:<\/p>\n<ul>\n<li>Giving in to my anal-retentive coding nature, I renamed the class to BullhornWorker to make things&nbsp;obvious<\/li>\n<li>The code was provided as a class, but it&#8217;s not an object, it&#8217;s a set of related&nbsp;utilities<\/li>\n<li>As such, any method I actually used has been marked as static because there are no common values to be&nbsp;initialized<\/li>\n<li>I moved the Bullhorn private label id and <span class=\"caps\">API<\/span> key out to Web.config variables to make the code easier to&nbsp;maintain<\/li>\n<li>Added caching for the query that lists all jobs in the system and any filtered job queries: because this is easily the most often call and given the job list does not update more than daily, there&#8217;s no danger to caching the list and a big performance&nbsp;boost<\/li>\n<li>Added a couple of helper methods to reduce&nbsp;redundancy<\/li>\n<li>The Web.config key DEVELOPMENT_DEBUGGING expects a boolean; if set to &#8220;true&#8221;, the code will return any <span class=\"caps\">XML<\/span> exception&nbsp;information<\/li>\n<li>Web.config keys required: BULLHORN_PRIVATE_LABEL_ID, BULLHORN_API_KEY, CACHE_ON,&nbsp;DEVELOPMENT_DEBUGGING<\/li>\n<\/ul>\n<p><img src=\"\/images\/portfolio\/new-age-job-search.jpg\" alt=\"Job Search Users no longer have to leave the New Age site to get search results from Bullhorn\" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/new-age-contact.jpg\" alt=\"Contact \" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/new-age-home.jpg\" alt=\"Home \" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"csharp"}},{"@attributes":{"term":".net"}},{"@attributes":{"term":"api"}},{"@attributes":{"term":"integration"}},{"@attributes":{"term":"jquery"}}]},{"title":"YUI Rich Text Editor in Django\u00a0Admin","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/yui-rich-text-editor-in-django-admin.html","rel":"alternate"}},"published":"2009-04-30T16:49:23-04:00","updated":"2009-04-30T16:49:23-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-04-30:\/yui-rich-text-editor-in-django-admin.html","summary":"<h1><span class=\"caps\">YUI<\/span> Rich Text Editor in Django&nbsp;Admin<\/h1>\n<p>This ain&#8217;t exactly rocket science, but it took me an embarrassing amount of time to get there, so I&#8217;m posting the code for next time. This will turn a given textarea in your admin area into a <span class=\"caps\">WYSIWYG<\/span>. It&#8217;s got \u2026<\/p>","content":"<h1><span class=\"caps\">YUI<\/span> Rich Text Editor in Django&nbsp;Admin<\/h1>\n<p>This ain&#8217;t exactly rocket science, but it took me an embarrassing amount of time to get there, so I&#8217;m posting the code for next time. This will turn a given textarea in your admin area into a <span class=\"caps\">WYSIWYG<\/span>. It&#8217;s got a fairly small feature set, but that&#8217;s only because I&#8217;ve stripped most of them out. You can add them back in by <a href=\"http:\/\/developer.yahoo.com\/yui\/editor\/\">taking a look at the documentation<\/a>. Per the <a href=\"http:\/\/docs.djangoproject.com\/en\/dev\/ref\/contrib\/admin\/#overriding-admin-templates\">Django docs<\/a>, create an admin folder under one of your templates directories, then add subfolders for the app and model (though you can do just one if you want it to apply to all forms in the app or do neither to apply to all apps and models in your site) and add this as &#8220;change_form.html&#8221; (it took me an extra 10 minutes to get this done because I was sure it should be named &#8220;change_form.py&#8221; in spite of copious amounts of documentation that said&nbsp;otherwise):<\/p>\n<div class=\"highlight\"><pre><span><\/span><code><span class=\"cp\">{%<\/span> <span class=\"k\">extends<\/span> <span class=\"s2\">&quot;admin\/change_form.html&quot;<\/span> <span class=\"cp\">%}<\/span>\n\n<span class=\"cp\">{%<\/span> <span class=\"k\">block<\/span> <span class=\"nv\">extrahead<\/span> <span class=\"cp\">%}{{<\/span> <span class=\"nb\">block<\/span><span class=\"nv\">.super<\/span> <span class=\"cp\">}}<\/span>\n<span class=\"cm\">&lt;!-- Skin CSS file --&gt;<\/span>\n<span class=\"nt\">&lt;link<\/span><span class=\"w\"> <\/span><span class=\"na\">rel=<\/span><span class=\"s\">&quot;stylesheet&quot;<\/span><span class=\"w\"> <\/span><span class=\"na\">type=<\/span><span class=\"s\">&quot;text\/css&quot;<\/span><span class=\"w\"> <\/span><span class=\"na\">href=<\/span><span class=\"s\">&quot;http:\/\/yui.yahooapis.com\/2.5.1\/build\/assets\/skins\/sam\/skin.css&quot;<\/span><span class=\"nt\">&gt;<\/span>\n<span class=\"cm\">&lt;!-- Utility Dependencies --&gt;<\/span>\n<span class=\"nt\">&lt;script<\/span><span class=\"w\"> <\/span><span class=\"na\">type=<\/span><span class=\"s\">&quot;text\/javascript&quot;<\/span><span class=\"w\"> <\/span><span class=\"na\">src=<\/span><span class=\"s\">&quot;http:\/\/yui.yahooapis.com\/2.5.1\/build\/yahoo-dom-event\/yahoo-dom-event.js&quot;<\/span><span class=\"nt\">&gt;&lt;\/script&gt;<\/span>\n<span class=\"nt\">&lt;script<\/span><span class=\"w\"> <\/span><span class=\"na\">type=<\/span><span class=\"s\">&quot;text\/javascript&quot;<\/span><span class=\"w\"> <\/span><span class=\"na\">src=<\/span><span class=\"s\">&quot;http:\/\/yui.yahooapis.com\/2.5.1\/build\/element\/element-beta-min.js&quot;<\/span><span class=\"nt\">&gt;&lt;\/script&gt;<\/span>\n<span class=\"cm\">&lt;!-- Needed for Menus, Buttons and Overlays used in the Toolbar --&gt;<\/span>\n<span class=\"nt\">&lt;script<\/span><span class=\"w\"> <\/span><span class=\"na\">src=<\/span><span class=\"s\">&quot;http:\/\/yui.yahooapis.com\/2.5.1\/build\/container\/container_core-min.js&quot;<\/span><span class=\"nt\">&gt;&lt;\/script&gt;<\/span>\n<span class=\"nt\">&lt;script<\/span><span class=\"w\"> <\/span><span class=\"na\">type=<\/span><span class=\"s\">&quot;text\/javascript&quot;<\/span><span class=\"w\"> <\/span><span class=\"na\">src=<\/span><span class=\"s\">&quot;http:\/\/yui.yahooapis.com\/2.5.1\/build\/menu\/menu-min.js&quot;<\/span><span class=\"nt\">&gt;&lt;\/script&gt;<\/span>\n<span class=\"nt\">&lt;script<\/span><span class=\"w\"> <\/span><span class=\"na\">type=<\/span><span class=\"s\">&quot;text\/javascript&quot;<\/span><span class=\"w\"> <\/span><span class=\"na\">src=<\/span><span class=\"s\">&quot;http:\/\/yui.yahooapis.com\/2.5.1\/build\/button\/button-min.js&quot;<\/span><span class=\"nt\">&gt;&lt;\/script&gt;<\/span>\n<span class=\"cm\">&lt;!-- Source file for Rich Text Editor--&gt;<\/span>\n<span class=\"nt\">&lt;script<\/span><span class=\"w\"> <\/span><span class=\"na\">src=<\/span><span class=\"s\">&quot;http:\/\/yui.yahooapis.com\/2.5.1\/build\/editor\/editor-beta-min.js&quot;<\/span><span class=\"nt\">&gt;&lt;\/script&gt;<\/span>\n<span class=\"nt\">&lt;script<\/span><span class=\"w\"> <\/span><span class=\"na\">type=<\/span><span class=\"s\">&quot;text\/javascript&quot;<\/span><span class=\"nt\">&gt;<\/span>\n<span class=\"w\">        <\/span>\/\/<span class=\"w\"> <\/span>YUI<span class=\"w\"> <\/span>editor\n<span class=\"w\">        <\/span>var<span class=\"w\"> <\/span>editor<span class=\"w\"> <\/span>=<span class=\"w\"> <\/span>new<span class=\"w\"> <\/span>YAHOO.widget.Editor(&quot;id_content&quot;,<span class=\"w\"> <\/span>{\n<span class=\"w\">            <\/span>handleSubmit:<span class=\"w\"> <\/span>true,\n<span class=\"w\">            <\/span>toolbar:<span class=\"w\"> <\/span>{\n<span class=\"w\">        <\/span>buttonType:<span class=\"w\"> <\/span>&#39;advanced&#39;,\n<span class=\"w\">        <\/span>buttons:<span class=\"w\"> <\/span>[\n<span class=\"w\">            <\/span>{<span class=\"w\"> <\/span>group:<span class=\"w\"> <\/span>&#39;fontstyle&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;Font&#39;,\n<span class=\"w\">                <\/span>buttons:<span class=\"w\"> <\/span>[\n<span class=\"w\">                    <\/span>{<span class=\"w\"> <\/span>type:<span class=\"w\"> <\/span>&#39;select&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;Arial&#39;,<span class=\"w\"> <\/span>value:<span class=\"w\"> <\/span>&#39;fontname&#39;,\ndisabled:<span class=\"w\"> <\/span>true,\n<span class=\"w\">                        <\/span>menu:<span class=\"w\"> <\/span>[\n<span class=\"w\">                            <\/span>{<span class=\"w\"> <\/span>text:<span class=\"w\"> <\/span>&#39;Arial&#39;,<span class=\"w\"> <\/span>checked:<span class=\"w\"> <\/span>true<span class=\"w\"> <\/span>},\n<span class=\"w\">                            <\/span>{<span class=\"w\"> <\/span>text:<span class=\"w\"> <\/span>&#39;Verdana&#39;<span class=\"w\"> <\/span>}\n<span class=\"w\">                        <\/span>]\n<span class=\"w\">                    <\/span>},\n<span class=\"w\">                    <\/span>{<span class=\"w\"> <\/span>type:<span class=\"w\"> <\/span>&#39;spin&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;10&#39;,<span class=\"w\"> <\/span>value:<span class=\"w\"> <\/span>&#39;fontsize&#39;,<span class=\"w\"> <\/span>range:<span class=\"w\"> <\/span>[\n10,<span class=\"w\"> <\/span>16<span class=\"w\"> <\/span>],<span class=\"w\"> <\/span>disabled:<span class=\"w\"> <\/span>true<span class=\"w\"> <\/span>},\n<span class=\"w\">                    <\/span>{<span class=\"w\"> <\/span>type:<span class=\"w\"> <\/span>&#39;color&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;Font<span class=\"w\"> <\/span>Color&#39;,<span class=\"w\"> <\/span>value:<span class=\"w\"> <\/span>&#39;forecolor&#39;,<span class=\"w\"> <\/span>disabled:<span class=\"w\"> <\/span>true<span class=\"w\"> <\/span>}\n<span class=\"w\">                <\/span>]\n<span class=\"w\">            <\/span>},\n<span class=\"w\">            <\/span>{<span class=\"w\"> <\/span>type:<span class=\"w\"> <\/span>&#39;separator&#39;<span class=\"w\"> <\/span>},\n<span class=\"w\">            <\/span>{<span class=\"w\"> <\/span>group:<span class=\"w\"> <\/span>&#39;textstyle&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;Font<span class=\"w\"> <\/span>Style&#39;,\n<span class=\"w\">                <\/span>buttons:<span class=\"w\"> <\/span>[\n<span class=\"w\">                    <\/span>{<span class=\"w\"> <\/span>type:<span class=\"w\"> <\/span>&#39;push&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;Bold<span class=\"w\"> <\/span>CTRL<span class=\"w\"> <\/span>+<span class=\"w\"> <\/span>SHIFT<span class=\"w\"> <\/span>+<span class=\"w\"> <\/span>B&#39;,<span class=\"w\"> <\/span>value:<span class=\"w\"> <\/span>&#39;bold&#39;<span class=\"w\"> <\/span>},\n<span class=\"w\">                    <\/span>{<span class=\"w\"> <\/span>type:<span class=\"w\"> <\/span>&#39;push&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;Italic<span class=\"w\"> <\/span>CTRL<span class=\"w\"> <\/span>+<span class=\"w\"> <\/span>SHIFT<span class=\"w\"> <\/span>+<span class=\"w\"> <\/span>I&#39;,<span class=\"w\"> <\/span>value:<span class=\"w\"> <\/span>&#39;italic&#39;<span class=\"w\"> <\/span>},\n<span class=\"w\">                    <\/span>{<span class=\"w\"> <\/span>type:<span class=\"w\"> <\/span>&#39;push&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;Underline<span class=\"w\"> <\/span>CTRL<span class=\"w\"> <\/span>+<span class=\"w\"> <\/span>SHIFT<span class=\"w\"> <\/span>+<span class=\"w\"> <\/span>U&#39;,<span class=\"w\"> <\/span>value:<span class=\"w\"> <\/span>&#39;underline&#39;<span class=\"w\"> <\/span>}\n<span class=\"w\">                <\/span>]\n<span class=\"w\">            <\/span>},\n<span class=\"w\">            <\/span>{<span class=\"w\"> <\/span>type:<span class=\"w\"> <\/span>&#39;separator&#39;<span class=\"w\"> <\/span>},\n<span class=\"w\">            <\/span>{<span class=\"w\"> <\/span>group:<span class=\"w\"> <\/span>&#39;indentlist&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;Indenting<span class=\"w\"> <\/span>and<span class=\"w\"> <\/span>Lists&#39;,\n<span class=\"w\">                <\/span>buttons:<span class=\"w\"> <\/span>[\n<span class=\"w\">                    <\/span>{<span class=\"w\"> <\/span>type:<span class=\"w\"> <\/span>&#39;push&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;Indent&#39;,<span class=\"w\"> <\/span>value:<span class=\"w\"> <\/span>&#39;indent&#39;,\ndisabled:<span class=\"w\"> <\/span>true<span class=\"w\"> <\/span>},\n<span class=\"w\">                    <\/span>{<span class=\"w\"> <\/span>type:<span class=\"w\"> <\/span>&#39;push&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;Outdent&#39;,<span class=\"w\"> <\/span>value:<span class=\"w\"> <\/span>&#39;outdent&#39;,\ndisabled:<span class=\"w\"> <\/span>true<span class=\"w\"> <\/span>},\n<span class=\"w\">                    <\/span>{<span class=\"w\"> <\/span>type:<span class=\"w\"> <\/span>&#39;push&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;Create<span class=\"w\"> <\/span>a<span class=\"w\"> <\/span>Bulleted<span class=\"w\"> <\/span>List&#39;,<span class=\"w\"> <\/span>value:\n&#39;insertunorderedlist&#39;<span class=\"w\"> <\/span>},\n<span class=\"w\">                    <\/span>{<span class=\"w\"> <\/span>type:<span class=\"w\"> <\/span>&#39;push&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;Create<span class=\"w\"> <\/span>a<span class=\"w\"> <\/span>Numbered<span class=\"w\"> <\/span>List&#39;,<span class=\"w\"> <\/span>value:\n&#39;insertorderedlist&#39;<span class=\"w\"> <\/span>}\n<span class=\"w\">                <\/span>]\n<span class=\"w\">            <\/span>},\n<span class=\"w\">            <\/span>{<span class=\"w\"> <\/span>type:<span class=\"w\"> <\/span>&#39;separator&#39;<span class=\"w\"> <\/span>},\n<span class=\"w\">            <\/span>{<span class=\"w\"> <\/span>group:<span class=\"w\"> <\/span>&#39;insertitem&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;Link&#39;,\n<span class=\"w\">                <\/span>buttons:<span class=\"w\"> <\/span>[\n<span class=\"w\">                    <\/span>{<span class=\"w\"> <\/span>type:<span class=\"w\"> <\/span>&#39;push&#39;,<span class=\"w\"> <\/span>label:<span class=\"w\"> <\/span>&#39;HTML<span class=\"w\"> <\/span>Link<span class=\"w\"> <\/span>CTRL<span class=\"w\"> <\/span>+<span class=\"w\"> <\/span>SHIFT<span class=\"w\"> <\/span>+<span class=\"w\"> <\/span>L&#39;,\nvalue:<span class=\"w\"> <\/span>&#39;createlink&#39;,<span class=\"w\"> <\/span>disabled:<span class=\"w\"> <\/span>true<span class=\"w\"> <\/span>}\n<span class=\"w\">                <\/span>]\n<span class=\"w\">            <\/span>}\n<span class=\"w\">        <\/span>]\n}\n<span class=\"w\">            <\/span>}\n<span class=\"w\">            <\/span>);\n<span class=\"w\">        <\/span>editor._defaultToolbar.buttonType<span class=\"w\"> <\/span>=<span class=\"w\"> <\/span>&#39;advanced&#39;;\n<span class=\"w\">        <\/span>editor.render();\n<span class=\"nt\">&lt;\/script&gt;<\/span>\nendblock\n\n<span class=\"cp\">{%<\/span> <span class=\"k\">block<\/span> <span class=\"nv\">bodyclass<\/span> <span class=\"cp\">%}{{<\/span> <span class=\"nb\">block<\/span><span class=\"nv\">.super<\/span> <span class=\"cp\">}}<\/span><span class=\"w\"> <\/span>yui-skin-samendblock\n<\/code><\/pre><\/div>\n\n<p>Like I said, not rocket science. It adds some <span class=\"caps\">CSS<\/span> <span class=\"amp\">&amp;<\/span> JavaScript includes (which are remotely-hosted, so you don&#8217;t even have to worry about media roots or how it works locally vs. live) and then a bit to add a class to the body tag for the <span class=\"caps\">YUI<\/span>&nbsp;skin.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"MarketConnector: Marketconnector Business\u00a0Community","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/marketconnector-business-community","rel":"alternate"}},"published":"2009-04-27T00:00:00-04:00","updated":"2009-04-27T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-04-27:\/marketconnector-business-community","summary":"<h1>MarketConnector: Marketconnector Business&nbsp;Community<\/h1>\n<h2>2009-04-27<\/h2>\n<p><em>Social network for New England businesses built in <span class=\"caps\">PHP<\/span> on Social&nbsp;Engine.<\/em><\/p>\n<p>It pains me enough, at almost 35, to see athletes my age retiring. So it was a shock to the system to have a client more than a decade my junior. <a href=\"http:\/\/www.seacoastonline.com\/articles\/20100419-BIZ-1010789\">Ben Collins \u2026<\/a><\/p>","content":"<h1>MarketConnector: Marketconnector Business&nbsp;Community<\/h1>\n<h2>2009-04-27<\/h2>\n<p><em>Social network for New England businesses built in <span class=\"caps\">PHP<\/span> on Social&nbsp;Engine.<\/em><\/p>\n<p>It pains me enough, at almost 35, to see athletes my age retiring. So it was a shock to the system to have a client more than a decade my junior. <a href=\"http:\/\/www.seacoastonline.com\/articles\/20100419-BIZ-1010789\">Ben Collins<\/a> is a business student at <span class=\"caps\">UNH<\/span> studying to be an entrepreneur; this site is his head-start on the competition. Ben already had a business plan, a site design he created and a solid set of technology requirements. I worked with Ben to flesh out the requirements of the four sections he wanted and how to integrate them into the software package he&#8217;d chosen, <a href=\"http:\/\/www.socialengine.net\/\">Social&nbsp;Engine.<\/a><\/p>\n<p>The site allows users to find jobs, post jobs, buy and sell items and get quotes for works from businesses in their local area. Set up as a social network, users can find trusted resources by getting recommendations in any of these categories from people they&nbsp;know.<\/p>\n<p><img src=\"\/images\/portfolio\/MK_Profiles.png\" alt=\"Member List \" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/MK_Job_Listing.png\" alt=\"Job Listings Live job posting from a member\" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/MK_Homepage.png\" alt=\"Homepage \" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"php"}},{"@attributes":{"term":"socialnetwork"}},{"@attributes":{"term":"socialengine"}}]},{"title":"My Name is\u00a0Crew","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/my-name-is-crew.html","rel":"alternate"}},"published":"2009-04-04T08:34:30-04:00","updated":"2009-04-04T08:34:30-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-04-04:\/my-name-is-crew.html","summary":"<h1>My Name is&nbsp;Crew<\/h1>\n<p>I am posting this because I need to keep track of these things. Dreamt last night Michelle and I put on a community event centered around the retirement of some guy that had been a social worker all his life. After the dance crew came off \u2026<\/p>","content":"<h1>My Name is&nbsp;Crew<\/h1>\n<p>I am posting this because I need to keep track of these things. Dreamt last night Michelle and I put on a community event centered around the retirement of some guy that had been a social worker all his life. After the dance crew came off the stage, there was a PowerPoint presentation of his life that I put together (each slide featured an allegorical photo of a raven) and a country music song. All I remember&nbsp;is:<\/p>\n<p><em>My name is Crew<br \/>\nMy name is Crew<br \/>\nSaving kids is kinda what I do\n[a capella]Leading them away from a path of self-destruction&nbsp;&#8230;<\/em><\/p>\n\n<p>And so on. The ravens were a result of watching a David Attenborough documentary last night and Michelle points out &#8220;kinda what I do&#8221; is a phrase that Bill Burr repeated in the stand-up show we watched <a href=\"http:\/\/www.thosecleverkids.com\/blog\/2009\/01\/10\/anatomy-of-a-late-night\/\">again<\/a> last night. So that explains a bit of it, but I still don&#8217;t get where these dreams with original music come from. I must be choking off my creative brain during waking hours. Earlier this week I&#8217;d dreamt <a href=\"http:\/\/raygun-o-gram.blogspot.com\/\" onclick=\"window.open(this.href); return false;\">my friend<\/a> had walked into a convenience store and declaimed a filthy sonnet in perfect <span class=\"caps\">ABAB<\/span> rhyme scheme explaining why he needed to buy the <em>New York Times<\/em> Sunday Magazine and not the whole&nbsp;paper.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Salmon Falls Nursery: Salmon Falls Nursery\u00a0Portfolio","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/salmon-falls-nursery-portfolio","rel":"alternate"}},"published":"2009-04-02T00:00:00-04:00","updated":"2009-04-02T00:00:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-04-02:\/salmon-falls-nursery-portfolio","summary":"<h1>Salmon Falls Nursery: Salmon Falls Nursery&nbsp;Portfolio<\/h1>\n<h2>2009-04-02<\/h2>\n<p><em>Design portfolio for a New Hampshire landscape design&nbsp;company<\/em><\/p>\n<p>Working with a design company on a portfolio tool can be an intimidating process. I think Lightfin and I saw a design-savvy client as an opportunity to build something that stands out. After \u2026<\/p>","content":"<h1>Salmon Falls Nursery: Salmon Falls Nursery&nbsp;Portfolio<\/h1>\n<h2>2009-04-02<\/h2>\n<p><em>Design portfolio for a New Hampshire landscape design&nbsp;company<\/em><\/p>\n<p>Working with a design company on a portfolio tool can be an intimidating process. I think Lightfin and I saw a design-savvy client as an opportunity to build something that stands out. After blogs and to-do lists, portfolios must be the most-built web applications on the planet (you&#8217;re reading this inside one right now: how meta); if you&#8217;re going to ignore the over-abundance of off-the-shelf options out there, you&#8217;d better do something interesting (and&nbsp;good).<\/p>\n\n<p>Call me biased, but I think we succeeded. The elegant and easy-to-use interface complements the beautiful landscape designs contained inside. I also used this as an opportunity to update some of the tooling in my standard <span class=\"caps\">PHP<\/span> kit. Like anyone who&#8217;s worked in <span class=\"caps\">PHP<\/span> for more than a couple of years (I think I&#8217;m on year 9, for better or for worse), I&#8217;ve built up a framework to handle the plumbing of typical web\/ database applications. This project allowed me to add some Ajax controls to the standard Edit\/ Delete object workflows, resulting in (again, biased observer) a rare administrative interface that can stand with the front-end the user&nbsp;sees.<\/p>\n<p><img src=\"\/images\/portfolio\/sf-category.jpg\" alt=\"Category View Category overview\" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/sf-detail.jpg\" alt=\"Detail Project details and photographs\" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/sf-admin.jpg\" alt=\"Admin The custom administration tools are also integrated into the site\" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/sf-home.jpg\" alt=\"Home \" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"ajax"}},{"@attributes":{"term":"php"}}]},{"title":"Expression Engine if\u00a0Clauses","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/expression-engine-if-clauses.html","rel":"alternate"}},"published":"2009-03-16T08:24:00-04:00","updated":"2009-03-16T08:24:00-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-03-16:\/expression-engine-if-clauses.html","summary":"<h1>Expression Engine if&nbsp;Clauses<\/h1>\n<p>This is the kind of thing that&#8217;s not worth a blog post except some day it might save one person hours of frustration. Expression Engine apparently doesn&#8217;t like it when if statements either span multiple lines or when the trailing curly brace is pushed \u2026<\/p>","content":"<h1>Expression Engine if&nbsp;Clauses<\/h1>\n<p>This is the kind of thing that&#8217;s not worth a blog post except some day it might save one person hours of frustration. Expression Engine apparently doesn&#8217;t like it when if statements either span multiple lines or when the trailing curly brace is pushed to a new line. I can&#8217;t quite run down which it is, but it&#8217;s not all that important: if your if clause isn&#8217;t behaving as expected, make sure it&#8217;s all on one line without any extraneous&nbsp;whitespace.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Dreams They Complicate My\u00a0Life","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/dreams-they-complicate-my-life.html","rel":"alternate"}},"published":"2009-02-26T08:00:16-05:00","updated":"2009-02-26T08:00:16-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-02-26:\/dreams-they-complicate-my-life.html","summary":"<h1>Dreams They Complicate My&nbsp;Life<\/h1>\n<p>Had one of those constant dreams nights which I take as indicative of good sleep, though I was awoken by my iPod once. I&#8217;ve been listening to the over-my-head <a href=\"http:\/\/www.bbc.co.uk\/radio4\/history\/inourtime\/inourtime.shtml\">In Our Time<\/a> podcast because, whether it&#8217;s terribly interesting or terribly boring, it makes \u2026<\/p>","content":"<h1>Dreams They Complicate My&nbsp;Life<\/h1>\n<p>Had one of those constant dreams nights which I take as indicative of good sleep, though I was awoken by my iPod once. I&#8217;ve been listening to the over-my-head <a href=\"http:\/\/www.bbc.co.uk\/radio4\/history\/inourtime\/inourtime.shtml\">In Our Time<\/a> podcast because, whether it&#8217;s terribly interesting or terribly boring, it makes me terribly sleepy. It was off-putting to wake up hearing a stranger in a dark room speaking of the Fall of Carthage. The&nbsp;highlights:<\/p>\n<ol>\n    <li>Falls into what I would call the &#8220;Tetris Dream&#8221; category, when you&#8217;ve become a little <em>too<\/em> interested in something: had a dream where I was in a field hospital somewhere in the jungle watching a <span class=\"caps\">TV<\/span> report, hosted by <a href=\"http:\/\/twitter.com\/leolaporte\">@leolaporte<\/a> about Canadian Twitterers, whom he referred to as &#8220;C-itters&#8221;. I&#8217;d really hoped we were beyond that kind of prejudice in&nbsp;2009.<\/li>\n    <li>I was a amateur anti-mob sniper, recruited for the job by a rogue government agent who&#8217;s ex-girlfriend I was dating (she was also recruited for the cause; for the record, I&#8217;m pretty sure it was <a href=\"http:\/\/www.imdb.com\/name\/nm1330166\/\">this woman<\/a> from <em><a href=\"http:\/\/www.imdb.com\/title\/tt0433309\/fullcredits#cast\">Numb3rs<\/a><\/em>). I was up in our hotel room[1] with my assignment in my sights when I noticed the Mob&#8217;s snipers hanging out of the hotel window right next to me. Jumping back out of the window, I went to inventory the guns and ammunition I&#8217;d been left when the treachery became clear: the case had almost no bullets (but plenty <span class=\"caps\">AA<\/span> batteries, the guns being electric). To heighten the stress of the moment, the cleaning crew started coming around the&nbsp;halls.<\/li>\n    <li>To cap the evening, I got another go at my newest recurring dream. Since my Mom died, I&#8217;ve been having this strange cartographic dream where I try to map out the city of Newport[2] from a boat. It never works, the boat sinks and whatever I&#8217;m looking for goes unfound. I could probably save this dream-self a lot of time if he&#8217;d give me a whack at his&nbsp;map.<\/li>\n<\/ol>\n\n<p><small>[1] We&#8217;d gotten to the point in our relationship where we were not only comfortable sharing a hotel room, we could interrupt a vacation to gun down mobsters without any negative effect on our relationship\n[2] More accurately, the whole of <a href=\"http:\/\/en.wikipedia.org\/wiki\/Aquidneck_Island\">Aquidneck Island<\/a>, as I think last time I wound up in Portsmouth under the Mount Hope Bridge.<\/small><\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"PHP Excel\u00a0Exporter","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/php-excel-exporter.html","rel":"alternate"}},"published":"2009-02-23T21:06:54-05:00","updated":"2009-02-23T21:06:54-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-02-23:\/php-excel-exporter.html","summary":"<h1><span class=\"caps\">PHP<\/span> Excel&nbsp;Exporter<\/h1>\n<p>A few times a year a client needs to export something from a database table to Excel. There&#8217;s a simple hack to do it in most any language. There are actually a few, but having come up as a web developer, my preferred trick is to \u2026<\/p>","content":"<h1><span class=\"caps\">PHP<\/span> Excel&nbsp;Exporter<\/h1>\n<p>A few times a year a client needs to export something from a database table to Excel. There&#8217;s a simple hack to do it in most any language. There are actually a few, but having come up as a web developer, my preferred trick is to just build an <span class=\"caps\">HTML<\/span> table and serve it as Excel by setting the mime type header. Having done this dozens of times, I finally formalized this into a simple <span class=\"caps\">PHP<\/span> class tonight to save myself some time and figured I might as well share&nbsp;it.<\/p>\n<p>The bad news: because I am lazy, it relies on an old data connection class I wrote years ago when I was even less bright than I am now. The thing&#8217;s so ugly I posted it <a href=\"http:\/\/snipplr.com\/view\/12517\/php-mysql-data-connection-class\/\">somewhere else<\/a> because I am too ashamed to host it here. You can rip that out and use whatever you prefer by just changing the logic in _get_table() below. If you do choose to use my old data-class.php, be aware it expects 4 constants, DB_SERVER, DB_USER, DB_USER_PASS, DB_NAME to create a connection to the&nbsp;database.<\/p>\n<p><strike>Here&#8217;s the exporter code itself<\/strike> Update: I moved the <a href=\"http:\/\/snipplr.com\/view\/12519\/excel-exporter\/\">code to snipplr<\/a> because this Wordpress plugin doesn&#8217;t handle newline characters very&nbsp;well.<\/p>\n<p>The simplest use is to instantiate an object, tell the exporter what you want to appear in the header row in the spreadsheet (by setting column_heads to an array of values) and then calling export(), passing it the <span class=\"caps\">SQL<\/span> query that gets the data. If the number of fields in your query doesn&#8217;t match the number of heads in column_heads, the resulting <span class=\"caps\">HTML<\/span> will be a mess. You will understand if the code assumes you never make such mistakes. Here&#8217;s a code&nbsp;example:<\/p>\n<pre lang=\"php\">\n$e = new ExcelExporter();\n$e->column_heads = array(\"First Name\", \"Last Name\");\necho $e->export(\"SELECT first_name, last_name FROM table\");\n<\/pre>\n\n<p>Quick&nbsp;notes:<\/p>\n<ul>\n<li>Control the Excel filename in my example by setting $e->filename(&#8220;something-else.xls&#8221;)<\/li>\n<li>Add a timestamp to every file (useful for making sure the filename is always unique) by setting $e->timestamp_file =&nbsp;true<\/li>\n<li>When you&#8217;re trying to implement this and it&#8217;s not working and having to say yes to the popup and let the file open in Excel is driving you crazy, set $e->debug = true and it will skip the Excel headers, sending the output to the&nbsp;browser<\/li>\n<\/ul>\n\n<p>The big gotcha that works well for me but might not for you: there&#8217;s a hook in the code that passes every data column through _format_field(). In my current class, this looks for any field with &#8220;_date&#8221; in the column name, assumes that field is a <a href=\"http:\/\/www.unixtimestamp.com\/index.php\">Unix timestamp<\/a> and transforms the value into a m\/d\/y date. If you live in the other 99% of the world where people format their dates un-Americanly, well, you can do that like this: $e-&gt;date_format(&#8220;d\/m\/y&#8221;) or whatever other crazy date\/ time format you&nbsp;like.<\/p>\n<p>If you think that behavior stinks, rip it out. Alternatively, you can modify it or subclass this code (like &#8220;client-xyz-exporter extends ExcelExporter&#8221; for every client who lives in Excel) and change _format_field() to do whatever you want in a one-off sort of way. This is not high art, it&#8217;s just a faster way of making someone happy (if you can imagine the kind of person whose life is improved by additional&nbsp;spreadsheets).<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Windows GPG\u00a0Front-End","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/windows-gpg-front-end.html","rel":"alternate"}},"published":"2009-02-17T13:26:22-05:00","updated":"2009-02-17T13:26:22-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-02-17:\/windows-gpg-front-end.html","summary":"<h1>Windows <span class=\"caps\">GPG<\/span>&nbsp;Front-End<\/h1>\n<p>I&#8217;m doing some work with <span class=\"caps\">GPG<\/span> encryption and I always like to have a visual\/ gui front-end to use to make sure I haven&#8217;t screwed something up in my command line adventures. I came across <a href=\"http:\/\/cryptophane.org\/\">Cryptophane<\/a> today and it seems like a nice way to \u2026<\/p>","content":"<h1>Windows <span class=\"caps\">GPG<\/span>&nbsp;Front-End<\/h1>\n<p>I&#8217;m doing some work with <span class=\"caps\">GPG<\/span> encryption and I always like to have a visual\/ gui front-end to use to make sure I haven&#8217;t screwed something up in my command line adventures. I came across <a href=\"http:\/\/cryptophane.org\/\">Cryptophane<\/a> today and it seems like a nice way to keep track of my particular <a href=\"http:\/\/en.wikipedia.org\/wiki\/Alice_and_Bob\">Alice and Bob<\/a>. The only problem I ran across was that my <span class=\"caps\">GPG<\/span> install was in a non-standard place and Cryptophane doesn&#8217;t look in the registry (I&#8217;m pretty sure <span class=\"caps\">GPG<\/span> writes to it). The error wasn&#8217;t immediately clear and there&#8217;s no online help (though a .chm is provided), so I thought I&#8217;d post this for anyone else who runs into a similar problem. My shortcut target now looks like this:\n&#8220;G:\\Program Files\\Cryptophane\\Cryptophane.exe&#8221; <strong>&#8212;gpg-path &#8220;G:\\Program Files\\<span class=\"caps\">GNU<\/span>\\GnuPG\\gpg.exe<\/strong>&#8221;<\/p>\n<p>Your paths may vary,&nbsp;etc.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Morning\u00a0Stress","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/morning-stress.html","rel":"alternate"}},"published":"2009-01-22T10:32:02-05:00","updated":"2009-01-22T10:32:02-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-01-22:\/morning-stress.html","summary":"<h1>Morning&nbsp;Stress<\/h1>\n<p>I want English Muffin insurance, for those times when you tear the thing all wrong and one side is basically not there and the thing toasts completely unevenly because of the difference in girth. And the pressure&#8217;s on then, because the damn things come in six-packs, which \u2026<\/p>","content":"<h1>Morning&nbsp;Stress<\/h1>\n<p>I want English Muffin insurance, for those times when you tear the thing all wrong and one side is basically not there and the thing toasts completely unevenly because of the difference in girth. And the pressure&#8217;s on then, because the damn things come in six-packs, which makes no sense. It doesn&#8217;t correlate with anything: there are five weekdays, seven days in a week if you&#8217;re eating them every day (and it&#8217;s 10\/14 if there&#8217;s two of you in the house). Every once in a while I&#8217;ll come upon a four-pack and think, &#8220;Two of those might work better&#8221;, but then I get up close and realize it&#8217;s one of those massive &#8220;<span class=\"caps\">SANDWICH<\/span> <span class=\"caps\">SIZE<\/span>!&#8221; affairs and I can&#8217;t do it. Sure I&#8217;ve eaten sandwiches made from English Muffins, even hamburgers when we ran out of buns, but there&#8217;s something depressing about intentionally buying those. And if you try to eat one for breakfast, you&#8217;re going to feel like a real fatty. So that doubles the pressure and I wind up in front of the toaster like some bomb disposal technician whose decided on which wire to cut and now it&#8217;s just a question of death or glory. This is why there are&nbsp;Eggos.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Nothing's Coming\u00a0Out!","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/nothing039s-coming-out.html","rel":"alternate"}},"published":"2009-01-15T13:25:15-05:00","updated":"2009-01-15T13:25:15-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-01-15:\/nothing039s-coming-out.html","summary":"<h1>Nothing&#039;s Coming&nbsp;Out!<\/h1>\n<p>You want to know why recycling isn&#8217;t keeping pace, why the universe is going to suffer heat death and run out of energy a few billion years from now? I just opened a new container of bay leaves&#8212; if you don&#8217;t know what those \u2026<\/p>","content":"<h1>Nothing&#039;s Coming&nbsp;Out!<\/h1>\n<p>You want to know why recycling isn&#8217;t keeping pace, why the universe is going to suffer heat death and run out of energy a few billion years from now? I just opened a new container of bay leaves&#8212; if you don&#8217;t know what those are, they&#8217;re pretty much what you thought they were. The salient point is their size; <a href=\"http:\/\/en.wikipedia.org\/wiki\/Bay_leaf\" onclick=\"window.open(this.href); return false;\">go ahead and look<\/a>, I&#8217;ll&nbsp;wait.<\/p>\n\n<p>The container had a shaker top on it. You know, the kind of thing you&#8217;d expect if the contents were ground up seeds and not say, vegetation off a tree. So I have to break a goddamn thumbnail because some halfwit in Sandusky, Ohio can&#8217;t figure out whether or not to slap a shaker lid (with two options, not that either one would work) on top without calling someone back at <span class=\"caps\">HQ<\/span>. Can&#8217;t you see him starting to take out that 25&#8217; yellow Stanley tape he&#8217;s carried around all his life for no good reason, thinking, &#8220;This is finally it&#8221; when he realizes everyone&#8217;s staring a little more than normal? Isn&#8217;t there something on the shop wall next to the <span class=\"caps\">OSHA<\/span> posters, some suggested guideline on when not to include the shaker cap? &#8220;If it&#8217;s bigger than the tip of your pinkie,&#8221; with a red crossout&nbsp;circle.<\/p>\n\n<p>Of course not, because the job&#8217;s long since been turned over to the one reliable employee, some robot who happily slaps caps all day. When Skylab comes on line and the Terminators get rid of us, it won&#8217;t be because of world wars or violence or inhumanity, it&#8217;ll be because some computer figured out it just spent the last 10 years making the world worse&nbsp;off.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Anatomy of a Late\u00a0Night","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/anatomy-of-a-late-night.html","rel":"alternate"}},"published":"2009-01-10T12:03:13-05:00","updated":"2009-01-10T12:03:13-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-01-10:\/anatomy-of-a-late-night.html","summary":"<h1>Anatomy of a Late&nbsp;Night<\/h1>\n<p>New Year&#8217;s Eve has totally thrown us off schedule. For some time (the formula for which is: <span class=\"caps\">NOW<\/span> - # of years we&#8217;ve had a dog) we&#8217;ve been consistently in bed by 11, 12 on weekend nights, with 1am being a notably late night \u2026<\/p>","content":"<h1>Anatomy of a Late&nbsp;Night<\/h1>\n<p>New Year&#8217;s Eve has totally thrown us off schedule. For some time (the formula for which is: <span class=\"caps\">NOW<\/span> - # of years we&#8217;ve had a dog) we&#8217;ve been consistently in bed by 11, 12 on weekend nights, with 1am being a notably late night. Head hit the pillow at 3 again last night and I&#8217;m delineating Why for myself so I can find the&nbsp;error<\/p>\n<ul>\n    <li>8pm: Watched <em><a href=\"http:\/\/www.tropicthunder.com\/\" onclick=\"window.open(this.href); return false;\">Tropic Thunder<\/a><\/em> which turned out to be exactly what I thought it was, a decent three-and-a-half star comedy, something that&#8217;s not so easy to find nowadays. Perhaps the comedy palate has grown more sophisticated since the days of <em>Meatballs<\/em>, though the trailer we caught beforehand, Van Wilder: Freshman Year, suggests otherwise. Amazing the amount of work shitty comedy writers (&#8220;And then her <em>tits<\/em> pop out!&#8221;) can still get while more talented writers (&#8220;It was a surprise for all when her breasts sprang free of the bespoke bustier she was wearing.&#8221;) go hungry. Movie opens well with fake trailers, then nose dives for a bit until it sets up the story. Would be worth sitting through for Robert Downey, Jr. alone. Tom Cruise was better than I want to&nbsp;admit.<\/li>\n    <li>10pm: Rock Band. As <a href=\"http:\/\/360voice.gamerdna.com\/tag\/yerfatwa\" onclick=\"window.open(this.href); return false;\">my poor X-Box<\/a> can attest, I&#8217;d jumped off the Rock Band train last fall. I&#8217;d gotten good enough to play some on Expert but was still way overmatched by certain songs on Hard (and always songs like &#8220;Foreplay\/ Longtime&#8221; that take half a goddamn hour to point out you&#8217;re going to fail for the fiftieth time, never some Ramones ditty that&#8217;s over in 1:58). A light clicked on and I realized &#8220;playing&#8221; a &#8220;game&#8221; doesn&#8217;t involve nearly popping a vessel in your head and throwing things after the age of 5 or so. I was fine with no more Rock Band, there was no hole in my life.\n    <br \/>Then I heard The Gaslight Anthem&#8217;s new album. After playing it non-stop for a week, the damn drummer<sup>(1)<\/sup> hooked me back into Rock Band. Thankfully things have gone a lot better since. Even managed to skid through &#8220;Don&#8217;t Fear the Reaper&#8221; last night, failing just late enough to make it to the&nbsp;end.<\/li>\n    <li>1am: <em><a href=\"http:\/\/www.comedycentral.com\/videos\/index.jhtml?videoId=183712&title=bill-burr-dangerous-minds\" onclick=\"window.open(this.href); return false;\">Bill Burr, Why Do I Do This?<\/a><\/em> via Netflix. Discovered him last week on Comedy Central, causing another late night. The set was so good I was ready to sit through the repeat airing until smarter heads prevailed. I&#8217;ve been obsessivley listening to his old <a href=\"http:\/\/www.billburr.com\/2008\/podcast.htm\" onclick=\"window.open(this.href); return false;\">podcast<\/a> episodes this week. Can&#8217;t believe he can spitball an hour worth of funny on a weekly&nbsp;basis.<\/li>\n    <li>2:30am: This is where things really fell off the track. It started to go wrong in the 1am hour when we re-watched something we&#8217;d seen a week before and wound up cracking the emergency <span class=\"caps\">PBR<\/span> 12 pack in the frige, but I could have just shut down the X-Box, finished the beer and gone to bed. Instead I have to page through the Netflix Instant Queue, even though if anything in there was worthy of watching at 3am I&#8217;d have watched it already. Nope, a half hour later it&#8217;s 3am, we&#8217;re only halfway through the pilot episode of <em>Macgyver<\/em>, the beer&#8217;s all gone and I realize the level of tension wasn&#8217;t high enough to keep anyone but me awake. The possible rocket explosion will have to wait until we have more beer. Actually, to honor the spirit of the show, I should really brew some Pruno in the toilet. How Richard Dean Anderson isn&#8217;t starring in anything more than my dreams nowadays is a&nbsp;mystery.<\/li>\n<\/ul>\n\n<p>Postscript, 8am: dog gets up in bed, throws an absolute shitfit, leaving me wide awake with the better part of 12 beers still coursing through my veins. I think it&#8217;s some sort of Temperance thing with her, trying to get us off the Devil&#8217;s&nbsp;Brew.<\/p>\n\n<p><small>1. Brush with fame: the drummer went to elementary school with a friend of mine. The amazing part is my friend went to elementary school in New Jersey and still wound up bright.<\/small><\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"HP: W3C Print CSS\u00a0Testing","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/w3c-print-css-testing","rel":"alternate"}},"published":"2009-01-06T00:00:00-05:00","updated":"2009-01-06T00:00:00-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2009-01-06:\/w3c-print-css-testing","summary":"<h1><span class=\"caps\">HP<\/span>: <span class=\"caps\">W3C<\/span> Print <span class=\"caps\">CSS<\/span>&nbsp;Testing<\/h1>\n<h2>2009-01-06<\/h2>\n<p><em>Sponsored by <span class=\"caps\">HP<\/span>, I worked with the <span class=\"caps\">W3C<\/span> to create tests so browser\/ user-agent programmers can make sure their code conforms to <span class=\"caps\">CSS2<\/span>.1 and <span class=\"caps\">CSS3<\/span> Print&nbsp;standards.<\/em><\/p>\n<p>A long and ultimately very rewarding project that started out by teaching me some humility. Coming \u2026<\/p>","content":"<h1><span class=\"caps\">HP<\/span>: <span class=\"caps\">W3C<\/span> Print <span class=\"caps\">CSS<\/span>&nbsp;Testing<\/h1>\n<h2>2009-01-06<\/h2>\n<p><em>Sponsored by <span class=\"caps\">HP<\/span>, I worked with the <span class=\"caps\">W3C<\/span> to create tests so browser\/ user-agent programmers can make sure their code conforms to <span class=\"caps\">CSS2<\/span>.1 and <span class=\"caps\">CSS3<\/span> Print&nbsp;standards.<\/em><\/p>\n<p>A long and ultimately very rewarding project that started out by teaching me some humility. Coming into this project, I felt like I was a world-class expert in <span class=\"caps\">CSS<\/span>. It turned out I might have been world-class, but it was as a web developer who worked in <span class=\"caps\">CSS<\/span>, a very different thing. I had one advantage coming into the project: the two <span class=\"caps\">W3C<\/span> representatives on the project were completely frustrated by the previous development team. There was nowhere to go but up.&nbsp;thumb:1&nbsp;<\/p>\n<p>The previous developers weren&#8217;t bad programmers, but they were <em>programmers<\/em>. I am one as well but as in much of what I do, I come at it from two perspectives. I&#8217;ve always worked well with usability and visual designers because while I am a programmer, I am also a user of computers. When presented with a possible solution, I try to respond as a user: does this make sense? Would I prefer it over how things are? Is it attractive? Programmers, myself included, look at proposed solutions and think Can I do that? Will the codebase support it? What&#8217;s going to break as a result? Both programmers and users get frustrated with computers. Much of that frustration stems from two&nbsp;myths:<\/p>\n<h2><span class=\"dquo\">&#8220;<\/span>Computers are&nbsp;Smart&#8221;<\/h2>\n<p>Computers are stupid. Left alone, they don&#8217;t do anything. You have to tell them what to do. And not just that, you have to be incredibly specific about what you want and be 100% correct in those specific directions or the computer will not do what you want. In a <a href=\"http:\/\/lyrics.wikia.com\/Soul_Position:Fuckajob\" target=\"_blank\">song<\/a> by Soul Position (one whose lyrics are not safe for work, so don&#8217;t click if you&#8217;re worried about that sort of thing), he describes programming rather optimistically, saying &#8220;At my 9-to-5, I teach computers to be clever&#8221;. No one does that. Programming is the art of making a computer <em>seem<\/em> clever. If you have a very specific task that can be accomplished the same way every time, a computer can be your best friend. If you have a task that&#8217;s messy and open to interpretation (like say, <a href=\"http:\/\/www.codinghorror.com\/blog\/2010\/06\/whatever-happened-to-voice-recognition.html\" target=\"_blank\">voice recognition<\/a>), you are wasting your time. Not exactly, but you can&#8217;t make a computer accomplish those kinds of tasks: you have to redefine the task into a smaller slice of the job or break it into bits that can be done and then require the inputs to your system to come in a very specific format (think of an automated phone menu: it claims you can talk to it, but you can only say a certain set of words and they need to come in the right&nbsp;order).<\/p>\n<h2><span class=\"dquo\">&#8220;<\/span>The Computer Made a&nbsp;Mistake&#8221;<\/h2>\n<p>No it didn&#8217;t. See the previous misconception. The computer doesn&#8217;t know anything and doesn&#8217;t think anything. Whomever told it what to do was not specific enough. Unfortunately, the computer did exactly what it was told to do. There&#8217;s a problem, but it&#8217;s not with the&nbsp;computer.<\/p>\n<p>This project taught me an awful lot about <span class=\"caps\">CSS<\/span> and the importance of precision. It&#8217;s hard enough to build a web site or write a program to do something correctly. If you have to rely on something like a web browser so users can view your work, you then have to hope the browser programmer built the browser correctly. And you have to hope the browser properly implements the standards it is supposed to conform to. If there is ambiguity in the standards, everybody has problems. The previous programmers had seen the project as a simple list of discrete items: given this feature, write a test that exercises it. The first problem is they didn&#8217;t really understand the <span class=\"caps\">CSS<\/span> features. The second problem isn&#8217;t programming-related, it&#8217;s a formal logic problem: if you write one test for the feature, you only confirm that things work correctly in that one case. The tests should exercise any and all possible ways of things working correctly and they should also attempt to force things to work incorrectly. The closest thing to this in programming is &#8220;<a href=\"http:\/\/en.wikipedia.org\/wiki\/Fuzz_testing\" target=\"_blank\">Fuzz Testing<\/a>&#8221;: if you expect a certain, specific format and I send you random, meaningless information, you shouldn&#8217;t be trying to render&nbsp;it.<\/p>\n<p>The two people I worked with, Elika and Melinda, were incredibly patient while I learned how to form good tests. Coming into the project, it seemed easy enough: take a <span class=\"caps\">CSS<\/span> property and create a few simple <span class=\"caps\">HTML<\/span> pages that exercise it. The problem with that is these tests were for <span class=\"caps\">CSS<\/span> properties that did not exist yet. You couldn&#8217;t open your favorite browser and see the thing work. Much of it had to happen entirely in my head. I did have <a href=\"http:\/\/www.princexml.com\/\" target=\"_blank\">Prince <span class=\"caps\">XML<\/span><\/a>; because of their client needs, the software already implemented a number of proposed <span class=\"caps\">CSS<\/span> features, especially print ones. But even then it was a slippery slope: did they implement the feature properly? Bad enough to have to design a test for a property that no user-agent implemented yet. Worse still to have a user-agent that implemented it improperly leaving you thinking your test was wrong. To the credit of Prince <span class=\"caps\">XML<\/span>&#8217;s programmers, I rarely ran that situation. But programmers are egotistical, so the thought was always in the back of my head, adding to the&nbsp;confusion.<\/p>\n<p>What did I learn? It&#8217;s important to be specific. While I try to remain faithful to the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Robustness_principle\" target=\"_blank\">Robustness Principle<\/a> in things I build, I sometimes wish the tools I worked with did not. While I work in Windows most of the time, my heart is with Unix\/ Linux. Twice in my professional life I&#8217;ve lost more than a day&#8217;s worth of working time due to a typo. In both cases, I got burned by Windows&nbsp;permissiveness.<\/p>\n<p>My first year as a web developer, I inherited a project from another team member who had moved to a project manager gig (which gives you an idea of the quality of his web development). I spent far too much time and energy trying to figure out why Internet Explorer was properly rendering a page&#8217;s background when every other browser could not. The file, &#8220;background.jpg&#8221; existed. And it was in the right place on the file system. No permission issues. Not a web server thing. It was one of those cases where your eyes see what they want to see after staring at a thing for so long. Because the code wasn&#8217;t asking for &#8220;background.jpg&#8221;. What the code actually, specifically said (and apologies for the old-school <span class=\"caps\">HTML<\/span>) was background=&#8221;background&#8221;. No file extension. Where every other browser said there was no file called that, <span class=\"caps\">IE<\/span> and Windows conspired together to &#8220;fix&#8221; my mistake and find the file they were sure&nbsp;meant.<\/p>\n<li>A few weeks ago (as of July 2010), I had a problem with Django template inheritance. Everything worked fine locally using the built-in Django server, but no matter what I did, the live server would not find or render any templates in a certain file. No matter which file I asked for, no matter if I renamed the files, played with the permissions, nothing would work. As is my habit now when stuck on a problem, I posted a <a href=\"http:\/\/stackoverflow.com\/questions\/2978054\/django-templatesyntaxerror-only-on-live-server-templates-exist\" target=\"_blank\">question on StackOverflow<\/a> so the whole world could be party to my stupidity. All those times I changed the template name, I never bothered to notice I&#8217;d left an extra whitespace at the end of the name. While Windows &#8220;helpfully&#8221; cleaned up my mistake, Linux saw me asking for a file name that did not&nbsp;exist.<\/li>\n<p>I understand why Windows file system is case-insensitive. While I wish it wasn&#8217;t, it&#8217;s a design decision and I can respect that. But some of the things Microsoft does to try to fix mistakes you make are less than helpful. If working with computers means being both specific and correct, fixing my mistakes is no help at all. I&#8217;d rather immediately be notified that I&#8217;ve messed up. Don&#8217;t try to make the computer seem&nbsp;clever.<\/p>\n<p>A full list of the tests I created can be seen <a href=\"http:\/\/wiki.csswg.org\/test\/css2.1\/submit\" target=\"_blank\">here<\/a>, though the domain they are tied to no longer exists. I do have the tests in version control if anyone wants&nbsp;them.<\/p>\n<p><img src=\"\/images\/portfolio\/W3C_Tests.png\" alt=\"W3C Repository Some of my tests at the W3C\" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"css"}},{"@attributes":{"term":"w3c"}}]},{"title":"\u201cLife's Good\u201d,\u00a0Indeed","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/quotlife039s-goodquot-indeed.html","rel":"alternate"}},"published":"2008-12-17T09:37:20-05:00","updated":"2008-12-17T09:37:20-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2008-12-17:\/quotlife039s-goodquot-indeed.html","summary":"<h1><span class=\"dquo\">&#8220;<\/span>Life&#039;s Good&#8221;,&nbsp;Indeed<\/h1>\n<p>I am providing this post-mortem both as a public service and so I don&#8217;t punch in the screen of my brand-new <span class=\"caps\">LG<\/span> monitor. I picked up a new <a href=\"http:\/\/www.lge.com\/products\/model\/detail\/l227wt.jhtml\" onclick=\"window.open(this.href); return false;\">22&#8221; monitor<\/a> at Best Buy yesterday after losing a monitor to the power surges from the ice \u2026<\/p>","content":"<h1><span class=\"dquo\">&#8220;<\/span>Life&#039;s Good&#8221;,&nbsp;Indeed<\/h1>\n<p>I am providing this post-mortem both as a public service and so I don&#8217;t punch in the screen of my brand-new <span class=\"caps\">LG<\/span> monitor. I picked up a new <a href=\"http:\/\/www.lge.com\/products\/model\/detail\/l227wt.jhtml\" onclick=\"window.open(this.href); return false;\">22&#8221; monitor<\/a> at Best Buy yesterday after losing a monitor to the power surges from the ice storm (what I ought to have done is replace the <span class=\"caps\">APC<\/span> unit that&#8217;s now cost me an external drive enclosure and a monitor, but that&#8217;s another gripe). Almost 24 hours later, the monitor is actually running as expected. Let me preface this by saying I appreciate my setup might be a little different from what the folks at <span class=\"caps\">LG<\/span> bothered to test&nbsp;on:<\/p>\n<ul>\n    <li>Mac hardware running&nbsp;Windows<\/li>\n    <li>it&#8217;s a second&nbsp;monitor<\/li>\n    <li>NVidia and <a href=\"http:\/\/www.realtimesoft.com\/ultramon\/overview\/\" onclick=\"window.open(this.href); return false;\">UltraMon<\/a> are both fighting for control of the&nbsp;setup<\/li>\n<\/ul>\n<p>All the same, this was a more painful hardware process than I remember going through. It&#8217;s a goddamn display, not an ultrasound machine. Nothing should be more plug-and-play. And yet, when I plugged it all in with the existing <span class=\"caps\">VGA<\/span> connection from the old monitor, none of the native resolutions were available. I installed the software and drivers, but it still couldn&#8217;t figure itself out. The <span class=\"caps\">LG<\/span> software could identify my primary monitor, but the software would not allow me to use any of the features because it could only run on an <span class=\"caps\">LG<\/span> device. Even when it figured out there was an <span class=\"caps\">LG<\/span> display somewhere, no dice. I&#8217;m assuming it has to be the primary display. Also, for a company that&#8217;s done such a good job of becoming an international player, it&#8217;s disappointing the English was as broken as the software displaying&nbsp;it.<\/p>\n<p>I gave up on <span class=\"caps\">LG<\/span> and updated the NVidia Control Panel, hoping newer versions would have the widescreen resolutions. Playing with the new control panel only blew things up worse: reversed the primary and the secondary and then screwed up Ultramon so badly the taskbar was displaying a box for every background process running on the box under my user account. It also saw fit to snap the resolution on both monitors to something fun. So,&nbsp;reboot.<\/p>\n<p>My last gasp, and it included a fair bit of gasping as I&#8217;ve been screwing off work due to a wrenched back, was to find a <span class=\"caps\">DVI<\/span> cable and try that. Nothing. No second monitor, no avowed knowledge of a second monitor in the control panel. For no good reason except I&#8217;m my own <span class=\"caps\">IT<\/span> department, rebooted. Success! Sort of. Both monitors are working during bootup, both are correctly identified in the control panel, both have their proper native resolutions dialed in and programs are being popped up on the <span class=\"caps\">LG<\/span>. Just one issue: it&#8217;s power light is in orange standby mode, the screen is off and no amount of pressing the power button will convince it to turn on or off. This is when one has to say, &#8220;I can tell a convincing lie to the returns desk if need be&#8221; and show inanimate objects just who the hell runs the show around here. Out comes the power cable. The funny little capacitor manages to keep the light orange for five brave seconds before giving up the ghost. I yell, &#8220;Clear&#8221;, jam the power cable back in as painfully as possible and here we are, all of us with a better understanding of the pecking order. And then I removed the startup item <span class=\"caps\">LG<\/span> installed (&#8220;forte display manager&#8221;) to keep it from doing it&#8217;s infinite loop dance with NVidia for control of the&nbsp;display.<\/p>\n<p>So, the public service announcement: if you get a new wide-screen <span class=\"caps\">LG<\/span> monitor, get a <span class=\"caps\">DVI<\/span> cable with it. Hook them up. Don&#8217;t install the <span class=\"caps\">LG<\/span> software (though you&#8217;ll most likely need the drivers). I suppose if you just have one monitor, you&#8217;ll be fine either way, but you&#8217;ll only find this post if something goes&nbsp;wrong.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Presented Without\u00a0Comment","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/presented-without-comment.html","rel":"alternate"}},"published":"2008-12-08T10:48:36-05:00","updated":"2008-12-08T10:48:36-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2008-12-08:\/presented-without-comment.html","content":"<h1>Presented Without&nbsp;Comment<\/h1>\n<object width=\"425\" height=\"344\"><param name=\"movie\" value=\"http:\/\/www.youtube.com\/v\/EDyDz8WeiM4&hl=en&fs=1\"><\/param><param name=\"allowFullScreen\" value=\"true\"><\/param><param name=\"allowscriptaccess\" value=\"always\"><\/param><embed src=\"http:\/\/www.youtube.com\/v\/EDyDz8WeiM4&hl=en&fs=1\" type=\"application\/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"425\" height=\"344\"><\/embed><\/object>\n\n<p><a href=\"http:\/\/www.chordstrike.com\/2008\/12\/even-in-a-reces.html\" onclick=\"window.open(this.href); return false;\">[via]<\/a><\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Xmas Flick Tradition Continues for Hicks in\u00a0Stix","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/xmas-flick-tradition-continues-for-hicks-in-stix.html","rel":"alternate"}},"published":"2008-12-04T11:16:35-05:00","updated":"2008-12-04T11:16:35-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2008-12-04:\/xmas-flick-tradition-continues-for-hicks-in-stix.html","summary":"<h1>Xmas Flick Tradition Continues for Hicks in&nbsp;Stix<\/h1>\n<p>I bought myself a couple of early Xmas\/ Birthday presents this week, <a href=\"http:\/\/www.imdb.com\/title\/tt0036872\/\" onclick=\"window.open(this.href); return false;\">Going My Way<\/a> and <a href=\"http:\/\/www.imdb.com\/title\/tt0037536\/\" onclick=\"window.open(this.href); return false;\">The Bells of St. Mary&#8217;s<\/a>. I bought those two old weepers in order to maintain the family tradition (my mother&#8217;s) of watching at least \u2026<\/p>","content":"<h1>Xmas Flick Tradition Continues for Hicks in&nbsp;Stix<\/h1>\n<p>I bought myself a couple of early Xmas\/ Birthday presents this week, <a href=\"http:\/\/www.imdb.com\/title\/tt0036872\/\" onclick=\"window.open(this.href); return false;\">Going My Way<\/a> and <a href=\"http:\/\/www.imdb.com\/title\/tt0037536\/\" onclick=\"window.open(this.href); return false;\">The Bells of St. Mary&#8217;s<\/a>. I bought those two old weepers in order to maintain the family tradition (my mother&#8217;s) of watching at least TBoSM every Christmas. It won&#8217;t be the same without her (and I&#8217;ll probably fall apart when that dumb little kid calls Bing &#8220;faddah&#8221;), but it&#8217;ll be&nbsp;something.<\/p>\n\n<p>I would tell you neither movie is an Oscar winner, but <em><a href=\"http:\/\/www.amazon.com\/gp\/product\/B000KJTGHO?ie=UTF8&ref_=pd_bbs_sr_1&s=dvd&qid=1228500665&sr=8-1\">Going My Way<\/a><\/em> took home <a href=\"http:\/\/www.imdb.com\/title\/tt0036872\/awards\" onclick=\"window.open(this.href); return false;\">7 (!), including Best Picture<\/a>. Cinema has come a long way in the interim: there&#8217;s more dramatic tension reading the phone book (&#8220;Will the Zs really make it at the end?&#8221;). The movies exist as frames for musical numbers, a bit of feel-good holiday cheer and not much else. All the same, I will assert (based on nothing more than hope) there are worse ways to spend 2 hours in front of the <span class=\"caps\">TV<\/span> at&nbsp;Christmas. <\/p>\n\n<p>I&#8217;ve seen both enough they run together, so much so I was surprised to see Barry Fitzgerald isn&#8217;t in the sequel, <em><a href=\"http:\/\/www.amazon.com\/Bells-St-Marys-Bing-Crosby\/dp\/B0000EMYML\/ref=pd_bbs_sr_2?ie=UTF8&s=dvd&qid=1228500665&sr=8-2\">The Bells of St. Mary&#8217;s<\/a><\/em>. It&#8217;s a solo tour de force for Bing Crosby&#8217;s Super Priest, who could kick the ass out of Ayn Rand&#8217;s Architect and bed any woman he wanted, except he&#8217;s so cool he&#8217;s into the absitence thing decades before it became cool. The film overcomes two glaring&nbsp;issues:<\/p>\n<ol>\n    <li>Allowing Bing Crosby anywhere near other people&#8217;s&nbsp;children<\/li>\n    <li>Employing Ingrid Bergman&#8217;s nun as an educator, given the church could theoretically reassign her to a high school class full of pubescent&nbsp;males<\/li>\n<\/ol>\n\n<div style=\"background: #cfcfcf; border: 1px dashed #eee; padding: 1em; margin-bottom: 1em;\">\n<p><strong>Aside&nbsp;#1<\/strong><\/p>\nTo emphasize what an issue #2 is, I present a full list of all the women in the world my father ever suggested were attractive\n<ol>\n    <li>My mother (1,000,006&nbsp;times)<\/li>\n    <li>Ingrid Bergman (1&nbsp;time)<\/li>\n<\/ol>\n<\/div>\n\n<p> &#8230; to get you to a conclusion that might as well appear in the opening credits. <span class=\"caps\">SPOILER<\/span> <span class=\"caps\">ALERT<\/span>: The school is saved! Like any holiday movie, it&#8217;s not about the story but about the season and some feeling of continuity in life. Much as I&#8217;m making fun of the film, it&#8217;ll be a mess &#8216;round here when they get to singing &#8220;The Bells of St. Mary&#8217;s&#8221;: the last time we heard it, it was being sung by the girls&#8217; choir from <a href=\"http:\/\/www.stmaryacademy-bayview.org\/matriarch\/default.asp\" onclick=\"window.open(this.href); return false;\">St. Mary&#8217;s Bay View<\/a> at the&nbsp;funeral.<\/p>\n\n<p>Like any good Spoil Yourself purchase on Amazon, I wound up with more than just what I set out to buy, adding a 3rd movie we used to watch together, <em>The Grapes of Wrath<\/em> after running across a post on the New York&nbsp;Times,<\/p>\n\n<div style=\"width: 500px; height: 335px;\">\n<object id=\"myExperience\" class=\"BrightcoveExperience\" width=\"500\" height=\"334\" type=\"application\/x-shockwave-flash\" data=\"http:\/\/c.brightcove.com\/services\/viewer\/federated_f9?&width=500&height=334&flashID=myExperience&bgcolor=%23FFFFFF&playerID=1847322191&publisherID=1749339200&isVid=true&isUI=true&%40videoPlayer=ref%3A1194832268537\">\n<\/div>\n\n<p>It was the kind of movie we&#8217;d watch if it was on <span class=\"caps\">TV<\/span> on a Sunday afternoon when there was ironing to be done. The populism and underdog-nature of the story appealed to my mom, but we knew what really got her was the mom. She saw her own mother in her and, of course, I see mine (don&#8217;t think the &#8220;Oh, Tom!&#8221; doesn&#8217;t catch my ear). The final, famous scene (&#8220;Where ever there&#8217;s a fight &#8230; &#8220;) always resonates. When I was young, close to my parents and just wanting to stay home, egotism made it easy to see myself as Heroic Tom Joad, leaving family and friends, purposely striding out the door to make the world A Better Place. Now that the roles are reversed, that I&#8217;m home and my mom is gone forever, the scene reminds me she&#8217;s not exactly gone. She might not show up if you&#8217;re getting trounced by a cop, but she&#8217;s there in my relationship with Michelle, she&#8217;s there in anything I do just for someone else, she&#8217;s there in just about anything I do right. The idea that time is a coping mechanism, a way of perceiving ourselves in the physical world, it&#8217;d be nice to think you could step outside, take a hard right and see everyone that&#8217;s left&nbsp;behind.<\/p>\n\n<div style=\"background: #cfcfcf; border: 1px dashed #eee; padding: 1em; margin-bottom: 1em;\">\n<p><strong>Aside&nbsp;#2<\/strong><\/p>\nAfter a dozen viewings of <em>Going My Way<\/em> (and having seen <em>The Quiet Man<\/em>), it was disconcerting to run across Barry Fitzgerald as a bad guy in <em><a href=\"http:\/\/www.imdb.com\/title\/tt0034162\/\" onclick=\"window.open(this.href); return false;\">The Sea Wolf<\/a><\/em>. I conveniently came across it one Saturday night on <span class=\"caps\">PBS<\/span> and watched because Jack London&#8217;s book had just been assigned in class. It was even worse than the time I saw Harry Morgan as a low-down, dirty ranchhand in <em><a href=\"http:\/\/www.imdb.com\/title\/tt0044413\/\" onclick=\"window.open(this.href); return false;\">Bend of the River<\/a><\/em>; at least by that point I knew he was the kind of guy that would <a href=\"http:\/\/en.wikipedia.org\/wiki\/Harry_Morgan#Personal_life\" onclick=\"window.open(this.href); return false;\">push his wife down a flight of stairs.<\/a>\n<br \/>\n<small>You can spare me the emails, I&#8217;m well aware (old movie on <span class=\"caps\">PBS<\/span> + in high school + Saturday night) = <span class=\"caps\">LOSER<\/span>.<\/small>\n<\/div>","category":{"@attributes":{"term":"Posts"}}},{"title":"denimrack: Denimrack Website\u00a0Overhaul","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/denimrack-website-overhaul","rel":"alternate"}},"published":"2008-11-10T00:00:00-05:00","updated":"2008-11-10T00:00:00-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2008-11-10:\/denimrack-website-overhaul","summary":"<h1>denimrack: Denimrack Website&nbsp;Overhaul<\/h1>\n<h2>2008-11-10<\/h2>\n<p><em>Updated an existing X-Cart-powered ecommerce site to improve usability, correct bugs on the front-end and add reporting to the administrative&nbsp;tools.<\/em><\/p>\n<p>Denimrack came to me with a list of edits they wanted to make to their live web site. I added tracking of abandoned purchases \u2026<\/p>","content":"<h1>denimrack: Denimrack Website&nbsp;Overhaul<\/h1>\n<h2>2008-11-10<\/h2>\n<p><em>Updated an existing X-Cart-powered ecommerce site to improve usability, correct bugs on the front-end and add reporting to the administrative&nbsp;tools.<\/em><\/p>\n<p>Denimrack came to me with a list of edits they wanted to make to their live web site. I added tracking of abandoned purchases so Denimrack can follow up with users to find out how to better meet customer needs. The site now has an Ajax-powered feedback form so users can get in touch with the company no matter what page they&#8217;re currently viewing. Similarly, users can now submit return requests from any page on the site. I dug into the interface and code to figure out how Denimrack could offer discounts to users through coupons and volume discounts. I then hooked some custom code into X-Cart so the site now watches user&#8217;s shopping carts to alert them when they are close to achieving a volume&nbsp;discount.<\/p>\n<p>We spent a good deal of time on the product detail screen since this is where users spend most of their time. I cleaned up a  number of display issues across browsers, made Clearance\/ Sale status more prominent and added a link to allow users to consult Denimrack&#8217;s stylist with questions about the pair of jeans they&#8217;re currently viewing. All edits and changes I made were carefully integrated into the existing coding approach. This was my first experience working with <a href=\"http:\/\/www.smarty.net\/\">Smarty<\/a>, so it took some time to get used to actually having logic and presentation separation in <span class=\"caps\">PHP<\/span>, but it was well worth it and Smarty has become part of my <span class=\"caps\">PHP<\/span> solution&nbsp;toolkit.<\/p>\n<p>On the administrative side, the client wanted more visibility into their overhead and sales. I integrated inventory and sales reports that can be filtered by date range into the existing custom administrative panel provided by the original&nbsp;developers.<\/p>\n<p><img src=\"\/images\/portfolio\/dr-detail.jpg\" alt=\"Product Detail \" style=\"margin: 1em 0\" \/>\n<img src=\"\/images\/portfolio\/dr-returns.jpg\" alt=\"Returns Form You can make a return request from any page on the site without losing your place.\" style=\"margin: 1em 0\" \/><\/p>\n<p><img src=\"\/images\/portfolio\/dr-home.jpg\" alt=\"Home Page \" style=\"margin: 1em 0\" \/><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"php"}},{"@attributes":{"term":"xcart"}},{"@attributes":{"term":"maintenance"}},{"@attributes":{"term":"ajax"}},{"@attributes":{"term":"smarty"}},{"@attributes":{"term":"ecommerce"}}]},{"title":"Making .NET 2.0 Spit JSON","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/making-net-20-spit-json.html","rel":"alternate"}},"published":"2008-11-08T09:56:23-05:00","updated":"2008-11-08T09:56:23-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2008-11-08:\/making-net-20-spit-json.html","summary":"<h1>Making .<span class=\"caps\">NET<\/span> 2.0 Spit <span class=\"caps\">JSON<\/span><\/h1>\n<p>I just finished translating a set of <span class=\"caps\">PHP<\/span> web services into C# for a national car insurer and came across two things worth mentioning, if only for my future&nbsp;reference.<\/p>\n<p>Each service needed an <span class=\"caps\">XML<\/span> and a <span class=\"caps\">JSON<\/span> version. I knew I didn&#8217;t \u2026<\/p>","content":"<h1>Making .<span class=\"caps\">NET<\/span> 2.0 Spit <span class=\"caps\">JSON<\/span><\/h1>\n<p>I just finished translating a set of <span class=\"caps\">PHP<\/span> web services into C# for a national car insurer and came across two things worth mentioning, if only for my future&nbsp;reference.<\/p>\n<p>Each service needed an <span class=\"caps\">XML<\/span> and a <span class=\"caps\">JSON<\/span> version. I knew I didn&#8217;t want to write code to hand-roll duplicate sets of responses, but I also didn&#8217;t think it was worth knocking up a formatter class for two response formats. I created the <span class=\"caps\">XML<\/span> responses and decided I&#8217;d transform them to <span class=\"caps\">JSON<\/span> via <span class=\"caps\">XSL<\/span>. Just before I got started on that, I remembered anything halfway smart I think of has already been done. Thus, <a href=\"http:\/\/code.google.com\/p\/xml2json-xslt\/\" target=\"_blank\">xml2json<\/a>.<\/p>\n<p>Sinfully proud of myself, I wired up the <span class=\"caps\">JSON<\/span> responses and pointed the pre-existing test site at my new services. And: nothing. Knowing I&#8217;m perfect, I fiddled with the site&#8217;s JavaScript for an embarrassingly long time before looking at the output of my <span class=\"caps\">JSON<\/span> services. I&#8217;d created a bunch of web services that returned a string type and the <span class=\"caps\">JSON<\/span> looked gorgeous in the unit tests, so where was the problem? Oh&nbsp;yeah:<\/p>\n<pre lang=\"xml\">\n<string>{json:\"help, i'm trapped in here\"}<\/string><\/pre>\n<p>There&#8217;s a lot I love about .<span class=\"caps\">NET<\/span>&#8217;s web services, mainly how the busywork is taken care of behind the scenes. Except there&#8217;s no easy way to get back there and change the plumbing (to mix a metaphor) so it spits out strings instead of <span class=\"caps\">XML<\/span>. .<span class=\"caps\">NET<\/span> 3.5 has native <span class=\"caps\">JSON<\/span> serialization, but this had to be 2.0-compatible. I found a <a href=\"http:\/\/delicious.com\/yerfatma\/json+dotnet\" target=\"_blank\">number of possible solutions<\/a>, most of which relied on the <a href=\"http:\/\/www.asp.net\/ajax\/ajaxcontroltoolkit\/samples\/\" target=\"_blank\">Ajax toolkit<\/a>. Having worked with it, I have two objections to the&nbsp;toolkit:<\/p>\n<ol>\n    <li>It&#8217;s really heavy, so you&#8217;d better need&nbsp;it<\/li>\n    <li>It feels like black magic: include the proper fake files, say the incantations just right, things may&nbsp;work<\/li>\n<\/ol>\n<p>The toolkit was too much of an elephant gun for this ant. But the alternative was to create my own custom response handler, which felt both egotistical and like a good way to make a mess. While weighing the various options, all of them ugly, it hit&nbsp;me:<\/p>\n<pre lang=\"csharp\">\n[WebMethod]\npublic void MyJSONService()\n{\n  Context.Response.Write(myJsonString);\n  Context.Response.Flush();\n  Context.Response.End();\n}<\/pre>\n<p>A hack can be something that works even though you don&#8217;t understand it, something you do because you&#8217;re too lazy to do it correctly or something less than beautiful that solves the problem with a minimum of fuss. I&#8217;d like to think this was a #3. It&#8217;s not ideal and it&#8217;s not a good solution for a large system, but if you&#8217;re just trying to get .<span class=\"caps\">NET<\/span> 2.0 to send back strings without it wrapping everything in an <span class=\"caps\">XML<\/span> safety envelope, this works without requiring two tons of library or chicken blood + a full&nbsp;moon.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Progressive Insurance: Progressive API\u00a0Conversion","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/progressive-api-conversion","rel":"alternate"}},"published":"2008-11-06T00:00:00-05:00","updated":"2008-11-06T00:00:00-05:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2008-11-06:\/progressive-api-conversion","summary":"<h1>Progressive Insurance: Progressive <span class=\"caps\">API<\/span>&nbsp;Conversion<\/h1>\n<h2>2008-11-06<\/h2>\n<p><em>Took an existing <span class=\"caps\">API<\/span> concept written in <span class=\"caps\">PHP<\/span>, converted it to C#, polished some of the rough edges and&nbsp;documented.<\/em><\/p>\n<p>Progressive had a proof-of-concept <span class=\"caps\">API<\/span> for insurance price quotes written in <span class=\"caps\">PHP<\/span>. They wanted it converted to C# for better client compatibility; the <span class=\"caps\">API \u2026<\/span><\/p>","content":"<h1>Progressive Insurance: Progressive <span class=\"caps\">API<\/span>&nbsp;Conversion<\/h1>\n<h2>2008-11-06<\/h2>\n<p><em>Took an existing <span class=\"caps\">API<\/span> concept written in <span class=\"caps\">PHP<\/span>, converted it to C#, polished some of the rough edges and&nbsp;documented.<\/em><\/p>\n<p>Progressive had a proof-of-concept <span class=\"caps\">API<\/span> for insurance price quotes written in <span class=\"caps\">PHP<\/span>. They wanted it converted to C# for better client compatibility; the <span class=\"caps\">API<\/span> was designed to be installed locally on customer web servers so they can integrate insurance quotes into their sites. The <span class=\"caps\">API<\/span> needed to deliver results in both <span class=\"caps\">XML<\/span> and <span class=\"caps\">JSON<\/span> formats. The final deliverable included four .<span class=\"caps\">NET<\/span> projects: the main web services solution, the class library, a web site project with front-end templates that consume the various services as a reference for client customization and a unit test project (using NUnit) as a way of checking the server was set up properly. In addition, I provided documentation on how to set up the projects and a <span class=\"caps\">CHM<\/span> file documenting the&nbsp;code.<\/p>\n\n<p>One challenge I encountered: while the only differences between the <span class=\"caps\">JSON<\/span> and <span class=\"caps\">XML<\/span> web services was the format of the code (internally they both use the same function and translate the <span class=\"caps\">XML<\/span> into <span class=\"caps\">JSON<\/span> via <span class=\"caps\">XSL<\/span> if needed), .<span class=\"caps\">NET<\/span> 2.0 insists all web services reply in <span class=\"caps\">XML<\/span>. Newer versions make it easy to overcome this, but getting rid of the <span class=\"caps\">XML<\/span> tags in 2.0 is torturous enough I felt it <a href=\"http:\/\/www.thosecleverkids.com\/blog\/2008\/11\/08\/making-net-20-spit-json\/\">called for a good&nbsp;hack.<\/a><\/p>","category":[{"@attributes":{"term":"Portfolio"}},{"@attributes":{"term":"csharp"}},{"@attributes":{"term":"php"}},{"@attributes":{"term":"api"}},{"@attributes":{"term":"conversion"}},{"@attributes":{"term":"documentation"}},{"@attributes":{"term":"nunit"}},{"@attributes":{"term":"tdd"}}]},{"title":"Twitter Updates for\u00a02008-10-20","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/twitter-updates-for-2008-10-20.html","rel":"alternate"}},"published":"2008-10-20T23:59:59-04:00","updated":"2008-10-20T23:59:59-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2008-10-20:\/twitter-updates-for-2008-10-20.html","summary":"<h1>Twitter Updates for&nbsp;2008-10-20<\/h1>\n<ul>\n    <li>Earplugs didn&#8217;t prevent much. #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966768483\">#<\/a><\/li>\n    <li>Hate when home plate umps make a strike call on a close checked swing. Can&#8217;t we get the 2nd opinion? #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966776385\">#<\/a><\/li>\n    <li>Found my enemy for the night: overly-demonstrative older woman, front row, just up the 3rd base line (over \u2026<\/li><\/ul>","content":"<h1>Twitter Updates for&nbsp;2008-10-20<\/h1>\n<ul>\n    <li>Earplugs didn&#8217;t prevent much. #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966768483\">#<\/a><\/li>\n    <li>Hate when home plate umps make a strike call on a close checked swing. Can&#8217;t we get the 2nd opinion? #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966776385\">#<\/a><\/li>\n    <li>Found my enemy for the night: overly-demonstrative older woman, front row, just up the 3rd base line (over <span class=\"caps\">RH<\/span> batter&#8217;s shoulder) #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966784417\">#<\/a><\/li>\n    <li>McCain&#8217;s ads make me feel like I missed an episode. Seem to have been edited with a blender. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966789099\">#<\/a><\/li>\n    <li>@ericwyman She&#8217;s right above the New Era sign with a Petula Clark bob, between two old guys. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966797894\">#<\/a><\/li>\n    <li>Why would Varitek need to tell the catching coach what he&#8217;s going to do? #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966800664\">#<\/a><\/li>\n    <li>@ericwyman good to hear. Make up for lost torrent time. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966801451\">#<\/a><\/li>\n    <li>Carl Crawford comes out to <span class=\"caps\">MIA<\/span>? 1. Sounds anti-Amerikun to me. 2. Good luck signing a guy who&#8217;s theme music says he just wants your money. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966802107\">#<\/a><\/li>\n    <li>@savetherobot Heart of Dorkness <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966807085\">#<\/a><\/li>\n    <li>Need to know what it says on Papi&#8217;s non-standard, non-team issued shirt. Something dirty, no doubt. #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966814045\">#<\/a><\/li>\n    <li>Buck Martinez&#8217;s Can&#8217;t-catch-up-to-a-sliding-runner theory sounded like it was a new Law of Thermodynamics. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966850358\">#<\/a><\/li>\n    <li>Cialis, if your boner pills are so great, why do they require two soaking tubs? <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966850720\">#<\/a><\/li>\n    <li>@mikesusz I&#8217;d have thought the roof, Field Turf and different colored walls would have been a tip off. And the empty lounge chairs. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966852234\">#<\/a><\/li>\n    <li>Dunno, how big are 2 out hits? There are 0 outs right now. #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966867285\">#<\/a><\/li>\n    <li>@ericwyman looked like a Very Special Fan. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966867723\">#<\/a><\/li>\n    <li><span class=\"caps\">TBS<\/span>, you claim Frank Caliendo makes a big impression, I&#8217;d like to prove it. Have him meet me on top of the Sears Tower. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966868312\">#<\/a><\/li>\n    <li><span class=\"dquo\">&#8220;<\/span>Hi, this is Matt Garza for Mucinex.&#8221; <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966884242\">#<\/a><\/li>\n    <li>Anyone else catching a romantic subtext to Ron <span class=\"amp\">&amp;<\/span> Buck&#8217;s discussion of pitchers <span class=\"amp\">&amp;<\/span> catchers? #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966884564\">#<\/a><\/li>\n    <li>@paulkelley the caught stealing? 3-2 and 1 out is a hit and run situation. Sucks they get the momentum from it. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966891559\">#<\/a><\/li>\n    <li>If that was an &#8220;easy&#8221; 1-2-3 inning, I don&#8217;t want to see a hard one. Too much solid contact. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966894235\">#<\/a><\/li>\n    <li>@paulkelley yeah, it was definitely a risky move, but Tito seems to send the runner in that situation about 80% of the time. Sucked. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966898150\">#<\/a><\/li>\n    <li><span class=\"caps\">PINCH<\/span> <span class=\"caps\">HIT<\/span> #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966904873\">#<\/a><\/li>\n    <li>Dog&#8217;s snoring soundly. Don&#8217;t know how she does it. Nerves of steel. #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966905651\">#<\/a><\/li>\n    <li>@ericwyman Thank you. Get that kid to an <span class=\"caps\">ENT<\/span>, stat. #garzasnot <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966924348\">#<\/a><\/li>\n    <li>Someone in the front row order something to make those weird-ass munchkin waitresses go away #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966958859\">#<\/a><\/li>\n    <li>Now is that Animal or Hawk wearing the sweatshirt in the Tampa dugout? #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966959353\">#<\/a><\/li>\n    <li>@ericwyman How quick does Price go in our draft next year? <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966959687\">#<\/a><\/li>\n    <li>Ah well, great season, fun playoffs and Tampa&#8217;s a damn good team. Could do without the fanbase. #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966972224\">#<\/a><\/li>\n    <li>What is that song? Where can I pay to have it not played? #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/966974276\">#<\/a><\/li>\n    <li>@CinemaSuicide Uf, thanks for giving me someone to block. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/967496360\">#<\/a><\/li>\n    <li>Please tell the dog I don&#8217;t negotiate with terrorists. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/967764740\">#<\/a><\/li>\n    <li>Good post on the value of defense and the price of wins in <span class=\"caps\">MLB<\/span>: <a href=\"http:\/\/is.gd\/4qPK\" rel=\"nofollow\">http:\/\/is.gd\/4qPK<\/a> <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/967854690\">#<\/a><\/li>\n    <li>@adarowski @SoxyLady I was sorry to hear it too, but I think it&#8217;s only &#8220;out of character&#8221; for the person he&#8217;s portrayed as in the media. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/967855572\">#<\/a><\/li>\n<\/ul>\n<p>Powered by <a href=\"http:\/\/alexking.org\/projects\/wordpress\">Twitter Tools<\/a>.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Twitter Updates for\u00a02008-10-19","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/twitter-updates-for-2008-10-19.html","rel":"alternate"}},"published":"2008-10-19T23:59:59-04:00","updated":"2008-10-19T23:59:59-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2008-10-19:\/twitter-updates-for-2008-10-19.html","summary":"<h1>Twitter Updates for&nbsp;2008-10-19<\/h1>\n<ul>\n    <li>If I&#8217;d been friends w\/Shel Silverstein, I&#8217;d have always <span class=\"caps\">RSVP<\/span>&#8217;d by saying, &#8220;Tell &#8216;em I&#8217;m coming, and Shel&#8217;s coming with me.&#8221; <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965844037\">#<\/a><\/li>\n    <li>@garyryan Well, it&#8217;s strange you could acquire the &#8220;Big Game&#8221; label before playing in one. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965844574\">#<\/a><\/li>\n    <li>Dinner at Agave \u2026<\/li><\/ul>","content":"<h1>Twitter Updates for&nbsp;2008-10-19<\/h1>\n<ul>\n    <li>If I&#8217;d been friends w\/Shel Silverstein, I&#8217;d have always <span class=\"caps\">RSVP<\/span>&#8217;d by saying, &#8220;Tell &#8216;em I&#8217;m coming, and Shel&#8217;s coming with me.&#8221; <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965844037\">#<\/a><\/li>\n    <li>@garyryan Well, it&#8217;s strange you could acquire the &#8220;Big Game&#8221; label before playing in one. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965844574\">#<\/a><\/li>\n    <li>Dinner at Agave (Portsmouth) tonight; disappointment. Everything Poco&#8217;s does, but worse, more expensive w\/ bad service kicker. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965845019\">#<\/a><\/li>\n    <li>In re Shel Silverstein, for people like @suchatreat, <a href=\"http:\/\/tinyurl.com\/6jpwt6\" rel=\"nofollow\">http:\/\/tinyurl.com\/6jpwt6<\/a> <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965847430\">#<\/a><\/li>\n    <li>@adarowski if you&#8217;re listening to Girl Talk, you&#8217;re going to want the Wikipedia pages to save the brain scratching. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965848352\">#<\/a><\/li>\n    <li>Tampa Bay, you&#8217;ll never be a respectable franchise until you strip the season tickets from Leather Lungs. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965851635\">#<\/a><\/li>\n    <li>My Facebook says &#8220;69 friends&#8221; I&#8217;ll pass, but the 13 year old in me thinks it&#8217;s funny. As is &#8220;the 13 year old in me&#8221;. Meta-illegal-joke <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965855404\">#<\/a><\/li>\n    <li>Buck Martinez just summed up the playoff experience: &#8220;When you&#8217;re throwing 90mph fastballs, it&#8217;s time to go #2.&#8221; <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965875029\">#<\/a><\/li>\n    <li>If you bought an off-brand, bullshit team jersey, don&#8217;t bring it to a nationally televised game. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965875409\">#<\/a><\/li>\n    <li>Cue Kevin Millah: &#8220;Don&#8217;t let us win one.&#8221; <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965877158\">#<\/a><\/li>\n    <li>You know <span class=\"caps\">TBS<\/span> is a serious network when Saeger&#8217;s jackets never run out of batteries. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965878022\">#<\/a><\/li>\n    <li>Want Youk&#8217;s beard to produce birds like Family Guy #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965878970\">#<\/a><\/li>\n    <li>I know we&#8217;re spoiled, but if you&#8217;re crying about a non-elimination loss by your 10 year-old team, gain perspective. #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965881226\">#<\/a><\/li>\n    <li>Finds it ironic Adele is backed by skinny chicks on <span class=\"caps\">SNL<\/span> <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965889204\">#<\/a><\/li>\n    <li>@garyryan &#8220;And that was the second time I got crabs.&#8221; <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965889710\">#<\/a><\/li>\n    <li>@paulkelley They should get the Tampa groundscrew to spraypaint that stupid starburst on a carpet somewhere in a dugout. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965924376\">#<\/a><\/li>\n    <li>1st time watching <span class=\"caps\">SNL<\/span> in years. Complete disappointment except for Adele. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965924688\">#<\/a><\/li>\n<\/ul>\n<p>Powered by <a href=\"http:\/\/alexking.org\/projects\/wordpress\">Twitter Tools<\/a>.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Twitter Updates for\u00a02008-10-18","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/twitter-updates-for-2008-10-18.html","rel":"alternate"}},"published":"2008-10-18T23:59:59-04:00","updated":"2008-10-18T23:59:59-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2008-10-18:\/twitter-updates-for-2008-10-18.html","content":"<h1>Twitter Updates for&nbsp;2008-10-18<\/h1>\n<ul>\n    <li>Taking dog for a walk, setting up @suchatreat&#8217;s b&#8217;day presents so as to best surprise. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/965082591\">#<\/a><\/li>\n<\/ul>\n<p>Powered by <a href=\"http:\/\/alexking.org\/projects\/wordpress\">Twitter Tools<\/a>.<\/p>","category":{"@attributes":{"term":"Posts"}}},{"title":"Twitter Updates for\u00a02008-10-17","link":{"@attributes":{"href":"https:\/\/tomclancy.info\/twitter-updates-for-2008-10-17.html","rel":"alternate"}},"published":"2008-10-17T23:59:59-04:00","updated":"2008-10-17T23:59:59-04:00","author":{"name":"Tom Clancy"},"id":"tag:tomclancy.info,2008-10-17:\/twitter-updates-for-2008-10-17.html","summary":"<h1>Twitter Updates for&nbsp;2008-10-17<\/h1>\n<ul>\n    <li>Upside to #redsox potentially being eliminated in 5: no more Chip Caray in anyone&#8217;s life. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/963149927\">#<\/a><\/li>\n    <li>tbshotcorner.com - shitty baseball site or your vaccination information headquarters? <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/963150382\">#<\/a><\/li>\n    <li>Well, last one out shut off the lights. #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/963183421\">#<\/a><\/li>\n    <li>Do not thou, when thou art a fan, boo a Papi \u2026<\/li><\/ul>","content":"<h1>Twitter Updates for&nbsp;2008-10-17<\/h1>\n<ul>\n    <li>Upside to #redsox potentially being eliminated in 5: no more Chip Caray in anyone&#8217;s life. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/963149927\">#<\/a><\/li>\n    <li>tbshotcorner.com - shitty baseball site or your vaccination information headquarters? <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/963150382\">#<\/a><\/li>\n    <li>Well, last one out shut off the lights. #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/963183421\">#<\/a><\/li>\n    <li>Do not thou, when thou art a fan, boo a Papi. Boo a Varitek, boo a Daisuke, but never an Ortiz #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/963193628\">#<\/a><\/li>\n    <li><span class=\"caps\">WHAT<\/span>! #redsox <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/963381297\">#<\/a><\/li>\n    <li>It would appear at two points last night, the #redsox had a 0% chance of winning: <a href=\"http:\/\/is.gd\/4fgR\" rel=\"nofollow\">http:\/\/is.gd\/4fgR<\/a> <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/963735699\">#<\/a><\/li>\n    <li>@laurelatoreilly in re: .<span class=\"caps\">NET<\/span> collective intelligence, you can&#8217;t dm people that don&#8217;t follow you. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/963882250\">#<\/a><\/li>\n    <li>Think you can unfollow me without consequences? Dream on: <a href=\"http:\/\/useqwitter.com\/\" rel=\"nofollow\">http:\/\/useqwitter.com\/<\/a> <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/964083584\">#<\/a><\/li>\n    <li>This week&#8217;s Zero Punctuation: A+ - <a href=\"http:\/\/is.gd\/47Tn\" rel=\"nofollow\">http:\/\/is.gd\/47Tn<\/a> <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/964123984\">#<\/a><\/li>\n    <li>Picked up some new (to me) stuff at the comic store: Sentry (http:\/\/www.the-isb.com\/?p=705) and the new series of Criminal. <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/964152678\">#<\/a><\/li>\n    <li>@erdanton cue up Billy Bragg&#8217;s &#8220;Levi Stubbs&#8217; Tears&#8221; in memoriam. <a href=\"http:\/\/is.gd\/4gDY\" rel=\"nofollow\">http:\/\/is.gd\/4gDY<\/a> <a href=\"http:\/\/twitter.com\/tclancy\/statuses\/964218826\">#<\/a><\/li>\n<\/ul>\n<p>Powered by <a href=\"http:\/\/alexking.org\/projects\/wordpress\">Twitter Tools<\/a>.<\/p>","category":{"@attributes":{"term":"Posts"}}}]}