<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Patrick Fitzsimmons Blog</title>
    <link>https://pfitz-old.hs-sites.com</link>
    <description>The blog of Patrick Fitzsimmons, a software engineer and entrepreneur in Cambridge, MA</description>
    <language>en-us</language>
    <pubDate>Mon, 16 Jun 2014 19:31:20 GMT</pubDate>
    <dc:date>2014-06-16T19:31:20Z</dc:date>
    <dc:language>en-us</dc:language>
    <item>
      <title>How to name variables and methods when coding in a dynamic language</title>
      <link>https://pfitz-old.hs-sites.com/how-to-name-variables</link>
      <description>&lt;p&gt;Dynamic languages lack the perfect IDE intellisense that tells us the type of every variable. Thus it&amp;nbsp;is necessary to use variable names that allow future readers of the code to unambiguously determine the type and contents of the variable.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Dynamic languages lack the perfect IDE intellisense that tells us the type of every variable. Thus it&amp;nbsp;is necessary to use variable names that allow future readers of the code to unambiguously determine the type and contents of the variable.&lt;/p&gt;  
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt; 
&lt;h4&gt;Method names&lt;/h4&gt; 
&lt;p&gt;Method names should always be verbs or verb phrase - get_person, load_database, mark_job_completed, etc.&lt;/p&gt; 
&lt;p&gt;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':&lt;/p&gt; 
&lt;pre class="code"&gt;def hydrate_context(context):
&amp;nbsp; &amp;nbsp; context['stuff'] = Stuff()

def fill_context(context):
&amp;nbsp; &amp;nbsp; context['stuff] = Stuff()
&lt;/pre&gt; 
&lt;p&gt;If the method has side effects that alter a permanent datastore, use a verb like 'update_db', 'save', or 'persist'&lt;/p&gt; 
&lt;p&gt;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:&lt;/p&gt; 
&lt;pre class="code"&gt;def fetch_embed_html():
&amp;nbsp; &amp;nbsp; return requests.get(self.url)
&lt;/pre&gt; 
&lt;p&gt;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:&lt;/p&gt; 
&lt;pre class="code"&gt;def fetch_and_normalize_embed_html(self):
&amp;nbsp; &amp;nbsp; html = self.fetch_embed_html()
&amp;nbsp; &amp;nbsp; return self.normalize(html)
&lt;/pre&gt; 
&lt;p&gt;If you have a variable that holds some sort of callback function, add 'callback' or 'method' or 'function' to the variable name:&lt;/p&gt; 
&lt;code&gt;&lt;/code&gt; 
&lt;pre class="code"&gt;&lt;code&gt;#GOOD:
def process_task(task, success_callback, error_callback):
&amp;nbsp; &amp;nbsp; ''' Do stuff ... '''

# BAD (It's unclear that "error" is a callback function, "error" could be anything, a message that's passed in, a list that collects error results, etc):
def process_task(task, success, error):&amp;nbsp;
&amp;nbsp; &amp;nbsp; pass
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;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. &amp;nbsp;Do not create verbless methods. (This is a python specific rule. &amp;nbsp;Javascript does not have getters, and so using methods that are just the attribute name is quite common in jQuery).&lt;/p&gt; 
&lt;pre class="code"&gt;GOOD:
def get_host(self):
&amp;nbsp; &amp;nbsp; return self.request.host
&lt;/pre&gt; 
&lt;pre class="code"&gt;GOOD:
@property
def host(self):
&amp;nbsp; &amp;nbsp; return self.request.host

# BAD ( I will be very confused when I do "print obj.host" and get "&amp;lt;function host&amp;gt;" instead of the host name)
def host(self):
&amp;nbsp; &amp;nbsp; return self.request.host
&lt;/pre&gt; 
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt; 
&lt;h4&gt;Object instances&lt;/h4&gt; 
&lt;p&gt;Object instances should be the lower case version of the class name, ex: game_type = GameType(), file_library = FileLibrary()&lt;/p&gt; 
&lt;p&gt;Sometimes this seems to verbose. &amp;nbsp;You are tempted to write 'library' instead of 'file_library'. &amp;nbsp;But remember, code is read many more times than it is written. &amp;nbsp;Optimize for the developer reading the code four months from now, not for your typing speed this second.&lt;/p&gt; 
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt; 
&lt;h4&gt;Lists&lt;/h4&gt; 
&lt;p&gt;Variables holding lists should always be the plural form of the thing the list is holding:&lt;/p&gt; 
&lt;pre class="code"&gt;&amp;nbsp; &amp;nbsp; for person in people:
&amp;nbsp; &amp;nbsp; for name in names:
&amp;nbsp; &amp;nbsp; for account in accounts:
&lt;/pre&gt; 
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt; 
&lt;h4&gt;Dictionaries&lt;/h4&gt; 
&lt;p&gt;Dictionaries are basically used in two different ways - as schemaless objects or as a lookup table.&lt;/p&gt; 
&lt;h5&gt;object-style dictionary usage&lt;/h5&gt; 
&lt;p&gt;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:&lt;/p&gt; 
&lt;pre class="code"&gt;person = {
&amp;nbsp; &amp;nbsp; 'name': 'jim',
&amp;nbsp; &amp;nbsp; 'birthdate': '4-17-1982',
&amp;nbsp; &amp;nbsp; 'hometown: 'Boston'
&amp;nbsp; &amp;nbsp; }
&lt;/pre&gt; 
&lt;p&gt;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. &amp;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:&lt;/p&gt; 
&lt;pre class="code"&gt;person = Person()
person_data = Person.to_dict()
person_json = json.dumps(person_data) &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;
&lt;/pre&gt; 
&lt;h5&gt;Dictionaries as lookup tables&lt;/h5&gt; 
&lt;p&gt;If the dictionary refers to some sort of mapping or lookup table, then name the variable for the lookup key and value:&lt;/p&gt; 
&lt;pre class="code"&gt;# GOOD:
person_by_name = {
&amp;nbsp; &amp;nbsp; 'jim': Person(),
&amp;nbsp; &amp;nbsp; 'sam': Person()
}

cities_by_country = {
&amp;nbsp; &amp;nbsp; 'United States': ['Boston', 'New York'],
&amp;nbsp; &amp;nbsp; 'France': ['Paris', 'Orleans']
}
&lt;br&gt;action_to_func_map = {
&amp;nbsp; &amp;nbsp; 'deploy': deploy_project,
&amp;nbsp; &amp;nbsp; 'kick' : kick_project,
}

# BAD - the code reader will think this ia list of persons, not a dictionary
persons = &amp;nbsp;{
&amp;nbsp; &amp;nbsp; 'jim': Person(),
&amp;nbsp; &amp;nbsp; 'sam': Person()
}
&lt;/pre&gt; 
&lt;p&gt;In general, name the variable either 'value_by_key' or 'key_to_value'.&lt;/p&gt; 
&lt;p&gt;Never name a dictionary just 'persons' or 'cities'. &amp;nbsp;The code reader will have no idea how to use the variable. &amp;nbsp;They will think it is a list and be very confused to find it is a lookup table. &amp;nbsp;Once they figure out it is a table, they will be unsure what the keys are.&lt;/p&gt; 
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt; 
&lt;h4&gt;Strings&lt;/h4&gt; 
&lt;p&gt;&lt;strong&gt;Strings should end in a postfix that indicates stringness/wordness&lt;/strong&gt;. Examples of good string variable names include: &amp;nbsp;author_name, field_label, img_src, template_source, body_text, page_key, data_str. &amp;nbsp;If you have a variable holding a users name, do not call that variable 'user', because someone reading the code will get it confused with an instance of the User class. &amp;nbsp;Call the variable user_name. &amp;nbsp;Do not call a string holding the name of a file 'file', that confuses it with a file object. &amp;nbsp;Call the string 'file_name' if it's just the file name, or 'file_path' if it contains the full path to the file.&lt;/p&gt; 
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt; 
&lt;h4&gt;Numbers&lt;/h4&gt; 
&lt;p&gt;Numbers should end with a&amp;nbsp;postfix marking the variable as clearly numeric. &amp;nbsp;Do not use plurals only as that makes the variable name confusing with lists – use 'result_count' not 'results'. &amp;nbsp;Other examples: item_id, home_price_int, costs_sum, load_avg&lt;/p&gt; 
&lt;p&gt;Err on the side of being unambiguous at the expense of verbosity. &amp;nbsp;Let's say you have a variable in a page template. The variable contains the percent of people who passed some academic test. &amp;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.&lt;/p&gt; 
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt; 
&lt;h4&gt;General Consistency&lt;/h4&gt; 
&lt;p&gt;Try to be consistent within your code, so that a variable name always indicates the same thing wherever it is used.&lt;/p&gt; 
&lt;p&gt;For instance, create a convention whereby:&lt;br&gt; (thing)_file is an instance of a file object&lt;br&gt; (thing)_file_name is a string with the name part of the file 'mystuff.txt'&lt;br&gt; (thing)_path is a string with the file full path: '/home/patrick/mystuff.txt'&lt;/p&gt; 
&lt;p&gt;Do not have (thing)_file be a file object in one place and a file name in another place.&lt;/p&gt; 
&lt;p&gt;If in your app 'thing_guid' refers to a string, then it should always be a string. &amp;nbsp;If it refers to an instance of a&amp;nbsp;uuid() or Guid() object, then it should always refer to the instance, and never have a type of string. &amp;nbsp;Pick one way and be consistent.&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h4&gt;Using Judgement&lt;/h4&gt; 
&lt;p&gt;The above guidelines should be followed 99% of the time for naming class attributes, module attributes, and method parameters. &amp;nbsp;For local variables or loop variables, you can use your judgment. &amp;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.&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p&gt; &lt;span class="hs-cta-wrapper"&gt; &lt;span class="hs-cta-node hs-cta-9997a77e-681b-40e7-b383-7dab8737c9a1"&gt; &lt;a href="http://cta-image-cms2.hubspot.com/cs/cpi/?&amp;amp;pg=9997a77e-681b-40e7-b383-7dab8737c9a1&amp;amp;pid=498"&gt;&lt;img alt="&lt;div style=&amp;quot;max-width:700px;&amp;quot;&gt;If you want to work at a company where you will get fussy code review comments if you name your variables poorly, my company, HubSpot, is hiring software engineers.  We&amp;amp;squot;re one of the fastest growing startups in the greater Boston area. &lt;span class=&amp;quot;link&amp;quot;&gt;Check out our jobs page to learn more about our culture and the type of work available&lt;/span&gt;.&lt;/div&gt;" class="hs-cta-img" style="border-width:0px" src="https://no-cache.hubspot.com/cta/default/498/9997a77e-681b-40e7-b383-7dab8737c9a1.png"&gt;&lt;/a&gt; &lt;/span&gt; &lt;/span&gt; &lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=498&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fpfitz-old.hs-sites.com%2Fhow-to-name-variables&amp;amp;bu=https%253A%252F%252Fpfitz-old.hs-sites.com&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>programming</category>
      <pubDate>Thu, 12 Dec 2013 16:00:00 GMT</pubDate>
      <author>pfitzsimmons@hubspot.com (Patrick Fitzsimmons)</author>
      <guid>https://pfitz-old.hs-sites.com/how-to-name-variables</guid>
      <dc:date>2013-12-12T16:00:00Z</dc:date>
    </item>
    <item>
      <title>While-loops Considered Harmful</title>
      <link>https://pfitz-old.hs-sites.com/while-loops-considered-harmful</link>
      <description>&lt;p&gt;Your phone buzzes with the server alert ring tone. Your product manager 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%.&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;Your phone buzzes with the server alert ring tone. Your product manager 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%.&lt;/p&gt; 
&lt;p&gt;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.&lt;/p&gt; 
&lt;p&gt;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.&lt;/p&gt; 
&lt;p&gt;Fortunately, there is a solution to avoid this class of bug completely: never write a while-loop.&lt;/p&gt; 
&lt;p&gt;Anywhere in your code where the need arises for a while loop, instead write a "for-loop" with a sensible maximum.&lt;/p&gt; 
&lt;p&gt;For example, let us say that I am doing a standard chunked-file read in python. In my younger days I would write:&lt;/p&gt; 
&lt;pre&gt;f = open('file.mp3', 'r')
while True:
&amp;nbsp; &amp;nbsp; chunk = f.read(4000)
&amp;nbsp; &amp;nbsp; if not chunk:
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break
&amp;nbsp; &amp;nbsp; output.write(chunk)
&lt;/pre&gt; 
&lt;p&gt;A better pattern is:&lt;/p&gt; 
&lt;pre&gt;# pick a number comfortably higher than the logic of the function
# needs to support.
EMERGENCY_BRAKE = 10000000&amp;nbsp;
for x in xrange(0, EMERGENCY_BRAKE):
&amp;nbsp; &amp;nbsp; chunk = f.read(4000)
&amp;nbsp; &amp;nbsp; if not chunk:
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break
&amp;nbsp; &amp;nbsp; output.write(chunk)&amp;nbsp;
if (x+1) &amp;gt;= EMERGENCY_BRAKE:
&amp;nbsp; &amp;nbsp; raise Exception("File reading loop hit the emergency brake")
&lt;/pre&gt; 
&lt;p&gt;Even better, you can write a helper method:&lt;/p&gt; 
&lt;pre&gt;def iter_with_brake(max_times=1000000):
&amp;nbsp; &amp;nbsp; for x in xrange(0, max_times + 1):
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if x == max_times:
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; raise Exception("Iteration exceeded maximum")
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; yield x
&lt;/pre&gt; 
&lt;p&gt;And now you can use this helper any time you would have previously used a while-loop:&lt;/p&gt; 
&lt;pre&gt;&lt;code&gt;for x in iter_with_brake():
&amp;nbsp; &amp;nbsp; chunk = f.read(4000)
&amp;nbsp; &amp;nbsp; if not chunk:
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; break
&amp;nbsp; &amp;nbsp; output.write(chunk) &amp;nbsp; &amp;nbsp;&amp;nbsp;
&lt;/code&gt;&lt;/pre&gt; 
&lt;p&gt;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.&lt;/p&gt; 
&lt;p&gt;(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).&lt;/p&gt; 
&lt;p&gt; &lt;span class="hs-cta-wrapper"&gt; &lt;span class="hs-cta-node hs-cta-7a67aaa5-0890-464f-b290-21d408a73628"&gt; &lt;a href="http://cta-image-cms2.hubspot.com/cs/cpi/?&amp;amp;pg=7a67aaa5-0890-464f-b290-21d408a73628&amp;amp;pid=498"&gt;&lt;img alt="By the way, our company, HubSpot, is hiring software engineers.  We&amp;amp;squot;re one of the fastest growing startups in the greater Boston area. &lt;span class=&amp;quot;link&amp;quot;&gt;Check out our jobs page to learn more about our culture and the type of work available&lt;/span&gt;." class="hs-cta-img" style="border-width:0px" src="https://no-cache.hubspot.com/cta/default/498/7a67aaa5-0890-464f-b290-21d408a73628.png"&gt;&lt;/a&gt; &lt;/span&gt; &lt;/span&gt; &lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=498&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fpfitz-old.hs-sites.com%2Fwhile-loops-considered-harmful&amp;amp;bu=https%253A%252F%252Fpfitz-old.hs-sites.com&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>programming</category>
      <pubDate>Wed, 20 Feb 2013 16:30:00 GMT</pubDate>
      <author>pfitzsimmons@hubspot.com (Patrick Fitzsimmons)</author>
      <guid>https://pfitz-old.hs-sites.com/while-loops-considered-harmful</guid>
      <dc:date>2013-02-20T16:30:00Z</dc:date>
    </item>
    <item>
      <title>How to Turn Your Windows Machine into Unix</title>
      <link>https://pfitz-old.hs-sites.com/2011/05/how-to-turn-your-windows-machine-into-unix</link>
      <description>&lt;p&gt;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:&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;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:&lt;/p&gt; 
&lt;p&gt;1) &lt;strong&gt;Install a real text editor - Vim or Emacs.&lt;/strong&gt; The optimized key bindings and extra power of Emacs/Vim allow you write code or prose with amazing speed. &lt;a href="http://sites.google.com/site/steveyegge2/effective-emacs"&gt;Read Steve Yegge&lt;/a&gt; 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 "&amp;gt;emacs file.txt"&lt;/p&gt; 
&lt;p&gt;2) &lt;strong&gt;Install the &lt;a href="http://gnuwin32.sourceforge.net/packages.html"&gt;GNU utils for windows&lt;/a&gt; and put them on your system path&lt;/strong&gt;. Now you can use all your favorite unix utilities such as grep, touch, ls, diff, etc, from your windows command line.&lt;/p&gt; 
&lt;p&gt;3) &lt;strong&gt;Enable copy/paste from the command line&lt;/strong&gt;. 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.&lt;/p&gt; 
&lt;p&gt;4) &lt;strong&gt;Install a better shell. I prefer IPython.&lt;/strong&gt; 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.&lt;/p&gt; 
&lt;p&gt;5) &lt;strong&gt;Remap Caplocks to trigger ctrl&lt;/strong&gt;. 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.&lt;/p&gt; 
&lt;p&gt;6) &lt;strong&gt;Forget about Cygwin&lt;/strong&gt;. 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. &amp;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.&lt;/p&gt; 
&lt;p style="text-align: center;"&gt;&amp;nbsp;&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=498&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fpfitz-old.hs-sites.com%2F2011%2F05%2Fhow-to-turn-your-windows-machine-into-unix&amp;amp;bu=https%253A%252F%252Fpfitz-old.hs-sites.com&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>programming</category>
      <pubDate>Fri, 13 May 2011 15:58:00 GMT</pubDate>
      <author>pfitzsimmons@hubspot.com (Patrick Fitzsimmons)</author>
      <guid>https://pfitz-old.hs-sites.com/2011/05/how-to-turn-your-windows-machine-into-unix</guid>
      <dc:date>2011-05-13T15:58:00Z</dc:date>
    </item>
    <item>
      <title>About me</title>
      <link>https://pfitz-old.hs-sites.com/about</link>
      <description>&lt;p&gt;&lt;span&gt;I am a startup guy and software engineer. &amp;nbsp;I currently am working on co-founding &lt;a href="http://www.grokky.com"&gt;Grokky&lt;/a&gt;. Before that, I worked at HubSpot for the better part of a decade. At HubSpot I helped build a powerful suite of marketing software tools that served 10,000 plus paying customers.&lt;/span&gt;&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;span&gt;I am a startup guy and software engineer. &amp;nbsp;I currently am working on co-founding &lt;a href="http://www.grokky.com"&gt;Grokky&lt;/a&gt;. Before that, I worked at HubSpot for the better part of a decade. At HubSpot I helped build a powerful suite of marketing software tools that served 10,000 plus paying customers.&lt;/span&gt;&lt;/p&gt;  
&lt;h3&gt;Stuff I've Built&lt;/h3&gt; 
&lt;strong&gt;HubSpot Content Optimization System (2011-2014)&lt;/strong&gt; 
&lt;p&gt;I was the tech lead for the team building the next generation of the HubSpot content tools. We have built tools for creating blog posts, landing pages, emails, and full web sites. Features include visual template building, a powerful templating language, WYSIWYG editing, A/B testing, and integration with the contacts system and analytics.&lt;/p&gt; 
&lt;p&gt;My personal responsibilities included: designing and/or reviewing overall architectual decisions, mentoring and doing code reviews for a team of 12 people, writing tens of thousands lines of code, working with the product manager to find the proper technical solution to business problems, attending usability sessions and proposing UI design changes, performing devops tasks to ensure we could have less than an hour of total downtime on our public facing pages over the course of a year.&lt;/p&gt; 
&lt;p&gt;The system was built in python running on django. The backend was implemented mostly as REST-ful API's, while the frontend used backbone and custom javascript.&lt;/p&gt; 
&lt;h4&gt;&lt;img alt="" src="https://pfitz-old.hs-sites.com/hs-fs/cos-layout-editor.png" style="max-height: 180px; border: 1px solid #BBB;"&gt;&amp;nbsp; &amp;nbsp;&lt;img alt="" src="https://pfitz-old.hs-sites.com/hs-fs/cos-editing.png" style="max-height: 180px; border: 1px solid #BBB;"&gt;&lt;/h4&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;strong&gt;HubSpot Analytics and Sources Application&lt;/strong&gt; 
&lt;p&gt;I co-lead a team that built an analytics system that would allow our customers to discover where visitors so their site originated from and how they converted into customers and leads, in a set of easy to use charts and tables.&lt;/p&gt; 
&lt;p&gt;The project used python and java for the programming, and the log processing jobs ran on Hadoop.&lt;/p&gt; 
&lt;p&gt;&lt;img alt="" src="https://pfitz-old.hs-sites.com/hs-fs/hubspot-sources.jpg?width=295&amp;amp;name=hubspot-sources.jpg" style="width: 295px; border: 1px solid #BBB;" width="295"&gt;&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Various Projects at HubSpot&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;In addition to the major projects listed here, during my seven years at HubSpot I have engaged in numerous smaller projects:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;a sales tool to crawl web sites and discover what marketing products the prospect was using&lt;/li&gt; 
 &lt;li&gt;an embedable javascript widget allowing visitors to follow the page creator&lt;/li&gt; 
 &lt;li&gt;a desktop executable for Windows and Mac OX that watches a directory for changes and updates files, blog posts, templates, CSS files and other resources to the COS API&lt;/li&gt; 
 &lt;li&gt;a prospects report that would display information about all web site visitors based on GeoIP lookups&lt;/li&gt; 
&lt;/ul&gt; 
&lt;strong&gt;HubSpot Content Management System - Version 1 ( 2006-2008)&lt;/strong&gt; 
&lt;p&gt;When I joined HubSpot I took over the early prototype of the HubSpot content tools, which was a custom DotNetNuke installation running in VB on the ASP.NET stack. I converted it to C# and rebuilt the UI to make it something easy for marketers to use with a drop drop controls. I also built out features such as analytics dashboards, a drag and drop form builder, an inline content editor, and a browser based template editor.&lt;/p&gt; 
&lt;p&gt;&lt;img alt="" src="https://pfitz-old.hs-sites.com/hs-fs/page-manager.png?width=301&amp;amp;name=page-manager.png" style="max-height: 160px; border: 1px solid #BBB;" width="301"&gt;&amp;nbsp; &amp;nbsp;&lt;img alt="" src="https://pfitz-old.hs-sites.com/hs-fs/hubspot-homepage.png" style="max-height: 160px; border: 1px solid #BBB;"&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;strong&gt;GroupSharp 2005&lt;/strong&gt; 
&lt;p&gt;My senior year at a college I founded a company to build a way for non-technical users to build and host an online database. I took the project from initial idea to the point where I was making money advertising via Google Adwords and selling subscriptions to the product. The company was "acquihired" by HubSpot.&lt;/p&gt; 
&lt;p&gt;&lt;img alt="" src="https://pfitz-old.hs-sites.com/hs-fs/groupsharp-homepage.png" style="max-height: 240px; border: 1px solid #BBB;"&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;strong&gt;Lanovision and Coffeeshop&lt;/strong&gt; 
&lt;p&gt;During college I developed an application to share music and videos with other people in the dormitory.&lt;/p&gt; 
&lt;p&gt;&lt;img alt="" src="https://pfitz-old.hs-sites.com/hs-fs/lanovision-cropped.png" style="max-height: 250px;"&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h3&gt;Areas of Experience&lt;/h3&gt; 
&lt;ul&gt; 
 &lt;li&gt;Web applications in Python/Django&lt;/li&gt; 
 &lt;li&gt;Building my own frameworks and tools in Python, including Sprocket for building aspect oriented API's, and Mockery for easy mocking in unittests.&lt;/li&gt; 
 &lt;li&gt;Single page web apps using JavaScript, CoffeeScript, HTML5, and Backbone.&lt;/li&gt; 
 &lt;li&gt;Web applications and services in Java, using Hibernate, Jersey, and &amp;nbsp;(and in the older days, Struts)&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt;  
&lt;img src="https://track.hubspot.com/__ptq.gif?a=498&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fpfitz-old.hs-sites.com%2Fabout&amp;amp;bu=https%253A%252F%252Fpfitz-old.hs-sites.com&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>about</category>
      <pubDate>Tue, 28 Oct 2008 04:52:00 GMT</pubDate>
      <author>pfitzsimmons@hubspot.com (Patrick Fitzsimmons)</author>
      <guid>https://pfitz-old.hs-sites.com/about</guid>
      <dc:date>2008-10-28T04:52:00Z</dc:date>
    </item>
  </channel>
</rss>
