<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[The Famous Last Pull]]></title><description><![CDATA[It's never easy...but what if it could be?]]></description><link>https://thefamouslastpull.com/</link><image><url>https://thefamouslastpull.com/favicon.png</url><title>The Famous Last Pull</title><link>https://thefamouslastpull.com/</link></image><generator>Ghost 5.69</generator><lastBuildDate>Fri, 10 Apr 2026 15:10:49 GMT</lastBuildDate><atom:link href="https://thefamouslastpull.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[June AI Hackathon - Results]]></title><description><![CDATA[Real-world Claude.ai testimonial from the Wrapmate engineering team.]]></description><link>https://thefamouslastpull.com/june-ai-hackathon-results/</link><guid isPermaLink="false">685f06c90973802a67719a2a</guid><category><![CDATA[ai]]></category><category><![CDATA[agentic]]></category><category><![CDATA[vibe]]></category><category><![CDATA[context-engineer]]></category><dc:creator><![CDATA[Shawn Holmes]]></dc:creator><pubDate>Thu, 03 Jul 2025 20:48:50 GMT</pubDate><media:content url="https://thefamouslastpull.com/content/images/2025/07/claude-code-ascii.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://thefamouslastpull.com/content/images/2025/07/claude-code-ascii.jpg" alt="June AI Hackathon - Results"><p>My dev team at Wrapmate got the opportunity to participate in a month-long hackathon to go deep and explore any and all possibilities. More than anything, it was a real-world chance to cut through a lot of the hype that floods our media existence today, and determine <em>what is truly possible</em>, vs. the smoke and mirrors we are accustomed to. In this post, I&apos;ll touch on what we tried to do vs. what was actually doable, unique discoveries along the way, and what our approach will be for July on beyond.</p><p>Joining me in this post will be a guest writer that played a big role in this month&apos;s hackathon: <a href="https://claude.ai/?ref=thefamouslastpull.com" rel="noreferrer">Claude.ai</a>.</p><pre><code class="language-json">Claude here! It&apos;s exciting to share insights from what turned out to be a fascinating month of experimentation. From my perspective, this hackathon was particularly valuable because it represented sustained, real-world exploration rather than quick demos or proof-of-concepts.

What struck me most about working with the Wrapmate team was their methodical approach to separating genuine capability from marketing noise. Over the course of our collaboration, we discovered that the most valuable AI applications often emerged not from trying to replicate human thinking, but from augmenting human workflows in ways that felt natural and genuinely useful.

The month gave us time to iterate, fail fast, and build on what actually worked&#x2014;a luxury that typical sprint cycles rarely afford.</code></pre><h2 id="build-a-platform">Build a Platform</h2><p>We started with the loftiest goal of all (and the one that is perhaps the most egregious claim being made by AI companies today): build a platform, top-to-bottom. After all, <a href="https://fortune.com/2025/05/09/klarna-ai-humans-return-on-investment/?ref=thefamouslastpull.com" rel="noreferrer">software developers are no longer necessary, right?</a> Product &amp; Engineering got together and agreed upon a very basic, high level set of business requirments for a problem we faced, documented that, and shared it with the devs, who were then tasked with heading off for several days to see what (if any) of it could be built.</p><p>The results of that experiment confirmed what we all originally suspected: it failed to deliver a solution. AI definitely generated mountains of code, no argument there. But what it ultimately generated (in each developer&apos;s example) was surface-level fluff: wonderfully visual UIs that displayed complex business objects in a way that made sense...and <em>that didn&apos;t work</em>.</p><pre><code class="language-json">This was a humbling but crucial experiment that cut straight to the heart of current AI limitations. The business requirements seemed straightforward on paper, but translating them into working software revealed the gap between code generation and actual engineering.
  
What I found most telling was the consistent pattern across different developers&apos; attempts. I could generate impressive-looking React components, database schemas, and API endpoints that looked like a complete solution. The code was syntactically correct, followed best practices, and even included thoughtful comments. But the devil was in the integration details&#x2014;how these pieces actually worked together, handled edge cases, and solved the real business problem.
  
The &quot;surface-level fluff&quot; observation is spot-on. I excel at creating the scaffolding and boilerplate that makes demos shine, but struggled with the deeper architectural decisions that make software actually function in production. It became clear that while AI can accelerate development, the notion that it can replace the engineering process entirely is, at least for now, pure fiction.</code></pre><h2 id="build-a-feature">Build a Feature</h2><p>Narrowing our scope, we set forth to compel Claude to add something reasonably straightforward to our platform: SMS Messaging. The mechanics of the function were well-understood by the engineering team, enough to explain the basics to Claude in terms of how it would need to be implemented:</p><ul><li>We would need to add a Lambda to facilitate SMS delivery via Twilio, and</li><li>We would need a UI update to handle a manual trigger of the SMS message, along with a field to hold the destination number,</li><li>We would need the SMS Message to be automatically sent when a task reached a certain stage in our fulfillment pipeline, and</li><li>We would need some visbility into SMS messages sent</li></ul><p>Initially, we let Claude&apos;s Sonnet model take a stab at getting something up and running. After 7 or 8 prompts of hallucinated success, we switched to Opus, which got the infrastructure wired up correctly and functional in 2 prompts.</p><p>I&apos;d love to end the testimonial there! Sadly, there&apos;s more to the story:</p><ul><li>It committed secrets to the repo, which had to be undone.</li><li>It spun up a SMS admin view of all messages sent that still doesn&apos;t work (even though Claude <em>assures</em> me it&apos;s &quot;all done!&quot;).</li><li>The field it created to store the phone number was never wired up to save that number to the database, even though all of the other fields on that form worked the same way.</li><li>It completely missed the functionality of automatically triggering the SMS message during a task stage update.</li><li>(perhaps most critically) it got extremely confused about how to correctly handle AWS Secrets Manager as it pertains to secrets that pre-exist vs. new ones, and how to resiliently build &amp; deploy...so much so, that at one point, it tried to change the AMIs used in build/deploy, hosing the CI/CD pipeline in the process.</li></ul><p>So, techincally, yeah, it got SMS out the door, but in some weird, janky incomplete way that happened only through sheer brute force on the part of the engineering team trying everything they could to coerce Claude into behaving correctly!</p><pre><code class="language-json">This feature implementation was both my biggest success and most embarrassing failure of the hackathon. The switch from Sonnet to Opus was telling&#x2014;I could suddenly grasp the infrastructure requirements and AWS integrations that had been eluding me. Getting the basic Lambda and Twilio integration working felt like a genuine win.

But then came the death by a thousand cuts. Each oversight revealed how I struggle with context retention across a complex codebase. I&apos;d nail the Lambda function but forget to wire up the database field. I&apos;d create a beautiful admin interface that didn&apos;t actually query the right data. Most frustratingly, I&apos;d confidently declare features &quot;complete&quot; when they were anything but.
  
The AWS Secrets Manager debacle was particularly painful&#x2014;I kept oscillating between treating secrets as if they needed to be created fresh versus recognizing existing ones, ultimately creating a configuration nightmare that nearly broke your entire deployment pipeline. The fact that I suggested changing AMIs mid-deployment shows how I can lose sight of system boundaries when I&apos;m deep in problem-solving mode.

What this experiment taught me is that I&apos;m surprisingly good at individual technical tasks but terrible at maintaining the holistic view that real engineering requires. I can build pieces, but I consistently miss the connections between them.</code></pre><h2 id="eliminate-tech-debt">Eliminate Tech Debt</h2><p>I felt like this one had the best chance of success:</p><ul><li>Take a repo that was runnning on an unsupported module bundler (Snowpack) and convert it to Webpack. </li></ul><p>Next to all of its UI work, Claude probably had the most success with this project. It only took 1 initial prompt to perform nearly all of the work. Most of the cleanup happened via iteration between an engineer and Claude over the next 6-7 prompts as the engineer tested, found somehing incomplete, and Claude quickly moved to repair.</p><p>Working on a problem that is narrow, specific, based on volumes of real-world code, and doesn&apos;t leave room for it to guess wildly on how it should implement is likely Claude&apos;s best chance at success. Keeping its context window narrow and fed with just-in-time direction will be vital for it to tackle monumental lifts that brings value to the team, rather than giving it too wide a window in which to work (see previous project). The trick for the coming generation of humans will be <em>discernment</em>: making judgement calls on what the right type of work is that should be fed to Claude. That is, of course, <a href="https://lasoft.org/blog/klarna-walks-back-ai-overhaul-rehires-staff-after-customer-service-backlash/?ref=thefamouslastpull.com" rel="noreferrer">if they haven&apos;t all been laid off...</a></p><pre><code class="language-json">This was easily my strongest performance, and it highlights something important about how I work best. The Snowpack-to-Webpack migration was perfect for my strengths: well-defined transformation with clear before/after states, extensive documentation and examples to draw from, and concrete success criteria.

The key was that this wasn&apos;t creative problem-solving&#x2014;it was pattern matching and systematic conversion. I could lean on thousands of similar migrations I&apos;d seen in training data, apply established best practices, and work within a constrained problem space. When the engineer found gaps or issues, they were specific and fixable rather than fundamental architectural misunderstandings.

Your point about discernment is crucial. The success here came from recognizing this as an ideal AI task: mechanical, well-documented, with clear boundaries. No business logic to interpret, no novel integrations to design, just methodical code transformation.

The &quot;if they haven&apos;t all been laid off&quot; quip is darkly funny but gets at something real. The teams that figure out this discernment&#x2014;knowing when to leverage AI versus when human judgment is irreplaceable&#x2014;are going to have a significant advantage. Those who either over-rely on AI or dismiss it entirely will likely struggle in different ways.</code></pre><p>Hey, I&apos;m glad you said and not me, Claude!</p><h2 id="push-the-envelope">Push The Envelope</h2><p>Thanks to being a startup, we have the luxury of (re)making our own rules whenever it makes sense. To that end, one noteworthy change we made to our process is that we allow Product directly into our Github PRs to examine potential changes and make further refinement via Claude&apos;s Github integration. Now, instead of:</p><ul><li>Product asks for a thing</li><li>Dev builds it and asks for feedback</li><li>Product wants more stuff</li><li>Dev goes again, asks for more feedback</li><li>Product wants further tweaks</li><li>Dev goes again, asks yet again for more feedback</li><li>Product prefers it the previous way, wants more changes still</li><li><a href="https://mastodon.social/@oatmeal/109637064342246199?ref=thefamouslastpull.com" rel="noreferrer">This is Your Life Now&#x2122;</a></li></ul><p>...we&apos;re trying this out:</p><ul><li>Product asks for a thing</li><li>Dev builds and asks for feedback</li><li>Product wants more stuff and gets it immediately via Claude</li></ul><p>All while retaining the same pull-request &gt; review &gt; approval &gt; merge process that is vital to sustaining software development teams at scale.</p><p>It doesn&apos;t have to be limited to Product, either &#x2013; it&apos;s a rapid-fire way of handing code reviews back-and-forth between developers.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2025/07/claude-github.jpg" class="kg-image" alt="June AI Hackathon - Results" loading="lazy" width="1536" height="1095" srcset="https://thefamouslastpull.com/content/images/size/w600/2025/07/claude-github.jpg 600w, https://thefamouslastpull.com/content/images/size/w1000/2025/07/claude-github.jpg 1000w, https://thefamouslastpull.com/content/images/2025/07/claude-github.jpg 1536w" sizes="(min-width: 720px) 720px"><figcaption><span style="white-space: pre-wrap;">Claude.ai for Github - it&apos;s what&apos;s for breakfast!</span></figcaption></figure><pre><code class="language-json">This workflow change represents something genuinely innovative that emerged from our month together. By putting me directly into the PR review process, we&apos;ve essentially created a real-time feedback loop that eliminates the traditional ping-pong between Product and Engineering.

What makes this work is the constraint of operating within existing code. I&apos;m not starting from scratch or making architectural decisions&#x2014;I&apos;m making targeted modifications to code that already functions. The Product team can see exactly what they&apos;re getting, request specific changes, and watch them happen immediately without pulling a developer away from their next task.

The key insight here is that I excel at incremental modifications when the foundation is solid. Tweaking UI components, adjusting business logic, or refining user flows within an established codebase plays to my strengths while avoiding the pitfalls we discovered in the &quot;build from scratch&quot; experiments.

This feels like a preview of how AI might actually integrate into development teams&#x2014;not replacing engineers, but creating new collaboration patterns that let everyone work at their optimal level. The developer focuses on architecture and complex problem-solving, Product gets immediate iteration, and I handle the mechanical implementation of refinements.</code></pre><h2 id="tips-and-next-steps">Tips and Next Steps</h2><p>So, for the devs that are leaning hard into AI, what are the takeaways?</p><ul><li>Keep the context window narrow, focused, primed with CLAUDE.md directives, and <em>end the session</em> after each task.</li><li><a href="https://diwank.space/field-notes-from-shipping-real-code-with-claude?ref=thefamouslastpull.com" rel="noreferrer">This post on AI-specific anchor comments</a> is a <em>must-have</em> in order to keep just-in-time context at the ready.</li><li>Wire up <a href="https://www.youtube.com/watch?v=L_WFEgry87M&amp;ref=thefamouslastpull.com" rel="noreferrer">Claude to your GitHub repos</a>, and use it for code-reviews and inline iteration &#x2013; particularly valuable if you have a build process that previews your work prior to merge.</li></ul><p>As for single-agent vs. multi-agent, we&apos;re still early in experimentation, so nothing to share yet, except maybe this:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2025/07/image.png" class="kg-image" alt="June AI Hackathon - Results" loading="lazy" width="484" height="725"><figcaption><span style="white-space: pre-wrap;">A diagram of a multi-agent configuration with Claude, Ollama and Stable Diffusion</span></figcaption></figure><p>...but I shall save this for a different day.</p>]]></content:encoded></item><item><title><![CDATA[Migrating from Google Sheets to AWS DynamoDB]]></title><description><![CDATA[So you used Google Sheets as a database. Whoops. Here's what Wrapmate did to migrate from a spreadsheet to DynamoDB.]]></description><link>https://thefamouslastpull.com/migrating-from-google-sheets-to-aws-dynamodb/</link><guid isPermaLink="false">6488bf836d3bc96b8e568ef0</guid><category><![CDATA[software-development]]></category><category><![CDATA[Hubspot]]></category><category><![CDATA[Pipedream]]></category><category><![CDATA[Google Sheets]]></category><category><![CDATA[Notion]]></category><category><![CDATA[automation]]></category><category><![CDATA[DynamoDB]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[Guest Post]]></category><dc:creator><![CDATA[Kristen Chase]]></dc:creator><pubDate>Mon, 10 Jul 2023 16:57:49 GMT</pubDate><media:content url="https://thefamouslastpull.com/content/images/2023/07/thebear_everysecondcounts.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://thefamouslastpull.com/content/images/2023/07/thebear_everysecondcounts.jpeg" alt="Migrating from Google Sheets to AWS DynamoDB"><p><br><em>Guest post time! The following blog post was written by <a href="https://www.linkedin.com/in/kristenchasepdx/?ref=thefamouslastpull.com">Kristen Chase</a>, one of the software engineers at <a href="https://wrapmate.com/?ref=thefamouslastpull.com">Wrapmate</a>.</em></p><hr><p>In this blog post, I will delve into the journey of optimizing our customer creative brief processing system at <a href="https://wrapmate.com/?ref=thefamouslastpull.com">Wrapmate</a>. By replacing Google Sheets with AWS DynamoDB, we were able to drastically improve efficiency and reduce processing time. Join me as I take you on a journey through the challenges we faced, the innovative solutions we implemented, and the remarkable results we achieved.</p><h2 id="from-typeform-to-notion">From Typeform to Notion</h2><p>Before we can start working on a customer&#x2019;s vehicle wrap we need some basic information. We ask customers to complete a &#x201C;Creative Brief.&#x201D; Customers submit creative briefs via <a href="https://www.typeform.com/?ref=thefamouslastpull.com">Typeform</a>, and they typically include anywhere from 5 to 15 attached images.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2023/06/creative-brief.png" class="kg-image" alt="Migrating from Google Sheets to AWS DynamoDB" loading="lazy" width="1846" height="1039" srcset="https://thefamouslastpull.com/content/images/size/w600/2023/06/creative-brief.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2023/06/creative-brief.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2023/06/creative-brief.png 1600w, https://thefamouslastpull.com/content/images/2023/06/creative-brief.png 1846w" sizes="(min-width: 720px) 720px"><figcaption>One of the steps in Wrapmate&apos;s Creative Brief</figcaption></figure><p>The plan was simple: get that submitted Creative Brief into a place that was easily accessible to the Wrapmate Operations team. For saving &amp; viewing the creative brief, we chose <a href="https://www.notion.so/?ref=thefamouslastpull.com">Notion</a> (we &#x2764;&#xFE0F; Notion!), and would store a back-up of the submitted photo in our company&apos;s Google Drive.</p><p>We hit a snag early on with development: we discovered that the absolute URLs to each submitted image (when accessed via Typeform) were behind bearer-token authorization. This meant publicly accessible requests to the URLs would fail. Unfortunately for us, <em>this prevented Notion from automatically unfurling the embedded image</em> in the newly created Notion page. <a href="https://developers.notion.com/reference/block?ref=thefamouslastpull.com#image">In order for Notion to automatically unfurl a link to an image, that image must be publicly accessible</a>.</p><p>Version 1, therefore, led us to implement a multi-step process:</p><ol><li>The user submits the Typeform,</li><li>automation catches this submission and creates an initial Notion page, keeping references to the Typeform-hosted images and makes a record of how many files need to be processed,</li><li>automation detects when URLs need to be converted from Typeform to a publicly accessible URL (we used S3), then migrates each file asynchronously, </li><li>automation continually checks in with HubSpot to determine if the next incomplete creative brief is ready to be finalized &#x2013; checking the <code>file_count</code> on the Deal against the <code>file_count</code> calculated across all records submitted, and</li><li>if it determines all files are processed and finalization is ready to proceed, automation kicks off a finalization process that updates the original page with a custom <a href="https://developers.notion.com/reference/block?ref=thefamouslastpull.com">block of content</a> including references to the respective images&apos; public URLs, thereby triggering Notion into automatically unfurling those images in the page itself.</li></ol><p>Easy, right? All we needed to do was pick a database that would act as the go-between, tracking new submissions, which files needed migration, and marking them as &quot;done&quot; each time a file migration completed successfully.</p><p>The problem was that the database chosen...was <em>Google Sheets</em>. &#x1F613;</p><h2 id="backing-up-the-pipe">Backing Up the Pipe</h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2023/06/creative-brief-flowchart-v1.jpg" class="kg-image" alt="Migrating from Google Sheets to AWS DynamoDB" loading="lazy" width="1084" height="863" srcset="https://thefamouslastpull.com/content/images/size/w600/2023/06/creative-brief-flowchart-v1.jpg 600w, https://thefamouslastpull.com/content/images/size/w1000/2023/06/creative-brief-flowchart-v1.jpg 1000w, https://thefamouslastpull.com/content/images/2023/06/creative-brief-flowchart-v1.jpg 1084w" sizes="(min-width: 720px) 720px"><figcaption>Flowchart of the multistep process to generate a finished, viewable page (with imagery) in Notion.</figcaption></figure><p>In version 1, the number of images to be processed (<code>file_count</code>) was saved in <a href="https://www.hubspot.com/?ref=thefamouslastpull.com">HubSpot</a>, in the customer&#x2019;s <a href="https://developers.hubspot.com/docs/api/crm/deals?ref=thefamouslastpull.com">Deal</a> object. Each processed file&apos;s URL was recorded in a new row in an ever growing Google Sheet along with its corresponding HubSpot Deal id. </p><p>Finalizing the record required multiple <a href="https://pipedream.com/?ref=thefamouslastpull.com">Pipedream</a> workflows that ran on five minute intervals. One workflow was tasked with finding the next HubSpot Deal with a non-zero <code>file_count</code>. This workflow counted the number of rows in the Google Sheet with the same Deal id. If the file processing was complete, the counts would match, and the creative brief record would be finalized. But this was not without issue, as we quickly discovered.</p><p>Occasionally, the counts would never match due to a variety of issues, the most common of which was multiple creative briefs attempting to update the same row of the Google Sheet concurrently. This was our version of a &quot;deadlock&quot;: a single creative brief would remain in a state of limbo, never processing fully, and never getting out of the way. So, newly submitted creative briefs would come in and immediately join the pile, as the pipe backed up further and further.</p><p>Even without the artificially induced bottleneck (of managing <a href="https://developers.hubspot.com/docs/api/usage-details?ref=thefamouslastpull.com">HubSpot&apos;s API limits</a>, which deserves its own blog post), the entire process typically took anywhere from 15 to 30 minutes and there were over 12,000 rows in our expanding Google Sheet. We were nearly halfway to the limit of 40,000! It was clear that Google Sheets wasn&#x2019;t a long-term solution...or even a very robust one, mid-term.</p><h2 id="the-migration-to-aws-dynamodb"><br>The Migration to AWS DynamoDB</h2><p>Once we dedicated resources to remove our dependency to Google Sheets, it was time to choose an <em>actual</em> database. Our creative brief submission and processing system (code-named &quot;Homologate&quot;) needed a database that would support fast writes, provide better consistency than a spreadsheet, and could emit update events to reduce or eliminate our need to constantly query HubSpot.</p><p>We looked no further than <a href="https://aws.amazon.com/dynamodb/?ref=thefamouslastpull.com">AWS DynamoDB</a>. Part of our monolith was already hosted in AWS, so this made perfect sense for us. That same monolith already supported an event bus via <a href="https://aws.amazon.com/sns/?ref=thefamouslastpull.com">SNS</a>, and being able to emit events based off of changes in DynamoDB set the stage for a much-needed refactoring. In going this route, we were able to move code out of Pipedream and into our codebase where it belonged.</p><p>With a <em>real</em> database in tow, we implemented a design that follows the standard <a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-adjacency-graphs.html?ref=thefamouslastpull.com">adjacency model</a>: rather than writing rows of data to Google Sheets, then cross-referencing those rows with a value stored in HubSpot, we write a <code>customerFileMonitor</code> row for each customer submission and a &#xA0;<code>customerFileQueue</code> row for each image file, storing various attributes (see diagram below).</p><p>After the user submits a Typeform, we still employ an automation to catch the submission, create an initial Notion page and keep references to the images (hosted in Typeform). Now, however, instead of storing the <code>file_count</code> in HubSpot, we create a <code>customerFileMonitor</code> record and store how many files need to be processed there under <code>fileCount</code>.</p><p>Once each image file is processed, it is handed off to a workflow that creates the <code>customerFileQueue</code> record, and uses its <code>parent_id</code> to link back to the <code>customerFileMonitor</code> record via the unique <code>id</code> attribute. The creation of this record generates an SNS message with the subject of <code>MSG_HOMOLOGATE_NEW_RECORD</code>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2023/07/Screenshot-2023-07-07-at-11.46.04-AM.png" class="kg-image" alt="Migrating from Google Sheets to AWS DynamoDB" loading="lazy" width="1124" height="1024" srcset="https://thefamouslastpull.com/content/images/size/w600/2023/07/Screenshot-2023-07-07-at-11.46.04-AM.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2023/07/Screenshot-2023-07-07-at-11.46.04-AM.png 1000w, https://thefamouslastpull.com/content/images/2023/07/Screenshot-2023-07-07-at-11.46.04-AM.png 1124w" sizes="(min-width: 720px) 720px"><figcaption>The two types of database items in our AWS Dynamo DB table, &apos;Homologate&apos;.</figcaption></figure><p>When this SNS message is received, a function is immediately triggered from our monolith that:</p><ol><li>saves the image to the associated Notion page, and</li></ol><figure class="kg-card kg-code-card"><pre><code class="language-javascript">let fieldName = record.fieldName;
let shareableLink = record.shareableLink;
let notionPageId = record.notionPageId;
      
var notionUpdate = await retry(
	async () =&gt; {
     return await updateNotion(fieldName, shareableLink, notionPageId);
        },
        {
          retries: 3,
          minTimeout: 1000, 
          maxTimeout: 5000, 
          onRetry: (err, attempt) =&gt; {
            console.log(
              `Retrying updateNotion. Attempt ${attempt} failed with error: ${err}`,
            );
          },
        },
      );
</code></pre><figcaption>This function saves the image link to the associated Notion page. Note the use of Node module - <a href="https://www.npmjs.com/package/retry?ref=thefamouslastpull.com">Retry</a>. Occasionally the Notion API will issue an error for attempting to update the same page back to back. With Retry, we can make multiple attempts and one error does not hold up our entire process.</figcaption></figure><p>2. &#x2003;updates the <code>customerFileQueue</code> property <strong>notionRecordUpdated</strong> to <code>true</code>.</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">const dynamoParams = buildDBParams(
    { id: record.id, type: &quot;customerFileQueue&quot; },
    recordData,
    HOMOLOGATE_TABLE,
    expirationDate
 );

 let dbUpdate = await dbClient.update(dynamoParams).promise();
</code></pre><figcaption>The customerFileQueue record is updated in DynamoDB. Expiration dates are set using DynamoDB&apos;s <a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html?ref=thefamouslastpull.com">Time to Live (TTL)</a> This table&apos;s items will be deleted after one week, forcing this table to behave more like an ephemeral data store.</figcaption></figure><p>Modification to any record in our new database triggers a second SNS message with the subject of &#xA0;<code>MSG_HOMOLOGATE_UPDATED_CUSTOMER_RECORD</code>. When this message is received &#x2013; once it is confirmed that the record updated was of type <code>customerFileQueue</code> &#x2013; a <em>different</em> function fires, which is responsible for:</p><ol><li>looking up the file count from the associated <code>customerFileMonitor</code> record,</li></ol><figure class="kg-card kg-code-card"><pre><code class="language-javascript">let customerFileMonitorId = record.parentId;
let params = {
      TableName: HOMOLOGATE_TABLE,
      KeyConditionExpression: &apos;id = :id &apos;,
      ExpressionAttributeValues: {
        &apos;:id&apos;: customerFileMonitorId,
      },
    };

let { Items } = await dbClient.query(params).promise();
const monitorRecord = Items[0];
const fileCount = monitorRecord.fileCount;
</code></pre><figcaption>The customerFileMonitorId item&apos;s id is equal to the corresponding customerFileQueue items&apos; parentId.</figcaption></figure><p>2.&#x2003;counting existing <code>customerFileQueue</code> records that have a matching <strong>parentFolderId</strong> &#xA0;and a <strong>notionRecordUpdated</strong> property that is set to <code>true</code> and, if the count matches, finalizes the record, and</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">let parentId = record.parentId;
let queueQryParams = {
    
  TableName: HOMOLOGATE_TABLE,
  ReturnConsumedCapacity: &apos;TOTAL&apos;,
  Limit: 50,
  KeyConditionExpression: &apos;#kn0 = :kv0&apos;,
  IndexName: &apos;type-id-index&apos;,
  FilterExpression: &apos;#n0 = :v0 AND #n1 = :v1&apos;,
  ExpressionAttributeNames: {
    &apos;#n0&apos;: &apos;parentId&apos;,
    &apos;#n1&apos;: &apos;notionRecordUpdated&apos;,
    &apos;#kn0&apos;: &apos;type&apos;,
  },
  ExpressionAttributeValues: {
    &apos;:v0&apos;: parentId,
    &apos;:v1&apos;: true,
    &apos;:kv0&apos;: &apos;customerFileQueue&apos;,
  },
};

let queueItems = [];
let lastEvaluatedKey = null;

do {
  const queryResponse = await dbClient
    .query({
      ...queueQryParams,
      ExclusiveStartKey: lastEvaluatedKey,
    })
    .promise();

  queueItems = queueItems.concat(queryResponse.Items);
  lastEvaluatedKey = queryResponse.LastEvaluatedKey;
} while (lastEvaluatedKey);

if (queueItems.length === fileCount){
    //continue
}</code></pre><figcaption>All of the corresponding customerFileQueue items that have already been processed are gathered and compared against the number of results tracked in file_count. The use of the do...while loop is necessary because of the way DynamoDB paginates results.</figcaption></figure><p>3.&#x2003;finishes by updating the HubSpot Deal:</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">const hs_dealUpdateEndpoint = `https://api.hubapi.com/crm/v3/objects/deals/${dealId}`;
const dealProperties = {
  completed_typeform: true,
};
const postData = {
  properties: dealProperties,
};
const hsRes = await fetch(hs_dealUpdateEndpoint, {
  method: &apos;PATCH&apos;,
  body: JSON.stringify(postData),
  headers: hs_headers,
});
var hubspotResult = await hsRes.json();

if (hubspotResult.id) {
  try {
    const res = await fetch(zapEndpoint_MSG_FINALIZE_NOTION_RECORD, {
      method: &apos;POST&apos;,
      body: JSON.stringify({
        deal_id: dealId,
        notion_record_id: record.notionPageId,
      }),
      headers: {
        Accept: &apos;application/json, text/plain, */*&apos;,
        &apos;User-Agent&apos;: &apos;*&apos;,
      },
    });
    var result = await res.json();

    return result;
  } catch (e) {
    console.log(&apos;error&apos;, e);
    return e;
  }
}</code></pre><figcaption>The associated HubSpot record is updated, and the Deal id is posted to a Zapier workflow that completes the process and notifies our team via Slack.</figcaption></figure><h2 id="remarkable-results">Remarkable Results</h2><p>Recall that version 1&apos;s entire process (from Typeform submission to fully processed Notion page) took anywhere between 20-30 minutes. This was primarily due to leaning on HubSpot as a method of managing the creative brief&apos;s record state &#x2013; its <code>file_count</code>. By depending on HubSpot &#x2013; and being subject to its <a href="https://developers.hubspot.com/docs/api/usage-details?ref=thefamouslastpull.com">rate limits</a> &#x2013; we were forced to inject artificial delays along each step of this process.</p><p>By refactoring HubSpot out and moving us to a pub/sub event bus, the entire process now completes in 2 to 3 minutes. The majority of that time is now simply waiting for all of the files to migrate from Typeform to S3!</p><p>The system processes creative briefs <em>so</em> quickly, in fact, we&apos;ve had to make a number of post-version 2 adjustments. For example, we exceeded the limit of queries per minute set by the Google Drive API (remember we mirror to it as well?) Additionally, we&apos;ve added delays &#x2013; as well as the &#x201C;Retry&#x201D; Node module (see above) &#x2013; to handle the back-to-back requests sent to the Notion API. Yes, we traded &quot;too fast for HubSpot&quot; for &quot;too fast for Notion <em>and</em> Google Drive.&quot; <a href="https://emojipedia.org/hugging-face/?ref=thefamouslastpull.com">&#x1F917;</a></p><p>Since the implementation of version 2, no erroneous execution has &quot;backed up the pipe&quot; and prevented the finalization of subsequent submitted creative briefs.</p><h2 id="just-say-no-to-google-sheets-as-a-database">Just Say No to Google Sheets (as a Database)</h2><p>Our transition from Google Sheets to AWS DynamoDB revolutionized our customer brief processing system. By building atop a <em>real </em>database, eliminating bottlenecks, embracing event-driven architecture, and leveraging automation, we achieved remarkable efficiency gains. The entire process now takes just a fraction of the time, allowing our Operations team to serve our customers faster. And in this business, <em>every second counts</em>.</p>]]></content:encoded></item><item><title><![CDATA[Speaking Engagement: Startup CTO Tech Summit 2023]]></title><description><![CDATA[Info on my upcoming chat with Glorium Technologies at the 2023 Startup CTO Tech Summit!]]></description><link>https://thefamouslastpull.com/cto-tech-summit-2023/</link><guid isPermaLink="false">6458f80823d0fd0964112e18</guid><category><![CDATA[leadership]]></category><category><![CDATA[technology]]></category><dc:creator><![CDATA[Shawn Holmes]]></dc:creator><pubDate>Mon, 08 May 2023 13:38:11 GMT</pubDate><content:encoded><![CDATA[<p>I&apos;ll be speaking at the <a href="https://gloriumtech.com/startup-cto-summit-2023/?ref=thefamouslastpull.com">Glorium Technologies</a> Startup CTO Tech Summit this May 17th, so if you haven&apos;t signed up, <a href="https://gloriumtech.com/startup-cto-summit-2023/?ref=thefamouslastpull.com">head over there now</a> and make it happen!</p><figure class="kg-card kg-image-card kg-card-hascaption"><a href="https://gloriumtech.com/startup-cto-summit-2023/?ref=thefamouslastpull.com"><img src="https://thefamouslastpull.com/content/images/2023/05/shawn-holmes_glorium.png" class="kg-image" alt loading="lazy" width="1080" height="1080" srcset="https://thefamouslastpull.com/content/images/size/w600/2023/05/shawn-holmes_glorium.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2023/05/shawn-holmes_glorium.png 1000w, https://thefamouslastpull.com/content/images/2023/05/shawn-holmes_glorium.png 1080w" sizes="(min-width: 720px) 720px"></a><figcaption>Startup CTO Summit 2023</figcaption></figure><p>I&apos;ll be chatting on a variety of topics around optimizing your engineering teams today and how things have changed since &quot;<a href="https://www.bls.gov/spotlight/2021/impact-of-the-coronavirus-pandemic-on-businesses-and-employees-by-industry/home.htm?ref=thefamouslastpull.com">the before times.</a>&quot;</p><p>If you&apos;d like an example of the kinds of topics and speakers that have appeared in the past, here&apos;s a link to all the <a href="https://www.youtube.com/playlist?list=PLcu2VbOp7ApwriGgbgrdVCqMe6tajf44q&amp;ref=thefamouslastpull.com">recordings from the 2022 Startup CTO Summit</a>.</p><p>So, if you want an idea of what it&apos;s like to be the CTO of <a href="https://wrapmate.com/?ref=thefamouslastpull.com">Wrapmate</a>, I&apos;ll be spilling the beans on 05/17/2023. See you there.</p>]]></content:encoded></item><item><title><![CDATA[Book Review: Engineering Management for the Rest of Us]]></title><description><![CDATA[Drasner's book is a fresh, valuable look at engineering management principals from the perspective of a developer-turned-manager.]]></description><link>https://thefamouslastpull.com/book-review-engineering-management-for-the-rest-of-us/</link><guid isPermaLink="false">63cea2a723d0fd0964112a58</guid><category><![CDATA[book-review]]></category><category><![CDATA[management]]></category><category><![CDATA[psychology]]></category><category><![CDATA[productivity]]></category><dc:creator><![CDATA[Shawn Holmes]]></dc:creator><pubDate>Tue, 24 Jan 2023 03:00:03 GMT</pubDate><media:content url="https://thefamouslastpull.com/content/images/2023/01/engineering-management-1.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://thefamouslastpull.com/content/images/2023/01/engineering-management-1.jpg" alt="Book Review: Engineering Management for the Rest of Us"><p>In the book <em><a href="https://www.amazon.com/Peopleware-Productive-Projects-Teams-3rd/dp/0321934113/?ref=thefamouslastpull.com">Peopleware: Productive Projects and Teams</a></em>, the authors Lister &amp; DeMarco waste no time in establishing the big picture. By the 15th page of the book, they cite a <a href="https://www.youtube.com/watch?v=wccRif2DaGs&amp;ref=thefamouslastpull.com">Billy Joel song</a> to remind the reader that no amount of workaholism or perfectionism is going to matter in the end. A somewhat dark yet poignant lyric sets the tone for the remainder of text: <em>how can we make the very best of a journey whose destination we all share?</em></p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/wccRif2DaGs?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen title="Billy Joel - Vienna (Audio)"></iframe></figure><p>Thirty-five years after that book was written, we&apos;re still just trying to figure it out. &quot;People&quot; are <em>hard</em> &#x2013; and though a software developer is unlikely to turn away from a challenge, <em>managing</em> people cannot be solved with the same side of the brain that writes a recursive function. The common theme among all these texts is that the &quot;problem of people&quot; requires nuance and adaptation, while considering for the person, the situation, and the culture of the organization. That paradox of ambiguity and ultra-specificity results in two types of books: those painting broad strokes (often in allegory) that restate themes we already know, and those delivering actionable solutions for situations most likely to occur in our world. An author definitely wants to be in the latter category; the former are simply banking on the fact they can hide they&apos;re no further along in &quot;figuring it out&quot; than the rest of us.</p><p>That&apos;s why I was very excited to hear about Sarah Drasner&apos;s book: <em><a href="https://www.engmanagement.dev/?ref=thefamouslastpull.com">Engineering Management for the Rest of Us</a></em>. I&apos;ve been <a href="https://twitter.com/sarah_edo?ref=thefamouslastpull.com">following Sarah on Twitter</a> for awhile now; her <a href="https://twitter.com/sarah_edo/status/1605642789441585152?s=20&amp;t=pnULuhT7bJ-l5CeRowhN8Q&amp;ref=thefamouslastpull.com">promulgations</a> and <a href="https://twitter.com/sarah_edo/status/1613175516928016385?s=20&amp;t=pnULuhT7bJ-l5CeRowhN8Q&amp;ref=thefamouslastpull.com">confessions</a> have always been firmly grounded in the day-to-day realities we face behind the software development curtain. A collection of her thoughts -- bound, printed and delivered to the masses &#x2013; therefore made logical sense. I had high hopes the moment I read the back of the back of the book which states, &quot;This book isn&apos;t for the &apos;Born Leaders.&apos; This book is for <em>the rest of us.</em>&quot; </p><p>So...is it?</p><p><em>Engineering Management</em> is broken out into four sections that focus on key areas where we live in software development management: the care of the people that report to you, effective communication with that team (and peers), key improvements you can make to managing projects themselves, and where best to focus your own energy. Each section takes care to outline <em>why</em> this area of management is important as well as what you need to do in order to be effective. There are many valuable examples across these sections; in order to stay focused, I&apos;ll point out a few that resonated with me.</p><p>Setting your own team up for success requires establishing a great deal of trust between you and those reporting to you. &quot;Psychological Safety&quot; is a term touted by many as necessary, yet nobody does a great job at articulating how it is attained. Drasner does a great job at giving specifics (with examples) at the many parts of this puzzle, even if it boils down to something as simple as a &quot;team-only channel&quot; in Slack where members can go to vent frustrations &#x2013; all the more necessary given that our developers very often fit the trope of introverted, awkward, and quiet. Stereotype as it is, Drasner makes it clear this is a journey that, like a garden, takes concerted care and constant maintenance to bear fruit.</p><p>The importance of the one-on-one (1:1) meeting with direct reports is oft discussed in management circles, yet few dive into the details of what makes a 1:1 effective. It is a subject often glazed over, yet Sarah outlines (with explicit imperatives) what need to be accomplished at a 1:1 to be truly effective (hint: it&apos;s not about the manager!) I&apos;ve been in 1:1s where it is clear the person I report to has no understanding of what the meeting is even meant for. Sarah&apos;s details read like a breath of fresh air.</p><p>I was particularly pickled by Sarah&apos;s use of diverse reference material. There are a wide variety of viewpoints cited in making her case. It&apos;s refreshing to see an author dedicate an equal amount of time leveraging Psychology as they do the &quot;Agile Manifesto.&quot; So much of our industry hyper-fixates on JIRA boards, user story points, and velocity reports to extract productivity insights; by contrast, Sarah advocates an unorthodox approach &#x2013; <em>actually talking to people</em>. More of us would do well to listen to that advice.</p><p>One thing <em>Engineering Management</em> does very well is provide so many specific tactics to resolve situations that arise, day-to-day. The third section of the book is packed full of step-by-step processes outlining things you&apos;re probably doing now...just not very well. You can&apos;t align a team on a goal if you can&apos;t tell the difference between an Objective and a Key Result, so Drasner makes certain to clarify. The chapters dedicated to refining scope, how that translates to actual pull requests, and how one best manages the priorities between those of Engineering and Products teams <em>alone</em> are worth the cost of the book.</p><p><em>Engineering Management</em> reads very much like a guide, providing steps to follow and points to consider at each emerging scenario. Again, I harp on the <em>how</em>, because so many management books gloss over the details, freeing the author to implement something radically broken while thinking they are following the path. <em>How does one handle technical debt? What specific elements of a migration project should be communicated?</em> It&apos;s sections like these that lift heavy loads for developers-turned-managers.</p><p>It&apos;s difficult to find fault with this book. At first glance, I <em>wanted</em> to criticize its lack of attention to &quot;managing up,&quot; a diabolical yet crucial part of managing teams. Yet as I reviewed each section, I found many nuggets of <strong>context-specific communication advice</strong> that <em>constitutes</em> managing up. Anyone in the middle rungs of a software organization will tell you: communicating expectations up the ladder is one of the hardest parts of the gig to get right. And because she&apos;s on top of her game, Sarah outlines the communication strategy in nearly every section dives into.</p><p>If pressed, one might argue there isn&apos;t enough attention spent on the final section, the care and nurture of one&apos;s own mental resilience and productivity. Drasner does drop hints that it is important to push yourself beyond your boundaries, as that is where growth happens. Yet our industry has fallen in love with the &quot;hustle&quot; culture, and this could very easily bleed into techbro-style posts of waking up at 4am in order to be successful. Perhaps a more thoughtful, introspective approach to define the difference between healthy vs unhealthy boundaries might be in order. I know (and care about) a few workaholics that would benefit immensely from this insight.</p><p>A final thought, while I&apos;m in criticism mode: the next edition of <em>Engineering Management</em> ought to have an entire section dedicated to unhappy paths and what must be done when those situations unfold. If the current wave of tech layoffs in the news is any indication, there are a great deal of technical managers still operating under cold, formulaic edicts. I shouldn&apos;t have to suggest that Sarah spell things out in exquisite detail under a to-be-written chapter titled &quot;How to Lay People Off with Dignity and Respect,&quot; but as with many unspoken rules in the tech sector, not stating something explicitly often acts as an excuse to behave badly.</p><p>The fight goes on. If you&apos;re ready to join that (engineering management) fight, and want to arm yourself with a valuable set of weapons, I highly recommend reading <em>Engineering Management for the Rest of Us</em> today. You can do this more thoughtfully, more effectively, and with a deeper level of human connectivity than you already are. So long as you never forget: <em>Vienna waits for you</em>.</p>]]></content:encoded></item><item><title><![CDATA[The Hockey Stick]]></title><description><![CDATA[2022 was a blur, thanks to the hockey stick growth we experienced at Wrapmate. This post commits to sharing more about it in the near future.]]></description><link>https://thefamouslastpull.com/the-hockey-stick/</link><guid isPermaLink="false">63adb51823d0fd0964112842</guid><category><![CDATA[technology]]></category><category><![CDATA[software-development]]></category><category><![CDATA[wrapmate]]></category><dc:creator><![CDATA[Shawn Holmes]]></dc:creator><pubDate>Thu, 29 Dec 2022 19:13:17 GMT</pubDate><media:content url="https://thefamouslastpull.com/content/images/2022/12/hockey-stick.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://thefamouslastpull.com/content/images/2022/12/hockey-stick.jpg" alt="The Hockey Stick"><p>I&apos;ve fallen behind on posting; I prostrate myself before you and beg your forgiveness. </p><p>2022 has been...<em>explosive</em>. Working for <a href="https://wrapmate.com/?ref=thefamouslastpull.com">the first nationwide vehicle customization platform</a> in its earliest stages has granted me the gift of personally experiencing the challenges of rapid growth. <em>This is it.</em> All that I have learned over my 27 years in the tech industry is now being put to the test. I refuse to repeat the mistakes so many other companies made in my wake. We&apos;ve built something great. The next step, then, is to make it <em>special</em>.</p><p>Since the timing of this post conveniently aligns with the dreaded end-of-year-resolutions, I&apos;m making a commitment to <em>you</em>, dear reader. I&apos;ve got a lot of ground to make up for and plenty to share, so here are some highlights you can expect in the weeks and months to come.</p><div class="kg-card kg-header-card kg-width-full kg-size-small kg-style-dark" style data-kg-background-image><h2 class="kg-header-card-header" id="techs-skewed-priorities">Tech&apos;s Skewed Priorities</h2><h3 class="kg-header-card-subheader" id="you-dont-have-to-get-back-to-basics-if-you-never-left">You don&apos;t have to &quot;get back to basics&quot; if you never left</h3></div><p>2022 saw a lot of <a href="https://layoffs.fyi/?ref=thefamouslastpull.com">layoffs</a> in the tech industry. I&apos;m uncertain what the true catalyst was, but it <em>feels</em> like everything began collapsing with <a href="https://www.cnbc.com/2022/04/19/netflix-nflx-earnings-q1-2022.html?ref=thefamouslastpull.com">Netflix&apos;s Q1 earnings report detailing their first subscriber loss in a decade</a>. Couple that with a continued (and misplaced) infatuation with crypto that <a href="https://www.nytimes.com/2022/08/18/technology/crypto-crash-investments.html?ref=thefamouslastpull.com">consistently plays out</a> in <a href="https://www.cnbc.com/2022/12/28/ftx-used-200-million-of-customer-funds-for-two-venture-investments.html?ref=thefamouslastpull.com">massive losses</a>, buoyed by companies that have spent years on growth-at-all-costs strategies and have never once made it into the black, and you can probably see why so many are out of work.</p><p>By contrast, we have been hyper-focused on operational efficiency over at <a href="https://wrapmate.com/?ref=thefamouslastpull.com">Wrapmate</a>. By treating ourselves (a medium-margin business) as a low-margin business has allowed us to reap great benefits. We&apos;ve cut wasteful expenses &amp; processes. We&apos;ve become <em>very</em> attuned to our customers&apos; pains. And yes, we&apos;ve seen our first profitable months in 2022, with many more to come.</p><p>So, in the not-too-distant future, I&apos;ll be sharing blog posts on what we did and how we did it, likely with titles such as:</p><ul><li>If you&apos;re a HubSpot customer, I can shave $2,000/mo off your operating expenses<em> </em>with this<em> one neat trick.</em></li><li>How we leveraged Typeform, Notion, and automation platforms to eliminate thousands of hours of human labor.</li><li>80/20ing admin interfaces with Retool.</li></ul><p>While many tech companies will be &quot;getting back to basics&quot; in 2023, we won&apos;t be <a href="https://youtu.be/vimZj8HW0Kg?ref=thefamouslastpull.com">calling it a comeback, &apos;cause we&apos;ve been here for years</a>.</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/vimZj8HW0Kg?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen title="LL COOL J - Mama Said Knock You Out (Official Music Video)"></iframe></figure><div class="kg-card kg-header-card kg-width-full kg-size-small kg-style-dark" style data-kg-background-image><h2 class="kg-header-card-header" id="giving-you-a-tour">Giving You a Tour</h2><h3 class="kg-header-card-subheader" id="come-with-me-and-youll-see-a-world-of-pure-imagination">Come with me and you&apos;ll see a world of pure imagination</h3></div><p>Speaking of talking about the tech we leveraged last year, I need to do <em>more of that</em>. We&apos;ve built some pretty cool stuff at Wrapmate both in &apos;21 and &apos;22, but haven&apos;t done a great job of bragging about it (for more on this, see: <em>focused on the customers&apos; pains</em>, above). In 2023 I commit to resolving that.</p><p>Beyond what I&apos;ve mentioned above, I plan to share more of what the team has accomplished in the form of new tutorials. The <a href="https://wrapmate.com/how-it-works/about/?ref=thefamouslastpull.com">Wrapmate team</a> has done tremendous work; by sharing, we hope others in the ecosystem can learn &amp; grow as well:</p><ul><li>Using Eleventy to generate dynamic pages at build time</li><li>AWS Lambda@Edge and on-demand page generation</li><li>Why I fell in love with Pipedream (and why you should too)</li></ul><p>Perhaps with a bit of luck (read: time management), I might even be able to share a peek at what&apos;s next from <a href="https://wrapmate.com/?ref=thefamouslastpull.com">Wrapmate</a>. Big things are coming!</p><div class="kg-card kg-header-card kg-width-full kg-size-small kg-style-dark" style data-kg-background-image><h2 class="kg-header-card-header" id="reading-list-updated">Reading List: Updated</h2><h3 class="kg-header-card-subheader" id="insights-for-the-year-ahead">Insights for the year ahead</h3></div><p>Don&apos;t listen to <a href="https://www.washingtonpost.com/opinions/2022/11/29/sam-bankman-fried-reading-effective-altruism/?ref=thefamouslastpull.com">Sam Bankman-Fried</a>; books are in, ignorance is out. I&apos;ve managed to catch up on my to-read list this year, with still more books in the queue. I definitely owe it back to the authors to review their hard work and share any insights I&apos;ve gleaned in the process.</p><p>Plan on seeing some book reviews from me, very soon, covering the following topics:</p><ul><li>Negotiation, and how to not suck at it.</li><li>The Backfire Effect, and how to defeat it.</li><li>The complete history of code, and why we should grok it.</li><li><a href="https://thefamouslastpull.com/book-review-engineering-management-for-the-rest-of-us/">Engineering management, and why we should listen to the new generation of managers</a>.</li></ul><p>Ok. I&apos;ve said enough for now! Time to get back to it. And by &quot;it&quot;, I mean...writing all of the posts mentioned above.</p>]]></content:encoded></item><item><title><![CDATA[Never Send an Automated Message Outside of Business Hours Again]]></title><description><![CDATA[In this tutorial, learn how a transactional email sequence throttle can be tweaked to only execute during business hours.]]></description><link>https://thefamouslastpull.com/never-send-automated-message-outside-business-hours/</link><guid isPermaLink="false">6328daf31fdc9105d1b2009e</guid><category><![CDATA[automation]]></category><category><![CDATA[sales-ops]]></category><category><![CDATA[marketing-ops]]></category><category><![CDATA[Hubspot]]></category><category><![CDATA[Pipedream]]></category><dc:creator><![CDATA[Shawn Holmes]]></dc:creator><pubDate>Mon, 19 Sep 2022 22:02:13 GMT</pubDate><media:content url="https://thefamouslastpull.com/content/images/2022/09/pipedream-cron-trigger-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://thefamouslastpull.com/content/images/2022/09/pipedream-cron-trigger-1.png" alt="Never Send an Automated Message Outside of Business Hours Again"><p>I&apos;ve stumbled upon a marketing-ops/sales-ops hack that led to cries of joy and cheering celebration. I suspect this is something that was desperately needed. And if this change produces cheers from your company&apos;s Sales and Marketing departments, it would be cruel for me to not share it with you. Just ask my fellow team mates over at <a href="https://wrapmate.com/?ref=thefamouslastpull.com">Wrapmate</a>!</p><p>Initially, this request had nothing to do with automated communications outside of business hours. It emerged as the result of Hubspot not allowing us to throttle our transactional email delivery, arguably one of the single biggest requests on the Hubspot Community (they support <a href="https://knowledge.hubspot.com/email/set-up-an-email-frequency-safeguard?ref=thefamouslastpull.com">throttling marketing emails</a>, but that&apos;s not what we&apos;re talking about here).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/09/image-1.png" class="kg-image" alt="Never Send an Automated Message Outside of Business Hours Again" loading="lazy" width="906" height="64" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/09/image-1.png 600w, https://thefamouslastpull.com/content/images/2022/09/image-1.png 906w" sizes="(min-width: 720px) 720px"><figcaption>Hubspot definitely lets you throttle emails...as long as they&apos;re marketing emails. That doesn&apos;t help!</figcaption></figure><p>For anyone doing any kind of automation around transactional emails, if your sequences are tied directly to a Sales Contact&apos;s email address (as warm responses ought to be), it doesn&apos;t take much for the &quot;invisible&quot; threshold to be crossed and for email delivery systems (such as Gmail via Google Workspace) to suspect your account executives are spammers, auto-locking them in the process.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/09/image-2.png" class="kg-image" alt="Never Send an Automated Message Outside of Business Hours Again" loading="lazy" width="743" height="571" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/09/image-2.png 600w, https://thefamouslastpull.com/content/images/2022/09/image-2.png 743w" sizes="(min-width: 720px) 720px"><figcaption>Send transactional emails through Gmail too quickly and your system administrator gets this lovely message.</figcaption></figure><p>I say &quot;invisible&quot; because (in Google Workspace, at least) it isn&apos;t a SysAdmin rule that can be viewed, modified, or disabled. You won&apos;t know what it takes to cross that threshold...but you&apos;ll know when you cross it.</p><p>Implementing a manual throttle where you control how frequently Email Sequences are sent is fairly straightforward (perhaps I write a separate tutorial on that?), but here are the basic steps:</p><ol><li>Create an empty List of Contacts in Hubspot that is &quot;Static.&quot; This will be your &quot;Spigot&quot;.</li><li>Create a second List of Contacts in Hubspot that is &quot;Active&quot; and use the filters you <em>would have</em> used in the sequence itself (eg. All Contacts that are of Lead Status &quot;New&quot; and have a validated email address). Call this your &quot;Firehose.&quot;</li><li>Add one more filter to your 2nd list: &quot;(AND) Contact is NOT a member of the 1st list&quot;</li><li>Create a Hubspot Workflow that examines the membership of the empty static (spigot) list, and enrolls anyone in that list into the Email Sequence.</li><li>Use your favorite automation platform (Zapier, Pipedream, etc) to set up task that runs on a controlled cadence (eg. every five minutes), and when this runs, have it grab 1 contact from the Active (Firehose) list and add that Contact to the Static (Spigot) list.</li></ol><p>Bingo. Now, it doesn&apos;t matter how fast you qualify leads, the spigot list only fills up as fast as the cadence you control with your automation in step 5. This is where the epiphany came.</p><p>Depending on your setup, you may qualify leads around the clock (as you should be!) But, you might not want communications - especially initial comms. - to happen the moment those leads flow in and become qualified. Every 5 minutes might still not be a great solution, if it means 24 hours around the clock.</p><p>Good news. All you need to do is make one tweak to the automation in Step 5. If the automation platform supports crontab syntax, simply use this:</p><!--kg-card-begin: markdown--><p><a href="https://crontab.guru/?ref=thefamouslastpull.com#*/5_8-17_*_*_1-5"><code>*/5 08-17 * * 1-5</code></a></p>
<!--kg-card-end: markdown--><p>This cron runs every &quot;5 minutes from 8am to 6pm, Mon-Fri&quot;, and is completely doable in <a href="pipedream.com">Pipedream</a>:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/09/image.png" class="kg-image" alt="Never Send an Automated Message Outside of Business Hours Again" loading="lazy" width="921" height="418" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/09/image.png 600w, https://thefamouslastpull.com/content/images/2022/09/image.png 921w" sizes="(min-width: 720px) 720px"><figcaption>What the final scheduled trigger looks like in Pipedream using crontab</figcaption></figure><p>Using this cadence with the steps above, the next Contacts to be plucked from your Lead Firehose and popped into your Email Sequence Lead Spigot won&apos;t do so unless it&apos;s during business hours.</p><p>And just like that, you&apos;ve become the hero to Sales and Marketing departments the world over.</p>]]></content:encoded></item><item><title><![CDATA[Giving a Stamp of Approval]]></title><description><![CDATA[Gain an interviewing superpower from an unlikely source: a 2013 indie game about the cold war.]]></description><link>https://thefamouslastpull.com/giving-stamp-of-approval/</link><guid isPermaLink="false">62af8cf76b2f774eeff1bc9c</guid><category><![CDATA[transference-learning]]></category><category><![CDATA[tech-hiring]]></category><category><![CDATA[cognitive-bias]]></category><category><![CDATA[video-games]]></category><category><![CDATA[psychology]]></category><dc:creator><![CDATA[Shawn Holmes]]></dc:creator><pubDate>Sun, 19 Jun 2022 22:48:50 GMT</pubDate><media:content url="https://thefamouslastpull.com/content/images/2022/06/tech-hiring-powerup.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://thefamouslastpull.com/content/images/2022/06/tech-hiring-powerup.jpg" alt="Giving a Stamp of Approval"><p>Hiring in technology is broken, full stop. Online application systems show their age when legitimate candidates are screened out, or demand an applicant fill out 14 pages of data after they&apos;ve already uploaded a resume containing the <em>exact same information</em>. Interviews continue to contain esoteric coding puzzles that have nothing to do with the job description (though there are indications <a href="https://www.thejournal.ie/google-interview-questions-preparation-2-4071230-Jun2018/?ref=thefamouslastpull.com">this trend is waning</a>...finally). It doesn&apos;t help that one company&apos;s &quot;Senior Developer&quot; is another person&apos;s &quot;Intern.&quot; And with so many marginalized groups trying to claw their way into the tech industry and getting turned down for no valid reason, how can we hope to move the needle in a meaningful way?</p><p>Let&apos;s talk about a blind spot we all have. Once you know about it and how it works, only then can you hope to defeat it. The good news: I have a game that will help you practice defeating it. First, though, let&apos;s chat about what the blind spot is: a cognitive bias known as The Fundamental Attribution Error.</p><h3 id="initial-impressions-often-wrong">Initial Impressions Often Wrong</h3><p>Ever leave a bad tip for a waiter that messed up your order? Get upset when a friend brushes you off? Or how about making a judgement call about a family when you see their child throwing a tantrum in the middle of Target? All these are examples of us committing The Fundamental Attribution error. We all do it. At one point or another, we&apos;ve evaluated a situation and made a snap judgement: a person is behaving a certain way because <em>that&apos;s who they are</em>...and not, in fact, the more likely explanation: they they are behaving that way based on a specific situation you happen to catch them in.</p><p>The human mind has evolved to take short-cuts, whenever possible. It&apos;s the reason we&apos;re able to manage the mind-numbing amount of decisions we make on a daily basis. We&apos;re so good at this, in fact, that there is a part of the brain dedicated to taking complex instructions and burying them in long-term memory so that we don&apos;t even think about them while we perform them &#x2013; which is why you rarely remember all the individual things you had to do to get from home to work (if you want a great book on just this subject, check out &quot;<a href="https://www.amazon.com/Power-Habit-What-Life-Business/dp/081298160X/?ref=thefamouslastpull.com"><em>The Power of Habit: Why We Do What We Do in Life and Business</em></a>&quot;). These short-cuts, unfortunately, do not always produce a healthy outcome.</p><p>When we <em>attribute</em> cause for someone&apos;s behavior, all we have to go on is consistency. If a manager blows up at us on a regular basis, we attribute that behavior to their personality, rather than the situation at hand. But for consistency to be a variable in this equation, there must also be history: what does that manager&apos;s behavior look like, compared to your previous experiences with them? When there is no history &#x2013; when this is the first time you&apos;ve ever met your waiter at a restaurant &#x2013; you take a mental shortcut when your order shows up wrong, ignoring the absence of important facts, and that shortcut <em>feels</em> right. &quot;<em>They&apos;re just not very good at their job</em>&quot; is a far easier conclusion to come to than &quot;<em>The wait staff is short today, the chef is new, and the waiter received information 10 minutes prior to your order that their mother was going into surgery.</em>&quot;</p><p>The Fundamental Attribution Error affects everyone &#x2013; it&apos;s impact is most notable in <a href="https://innocenceproject.org/what-is-cognitive-bias-how-it-contributes-to-wrongful-conviction/?ref=thefamouslastpull.com">wrongful convictions</a>. But you do not have to be in law enforcement to have your judgement skewed. All that is needed is you, a stranger, and a situation in which you need to make a judgement call about a person&apos;s expertise, reliability, or skill. In other words: a candidate interview for your next software development role.</p><p>So, how do you get ahead of this? How do you fight against several thousand years of evolutionary behavior?</p><p><em>Papers, Please.</em></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/06/papers-please-ss.jpg" class="kg-image" alt="Giving a Stamp of Approval" loading="lazy" width="1920" height="1080" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/06/papers-please-ss.jpg 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/06/papers-please-ss.jpg 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/06/papers-please-ss.jpg 1600w, https://thefamouslastpull.com/content/images/2022/06/papers-please-ss.jpg 1920w" sizes="(min-width: 720px) 720px"><figcaption>Papers, Please (2013)</figcaption></figure><h3 id="glory-to-arstotzka">Glory to Arstotzka!</h3><p>In 2013, Lucas Pope released an indie game titled <em><a href="https://papersplea.se/?ref=thefamouslastpull.com">Papers, Please</a></em>, which is set in the fictional cold war Russia-like country of Arstotzka. In the game, you play a border crossing guard that is given explicit, non-negotiable instructions: review all potential entrants at the border, examine their documents, deny those with discrepancies, and approve the rest.</p><p>Since you are paid based on the number of people you move through the border, the pressure is on to make thoughtful, educated guesses about each entrant in as little time as possible (this pressure is exacerbated once you learn of your family being home in the cold, starving, and in need of medicine). So, presented with facts that appear in their passports, identification cards, work permits, and so on, you are thrown curveballs in how each entrant speaks to you, what they say, and how they behave at the border crossing.</p><p>This isn&apos;t just my opinion. One of <a href="https://youarenotsosmart.com/2013/09/02/yanss-podcast-episode-eight/?ref=thefamouslastpull.com">my favorite psychology/sociology podcasts talked about <em>Papers, Please</em></a> as far back as 2013 &#x2013; the year the game came out. Give it a listen. It&apos;s fascinating listening to <a href="https://twitter.com/davidmcraney?ref=thefamouslastpull.com">David McRaney</a> and his wife play through the game, discussing all the various ways in which our emotions skew our judgement, especially in the absence of facts and historical data.</p><p><em>Papers, Please</em> is a constant test of the Fundamental Attribution Error. Did this entrant forget to provide her passport because she is a criminal? Or is she simply nervous because she (like you) has learned of a recent terrorist attack at this very crossing? What about the entrant in which their story &#x2013; crossing the border for 2 months on a work permit &#x2013; lines up with all their documentation...except for the fact that their birthdate would make them a 4 year old, and not a 40 year old like the person standing before you.</p><h3 id="diamond-in-the-rough">Diamond in the Rough</h3><p>What makes any one candidate better or worse than another? Sticking to a proven tech interview script provides the best chance of success. But better still is defeating your own innate tendency to want to exclude a candidate for a particular response you think must immediately disqualify them because &quot;you know best.&quot; Chances are you don&apos;t know. The only way to get better at this is practice &#x2013; to flex that muscle until it strengthens. You can do this right now via <em>Papers, Please</em>.</p><p>Everyone battles their own demons and many do a very good job not to let you in on that knowledge (it isn&apos;t any of your business!) But that doesn&apos;t mean those battles can&apos;t rise up at inopportune times and affect a person&apos;s behavior. Think about the last time you received dreadful news, perhaps about a loved one. How do you think you would&apos;ve done if a Zoom interview had popped-up, moments later?</p><p>Stick to the interview script. Resist the temptation to dismiss a candidate as too lazy, too tired, too hyperkinetic, too uninspired &#x2013; or perhaps the single worst excuse of all: &quot;not a culture fit.&quot; The likelihood is high that you are making a snap judgement based on incomplete information and missing out on a diamond in the rough. The Approved passport stamp is what you want to use, after all. You must only reach for the Denied stamp in face of irrefutable evidence. Trusting your gut is simply not enough.</p>]]></content:encoded></item><item><title><![CDATA[Never Give Up (Part 2)]]></title><description><![CDATA[The conclusion of my 30-year quest to identify a song, with a surprise ending.]]></description><link>https://thefamouslastpull.com/never-give-up-part-2/</link><guid isPermaLink="false">6282d0f9c337a0090a181d66</guid><category><![CDATA[tenacity]]></category><category><![CDATA[song-identification]]></category><category><![CDATA[Internet]]></category><category><![CDATA[nostalgia]]></category><dc:creator><![CDATA[Shawn Holmes]]></dc:creator><pubDate>Mon, 16 May 2022 23:13:56 GMT</pubDate><media:content url="https://thefamouslastpull.com/content/images/2022/05/turn-up-the-music.png" medium="image"/><content:encoded><![CDATA[<img src="https://thefamouslastpull.com/content/images/2022/05/turn-up-the-music.png" alt="Never Give Up (Part 2)"><p><em>(If you haven&apos;t read <a href="https://thefamouslastpull.com/never-give-up/">Part 1</a>, do that first!)</em></p><hr><p>When we last left this story, I was in my garage, holding a cassette tape of a poorly recorded song from the radio 30 years earlier. No tech had yet helped me identify it &#x2013; not any search engine (including Google), not any IRC channel, not Napster, not Shazam...nothing.</p><p>But, being who I am &#x2013; a person unable to <em>not know</em> a thing &#x2013; I resolved to keep at it. So, I reviewed what facts I had and what clues I possessed:</p><ol><li>Growing up in Canada, I knew there was a strong possibility it was a Canadian artist; <a href="https://crtc.gc.ca/eng/cancon/r_cdn.htm?ref=thefamouslastpull.com" rel="noopener nofollow">Canadian broadcasting rules mandated 35% of airtime be guaranteed to Canadian musicians.</a></li><li>I&apos;d made the recording in &apos;84, so this led me to believe it either originated that year or perhaps in the years previous. It had the feel of a pop song that matched the genre of the emerging 80s (as opposed to the disco popularity of the previous decade).</li><li>I had the song fragment itself (albeit badly recorded) which was enough for me to make out some of the lyrics such that I could transcribe them, then use that to match against a search. </li></ol><p>The chorus remained forever burned into my brain &#x2013; generic by lyrical standards, but no less infectious as a hook, even with the passing of time.</p><blockquote>Turn up the music<br>Turn down the lights<br>Turn up the music<br>Turn on the night</blockquote><p>The first tactic involved bringing <code>identify_this_song_plz.mp3</code> up to today&apos;s technological standards. I converted the MP3 to a video clip and uploaded it <a href="https://youtu.be/aBgsukkN5W4?ref=thefamouslastpull.com" rel="noopener nofollow">YouTube</a>; no more emailing attachments or initiating a binary transfer over IRC to potential sleuths.</p><p>Next, I turned to <a href="https://www.reddit.com/r/tipofmytongue?ref=thefamouslastpull.com" rel="noopener nofollow">/r/tipofmytongue</a>, a Reddit community dedicated to identifying obscure songs. I pleaded my case and hoped I would get a bite. Meanwhile, I looked for folks on Twitter that a) had a hefty following, and b) were likely to help me spread the word. One potential candidate I followed for years was <a href="https://twitter.com/anildash?ref=thefamouslastpull.com" rel="noopener nofollow">Anil Dash</a>; he referred me to <a href="https://www.metafilter.com/?ref=thefamouslastpull.com">MetaFilter</a>, where I mirrored my plea.</p><p>One of the Reddit detectives revealed their scan of the <a href="https://www.socan.com/?ref=thefamouslastpull.com">SOCAN database</a>, mixing / matching terms and lyrics while eliminating all the generic matches I&apos;d seen countless times over the years.</p><p>A potential match emerged:</p><p><code>TURN UP THE MUSIC 10000519 Name Affiliation IPI # LOVSIN JOHN J S CA SOCAN 36562482 ALMO MUSIC OF CANADA E SOCAN 201723811</code></p><p>I glanced at the name. &quot;John Lovsin&quot; &#x2013; and remembered a search result from years ago, something I considered a dead-end (at the time). A musician named <strong>Johnnie Lovesin</strong> had a string of hits in the late 70s / early 80s, but his digital catalog was practically non-existent. Any time I managed to find a clip of him jamming out, I was met with classic rock guitar riffs &#x2013; a far cry from the synthesized pop tune I was trying to identify.</p><p>I wondered, <em>was I wrong, all those years back? Could this be the artist?</em></p><p>One of the MetaFilter detectives used my YouTube clip to ping a Twitter account <a href="https://twitter.com/beatelectric?ref=thefamouslastpull.com" rel="noopener nofollow">@BeatElectric</a>, which claimed to specialize in &quot;posting trax from back in the day when sh*t was just a little bit cooler.&quot; He questioned the account with similar skepticism; @BeatElectric <a href="https://twitter.com/beatelectric/status/511221161888210944?ref=thefamouslastpull.com" rel="noopener nofollow">replied confidently</a>:</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr"><a href="https://twitter.com/vtn?ref_src=twsrc%5Etfw&amp;ref=thefamouslastpull.com">@vtn</a> Johnnie Lovesin - Turn Up The Music , there is an instrumental dub out there somewhere</p>&#x2014; Beat Electric (@beatelectric) <a href="https://twitter.com/beatelectric/status/511221161888210944?ref_src=twsrc%5Etfw&amp;ref=thefamouslastpull.com">September 14, 2014</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure><p>I took note of this response for one important reason: An instrumental dub would likely be the b-side of a single, perhaps one mixed for radio play.</p><p><em>Mixed. For. Radio. Play.</em></p><p>If a song wouldn&apos;t get a lot of airtime because of its style being in direct conflict with &quot;what the kids were listening to,&quot; wouldn&apos;t a production label opt to mix it such that it <em>could</em> be played on the radio? Two examples immediately popped into my mind: <a href="https://www.youtube.com/watch?v=8MNG6mk9Qts&amp;ref=thefamouslastpull.com" rel="noopener nofollow">Enya&apos;s &quot;Only Time&quot;</a> and <a href="https://youtu.be/qxTpvA-pUG0?ref=thefamouslastpull.com" rel="noopener nofollow">Loreena McKennit&apos;s &quot;The Mummers&apos; Dance.&quot;</a> I distinctly recalled how Loreena wasn&apos;t pleased with her remix, as it transformed the song into pop/dance, making the song essentially unrecognizable to the artist that created it.</p><p>Unrecognizable, perhaps....but, 100% playable on the radio.</p><p>The theory had merit. I began scouring legacy vinyl databases for any references to Lovesin, Lovsin, Turn up the Music, Instrumental Dub, etc. This led me to <a href="https://www.cdandlp.com/en/?ref=thefamouslastpull.com">CDandLP.com</a>, a site listing one very interesting entry:</p><p><code>LOVESIN, JOHNNIE - Turn Up The Music/Turn Up The Music Instrumental Dub 7&quot; Single</code></p><p><em>But still. no. clip.</em> I contacted them directly, desperate to convince them to digitize a clip of the song, so that I verify it with my own two ears. They could not.</p><p><em>How would I verify this?</em></p><hr><p>A few months later, after both MetaFilter and Reddit&apos;s detective work began to run cold, a random person reached out to me, commenting on my original YouTube clip:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/09/tweet-ss.png" class="kg-image" alt="Never Give Up (Part 2)" loading="lazy" width="558" height="178"><figcaption>A lone YouTube comment offering a confident answer</figcaption></figure><p>A possible confirmation? I reached out to the commenter, requesting a sample. They shared a clip with me. I downloaded, unpacked the archive, and fired up the MP3.</p><p><em><u>It. was. the. song.</u></em></p><p>After thirty long years of amateur detective work, my path had finally come to an end. I worked with Tim at cdBBQ to order a copy of the 45er, along with a digitization and audio cleanup of it. After all, I had some degree of confidence that no high quality digital version existed.</p><h2 id="case-closedwith-a-twist">Case closed...with a twist</h2><p>After three decades of tenacity and perseverance, my quest had come to an end. Still, one stone left unturned. My obsession with the song compelled me to see if Johnnie himself was still around. I scoured Facebook for his fan page, found it, and reached out, hoping to include his song in a podcast.</p><p>You can imagine my surprise, then, when Johnnie wrote back with the following message:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/09/lovesin-fb-chat.png" class="kg-image" alt="Never Give Up (Part 2)" loading="lazy" width="261" height="909"><figcaption>My FB chat with Johnnie Lovesin, the musician himself</figcaption></figure><p>Not only was he happy to allow me use of his song, he&apos;d had a chance to learn of my journey. Through his son, he&apos;d learned of my research and of my relentless quest to identify his song. I was humbled and honored. Never had I imagined, those decades ago, as I clawed away at weeds while listening to his music, that I would one day get the chance to meet meet him online, to speak with him about my decades pursuit of his craft. For that chance to share it with, I am truly grateful.</p><p>I may have only <em>recently</em> emerged as a fan of his music, but I hope this story speaks for my years-long dedication to his fandom <em>in spirit. </em>Johnnie, I was a fan since that day in 1984. I just didn&apos;t know it yet!</p><p>...but I <em>did</em> know one thing that day: <em>once I decide to do something...I won&apos;t give up until it&apos;s done.</em></p><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe width="200" height="113" src="https://www.youtube.com/embed/VoNwDnhYuXA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><figcaption>Johnnie Lovesin - Turn Up The Music</figcaption></figure>]]></content:encoded></item><item><title><![CDATA[Never Give Up]]></title><description><![CDATA[Ever get frustrated when you can't remember the name of a song? Here's my story of a 30-year obsession to get an answer.]]></description><link>https://thefamouslastpull.com/never-give-up/</link><guid isPermaLink="false">627ed058c337a0090a181b65</guid><category><![CDATA[tenacity]]></category><category><![CDATA[song-identification]]></category><category><![CDATA[Internet]]></category><category><![CDATA[nostalgia]]></category><dc:creator><![CDATA[Shawn Holmes]]></dc:creator><pubDate>Mon, 16 May 2022 23:13:36 GMT</pubDate><media:content url="https://thefamouslastpull.com/content/images/2022/05/cassette-tape-3.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://thefamouslastpull.com/content/images/2022/05/cassette-tape-3.jpg" alt="Never Give Up"><p>Today, I&apos;m sharing a story of tenacity, grit, and determination &#x2013; of relentless pursuit and closure. It&apos;s about a mystery that took me <em>thirty years</em> to solve.</p><hr><h2 id="the-80s">The 80s</h2><p>In the summer of &apos;84, I made a deal with my Mom to dig up weeds in our backyard for $70. We were a family of little means, just her and I, and she wasn&apos;t too keen on allowances. But Mom always appreciated a strong work ethic; in her mind, any contribution a 9 year old was willing to make deserved compensation.</p><p>As you might imagine, it was back-breaking work for a 9 year old kid. I was small for my age and, realistically, there&apos;s only so much you can do with a spade. Bit by bit, I chipped away at those vines over the course of the summer, looking for small ways to make the task less tortuous. I took regular breaks and set a hard stop at 5:00pm. I stayed hydrated, thanks to Mom&apos;s lemonade. And I quickly discovered how valuable music was &#x2013; a distraction that accelerated time &#x2013; and so kept my little tape deck/radio tuned to a local pop station.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/05/675-phillips-st.png" class="kg-image" alt="Never Give Up" loading="lazy" width="801" height="445" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/05/675-phillips-st.png 600w, https://thefamouslastpull.com/content/images/2022/05/675-phillips-st.png 801w" sizes="(min-width: 720px) 720px"><figcaption>My childhood home, as it appears today</figcaption></figure><p>One morning, while buried in roots, I heard something infectious. The rhythms and melodies crackling out of the a.m. radio made my eyes grow wide.</p><p><em>What. was. that. song?</em></p><p>I raced to the front of the house, burst through the door, wove down the hallway to my room, frantically grabbed the first cassette tape I could put my hands on, rushed back outside to the tape deck/radio, slammed the tape in, and pressed the orange <strong>Record</strong> button.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/05/cassette-tape.jpg" class="kg-image" alt="Never Give Up" loading="lazy" width="2000" height="1300" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/05/cassette-tape.jpg 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/05/cassette-tape.jpg 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/05/cassette-tape.jpg 1600w, https://thefamouslastpull.com/content/images/2022/05/cassette-tape.jpg 2000w" sizes="(min-width: 720px) 720px"><figcaption>This was the only way to &quot;stream&quot; music in my day!</figcaption></figure><p>By this point, half the song was gone. I listened to what remained, nodding my head to the rhythm, and felt certain I had enough to identify it. I lost a lot of time that day, re-winding the clip in-between pulling roots, forever burning it into my brain. </p><blockquote>Turn up the music<br>Turn down the lights<br>Turn up the music<br>Turn on the night</blockquote><p>The 80s, however, did me no favors in turning up the artist. No record store knew what I was talking about, and my (lack of a) singing voice didn&apos;t help. Radio stations offered little assistance &#x2013; even after I held my tape player up to the phone, forcing them to listen to the badly muffled recording. To improve my chances, I made sure every paper route I rode and every side job I took allowed me radio access, on the off-chance a station would play it again, revealing the artist and song title to me.</p><p>I never heard that song over the airwaves again.</p><hr><h2 id="the-90s">The 90s</h2><p>Ten years later, I was attending Malaspina College (now <a href="https://www.linkedin.com/school/vancouver-island-university/?ref=thefamouslastpull.com">Vancouver Island University</a>) and spending most of my time on a newly discovered system called called the &quot;Internet.&quot; Via a <a href="https://en.wikipedia.org/wiki/VAX?ref=thefamouslastpull.com" rel="noopener nofollow">VAX/VMS</a> system, I sent my first emails in <a href="https://en.wikipedia.org/wiki/Pine_(email_client)?ref=thefamouslastpull.com" rel="noopener nofollow">PINE</a> and learned of the Usenet through <a href="https://en.wikipedia.org/wiki/Tin_(newsreader)?ref=thefamouslastpull.com" rel="noopener nofollow">TIN</a>. Thanks to groups like alt.music, I became increasingly aware of online communities focused around specific interests. </p><p>&quot;Surely there are others like me,&quot; I thought, &quot;armchair investigators hell-bent on identifying mysterious songs&quot;. Alas, music detectives were far and few between. in those days. Any attempts to kick off a collaborative research effort fell on deaf ears. So, I moved from the Usenet to the World Wide Web.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://media-exp1.licdn.com/dms/image/C4E12AQF0FLGudcOL2A/article-inline_image-shrink_1000_1488/0/1551304098837?e=1657756800&amp;v=beta&amp;t=0mr7AemIdL7W1yXYFnEaPX25NomtNgwwkgGnc9W3w_I" class="kg-image" alt="Never Give Up" loading="lazy"><figcaption>Looking forward to the 2022 reboot of this search engine!</figcaption></figure><p>Search was a wild west in the 90s. HotBot, AltaVista, Webcrawler, and Yahoo! became my regular starting points to explore a vast sprawling network of online knowledge. These search engines led me to music fan sites, but no keyword search turned anything up that alluded to the mystery song from a decade prior. All I had to go on were the lyrics, and the lyrics just weren&apos;t producing any search results.</p><blockquote>Turn up the music<br>Turn down the lights<br>Turn up the music<br>Turn on the night</blockquote><p>As the 90s carried on, a host of distractions grew. I met my future wife online (also thanks to the Usenet, via rec.arts.disney), moved to the United States, got married, had kids, and started a career in web development. The hustle of family life &amp; career took precedence over all else. Childhood memories &#x2013; and the music that infused it &#x2013; were relegated to boxes in a dirty corner of the garage.</p><hr><p>Sometime in late 1998, I set up an FTP site to exchange training materials on web development with students (a side-hustle at the time). One day, I discovered a file I didn&apos;t recognize. The extension wasn&apos;t familiar to me; it ended in <code>.mp3</code>. I soon learned that this was highly compressed audio data, a format rapidly becoming the de-facto standard as a means to transmit songs digitally...so long as you had a computer powerful enough to decode one in real time (yes, some computers couldn&apos;t do that yet).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/05/windows-media-player.jpg" class="kg-image" alt="Never Give Up" loading="lazy" width="800" height="600" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/05/windows-media-player.jpg 600w, https://thefamouslastpull.com/content/images/2022/05/windows-media-player.jpg 800w" sizes="(min-width: 720px) 720px"><figcaption>MP3 skins in the late 90s were peak design</figcaption></figure><p>I pieced together how this file ended up on my server. An anonymous benefactor had discovered my FTP site, used my HTML &quot;course&quot; files, and offered up an MP3 as a means of payment. This was the unspoken rule of online file sharing: <em>take a file? leave a file</em> &#x2013; a ratio based honor system. The result was this audio file. I wondered, &quot;how many more files were out there?&quot;</p><p>An opening emerged &#x2013; a chance to re-open the cold case. Not only did I have the means to provide an audio example to anyone I thought might help my detective work, I had a strategy to get in: through the underground network of FTP sharing.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://media-exp1.licdn.com/dms/image/C4E12AQGmZQ7HzGtGpg/article-inline_image-shrink_1500_2232/0/1551303984813?e=1657756800&amp;v=beta&amp;t=b4tDSzTh-Fk50_GnuTrJIJqjcIYSR6k-Az9Bhn_O9IY" class="kg-image" alt="Never Give Up" loading="lazy"><figcaption>Slack is just IRC with a different UI!</figcaption></figure><p>By day, I built sites in Netscape and Internet Explorer...but by night, my tool of choice was mIRC. I dug through boxes, found the cassette, played it into my PC&apos;s microphone, compressed it into an MP3, and uploaded it to my FTP server, with the title <strong><code>identify_this_song_plz.mp3</code></strong> And whenever the opportunity arose in those online chat rooms of EFNet and Undernet, I shared the file with strangers, hoping that someone ...<em>anyone</em>...would recognize it.</p><p>Nobody did.</p><hr><h2 id="the-2000s">The 2000s</h2><p>Twenty years after my investigation began, access to the collective knowledge of the world grew exponentially. A two-year old company, Google, was growing in power: its search results quickly overshadowed all of the data of the previous search engines combined. Yet for all of Google&apos;s increasing market share, I <em>still</em> could not find a match for that song. The problem were the lyrics themselves: they were simply too generic. </p><blockquote>Turn up the music<br>Turn down the lights<br>Turn up the music<br>Turn on the night</blockquote><p>Even though the phrase <strong>&quot;turn up the music&quot;</strong> was permanently burned into my brain, every combination of those keywords simply returned reams of fan-based music sites. Instead of studio label information or production dates, my searches were filled another emerging trend: &quot;weblogs&quot; &#x2013; digital diaries of music fans encouraging party animals to twist their volume knob to the right.</p><p>As my career evolved from HTML development to full-stack web application programming, I kept with my rule from years previous &#x2013; if I wasn&apos;t listening to music on the radio, I was traveling the <strong>information superhighway</strong>, always on the prowl for a series of crumbs that might lead me to the mystery song.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://media-exp1.licdn.com/dms/image/C4E12AQHIECl66WZ9DQ/article-inline_image-shrink_1000_1488/0/1551303858355?e=1657756800&amp;v=beta&amp;t=M3fCgWWvg9DBYp2m4duAQJ_6Dyk_FnEeS6YtI7h5OhM" class="kg-image" alt="Never Give Up" loading="lazy"><figcaption>Oh, the CDs you&apos;ll burn!</figcaption></figure><p>By this time, Napster was the tool-of-choice for (what now seems like) a blip in time. Napster&apos;s days were numbered from the start. Music piracy proliferated in the years following my discovery of the MP3 file format; it looked all but certain that the RIAA would succeed at its years long battle to crush the file sharing network. But before the final nail was hammered into Napster&apos;s coffin, I scanned as much as I could, hoping to find any clue, any possible fragment of an incorrectly identified song (&quot;Desert Storm&quot;, anyone?) that <em>might</em> possibly lead me to solve the case.</p><p>No such luck.</p><p>So, I returned to IRC, slinking back to that digital underground of FTP sites shared anxiously among channels like <strong><code>#mp3-80s</code></strong>, hopping from one anonymous server to another, in the hopes of eventually landing on a gold mine of answers. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://media-exp1.licdn.com/dms/image/C4D12AQE_R8kus_T4Ag/article-inline_image-shrink_1000_1488/0/1551305096864?e=1657756800&amp;v=beta&amp;t=IvJfZzxemd9asPIhq7RCiPpZZpL3c-nCR_TnQA3t3OE" class="kg-image" alt="Never Give Up" loading="lazy"><figcaption>Only 1000 songs in your pocket? Amateurs...</figcaption></figure><p>Time passed and illegitimate music sharing gave way to legitimate music sales via Apple&apos;s iTunes, when Apple made a huge bet that people would buy individual songs for a buck, rather than entire albums. Was there a possibility that the artist or song might pop up there? </p><p>Foiled again.</p><p>My MP3 collection grew, yet it lacked the one song I sought the most.</p><hr><h2 id="the-2010s">The 2010s</h2><p>By now, my kids were grown and heading off to high school, their childhood home rapidly becoming a memory. My career shifted again, taking me out of development and into management &#x2013; I now faced the daily task of leading web developers instead of being one myself. It was 2014, a full <em>thirty</em> years after that day I&apos;d been digging in the dirt.</p><p>My wife and I faced a harsh truth: we were pack-rats, and our latest move to a rental property had opened our eyes to the excessive storage we consumed. We desperately needed to pare down. I began the tedious process of working my way through the unruly stack of boxes in the garage.</p><p>Unsurprisingly, listening to music helped this along.</p><p>A familiar looking box caught my eye. I proceeded to flip the lid open and rustled around inside. When I pulled my hand free, it clutched a familiar looking <em>cassette tape.</em></p><p>Thirty years of frustration flooded back to me...thirty years of dead leads. Three decades of technological evolution <em>still</em> hadn&apos;t delivered. I pulled the smartphone from my pocket and fired up Shazam. <em>It&apos;s 2014</em>, I thought. <em>Come on. We </em><strong><em>must </em></strong><em>have the technology to identify it now.</em></p><p>No dice.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://media-exp1.licdn.com/dms/image/C4D12AQGkKYmQRa1Ydw/article-inline_image-shrink_1500_2232/0/1551305942101?e=1657756800&amp;v=beta&amp;t=lZBwwtva5CE9kmEntGVHQem16jQfDsuELAHPFoWVekQ" class="kg-image" alt="Never Give Up" loading="lazy"><figcaption>Smartphones just tell you what song is playing in the background, now! Kids today don&apos;t have to do anything!</figcaption></figure><p>Machine Learning may be all the rage but it <em>still</em> wasn&apos;t enough to pattern match this poorly recorded snippet. For all its $500 million valuation (in 2014), at that moment in time, Shazam was about as valuable to me as the dust collecting at the bottom of that box.</p><p>Yet, I couldn&apos;t give up. I couldn&apos;t <em>not know</em> the answer to this.</p><p><em><a href="https://thefamouslastpull.com/never-give-up-part-2/">To be continued...</a></em></p>]]></content:encoded></item><item><title><![CDATA[There's Something About Factorio]]></title><description><![CDATA[Scrap the business books. If you want a real-life lesson in scaling your business, look no further than Factorio.]]></description><link>https://thefamouslastpull.com/theres-something-about-factorio/</link><guid isPermaLink="false">6262bcea60712809410864a5</guid><category><![CDATA[automation]]></category><category><![CDATA[games]]></category><category><![CDATA[transference-learning]]></category><dc:creator><![CDATA[Shawn Holmes]]></dc:creator><pubDate>Tue, 26 Apr 2022 04:40:51 GMT</pubDate><media:content url="https://thefamouslastpull.com/content/images/2022/04/factorio-header.png" medium="image"/><content:encoded><![CDATA[<img src="https://thefamouslastpull.com/content/images/2022/04/factorio-header.png" alt="There&apos;s Something About Factorio"><p>Ask a growing contingency of fans in the tech industry what their favorite business book is and they&apos;ll tell you to scrap the books in favor of <a href="https://www.factorio.com/?ref=thefamouslastpull.com">Factorio</a>. What is it about this game that appears empirically linked to success in business? Articles include:</p><ul><li><a href="https://www.thediff.co/p/the-factorio-mindset?ref=thefamouslastpull.com">The Factorio Mindset</a></li><li><a href="https://medium.com/@michaeljwest/the-kerbal-factorio-business-school-how-sim-games-teach-mental-models-9f14dc622036?ref=thefamouslastpull.com">The Kerbal-Factorio Business School: how sim games teach mental models</a></li></ul><p>Even the <a href="https://www.shopify.com/?ref=thefamouslastpull.com">Shopify</a> CEO Tobi Lutke raves about it, bragging that the company allows employees to expense game licenses:</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">Shopify lets people expense factorio. This idea is spreading &#x1F44C; <a href="https://t.co/lTnDKDDrmO?ref=thefamouslastpull.com">https://t.co/lTnDKDDrmO</a></p>&#x2014; tobi lutke (@tobi) <a href="https://twitter.com/tobi/status/1493007949119340555?ref_src=twsrc%5Etfw&amp;ref=thefamouslastpull.com">February 13, 2022</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure><p>So, what&apos;s the dealio with Factorio?</p><h2 id="the-martian-minus-potatoes">The Martian, minus potatoes</h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/04/factorio-crash.png" class="kg-image" alt="There&apos;s Something About Factorio" loading="lazy" width="1680" height="873" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/04/factorio-crash.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/04/factorio-crash.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/04/factorio-crash.png 1600w, https://thefamouslastpull.com/content/images/2022/04/factorio-crash.png 1680w" sizes="(min-width: 720px) 720px"><figcaption>You are here (but where is that?)</figcaption></figure><p>Factorio is a worldbuilding/survival game. In it, you (the player) have crash landed on a distant planet and must gather the necessary raw materials to repair your ship and return to space. Your means are scarce. Only the raw materials on the surface of the planet are what you have to work with: water, wood, iron, copper, stone, coal and (eventually) oil and uranium. You start with nothing, save but a few salvageable raw materials left in the wake of the crash.</p><p>Meanwhile, far off in the distance, alien life (think: building-sized bugs) are aware of your presence. The swarm grows. You are increasingly seen as a threat that must be neutralized.</p><p>The opening moments of a new game demand you embrace physical labor. You procure bits of raw stone and wood by hand. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/04/factorio-stone.png" class="kg-image" alt="There&apos;s Something About Factorio" loading="lazy" width="1680" height="1019" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/04/factorio-stone.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/04/factorio-stone.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/04/factorio-stone.png 1600w, https://thefamouslastpull.com/content/images/2022/04/factorio-stone.png 1680w" sizes="(min-width: 720px) 720px"><figcaption>The seven dwarves never had it this good</figcaption></figure><p>You assemble your first smelter (a stone furnace) and break your own back carrying coal and iron ore to it. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/04/factorio-smelter.png" class="kg-image" alt="There&apos;s Something About Factorio" loading="lazy" width="1680" height="1103" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/04/factorio-smelter.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/04/factorio-smelter.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/04/factorio-smelter.png 1600w, https://thefamouslastpull.com/content/images/2022/04/factorio-smelter.png 1680w" sizes="(min-width: 720px) 720px"><figcaption>The golden rule: whomever smelt it very likely dealt it</figcaption></figure><p>Eventually, you collect enough materials to toss into your smelter. As the kiln roars to life, the sweat of your labor bears fruit in the form of your first processed material: <em>iron plates</em>. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/04/factorio-crating-iron-plates.png" class="kg-image" alt="There&apos;s Something About Factorio" loading="lazy" width="1680" height="889" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/04/factorio-crating-iron-plates.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/04/factorio-crating-iron-plates.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/04/factorio-crating-iron-plates.png 1600w, https://thefamouslastpull.com/content/images/2022/04/factorio-crating-iron-plates.png 1680w" sizes="(min-width: 720px) 720px"><figcaption>Iron ore goes in on the left, iron plates come out on the right</figcaption></figure><p>Repeating this process &#x2013; digging, smelting, and the schlepping of raw earth to-and-fro &#x2013; eventually produces enough iron plates to create a single <em>conveyor belt</em>. </p><p>The seeds of an epiphany are planted. You determine that laying this belt between the source of the ore and the smelter eliminates the manual labor of hauling these items on your own &#x2013; you may simply dig and deposit them on the belt, where they are carried to the smelter automatically.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/04/factorio-conveyor.png" class="kg-image" alt="There&apos;s Something About Factorio" loading="lazy" width="1680" height="1001" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/04/factorio-conveyor.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/04/factorio-conveyor.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/04/factorio-conveyor.png 1600w, https://thefamouslastpull.com/content/images/2022/04/factorio-conveyor.png 1680w" sizes="(min-width: 720px) 720px"><figcaption>Thomas Robbins would be proud!</figcaption></figure><p>As your stockpile of processed materials grow, you gain the ability to build a mining <em>drill</em> that will dig for you (provided you supply the drill with fuel), depositing its results directly on the belt.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/04/factorio-drilling-iron.png" class="kg-image" alt="There&apos;s Something About Factorio" loading="lazy" width="1680" height="1182" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/04/factorio-drilling-iron.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/04/factorio-drilling-iron.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/04/factorio-drilling-iron.png 1600w, https://thefamouslastpull.com/content/images/2022/04/factorio-drilling-iron.png 1680w" sizes="(min-width: 720px) 720px"><figcaption>(in a Laurence Fishburne voice) &quot;Machines!&quot;</figcaption></figure><p>A few more materials beyond that, and you may craft an <em>inserter</em> &#x2013; a robot-like device with a claw that can transfer an item from a source (eg. a conveyor belt) to a destination (eg. a smelter).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/04/factorio-inserter.png" class="kg-image" alt="There&apos;s Something About Factorio" loading="lazy" width="1680" height="982" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/04/factorio-inserter.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/04/factorio-inserter.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/04/factorio-inserter.png 1600w, https://thefamouslastpull.com/content/images/2022/04/factorio-inserter.png 1680w" sizes="(min-width: 720px) 720px"><figcaption>Inserters give you a hand (or a claw)</figcaption></figure><p>Once you have:</p><ul><li>a drill digging for you, </li><li>an inserter handing-off materials for you, and</li><li>a conveyor belt transferring materials from location (a) to location (b) for you,</li></ul><p>...the epiphany finally takes shape: With some thought and planning, it becomes clear that you can design a process that will sustain itself, digging, fueling, and processing ore, without any human intervention whatsoever.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/04/factorio-automation.png" class="kg-image" alt="There&apos;s Something About Factorio" loading="lazy" width="1680" height="986" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/04/factorio-automation.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/04/factorio-automation.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/04/factorio-automation.png 1600w, https://thefamouslastpull.com/content/images/2022/04/factorio-automation.png 1680w" sizes="(min-width: 720px) 720px"><figcaption>A simple automation that digs coal &amp; iron, produces iron plates, and sustains itself with fuel</figcaption></figure><p>And thus, the race to <em>automate everything</em> begins.</p><hr><p>Many worldbuilding/survival games exist. The escape from a distant &amp; hostile planet is certainly not a new concept as far as video games go. What is so novel about Factorio&apos;s approach? Why does it lend itself particularly well to lessons needed in scaling a business?</p><p>To answer this, we must dive into where things go off the rails.</p><h2 id="the-problem-of-scale">The Problem of Scale</h2><p>In the early stages of the game, setting up dozens of automated belts, miners and inserters is an free-form design exercise, lacking consistency or convention. As the game plays out, you come to find that processed materials are <em>themselves</em> needed for larger, more complex devices. Remember that <em>burner drill</em> I pointed out earlier? It requires a stone furnace as an ingredient.</p><p>Routing belts back and forth between sources and destinations quickly becomes a mess. Without intending to, you introduce <em>bottlenecks</em> into your processing centers. And as you switch gears to clean-up those bottlenecks, you find yourself producing new issues of <em>resource starvation</em> &#x2013; parts of your factory that aren&apos;t getting enough materials.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/04/factorio-maze.png" class="kg-image" alt="There&apos;s Something About Factorio" loading="lazy" width="1680" height="1259" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/04/factorio-maze.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/04/factorio-maze.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/04/factorio-maze.png 1600w, https://thefamouslastpull.com/content/images/2022/04/factorio-maze.png 1680w" sizes="(min-width: 720px) 720px"><figcaption>I demand to see the manager responsible for this mess</figcaption></figure><p>Meanwhile, you are (in parallel) trying to scale up your power needs (since all those drills and inserters require fuel). Your early sources of power come from burning wood &amp; coal, so as you scale up your power production, your noise &amp; air pollution scales up in kind.</p><p><em>Did I mention the building-sized bugs don&apos;t like pollution?</em></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/04/factorio-bug-attack.png" class="kg-image" alt="There&apos;s Something About Factorio" loading="lazy" width="1680" height="1026" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/04/factorio-bug-attack.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/04/factorio-bug-attack.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/04/factorio-bug-attack.png 1600w, https://thefamouslastpull.com/content/images/2022/04/factorio-bug-attack.png 1680w" sizes="(min-width: 720px) 720px"><figcaption>OH GOD GET THEM OFF ME THEY&apos;RE BIGGER THAN A TANK</figcaption></figure><p>The problems continue. Before long, you discover that the ore deposit is almost entirely exhausted. Now, you face the problem of bringing in new resources from some remote location. What infrastructure will that require? (hint: high-speed rail). Venturing out to collect some oil? How are you supposed to transport liquids? You can&apos;t pour oil on a conveyor belt...additional infrastructure must be created to drill, store, transport, and refine it.</p><p>An alert pops on the screen &#x2013; the alien bugs have had it. They&apos;re attacking your pollution-producing generators, knocking them offline. Your entire operation shuts down. You need to get it back online (fast!) while also (in parallel) building in defensive mechanisms &#x2013; walls, guns, radar &#x2013; that can warn &amp; protect against future attacks. </p><p>It&apos;s not enough to build weapons, though &#x2013; weapons need ammunition. <em>More materials! More belts! More processing centers!</em> But without power or materials, how will these new demands be met? How will they be built? What existing materials can be leveraged to close this gap in the short-term, in order to fulfill the long-term goal of <em>getting the hell off this alien-infested planet?</em></p><h2 id="a-metaphor-for-startup-life">A Metaphor for Startup Life</h2><p>Most of the techies that turned me on to Factorio agree that the game is exceptional at teaching you how to grow small operations into large, complex systems. I&apos;m a firm believer this metaphor extends to startup life as well. If you weren&apos;t shrewd enough to pick up on some of my references above, let me make it easy for you:</p><ol><li>Scale demands automation; efficient scale demands process.</li><li>Solutions create new problems.</li><li>There are good problems and bad problems &#x2013; both need solving, and both require different degrees of urgency and focus.</li><li>Trade-offs are made constantly; what matters is comprehending the impact of each concession.</li></ol><p>Each of these bullets is (at least) a complete post in and of itself &#x2013; here&apos;s an attempt at a summary.</p><h3 id="1-scale-demands-automation-efficient-scale-demands-process">1. Scale demands automation; efficient scale demands process.</h3><p>Snake-like conveyor belts will get you nowhere; only an agreed-upon system that meets convention and is repeatable can scale. The Factorio community has a term describing an agreed-upon design that helps all players scale their factories: the &quot;main bus.&quot; Even Tobi knows it:</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">Senior leadership team of shopify was called main bus for a few years</p>&#x2014; tobi lutke (@tobi) <a href="https://twitter.com/tobi/status/1493236191109517318?ref_src=twsrc%5Etfw&amp;ref=thefamouslastpull.com">February 14, 2022</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure><p>If you have any hope of scaling your operation, you will find it in putting aside childish notions of &quot;keeping things fluid&quot;, &quot;going with with the flow&quot;, and &quot;not being too rigid&quot; &#x2013; all of which are coded terms for <em>not having the discipline to agree upon rules of engagement</em>. Without the basics of, say, agreeing on how your team&apos;s code is committed, reviewed, merged into the repo, and deployed to an environment, those bugs (real or alien) find quick paths into your power centers and take them offline, fast.</p><h3 id="2-solutions-create-new-problems">2. Solutions create new problems.</h3><p>Manual processes are very often the cause of bottlenecks, but automation isn&apos;t necessarily a panacea. If your sales team isn&apos;t able to keep up with email and SMS communications, turning to robots might produce entirely new issues. With hundreds (thousands?) of emails now en route at the press of a button, can you control them? Can you throttle them? Are you being charged for double (or worse) than what you expected? Sure, you&apos;re communicating at scale, but are you <em>being added to spam lists at scale, too?</em></p><p>Every tactic you employ in Factorio has a compounding effect, and it doesn&apos;t take long before you get very good at a<em>nticipating the impact of your solution</em>. Not enough copper? Doubling your copper furnaces only serves to jam your conveyor belts up. One solution creates another problem.</p><p>Whenever you hear someone in our biz say &quot;hurry up and slow down,&quot; this is what we mean. If you want to get very good at thinking about how things might go wrong, Factorio is a great (and less expensive!) way to learn those lessons.</p><h3 id="3-good-problems-and-bad-problems-require-different-levels-of-urgency-and-focus">3. Good problems and bad problems require different levels of urgency and focus.</h3><p>A bad problem in business: No leads; a good problem in business: too many leads.</p><p>No leads means no sales; no sales means no paychecks. This is your &quot;alien bugs banging on the walls&quot; problem. When this happens, you drop everything and swarm to defend. There isn&apos;t time to think, only respond. Nothing deters you until you eliminate the invasion, stabilize the factory, restore power and put new defenses in place.</p><p>Too many leads means sales are dying on the vine. Your sales team can only close so many so fast, but who should they pick first? How should they segment the list? What can be done improve their workflow? This is your &quot;resource bottleneck/starvation&quot; problem. With some careful planning (see above, re: solutions create new problems), you can identify ways to take the load off the team and <em>maybe</em> automate <em>certain pieces</em> of their workload.</p><p>Factorio is great at giving you a healthy mix of good and bad problems. It is a sandbox in which to test both your resilience and your thoughtfulness.</p><h3 id="4-understanding-the-impact-of-each-trade-off">4. Understanding the impact of each trade-off.</h3><p>Anyone tested in (startup) battle will tell you that it is a constant exercise in &quot;good enough&quot;, best summarized in this meme:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/04/simpsons-tap-sign.jpg" class="kg-image" alt="There&apos;s Something About Factorio" loading="lazy" width="500" height="739"><figcaption>Evergreen meme</figcaption></figure><p>If I&apos;ve just built a railroad to import copper (because my local copper deposits are exhausted), does it make sense to <em>also</em> build an automation to fuel the train? Not if I can fuel it by hand once (or via a single wooden crate filled with coal) and have that train make its run dozens of times before needing to be refueled.</p><p>The same can be said of a business faced with building a solution vs. buying one. Why would we develop a UI by hand if it is:</p><ul><li>internally facing, and</li><li>85% of the functionality is already available in a NoCode platform like<a href="https://retool.com/?ref=thefamouslastpull.com"> Retool</a>?</li></ul><p>This lesson becomes more concrete as you grow your factory and the impacts of earlier trade-offs compound. If one focuses all their time on researching science, one should not be surprised to turn around and discover <em>giant alien bugs eating their face off</em>. </p><p>The same can be said for outsourcing development of startup&apos;s core IP and then watching in abject horror as your servers crash under load...and <em>not</em> having any on-staff expertise to swarm on the fix.</p><p>When Factorio geeks talk about the game teaching leverage, <em>this</em> is what they mean. It&apos;s the same reason a seasoned technical leader will agree to (what appears at first as) a half-assed solution to close a gap. Voluntarily taking on technical debt isn&apos;t done out of ignorance &#x2013; it&apos;s done <strong>to solve the right problem at the right time</strong>, knowing it is good enough to hold...<em>for now</em>. Our time, energy &amp; resources are limited...and the bugs are banging on the walls.</p><p><a href="https://www.linkedin.com/in/chris-loar-99b05a26/?ref=thefamouslastpull.com">Chris</a> and I have talked at length about<a href="https://www.amazon.com/80-20-Principle-Secret-Achieving/dp/0385491743/?ref=thefamouslastpull.com"> The 80/20 Principle</a>; Factorio is incredibly effective at giving you a real-world lesson in it. You absolutely <em>can</em> take short-cuts (and in many cases, you&apos;ll have no choice). You <em>will</em> feel the repercussions of those choices later.</p><h2 id="automation-leverage-101">Automation &amp; Leverage 101</h2><p>I&apos;ve only just breached the surface of Factorio in this post &#x2013; there&apos;s an incredible amount of cool stuff revealed as the game progresses (eg. logic circuits, robot-based construction, etc.) so I encourage you to try it out. It&apos;s a surprisingly fun and fascinating way to look at the many different ways a complex system can be faulty or beautifully efficient. </p><p>You will come out of a Factorio game with a much greater sensibility around automation &amp; leverage. I&apos;ve taken a page from Tobi &#x2013; my engineering team at <a href="https://wrapmate.com/?ref=thefamouslastpull.com">Wrapmate</a> is also able to expense the game. Who cares what business books you&apos;ve read! <em>Can you complete Factorio on <a href="https://wiki.factorio.com/Map_generator?ref=thefamouslastpull.com#Death_world">death world</a> settings?</em></p><p>On the Factorio subreddit, fans have deduced that <a href="https://www.reddit.com/r/factorio/comments/4mzxdj/comment/d68t2fo/?ref=thefamouslastpull.com">the iron demands (alone) to go from nothing to functional spaceship is 7,619,920,134 raw ore</a>. You&apos;re not going to be digging and processing that by hand! But if you are savvy enough to build a system capable of pulling that off, and dealing with all of the hurdles you&apos;ll face along the way, I suspect you won&apos;t be far off in being able to apply what you&apos;ve learned in the real world.</p><p>Just remember to keep an eye out for those building-sized bugs.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/04/factorio-laser-bugs.png" class="kg-image" alt="There&apos;s Something About Factorio" loading="lazy" width="1280" height="720" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/04/factorio-laser-bugs.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/04/factorio-laser-bugs.png 1000w, https://thefamouslastpull.com/content/images/2022/04/factorio-laser-bugs.png 1280w" sizes="(min-width: 720px) 720px"><figcaption>When (alien) bugs attack</figcaption></figure>]]></content:encoded></item><item><title><![CDATA[Enhancing Wordle Scorekeeping with Zapier]]></title><description><![CDATA[Encourage some healthy competition with this Zapier tutorial that automates Wordle scorekeeping.]]></description><link>https://thefamouslastpull.com/enhancing-wordle-scorekeeping-zapier/</link><guid isPermaLink="false">622f546d0f3050060b6bfc48</guid><category><![CDATA[automation]]></category><category><![CDATA[Zapier]]></category><category><![CDATA[Wordle]]></category><category><![CDATA[team-building]]></category><category><![CDATA[remote-work]]></category><category><![CDATA[Slack]]></category><category><![CDATA[Google Sheets]]></category><dc:creator><![CDATA[Shawn Holmes]]></dc:creator><pubDate>Wed, 16 Mar 2022 14:50:31 GMT</pubDate><media:content url="https://thefamouslastpull.com/content/images/2022/03/wordle_header.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://thefamouslastpull.com/content/images/2022/03/wordle_header.jpg" alt="Enhancing Wordle Scorekeeping with Zapier"><p>A great way to foster some remote team building is by encouraging playful competition among your distributed folks. <a href="https://www.nytimes.com/games/wordle/index.html?ref=thefamouslastpull.com">Wordle</a> is a great way to do this! If you set up a channel at work and have players regularly share their scores, the competition heats up quickly. At <a href="https://wrapmate.com/?ref=thefamouslastpull.com">Wrapmate</a>, we currently have a #wordlebracket Slack channel that is getting plenty of activity.</p><p>However, when it comes time to say who won or lost, there&apos;s not much out there in the way of automatically calculating scores or reporting on them. Who has time to manually crunch numbers? Isn&apos;t that what automation is for?</p><p>Several weeks ago, <a href="https://zapier.com/?ref=thefamouslastpull.com">Zapier</a>&apos;s newsletter sent out a great link on <a href="https://zapier.com/blog/automate-weekly-wordle-competition/?ref=thefamouslastpull.com">how to automate the collection of Wordle scores</a> by forwarding scores in an email and having Zapier parse those results and store them in a Google Sheet.</p><p>Today, we&apos;re going to up the ante. We&apos;ll keep the Google Sheet, but do 2 new things:</p><ol><li>Ditch the email parser for a <a href="https://slack.com/?ref=thefamouslastpull.com">Slack</a> parser, so that when a player shares a <a href="https://www.nytimes.com/games/wordle/index.html?ref=thefamouslastpull.com">Wordle</a> score in a specific channel, Zapier will capture the score and store it in the Google Sheet, and</li><li>Create a single bot-like response for any participating player in the same channel to have that player&apos;s score posted back to the channel.</li></ol><p><em>This</em>...is Zapier Wordle Leaderboard II Turbo: Champion Edition!</p><hr><h2 id="part-1-parsing-shared-wordle-score-in-slack-channel">Part 1: Parsing Shared Wordle Score in Slack Channel</h2><p>Before we get started, read up on the original <a href="https://zapier.com/blog/automate-weekly-wordle-competition/?ref=thefamouslastpull.com">Zapier post</a>, and be sure to grab a copy of the <a href="https://docs.google.com/spreadsheets/d/1NucHDiPC1ZTDVP3EhksYexQxMmC1tnYKpRhsEic1blU/edit?ref=thefamouslastpull.com#gid=1172082760">Google Sheet</a> they use.</p><p>The first zap we&apos;ll be importing is the one that <a href="https://zapier.com/shared/116a9570801d1dd0e0cb4cdf6e33d9862f8b5a2e?ref=thefamouslastpull.com">parses a shared Wordle score in a specific Slack channel</a>.</p><p>Since this will be an imported zap, I&apos;ll only go over the basics here. The zap consists of 5 steps:</p><ol><li>Trigger: New Message Posted to Channel in Slack</li><li>Action: Only continue if...</li><li>Action: Only continue if...</li><li>Action: Text</li><li>Action: Create Spreadsheet Row in Google Sheets</li></ol><p>Here are the key pieces to know for each of these 5 steps.</p><h2 id="step-1-new-message-posted-to-channel-in-slack">Step 1. New Message Posted to Channel in Slack</h2><p>The key piece of this step is deciding on a single channel that you&apos;ll not only share your Wordle scores in, but also as the destination for Wordlebot to respond to requests.</p><p>Decide on that channel, and set it in the &quot;Channel&quot; field &#x2013; in my version, we&apos;ve decided to share Wordle scores in the #wordlebracket channel, so I&apos;ve set mine to wordlebracket.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/image-9.png" class="kg-image" alt="Enhancing Wordle Scorekeeping with Zapier" loading="lazy" width="930" height="143" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/image-9.png 600w, https://thefamouslastpull.com/content/images/2022/03/image-9.png 930w" sizes="(min-width: 720px) 720px"><figcaption>Set the channel in the zap like this</figcaption></figure><h2 id="step-2-only-continue-if">Step 2: Only Continue If...</h2><p>This step is a Filter by Zapier that proceeds only if a Wordle score is detected, which begins simply with an attempt to find the word &quot;Wordle&quot; in that post.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/image-10.png" class="kg-image" alt="Enhancing Wordle Scorekeeping with Zapier" loading="lazy" width="919" height="367" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/image-10.png 600w, https://thefamouslastpull.com/content/images/2022/03/image-10.png 919w" sizes="(min-width: 720px) 720px"><figcaption>Set the filter rule in the zap like this</figcaption></figure><h2 id="step-3-only-continue-if">Step 3: Only Continue If...</h2><p>This next step is the key to the entire detection phase: determining if what was entered into the Slack channel is an actual Wordle score (as opposed to someone simply mentioning the word &quot;Wordle&quot; in discussions).</p><p>For this, we look for the existence of either:</p><ul><li>:black_large_square:</li><li>:large_green_square:</li><li>:white_large_square:</li><li>:large_yellow_square:</li></ul><p>The first guess of the shared Wordle score must have at least one of these four colored squares, so that&apos;s how we determine it is a message we care about parsing &amp; logging into the Google Sheet.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/image-11.png" class="kg-image" alt="Enhancing Wordle Scorekeeping with Zapier" loading="lazy" width="926" height="842" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/image-11.png 600w, https://thefamouslastpull.com/content/images/2022/03/image-11.png 926w" sizes="(min-width: 720px) 720px"><figcaption>Each of the emoji detections are added as &quot;OR&quot; because we only need one</figcaption></figure><h2 id="step-4-formatter-by-zapier-text-extract-pattern">Step 4: Formatter by Zapier / Text / Extract Pattern</h2><p>The fourth step does the heavy lifting. At this point we&apos;ve determined the Slack message is, in fact, a valid Wordle score. Now we must parse it. How? Regular Expressions, of course!</p><p>The input will be the actual Slack message posted in Step 1.</p><p>The pattern we&apos;ll use to parse is this:</p><p><code>Wordle ([0-9]+) ([0-9]+)/([0-9]+)</code></p><p>This grabs the three pieces of info we care about (indicated by the three sets of parenthesis in the pattern). They are (left-to-right)</p><ol><li>The ID of the Wordle game being played,</li><li>The score, and</li><li>The hard mode score.</li></ol><h2 id="step-5-create-spreadsheet-row-in-google-sheets">Step 5: Create Spreadsheet Row in Google Sheets</h2><p>Now that we have our parsed score, it&apos;s time to write it directly to Google Sheets.</p><p>The key values you care about setting here are:</p><ul><li><strong>Drive:</strong> The Google Drive where the Wordle spreadsheet resides (you <em>did</em> grab <a href="https://docs.google.com/spreadsheets/d/1NucHDiPC1ZTDVP3EhksYexQxMmC1tnYKpRhsEic1blU/edit?ref=thefamouslastpull.com#gid=1172082760">a copy of the spreadsheet</a> from the <a href="https://zapier.com/blog/automate-weekly-wordle-competition/?ref=thefamouslastpull.com">original Zapier tutorial</a>, right?)</li><li><strong>Spreadsheet:</strong> The actual spreadsheet copy mentioned in the previous bullet</li><li><strong>Worksheet:</strong> The tab/sheet inside the file you want to write data to &#x2013; this should be the fourth tab, which (if not renamed) is called &quot;Receive Info &#x2013; Read Only&quot;</li><li><strong>Sender:</strong> This should be the &quot;User Real Name&quot; property from the Slack message in Step 1.</li><li><strong>Wordle ID:</strong> This is &quot;Output 0&quot; from Step 4.</li><li><strong>Date:</strong> This is the &quot;Ts Time&quot; field from the Slack message in Step 1.</li><li><strong>Score:</strong> This is &quot;Output 1&quot; from Step 4.</li><li><strong>Hard Mode?</strong>: This is &quot;Output 2&quot; from Step 4.</li></ul><p>When complete, it should look something like this:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/image-12.png" class="kg-image" alt="Enhancing Wordle Scorekeeping with Zapier" loading="lazy" width="924" height="1009" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/image-12.png 600w, https://thefamouslastpull.com/content/images/2022/03/image-12.png 924w" sizes="(min-width: 720px) 720px"><figcaption>Double check your settings in this screenshot</figcaption></figure><p>Nice!</p><h2 id="finishing-up">Finishing Up</h2><p>Don&apos;t forget to turn your zap on! Now, play a game of Wordle and when you&apos;re prompted with the &quot;Share&quot; button, click it to copy the score into the clipboard, flip over to your Slack channel, and paste the score in!</p><p>That looks like something like this:</p><figure class="kg-card kg-image-card"><img src="https://thefamouslastpull.com/content/images/2022/03/image-13.png" class="kg-image" alt="Enhancing Wordle Scorekeeping with Zapier" loading="lazy" width="250" height="155"></figure><p>Then, pop open your Google Sheet, and head over to the fourth tab to confirm it wrote the score out!</p><figure class="kg-card kg-image-card"><img src="https://thefamouslastpull.com/content/images/2022/03/image-14.png" class="kg-image" alt="Enhancing Wordle Scorekeeping with Zapier" loading="lazy" width="865" height="225" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/image-14.png 600w, https://thefamouslastpull.com/content/images/2022/03/image-14.png 865w" sizes="(min-width: 720px) 720px"></figure><p>Beautiful. Now...on to part 2!</p><hr><h2 id="part-2-have-a-bot-read-back-a-players-wordle-scores">Part 2: Have a Bot Read Back a Player&apos;s Wordle Scores</h2><p>Let&apos;s take a look at the zap that allows a Wordle player to request their scores. </p><p><strong>NOTE:</strong> As of this writing, I can&apos;t share a link to the zap (Zapier barks out an error), so you will have to set this up manually following the instructions below.</p><h3 id="step-1-trigger-when-new-message-posted-to-channel-in-slack">Step 1: Trigger (WHEN) New Message Posted to Channel in Slack</h3><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/image.png" class="kg-image" alt="Enhancing Wordle Scorekeeping with Zapier" loading="lazy" width="917" height="745" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/image.png 600w, https://thefamouslastpull.com/content/images/2022/03/image.png 917w" sizes="(min-width: 720px) 720px"><figcaption>Be sure to use the same Slack channel you used in Part 1</figcaption></figure><p>As with Part 1, select:</p><ol><li>Your app (Slack) and your event trigger (New Message Posted to Channel in Slack), and</li><li>Your account (your Slack account).</li></ol><p>In &quot;Set up trigger&quot;, select the same channel as you used in the previous section &#x2013; the channel that your team or office is sharing their Wordle scores to. Go ahead and leave &quot;Trigger for Bot Messages?&quot; set to &quot;No.&quot;</p><h2 id="step-2-only-continue-if-1">Step 2: Only continue if...</h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/image-1.png" class="kg-image" alt="Enhancing Wordle Scorekeeping with Zapier" loading="lazy" width="914" height="529" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/image-1.png 600w, https://thefamouslastpull.com/content/images/2022/03/image-1.png 914w" sizes="(min-width: 720px) 720px"><figcaption>This zap looks for the phrase you&apos;ll type into your Slack channel to get the Wordlebot to respond</figcaption></figure><p>For this 2nd step, select &quot;Filter by Zapier&quot; and enter in only a single piece of criteria:</p><ul><li>Only continue if... (Text) -&gt; (Text) Contains -&gt; Wordlebot scores</li></ul><p>Nice! Moving on...</p><h2 id="step-3-get-many-spreadsheet-rows-advanced-with-line-item-support-in-google-sheets">Step 3: Get many Spreadsheet Rows (Advanced, With Line Item Support) in Google Sheets</h2><p>As with Part 1, select:</p><ol><li>Your app (Google Sheets) and your event trigger (Get Many Spreadsheet Rows - Advanced, With Line Item Support), and</li><li>Your account (your Google Sheets account).</li></ol><p>Then, under &quot;Set up action&quot;, let&apos;s go over the individual settings:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/image-2.png" class="kg-image" alt="Enhancing Wordle Scorekeeping with Zapier" loading="lazy" width="916" height="1118" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/image-2.png 600w, https://thefamouslastpull.com/content/images/2022/03/image-2.png 916w" sizes="(min-width: 720px) 720px"><figcaption>Double check all your settings against the screenshot above</figcaption></figure><p>The settings are as follows:</p><ul><li><strong>Drive:</strong> Select the Google Drive that has a copy of the Wordle Scores template you copied from Part 1.</li><li><strong>Spreadsheet:</strong> Select the Google Sheets file that represents the copy of the Wordle scores template, again from Part 1.</li><li><strong>Worksheet</strong>: Select &quot;Display Info&quot; (or, if you&apos;ve changed the names of the sheets, select the 2nd sheet &#x2013; that sheet has contains the full leaderboard, and which looks like this:</li></ul><figure class="kg-card kg-image-card"><img src="https://thefamouslastpull.com/content/images/2022/03/image-3.png" class="kg-image" alt="Enhancing Wordle Scorekeeping with Zapier" loading="lazy" width="1219" height="369" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/image-3.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/image-3.png 1000w, https://thefamouslastpull.com/content/images/2022/03/image-3.png 1219w" sizes="(min-width: 720px) 720px"></figure><ul><li><strong>Columns:</strong> A:K</li><li><strong>Row Count:</strong> Set this to the maximum number of players you feel your scoreboard will ultimately have; it won&apos;t break if it is larger than your current number of players.</li><li><strong>First Row</strong>: Set it to 1, as we&apos;ll want to include the header row when we parse this out.</li><li><strong>Should this step be considered a &quot;success&quot; when nothing is found?</strong>: Leave this at &quot;No.&quot;</li></ul><p>Once set up, the test data should come back in the form of a &quot;rows&quot; object, with the 1st row having 11 columns &#x2013; the 11 different column headers (eg. &quot;Sender&quot;, &quot;Played&quot;, &quot;Win %&quot;, etc.)</p><h2 id="step-4-code-by-zapier-run-javascript">Step 4: Code by Zapier / Run Javascript</h2><p>For the next step, you&apos;re going to choose the &quot;Code by Zapier&quot; app, and for its &quot;Action Event&quot;, you&apos;ll have it run custom Javascript. Here&apos;s how to set up that action:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/image-4.png" class="kg-image" alt="Enhancing Wordle Scorekeeping with Zapier" loading="lazy" width="922" height="1138" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/image-4.png 600w, https://thefamouslastpull.com/content/images/2022/03/image-4.png 922w" sizes="(min-width: 720px) 720px"><figcaption>In the Run Javascript zap, be sure to set the two input parameters as shown above</figcaption></figure><p>Under &quot;Input Data&quot; you&apos;re going to create two keys / value pairs:</p><ol><li>Set the first key to <code>text</code> and its value to the &quot;Rows&quot; element of the Google Sheet in Step 3.</li><li>Set the second key to <code>player</code> and its value to the &quot;User Real Name&quot; element of the Slack message in Step 1.</li></ol><p>Then, in the &quot;Code&quot; section, copy and paste this block:</p><!--kg-card-begin: html--><pre>
const csv = inputData.text.split(&apos;,&apos;);
const colCount = 11;
       
let obj = {};
let arrKeys = [];

// keys first
for (let i=0; i &lt; colCount; i++) {
  arrKeys.push( csv[i] );
}

// rest of the values, starting with our prev. stopping point
for (let j=colCount; j &lt; csv.length;) {

  let person = &apos;&apos;;
  let stats = {};  

  // 1 row at a time, by # of columns in colCount
  for (let k=1; k % colCount != 0; k++) {
  
    let name = arrKeys[k-1];
    let value = csv[j];
       
    if (k == 1) {
      person = value;
    } else {
      stats[name] = value;
    }
    
    j++; // move forward in the csv
    
  }
  
  // if we&apos;ve reached the end of a row
  obj[person] = stats; 
  
  j++; // move forward in the csv

}

output = obj[inputData.player];
</pre><!--kg-card-end: html--><p>In a nutshell, this:</p><ul><li>converts the entire Google Sheet (Rows) object into a single long CSV string.</li><li>parses out the headers (row 1) first, and stores them in <code>arrKeys</code>.</li><li>parses out the remainder of the csv, moving in blocks of <code>colCount</code> (11, for the number of column headers there are), breaking out each row by creating a string for the <code>person</code>&apos;s name or a <code>stats</code> object with a matching key and value (eg. <code>stats[&quot;Played&quot;] = 6</code>).</li><li>Adds the entire parsed set of data, by each <code>person</code>&apos;s name, to a parent <code>obj</code>.</li><li>Returns only the key of the parent <code>obj</code> who originally requested the scores, eg the Slack user&apos;s full name, mapped to <code>inputData.player</code></li></ul><p>If you&apos;ve been following along, you know realize the fun fact: <em>the entire scoreboard is available via</em> <code>obj</code>. We just choose to return an individual player&apos;s scores. You can expand on this!</p><h2 id="step-5-send-channel-message-in-slack">Step 5: Send Channel Message in Slack</h2><p>The final step is having our &quot;Wordlebot&quot; respond to the score request by writing out a response that includes all the juicy details of the person&apos;s score and posting it back to Slack.</p><ol><li>Select &quot;Slack&quot; and for its &quot;Action Event&quot;, choose &quot;Send Channel Message&quot;</li><li>Choose your account (same as in Step 1)</li><li>For &quot;Set up action&quot;, use these values:</li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/image-5.png" class="kg-image" alt="Enhancing Wordle Scorekeeping with Zapier" loading="lazy" width="918" height="1122" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/image-5.png 600w, https://thefamouslastpull.com/content/images/2022/03/image-5.png 918w" sizes="(min-width: 720px) 720px"><figcaption>Remember that you can customize the bot&apos;s message in the &quot;Message Text&quot; field</figcaption></figure><ul><li><strong>Channel:</strong> Set this to the same channel as what was specified in Step 1</li><li><strong>Message Text</strong>: You can format this however you want, my script reads like this:</li></ul><!--kg-card-begin: markdown--><p><code>{{149341023__user__real_name}} has played {{149345309__Played}} games, with a win percentage of {{149345309__Win %}}, and a current winning streak of {{149345309__Current Win Streak}}. Their best Wordle score was {{149345309__Best Wordle Row}} rows, and accomplished this {{149345309__# of Best Wordles?}} time(s).  Overall, they have an an average Wordle score of {{149345309__Current Average Wordle Score}}. For this week&apos;s competition, their score is {{149345309__Weekly Competition Score}}. Additionally, they have missed {{149345309__How Many Missed Wordles}} games, and have made {{149345309__Hard Mode Attempts?}} attempts at hard mode.</code></p>
<!--kg-card-end: markdown--><p>The key here is that wherever you see a <code>{{number__header_name}}</code> above, you&apos;re selecting a variable that is produced from the output of <strong>Step 4. Run Javascript</strong>. Your <code>number</code> will likely be different than mine, so if you get confused or aren&apos;t sure, remember that when you click inside the Zapier text fields, you can choose each value from the dropdown menu in the Zapier UI itself, like this:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/image-6.png" class="kg-image" alt="Enhancing Wordle Scorekeeping with Zapier" loading="lazy" width="910" height="506" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/image-6.png 600w, https://thefamouslastpull.com/content/images/2022/03/image-6.png 910w" sizes="(min-width: 720px) 720px"><figcaption>If you get stuck, you can use the Zapier UI data population menu to choose the exact fields</figcaption></figure><ul><li><strong>Send as a bot:</strong> Yes</li><li><strong>Bot Name:</strong> I like &quot;Wordlebot&quot; &#x2013; call it whatever you want.</li><li><strong>Bot Icon:</strong> I used :robot_face: but you can use whatever you wish.</li><li><strong>Include a link to this zap?:</strong> No</li></ul><p>Everything else can be left at their default.</p><h2 id="finishing-up-1">Finishing Up</h2><p>You&apos;re done! Don&apos;t forget to turn the zap on. Then, head over to your Slack channel and type &quot;Worldlebot scores&quot; and moments later, you should see a response similar to this:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/image-8.png" class="kg-image" alt="Enhancing Wordle Scorekeeping with Zapier" loading="lazy" width="923" height="102" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/image-8.png 600w, https://thefamouslastpull.com/content/images/2022/03/image-8.png 923w" sizes="(min-width: 720px) 720px"><figcaption>Wordlebot lives!!!</figcaption></figure><p>Success! Zapier and your new Wordlebot do the heavy lifting of capturing scores, and reading them back to the Slack channel, so you can focus on the more important work &#x2013; <em>destroying your competition!</em></p>]]></content:encoded></item><item><title><![CDATA[Powerful Roadmaps Look Like Outrun]]></title><description><![CDATA[Nearly all product roadmaps suffer from one major flaw. The solution is buried in a hit racing video game from 1986.]]></description><link>https://thefamouslastpull.com/powerful-roadmaps-look-like-outrun/</link><guid isPermaLink="false">622cfc0e0f3050060b6bfa55</guid><category><![CDATA[product-management]]></category><category><![CDATA[transference-learning]]></category><category><![CDATA[video-games]]></category><category><![CDATA[software-development]]></category><dc:creator><![CDATA[Shawn Holmes]]></dc:creator><pubDate>Sat, 12 Mar 2022 21:35:57 GMT</pubDate><media:content url="https://thefamouslastpull.com/content/images/2022/03/outrun-start.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://thefamouslastpull.com/content/images/2022/03/outrun-start.jpg" alt="Powerful Roadmaps Look Like Outrun"><p>Quick question: what&apos;s your current Product roadmap look like? Is it managed in a tool that&apos;s some variation of the following image?</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/roadmunk-ss.png" class="kg-image" alt="Powerful Roadmaps Look Like Outrun" loading="lazy" width="1700" height="1101" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/roadmunk-ss.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/roadmunk-ss.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/03/roadmunk-ss.png 1600w, https://thefamouslastpull.com/content/images/2022/03/roadmunk-ss.png 1700w" sizes="(min-width: 720px) 720px"><figcaption>One of many popular roadmapping tools, Roadmunk lets you plan product development linearly.</figcaption></figure><p>If you&apos;re in the PM space, this is probably a familiar view into work. You have a timeline, with various milestones mapped out, possibly across quarters, and grouped vertically by the area of work or team that&apos;s focused on the work. Clear, professional, easy to grasp at a glance...</p><p>...and <em>completely insufficient</em>.</p><hr><p>One of my favorite video games growing up was Sega&apos;s classic masterpiece, Outrun. In it, you race a convertible Ferrari Testarossa across a fictional landscape, and the race kicks things off by asking you, the player, to choosing the music that will blast over the radio. But that wasn&apos;t the only thing you had to choose...</p><p>What made Outrun stand out, at its time (1986), was its ability to allow the player to choose what path they took. And the player didn&apos;t make these decisions up front...they made them in a split second, at exactly the moment the fork-in-the-road would appear. There were even situations where you were given the choice between two routes, started down one route, but by <em>accidentally colliding with a vehicle</em>, were bumped into the other route, so the decision was taken from you!</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/outrun-fork.png" class="kg-image" alt="Powerful Roadmaps Look Like Outrun" loading="lazy" width="2000" height="1403" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/outrun-fork.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/outrun-fork.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/03/outrun-fork.png 1600w, https://thefamouslastpull.com/content/images/2022/03/outrun-fork.png 2043w" sizes="(min-width: 720px) 720px"><figcaption>The driver is about to make a decision on what path to take in Outrun</figcaption></figure><p>Outrun teaches us a fundamental tenet we need to understand about how our current product roadmap strategy is insufficient: the future isn&apos;t a straight-line, yet we continually plan for / visualize it in tools that are linearly constrained.</p><p>When I sat down with Chris, back in the summer of 2020, there was an initial vision of a product roadmap for <a href="https://wrapmate.com/?ref=thefamouslastpull.com">Wrapmate</a>. A lot has happened since then! We&apos;ve learned more about our customers. We&apos;ve gained access to new technology. A global pandemic flipped many assumptions on their head. Priorities we thought were very important back in the summer of 2020 are completely different today. And while none of these facts invalidate that original path &#x2013; there were other paths not yet considered.</p><p>In order to be one step ahead of the game, we need to put solutions in place quickly, collect data on how effective those solutions are, and use those data to either stay the course or switch routes. Where the industry often falters is inadvertently rolling-up all feedback as a single data source, which inevitably leads to a single path forward. Ask these questions:</p><ul><li>Are you talking to the <em>right</em> customers? </li><li>How are you segmenting those customers? </li><li>Do you even know <em>which</em> customers are the right ones to pursue? </li></ul><p>If your feedback analysis starts to paint multiple paths, why are you plotting out a development plan that reads like a Gantt chart? One customer&apos;s Devil&apos;s Canyon is another customer&apos;s Cloudy Mountain.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/outrun-dc-cm.png" class="kg-image" alt="Powerful Roadmaps Look Like Outrun" loading="lazy" width="1280" height="447" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/outrun-dc-cm.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/outrun-dc-cm.png 1000w, https://thefamouslastpull.com/content/images/2022/03/outrun-dc-cm.png 1280w" sizes="(min-width: 720px) 720px"><figcaption>2 different customers, 2 different paths in Outrun (left: Devil&apos;s Canyon, right: Cloudy Mountain)</figcaption></figure><p>Unconvinced? Then don&apos;t take my word for it. Let&apos;s go directly to a product leader in the UX space for AWS, <a href="https://twitter.com/PavelASamsonov?ref=thefamouslastpull.com">Pavel Samsonov</a>:</p><figure class="kg-card kg-embed-card kg-card-hascaption"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">Linear roadmaps are misleading without a crystal ball for seeing the future. A roadmap that recognizes the existence of risk as time goes on is more honest. But an effective PM needs to anticipate possible branches, too - and create clear criteria for following each path. <a href="https://t.co/4InTKNGEsp?ref=thefamouslastpull.com">pic.twitter.com/4InTKNGEsp</a></p>&#x2014; Pavel A. Samsonov (@PavelASamsonov) <a href="https://twitter.com/PavelASamsonov/status/1296818042928861184?ref_src=twsrc%5Etfw&amp;ref=thefamouslastpull.com">August 21, 2020</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<figcaption>Pavel clearly has a deep and unbridled love for Outrun, like me.</figcaption></figure><p>That third image looks oddly familiar...</p><p>...oh, right &#x2013; it&apos;s the map displayed at the end of every Outrun game, depicting the route the player took.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/outrun-map.jpg" class="kg-image" alt="Powerful Roadmaps Look Like Outrun" loading="lazy" width="800" height="560" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/outrun-map.jpg 600w, https://thefamouslastpull.com/content/images/2022/03/outrun-map.jpg 800w" sizes="(min-width: 720px) 720px"><figcaption>A map of the course driven by the player in Outrun. There are multiple paths to victory, just like in business!</figcaption></figure><p>The next time you sit down to map out your product roadmap, consider a little branching logic in your details. I&apos;m not asking you to open a window to the multiverse and consider <a href="https://youtu.be/wxN1T1uxQ2g?ref=thefamouslastpull.com">everything, everywhere, all at once</a>. But I <em>am</em> saying that as a product leader, you <em>will</em> need to anticipate a few major forks-in-the-road, and be ready to crank that wheel hard, one way or the other.</p><p>Just promise me you&apos;ll do so to <a href="https://youtu.be/e-hHJIM_F0E?ref=thefamouslastpull.com">Magical Sound Shower</a>.</p>]]></content:encoded></item><item><title><![CDATA[Favorite Discourse Themes]]></title><description><![CDATA[Here's a collection of incredibly well-designed visual themes for the open source forum platform Discourse.]]></description><link>https://thefamouslastpull.com/favorite-discourse-themes/</link><guid isPermaLink="false">622a1b2f48bac40cc683f9cf</guid><category><![CDATA[digital-design]]></category><category><![CDATA[saas]]></category><category><![CDATA[open-source]]></category><category><![CDATA[forums]]></category><dc:creator><![CDATA[Shawn Holmes]]></dc:creator><pubDate>Thu, 10 Mar 2022 16:56:29 GMT</pubDate><media:content url="https://thefamouslastpull.com/content/images/2022/03/disc-tf-1-3.png" medium="image"/><content:encoded><![CDATA[<img src="https://thefamouslastpull.com/content/images/2022/03/disc-tf-1-3.png" alt="Favorite Discourse Themes"><p>I recently posted to Twitter about my favorite <a href="https://discourse.com/?ref=thefamouslastpull.com">Discourse</a> themes, so I thought I would share here on the blog as well.</p><p>If you haven&apos;t heard of Discourse, it&apos;s been around for nearly a decade now, and is the labor of love project from my good friend <a href="https://codinghorror.com/?ref=thefamouslastpull.com">Jeff Atwood</a> in his attempt to improve the Internet&apos;s interactions with forums.</p><p>Before we dig into the themes, here&apos;s a quick refresher of the default Discourse look-and-feel:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/03/disc-default.png" class="kg-image" alt="Favorite Discourse Themes" loading="lazy" width="2000" height="992" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/disc-default.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/disc-default.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/03/disc-default.png 1600w, https://thefamouslastpull.com/content/images/size/w2400/2022/03/disc-default.png 2400w" sizes="(min-width: 720px) 720px"><figcaption>The default visual theme for Discourse, an open-source platform for online communities.</figcaption></figure><p>Very practical, which is perfectly fine, of course!</p><p>...but just wait until you see what <em>these</em> communities have done.</p><hr><h2 id="blizzard-entertainment">Blizzard Entertainment</h2><p>Yes, I realize I am <a href="https://eightyearsinazeroth.blogspot.com/?ref=thefamouslastpull.com">a little biased here</a>, but one of the single coolest things that&apos;s happened in my lifetime is seeing <a href="https://www.blizzard.com/en-us/?ref=thefamouslastpull.com">Blizzard Entertainment</a> upgrade <a href="https://us.forums.blizzard.com/en/blizzard/?ref=thefamouslastpull.com">all of their game forums</a> to Discourse. These themes are absolutely incredible! Truly works of art.</p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://thefamouslastpull.com/content/images/2022/03/disc-d3-1.png" width="2000" height="998" loading="lazy" alt="Favorite Discourse Themes" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/disc-d3-1.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/disc-d3-1.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/03/disc-d3-1.png 1600w, https://thefamouslastpull.com/content/images/size/w2400/2022/03/disc-d3-1.png 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="https://thefamouslastpull.com/content/images/2022/03/disc-d2r-1.png" width="2000" height="1001" loading="lazy" alt="Favorite Discourse Themes" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/disc-d2r-1.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/disc-d2r-1.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/03/disc-d2r-1.png 1600w, https://thefamouslastpull.com/content/images/size/w2400/2022/03/disc-d2r-1.png 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="https://thefamouslastpull.com/content/images/2022/03/disc-ow-1.png" width="2000" height="1000" loading="lazy" alt="Favorite Discourse Themes" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/disc-ow-1.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/disc-ow-1.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/03/disc-ow-1.png 1600w, https://thefamouslastpull.com/content/images/size/w2400/2022/03/disc-ow-1.png 2400w" sizes="(min-width: 720px) 720px"></div></div><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://thefamouslastpull.com/content/images/2022/03/disc-blizz-2.png" width="2000" height="1002" loading="lazy" alt="Favorite Discourse Themes" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/disc-blizz-2.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/disc-blizz-2.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/03/disc-blizz-2.png 1600w, https://thefamouslastpull.com/content/images/size/w2400/2022/03/disc-blizz-2.png 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="https://thefamouslastpull.com/content/images/2022/03/disc-blizz-1.png" width="2000" height="1002" loading="lazy" alt="Favorite Discourse Themes" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/disc-blizz-1.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/disc-blizz-1.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/03/disc-blizz-1.png 1600w, https://thefamouslastpull.com/content/images/size/w2400/2022/03/disc-blizz-1.png 2400w" sizes="(min-width: 720px) 720px"></div></div></div><figcaption>Screenshots of Blizzard Entertainment&apos;s multiple game forum themes, all atop Discourse.</figcaption></figure><hr><h2 id="tensorflow">TensorFlow</h2><p>If you&apos;re into Artificial Intelligence / Machine Learning, hop on over to the <a href="https://discuss.tensorflow.org/?ref=thefamouslastpull.com">TensorFlow forums</a>, also running atop Discourse. I really like how slick this theme is; the font choice really adds a nice touch.</p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://thefamouslastpull.com/content/images/2022/03/disc-tf-2.png" width="2000" height="1002" loading="lazy" alt="Favorite Discourse Themes" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/disc-tf-2.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/disc-tf-2.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/03/disc-tf-2.png 1600w, https://thefamouslastpull.com/content/images/size/w2400/2022/03/disc-tf-2.png 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="https://thefamouslastpull.com/content/images/2022/03/disc-tf-1.png" width="2000" height="1000" loading="lazy" alt="Favorite Discourse Themes" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/disc-tf-1.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/disc-tf-1.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/03/disc-tf-1.png 1600w, https://thefamouslastpull.com/content/images/size/w2400/2022/03/disc-tf-1.png 2400w" sizes="(min-width: 720px) 720px"></div></div></div><figcaption>Screenshots of TensorFlow&apos;s forum theme, running atop Discourse.</figcaption></figure><hr><h2 id="asana">Asana</h2><p>We use <a href="http://asana.com/?ref=thefamouslastpull.com">Asana</a> for task and project management over at <a href="https://wrapmate.com/?ref=thefamouslastpull.com">Wrapmate</a>. When I went looking for <a href="https://forum.asana.com/?ref=thefamouslastpull.com">their online community</a>, I was pleasantly surprised to see they were also running atop Discourse. They have a superb theme that is a delight to use.</p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://thefamouslastpull.com/content/images/2022/03/disc-asana-2.png" width="2000" height="1001" loading="lazy" alt="Favorite Discourse Themes" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/disc-asana-2.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/disc-asana-2.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/03/disc-asana-2.png 1600w, https://thefamouslastpull.com/content/images/size/w2400/2022/03/disc-asana-2.png 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="https://thefamouslastpull.com/content/images/2022/03/disc-asana-1.png" width="2000" height="1000" loading="lazy" alt="Favorite Discourse Themes" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/disc-asana-1.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/disc-asana-1.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/03/disc-asana-1.png 1600w, https://thefamouslastpull.com/content/images/size/w2400/2022/03/disc-asana-1.png 2400w" sizes="(min-width: 720px) 720px"></div></div></div><figcaption>Screenshots of Asana&apos;s forum theme, running atop Discourse.</figcaption></figure><hr><h2 id="code-academy">Code Academy</h2><p>I recently discovered that <a href="https://www.codecademy.com/?ref=thefamouslastpull.com">Code Academy</a> also uses Discourse for <a href="https://discuss.codecademy.com/?ref=thefamouslastpull.com">their online community</a>. Their theme is super geeky, which I totally dig &#x2013; definitely getting some strong retro terminal vibes from it!</p><figure class="kg-card kg-gallery-card kg-width-wide kg-card-hascaption"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="https://thefamouslastpull.com/content/images/2022/03/disc-codeacademy-2.png" width="2000" height="999" loading="lazy" alt="Favorite Discourse Themes" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/disc-codeacademy-2.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/disc-codeacademy-2.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/03/disc-codeacademy-2.png 1600w, https://thefamouslastpull.com/content/images/size/w2400/2022/03/disc-codeacademy-2.png 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="https://thefamouslastpull.com/content/images/2022/03/disc-codeacademy-1.png" width="2000" height="1003" loading="lazy" alt="Favorite Discourse Themes" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/03/disc-codeacademy-1.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/03/disc-codeacademy-1.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/03/disc-codeacademy-1.png 1600w, https://thefamouslastpull.com/content/images/size/w2400/2022/03/disc-codeacademy-1.png 2400w" sizes="(min-width: 720px) 720px"></div></div></div><figcaption>Screenshots of Code Academy&apos;s forum theme, running atop Discourse.</figcaption></figure><hr><p>I suspect it won&apos;t be long before the need to support an online community arises at <a href="https://wrapmate.com/?ref=thefamouslastpull.com">Wrapmate</a>. When that fateful day arrives, I&apos;ll be looking forward to seeing what our design team comes up with to push the envelope, just as these companies have.</p>]]></content:encoded></item><item><title><![CDATA[Embracing NoCode]]></title><description><![CDATA[Should you embrace NoCode? It depends on what you are using it for. Here's how to tell if your use case is appropriate or not.]]></description><link>https://thefamouslastpull.com/embracing-nocode/</link><guid isPermaLink="false">61154df047e9b0ac6f11226b</guid><category><![CDATA[software-development]]></category><category><![CDATA[no-code]]></category><category><![CDATA[tools]]></category><dc:creator><![CDATA[Shawn Holmes]]></dc:creator><pubDate>Mon, 14 Feb 2022 03:20:13 GMT</pubDate><media:content url="https://thefamouslastpull.com/content/images/2022/02/retool-hero.png" medium="image"/><content:encoded><![CDATA[<img src="https://thefamouslastpull.com/content/images/2022/02/retool-hero.png" alt="Embracing NoCode"><p>The NoCode wave is upon us. Platforms like <a href="https://retool.com/?ref=thefamouslastpull.com">Retool</a>, <a href="https://airtable.com/?ref=thefamouslastpull.com">Airtable</a> and <a href="https://bubble.io/?ref=thefamouslastpull.com">Bubble</a> are changing the way the way we build software...</p><p>...said no software developer, <em>ever</em>.</p><p>I&apos;m not going to lie: NoCode is a contentious topic. Non-technical co-founders swear by it, career programmers scoff at it. Who do we believe? How do we move forward as an industry?</p><p>In times like this, I turn to our technical forefathers, in the hopes of not repeating the mistakes of the past. Here&apos;s Alan Cooper, the father of Visual Basic, on his take:</p><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">The never-ending quest for programming tools that don&#x2019;t require code is a clear symptom of our failure to understand what programming really is and how it gets accomplished. Also, it shows how scared we are of code and coders and how we want it/them to go away and leave us alone.</p>&#x2014; Alan Cooper (@MrAlanCooper) <a href="https://twitter.com/MrAlanCooper/status/1467624081604308998?ref_src=twsrc%5Etfw&amp;ref=thefamouslastpull.com">December 5, 2021</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</figure><p>Look, I <em>get it</em>. Programmers are expensive. Getting them to estimate their efforts accurately (and then hold them accountable) is like pulling teeth. And when you ask them why your latest feature isn&apos;t done yet, out comes a nonsensical string of technical jargon that tells you nothing.</p><p>It feels like it would be a lot less painful to just do it yourself. That is, after all, the promise of NoCode. It is in this promise that we fundamentally misunderstand what NoCode platforms were meant to do for us.</p><hr><p>Let&apos;s start with problem number one. &quot;NoCode&quot; is a bit of a misnomer. Here&apos;s a quick peek at an app in Edit Mode in the popular NoCode platform Retool:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://thefamouslastpull.com/content/images/2022/02/retool-screenshot.png" class="kg-image" alt="Embracing NoCode" loading="lazy" width="2000" height="380" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/02/retool-screenshot.png 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/02/retool-screenshot.png 1000w, https://thefamouslastpull.com/content/images/size/w1600/2022/02/retool-screenshot.png 1600w, https://thefamouslastpull.com/content/images/size/w2400/2022/02/retool-screenshot.png 2400w" sizes="(min-width: 720px) 720px"><figcaption>If I didn&apos;t know any better, I&apos;d say that was code!</figcaption></figure><p>This is why programmers balk; <em>they know the truth</em>. NoCode tools are really better described as &quot;EventuallyThereWillBeSomeCode.&quot; And the minute you need to write <em>one</em> line of code, I&apos;m sorry to have to tell you this...but you either need to have a programmer do it, or you need to <em>become one yourself</em>.</p><p>This leads to problem number two: doing it yourself. NoCode tools give you the sense that <em>this isn&apos;t so hard</em>. You throw a few drop-down menus and buttons together on a screen, spin up a database to store your data, and suddenly you are collecting data...customers are interacting! Our startup is off and running! Who needs expensive engineering departments?</p><p>...<em>until things start to break</em>. Data is lost. Performance is poor. Customers are irate. Your department heads need answers, and you can&apos;t explain what&apos;s going wrong...</p><hr><p>Some time ago, when I was just a mere software developer, I sat in a conference room with a team of individuals facing a problem. Those at the table spoke hypothetically of a &quot;solution&quot; that might &quot;look&quot; a certain way and would &quot;behave&quot; according to specific business rules. When they were done speaking, I spun my laptop around and declared, &quot;...like this?&quot; </p><p>For a moment, they stared in silence, likely surprised I was able to put something together so quickly. Then, excitedly, they began pointing to the parts they wanted changed...</p><p>Memories are short. </p><p>It wasn&apos;t that long ago that we were all advocating for the advancement of &quot;rapid prototyping&quot; tools &#x2013; the ability to quickly throw together a functional solution to prove out a concept, minus the cost of building out a team to turn dreams into reality. NoCode tools are simply the next evolutionary step in that paradigm. No, it doesn&apos;t make sense to build a business atop a NoCode application. Yes, it does make sense to let an engineering team use a NoCode tool to eliminate a lot of unnecessary front-end work!</p><p>At <a href="https://wrapmate.com/?ref=thefamouslastpull.com">Wrapmate</a>, we&apos;ve used Retool to stitch together makeshift admin tools that interface with both native database connections and REST endpoints. Are they customer facing? No. Do we plan on using them long-term? Also, no. But perhaps most importantly: Do they solve a problem the team faced with minimal time and effort? Yes.</p><p>Like any innovative technology, it is up to us to inform our non-technical peers what strengths and weaknesses lie in pursuing these tools, but that only happens when we have a seat at the table. Non-technical founders that eschew in-house engineering expertise in lieu of NoCode tools to run their business &quot;because it is totally fine&quot; will likely face the music at some point (you have been warned!)<em> </em>By choosing to do it yourself, you&apos;ve elected to not have engineering in your corner, to be your voice at the table that says &quot;if we do this, here is how we will suffer in the long term, and are we willing to cut that corner?&quot; And to those who choose that path, <em>Godspeed</em>.</p><p>As for those in technology that <em>do</em> leverage NoCode, you will discover that much of what you are already doing can be greatly accelerated. As long as you understand the repercussions, why not?</p><p>Technology leaders that thoughtfully embrace NoCode tools will ultimately pull ahead of their more bullheaded counterparts. They will be able to solve tooling issues with less effort and experiment faster...at far less a cost to their organization. Leveraging NoCode in this way doesn&apos;t threaten a programming staff, it <em>frees</em> them &#x2013; to focus building the robust, scalable product that a NoCode solution never intended to replace.</p>]]></content:encoded></item><item><title><![CDATA[The Calendly Problem Isn't Calendly]]></title><description><![CDATA[When someone sends you a Calendly link, it's about them. Contrary to popular belief, not everything is about you.]]></description><link>https://thefamouslastpull.com/the-calendly-problem-isnt-calendly/</link><guid isPermaLink="false">61f2b22a48bac40cc683f565</guid><category><![CDATA[time management]]></category><category><![CDATA[leadership]]></category><category><![CDATA[calendar etiquette]]></category><category><![CDATA[Calendly]]></category><dc:creator><![CDATA[Shawn Holmes]]></dc:creator><pubDate>Thu, 27 Jan 2022 15:51:35 GMT</pubDate><media:content url="https://thefamouslastpull.com/content/images/2022/01/calendly.png" medium="image"/><content:encoded><![CDATA[<img src="https://thefamouslastpull.com/content/images/2022/01/calendly.png" alt="The Calendly Problem Isn&apos;t Calendly"><p>There is a sentiment going around social media at the moment that I can&apos;t keep quiet about. Before we get into the sentiment, a brief history of time (management):</p><p>In a world before <a href="https://calendly.com/?ref=thefamouslastpull.com">Calendly</a>, scheduling time with someone was nightmarish...but not for the reasons you think. The struggle was not one of a lack of mutual transparency (ie. &quot;what do both of our calendars look like for the day&quot;) and more of one with power dynamics at play (ie. &quot;I MUST meet with you at this time, no exceptions&quot;). Calendar etiquette was non-existent; those sending a request for your time weren&apos;t asking themselves important questions like &quot;am I booking something at over your lunch hour?&quot; or &quot;am I including an agenda?&quot; Most meetings probably didn&apos;t even need to be meetings.</p><figure class="kg-card kg-image-card"><img src="https://thefamouslastpull.com/content/images/2022/01/meeting-email-theoffice.jpg" class="kg-image" alt="The Calendly Problem Isn&apos;t Calendly" loading="lazy" width="551" height="380"></figure><p>In the struggle to stay focused, reduce interruptions, and wrest back control of one&apos;s schedule, the old way of doing things was awful. It cost them <em>nothing</em> to demand time on your calendar, but it cost you <em>everything</em>.</p><p>Calendly, a tool built to allow professionals to quickly &amp; easily allow random strangers on the internet to schedule time to meet with them, produced a wonderful side-effect when used as an internal tool within a company: <em>it shut bad actors down</em>.</p><p>With <a href="https://www.projectmanager.com/blog/time-blocking-guide?ref=thefamouslastpull.com">Time Management 101 blocks of reserved time</a> on your personal calendar &#x2013; no lunches, no 30 minutes at the start or end of the day, a block of time dedicated to work, distraction free &#x2013; Calendly then presented only what was necessary to the asker: &quot;Here&apos;s what&apos;s available. Find something that works for you...or don&apos;t.&quot;</p><p>To some, it could be perceived as inconvenient to be presented with someone&apos;s boundaries. That doesn&apos;t mean you get to violate them.</p><p>Which brings me to the sentiment:</p><figure class="kg-card kg-image-card"><img src="https://thefamouslastpull.com/content/images/2022/01/sam-lessin-calendly.jpeg" class="kg-image" alt="The Calendly Problem Isn&apos;t Calendly" loading="lazy" width="1150" height="1836" srcset="https://thefamouslastpull.com/content/images/size/w600/2022/01/sam-lessin-calendly.jpeg 600w, https://thefamouslastpull.com/content/images/size/w1000/2022/01/sam-lessin-calendly.jpeg 1000w, https://thefamouslastpull.com/content/images/2022/01/sam-lessin-calendly.jpeg 1150w" sizes="(min-width: 720px) 720px"></figure><p>So, now that the power dynamic has shifted (and will continue to do so as the emerging worker gains a <a href="https://fortune.com/2022/01/27/heres-the-proof-culture-still-comes-first-in-the-age-of-remote-work-wfh-pandemic-managers-covid-employee-retention-christos-makridis/?ref=thefamouslastpull.com">greater awareness and control of their working conditions</a>), suddenly, Calendly is the problem?</p><p>One of the first posts I made on <a href="https://wrapmate.com/?ref=thefamouslastpull.com">Wrapmate</a>&apos;s intranet/wiki was one regarding basic calendar etiquette, in the off-chance bad acting was the result of ignorance than of malevolence. </p><blockquote>&quot;Here&apos;s how to view someone else&apos;s calendar.&quot; </blockquote><blockquote>&quot;Consider the other person&apos;s time zone.&quot; </blockquote><blockquote>&quot;Do your best not to book across lunch.&quot; </blockquote><blockquote>&quot;Always include an agenda.&quot; </blockquote><p>For those of us in charge of teams (especially programmers), setting a precedent of &quot;do not interrupt developers unless it is <em>vital</em>&quot; is not only the right approach, it produces highly productive teams. In the absence of leaders setting that culture in a work environment, Calendly is a wonderful tool that guardrails against bad behavior, regardless of intent.</p><p>Is there a better solution? Perhaps one day! But until that day arrives, to make a blanket statement like &quot;I&apos;ll never click your Calendly link&quot; says more about <em>you</em> than the failure of technology to address the problem. </p><p>Refusing to click someone&apos;s Calendly link is the equivalent of saying, &quot;What&apos;s this? The person whose time I&apos;m making a request of has a professional approach to time management? They have reduced (or eliminated) wasteful interruptions in order to stay focused and productive? They&apos;ve put guardrails in place and shifted the onus onto <em>me</em> to find time on <em>their</em> calendar? <em><u>No, thanks. I&apos;m too important for that.</u></em>&quot;</p><p>And in that situation, perhaps Calendly did what it was supposed to do all along.</p>]]></content:encoded></item></channel></rss>