<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Patrick Fitzsimmons -- Software Engineer</title>
        <description>Programmer and startup guy in Cambridge, MA</description>
        <link>https://www.patfitzsimmons.com</link>
        <language>en-us</language>
        <lastBuildDate>Tue, 24 May 2016 15:03:00 +0000</lastBuildDate>
        <generator>Stallion</generator>
        <atom:link href="http://www.patfitzsimmons.com/blog/rss.xml" rel="self" type="application/rss+xml" />
        
        <item>
            <title>A magical technique for resolving disputes at work</title>
            <description><![CDATA[<p>As a manager, one of the trickiest situations to handle is when you and a team member clash over a technical or business issue. What do you do? Do you override them, at risk of crushing their motivation? Do you get into a heated argument? Do you let them go their own way, only to silently stew as you watch them screw up the project? Do you give some mealy-mouthed suggestion, e.g. &ldquo;I feel like we would be better off if you did it this way&hellip;&rdquo;? This predicament also arises when arguing with peers or supervisors.</p>
<!--more-->
<p>A revelation came to me a few years ago when I read an article suggesting that <a href="http://www.nytimes.com/2011/06/15/arts/people-argue-just-to-win-scholars-assert.html">arguing is not about truth</a>. Humans evolved our talent for arguing in order to win allies:</p>
<blockquote>
  <p>Now some researchers are suggesting that reason evolved for a completely different purpose: to win arguments. Rationality, by this yardstick (and irrationality too, but we’ll get to that) is nothing more or less than a servant of the hard-wired compulsion to triumph in the debating arena. According to this view, bias, lack of logic and other supposed flaws that pollute the stream of reason are instead social adaptations that enable one group to persuade (and defeat) another. </p>
</blockquote>
<p>I have noticed this behavior at work. I start a discussion. The discussion turns into an argument. I sense myself becoming defensive. Suddenly I am justifying my own existence and abilities. Opposing arguments are coming into my brain, almost reflexively, outside of my own control. It is like my subconcious is feeding me ammunition for a war. I notice the person I am arguing with doing the same thing, and now I am locked into a hard fight that has strayed far from the goal of figuring out the best solution for the team.</p>
<p>These kind of arguments are poison. It gets even worse in a group meeting when I feel like I am defending my competence in front of an audience.</p>
<p>So what to do instead? Here is a &ldquo;magic&rdquo; technique I have discovered for resolving disputes in a productive manner:</p>
<h3>Bring up your concern in a non-accusatory way.</h3>
<p>Here is a bad way to voice your concern:</p>
<blockquote>
  <p>Why did you use framework X for this project? I think framework Y would be better.</p>
</blockquote>
<p>Here is a good way:</p>
<blockquote>
  <p>Do you have strong opinions about using framework X for this project? I&rsquo;m thinking that using framework Y might have some advantages.</p>
</blockquote>
<p>The first phrasing forces the other person into a defensive mode. Even if they did not have strong opinions about using framework X in the first place, their subconcious will rally to meet the threat and start generating rationalizations on the spot. The person will feel an instinct to justify their intelligence and decision-making abilities.</p>
<p>The second phrasing allows for an easy out &ndash; they can just say they do not have a strong opinion. Nor does the phrasing challenge their abilities, so you avoid putting them on defense.</p>
<h3>As soon you sense defensiveness, stop and change tactics.</h3>
<p>Once I start discussing the pros and cons of X versus Y, the discussion still might become heated. As I sense myself or my teammate becoming reflexively defensive, I back off. The argument has changed tone and will no longer be productive.</p>
<h3>Huddle together and collaboratively examine options.</h3>
<p>When the argument becomes heated, I stop and say, &ldquo;OK, this debate is getting too complex for me to keep straight in my head. Let&rsquo;s huddle.&rdquo; We both sit in front of the same computer screen and I open up a text editor. At the top of the document I write the problem that we are trying to solve. For example, &ldquo;Problem: our web application only supports 1,000 concurrent users and we need to support 10,000&rdquo;. Then I say, &ldquo;Let&rsquo;s brainstorm. What are the ways we can solve this problem?&rdquo; We enter the options we were arguing about previously, but also generate new ideas. Then under each possible solution, we each list pros and cons. For each con, we go one level deeper and offer ideas on how serious the con is, and how the con could be worked around.</p>
<p>The key is that we jointly create pros and cons for all solutions. In this way, it is no longer &ldquo;My solution versus their solution.&rdquo; We both own the solutions, and neither of us risks losing face. </p>
<p>At the end of the brainstorm we have quite a long outline. Sometimes the answer is obvious to both of us once we have enumerated the pros and cons. Sometimes the right answer hinges upon a critical assumption. The next step might be, &ldquo;Let&rsquo;s spend a day and run a trial that will test our performance assumptions if we choose option A. If performance is sufficient, we will do option A.&rdquo; Other times we might remain conflicted. </p>
<h3>Search your mind for data points you have not shared.</h3>
<p>Sometimes during an argument, I pause, step back, and think, &ldquo;What is the sticking point of our dispute? Why am I seeing things in a different way than my colleague?&rdquo; I may realize that I have some unspoken data point in the back of my head that I am relying on. Perhaps I recently talked with a friend about why framework Y was so cool. Perhaps I was on a forum where I saw that a bunch of people were looking to work at a company using framework Y, and I had some vision that we could use Framework Y as a way to attract top talent. It is surprising how often a dispute arises from one person having data points they are not sharing. The solution is simple: Take a moment, think deeply about why you feel the way you do, and share your data points.</p>
<h3>Making the call</h3>
<p>I have found that after using the huddle-and-collaborate technique, about 90% of conflicts simply melt away (hence me calling the technique &ldquo;magic&rdquo; &ndash; the dispute simply disappears). The original dispute usually happened because one person had data, perspectives, or work-arounds that the other person was not aware of. Once the pros and cons are visible to all, the right answer is usually obvious.</p>
<p>What about the other 10% of the time when you are still at odds? When in doubt, defer to the person who is actually doing the work. The person doing the work has their head in the problem and is in a better place to make a decision. Furthermore, if you pull rank and then turn out to be wrong, you will crush their morale. Whereas if they make the call, and turn out to be wrong, they will put in the extra effort to make amends. They will learn from the mistake and develop better judgement in the future. Do not compromise for the sake of compromise, as that makes no one happy and only leads to mediocrity.</p>
<p>The cases when you need to pull rank are when 1) being wrong incurs huge strategic costs to the business or 2) you sense that interests might not be aligned between the employee and the company. For example, in software engineering the employee has a personal incentive to try new frameworks and tools. New tools are fun and build the résumé. The company has an incentive to use tried-and-true tools. The company wishes to standardize across teams so that employees spend less time learning and more time doing. So if you sense the engineer wants to try a new tool purely for the sake of learning something new, then you might have to say no.<sup id='fnref:1'><a href='#fn:1' rel='footnote'>1</a></sup></p>
<p>I hope you find this technique useful and good luck with your next argument!</p>
<div class='footnotes'><hr /><ol><li id='fn:1'>
<p>I do not mean to say that you should never try new tools and languages. The employee may want to try the new tools because they actually have a good chance of making the whole business more modern and productive. The book <a href="http://www.amazon.com/Peopleware-Productive-Projects-Second-Edition/dp/0932633439">Peopleware</a> provides a good rule of thumb. Allow one major experiment per project. That is enough to keep your engineering organization fresh and modern, but avoids the trap of losing too much productivity to learning new tools.</p>
<a href='#fnref:1'>&#8617;</a></li></ol></div>]]></description>
            <link>https://www.patfitzsimmons.com/resolving-disputes</link>
            <pubDate>Tue, 24 May 2016 15:02:00 +0000</pubDate>
            <guid isPermaLink="true">https://www.patfitzsimmons.com/resolving-disputes</guid>
        </item>
        
        <item>
            <title>How to name variables and methods when coding in a dynamic language</title>
            <description><![CDATA[<p>Dynamic languages lack the IDE intellisense that tells us the type of every variable. Thus it is necessary to choose variable names that allow future readers of the code to unambiguously determine the type and contents of the variable.</p>
<!--more-->
<h4>Method names</h4>
<p>Method names should always be verbs or verb phrase - get_person, load_database, mark_job_completed, etc.</p>
<p>If the method has side effects and alters a passed in object (generally a bad idea but sometimes OK), then be explicit by using the verb 'fill' or 'hydrate':</p>
<pre><code>def hydrate_context(context):
    context[&#39;stuff&#39;] = Stuff()

def fill_context(context):
    context[&#39;stuff] = Stuff()
</code></pre>
<p>If the method has side effects that alter a permanent datastore, use a verb like 'update_db', 'save', or 'persist'</p>
<p>If you are grabbing a remote resource, use the verb 'fetch' rather than 'get' to imply that the code is reaching out a distance to get the content:</p>
<pre><code>def fetch_embed_html():
    return requests.get(self.url)
</code></pre>
<p>If your method does two things (generally a code smell, but sometimes you just need a method that wraps two other methods), then be explicit about what the method does and what it returns:</p>
<pre><code>def fetch_and_normalize_embed_html(self):
    html = self.fetch_embed_html()
    return self.normalize(html)
</code></pre>
<p>If you have a variable that holds some sort of callback function, add 'callback' or 'method' or 'function' to the variable name:</p>
<pre><code>#GOOD:
def process_task(task, success_callback, error_callback):
    try:
        self.dispatch(task)
        succes_callback()
    except Exception, e:
        error_callback(e)
    
# BAD (It&#39;s unclear that &quot;error&quot; is a callback function,
# &quot;error&quot; could be anything, a message that&#39;s passed
# in, a list that collects error results, etc):
def process_task(task, success, error):
    ...
</code></pre>
<p>If you want to add a simple getter to an object, use a verb in the method name if it's a method, or use a property if there is no verb in the name. &nbsp;Do not create verbless methods. (This is a python specific rule. &nbsp;Javascript does not have getters, and so using methods that are just the attribute name is quite common in jQuery).</p>
<pre><code>#GOOD:
def get_host(self):
    return self.request.host

GOOD:
@property
def host(self):
    return self.request.host

# BAD ( I will be very confused when I do
# &quot;print obj.host&quot; and get &quot;&lt;function host&gt;&quot;
# instead of the host name)
def host(self):
    return self.request.host
</code></pre>
<h4>Object instances</h4>
<p>Object instances should be the lower case version of the class name, ex: game_type = GameType(), file_library = FileLibrary()</p>
<p>Sometimes this seems to verbose. &nbsp;You are tempted to write 'library' instead of 'file_library'. &nbsp;But remember, code is read many more times than it is written. &nbsp;Optimize for the developer reading the code four months from now, not for your typing speed this second.</p>
<h4>Lists</h4>
<p>Variables holding lists should always be the plural form of the thing the list is holding:</p>
<pre><code>for person in people:
for name in names:
for account in accounts:
</code></pre>
<h4>Dictionaries</h4>
<p>Dictionaries are basically used in two different ways - as schemaless objects or as a lookup table.</p>
<h5>Object-style dictionary usage</h5>
<p>If you are in a small, standalone script, that uses almost all dictionaries and no classes, then it is OK to name the variable holding the dictionary for what the thing is:</p>
<pre><code>person = {
    &#39;name&#39;: &#39;jim&#39;,
    &#39;birthdate&#39;: &#39;4-17-1982&#39;,
    &#39;hometown: &#39;Boston&#39;
}
</code></pre>
<p>But if you are in code that has a class Person, and you have a dictionary that is storing some serialized form of that class, then naming that dictionary 'person' creates confusion. &nbsp;Use 'person' to refer to an object instance, and use 'person_data' or 'person_dict' to refer to the dictionary form, and use 'person_str' or 'person_json' to refer to the serialized form:</p>
<pre><code>person = Person()
person_data = Person.to_dict()
person_json = json.dumps(person_data) 
</code></pre>
<h5>Dictionaries as lookup tables</h5>
<p>If the dictionary refers to some sort of mapping or lookup table, then name the variable for the lookup key and value:</p>
<pre><code># GOOD:
person_by_name = {
    &#39;jim&#39;: Person(),
    &#39;sam&#39;: Person()
}

cities_by_country = {
    &#39;United States&#39;: [&#39;Boston&#39;, &#39;New York&#39;],
    &#39;France&#39;: [&#39;Paris&#39;, &#39;Orleans&#39;]
}
action_to_func_map = {
    &#39;deploy&#39;: deploy_project,
    &#39;kick&#39; : kick_project,
}

# BAD - the code reader will think this is a
# list of persons, not a dictionary
persons = {
    &#39;jim&#39;: Person(),
    &#39;sam&#39;: Person()
}
</code></pre>
<p>In general, name the variable either 'value_by_key' or 'key_to_value'.</p>
<p>Never name a dictionary just 'persons' or 'cities'. &nbsp;The code reader will have no idea how to use the variable. &nbsp;They will think it is a list and be very confused to find it is a lookup table. &nbsp;Once they figure out it is a table, they will be unsure what the keys are.</p>
<h4>Strings should end in a postfix that indicates stringness/wordness.</h4>
<p>Examples of good string variable names include: &nbsp;author_name, field_label, img_src, template_source, body_text, page_key, data_str. &nbsp;If you have a variable holding a users name, do not call that variable &lsquo;user&rsquo;, because someone reading the code will get it confused with an instance of the User class. &nbsp;Call the variable username. &nbsp;Do not call a string holding the name of a file &lsquo;file&rsquo;, that confuses it with a file object. &nbsp;Call the string &lsquo;file_name&rsquo; if it&rsquo;s just the file name, or &lsquo;file_path&rsquo; if it contains the full path to the file.</p></p>
<h4>Numbers</h4>
<p>Numbers should end with a&nbsp;postfix marking the variable as clearly numeric. &nbsp;Do not use plurals only as that makes the variable name confusing with lists – use 'result_count' not 'results'. &nbsp;Other examples: item_id, home_price_int, costs_sum, load_avg</p>
<p>Err on the side of being unambiguous at the expense of verbosity. &nbsp;Let's say you have a variable in a page template. The variable contains the percent of people who passed some academic test. &nbsp;If you name this variable 'percent_passed', it is not immediately obvious if the variable contains a string that looks like '34%' or a float that contains .34. Instead, name your variable 'percent_passed_formatted' for the string version and 'percent_passed_float' for the float version to make it obvious.</p>
<h4>General Consistency</h4>
<p>Try to be consistent within your code, so that a variable name always indicates the same thing wherever it is used.</p>
<p>For instance, create a convention whereby:<br> (thing)_file is an instance of a file object<br> (thing)_file_name is a string with the name part of the file 'mystuff.txt'<br> (thing)_path is a string with the file full path: '/home/patrick/mystuff.txt'</p>
<p>Do not have (thing)_file be a file object in one place and a file name in another place.</p>
<p>If in your app 'thing_guid' refers to a string, then it should always be a string. &nbsp;If it refers to an instance of a&nbsp;uuid() or Guid() object, then it should always refer to the instance, and never have a type of string. &nbsp;Pick one way and be consistent.</p>
<h4>Using Judgement</h4>
<p>The above guidelines should be followed 99% of the time for naming class attributes, module attributes, and method parameters. &nbsp;For local variables or loop variables, you can use your judgment. &nbsp;Since the variable is initialized so close to where the variable is used, it can be pretty obvious to the person reading the code exactly what it is in it, and thus having a verbose variable name is less critical.</p>]]></description>
            <link>https://www.patfitzsimmons.com/how-to-name-variables</link>
            <pubDate>Thu, 12 Dec 2013 11:30:00 +0000</pubDate>
            <guid isPermaLink="true">https://www.patfitzsimmons.com/how-to-name-variables</guid>
        </item>
        
        <item>
            <title>While-loops considered harmful</title>
            <description><![CDATA[<p>Your phone buzzes with the server alert ring-tone. The director of customer support taps you on the shoulder: "Um, it looks like we're down." Not a single screen in your web app loads. You attempt to SSH into your server but connecting takes for...ev...er. Finally you connect to the shell and see the CPU pegged at 100%. You tail the access logs, but nothing looks fishy. Site traffic is normal. Frantic and desperate, you reboot the server. The server comes back up ... but immediately the CPU spikes back to 100%.</p>
<!--more-->
<p>An hour later you find the problem. That hour seemed like an eternity as you tore your hair, fended off account managers, grepped every line of source you could find, and wondered what it feels like to get fired. And what was the error? It was a while loop that processed some unexpected input and spun forever.</p>
<p>Infinite loop bugs are among the most insidious and - outside of wiping out customer data - most destructive bugs. In web application development, most bugs only affect the particular code path where the buggy code resides. Most of the time you know what paths are most critical and can give those paths an extra thorough review. But a while-loop bug in some unimportant, admin-only screen can disable the entire application for everyone. When the problem strikes, it is very difficult to figure out what exactly is causing the app to freak out and where the buggy code lives.</p>
<p>Fortunately, there is a solution to avoid this class of bug completely: never write a while-loop.</p>
<p>Anywhere in your code where the need arises for a while loop, instead write a "for-loop" with a sensible maximum.</p>
<p>For example, let us say that I am doing a standard chunked-file read in python. In my younger days I would write:</p>
<pre><code>f = open(&#39;file.mp3&#39;, &#39;rb&#39;)
while True:
    chunk = f.read(4000)
    if not chunk:
        break
    output.write(chunk)
</code></pre>
<p>A better pattern is:</p>
<pre><code># pick a number comfortably higher than the
# logic of the function needs to support.
EMERGENCY_BRAKE = 10000000
for x in xrange(0, EMERGENCY_BRAKE):
    chunk = f.read(4000)
    if not chunk:
        break
    output.write(chunk)
    if (x+1) &gt;= EMERGENCY_BRAKE:
        raise IndexError(&quot;File reading loop hit the emergency brake&quot;)
</code></pre>
<p>Even better, you can write a helper method:</p>
<pre><code>def iter_with_brake(max_times=1000000):
    for x in xrange(0, max_times + 1):
        if x &gt;= max_times:
            raise IndexError(&quot;Iteration exceeded maximum&quot;)
        yield x
</code></pre>
<p>And now you can use this helper any time you would have previously used a while-loop:</p>
<pre><code>for x in iter_with_brake():
    chunk = f.read(4000)
    if not chunk:
        break
    output.write(chunk)
</code></pre>
<p>In the trivial case of reading a file, the lack of an emergency brake is unlikely to cause a problem. But when you start creating more complicated while-loops, such as for tree traversal, streaming parsers, etc., while-loops become very dangerous. I therefore highly recommend eliminating them entirely.</p>
<p>(Note for the pedantic: this blog post targets web application programmers. There are of course cases in software development where while loops are still fine. If you are writing the main event loop for a sensor on the next Pioneer space probe, your while-loop should happily keep plugging away until the end of the universe).</p>]]></description>
            <link>https://www.patfitzsimmons.com/while-loops-considered-harmful</link>
            <pubDate>Wed, 20 Feb 2013 11:30:00 +0000</pubDate>
            <guid isPermaLink="true">https://www.patfitzsimmons.com/while-loops-considered-harmful</guid>
        </item>
        
        <item>
            <title>How to Turn Your Windows Machine into Unix</title>
            <description><![CDATA[<p>For the many years, the requirements of my job forced me to use Windows for working on parts of our code base. When working in Windows, I dearly missed the tools of a unix environment (ls, grep, the shell, etc). But over the years I've figured out a bunch of hacks that make using Windows a lot more tolerable. Here they are:</p>
<!--more-->
<p><strong>Install a real text editor - Vim or Emacs.</strong> The optimized key bindings and extra power of Emacs/Vim allow you write code or prose with amazing speed. <a href="http://sites.google.com/site/steveyegge2/effective-emacs">Read Steve Yegge</a> if you're not convinced. Put emacs in the system path, so that as you browse around in the shell you can edit files by entering "&gt;emacs file.txt"</p>
<p><strong>Install the <a href="http://gnuwin32.sourceforge.net/packages.html">GNU utils for windows</a> and put them on your system path</strong>. Now you can use all your favorite unix utilities such as grep, touch, ls, diff, etc, from your windows command line.</p>
<p><strong>Enable copy/paste from the command line</strong>. In the windows command prompt, click on the icon in the upper left and then click properties. Then set "Quick Edit" mode to checked. Now you can copy text by highlighting it with the mouse and hitting enter. You can paste by clicking the middle mouse button.</p>
<p><strong>Install a better shell. I prefer IPython.</strong> IPython gives you most of the bash functionality and key bindings. Type Ctrl-r to search for previous commands. Ctrl-A to move to the beginning of the line, ctrl-k to kill a line, ctrl-y to paste/yank a line back, etc. The tab completion works like unix where it only completes until the point of ambiguity. The only annoying thing is that you must prefix all shell commands with "!". But on the plus side, you also have an interactive python prompt, which is handy if you need to test a snippet of code or do some quick math.</p>
<p><strong>Remap Caplocks to trigger ctrl</strong>. Cap-locks is basically useless. Ctrl is used all the time in programming, especially if you use emacs. Remapping will make you type far more efficiently.</p>
<p><strong>Forget about Cygwin</strong>. Cygwin offers the promise of a full unix shell from within windows. But the Cygwin environment has too many pieces that are broken or incompatible. You feel like you are in unix, but then you try to run a script and you get a deep down stack trace. &nbsp;You spend six hours trying to debug it before finding that the underlying C-library is simply incompatible with the Cygwin environment. If you want to use linux on your windows box without dual booting, use a full VM like Colinux or VM Ware. I keep a small, headless, Colinux, Centos5 process running in the background that I SSH into if I need to do something that is linux only.</p>]]></description>
            <link>https://www.patfitzsimmons.com/2011/05/how-to-turn-your-windows-machine-into-unix</link>
            <pubDate>Fri, 13 May 2011 12:00:00 +0000</pubDate>
            <guid isPermaLink="true">https://www.patfitzsimmons.com/2011/05/how-to-turn-your-windows-machine-into-unix</guid>
        </item>
        

    </channel>

</rss>