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

<channel>
	<title>Fairway Technologies</title>
	<atom:link href="http://www.fairwaytech.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.fairwaytech.com</link>
	<description>Technology Consulting and Software Development</description>
	<lastBuildDate>Wed, 22 Feb 2012 06:33:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>When is perfect perfect enough?</title>
		<link>http://www.fairwaytech.com/2012/02/when-is-perfect-perfect-enough/</link>
		<comments>http://www.fairwaytech.com/2012/02/when-is-perfect-perfect-enough/#comments</comments>
		<pubDate>Fri, 10 Feb 2012 17:11:24 +0000</pubDate>
		<dc:creator>Brett Humphrey</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.fairwaytech.com/?p=2096</guid>
		<description><![CDATA[By some crazy stroke of luck I was invited to participate in the Diablo III Beta program.  It&#8217;s been 12 agonizing years since the last iteration of the game was [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.fairwaytech.com/wp-content/uploads/2012/02/diablo.jpg"><img class="alignleft size-full wp-image-2097" title="Chief Brimstone Officer" src="http://www.fairwaytech.com/wp-content/uploads/2012/02/diablo.jpg" alt="" width="128" height="128" /></a>By some crazy stroke of luck I was invited to participate in the <a href="http://en.wikipedia.org/wiki/Diablo_III" target="_blank">Diablo III</a> Beta program.  It&#8217;s been 12 agonizing years since the last iteration of the game was released (not including expansions).  12 years is a long time to wait for any sequel in a successful franchise, but even more conspicuous for a giant game company with deep pockets like Blizzard Entertainment.  <span id="more-2096"></span>But Blizzard seems to relish being perennially behind schedule, because as they say, they are making the game &#8216;perfect&#8217;.  &#8220;The game will be ready when it&#8217;s ready&#8221; is the hardline mantra from Blizz.  A uniquely-Blizzard smack of self-righteous indignation, like a bloody cudgel to the collective breastplates of the legions of increasingly frustrated but loyal Diablo fans.</p>
<p>On one hand I admire Blizzards&#8217; desire to release a product that is polished and ready for release into the big bad wild, but on the other hand I just wish they&#8217;d get on with it.</p>
<p>In life, as in software, there are a lot of good reasons to strive for perfection.  Quality, reliability, longevity, etc.  But most of the time singular focus on perfection is a dangerous illusion.  Obsessively striving to perfect something often comes at the expense of all other factors of success.  These are costly sacrifices to time, money, and in the case of many Diablo fans, sanity.</p>
<p>Here are a few of the more common casualties of chasing perfection:</p>
<ul>
<li><strong>Diminishing Returns</strong> &#8211; The effort required to polish something beyond discernible improvement is rarely worth it.  Will your users even notice, or more importantly appreciate these efforts?</li>
<li><strong>The 80/20 Rule</strong> &#8211; The final 20% of any project usually takes 80% of the effort.  Moreover sometimes the last 20% can be so unreasonably difficult that all previous effort needs to be scrapped.  This is how good ideas get scrapped.</li>
<li><strong>Lost Time</strong> &#8211; Excess time spent honing tiny details could be spent working on future phases, while users can invest themselves much earlier.</li>
<li><strong>Lost Feedback</strong> &#8211; Delaying releases also delays some of the most vitally important insights and feedback from users.  Critical bugs are one thing, but maybe that awesome feature you thought people would love sucks?  How will you know?</li>
<li><strong>Flawed Design</strong> &#8211; Software designed with perfection in mind is idealistic in nature and often plagued by inflexible architecture and poor integration.  In these cases, design trumps compatibility and you end up with a system that doesn&#8217;t play nice with anything else.</li>
<li><strong>Cost</strong> &#8211; It&#8217;s just plain more expensive to work on something for 10 years than it is for 5 years.</li>
<li><strong>Opportunity Cost</strong> &#8211; What new features and suggestions could have been implemented in the time it took to polish every dark recess of the code base?  How much market share has been lost while your competitors capitalized on your inactivity?  How much money has been forfeited from a lack of new features or major releases?</li>
<li><strong>Technology Decay</strong> &#8211; Technology is inexorable and cruel, leaving behind antiquated versions of legacy software in favor of anything faster, cheaper, better or newer.  Suddenly your state of the art system is a stinky pile of legacy garbage that nobody wants to touch.</li>
<li><strong>Paradoxical Refining</strong> &#8211; Obsessive second-guessing can lead to valid or otherwise satisfactory features being changed repeatedly, sometimes for the worse. Ever agonize over something (like a blog entry) until you had thoroughly mangled an otherwise acceptable success?</li>
</ul>
<p>Perfection in software is an illusion.  As an example, many modern quality assurance practices like zero defect testing, though well-intentioned, are often distorted by the pursuit of perfection.  The intent in seeking software perfection is admirable, but the goal is impractical or unattainable.  Slavishly chasing perfection can seriously jeopardize the overall success of a project.  Desire for perfection should be tempered with an understanding of what is possible, acceptable and reasonable for success.</p>
<p>So, at what point does one decide to stop chasing the perfection fairy?  I usually ask myself if I have met or exceeded the customers&#8217; expectations.  Success is defined by the customer.  Is the customer happy?  If so, I move on.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fairwaytech.com/2012/02/when-is-perfect-perfect-enough/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fairway Informant &#8211; Q1 2012 Newsletter</title>
		<link>http://www.fairwaytech.com/2012/02/fairway-q1-2012-newsletter/</link>
		<comments>http://www.fairwaytech.com/2012/02/fairway-q1-2012-newsletter/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 19:00:31 +0000</pubDate>
		<dc:creator>Jessica Colton</dc:creator>
				<category><![CDATA[newsletter]]></category>

		<guid isPermaLink="false">http://www.fairwaytech.com/?p=2126</guid>
		<description><![CDATA[&#8220;In This Issue&#8221; CEO Corner Client Spotlight 2011 Year in Review Tips &#38; Tricks Client Testimonials We&#8217;ve Updated Our Blog Resources: Free White Paper We&#8217;re Hiring! Welcome to the first [...]]]></description>
			<content:encoded><![CDATA[<div class="rightFixed">
<p>  &#8220;In This Issue&#8221;</p>
<ul>
<li><a href="#ceocorner">CEO Corner</a></li>
<li><a href="#clientspotlight">Client Spotlight</a></li>
<li><a href="#review">2011 Year in Review</a></li>
<li><a href="#tips">Tips &amp; Tricks</a></li>
<li><a href="#testimonials">Client Testimonials</a></li>
<li><a href="#blog">We&#8217;ve Updated Our Blog</a></li>
<li><a href="#whitepaper">Resources: Free White Paper</a></li>
<li><a href="#hiring">We&#8217;re Hiring!</a></li>
</ul>
</div>
<p><img src="http://www.fairwaytech.com/wp-content/uploads/2012/02/informant.gif" alt="" width="297" height="138" align="left" class="alignnone size-full wp-image-2151" title="informant"  style="margin-right: 20px;"/>Welcome to the first edition of the Fairway Informant, our new Quarterly newsletter. Although we&#8217;re a bit tardy, all of us at Fairway Technologies send warm New Year&#8217;s greetings to our clients, partners, and friends. Thanks to all of you for the opportunity to help you succeed in 2011. We take your trust in us very seriously – and we are always looking for ways to improve the services we provide. We welcome any feedback on your experience and suggestions for how we can make it better. <a name="ceocorner"></a>
</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<hr />
<h2>CEO Corner</h2>
<hr />
<p><img class="size-medium wp-image-2131 alignright" title="companyphoto" src="http://www.fairwaytech.com/wp-content/uploads/2012/02/companyphoto-300x81.jpg" alt="" width="300" height="81" /></p>
<p>  Has it really been 10 years? It certainly doesn&#8217;t seem like it, but judging by the desolate patch of forehead I used to call a hairline it may as well have been 50 years.</p>
<p>  Things may be different today, but nothing&#8217;s really changed and I&#8217;m proud of that. When I started Fairway 10 years ago I set out to work with only the people I wanted to work with. The best and brightest from my own small but deeply talented nexus of engineering friends and acquaintances. Our goal was simple; to provide the highest quality software development services in town. I believe we&#8217;ve achieved that, and had a lot of fun and made (and brewed) a lot of memories along the way.</p>
<p>  Fairway&#8217;s humble roots sprouted from the spare bedroom of my rented house where dogs and lawn mowers could not deter the first crack team of engineers who called Fairway home. At the calm and unbiased suggestion of my Chief Spousal Officer, we soon moved our nascent operation to a 600 square foot office space located below a public bathroom that leaked into the walls and attracted individuals generally not in need of software development services. It was in this office that we established some of our most cherished rituals, such as foosball penalty ice cream cones, D&amp;D night, and our now legendary brewfests.</p>
<p>  Onward and literally upward, we eventually moved to a larger office space above a liquor store and adjacent to a pot shop. In retrospect this was probably not the smartest decision, and I soon feared a cataclysmic destruction of productivity that fortunately never materialized. At least we had an ocean view; our own little sliver of La Jolla horizon huddled behind telephone wires and a conspicuously placed China Chef sign.</p>
<p>  Which brings us to our present day Fairway, glittery new offices in a very respectable (at least until we arrived) office building in the idyllic heart of La Jolla village. Interestingly (or perhaps not so), the financial district doesn&#8217;t seem to like or appreciate technologists. Even my sign on the front door, &#8220;Solicitors will be persecuted,&#8221; is met with chuffs of disgruntled indignation. I enjoy the contrast of being the Clampetts of the neighborhood though. All we need is a couch on the front porch and an El Camino on blocks to top it off.</p>
<p>  Over the years clients have come and gone, and employees too. I count myself lucky to have worked with friends as both clients and employees, and am luckier to have remained so when some have chosen to move on. We have spent 10 years assembling a team of amazingly talented technology gurus who also happen to be amazing people. This coalescence of talent is the huge benefit of working with people you know well and trust, and one of the important elements of Fairway&#8217;s secret sauce.</p>
<p>  In reflecting on my time at Fairway and the unfathomably fortunate path we&#8217;ve charted over the years, it&#8217;s hard to imagine doing any of it without the blood, sweat and tears of some of my closest friends and business associates. People are what make Fairway great, and we&#8217;re lucky to work with some of the smartest, coolest (in the nerdy sense), hardest-working people in southern California.</p>
<p>  So after 10 years, I guess all I have to say is thanks! Thanks to our passionate crew of technocrats who&#8217;ve made Fairway one of San Diego&#8217;s best (and coolest) places to work, to our customers who have put their faith in us to deliver bullet proof software time after time, and to everyone else who has supported us in our endeavor to provide the highest quality software development services in town.</p>
<p>  Thank you, and here&#8217;s to another 10 years!</p>
<p>  <a name="clientspotlight"></a>
</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<hr />
<h2>Client Spotlight<em></em></h2>
<hr />
<p><img class="size-medium wp-image-2132 alignright" title="independa2" src="http://www.fairwaytech.com/wp-content/uploads/2012/02/independa2-300x81.gif" alt="" width="300" height="81" /><br />
  <span class="Apple-style-span" style="font-size: 13px; font-weight: normal;">Client: <strong>Independa, Inc.</strong><br />
  </span><span class="Apple-style-span" style="font-size: 13px; font-weight: normal;">Website: <a href="http://www.independa.com" target="_blank">www.independa.com</a><br />
  </span><span class="Apple-style-span" style="font-size: 13px; font-weight: normal;">Industry: Technology<br />
  </span><span class="Apple-style-span" style="font-size: 13px; font-weight: normal;">Fairway Service provided: Website redesign</span>
</p>
<p>Independa, Inc. provides an integrated Telecare platform to help professional and family caregivers enable their care recipients to continue living at the residence of their choice longer more safely and more comfortably. Independa trusted Fairway to increase the functionality and appeal of their website in preparation for a major product launch, which was scheduled to take place in less than a week. Despite the extremely aggressive deadline, Fairway&#8217;s team of technical and creative experts quickly produced a newly designed website that delivered custom enhancements to support key business objectives with measurable success. <a title="independa-inc" href="http://www.fairwaytech.com/wp-content/uploads/2012/02/case-study-independa.pdf">Read the full case study</a></p>
<p>  <a name="review"></a>
</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<hr />
<h2>2011 Year in Review</h2>
<hr />
<p><img class="size-medium wp-image-2133 alignright" title="reviewmirror" src="http://www.fairwaytech.com/wp-content/uploads/2012/02/reviewmirror-300x81.jpg" alt="" width="300" height="81" /></p>
<p>  Time flies when you&#8217;re having fun. Time flies even faster when you work in a fun environment with talented people and uber-cool technology. Here at Fairway, there&#8217;s no exception – 2011 flew by, and we&#8217;d like to share some of our key highlights during the past year.</p>
<p>  <em><strong>Best of the Best</strong></em><br />
  Fairway Technologies was proud to be named one of San Diego&#8217;s 2011 Top Ten Best Places to Work by the San Diego Business Journal, in the small business category (15-49 employees). This honor follows the company&#8217;s previous recognition as a finalist in the 2010 Best Places to Work contest as well.</p>
<p>  The prestigious award recognizes organizations for their exemplary workplace environment, employer benefits and most importantly, employee satisfaction. Stand-out organizations such as Fairway were selected through the analysis of detailed data gathered from an employer questionnaire, and employee satisfaction surveys.</p>
<p>  Fairway Technologies promotes a fun and relaxed environment and encourages employees to maintain a healthy work-life balance. Fairway&#8217;s generous benefits (insert hyperlink) include five weeks of Personal Time Off. Job training and professional growth are also part of the company values.</p>
<p>  &#8220;We couldn&#8217;t be happier to be recognized as one of San Diego&#8217;s Top Ten places to work. Our employees are the heart and soul of our business, and we are especially honored that this recognition is based on their feedback. We endeavor to provide our folks with challenging work and a conspicuously awesome environment, while giving them the freedom to balance their professional and personal lives,&#8221; commented Brett Humphrey, CEO of Fairway Technologies. Humphrey continued, &#8220;Ultimately, people are what make a workplace great, and we are committed to attracting and retaining San Diego&#8217;s top software engineering and business talent.&#8221;</p>
<p>  <strong><em>Website Enhancement</em></strong><br />
  In October, we gave ourselves a make-over, launching a brand new website (insert hyperlink)! Designed and built with the latest technologies to improve visitor experience, the new website takes full advantage of HTML5 and CSS3 to optimize the web experience across multiple platforms, enhance web forms such as search boxes and text inputs, improve integration with social networking sites, and provide a richer experience. Significant improvements were also made to the navigation, content, flow and overall look and feel of the website.</p>
<p>  <strong><em>Expanding Client Base</em></strong><br />
  Despite a tough economic climate, uncertain outlook, and crowded competitive landscape, Fairway successfully added 13 new and uniquely diversified companies to its existing roster, which already boasts impressive partners such as eBay, Johnson &amp; Johnson, and Bridgepoint Education. The company attributes this achievement to a dramatically high referral and retention rate, garnered from the company&#8217;s repeated demonstration of technical expertise, quality service, and an unwavering mission to always exceed client expectations.</p>
<p>  &#8220;2011 was a tough year all around, but the company persevered and remained intently focused on what we do best,&#8221; said Brett Humphrey, CEO at Fairway Technologies. &#8220;As result, we ended the year with the highest year-over-year revenues in our history, and are prepared to continue this momentum with a diversified client base and refocused efforts within internal business development and marketing. As IT investments continue to increase, we look forward to accelerating client growth and developing strategic partnerships with complementary service and product companies.&#8221;</p>
<p>  <a name="tips"></a>
</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<hr />
<h2>Tips &amp; Tricks</h2>
<hr />
<p><img class="size-medium wp-image-2134 alignright" title="tipsandtricks" src="http://www.fairwaytech.com/wp-content/uploads/2012/02/tipsandtricks-300x81.jpg" alt="" width="300" height="81" /></p>
<p>  Have you ever wanted to know what the printed version of a file would look like, but didn&#8217;t want to actually print it out, and &#8220;print preview&#8221; was just not cutting it? Find out how…</p>
<p>  If you install the FREE version of <a title="pdf link" href="http://primopdf.com">PrimoPDF</a>, it will add a new &#8220;printer&#8221; to your print dialog:</p>
<p>  <a href="http://www.fairwaytech.com/wp-content/uploads/2012/02/Primopdf.png"><img class="alignnone size-medium wp-image-2130" title="Primopdf" src="http://www.fairwaytech.com/wp-content/uploads/2012/02/Primopdf-300x227.png" alt="" width="300" height="227" /></a></p>
<p>  If you select that option, then click &#8220;OK&#8221;, it will create a PDF of the document or web page you&#8217;re trying to print, and the PDF will look exactly like the printed version.</p>
<p>  It might not seem amazing at first, but there are a lot of web pages that look very different when printed compared to how they look on the screen. This simple trick will let you see what that printed version will look like without wasting any paper.</p>
<p>  <a name="testimonials"></a>
</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<hr />
<h2>Client Testimonials</h2>
<hr />
<p><img class="size-medium wp-image-2135 alignright" title="testimonials" src="http://www.fairwaytech.com/wp-content/uploads/2012/02/testimonials-300x81.jpg" alt="" width="300" height="81" /></p>
<p>  We measure our success through client satisfaction. <a href="http://www.fairwaytech.com/about-us/customer-testimonials/">Find out</a> what makes Fairway the preferred technology partner for today&#8217;s leading companies<a name="blog"></a>
</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<hr />
<h2>We&#39;ve Updated Our Blog!</h2>
<hr />
<p><img class="size-full wp-image-2136 alignright" title="blog" src="http://www.fairwaytech.com/wp-content/uploads/2012/02/blog.jpg" alt="" width="244" height="164" /></p>
<p>  Stop by our blog every Friday for a weekly dose of technology insight, analysis and humor.</p>
<p>  <a title="blog link" href="http://www.fairwaytech.com/category/blog/">View our latest post</a></p>
<p><a name="whitepaper"></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<hr />
<h2>FREE White Paper</h2>
<hr />
<p>&#8220;<em>Best Practices for Selecting Onshore, Nearshore, or Offshore Technology Services</em>&#8221;</p>
<p>  Although outsourcing IT and business functions has become an increasingly common global practice among enterprises looking for competitive advantage, the question still remains, &#8220;which is better: onshore, nearshore, or offshore?</p>
<p>  Fairway Technologies has developed a <a title="White Paper" href="http://www.fairwaytech.com/resources/white-papers/">FREE White Paper</a> to help companies determine which outsourcing method is best suited to their needs, titled &#8220;<a title="White Paper" href="http://www.fairwaytech.com/resources/white-papers/">Location, Location, Location: Best Practices for Selecting Onshore, Nearshore or Offshore Technology Services</a>&#8221;</p>
<p>  Developed via extensive study, research, surveys and interviews with IT professionals that are involved with sourcing and vendor management decisions, this White Paper features:<br />
  &#8211; detailed assessment of the benefits and risks related to outsourcing<br />
  &#8211; common concerns and hidden costs of outsourcing<br />
  &#8211; the ten best practices companies should be aware of when comparing onshore, nearshore, and offshore models</p>
<p>  <a name="hiring"></a>
</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<hr />
<h2>We&#39;re Hiring!</h2>
<hr />
<p><img class="size-full wp-image-2137 alignright" title="Bestplacetowork" src="http://www.fairwaytech.com/wp-content/uploads/2012/02/Bestplacetowork.gif" alt="" width="89" height="89" /></p>
<p>  Find out what makes Fairway one of the most popular technology employers in San Diego, and how you can <a title="careers" href="http://www.fairwaytech.com/careers/">join our uber-talented team of experts!</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fairwaytech.com/2012/02/fairway-q1-2012-newsletter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SOPA/PIPA: Anti-Censorship Protest or Techies Revenge?</title>
		<link>http://www.fairwaytech.com/2012/01/sopapipa-anti-censorship-protest-or-techies-revenge/</link>
		<comments>http://www.fairwaytech.com/2012/01/sopapipa-anti-censorship-protest-or-techies-revenge/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 18:26:03 +0000</pubDate>
		<dc:creator>Mike Mannion</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.fairwaytech.com/?p=2048</guid>
		<description><![CDATA[In the past week or so, we&#8217;ve seen something truly unique in the world of technology.  I&#8217;m referring to the highly effective protests of the proposed SOPA and PIPA laws [...]]]></description>
			<content:encoded><![CDATA[<p>In the past week or so, we&#8217;ve seen something truly unique in the world of technology.  I&#8217;m referring to the highly effective protests of the proposed SOPA and PIPA laws by web giants &#8220;Google&#8221; and &#8220;Wikipedia&#8221; (among many others).  If you&#8217;re not sure what SOPA and PIPA are, you should go to Google or Wikipedia and read all about it (irony intended). <span id="more-2048"></span></p>
<p>The teams at Wikipedia and Google decided that they&#8217;d had enough of the U.S. Congress&#8217;s meddling with the web, and so they decided to do something about it.  Wikipedia intentionally blacked-out their U.S. site for a day, and Google covered their iconic logo with a black &#8220;censor bar.&#8221;  In concert, hundreds of other websites hosted online petitions telling Congress to back off.  I don&#8217;t know about you, but it seemed that every other Facebook/Twitter post I saw was about SOPA/PIPA for a few days &#8211; and all of them had links to online petitions protesting the proposed laws.</p>
<p>The effect of all of this online rabble-rousing was immediate.  Those responsible for writing and sponsoring these proposed laws changed course within 48 hours, and as of right now, Congress seems to be moth–balling SOPA and PIPA.  Again, check with Wikipedia or Google for the latest…</p>
<p>So, wow.  Revenge of the Nerds, indeed.  A few well-known web sites and some web-forms now have the power to derail months of policy planning and millions of dollars of D.C. lobbying.  Even though I knew all about the protests, I went to Wikipedia that day to look up something (force of habit) &#8211; and I saw the page go black.  It was a great reminder, and I clicked-off to sign one of the petitions that I&#8217;d seen during the week.</p>
<p>The whole thing left me thinking, &#8220;Why didn&#8217;t Congress just ask Google, or Wikipedia, or Reddit (or any of the major online brands who publicly condemned SOPA and PIPA) what their thoughts were before drafting the initial laws?&#8221;</p>
<p>I don&#8217;t mean to be crass, but there was a Senator (Stevens) who thought the Internet was a &#8220;series of tubes&#8221; just a few years back  (<a href="http://en.wikipedia.org/wiki/Series_of_tubes">http://en.wikipedia.org/wiki/Series_of_tubes</a>).  Clearly, some members of Congress have issues grasping the complexities of the environment, and their role within it.  With that, perhaps it would have been wise to bring in the people who know what the heck&#8217;s going on before you try to change and govern it.</p>
<p>The more I thought about it, I realized how much this whole SOPA/PIPA mess mirrors the way many businesses work with their IT teams.  Just replace &#8220;Government&#8221; with &#8220;Management&#8221; and &#8220;Google/Wikipedia&#8221; with &#8220;Steve in IT&#8221;, and we see it all the time.</p>
<p><em>Scenario:  A Manager or Exec who really doesn&#8217;t understand how all the systems work behind the scenes conjures up a plan that will be &#8220;great for everyone.&#8221;  After announcing their plans, they bring in the IT team to implement it, and &#8220;Steve&#8221; rolls his eyes and thinks, &#8220;This is a horrible plan that will create more problems than it solves.&#8221;</em></p>
<p>For those of us who do IT for a living, we can only wonder how many &#8220;Steve&#8217;s&#8221; out there are willing to intentionally take down the company website for a day to prove their point?  Exactly.</p>
<p>I&#8217;m viewing this whole SOPA/PIPA debacle as a reminder that business and IT leaders should engage their IT team members as early as they can in the planning process.  Of course there are times when corporate strategy dictates a big shift in direction, and changes can be unpopular &#8211; but I&#8217;ve seen (and been guilty of launching &#8211; oops!) a few projects that would have been well-served by bringing the right people into the conversation much earlier.</p>
<p>Relying on &#8220;Steve in IT&#8221; to stop the company from hurting itself unwittingly is pretty risky.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fairwaytech.com/2012/01/sopapipa-anti-censorship-protest-or-techies-revenge/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Decade of Fairway</title>
		<link>http://www.fairwaytech.com/2012/01/a-decade-of-fairway/</link>
		<comments>http://www.fairwaytech.com/2012/01/a-decade-of-fairway/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 03:33:42 +0000</pubDate>
		<dc:creator>Brett Humphrey</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.fairwaytech.com/?p=2062</guid>
		<description><![CDATA[Has it really been 10 years?  It certainly doesn&#8217;t seem like it, but judging by the desolate patch of forehead I used to call a hairline it may as well [...]]]></description>
			<content:encoded><![CDATA[<p>Has it really been 10 years?  It certainly doesn&#8217;t seem like it, but judging by the desolate patch of forehead I used to call a hairline it may as well have been 50 years.</p>
<p>Things may be different today, but nothing&#8217;s really changed and I&#8217;m proud of that.  When I started Fairway 10 years ago I set out to work with only the people I wanted to work with.  The best and brightest from my own small but deeply talented nexus of engineering friends and acquaintances.  Our goal was simple; to provide the highest quality software development services in town.  I believe we&#8217;ve achieved that, and had a lot of fun and made (and brewed) a lot of memories along the way.</p>
<p><span id="more-2062"></span><a href="http://www.fairwaytech.com/wp-content/uploads/2012/01/brett.jpg"><img class="alignright size-medium wp-image-2063" title="Chief Motivational Officer" src="http://www.fairwaytech.com/wp-content/uploads/2012/01/brett-300x225.jpg" alt="" width="300" height="225" /></a>Fairway’s humble roots sprouted from my spare bedroom in 2002, where dogs and leaf blowers could not deter the first crack team of engineers who called Fairway home.  At the patient but incontrovertible insistence of my Chief Spousal Officer we soon moved our nascent operation to a 600 square-foot office space located below a public bathroom that leaked into the walls and attracted individuals generally not in need of software development services.  It was in this office that we established some of our most cherished rituals, such as <a href="http://www.thevole.com">foosball penalty ice cream cones</a>, D&amp;D night, and our now legendary brewfests.</p>
<p><a href="http://www.fairwaytech.com/wp-content/uploads/2012/01/maya.jpg"><img class="alignleft size-medium wp-image-2064" title="Chief Bacon Officer" src="http://www.fairwaytech.com/wp-content/uploads/2012/01/maya-300x225.jpg" alt="" width="300" height="225" /></a>In 2006 we moved onward and literally upward, to a larger office space above a liquor store and adjacent to a pot shop.  In retrospect this was probably not the smartest decision, and I soon feared a cataclysmic erosion of productivity that fortunately never materialized.  At least we had an ocean view; our own little sliver of La Jolla horizon huddled behind telephone wires and a conspicuously placed China Chef sign.</p>
<p>Which brings us to our present day Fairway; glittery new offices in a very respectable (at least until we arrived) office building in the idyllic heart of La Jolla village.  Interestingly (or perhaps not so), the financial district doesn’t seem to like or appreciate technologists.  Even my sign on the front door, “solicitors will be persecuted,” is met with <a title="Sign of the Times" href="http://www.fairwaytech.com/2010/11/sign-of-the-times/">chuffs of disgruntled indignation</a>.  I enjoy the contrast of being the Clampetts of the neighborhood though.  All we need is a couch on the front porch and an El Camino on blocks to really top it off.</p>
<p><a href="http://www.fairwaytech.com/wp-content/uploads/2012/01/crew.jpg"><img class="alignright size-medium wp-image-2065" title="The Crew" src="http://www.fairwaytech.com/wp-content/uploads/2012/01/crew-300x240.jpg" alt="" width="300" height="240" /></a>Over the years clients, employees, successes and failures have come and gone.  I count myself lucky to have worked with friends as both clients and employees, and am luckier to have remained so when some have chosen to move on.  We&#8217;ve spent 10 years assembling a team of amazingly talented technology gurus who also happen to be amazing people.  This coalescence of talent is the huge benefit of working with people you know well and trust, and one of the important elements of Fairway’s secret sauce.</p>
<p>In reflecting on my time at Fairway and the unfathomably fortunate path we&#8217;ve charted over the years, it&#8217;s hard to imagine doing any of it without the blood, sweat and tears of some of my closest friends and business associates.   People are what make Fairway great, and we’re lucky to work with some of the smartest, coolest (in the nerdy sense), hardest-working people in southern California.</p>
<p>So after 10 years, I guess all I have to say is thanks!  Thanks to our passionate crew of technocrats who’ve made Fairway one of <a title="Press Room" href="http://www.fairwaytech.com/about-us/press-room/">San Diego’s best (and coolest) places to work</a>, to our customers who have put their faith in us to deliver bullet proof software time after time, and to everyone else who has supported us in our endeavor to provide the highest quality software development services in town.</p>
<p>Thank you, and here’s to another 10 years!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fairwaytech.com/2012/01/a-decade-of-fairway/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Handling Session Timeout Gracefully</title>
		<link>http://www.fairwaytech.com/2012/01/handling-session-timeout-gracefully/</link>
		<comments>http://www.fairwaytech.com/2012/01/handling-session-timeout-gracefully/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 17:44:42 +0000</pubDate>
		<dc:creator>Noah Heldman</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[ASP.NET MVC 3]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Module Pattern]]></category>
		<category><![CDATA[Session]]></category>

		<guid isPermaLink="false">http://www.fairwaytech.com/?p=1915</guid>
		<description><![CDATA[Nerd-Face Have you ever been to those sites that show you a nice helpful popup to let you know that your session will expire in a few minutes?  You know, [...]]]></description>
			<content:encoded><![CDATA[<h2 class="brush:js">Nerd-Face</h2>
<p>Have you ever been to those sites that show you a nice helpful popup to let you know that your session will expire in a few minutes?  You know, the ones that show you a countdown timer, and let you Continue Your Session, or Log Out?  And if you&#8217;ve been gone so long that your session really did expire because you were feeding your <strong>nerd-face</strong>, it automatically logs you out and shows you a nice message letting you know it was only to protect you?  That it was For Your Own Good?</p>
<p>Yeah, me too!   Then I said, &#8220;I want one!&#8221; and set out to build my own.<span id="more-1915"></span></p>
<h2>Gravy</h2>
<p>Here&#8217;s what it looks like when it first pops up:</p>
<p><a href="http://www.fairwaytech.com/wp-content/uploads/2012/01/image.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://www.fairwaytech.com/wp-content/uploads/2012/01/image_thumb.png" alt="image" width="421" height="230" border="0" /></a></p>
<p>When you click &#8220;Continue&#8221;, the dialog box closes and re-establishes the session.  If you then stay idle for a while, the dialog box will reopen and the countdown starts again.</p>
<p>When you click &#8220;Log Out&#8221;, the dialog box closes, logs you out, and sends you to the home page.  It includes a return URL, so if you log in again, then Hey!, you&#8217;re right back where you were.</p>
<p>Oh, and check this out:  it dynamically updates the HTML title, which (at least on Windows) will show you the countdown in your task bar.  That&#8217;s just <strong>gravy</strong>!</p>
<p><a href="http://www.fairwaytech.com/wp-content/uploads/2012/01/image1.png"><img style="background-image: none; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://www.fairwaytech.com/wp-content/uploads/2012/01/image_thumb1.png" alt="image" width="179" height="53" border="0" /></a></p>
<p>But that&#8217;s just how I do it.  Everything in the code is easily tweakable.  And there&#8217;s just not that much code.</p>
<h2>Bottle Opener</h2>
<p>Bloggers have to make assumptions.  And sometimes the code we write has dependencies.  These are mine:</p>
<ul>
<li>I assume you are clever and funky</li>
<li>I assume you know HTML, JavaScript, and a little jQuery</li>
<li>I assume you own a <strong>bottle opener</strong></li>
<li>I assume you value quality</li>
<li>My code depends on <a href="http://www.jquery.com" target="_blank">jQuery</a> and <a href="http://jqueryui.com" target="_blank">jQuery UI</a>.  You don&#8217;t have to have them to make this approach work, but it simplifies some things.</li>
<li>My server-side code is written in <a href="http://asp.net/mvc" target="_blank">ASP.NET MVC 3</a>.  It is part of a larger framework that includes <a href="http://msdn.microsoft.com/en-us/library/yh26yfzy.aspx" target="_blank">ASP.NET Membership</a>, <a href="http://mvccontrib.codeplex.com/wikipage?title=T4MVC" target="_blank">T4MVC</a>, and <a href="http://structuremap.net/structuremap/" target="_blank">StructureMap</a> for dependency injection.  Again, you don&#8217;t have to have these, but you will need some sort of back-end that supports sessions.  Otherwise, <em>why are you here?  Were you just searching for &#8220;gravy&#8221; and found this?</em></li>
<li>I assume you like pumpkin pie</li>
</ul>
<p>But really, I wish I didn’t have to assume and depend so much.  But where I do, I’ll try to at least link to info that will be helpful.</p>
<h2>Gnarly Diamond</h2>
<p>The magic in this code comes from the power of JavaScript, which is a dark and dangerous art in the wrong hands, and some kind of <strong>gnarly diamond</strong> if you&#8217;re <a href="http://javascript.crockford.com/" target="_blank">Douglas Crockford</a>.  <a href="http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742" target="_blank">His book</a> is awesome, very dense, and makes a whole lot of assumptions about its audience.</p>
<p>My code follows the <a href="http://www.codeproject.com/KB/scripting/ModulePattern.aspx" target="_blank">Module Pattern</a> (invented by Mr. Crockford), which minimizes global variables, and allows you to decide what in your code is public and private.  As for the countdown timer, that&#8217;s just those old stand-bys <a href="http://www.w3schools.com/jsref/met_win_settimeout.asp" target="_blank">setTimeout(functionName, milliseconds)</a>, which waits a specified number of milliseconds before calling your function, and <a href="http://www.w3schools.com/jsref/met_win_setinterval.asp" target="_blank">setInterval(functionName, milliseconds)</a>, which calls your function <em>relentlessly</em> every [milliseconds] milliseconds.</p>
<h2>Viola!</h2>
<p>At this point, you are probably itchy to see some code.  So then, <a href="http://public.wsu.edu/~brians/errors/voila.html" target="_blank">viola</a>!  Let’s build up the JavaScript SessionManager module step by step:</p>
<h3>Structure</h3>
<p>First, here’s the basic JavaScript structure we’ll be using.  Lots of pseudocode here, but it should give the basic idea.  If you read the comments, you might learn a thing or two.</p>
<pre class="brush: js;gutter: false;">var SessionManager = function() {
    // Private Variables will go here...

    // Private Functions

    // endSession: Called when the session expires
    var endSession = function() {
        // Close the dialog
        // Redirect to the "expire" URL
    };

    // displayCountdown: Wrapper for updating the countdown display every second
    var displayCountdown = function() {

        // Inner countdown function, which we can call right away, then
        // call every second (setInterval waits before its first function call)
        var countdown = function() {
            // Get countdown minutes and seconds
            // Update the HTML title
            // Update the countdown display
            // If the countdown timer reaches zero,
            //   Update the HTML title to "Session Expired"
            //   Call the endSession() function

            // Decrement the counter
        };

        // Call the countdown() function immediately
        countdown();

        // Call the countdown() function every second thereafter
        window.setInterval(countdown, 1000);
    };

    // promptToExtendSession: Display the jQuery dialog
    // and kick off the countdown timer
    var promptToExtendSession = function() {
        // Build up a jQuery dialog
        // with buttons to "Continue" (extend session)
        // and "Log Out" (end session)

        displayCountdown();
    };

    // startSessionManager: Calls promptToExtendSession() after 5 minutes
    var startSessionManager = function() {
        window.setTimeout(promptToExtendSession, 300000);
    };

    // refreshSession: Refresh the session
    var refreshSession = function() {
        // Refresh the session using the "extend" session url

        // Restart the countdown to the popup
        startSessionManager();
    };

    // Public Functions

    // These will be the only public methods available to outside callers
    return {
        // Start the session (call using SessionManager.start())
        start: function() {
            startSessionManager();
        },

        // Extend the session (call using SessionManager.extend())
        extend: function() {
            refreshSession();
        }
    };
}(); // See those parentheses?  They will execute this function immediately and
     // return the anonymous object with two public functions (start and extend)

// And now, we can call our public method to plant the popup seed!
SessionManager.start();</pre>
<h3>Fill &#8216;Er Up</h3>
<p>Okay, so that’s the basic layout. Let’s fill in the blanks.  Here we’ll add our private variables, our jQuery Dialog with real live countdown display, and implement the rest of our functions.</p>
<p>I’ll highlight some of the neato stuff in the comments.</p>
<pre class="brush: js;gutter: false;">var SessionManager = function() {
    // Private Variables
    var sessionTimeoutSeconds = 20 * 60,                                 // Session timeout is 20 minutes
        promptSeconds = 5 * 60,                                          // Prompt shows for 5 minutes
        secondsBeforePrompt = sessionTimeoutSeconds - countdownSeconds,  // 15 minutes until prompt pops up
        $dlg,                                                            // jQuery Dialog
        displayCountdownIntervalId,                                      // setInterval id, for clean up
        promptToExtendSessionTimeoutId,                                  // setTimeout id, for clean up
        originalTitle = document.title,                                  // grab the HTML &lt;title&gt; (for later)
        extendSessionUrl = '/Session/Extend',                            // URL to call when extending session
        expireSessionUrl = '/Session/Expire';                            // URL to call when expiring session

    // Private Functions
    var endSession = function() {
        $dlg.dialog('close');                                            // Close the jQuery Dialog
        location.href = expireSessionUrl;                                // Redirect to the expiration URL
    };

    var displayCountdown = function() {
        var countdown = function() {
            var cd = new Date(count * 1000),                             // Returns milliseconds since 01/01/70
                minutes = cd.getUTCMinutes(),                            // Grab the minutes
                seconds = cd.getUTCSeconds();                            // Grab the seconds

            document.title = 'Expire in ' + minutes + ':' + seconds;     // Update the HTML title
            $('#sm-countdown').html(minutes + ':' + seconds);            // Update the countdown display
            if (count === 0) {                                           // If we reached zero,
                document.title = 'Session Expired';                      // update the HTML title
                endSession();                                            // and end the session
            }
            count--;
        };
        countdown();                                                      // Call the function once
        displayCountdownIntervalId = window.setInterval(countdown, 1000); // Call the function every second
    };

    var promptToExtendSession = function() {
        $dlg = $('#sm-countdown-dialog').dialog({                         // See the HTML below
            title: 'Session Timeout Warning',
            buttons: {
                'Continue': function() {
                    $(this).dialog('close');                              // Close the dialog
                    refreshSession();                                     // Refresh the session
                    document.title = originalTitle;                       // Change the title back
                },
                'Log Out': function() {
                    endSession(false);                                    // End the session
                }
            }
        });
        count = promptSeconds;                                            // Set our counter
        displayCountdown();                                               // Show that dialog!
    };

    var refreshSession = function() {
        window.clearInterval(displayCountdownIntervalId);                 // Stop calling countdown so
                                                                          // we can start a new timer
        var img = new Image(1, 1);                                        // Create a tiny image
        img.src = extendSessionUrl;                                       // and set its source to the
                                                                          // extend session url (like
                                                                          // poor man's Ajax!)
        window.clearTimeout(promptToExtendSessionTimeoutId);              // Clear the timeout so we can...
        startSessionManager();                                            // ... start it all over!
    };

    // Just a private implementation to actually start our countdown before popup
    var startSessionManager = function() {
        promptToExtendSessionTimeoutId = window.setTimeout(promptToExtendSession, secondsBeforePrompt * 1000);
    };

    // Public Functions
    return {
        start: function() {
            startSessionManager();
        },

        extend: function() {
            refreshSession();
        }
    };
}();</pre>
<h3>Two Monologues Do Not Make a Dialog</h3>
<p>Here’s the HTML for the dialog:</p>
<pre class="brush: xml;gutter: false;">&lt;div id="sm-countdown-dialog" style="display:none"&gt;
    &lt;p&gt;Your session will expire in:&lt;/p&gt;
    &lt;div id="sm-countdown"&gt;&lt;!-- Placeholder for dynamic countdown --&gt;&lt;/div&gt;
    &lt;p&gt;Click "Continue" to keep working, or "Log Out" if you are finished.&lt;/p&gt;
&lt;/div&gt;</pre>
<h3>Impatience</h3>
<p>I also added support for testing this when you don&#8217;t want to wait 15 minutes for your popup to show up, and you don&#8217;t want to keep changing your session timeout on the back end and restarting your server&#8230;</p>
<p>It uses a couple query string variables to set the total session timeout (smt) and the number of seconds before the countdown dialog appears (smc). You can use it like this on any page where the JavaScript exists:</p>
<pre class="brush:xml;gutter: false;">http://flumko.me/pork/edit?smt=30&amp;smc=20</pre>
<p>What that does is show the dialog after 20 seconds, and it will start a 10 second countdown before it expires the session.</p>
<h3>Helpy Helperton</h3>
<p>Things like getting a query string and padding a string are really utilities, and should be relegated to their own modules.  To support this, I&#8217;m adding a new module called HtmlHelpers, so we can grab the query string value easily, then I just use that if provided, otherwise I fall back to the default (that&#8217;s the coolness of the || operator):</p>
<pre class="brush:js;gutter: false;">// HtmlHelpers Module
// Call by using HtmlHelpers.getQueryStringValue("myname");
var HtmlHelpers = function() {
    return {
        // Based on http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
        getQueryStringValue: function(name) {
            var match = RegExp('[?&amp;]' + name + '=([^&amp;]*)').exec(window.location.search);
            return match &amp;&amp; decodeURIComponent(match[1].replace( /\+/g , ' '));
        }
    };
}();

var SessionManager = function() {
    // Private Variables
    var countdownSeconds = HtmlHelpers.getQueryStringValue('smc') || 300,
        sessionTimeoutSeconds = HtmlHelpers.getQueryStringValue('smt') || 1200;

    // Lots of code deleted here...
}();</pre>
<p>I do something similar with another module called StringHelpers, which adds a padLeft function to pretty up our countdown display:</p>
<pre class="brush:js;gutter: false;">// StringHelpers Module
// Call by using StringHelpers.padLeft("1", "000");
var StringHelpers = function() {
    return {
        // Pad string using padMask.  string '1' with padMask '000' will produce '001'.
        padLeft: function(string, padMask) {
            string = '' + string; // If it ain't a string, make it one (ye olde type coercion!)
            return (padMask.substr(0, (padMask.length - string.length)) + string);
        }
    };
}();</pre>
<h3>The Final Countdown</h3>
<p>So, here&#8217;s our final JavaScript code, incorporating everything we’ve seen so far, and a little bit more.  Super shiny!</p>
<pre class="brush:js;gutter: false;">&lt;!-- Countdown Dialog HTML --&gt;
&lt;div id="sm-countdown-dialog" style="display:none"&gt;
    &lt;p&gt;Your session will expire in:&lt;/p&gt;
    &lt;div id="sm-countdown"&gt;&lt;!-- Placeholder for dynamic countdown --&gt;&lt;/div&gt;
    &lt;p&gt;Click "Continue" to keep working, or "Log Out" if you are finished.&lt;/p&gt;
&lt;/div&gt;

&lt;script type="text/javascript"&gt;
$(function() { // Wrap it all in jQuery documentReady because we use jQuery UI Dialog
    // HtmlHelpers Module
    // Call by using HtmlHelpers.getQueryStringValue("myname");
    var HtmlHelpers = function() {
        return {
            // Based on http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
            getQueryStringValue: function(name) {
                var match = RegExp('[?&amp;]' + name + '=([^&amp;]*)').exec(window.location.search);
                return match &amp;&amp; decodeURIComponent(match[1].replace( /\+/g , ' '));
            }
        };
    }();

    // StringHelpers Module
    // Call by using StringHelpers.padLeft("1", "000");
    var StringHelpers = function() {
        return {
            // Pad string using padMask.  string '1' with padMask '000' will produce '001'.
            padLeft: function(string, padMask) {
                string = '' + string;
                return (padMask.substr(0, (padMask.length - string.length)) + string);
            }
        };
    }();

    // SessionManager Module
    var SessionManager = function() {
        // NOTE:  I use @Session.Timeout here, which is Razor syntax, and I am pulling that value
        //        right from the ASP.NET MVC Session variable.  Dangerous!  Reckless!  Awesome-sauce!
        //        You can just hard-code your timeout here if you feel like it.  But I might cry.
        var sessionTimeoutSeconds = HtmlHelpers.getQueryStringValue('smt') || (@Session.Timeout * 60),
            countdownSeconds = HtmlHelpers.getQueryStringValue('smc') || 300,
            secondsBeforePrompt = sessionTimeoutSeconds - countdownSeconds,
            $dlg,
            displayCountdownIntervalId,
            promptToExtendSessionTimeoutId,
            originalTitle = document.title,
            count = countdownSeconds,
            extendSessionUrl = '/Session/Extend',
            expireSessionUrl = '/Session/Expire?returnUrl=' + location.pathname;

        var endSession = function() {
            $dlg.dialog('close');
            location.href = expireSessionUrl;
        };

        var displayCountdown = function() {
            var countdown = function() {
                var cd = new Date(count * 1000),
                    minutes = cd.getUTCMinutes(),
                    seconds = cd.getUTCSeconds(),
                    minutesDisplay = minutes === 1 ? '1 minute ' : minutes === 0 ? '' : minutes + ' minutes ',
                    secondsDisplay = seconds === 1 ? '1 second' : seconds + ' seconds',
                    cdDisplay = minutesDisplay + secondsDisplay;

                document.title = 'Expire in ' +
                    StringHelpers.padLeft(minutes, '00') + ':' +
                        StringHelpers.padLeft(seconds, '00');
                $('#sm-countdown').html(cdDisplay);
                if (count === 0) {
                    document.title = 'Session Expired';
                    endSession();
                }
                count--;
            };
            countdown();
            displayCountdownIntervalId = window.setInterval(countdown, 1000);
        };

        var promptToExtendSession = function() {
            $dlg = $('#sm-countdown-dialog')
                .dialog({
                    title: 'Session Timeout Warning',
                    height: 205,
                    width: 250,
                    bgiframe: true,
                    modal: true,
                    buttons: {
                        'Continue': function() {
                            $(this).dialog('close');
                            refreshSession();
                            document.title = originalTitle;
                        },
                        'Log Out': function() {
                            endSession(false);
                        }
                    }
                });
            count = countdownSeconds;
            displayCountdown();
        };

        var refreshSession = function() {
            window.clearInterval(displayCountdownIntervalId);
            var img = new Image(1, 1);
            img.src = extendSessionUrl;
            window.clearTimeout(promptToExtendSessionTimeoutId);
            startSessionManager();
        };

        var startSessionManager = function() {
            promptToExtendSessionTimeoutId =
                window.setTimeout(promptToExtendSession, secondsBeforePrompt * 1000);
        };

        // Public Functions
        return {
            start: function() {
                startSessionManager();
            },

            extend: function() {
                refreshSession();
            }
        };
    }();

    SessionManager.start();

    // Whenever an input changes, extend the session,
    // since we know the user is interacting with the site.
    $(':input').change(function() {
        SessionManager.extend();
    });
});
&lt;/script&gt;</pre>
<h2>Honey Badger</h2>
<p><em>But Noah, your variable names are comically long and descriptive!</em></p>
<p>You&#8217;re right. I love that. But it may make you angrier than a <strong>honey badger</strong>, so please allow me to talk you down.</p>
<p>Because all of my verbose variable names are truly private inside the module, your favorite minifier/compressor can safely mangle those variable names to a single letter, reducing client load by eleventy billion percent.  Huzzah for the shopkeep!</p>
<h2>My Back End Sings</h2>
<p>Fantastic. All this JavaScript, and nothing on the server side to make it work. Let&#8217;s fix that.</p>
<p>We are using ASP.NET MVC 3 on my current project, so here&#8217;s how I made <strong>my back end sing</strong>. First, we have our two urls from the JavaScript:</p>
<pre class="brush:js;gutter: false;">var extendSessionUrl = '/Session/Extend',
    expireSessionUrl = '/Session/Expire';</pre>
<p>So we&#8217;ll add an ASP.NET MVC 3 SessionController with Extend and Expire actions, using the SeeSharp language all the kids are talking about:</p>
<pre class="brush:csharp;gutter: false;">using System.Web.Mvc;

namespace Fairway.Web.Controllers
{
    public partial class SessionController : BaseController
    {
        private readonly IFormsAuthenticationService _formsAuthenticationService;

        public SessionController(IFormsAuthenticationService formsAuthenticationService)
        {
            _formsAuthenticationService = formsAuthenticationService;
        }

        // This is used from JavaScript to re-establish the user's session
        [Authorize]
        [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] // Never Cache
        public virtual ActionResult Extend()
        {
            // Re-establish the session timeout
            Session.Timeout = 20;
            return new EmptyResult();
        }

        [Authorize]
        public virtual ActionResult Expire(string returnUrl)
        {
            _formsAuthenticationService.SignOut();

            // Redirect to the role-specified "session expired" view
            // This needs to be a separate Action because we need to issue a separate
            // request once the session has been abandoned in order to have the correct
            // context (that the user is logged out).
            return RedirectToAction(MVC.Session.SessionExpired(returnUrl));
        }

        public virtual ActionResult SessionExpired(string returnUrl)
        {
            ViewData["ReturnUrl"] = returnUrl;

            return View(MVC.Account.Views.SessionExpired);
        }
    }
}</pre>
<p>Now we can respond to those calls from JavaScript! The key points here are:</p>
<ul>
<li>The Extend() method cannot be cached, or your session may not refresh correctly</li>
<li>The Expire() method signs the user out, but has to redirect to a new action, which will know that the user is logged out</li>
</ul>
<h2>Nerd-Glue</h2>
<p>We’ve got some JavaScript.  We’ve got some HTML.  We’ve got some back end.  How do you stick it all together in a useful way?  With <strong>nerd-glue</strong>, naturally!</p>
<ol>
<li>Add the HTML and JavaScript from “The Final Countdown” (above) to the bottom of every page in your site where you want the session timeout logic
<ol style="list-style-type: lower-alpha;">
<li>Of course, you should probably put it in an include, or a partial view, and then drop it in your site layout, master page, or equivalent</li>
<li>You should probably also wrap the JavaScript and HTML code in logic that ensures that the request is coming from an authenticated user with an active session</li>
</ol>
</li>
<li>Add the server-side code to handle the “extend” and “expire” urls</li>
<li>I guess that’s it</li>
</ol>
<h2>Imperial</h2>
<p>I&#8217;ve told you a few things about my approach for gracefully handling session timeout.  Here are some things I haven&#8217;t told you:</p>
<ul>
<li>It&#8217;s not a jQuery plugin, but could be (shameless plug for <a title="FlexBox" href="http://www.fairwaytech.com/flexbox/">FlexBox plugin</a>!)</li>
<li>My favorite color is mercury</li>
<li>The code could use more cleanup (but most code could)</li>
<li>Hess Brewing makes a mean Rye <strong>Imperial</strong> Stout</li>
</ul>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fairwaytech.com/2012/01/handling-session-timeout-gracefully/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generating Software Diagrams</title>
		<link>http://www.fairwaytech.com/2012/01/generating-software-diagrams/</link>
		<comments>http://www.fairwaytech.com/2012/01/generating-software-diagrams/#comments</comments>
		<pubDate>Fri, 13 Jan 2012 22:18:55 +0000</pubDate>
		<dc:creator>Ray Mitchell</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Diagrams]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ray Mitchell]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.fairwaytech.com/?p=1775</guid>
		<description><![CDATA[Introduction In this post I&#8217;m going to describe how to automatically generate diagrams from source code.  I&#8217;ve found that diagrams provide the quickest path to understanding how a piece of [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>In this post I&#8217;m going to describe how to automatically generate diagrams from source code.  I&#8217;ve found that diagrams provide the quickest path to understanding how a piece of software works.  Diagrams also provide a great means to discuss software at a high level.  They&#8217;ve proven invaluable in the software development and software consulting work I&#8217;ve done.</p>
<p>Often diagrams are created by hand.  Unfortunately hand-crafted diagrams are prone to manual mistakes and falling out-of-sync as the source code changes.  Many IDE&#8217;s can automatically generate diagrams from source code on the fly, but sometimes your IDE doesn&#8217;t provide the diagrams or options you want.  Being able to generate your own diagrams will give you the ability to create exactly what you need when you need it.<span id="more-1775"></span></p>
<h3>A Diagram is Worth a Thousand Lines of Code</h3>
<p>Before we talk about automatically generating diagrams, let&#8217;s consider an example that demonstrates the value of diagrams.</p>
<p>When I first encounter a piece of software I find it useful to identify all type dependencies.  Suppose we&#8217;d like to identify all user-defined type dependencies (ignoring the built-in types) in this snippet of java code:</p>
<pre class="brush:java">// File:  Car.java
import java.util.List;

public class Car
{
	private final String make;
	private final String model;
	private final Engine engine;
	private final List&lt;Tire&gt; tires;

	public String getMake() {
		return make;
	}

	public Car(String make, String model, Engine engine, List&lt;Tire&gt; tires) {
		this.make = make;
		this.model = model;
		this.engine = engine;
		this.tires = tires;
	}

	public String getModel() {
		return model;
	}

	public List&lt;Tire&gt; getTires() {
		return tires;
	}

	public Engine getEngine() {
		return engine;
	}
}

// Engine.java
public class Engine
{
	private final double cubicInches;
	private final double horsePower;

	public Engine(double cubicInches, double horsePower) {
		this.cubicInches = cubicInches;
		this.horsePower = horsePower;
	}

	public double getCubicInches() {
		return cubicInches;
	}

	public double getHorsePower() {
		return horsePower;
	}
}

// Tire.java
public class Tire
{
	private final double maxLoadLbs;
	private final double maxInflationPsi;

	public Tire(double maxLoadLbs, double maxInflationPsi) {
		super();
		this.maxLoadLbs = maxLoadLbs;
		this.maxInflationPsi = maxInflationPsi;
	}

	public double getMaxLoadLbs() {
		return maxLoadLbs;
	}

	public double getMaxInflationPsi() {
		return maxInflationPsi;
	}
}</pre>
<p>This is a relatively short sample of code, yet it can take awhile to see that type Car depends on type Engine and type Tire.  What if there were 10&#8242;s or even 100&#8242;s of types?  It&#8217;s much easier to identify the type dependencies by looking at a diagram:</p>
<p style="padding-left: 30px;"><a href="http://www.fairwaytech.com/wp-content/uploads/2012/01/diagram.png"><img class="alignnone size-full wp-image-1804" src="http://www.fairwaytech.com/wp-content/uploads/2012/01/diagram.png" alt="" width="200" height="155" /></a></p>
<h3>A Tool to Generate Diagrams</h3>
<p>I created the previous diagram manually (we&#8217;ll see how to automate this soon) using a command-line tool named &#8220;dot&#8221; which is part of the <a href="http://www.graphviz.org/" target="_blank">GraphViz</a> open-source <a href="http://en.wikipedia.org/wiki/Graph_%28data_structure%29">graph</a> visualization software package.  The dot tool reads in a graph definition file (a text file) and produces an image file (e.g. jpeg, png, svg) containing the corresponding graph diagram.  In this case I chose png as the target format.</p>
<p>To generate the diagram I first created a text file named &#8220;TypeDependencies.dot&#8221; with the following contents:</p>
<pre class="brush:java">digraph TypeDependencies {
    Car -&gt; Engine
    Car -&gt; Tire
}</pre>
<p>The first line states that we&#8217;re defining a directed graph (in a directed graph edges come out of a source node and go into a destination node).  The next two lines define edges going from the Car node to the Engine node and from the Car node to the Tire node.</p>
<p>Next, I ran the the following command in the directory containing the TypeDependencies.dot file (for this to work GraphViz must be installed and the dot tool must be on your path):</p>
<pre class="brush:java">dot -Tpng TypeDependencies.dot -oTypeDependencies.png</pre>
<p>This produced the image file &#8220;TypeDependencies.png&#8221; (the diagram image shown earlier).</p>
<h3>Automating the Process</h3>
<p>To fully automate the creation of our diagram we must automatically generate the graph definition file and pass it to the dot tool.  We&#8217;ll write a script that inspects the source code for type dependencies, generates the graph definition file, and invokes the dot tool to generate the diagram.  All steps will be automated.</p>
<p>I&#8217;ve chosen python as the script language but any language would work.  This script is purposely kept simple to provide a straightforward demonstration of extracting information from source code and generating a diagram.  A robust (and more general purpose) implementation would require using a <a href="http://en.wikipedia.org/wiki/Parser">language parser</a> to properly handle the source language grammar or even better <a href="http://en.wikipedia.org/wiki/Reflection_%28computer_programming%29">reflection </a>if supported by the source language.</p>
<p>Here is the python script:</p>
<pre class="brush:py">#!/usr/bin/python
# Usage:  gen-diagram.py source-directory diagram-name
import os
import re
import subprocess
import sys

# Capture command-line arguments
SOURCE_DIRECTORY = sys.argv[1]
DIAGRAM_NAME = sys.argv[2]

# Extract type dependencies from all java files in all subdirectories
dependencies = {}
for dirpath, dirnames, filenames in os.walk(SOURCE_DIRECTORY):
    for filename in filenames:
        if filename.endswith(".java"):
            file = open(os.path.join(dirpath, filename))
            className = None

            # For each line in file
            while True:
                # EOF
                line = file.readline()
                if not line:
                    break

                # Class definition
                m = re.match("^.*class\s+(\w*).*$", line)
                if m:
                    className = m.group(1)
                    dependencies[className] = []

                # Field definition
                if not className is None:
                    # Regular field
                    m = re.match("^.*private.*\s+(\w+)\s+\w+\s*;\s+$", line)
                    if m:
                        dependencies[className].append(m.group(1))
                    # Generic field
                    m = re.match("^.*private.*&lt;\s*(\w+)\s*&gt;.*$", line)
                    if m:
                        dependencies[className].append(m.group(1))

            file.close()

# Generate graph edges for all user-defined types
edges = []
for className in dependencies:
    for fieldType in dependencies[className]:
        if fieldType in dependencies:
            edges.append("%s -&gt; %s" % (className, fieldType))

# Write the graph definition file
file = open(DIAGRAM_NAME + ".dot", "w")
file.write("digraph %s {\n" % (DIAGRAM_NAME))
for edge in edges:
    file.write("\t%s\n" % (edge))
file.write("}")
file.close()

# Generate the diagram (requires GraphViz dot tool be installed and in path)
subprocess.Popen(["dot", "-Tpng", DIAGRAM_NAME + ".dot",
        "-o" + DIAGRAM_NAME + ".png"])</pre>
<p>This script takes the source directory and diagram name as command line arguments and produces a dot file containing the diagram definition and a png file containing the generated diagram.</p>
<p>If your java source code is located at c:\source then running the script with the following options:</p>
<pre class="brush:java">gen-diagram.py c:\source TypeDependencies</pre>
<p>will produce the files TypeDependencies.dot and TypeDependencies.png.</p>
<h3>Conclusion</h3>
<p>With the techniques described in this article you can generate diagrams from a wide variety of sources.  I&#8217;ve used these techniques to generate multiple diagram types (including UML class diagrams) from XML, C#, and Java code.  There&#8217;s no reason to limit yourself to generating diagrams from source code.  Diagrams can be generated from any source that is in a parsable text format (or in reflectable binary format).  Company org charts, database diagrams, and network diagrams would all be straightforward to automatically generate given the proper input.</p>
<p>The diagrams themselves can also be highly customized.  GraphViz provides a wide variety of options allowing you to control the arrowheads, edge labels, node shapes, and node and edge colors shown in the generated diagrams.  I encourage you to browse the GraphViz site (especially the gallery of sample diagrams) to get a feel for the options available.</p>
<p>Automating GraphViz has become a key component in my software development toolkit.  I hope you find it useful as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fairwaytech.com/2012/01/generating-software-diagrams/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Audacity of Nope</title>
		<link>http://www.fairwaytech.com/2011/10/the-audacity-of-nope/</link>
		<comments>http://www.fairwaytech.com/2011/10/the-audacity-of-nope/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 22:03:48 +0000</pubDate>
		<dc:creator>Brett Humphrey</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://fairwaytech.com/?p=1623</guid>
		<description><![CDATA[The technology industry and indeed the world lost a titan of the modern technology pantheon yesterday.  Steve Jobs was a pioneer and an innovator and a progressive thought leader, but [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://fairwaytech.com/wp-content/uploads/2011/10/sad_mac_icon_bigger.jpg"><img class="size-full wp-image-1624 alignleft" title="Sad Mac" src="http://fairwaytech.com/wp-content/uploads/2011/10/sad_mac_icon_bigger.jpg" alt="Sad Mac" width="73" height="73" /></a>The technology industry and indeed the world lost a titan of the modern technology pantheon yesterday.  Steve Jobs was a pioneer and an innovator and a progressive thought leader, but what may have been greatest about Jobs in my view was his audacious, fervent and oftentimes smug ability to say No.<br />
<span id="more-1623"></span><br />
Nope is what makes Apple great.  Adobe Flash?  Nope.  Doodads, fads, and support for legacy standards?  Hell no.  People hate it, but it&#8217;s like taking your medicine, you&#8217;ll thank Jobs for it later.  Thank you, Steve.</p>
<p>Jobs has said that &#8220;[innovation] comes from saying no to 1,000 things to make sure we don’t get on the wrong track or try to do too much.&#8221;  Maybe Steve Jobs&#8217; real genius was his willingness to systematically squash 1,000 less-than-awesome ideas?  He was the arch-decider at Apple after all, and the self-described gravitational force that kept the vision intact and focused.  Apple&#8217;s restraint and devout focus on simplicity and elegance has made their products supremely cool &#8211; evident, if not digestible to all but the most rabid Apple-haters out there.</p>
<p>To achieve simplicity you need a singular vision.  Jobs provided that.</p>
<p>Jobs was proof that the more you are a megalomaniacal micro-managing autocrat the easier it is to enforce a progressive vision and keep it cohesive.  Without Jobs I worry that Apple will struggle to maintain their zeal for simplicity and elegance in design, and irrevocably dilute their key market differentiator.  Tim Cook may be a micro-managing despot like Jobs, but he seems to lack Jobs&#8217; laser-focus, vision and perhaps more importantly his audacity for No.</p>
<p>Apple nay-sayers have to acknowledge Jobs&#8217; greatness, and I have a great deal of respect for a genius born of an innate sense of focus more than anything else.  Voodoo-warlock prognosticator?  Maybe not.  But genius of focus, definitely.</p>
<p>It seems to me that product companies may be best served by megalomaniacs who cultivate their focus with an iron fist, while services companies (such as Fairway) may benefit from narcissists who can charm their customers with their charisma.  Jobs seemed to be both really: secretive, powerful, perfection-obsessed, and sometimes obstinate, but also a showman huckster and cult-inspiring front-man for the Apple indoctrinated.</p>
<p>And what will become of the ubiquitous and cultish group of technorati sitting outside their adopted Starbucks habitat, listening to their iPods, working diligently on fan-fic short stories on the latest model MacBook Pro?  Apple fan-boys need a godlike icon to resolve their cognitive dissonance for Apple&#8217;s short-comings and armor themselves against heretical Microsoft/Google counter-culturists griping about Apple&#8217;s products and policies.  What will happen without Jobs to shield and shepherd the Apple faithful?</p>
<p>It&#8217;s kind of sad to think about, really.  Now I&#8217;m sad.  Not just about Jobs&#8217; unfairly-early departure, I&#8217;m also sad that something that was cool has less of a chance of continuing to be cool.</p>
<p>Steve, the world will miss your audaciousness, singular vision and uncompromising Nope.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fairwaytech.com/2011/10/the-audacity-of-nope/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Origins of Culture</title>
		<link>http://www.fairwaytech.com/2011/08/the-origins-of-culture-2/</link>
		<comments>http://www.fairwaytech.com/2011/08/the-origins-of-culture-2/#comments</comments>
		<pubDate>Mon, 15 Aug 2011 22:00:41 +0000</pubDate>
		<dc:creator>Brett Humphrey</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://69.89.31.239/~fairwayt/fairway/?p=1276</guid>
		<description><![CDATA[Where does your company&#8217;s culture come from? I had an interesting conversation with our HR manager the other day about how our company&#8217;s culture was created and cultivated. She claimed [...]]]></description>
			<content:encoded><![CDATA[<p>Where does your company&#8217;s culture come from?</p>
<p>I had an interesting conversation with our HR manager the other day about how our company&#8217;s culture was created and cultivated. She claimed that culture begins and ends with upper management — that culture was purely a function of the top brass, whose direction determined how it evolved. This struck me as odd, and for someone I rarely disagree with I was surprised to hear her say this so matter-of-factly. I think I always assumed that at most companies the management team was at best an well-intentioned impedance to a genuinely enjoyable company culture. Sure, the brass can institute corporate-mandated fun or other culture-rific policies, but it is my belief that the actual core culture of a company — it&#8217;s soul — grows more organically based on the personalities of the people who work there.<br />
<span id="more-1276"></span><br />
We&#8217;ve all been to those painful enforced-fun team events where the office cheerleaders (often HR) enthusiastically attempt to engage the other 99% — the cynical, jaded or otherwise disinterested clockpunchers. It&#8217;s a sad affair, but how did their company&#8217;s culture get to such a lowly state? When did their company&#8217;s soul get ripped out and put on a spike &#8211; a shell mockery of management&#8217;s genuine but perhaps misguided intentions?</p>
<p>I think it&#8217;s because you can&#8217;t mandate culture. Management can&#8217;t be responsible for creating fun, or inventing culture &#8211; at least not directly. Maybe the best management can do to foster a healthy culture is remove obstacles for people who want to pursue their interests and be themselves at work &#8211; to provide a venue for people to create their own culture? If the true origin of culture comes from the people that live it then naturally only their own passions will promote a lasting healthy culture, regardless of what management tries to implement.</p>
<p>At Fairway we have a rather informal and casual culture; people have lots of different interests and are free to pursue them. One aspect that I really enjoy is our lunch culture. It&#8217;s good to take a break, get out in the sun, and enjoy each other&#8217;s company. That&#8217;s easier said than done for a lot of companies, particularly those located in some office park hellscape, but even so, having a few nice neighborhood restaurants nearby helps. For managers interested in their company&#8217;s culture, lunch is one of the best places to take its pulse. Do you notice people sitting around sullen and silent, wary of their normal urge to take cynical shots at the company or complain about their co-workers (or you)? Or do they laugh and talk about their diverse (or in our case, uniformly nerdy) array of interests and passions? Employee chatter is culture&#8217;s secret-sauce, and knowing what&#8217;s going on over broken bread is important if you hope to understand or influence your company&#8217;s culture.</p>
<p>But, I digress. It may be a little scary for management to think that they have little control over their own corporate culture. But total control over company culture is an illusion, which is my point. Sure, you can tend the soil, sprinkle some water, even rip out some weeds, but you&#8217;ll never be able to create the seeds.</p>
<p>So what do you think? Where does your company&#8217;s culture come from?</p>
<p>Management or the masses? Trickle-down or grass roots?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fairwaytech.com/2011/08/the-origins-of-culture-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Scrum Overview in Prezi &#8211; not another boring slideshow</title>
		<link>http://www.fairwaytech.com/2011/07/scrum-overview-in-prezi-not-another-boring-slideshow/</link>
		<comments>http://www.fairwaytech.com/2011/07/scrum-overview-in-prezi-not-another-boring-slideshow/#comments</comments>
		<pubDate>Thu, 07 Jul 2011 00:00:19 +0000</pubDate>
		<dc:creator>Leslie Weller</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://69.89.31.239/~fairwayt/fairway/?p=691</guid>
		<description><![CDATA[I&#8217;ve wanted to create something on the Prezi platform ever since I saw it a few months ago. It seems like a really cool interactive approach to presentations that breaks [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve wanted to create something on the <a href="http://prezi.com" target="_blank">Prezi platform</a> ever since I saw it a few months ago. It seems like a really cool interactive approach to presentations that breaks away from the PowerPoint mold.</p>
<p>After listening to Noah Heldman&#8217;s Code Brew this past Monday on scrum and Agile project management methodology, I thought it would be fun to turn his thoughts (and word doc) into a Prezi.<br />
<span id="more-1437"></span><br />
I&#8217;m just barely getting in the shallow end of the pool when it comes to swimming in the sea of Prezi. But I&#8217;m enchanted with its sense of flow and movement; not only for viewing, but also for creating in it as well.</p>
<p>I like the circle menu choices in the left hand corner that spins around as you pick whether to write, change colors, insert images/video, group items, or create a flow to your presentation.</p>
<p>I thought it very honest of Prezi to warn against creating too much movement. They said that too much zooming in and out and twisting could give people headaches or feelings of motion sickness.</p>
<p>I had to chuckle. Their warning kind of reminded me of pharmaceutical drug ads that proclaim to cure one ailment at the risk of giving you a multitude of other maladies.</p>
<p>It&#8217;s not that I don&#8217;t like PowerPoint or anything, in fact, my MBA &#8216;mates dubbed me &#8220;PowerPoint Queen&#8221; or something equally nerdy. But it&#8217;s nice to have a new, fresh alternative to presenting ideas visually.</p>
<p><strong>Looking for a scrum overview?</strong></p>
<ol>
<li>Yes, check out the <a href="http://prezi.com/rpg5ocdv2qh3/scrum-overview-by-fairway-technologies/" target="_blank"> Scrum Overview Prezi</a> I just created.</li>
<li>You may also want to take a look at Noah&#8217;s source word doc found <a href="/wp-content/uploads/2011/07/12.scrumoverview.pdf" target="_blank">here</a> on our website.</li>
<li>Or read the book that Noah attributes much of the content to, <em><a href="http://www.amazon.com/Agile-Project-Management-Microsoft-Professional/dp/073561993X" target="_blank"> Agile Project Management with Scrum</a></em> by Ken Schwaber.</li>
</ol>
<p><strong><br />
Simply want to see a <a href="http://prezi.com/rpg5ocdv2qh3/scrum-overview-by-fairway-technologies/" target="_blank"> Prezi example</a>? Need a clever alternative to PowerPoint?</strong></p>
<p>You can check out my handiwork <a href="http://prezi.com/rpg5ocdv2qh3/scrum-overview-by-fairway-technologies/" target="_blank"> here</a>.</p>
<p>I&#8217;d be interested to know what you think.</p>
<p>Keep in mind that this is my first attempt and I didn&#8217;t spend much time on it. I&#8217;m planning to expand the Scrum Overview Prezi, especially if the feedback is good.</p>
<p>If not, well, it sure was a fun diversion.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fairwaytech.com/2011/07/scrum-overview-in-prezi-not-another-boring-slideshow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Numbers don&#8217;t lie: LinkedIn Statistics</title>
		<link>http://www.fairwaytech.com/2011/06/numbers-dont-lie-linkedin-statistics/</link>
		<comments>http://www.fairwaytech.com/2011/06/numbers-dont-lie-linkedin-statistics/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 00:00:34 +0000</pubDate>
		<dc:creator>Leslie Weller</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://69.89.31.239/~fairwayt/fairway/?p=687</guid>
		<description><![CDATA[Numbers Never Lie is one of my favorite sayings. So is Follow The Money, but that&#8217;s another story. As a mild-insomniac, I found myself click-click-clicking around LinkedIn last night. I [...]]]></description>
			<content:encoded><![CDATA[<p><em>Numbers Never Lie</em> is one of my favorite sayings. So is <em>Follow The Money</em>, but that&#8217;s another story. As a mild-insomniac, I found myself click-click-clicking around <a href="http://www.linkedin.com/company/fairway-technologies" target="_blank">LinkedIn</a> last night. I stumbled across a link which invited me to, &#8220;Check out insightful statistics about Fairway Technologies employees.&#8221;</p>
<p>I couldn&#8217;t help myself. As a closet math-nerd and sociology major, I&#8217;m a sucker for statistics. Click.<br />
<span id="more-687"></span><br />
As soon as I viewed the Job Function Composition chart, I immediately thought it reflected Fairway&#8217;s commitment to reduce overhead while investing in developer <a href="about-us/our-people">talent</a>. Clearly, less admin, more R&amp;D than &#8220;the other guys&#8221;.</p>
<p>Of course, I must acknowledge that LinkedIn does not have official headcounts for us nor for other firms, so these stats represent an approximation rather than exactness. But I believe the graphs paint a reasonably reliable picture.</p>
<p>I smiled when I saw this Years of Work Experience chart because it shows at a glance what takes a while to explain with words. Fairway Technologies has very seasoned and senior talent. But not so seasoned that we&#8217;ve lost our passion or zest.</p>
<p>We have solved many tough technical and business challenges throughout our careers. (And continue to do the same for new clients). Yet as a small company, we are nimble. Our engagements aren&#8217;t padded with software or hardware &#8220;drag&#8221;, nor bureaucratic processes. We get things done. We move with purpose, and we do it right.</p>
<p>How have you used LinkedIn lately? Discovered anything new?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fairwaytech.com/2011/06/numbers-dont-lie-linkedin-statistics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

