<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:base="https://patricklee.nyc/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Patrick Lee</title>
    <link>https://patricklee.nyc/</link>
    <atom:link href="https://patricklee.nyc/rss.xml" rel="self" type="application/rss+xml" />
    <description>Software engineer</description>
    <language>en</language>
    <item>
      <title>Task Oriented Dialog Systems</title>
      <link>https://patricklee.nyc/blog/task-oriented-dialog-systems/</link>
      <description>&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;During my time at Clockwise, &lt;a href=&quot;https://www.linkedin.com/pulse/building-prism-how-we-developed-our-domain-specific-patrick-lerhaupt-uinvc/&quot;&gt;I worked on Prism&lt;/a&gt;, a calendar management product that leverages AI to interpret user commands to execute actions on their calendar. I won&#39;t go too deep into my work at Clockwise, but I will explore the concept of using domain-specific languages with LLMs to achieve a goal.&lt;/p&gt;
&lt;p&gt;I stumbled across this concept when I found &lt;a href=&quot;https://arxiv.org/pdf/2305.19234&quot;&gt;Grammar Prompting for Domain-Specific Language
Generation with Large Language Models&lt;/a&gt;. During the last year, I haven&#39;t seen much discourse on domain-specific languages in conjunction with large language models, and I&#39;ve been trying to wrap my head around why. I&#39;m not an expert in machine learning or natural language processing (NLP), so I have incomplete knowledge.&lt;/p&gt;
&lt;p&gt;This post is a collection of insights I&#39;ve gathered over the past year. If you&#39;re well-versed in Task-Oriented Dialog (TOD) systems, I&#39;d love to connect and learn more from you!&lt;/p&gt;
&lt;h1&gt;Task-oriented dialog systems&lt;/h1&gt;
&lt;p&gt;From what I&#39;ve gathered, the approach we used is a subset of NLP known as Task-Oriented Dialog (TOD) Systems.&lt;/p&gt;
&lt;h2&gt;What is a Task-Oriented Dialog (TOD) System?&lt;/h2&gt;
&lt;p&gt;From my understanding, a TOD:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Is a &lt;em&gt;conversational system&lt;/em&gt; that helps users &lt;strong&gt;do&lt;/strong&gt; something (achieve a goal).&lt;/li&gt;
&lt;li&gt;Interprets the user&#39;s intent through baked-in assumptions or through workflows to disambiguate requests.&lt;/li&gt;
&lt;li&gt;Manages the conversation state and has logic to complete workflows (to achieve a goal).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In a nutshell, it&#39;s a system that interprets a user&#39;s intent (their utterance), resolves ambiguity, and then formulates a plan for execution.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fun Fact: In NLP, they use the term utterance to refer to a single unit of human speech or text. It&#39;s the basic unit of communication in NLP systems.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;What&#39;s an example?&lt;/h2&gt;
&lt;p&gt;Take, for example, an assistant like &lt;a href=&quot;https://www.amazon.science/blog/new-alexa-research-on-task-oriented-dialogue-systems&quot;&gt;Amazon&#39;s Alexa&lt;/a&gt; or Apple&#39;s Siri. A user may provide the following utterance:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; Siri, what&#39;s the weather today?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Assistant:&lt;/strong&gt; The weather today in New York is 74 degrees Fahrenheit.&lt;/p&gt;
&lt;p&gt;How does the system go from the user asking what the weather is to it responding with the weather? This Task-Oriented Dialog system requires several major components:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Figure out what the user is trying to achieve: &amp;quot;The user would like to know the weather&amp;quot;&lt;/li&gt;
&lt;li&gt;Remove ambiguity, such as the user&#39;s location: &amp;quot;The user would like to know the weather in their location&amp;quot;&lt;/li&gt;
&lt;li&gt;Create a plan to execute: &amp;quot;Get the weather in their location and return that to the user&amp;quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Even breaking down this system into smaller pieces results in quite a bit of complexity!&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The system needs a way to turn the user&#39;s request into a plan (a program).&lt;/li&gt;
&lt;li&gt;The system needs a way to figure out the user&#39;s location.&lt;/li&gt;
&lt;li&gt;The system needs a way to output this result to the user.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In order to get a machine to interpret the user&#39;s intent, the intent must be translated into a machine-readable plan. This is where a representation of complex ideas comes into play (a domain-specific language maybe?):&lt;/p&gt;
&lt;p&gt;For example, what if our plan was a Python program?&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def get_user_location():
  &#39;&#39;&#39;Gets the user location from previously stored user information or via device gps&#39;&#39;&#39;

def get_weather(location):
  &#39;&#39;&#39;Query an external weather API to get the weather in the user&#39;s location&#39;&#39;&#39;

def program():
  return get_weather(get_user_location())
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s a lot of different systems for a relatively &amp;quot;simple&amp;quot; request!&lt;/p&gt;
&lt;h2&gt;Why aren&#39;t they more popular?&lt;/h2&gt;
&lt;p&gt;This is a question I&#39;ve asked myself time and time again over the last year. The approach is fairly solid, and with large language models, NLP is so much easier than it used to be. So why isn&#39;t it more popular?&lt;/p&gt;
&lt;h3&gt;Anatomy of a basic TOD system&lt;/h3&gt;
&lt;p&gt;First, let&#39;s look at what we need for a basic TOD system:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We need a way to turn a user&#39;s utterance into some kind of structured data that we can then interpret.&lt;/li&gt;
&lt;li&gt;We need a way to train some model to output this structured data.&lt;/li&gt;
&lt;li&gt;We need to then take the output plan and &amp;quot;run&amp;quot; it on our systems to execute actions to achieve a goal.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;How this looks in the system we built at Clockwise was:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We generated user utterances and domain-specific language conversations synthetically using a larger model.&lt;/li&gt;
&lt;li&gt;We fine-tuned an open-source model using this data.&lt;/li&gt;
&lt;li&gt;We built an interpreter that would &amp;quot;run&amp;quot; this DSL and execute actions to achieve the user&#39;s goal and connected it to existing internal APIs.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It was a &lt;strong&gt;ton&lt;/strong&gt; of work! It took me and a team of backend engineers a year to get a stable working system!&lt;/p&gt;
&lt;h3&gt;Downsides of TOD systems&lt;/h3&gt;
&lt;p&gt;So why aren&#39;t TOD systems more popular in this age of a massive influx of AI companies? In my opinion:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;They just don&#39;t know about it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Many people, myself included, enter the space with little to no prior knowledge or experience in NLP systems. We became interested with the popularization of LLMs and wanted to build things with this new LLM technology.&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;TODs are complex and hard to build!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It takes a lot of work to build a TOD system. Just the basic system I outlined required:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating a domain-specific language&lt;/li&gt;
&lt;li&gt;Creating an interpreter for this custom domain-specific language&lt;/li&gt;
&lt;li&gt;Generating a dataset to teach a model how to output this domain-specific language&lt;/li&gt;
&lt;li&gt;Making sure this dataset was clean and didn&#39;t have issues like hallucinated keywords, or syntax errors&lt;/li&gt;
&lt;li&gt;Doing the actual model training and tweaking hyperparameters&lt;/li&gt;
&lt;li&gt;Serving the model on some kind of GPU-enabled infrastructure&lt;/li&gt;
&lt;li&gt;Creating an eval dataset and setting up a way to test model output to control quality&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&#39;s a lot of complex components and takes a long time even if you have a team of highly experienced engineers.&lt;/p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;It takes a lot of work to create custom datasets to train a model on your domain-specific language.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you create a custom DSL, any trained model will have no context on that language since it doesn&#39;t appear in its training data. That means that you need to provide documentation and examples for how to use the DSL, and in turn, that means you need to have a deep understanding of the different use cases and appropriate actions the model can take.&lt;/p&gt;
&lt;h3&gt;Upsides of a TOD system&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Control&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With a TOD system, it is much easier to control the LLM output, constraining it to whatever is do-able by your domain-specific language. You can also keep your business logic out of the prompt for the model. Essentially your &amp;quot;plans&amp;quot; or programs in your DSL is your business logic and it can be expressed in some intermediate representation.&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Auditability&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With some intermediate representation of the user&#39;s intent, you can easily audit this plan or present it to the user for confirmation prior to executing the actions. This is very important to ensure the user experience is both reproducible and controllable. You don&#39;t want an LLM making decisions in some black box that you can&#39;t debug or explain to the user why it did what it did. You certainly don&#39;t want to let an LLM make potentially damaging changes to users&#39; data without their explicit confirmation!&lt;/p&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;LLMs are not AGI&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I think it&#39;s important to re-iterate that LLMs are not general intelligence. Leaving the ability for an LLM to make decisions is akin to letting users roll a weighted die on how to achieve their goal. It may work most of the time, but it can also blow up in their faces.&lt;/p&gt;
&lt;h3&gt;So why aren&#39;t they more popular?&lt;/h3&gt;
&lt;p&gt;Ultimately, I think they&#39;re just hard to build. Large companies have the resources to invest into NLP experts and teams of developers to build out complicated systems and main them. Smaller companies that want to &amp;quot;implement AI&amp;quot; are just trying to find low hanging fruit and build their entire workflows around LLMs.&lt;/p&gt;
&lt;p&gt;There is also a fatigue around &amp;quot;chat bots&amp;quot; happening now. Lots of chat focused applications are thin wrappers over LLMs and they&#39;ve shown their functionality to be quite limited. There has been a push to integrate LLMs in other ways into products like copilots or agents.&lt;/p&gt;
&lt;p&gt;If you have a different theory, I would &lt;strong&gt;love&lt;/strong&gt; to hear it though!&lt;/p&gt;
&lt;h2&gt;Alternative: Function Calling / Tool Use&lt;/h2&gt;
&lt;p&gt;For those of us coming into the NLP and TOD space from the outside, we encounter &lt;a href=&quot;https://platform.openai.com/docs/guides/function-calling&quot;&gt;function calling&lt;/a&gt; or tool use. Function calling is a popular feature implemented in many large LLM services that allow LLMs to &amp;quot;use tools&amp;quot; or reach out to external APIs or to call code.&lt;/p&gt;
&lt;p&gt;These are good tools if you&#39;re using an LLM as a conversational partner and to enable the LLM to achieve more, but for a TOD system, function calling requires embedding all your business logic into LLM prompts. Ultimately, this means less controllability of a highly non-deterministic system, and ultimately decision-making is left to the LLM. Letting an LLM control your business logic is &lt;strong&gt;not good&lt;/strong&gt;! You want full control and accountability of your system!&lt;/p&gt;
&lt;h2&gt;Just use Python&lt;/h2&gt;
&lt;p&gt;Why create your own language when you can use an existing language like Python? The model already knows how to write Python.&lt;/p&gt;
&lt;p&gt;Yes, that&#39;s true. We looked into this and you run into two main problems.&lt;/p&gt;
&lt;p&gt;First, you need to figure out how to sandbox Python and be sure there are no leaks anywhere; otherwise, you create a major security hole.
Second, you run into the issue of the model trying to use its vast knowledge of Python to do all sorts of stuff.&lt;/p&gt;
&lt;p&gt;When we experimented with Python output, the model tended to try to import packages, both from the core library and third party. This opens up another vector for attack.&lt;/p&gt;
&lt;p&gt;Finally, Python is fairly verbose, and the more verbose your language, the more tokens it takes to generate an output, the slower your overall system will be.&lt;/p&gt;
&lt;h2&gt;Isn&#39;t fine-tuning dead?&lt;/h2&gt;
&lt;p&gt;Why are you fine-tuning models? Didn&#39;t you know that &lt;a href=&quot;https://christianjmills.com/posts/mastering-llms-course-notes/conference-talk-009/&quot;&gt;fine-tuning is dead?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Well, I&#39;m sorry to tell you that the reports of fine-tuning&#39;s demise are greatly exaggerated. RAG and in-context learning are powerful, yes, but you&#39;re still paying per token for model input!&lt;/p&gt;
&lt;p&gt;You&#39;re also beholden to high latencies with external services! You can fine-tune an 8B model for a specific purpose with much lower per-token latencies than using a larger general model.&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;So this is what I understand of the current state of the world from my very limited point of view as a web developer trying to figure out how to incorporate LLMs into an existing product.&lt;/p&gt;
&lt;p&gt;I would love to learn more about Task Oriented Dialog systems and get a better sense of the environment in which they exist. Please reach out! I&#39;d love to hear from you if you&#39;ve worked on systems like this before.&lt;/p&gt;
&lt;h1&gt;Other Resources&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://direct.mit.edu/tacl/article/doi/10.1162/tacl_a_00333/96470/Task-Oriented-Dialogue-as-Dataflow-Synthesis&quot;&gt;Task-Oriented Dialogue as Dataflow Synthesis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2305.19234&quot;&gt;Grammar Prompting for Domain-Specific Language Generation with Large Language Models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2306.03460&quot;&gt;Natural Language Commanding via Program Synthesis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2308.02323&quot;&gt;Dataflow Dialogue Generation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2212.09939&quot;&gt;AnyTOD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/google-research/task-oriented-dialogue?tab=readme-ov-file&quot;&gt;google-research/task-oriented-dialogue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/budzianowski/multiwoz&quot;&gt;budzianowski/multiwoz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cs.princeton.edu/courses/archive/spring20/cos598C/&quot;&gt;Princeton COS598C&lt;/a&gt; &lt;a href=&quot;https://www.cs.princeton.edu/courses/archive/spring20/cos598C/lectures/lec16-task-oriented-dialogue.pdf&quot;&gt;Lecture Notes on TOD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.science/alexa-prize/proceedings/making-something-out-of-nothing-building-robust-task-oriented-dialogue-systems-from-scratch&quot;&gt;Making Something out of Nothing: Building Robust Task-oriented Dialogue Systems from Scratch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
      <pubDate>Fri, 04 Oct 2024 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/task-oriented-dialog-systems/</guid>
    </item>
    <item>
      <title>Moving onto a new chapter</title>
      <link>https://patricklee.nyc/blog/moving-onto-a-new-chapter/</link>
      <description>&lt;h1&gt;Moving onto a new chapter&lt;/h1&gt;
&lt;p&gt;I left Noom on June 5th, 2023 after 5 years. I wanted to write about a few of the highlights of my time at Noom, why I&#39;m leaving, and where I&#39;ll be going.&lt;/p&gt;
&lt;p&gt;I never thought Noom would take off the way it did. When I joined the company in 2018, it was small and recovering from its last round of layoffs. The company hadn&#39;t found product-market fit yet. We were scrappy and fighting to survive. I joined two other engineers on the Growth team and we went head first into rapid experimentation. We found product-market fit in 2019 and little did I know the next few years would be some of the most intense periods of my working life.&lt;/p&gt;
&lt;p&gt;A few highlights:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I had the opportunity to build and architect an experimentation platform for Noom.com.&lt;/li&gt;
&lt;li&gt;I helped scale the growth team from 3 engineers to 30 at our largest in just 2 years.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A few reasons I&#39;m moving on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I&#39;ve battled burnout several times, a lot of it was due to my role as an Engineering Manager.&lt;/li&gt;
&lt;li&gt;The company has grown up and has reached a stage where I feel less effective.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Highlights&lt;/h1&gt;
&lt;h2&gt;The Meristem Experimentation Platform&lt;/h2&gt;
&lt;p&gt;We built our own experimentation system instead of buying something off the shelf. I know, I know. We re-invented the wheel! It seemed like the right decision to make at the time. To understand the solution we came up with, its important to understand the context in which we made those decisions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We ran experiments using feature flags.&lt;/li&gt;
&lt;li&gt;We were a very small team with a lot of product managers per engineer. Our PM/Eng ratio typically hovered around 1.5. That&#39;s 1.5 Engineers per Product Manager! To put that into context, for example, Netflix has a ratio of about 12! That&#39;s 12 engineers per 1 PM!&lt;/li&gt;
&lt;li&gt;PMs were responsible for creating a hypothesis for improving Noom.com conversion rates, creating the specification, and project managing the experiment, QAing and doing data analysis afterwards. They typically had very full workloads! Our PMs did &lt;em&gt;everything&lt;/em&gt;!&lt;/li&gt;
&lt;li&gt;Engineers were in charge of implementing experiments and working with PMs to right size the amount of work for an experiment based on the ROI of the feature. Engineers are also in charge of maintenance of noom.com&lt;/li&gt;
&lt;li&gt;The team prioritized experiment velocity (to  a fault). A base expectation was that each engineer would create and launch around one experiment per week (depending on the difficulty of implementation). This meant that there was not a lot of time for things like cleanups or investing into the infrastructure due to the pressure to run more experiments and lack of &amp;quot;slack&amp;quot; on the engineering side to devote to tech debt cleanups.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These constraints meant that we were trying to experiment very quickly and that all available engineering time was typically devoted to building and experimenting with new features. By using feature flags, we were incurring technical debt for every experiment we ran. Not only that, but feature flags typically interacted in difficult to predict ways and required expensive processes to get merged and tested for every potential experiment we wanted to run. This was &lt;em&gt;a lot&lt;/em&gt; of overhead!&lt;/p&gt;
&lt;p&gt;My teammates Sumin and Hubert came up with a novel idea: &amp;quot;What if we could use Git to manage our experiment variation branches&amp;quot;? We&#39;d be able to throw out the code for failed experiments easily since roughly 9 out of every 10 experiments were considered failures. Then we&#39;d only merge code into our codebase that we knew we&#39;d wanted to keep. By not having to merge code into our main codebase for every experiment, we&#39;d save ourselves a lot of effort reviewing the code, testing the code, maintaining the code, and the removing it when the experiment ultimately failed. We were optimizing for experiment velocity while heavily constrained by engineering bandwidth.&lt;/p&gt;
&lt;p&gt;I was put in charge of the project and built out an &lt;a href=&quot;https://medium.com/noom-engineering/the-growth-machine-how-noom-runs-365-landing-page-experiments-per-year-1e098ea33354&quot;&gt;initial version&lt;/a&gt;. Surprisingly, it worked but we hit scaling issues pretty quickly. We re-built the system with a different architecture and &lt;a href=&quot;https://medium.com/noom-engineering/how-noom-uses-technology-to-herd-the-experimental-cats-256d3713c761&quot;&gt;it ended up working really well for us&lt;/a&gt;. The system isn&#39;t without its flaws that we&#39;ve had to work around. If I were to build another experimentation system today, I&#39;d probably choose somthing else, but for our constraints it worked well.&lt;/p&gt;
&lt;h2&gt;Scaling the team and going into management&lt;/h2&gt;
&lt;p&gt;I also started to transition into engineering management. I went from a mid-level Individual Contributor (IC) to Tech Lead, to Tech Lead Manager and finally to Senior Tech Lead manager. As I progressed, my focus shifted from technology to people and teams and although my title was Tech Lead Manager, I was effectively an Engineering Manager by the end of my time at Noom.&lt;/p&gt;
&lt;p&gt;I made a lot of mistakes as a manager and I often describe management as feeling like you have an infinite number of ways to fail and very few ways to succeed. It&#39;s a stressful and thankless job with very long iteration cycles. I still don&#39;t think of myself as a particularly good manager, and I&#39;m often haunted by an incessent feeling that I was letting my teams down.&lt;/p&gt;
&lt;p&gt;I&#39;d say my biggest accomplishments as a manager at Noom were the people I&#39;d help grow and mentor who would go on to succeed themselves. I don&#39;t look back at my time as a manager and remember the metrics we helped move, or the features we shipped, or congratulations from my bosses. Its the people that looked to me for advice, that I helped promote, that I helped get recognition that I got the most satisfaction from.&lt;/p&gt;
&lt;p&gt;By and far my biggest gripe with management are the administrative parts like promotion packets, performance reviews, Performance Improvement Plans (PIPs), Objectives and Key Results (OKRs), etc. As Noom went from a small startup to a larger and more mature company, there was more and more priority placed on standardizing and calibrating across the company. I&#39;ve heard these are typical growing pains that companies around Noom&#39;s size faced, but I can&#39;t confirm or deny this posit since Noom is the only hyper growth company I&#39;ve worked for.&lt;/p&gt;
&lt;p&gt;When Noom rolled out a new performance review system that tied performance to compensation, I struggled a lot with this change. The goal was to reward and recognize high performers, which sounds like a really great goal. You want to make sure that those teammates that are bringing a lot of value to the team are recognized and rewarded. In practice howwever, as a manager it feels really shitty to have to discern who is deserving of higher raises or bonuses based on indivdual performance when you&#39;re actually trying to optimize for your team performing well. How do you gauge whether somebody is actually performing at a level above and beyond their own? We fell back to our competency matrix, which had a few main areas but also left a lot of room for interpretation. Not every engineer fit into this template, so some did extraordinarily well in some areas and less well in others. Some also did work on areas not covered by the matrix (like documentation or organizing team events). We did raise these issues and they did eventually get addressed, but it was an extremely painful transition.&lt;/p&gt;
&lt;p&gt;Another thing I noted during my time moving from an extremely small and fast paced team to a large team was that focus and incentives shifted from the organization to individuals. What I mean by this is that as we grew, us managers became much more aware of the need to promote people, which meant we were incentivized to ensure engineers were checking off certain boxes to be able to promote them. A stark contrast from when the team was small and scrappy, we just worked towards a pure goal of keeping the company alive. As we grew, this goal was de-emphasized and a lot more focus was placed on ensuring people were happy, growing, and productive. I don&#39;t necessarily think this is a bad thing, but it was certainly not something I was prepared for.&lt;/p&gt;
&lt;p&gt;Finally, I look back now and I realize how difficult it is to learn to be a manager as a group of first time managers with little support. I wish we had more experienced engineering managers to help guide and teach us as we went, because when we finally got a manager with deep Engineering Management experience, the experience was a lot more pleasant. However it was too little, too late.&lt;/p&gt;
&lt;p&gt;I&#39;d love to try engineering management again in the future, now that I&#39;ve learned what the job entails and have a &lt;a href=&quot;https://randsinrepose.com/welcome-to-rands-leadership-slack/&quot;&gt;network&lt;/a&gt; of other engineering managers to learn from. But maybe I&#39;ll try working as an IC for a while first.&lt;/p&gt;
&lt;h1&gt;Why I&#39;m moving on&lt;/h1&gt;
&lt;p&gt;I burnt out several times during my time at Noom. I&#39;m pretty self-motivated and when I&#39;m invested, I go hard. This meant that I would find myself working really hard and burning out, or being heavily invested in something at work and burning out if I lose agency or am required to &amp;quot;disagree and commit&amp;quot;. This cycle of burning out is expensive on my psyche, and over time it manifests in negative thinking. I noticed that I&#39;m sliding into this cycle so the best way for me to reset is to move on to a new role, taking these lessons with me.&lt;/p&gt;
&lt;p&gt;I&#39;ve also done a lot of introspection these last few months and realize that as Noom grew, it needed more process in lieu of the higher bandwidth communication that was easy when the company was 50 people. As organizations grow, you need structure to ensure people are working towards the same goal, this unfortunately means that companies undergo growing pains where people like me that joined early on are required to change and adapt to the new environment. The skills that make an individual successful at a small company are very different from the skills necessary at a larger company.&lt;/p&gt;
&lt;p&gt;The incentive structures are also very different. Typically at startups, you&#39;d find a lot of intrinsically-motivated people, working towards a goal. This pool of intrinsically-motivated people is exceptionally small, and as a company grows it needs to add extrinsically-motivated people to fill the ranks. Extrinsically motivated people respond to a very different incentive structure that can be at odds with intrinsically-motivated people.&lt;/p&gt;
&lt;p&gt;What I realize is that as Noom grew, I often felt at odds with the cultural shift the company underwent. I don&#39;t know if I&#39;m just better suited to smaller companies, or was unable to adapt to the cultural shift at the company, but I often felt at odds with the leadership and processes that were put in place to support a more mature company. I don&#39;t think its good or bad, just is a consequence of hyper growth. You can be extremely diligent about preserving your &amp;quot;culture&amp;quot; but things will still change.&lt;/p&gt;
&lt;h1&gt;Next steps&lt;/h1&gt;
&lt;p&gt;I&#39;m excited to announce that I&#39;ll be moving back to an Individual Contributor (IC) role at &lt;a href=&quot;https://www.getclockwise.com/&quot;&gt;Clockwise&lt;/a&gt;. They have a really amazing piece of technology that helps people maximize their time and abstract away the really annoying task of managing your calendar. I&#39;m really excited to be joining the Growth team and working on projects like &lt;a href=&quot;https://www.getclockwise.com/ai&quot;&gt;Clockwise AI&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Sat, 03 Jun 2023 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/moving-onto-a-new-chapter/</guid>
    </item>
    <item>
      <title>How I use Obsidian</title>
      <link>https://patricklee.nyc/blog/how-i-use-obsidian/</link>
      <description>&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://obsidian.md/&quot;&gt;Obsidian&lt;/a&gt; is all the rage right now in the productivity tool market, especially with software engineers. Similar to my note-taking app &lt;a href=&quot;https://github.com/collateapp&quot;&gt;Collate Notes&lt;/a&gt; which I built in 2016 it utilizes a Markdown file format with a YAML &amp;quot;front matter&amp;quot; section on top (a-la &lt;a href=&quot;https://jekyllrb.com/docs/front-matter/&quot;&gt;Jekyll&#39;s doc format&lt;/a&gt;) to handle document metadata.&lt;/p&gt;
&lt;p&gt;This local-file first approach means that your data is durable, since it&#39;s just markdown files in a folder structure. Even if Obsidian goes out of business, the data is still there and easily usable.&lt;/p&gt;
&lt;p&gt;It also means that you need to develop your own way of using it. The tool does not dictate how you organize your data, you need to come up with your own system.&lt;/p&gt;
&lt;h2&gt;My System&lt;/h2&gt;
&lt;h3&gt;Keeping it simple&lt;/h3&gt;
&lt;p&gt;There are a lot of systems out there like the &lt;a href=&quot;https://fortelabs.com/blog/para/&quot;&gt;PARA Method&lt;/a&gt; which have several folders to organize your data depending on the context of the information. PARA requires an Archive, Projects, Areas, and Resources folder and has rules on where to store specific kinds of information.&lt;/p&gt;
&lt;p&gt;I tried it for a while and realized that more often than not I would spend time trying to figure out if something was an Area, or Resource, or Project. It&#39;s not worth the mental overhead. I want a super simple system that just stays out of my way.&lt;/p&gt;
&lt;h3&gt;Organizing Knowledge&lt;/h3&gt;
&lt;p&gt;I have two &amp;quot;areas&amp;quot; in my note-taking system. An &amp;quot;Inbox&amp;quot; where I keep anything active that I&#39;m currently working on or need access to, which is the root of the vault. And a &lt;code&gt;Knowledge&lt;/code&gt; folder inside that where I put everything when I&#39;m done with it. That&#39;s it.&lt;/p&gt;
&lt;p&gt;It looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;!Knowledge/
&amp;lt;everything else&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The workflow looks like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I want to write something down.&lt;/li&gt;
&lt;li&gt;I create a new file in the root of the folder and write it down.&lt;/li&gt;
&lt;li&gt;If I want to group stuff together, I create a folder.&lt;/li&gt;
&lt;li&gt;Once I&#39;m no longer working on this thing, or I don&#39;t need it anymore. Move it to the Knowledge folder.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Knowledge folder has subfolders, that help me organize information into smaller buckets. I have buckets for things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;My Home&lt;/li&gt;
&lt;li&gt;Business Ideas&lt;/li&gt;
&lt;li&gt;Finance&lt;/li&gt;
&lt;li&gt;Fitness&lt;/li&gt;
&lt;li&gt;Health&lt;/li&gt;
&lt;li&gt;Knowledge Management&lt;/li&gt;
&lt;li&gt;Work&lt;/li&gt;
&lt;li&gt;Software Engineering&lt;/li&gt;
&lt;li&gt;Writing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The main purpose of the Knowledge folder is to keep information around if I need it, but just tuck it away out of sight, so I can focus on the important stuff.&lt;/p&gt;
&lt;h3&gt;Task Management&lt;/h3&gt;
&lt;p&gt;The other piece of my system is task management. I&#39;ve tried all sorts of apps out there to manage tasks, and this one is the simplest and keeps tasks close to knowledge.&lt;/p&gt;
&lt;p&gt;For example, if I&#39;m working in a document where I&#39;m ideating, collecting information from various sources, or writing thoughts, it is handy to be able to drop tasks into the same document.&lt;/p&gt;
&lt;p&gt;I use the &lt;a href=&quot;https://obsidian-tasks-group.github.io/obsidian-tasks/&quot;&gt;Tasks Plugin&lt;/a&gt; to aggregate my tasks from across my whole vault, and tags to add context to tasks.&lt;/p&gt;
&lt;p&gt;A task looks like this (Emojis are used by the &lt;a href=&quot;https://obsidian-tasks-group.github.io/obsidian-tasks/&quot;&gt;tasks plugin&lt;/a&gt; to add metadata).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- [ ] Take out the garbage 🔼 📅 2023-02-08 #personal
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I have a &lt;code&gt;Tasks&lt;/code&gt; note where I aggregate all my tasks using a &lt;a href=&quot;https://obsidian-tasks-group.github.io/obsidian-tasks/queries/&quot;&gt;query&lt;/a&gt; and ensure it&#39;s grouped by tags.&lt;/p&gt;
&lt;pre&gt;
```tasks
(not done) OR (done date is today)
group by tags
sort by urgency
short mode
```
&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That&#39;s the system that&#39;s currently working for me. Everyone comes up with their own system based on their preferences, so do what feels right for you. This is how I&#39;m currently managing things, and I&#39;ll use it as long as it &lt;a href=&quot;https://patricklee.nyc/blog/note-taking-hell/&quot;&gt;sticks&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Tue, 07 Feb 2023 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/how-i-use-obsidian/</guid>
    </item>
    <item>
      <title>I&#39;m your manager, now what?</title>
      <link>https://patricklee.nyc/blog/i-m-your-manager-now-what/</link>
      <description>&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;After a recent reorganization at my company, I&#39;m taking this opportunity to start fresh with how I approach my relationship with my direct reports. I&#39;ve found that my instructions to my reports are often handed down piecemeal, expectations aren&#39;t set, or I&#39;ve just forgotten things I should be doing. That is not a great experience as a direct report.&lt;/p&gt;
&lt;p&gt;This document is really meant to keep me accountable as your manager. It&#39;s here, so you understand what I can do for you and what I expect from you. I&#39;ll refine this document as I go, and if there is anything in here you disagree with, please let me know!&lt;/p&gt;
&lt;h2&gt;My general philosophy towards management&lt;/h2&gt;
&lt;p&gt;My overall philosophy can be summed in my blog post: &lt;a href=&quot;https://patricklee.nyc/blog/the-grug-brained-manager/&quot;&gt;The Grug Brained Manager&lt;/a&gt;. Don&#39;t feel like you have to read it unless you want to get a deeper understanding of my management philosophy. In a nutshell:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;No Surprises&lt;/strong&gt;. I can&#39;t promise you won&#39;t ever be surprised, but I will try my hardest to make sure you have full information as soon as I can give it to you.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Give me the technical details.&lt;/strong&gt; I love the technical details, even if it&#39;s not my area of expertise. I&#39;m happy being a rubber duck or listening to you deep-dive into a technical issue. I may not be much help, but I&#39;ll always listen.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;I trust you.&lt;/strong&gt; By default, I will trust you to do your job to the best of your ability. I will also trust you to tell me if you need help, and I will do everything in my power to help you. Remember that trust is easy to break and difficult to repair, so I ask you to level with me whenever possible, and I will try to do the same.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Feedback is hard.&lt;/strong&gt; I will do my best to give you feedback with empathy and kindness, and work with you if there is something you can work on.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Expectations&lt;/h2&gt;
&lt;h2&gt;Onboarding&lt;/h2&gt;
&lt;p&gt;If you&#39;re new to the company, congrats! I&#39;ll be helping to support you during your onboarding period. You should be creating onboarding goals during your first few weeks on what you&#39;d like to accomplish with my help.&lt;/p&gt;
&lt;p&gt;I&#39;ll supply you with our onboarding materials, an onboarding buddy, and make myself available to answer questions.&lt;/p&gt;
&lt;p&gt;I understand onboarding is a pretty daunting time. There is a lot of new things coming at you very quickly. I don&#39;t expect you to jump in coding right away and prefer you ramp up slowly instead of drinking from the firehose. Let me know if you&#39;re feeling overwhelmed at any point and I&#39;ll try to throttle things back for you.&lt;/p&gt;
&lt;h2&gt;One on One meetings (1:1s)&lt;/h2&gt;
&lt;p&gt;Regular 1:1s are important for us to stay in touch and to ensure there is an open and available space for us to talk. My preference is weekly or bi-weekly, but I&#39;ll defer to you on the cadence.&lt;/p&gt;
&lt;p&gt;You own the agenda for the 1:1s. I&#39;ll bring topics, but I&#39;m expecting you to bring topics to discuss as well, and your topics will usually be prioritized above my topics. It&#39;s a good idea to spend a few minutes before our 1:1 to jot down some notes in our shared 1:1 document. This shared document is a great place to drop non-urgent questions or thoughts between meetings so you&#39;ll populate the agenda as you progress through the week.&lt;/p&gt;
&lt;p&gt;Some things we can discuss in your 1:1:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What are you working on? What problems are you encountering? Where are your bottlenecks?
&lt;ul&gt;
&lt;li&gt;By feeding me information on things that aren&#39;t going well, I get a better sense of what&#39;s happening on the ground and where problems maybe forming. This is super valuable!&lt;/li&gt;
&lt;li&gt;Do you have an idea for a project? Let&#39;s talk about it.&lt;/li&gt;
&lt;li&gt;Did you encounter an issue or bug somewhere? Let&#39;s talk about it.&lt;/li&gt;
&lt;li&gt;Do you have any ideas on how to improve our workflow? I&#39;d love to hear it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Let&#39;s talk about your career goals and your next step.
&lt;ul&gt;
&lt;li&gt;It&#39;s totally fine if you have no idea what your goals or next step should be, I can help guide you there with this &lt;a href=&quot;https://www.radicalcandor.com/how-to-have-career-conversations/&quot;&gt;three part career conversation&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Is your next step a promotion? Let&#39;s talk about the timeline, how the company promotes, and what you will need to do to assemble a promo packet.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Let&#39;s talk about your performance and performance review
&lt;ul&gt;
&lt;li&gt;How familiar are you with the company&#39;s performance review system? Let&#39;s talk about it.&lt;/li&gt;
&lt;li&gt;Do you have a &lt;a href=&quot;https://jvns.ca/blog/brag-documents/&quot;&gt;brag doc&lt;/a&gt;? Let&#39;s take a look at it or update it! A brag doc will help me represent your work in the best light during performance reviews.&lt;/li&gt;
&lt;li&gt;Do you know and understand the company&#39;s expectations for you in your role at your current level? Is there any part of your role you don&#39;t understand?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Curious about how parts of the company work?
&lt;ul&gt;
&lt;li&gt;I&#39;ll do my best to answer your questions or find the answer for you.&lt;/li&gt;
&lt;li&gt;Do you have any questions about your benefits or compensation? I can try to answer them or point you to somebody that can.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Curious about my take on a situation? Just ask.&lt;/li&gt;
&lt;li&gt;Do you want to vent about something? Go ahead, it&#39;s a safe space and between us.&lt;/li&gt;
&lt;li&gt;Tell me how you&#39;re feeling. Is everything going well outside work? Have you been distracted lately? Is there anything I can do to help (time off, too much work on your plate, etc.)?&lt;/li&gt;
&lt;li&gt;Need advice? I can do my best to help guide you through whatever it is you&#39;re going through.&lt;/li&gt;
&lt;li&gt;Are you happy in your role? If there is something you feel is missing, let me know so we can work on it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For my direct reports that are also managers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How is your team doing? Are you encountering any issues with your direct reports?&lt;/li&gt;
&lt;li&gt;What is your team working on?&lt;/li&gt;
&lt;li&gt;Do you have any situations with your reports where I could provide guidance?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;You don&#39;t need to wait until our 1:1 though. Feel free to schedule time with me or ping me on slack at any time.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;Brag Doc&lt;/h2&gt;
&lt;p&gt;Help me help you. I may or may not have a view of what you do on a day-to-day basis. When it comes time for promotions or performance reviews, you are your own best advocate. I will do what I can to advocate for you on your behalf, but you need to give me ammunition to make a strong case.&lt;/p&gt;
&lt;p&gt;A brag doc or work log is a simple list of the things you work on so I can take that and transform that into a performance review or promotion packet.&lt;/p&gt;
&lt;p&gt;By updating it at a regular interval, you don&#39;t need to do the &amp;quot;what did I work on a month ago or more&amp;quot; dance. Take a minute or two every week to just jot down what you&#39;ve been working on and when performance review season comes around, you don&#39;t have to do anything!&lt;/p&gt;
&lt;p&gt;Having a running work log/brag doc is also useful when it comes time to update your resume. You&#39;ll have a full accounting of your work that you can easily pull highlights from.&lt;/p&gt;
&lt;h2&gt;Promotions&lt;/h2&gt;
&lt;p&gt;Going for promotion is your choice. I will happily assist you in trying for a promotion if it&#39;s your goal, but I won&#39;t force you if you&#39;re happy where you&#39;re at.&lt;/p&gt;
&lt;p&gt;Promotions take time to plan for and to build a case for. Managers are expected to assemble a &amp;quot;Promo Packet&amp;quot; to be submitted to be reviewed. This promo packet makes the case for you and your promotion. You&#39;ll typically need to prove you exhibit the skills of a person of the next level for a minimum of six months. We&#39;ll also need to collect endorsements from people you work closely with, which I&#39;ll take care of.&lt;/p&gt;
&lt;p&gt;Let me know you want to try for promotion as soon as possible. It may take planning to build a case, and I&#39;ll guide you along the way.&lt;/p&gt;
&lt;h2&gt;Time off&lt;/h2&gt;
&lt;p&gt;I support you taking all your Paid Time Off (PTO) when you&#39;d like to take it. Please use your time off and let me know how I can support you, so you &lt;em&gt;can&lt;/em&gt; use it! I will almost always approve PTO and generally believe the team should support your time off and not vice versa.&lt;/p&gt;
&lt;p&gt;In terms of logistics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Please follow whatever PTO policy the company has laid out.&lt;/li&gt;
&lt;li&gt;Please make sure your calendar is marked without of office (OOO).&lt;/li&gt;
&lt;li&gt;A 2+ week notice before your PTO would be appreciated, but I understand if it&#39;s last minute, and we talk about it.&lt;/li&gt;
&lt;li&gt;Make sure your team and any stakeholders know you&#39;re taking PTO, and remind them as it gets closer and closer.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Working hours, location, etc.&lt;/h2&gt;
&lt;p&gt;Personally, I don&#39;t care what hours you work, or where you work, as long as you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Have your working hours set in your calendar.&lt;/li&gt;
&lt;li&gt;Attend all meetings.&lt;/li&gt;
&lt;li&gt;Have at least a 4-hour overlap between your hours and the general company working hours.&lt;/li&gt;
&lt;li&gt;Are responsive and get your work done on time and to a high standard.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, the company might have policies in place. Please follow the company policy first, and my personal policy second.&lt;/p&gt;
&lt;p&gt;I generally encourage people to have set working hours in which they are actively working and available, and then &amp;quot;offline&amp;quot; the rest of the day.&lt;/p&gt;
&lt;h2&gt;Communication&lt;/h2&gt;
&lt;p&gt;With remote work, it&#39;s really important to be communicative. Since we don&#39;t have your physical presence in an office, being over-communicative in our team messaging software is important!&lt;/p&gt;
&lt;p&gt;I will never expect a response from you if I message or email you off-hours. If it&#39;s an emergency, and you&#39;re needed, you will be paged.&lt;/p&gt;
&lt;h2&gt;Your work&lt;/h2&gt;
&lt;p&gt;I generally expect your work to be mostly bug free, conform to existing standards, and is of a high-enough quality commensurate to your level. I don&#39;t expect perfection, but I do expect improvement if you receive feedback.&lt;/p&gt;
&lt;p&gt;The most important thing is showing enthusiasm for your work, working well with your team, and treating everybody with kindness and respect. Being good at your job doesn&#39;t mean being a brilliant jerk, it means being somebody people trust and respect to get the job done.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I hope this post was able to help form a basis for our working relationship as manager / direct report. I want to make sure you have the full information to ensure you&#39;re meeting my expectations, and I want to make sure my expectations are clearly spelled out without any ambiguity.&lt;/p&gt;
&lt;p&gt;Check back from time to time as this doc might be updated as I continue to grow as a manager.&lt;/p&gt;
</description>
      <pubDate>Fri, 27 Jan 2023 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/i-m-your-manager-now-what/</guid>
    </item>
    <item>
      <title>Experimentation reading list</title>
      <link>https://patricklee.nyc/blog/experimentation-reading-list/</link>
      <description>&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;During my time on the Growth team at Noom, I&#39;ve had to learn a lot about online controlled experimentation. I&#39;ve put together most of the public resources I&#39;ve come across into this document.&lt;/p&gt;
&lt;p&gt;If you&#39;re brand new to online controlled experimentation, I high recommend starting with &lt;a href=&quot;https://experimentguide.com/&quot;&gt;Trustworthy Online Controlled Experiments : A Practical Guide to A/B Testing&lt;/a&gt;. Its a detailed guide on the experimentation landscape. It was a must-read for every member of my team, and was known as the &amp;quot;Experimentation Bible&amp;quot;.&lt;/p&gt;
&lt;h2&gt;Whitepapers&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://research.google/pubs/pub36500/&quot;&gt;Overlapping Experiment Infrastructure: More, Better, Faster Experimentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://exp-platform.com/large-scale/&quot;&gt;Online Controlled Experiments at Large Scale&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ai.stanford.edu/~ronnyk/2009controlledExperimentsOnTheWebSurvey.pdf&quot;&gt;Controlled experiments on the web: survey and practical guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1710.08217&quot;&gt;Democratizing online controlled experiments at Booking.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.exp-platform.com/Documents/2014%20experimentersRulesOfThumb.pdf&quot;&gt;Seven Rules of Thumb for Web Site Experimenters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/1801.08532&quot;&gt;SQR: Balancing Speed, Quality and Risk in Online Experiments&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://patricklee.nyc/public/blog/20230124_experimentation_reading_list.md/GrowthBookStatsWhitepaper-2021.pdf&quot;&gt;Growth Book Stats Whitepaper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2012.10403#&quot;&gt;Success Stories from a Democratized Experimentation Platform&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Notes:
&lt;ul&gt;
&lt;li&gt;Netflix experimentation platform&lt;/li&gt;
&lt;li&gt;Interesting: Netflix uses R/Python notebooks so people can contribute reports, statistical methodologies, and metrics.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Books&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://experimentguide.com/&quot;&gt;Trustworthy Online Controlled Experiments : A Practical Guide to A/B Testing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Videos&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=qtboCGd_hTA&quot;&gt;Online Controlled Experiments: Lessons from Running A/B/n Tests for 12 Years, Ron Kohavi 20151130&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Statistics&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=AJX4W3MwKzU&quot;&gt;Stanford Seminar: Peeking at A/B Tests - Why It Matters and What to Do About It&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Notes:
&lt;ul&gt;
&lt;li&gt;Frequentest
&lt;ul&gt;
&lt;li&gt;Popular 100 years ago
&lt;ul&gt;
&lt;li&gt;Data was expensive to gather back then.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Fixed sample size testing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Peeking problem
&lt;ul&gt;
&lt;li&gt;Continuously monitor results dashboard&lt;/li&gt;
&lt;li&gt;Adjust test length in real time (Adaptive sample size testing)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Peeking can dramatically inflate false positives.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Intuition
&lt;ul&gt;
&lt;li&gt;Sample size specifies a point in time, doesn&#39;t say anything about what happens between the start of the experiment and when you hit sample size.&lt;/li&gt;
&lt;li&gt;High chance of significant result on the way to sample size may bias whether we keep the test running or not.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;If you wait long enough, there is a high chance of an eventually inconclusive result looking &amp;quot;significant&amp;quot; along the way!&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Experimentation Platform&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.microsoft.com/en-us/research/group/experimentation-platform-exp/&quot;&gt;Experimentation Platform - Microsoft Research&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://multithreaded.stitchfix.com/blog/2019/07/30/building-centralized-experimental-platform/&quot;&gt;Building our Centralized Experimental Platform | Stitch Fix Technology - Multithreaded&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Notes:
&lt;ul&gt;
&lt;li&gt;They have analytics automated&lt;/li&gt;
&lt;li&gt;Not a lot of details in this blog post&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.com/intuit-engineering/open-sourcing-wasabi-the-a-b-testing-platform-by-intuit-a8d5abc958d&quot;&gt;Meet Wasabi, an Open Source A/B Testing Platform&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wasabi not under active development&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.com/airbnb-engineering/https-medium-com-jonathan-parks-scaling-erf-23fd17c91166&quot;&gt;Scaling Airbnb&#39;s Experimentation Platform&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Notes:
&lt;ul&gt;
&lt;li&gt;Uses Airflow for meteics
&lt;ul&gt;
&lt;li&gt;ERF runtime from 24 hours to 45 minutes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Useful article to learn about how they do data processing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://techblog.netflix.com/2016/04/its-all-about-testing-netflix.html&quot;&gt;It&#39;s All A/Bout Testing&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Notes:
&lt;ul&gt;
&lt;li&gt;Targeting and allocation
&lt;ul&gt;
&lt;li&gt;There is one more topic to address before we dive further into details, and that is how members get allocated to a given test. We support two primary forms of allocation: batch and real-time.&lt;/li&gt;
&lt;li&gt;Batch allocations give analysts the ultimate flexibility, allowing them to populate tests using custom queries as simple or complex as required. These queries resolve to a fixed and known set of members which are then added to the test. The main cons of this approach are that it lacks the ability to allocate brand new customers and cannot allocate based on real-time user behavior. And while the number of members allocated is known, one cannot guarantee that all allocated members will experience the test (e.g. if we’re testing a new feature on an iPhone, we cannot be certain that each allocated member will access Netflix on an iPhone while the test is active).&lt;/li&gt;
&lt;li&gt;Real-Time allocations provide analysts with the ability to configure rules which are evaluated as the user interacts with Netflix. Eligible users are allocated to the test in real-time if they meet the criteria specified in the rules and are not currently in a conflicting test. As a result, this approach tackles the weaknesses inherent with the batch approach. The primary downside to real-time allocation, however, is that the calling app incurs additional latencies waiting for allocation results. Fortunately we can often run this call in parallel while the app is waiting on other information. A secondary issue with real-time allocation is that it is difficult to estimate how long it will take for the desired number of members to get allocated to a test, information which analysts need in order to determine how soon they can evaluate the results of a test.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.twitter.com/engineering/en_us/a/2015/twitter-experimentation-technical-overview&quot;&gt;Twitter experimentation: technical overview&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Notes:
&lt;ul&gt;
&lt;li&gt;Uses feature flags&lt;/li&gt;
&lt;li&gt;Pretty unremarkable&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://engineering.zalando.com/posts/2021/01/experimentation-platform-part1.html&quot;&gt;Zalando Engineering Blog - Experimentation Platform at Zalando: Part 1 - Evolution&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Notes:
&lt;ul&gt;
&lt;li&gt;Uses craw/walk/run phrasing a-la Ronnie K&lt;/li&gt;
&lt;li&gt;Their system allows for staged rollouts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://eng.uber.com/xp/&quot;&gt;Under the Hood of Uber&#39;s Experimentation Platform&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Good details, screenshots of their XP.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Broadly, we use four types of statistical methodologies: fixed horizon A/B/N tests (t-test, chi-squared, and rank-sum tests), sequential probability ratio tests (SPRT), causal inference tests (synthetic control and diff-in-diff tests), and continuous A/B/N tests using bandit algorithms (Thompson sampling, upper confidence bounds, and Bayesian optimization with contextual multi-armed-bandit tests, to name a few). We also apply block bootstrap and delta methods to estimate standard errors, as well as regression-based methods to measure bias correction when calculating the probability of type I and type II errors in our statistical analyses.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The XP detects major issues during analysis:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sample size imbalance (Sample size ratio in control and treatment group)&lt;/li&gt;
&lt;li&gt;Flickers (Users that have switched between control and treatment groups)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;They do data pre-processing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Outlier detection using a clustering algorithm to detect and remove outliers&lt;/li&gt;
&lt;li&gt;Variance reduction using CUPED Method&lt;/li&gt;
&lt;li&gt;Remove pre-experiment bias using difference in differences to correct pre-experiment bias between groups.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sequential testing&lt;/p&gt;
&lt;p&gt;This is very similar to the circuit breaker system we were interested in building.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One use case where a sequential test comes in handy for our team is when identifying outages caused by the experiments running on our platform. We cannot wait until a traditional A/B test collects sufficient sample sizes to determine the cause of an outage; we want to make sure experiments are not introducing key degradations of business metrics as soon as possible, in this case, during the experimentation period. Therefore, we built a monitoring system powered by a sequential testing algorithm to adjust the confidence intervals accordingly without inflating Type-I error.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Using our XP, we conduct periodic comparisons about these business metrics, such as app crash rates and trip frequency rates, between treatment and control groups for ongoing experiments. Experiments continue if there are no significant degradations, otherwise they will be given an alert or even paused. The workflow for this monitoring system is shown in Figure 6, below:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Bandit aka Continuous Experiments&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bandit is used at Uber for:
&lt;ul&gt;
&lt;li&gt;Content optimization&lt;/li&gt;
&lt;li&gt;Spend optimization&lt;/li&gt;
&lt;li&gt;Hyper-parameter tuning for learning models.&lt;/li&gt;
&lt;li&gt;Automated Rollouts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://eng.uber.com/experimentation-platform/&quot;&gt;Building an Intelligent Experimentation Platform with Uber Engineering&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Notes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Uber uses their XP to do staged rollouts.&lt;/li&gt;
&lt;li&gt;On metric computation&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;The new analysis tool does not pre-compute the data of the metrics, which cut down on our data storage spend and reduced our analysis generation time. Now, when the data is ready for analysis, we use a &lt;a href=&quot;https://en.wikipedia.org/wiki/SQL&quot;&gt;SQL&lt;/a&gt; query file to generate metrics on the fly whenever people make a request on the WebUI. After that, we use &lt;a href=&quot;https://www.scala-lang.org/&quot;&gt;Scala&lt;/a&gt; as our service engine to compute the probability (&lt;a href=&quot;https://en.wikipedia.org/wiki/P-value&quot;&gt;p-value&lt;/a&gt;) that the treatment group mean is significantly different than the control group mean, determining if the experiment reached the target sample size.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.linkedin.com/pulse/in-house-experimentation-platforms-denise-visser/&quot;&gt;In-house experimentation platforms&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cool list of various companies experimentation platforms.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://data.blog/2021/03/16/explat-automattics-experimentation-platform/&quot;&gt;ExPlat: Automattic&#39;s Experimentation Platform&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Notes:
&lt;ul&gt;
&lt;li&gt;System is called Abacus&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=&amp;amp;ved=2ahUKEwjk5IWj04b0AhWBpnIEHZu0AOoQFnoECAUQAQ&amp;amp;url=https%3A%2F%2Fgithub.com%2FAutomattic%2Fabacus&amp;amp;usg=AOvVaw0Z4geVG-mMz1vxvOSMB15A&quot;&gt;Open source&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
      <pubDate>Tue, 24 Jan 2023 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/experimentation-reading-list/</guid>
    </item>
    <item>
      <title>Easy dynamic social sharing image with eleventy</title>
      <link>https://patricklee.nyc/blog/easy-dynamic-social-sharing-image-with-eleventy/</link>
      <description>&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I&#39;m in the process of rebuilding this website using &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;eleventy&lt;/a&gt; and I wanted to get fancy with this revamped site.&lt;/p&gt;
&lt;p&gt;One feature I wanted was a custom Open Graph social share image for each page on the site. If you&#39;re not familiar with Open Graph, check out &lt;a href=&quot;https://www.freecodecamp.org/news/what-is-open-graph-and-how-can-i-use-it-for-my-website/&quot;&gt;this explanation&lt;/a&gt;. In a nutshell, when you share links to the site on social networks, it should an image to draw people into the page.&lt;/p&gt;
&lt;p&gt;Eleventy has a pretty robust ecosystem already and lo and behold, there are already plugins to handle this for you. Great, let&#39;s just check them out.&lt;/p&gt;
&lt;h2&gt;What&#39;s out there?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/tannerdolby/eleventy-plugin-social-img#readme&quot;&gt;eleventy-plugin-social-img&lt;/a&gt; pre-generates cards using a shortcode. I spent about 30 minutes trying to grok the readme and how to use the plugin. I like that you could create an HTML template, but the plugin looked overly complicated for what I needed.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Resocio/eleventy-plugin-social-image#readme&quot;&gt;@resoc/eleventy-plugin-social-image&lt;/a&gt; only works with Netlify and requires a server component. This site is hosted on GitHub Pages and is fully static. Pass.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/tpiros/eleventy-plugin-social-share-card-generator#readme&quot;&gt;eleventy-plugin-social-share-card-generator&lt;/a&gt; requires a Cloudinary account. Pass.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/KiwiKilian/eleventy-plugin-og-image#readme&quot;&gt;eleventy-plugin-og-image&lt;/a&gt; looks promising, pre-generates images, and looks pretty easy to use. This could be a runner-up if I ever want to go a different route.&lt;/p&gt;
&lt;p&gt;All in all, I wasn&#39;t a huge fan of these solutions. There had to be something simpler.&lt;/p&gt;
&lt;h2&gt;Something simpler&lt;/h2&gt;
&lt;p&gt;The eleventy team offers various &lt;a href=&quot;https://www.11ty.dev/docs/api-services/&quot;&gt;API Services&lt;/a&gt; for the public to use. &lt;a href=&quot;https://www.11ty.dev/docs/services/screenshots/&quot;&gt;Screenshots&lt;/a&gt; is a runtime service that takes a screenshot of a URL and returns that image (and caches it). Bingo!&lt;/p&gt;
&lt;p&gt;All I need to do is create a simple template and style it however I&#39;d like for my social sharing card. Apply the template to every page in the site. Then the service can generate screenshots for my blog posts on demand when somebody shares a link to my site.&lt;/p&gt;
&lt;h2&gt;Creating the card template&lt;/h2&gt;
&lt;p&gt;To make it easy to manipulate URLs, I would have a mirrored set of paths at &lt;code&gt;https://patricklee.nyc/social/&amp;lt;page URL&amp;gt;&lt;/code&gt;. Then I simply embed that URL to the screenshot service API URL and it would return an image.&lt;/p&gt;
&lt;p&gt;Example of the social card webpage:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://patricklee.nyc/social/about&quot;&gt;https://patricklee.nyc/social/about&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Example of the social card screenshot image generated by the service:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://v1.screenshot.11ty.dev/https%3A%2F%2Fpatricklee.nyc%2Fsocial%2Fabout%2F/opengraph/_1674507886315&quot;&gt;https://v1.screenshot.11ty.dev/https%3A%2F%2Fpatricklee.nyc%2Fsocial%2Fabout%2F/opengraph/_1674507886315&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: You need to URLEncodeURI the page being passed into the API&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I created the simplest webpage possible, you can see the template &lt;a href=&quot;https://github.com/patleeman/patricklee.nyc/blob/master/_includes/social.liquid&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I wanted a simple design with the title of the page, the URL of this site, and a picture of me.&lt;/li&gt;
&lt;li&gt;I created a 1200 x 630 pixel box, then added my card contents in there. The &lt;a href=&quot;https://www.11ty.dev/docs/services/screenshots/#usage&quot;&gt;screenshot service&lt;/a&gt; accepts a size parameter &lt;code&gt;opengraph&lt;/code&gt; which will take a 1200 x 630 pixel screenshot.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Generating the pages&lt;/h2&gt;
&lt;p&gt;Next, we need to generate the pages on the build. To do this. I created a page &lt;code&gt;social.md&lt;/code&gt; with some basic frontmatter. See the page &lt;a href=&quot;https://github.com/patleeman/patricklee.nyc/blob/master/social.md?plain=1&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
layout: social.liquid
pagination:
  data: collections.all
  size: 1
  alias: post
permalink: &amp;quot;social//&amp;quot;
---

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This page uses a combination of &lt;a href=&quot;https://www.11ty.dev/docs/collections/#the-special-all-collection&quot;&gt;&lt;code&gt;collections.all&lt;/code&gt;&lt;/a&gt;, &lt;code&gt;pagination&lt;/code&gt;, and &lt;code&gt;permalink&lt;/code&gt; to force eleventy to generate a page for every page on the site under the &lt;code&gt;/social/&lt;/code&gt; namespace.&lt;/p&gt;
&lt;p&gt;Now when we want the social image for any page we simply add &lt;code&gt;/social/&lt;/code&gt; to the URL.&lt;/p&gt;
&lt;p&gt;For example, the page &lt;code&gt;https://patricklee.nyc/about&lt;/code&gt; has a social image at &lt;code&gt;https://patricklee.nyc/social/about&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Updating the Open Graph tags&lt;/h2&gt;
&lt;p&gt;The last part is to update the Open Graph tags to use this image. In my header, I had my Open Graph social tags available. I just needed to create a URL that would take each page&#39;s URL, and append &lt;code&gt;/social&lt;/code&gt; to it, then embed it into the screenshot service&#39;s URL scheme.&lt;/p&gt;
&lt;p&gt;To make things dead simple, I just &lt;a href=&quot;https://github.com/patleeman/patricklee.nyc/blob/56e675dd7d94121337a91924dc72eec5bbfab084/.eleventy.js#L51-L57&quot;&gt;created a shortcode&lt;/a&gt; that would generate this URL when used on a page.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;// eleventy.js
eleventyConfig.addShortcode(&amp;quot;openGraphScreenshotURL&amp;quot;, function () {
  // URL Encode the page
  const encodedURL = encodeURIComponent(
    `https://patricklee.nyc/social${this.page.url}`
  );
  // Generate a cache-busting key for quicker testing
  const cacheKey = `_${new Date().valueOf()}`;
  // Return the screenshot service&#39;s URL to add to the open graph tags.
  return `https://v1.screenshot.11ty.dev/${encodedURL}/opengraph/${cacheKey}`;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then I updated my header to use this shortcode under the &lt;code&gt;og:image&lt;/code&gt; and &lt;code&gt;twitter:image&lt;/code&gt; tags &lt;a href=&quot;https://github.com/patleeman/patricklee.nyc/blob/56e675dd7d94121337a91924dc72eec5bbfab084/_includes/layouts/header.liquid#L13&quot;&gt;like so&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;!-- header.liquid --&amp;gt;
&amp;lt;meta property=&amp;quot;og:image&amp;quot; content=&amp;quot;https://v1.screenshot.11ty.dev/https%3A%2F%2Fpatricklee.nyc%2Fsocial%2Fblog%2Feasy-dynamic-social-sharing-image-with-eleventy%2F/opengraph/_1728070925785&amp;quot; /&amp;gt;
&amp;lt;meta property=&amp;quot;twitter:image&amp;quot; content=&amp;quot;https://v1.screenshot.11ty.dev/https%3A%2F%2Fpatricklee.nyc%2Fsocial%2Fblog%2Feasy-dynamic-social-sharing-image-with-eleventy%2F/opengraph/_1728070925785&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That&#39;s all it takes!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The risk here is if the eleventy team decides to sunset the screenshot API, I&#39;ll need to switch to a solution that pre-generates the social share images or host the API myself. Considering how little traffic this site gets, I&#39;ll take that risk for reduced complexity now.&lt;/p&gt;
&lt;p&gt;I like this solution &lt;s&gt;because I came up with it&lt;/s&gt; because it is simpler, doesn&#39;t require pre-generating all the images upfront, and doesn&#39;t require adding more packages. Oh and because I was able to offload a lot of the work to the wonderful devs at eleventy. Thanks, ya&#39;ll!&lt;/p&gt;
</description>
      <pubDate>Mon, 23 Jan 2023 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/easy-dynamic-social-sharing-image-with-eleventy/</guid>
    </item>
    <item>
      <title>The Grug Brained Manager</title>
      <link>https://patricklee.nyc/blog/the-grug-brained-manager/</link>
      <description>&lt;h2&gt;The Grug Brained Manager&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://patricklee.nyc/public/blog/20220823_the_grug_brained_manager.md/grug.png&quot; alt=&quot;AI generated caveman wearing a tie&quot; /&gt;&lt;/p&gt;
&lt;p&gt;this collection of thoughts on managing software development teams by a grug brained manager based on &lt;a href=&quot;https://grugbrain.dev/&quot;&gt;grug brained developer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;grug brained manager not smart. somehow managed to convince boss that grug capable of managing others. grug barely capable to polish mouth stones.&lt;/p&gt;
&lt;p&gt;grug pretend grug know what do. grug talk to other grug managers and realize nobody know what to do. grug realize management not as simple as development.&lt;/p&gt;
&lt;p&gt;over time grug learn painful lesson after painful lesson and decide to write on stone tablet so young grug manager not make same mistake.&lt;/p&gt;
&lt;h2&gt;Managing People Is Hard&lt;/h2&gt;
&lt;p&gt;nobody told grug managing so hard. grug used to be okay grug brained developer.&lt;/p&gt;
&lt;p&gt;wanted become grug manager for more shiny rock and to be grug leader. grug no realize managing not same as developing. grug very happy developing, feel good when make shiny object and solve problem.&lt;/p&gt;
&lt;p&gt;grug no realize in management, there no shiny object to hold up proudly. type of problems grug solve take long time to see results. grug has lots of self doubt when think what to do, but grug need to make decision and commit.&lt;/p&gt;
&lt;p&gt;there not a lot of support as manager. grug find that there not a lot of process or materials for grug to learn to do job. when grug was developer, lots other grug make content to learn job. as manager, not as much information for grug on how to do actual job.&lt;/p&gt;
&lt;p&gt;grug introvert, that why grug get into making software. management however is purely people-focused, which means job is more taxing for grug. grug realize that in management, easier for grug to burn out. grug more tired at end of day. grug need to make sure to make time for self care, but hard to balance. grug burned out several times and sometimes just want to take a six month sabbatical to recover.&lt;/p&gt;
&lt;p&gt;grug not prepared to deal with unhappy people. grug no like conflict, however grug must deal with conflict in job. when grug responsible for unhappy person, it weigh heavily on grug mind and grug want to make situation better. this add extra stress on grug.&lt;/p&gt;
&lt;p&gt;grug realize that management takes much larger emotional toll on grug than developing. grug must work extra hard to not show emotion because team looks to grug as leader. sometimes grug feel strong emotion in pit of stomach but must force it to go away. this is hard for grug.&lt;/p&gt;
&lt;p&gt;it not all bad though.&lt;/p&gt;
&lt;p&gt;grug get satisfaction from seeing young grug learn and get promoted. when grug team get shiny rock and praise, grug feel good for them. grug no do this for glory, only shiny rock and see grug team solve problem and be happy.&lt;/p&gt;
&lt;p&gt;grug also get satisfaction from helping other grug do work. grug get sense of satisfaction from stopping grug product manager from other team bugging team member. grug chase them with stick and beat chest.&lt;/p&gt;
&lt;p&gt;grug also get more shiny rock for constant headaches.&lt;/p&gt;
&lt;p&gt;grug was okay grug brained developer, but there many more smarter grug brained developer. senior grug developer position rare and there are many more smart and passionate developer that will overpower grug.&lt;/p&gt;
&lt;p&gt;grug not want to develop software in free time, grug want to live life with family and provide many shiny rock for them. grug took realistic look at grug career path and decide that grug can progress in management career more than developer career.&lt;/p&gt;
&lt;p&gt;grug has skill other developer may not have. grug good at writing on stone tablet. grug enjoy think about how team can work better. grug enjoy helping lead team so company get more shiny rock and help customers. lots of grug developer only want to concentrate on making shiny object shinier, grug want to make sure customer enjoy shiny object.&lt;/p&gt;
&lt;p&gt;grug want young grug to think hard when want to try management. management not the right career path for all grug, but hard to know unless young grug try it.&lt;/p&gt;
&lt;h2&gt;Rule #1: No Surprises&lt;/h2&gt;
&lt;p&gt;grug learn over time that number one rule is &lt;strong&gt;no surprises&lt;/strong&gt;. surprises bad. surprises very bad if it affects shiny rocks grug’s team takes home. breaking this rule can lead to very bad consequences like difficult conversations or a club over grug’s head.&lt;/p&gt;
&lt;p&gt;grug realize biggest reason for surprise is grug expect one thing and direct report expect another. communication the most important thing for grug manager to do right.&lt;/p&gt;
&lt;p&gt;grug believe grug need to make expectations explicit up front with grug report. grug need to make sure direct report know what grug expect of them. direct report need to know what and how to do their job, if they do not, grug fail as manager.&lt;/p&gt;
&lt;p&gt;grug also believe that direct report should make expectations explicit with grug. grug need to know what direct report want and work with report to help them get it. grug fail as manager if he no know that.&lt;/p&gt;
&lt;p&gt;grug learn hard way that sometimes grug avoid hard conversation because it make grug uncomfortable. grug make excuse for self or ignore problem. then small problem become big problem. grug embarrassed this happen many times before grug learn. it still happen but grug used to embarrassment now.&lt;/p&gt;
&lt;p&gt;other time grug not know what expectations should be for grug developer. company leadership failed grug by not teaching grug how to be manager, but that not good excuse. grug learn many painful leadership due to grug’s lack of experience and support.&lt;/p&gt;
&lt;h2&gt;Feedback&lt;/h2&gt;
&lt;h2&gt;Getting feedback for reports&lt;/h2&gt;
&lt;p&gt;grug no have eyes everywhere. grug has limited time and too many meetings. it sometimes difficult to know how direct reports are performing. even when grug in same team as direct report, sometimes it difficult for grug to know what direct report doing.&lt;/p&gt;
&lt;p&gt;grug learn that getting feedback is hard.&lt;/p&gt;
&lt;p&gt;grug learn that grug need to meet with people that work with direct report and build relationship with them. grug needs them to trust grug so they will open up and give grug honest feedback.&lt;/p&gt;
&lt;p&gt;many people uncomfortable with giving honest feedback, especially to coworker’s manager. grug need to convince them that grug intentions good and that grug want to help direct report become better teammate.&lt;/p&gt;
&lt;p&gt;grug learn hard lesson when grug not collect feedback for direct reports. when direct report under performing, grug not know because nobody told grug. only when situation got very bad did grug know and by then grug had failed. grug learn that grug need to go and get feedback from people.&lt;/p&gt;
&lt;h2&gt;Giving feedback to reports&lt;/h2&gt;
&lt;p&gt;grug learn that giving feedback is &lt;strong&gt;hard&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;grug learn that giving feedback is one of the hardest part of management. grug not used to telling people bad things about them to their face. in real world, if grug give random person on street feedback, they hit grug with club.&lt;/p&gt;
&lt;p&gt;in business, grug learn that giving feedback can mean the difference between a good and bad team. luckily most of the time grug no get hit with club.&lt;/p&gt;
&lt;p&gt;grug need to mix own feedback for direct report and feedback from report’s team. grug learn that it takes work to figure out where direct report can improve. grug then needs to give direct report feedback.&lt;/p&gt;
&lt;p&gt;when collecting feedback for direct report, having concrete examples for negative feedback helps people connect their behavior to real situation. when people come to grug with feedback for direct report, grug try to ask for specific situation. when grug see behavior grug want to give feedback on, grug try to write it down.&lt;/p&gt;
&lt;p&gt;grug learn that giving negative feedback between positive feedback very bad. smart managers call it “shit sandwich”. grug no like shit sandwich.&lt;/p&gt;
&lt;p&gt;grug realize at end of the day, giving feedback to report like ripping off band aid. grug need to do it and get through pain. key thing grug learn is that grug always try to have good intention for direct report and that benefit should outweigh the cost.&lt;/p&gt;
&lt;p&gt;over time, after grug do it more, giving feedback not as scary, but still hard.&lt;/p&gt;
&lt;h2&gt;Managers should stay technical&lt;/h2&gt;
&lt;p&gt;grug firmly believe that managers that are close to developers should make time to work with the technology.&lt;/p&gt;
&lt;p&gt;grug realizes that the higher you are on the food chain, the more valuable your time is. there are job you can not delegate so those job should take precedence over job you can delegate.&lt;/p&gt;
&lt;p&gt;grug has worked with middle managers that are not technical. grug does not know how they make wise decisions. non-technical managers must rely on their team to make decisions. grug does not want to sit in the middle and relay messages. non-technical managers also lack ability to understand if things their team talk about make sense.&lt;/p&gt;
&lt;p&gt;grug consults technical members of team and defers to their decision. but grug is able to make better decisions than the non-technical managers.&lt;/p&gt;
&lt;p&gt;grug mostly spend available time working on small problems that help the team’s productivity. grug tries to stay out of the way as much as possible. grug fix bug here, implement nice to have feature there.&lt;/p&gt;
&lt;p&gt;grug believes that in order to lead people, grug needs to stay grounded to what life is like for them.&lt;/p&gt;
&lt;h2&gt;Hiring &amp;amp; Firing&lt;/h2&gt;
&lt;h2&gt;Hiring&lt;/h2&gt;
&lt;p&gt;when times are good, grug get approval to hire more grug developer for team.&lt;/p&gt;
&lt;p&gt;grug learn that hiring grug on to team is risky. new grug developers on team cost the team productivity for several months while they ramp up. new grug developers can also change the team dynamics. grug needs to be careful when bringing in new developers.&lt;/p&gt;
&lt;p&gt;grug learned that sometimes there is a mismatch between the hiring process and the day to day work. grug disagrees with difficult tests given in the hiring process, but grug doesn’t know how to do any better. grug also learned that the candidates that were going through the hiring process are very talented. grug sometimes wonders if the company could do better, but does not know how to fix it.&lt;/p&gt;
&lt;p&gt;grug learned that interviews go both ways. grug needs to be a good representative of the company and try to sell the company to the candidate. grug realizes in software development, talented candidates have many options, and grug wants to only hire talented candidates.&lt;/p&gt;
&lt;h2&gt;Firing&lt;/h2&gt;
&lt;p&gt;grug believes that firing somebody should be a last option and if it gets to that point, then grug has failed. grug does not want to negatively affect somebody’s life until grug has exhausted all other options.&lt;/p&gt;
&lt;p&gt;grug believes that its important to have empathy when dealing with these hard situations.&lt;/p&gt;
&lt;p&gt;grug believes that identifying potential problems early and having difficult conversations early can help avoid issues.&lt;/p&gt;
&lt;p&gt;however, sometimes there is a communication issue or misaligned expectations. grug tries to be very explicit with the report on what exactly grug needs to see the report improve on.&lt;/p&gt;
&lt;p&gt;sometimes you give people many chances and they still don’t meet grug’s expectations, so grug then needs to make the hard decision to fire them.&lt;/p&gt;
&lt;h2&gt;Processes&lt;/h2&gt;
&lt;p&gt;grug once hear phrase “process is just expectations made explicit” and grug very much like this.&lt;/p&gt;
&lt;p&gt;grug believe that like software, it is easy to prematurely optimize process within teams. grug tries to not have process until its necessary.&lt;/p&gt;
&lt;p&gt;process can slow people down. grug hear from other grug often that they need to deal with “red tape”. process for the sake of process can get in the way of grug’s team doing their job.&lt;/p&gt;
&lt;p&gt;process should be challenged from time to time. grug thinks that just because a process exists, doesn’t make it law. processes need to be re-evaluated to make sure they are still beneficial.&lt;/p&gt;
&lt;h2&gt;Keeping it simple&lt;/h2&gt;
&lt;p&gt;grug learn long ago during software development days that complexity is the external enemy. grug internalized this and tries to reduce complexity as much as possible.&lt;/p&gt;
&lt;p&gt;grug tries to teach their team the ways of the grug brained developer as much as possible.&lt;/p&gt;
&lt;p&gt;grug firmly believe that the right amount of code is 0 lines. grug wants to judiciously delete code whenever possible and make sure existing code is simple.&lt;/p&gt;
&lt;p&gt;when making technical decisions, grug considers who will be working on it. code should be accessible to even the most junior developer. writing code should be simple and obvious.&lt;/p&gt;
&lt;h2&gt;Leadership&lt;/h2&gt;
&lt;p&gt;grug had vision of leadership from movies where heroic leader charges enemy lines from the front. the reality of leadership though is that grug goes around making sure team is not blocked by anything, they like what they are working on and are happy, and that the team has what they need to do their jobs.&lt;/p&gt;
&lt;p&gt;grug’s main job is to make sure the team functions well and that ultimately they hit their goals.&lt;/p&gt;
&lt;p&gt;grug believe strongly that leading by example is important, so grug tries to live up to expectations grug has for team as much as possible. grug hear once that a leader shouldn’t ask their team to do something they wouldn’t do themselves and grug nod head vigorously.&lt;/p&gt;
&lt;p&gt;grug also believes that decisions should be made with empathy, that there is an inherent power imbalance between manager and worker that should be kept in mind.&lt;/p&gt;
&lt;p&gt;at the end of the day, grug just try to do good job as best as grug can. grug realize that there no true ideal for what a leader is. grug just try to do what is best for team members and company and try to hold together as much of the team as possible.&lt;/p&gt;
&lt;h2&gt;Communication&lt;/h2&gt;
&lt;p&gt;communication number one thing to get right as manager.&lt;/p&gt;
&lt;p&gt;clarity of communication is important skill for manager to have. grug managers can express complex ideas in simple terms.&lt;/p&gt;
&lt;p&gt;grug try not to assume people know thing and will check or give simple fast explanation for thing people may not know of. grug often see people afraid to ask clarifying questions and tries to make communication accessible.&lt;/p&gt;
&lt;p&gt;grug often need to synthesize information from various sources and combine it into coherent thesis. it important that grug listen to people and ask questions to understand underlying problem.&lt;/p&gt;
&lt;p&gt;written communication is very important for remote team. grug has team members across many time zone, written asynchronous communication ensures people can engage when it works for them.&lt;/p&gt;
&lt;p&gt;when grug must do a presentation, grug believe strongly in &lt;a href=&quot;https://guykawasaki.com/the-only-10-slides-you-need-in-your-pitch/&quot;&gt;Guy Kawasaki’s 10/20/30 presentation method.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;grug know that when manager suggest thing, it easy for people to take it as mandate. grug try to ask questions when possible to guide thought process instead of suggesting thing. grug also try to set expectation that grug not close to problem and that grug defer to team as technical experts.&lt;/p&gt;
&lt;p&gt;grug try to use simple language whenever possible. grug has many English as second language team members and wants to make sure they can understand grug.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://patricklee.nyc/public/blog/20220823_the_grug_brained_manager.md/whywastetime.gif&quot; alt=&quot;Kevin from The Office saying why waste time?&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Grug like&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.goodreads.com/book/show/33369254-the-manager-s-path&quot;&gt;The Manager&#39;s Path by Camille Fournier&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kellblog.com/2015/03/08/career-development-what-it-really-means-to-be-a-manager-director-or-vp/&quot;&gt;Career Development: What It Really Means to be a Manager, Director, or VP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://charity.wtf/2022/06/13/advice-for-engineering-managers-who-want-to-climb-the-ladder/&quot;&gt;Advice for Engineering Managers Who Want to Climb the Ladder&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;grug think that key to management is to communicate expectations clearly and set up team to meet those expectations.&lt;/p&gt;
</description>
      <pubDate>Tue, 23 Aug 2022 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/the-grug-brained-manager/</guid>
    </item>
    <item>
      <title>Resurrecting RSS feeds</title>
      <link>https://patricklee.nyc/blog/resurrecting-rss-feeds/</link>
      <description>&lt;h2&gt;The good ole days&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update (2023-01-21): I&#39;ve migrated this blog to &lt;a href=&quot;https://www.11ty.dev/&quot;&gt;eleventy&lt;/a&gt; and use its built in RSS/Atom feed generator now.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Back when I was a young lad, RSS feeds were &lt;em&gt;the&lt;/em&gt; way to stay up to date on news, blogs, and other content. You&#39;d find sites you liked, then add their content to your RSS feed reader and then you&#39;d be able to go to a single place to view all your news and content. You&#39;d be able to curate a large number of sites and read new items on a daily basis. Those were the days!&lt;/p&gt;
&lt;p&gt;Then digital advertising got big, there was real money to be made from eyeballs on your website, so slowly sites began guarding their RSS feed content, ultimately getting rid of them altogether. You wanted people engaging with your site, not with your content, and slowly content began shifting to social media.&lt;/p&gt;
&lt;p&gt;Back then, all you needed was your Google Reader feed. These days, content is gated within small walled gardens. If you aren&#39;t a member of these walled gardens, forget seeing the content! When my feeds started dying, I switched to Digg and then Reddit and Hacker News.&lt;/p&gt;
&lt;p&gt;The thing I miss most about syndicated feeds, is that it was so much easier to receive updates for smaller bloggers and news sources. Social media and Reddit are great at surfacing new content, but if I want to follow along with a small time writer, there isn&#39;t much recourse. These days you&#39;d have to follow somebody&#39;s Twitter or their Substack, but it just isn&#39;t as easy as it used to be.&lt;/p&gt;
&lt;p&gt;Today I set up a RSS reader (&lt;a href=&quot;https://netnewswire.com/&quot;&gt;NetNewsWire&lt;/a&gt;)and I&#39;m going to attempt to curate my feed with authors I&#39;m interested in hearing from. I also added a RSS feed to this blog, so others can subscribe to my feed and read what I&#39;m writing about. It won&#39;t replace Reddit or Hacker news for me, but I hope I can supplement that content!&lt;/p&gt;
&lt;p&gt;Subscribe to this blog&#39;s &lt;a href=&quot;https://patricklee.nyc/rss.xml&quot;&gt;feed&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Aside: Adding a RSS feed to this blog&lt;/h2&gt;
&lt;p&gt;Since I decided to go ahead and re-invent the wheel for this personal blog and build my own Pandoc powered static site generator, I needed a way to generate RSS feeds.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://cyber.harvard.edu/rss/rss.html&quot;&gt;RSS 2.0 spec&lt;/a&gt; is pretty simple, so why not just generate my own &lt;code&gt;rss.xml&lt;/code&gt; file then?&lt;/p&gt;
&lt;p&gt;Using a pretty simple bash script, I just parse my directory of markdown files and assemble the feed:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;function generate_RSS_feed {
    echo &amp;quot;Generating RSS feed&amp;quot;
    declare items
    while read -r file; do
        url_path=$(echo &amp;quot;$file&amp;quot; | sed &amp;quot;s:docs\/::g&amp;quot; | sed &amp;quot;s:\.md::g&amp;quot;)
        date=$(grep &amp;quot;created:&amp;quot; &amp;quot;$file&amp;quot; | sed &amp;quot;s/created: //g&amp;quot;)
        converted_date=$(convert_date_format_822 &amp;quot;%Y-%m-%d&amp;quot; &amp;quot;$date&amp;quot;)
        title=$(grep &amp;quot;title:&amp;quot; &amp;quot;$file&amp;quot; | sed &amp;quot;s/title: //g&amp;quot;)
        html=$(pandoc &amp;quot;$file&amp;quot;)
        items+=$(cat &amp;lt;&amp;lt; END
    &amp;lt;item&amp;gt;
      &amp;lt;title&amp;gt;${title}&amp;lt;/title&amp;gt;
      &amp;lt;description&amp;gt;&amp;lt;![CDATA[${html}]]&amp;gt;&amp;lt;/description&amp;gt;
      &amp;lt;link&amp;gt;https://patricklee.nyc/$url_path&amp;lt;/link&amp;gt;
      &amp;lt;pubDate&amp;gt;${converted_date}&amp;lt;/pubDate&amp;gt;
    &amp;lt;/item&amp;gt;
END
)
    done &amp;lt; &amp;lt;(find &amp;quot;docs/blog&amp;quot; -name &#39;*.md&#39; ! -name &amp;quot;index.md&amp;quot;)
    pub_date=$(date -R)
    template=$(cat &amp;lt;&amp;lt; END
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; ?&amp;gt;
&amp;lt;rss version=&amp;quot;2.0&amp;quot;&amp;gt;
  &amp;lt;channel&amp;gt;
    &amp;lt;title&amp;gt;Patricklee.nyc&amp;lt;/title&amp;gt;
    &amp;lt;link&amp;gt;https://patricklee.nyc/&amp;lt;/link&amp;gt;
    &amp;lt;description&amp;gt;Software engineering and general geekery&amp;lt;/description&amp;gt;
    &amp;lt;language&amp;gt;en-us&amp;lt;/language&amp;gt;
    &amp;lt;pubDate&amp;gt;${pub_date}&amp;lt;/pubDate&amp;gt;
    ${items}
  &amp;lt;/channel&amp;gt;
&amp;lt;/rss&amp;gt;
END
)
    touch &amp;quot;build/rss.xml&amp;quot;
    echo -e &amp;quot;$template&amp;quot; &amp;gt; &amp;quot;build/rss.xml&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All this does is parse the frontmatter section of the markdown file to get some basic metadata, then use Pandoc to convert the file to html. It then assembles the XML file and writes it to &lt;code&gt;rss.xml&lt;/code&gt;. This function runs at the end of my blog&#39;s &lt;a href=&quot;https://github.com/patleeman/patricklee.nyc/blob/master/build.sh&quot;&gt;build chain&lt;/a&gt;, but it can be run isolated as well.&lt;/p&gt;
&lt;p&gt;See the &lt;a href=&quot;https://github.com/patleeman/patricklee.nyc/blob/master/build_scripts/rss.sh&quot;&gt;script here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&#39;m actually quite happy with this collection of bash scripts and Pandoc to generate my static site. The whole thing is stupid simple, there is zero magic, its ugly but functional and it is very narrowly scoped. There is very little that can go wrong and not many dependencies. For a blog that I want to infrequently update and keep around for a long time, its perfect and won&#39;t rot once a new JS framework gains popularity.&lt;/p&gt;
</description>
      <pubDate>Wed, 15 Jun 2022 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/resurrecting-rss-feeds/</guid>
    </item>
    <item>
      <title>Note taking hell</title>
      <link>https://patricklee.nyc/blog/note-taking-hell/</link>
      <description>&lt;h2&gt;Note taking hell&lt;/h2&gt;
&lt;p&gt;Update(Feb 7, 2023): I&#39;ve written down how &lt;a href=&quot;https://patricklee.nyc/blog/how-i-use-obsidian&quot;&gt;I&#39;m currently using Obsidian&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I have a hard time sticking with a note taking system. I think at this point I&#39;ve tested all the major note taking tools:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Evernote&lt;/li&gt;
&lt;li&gt;OneNote&lt;/li&gt;
&lt;li&gt;Simple note&lt;/li&gt;
&lt;li&gt;Turtl&lt;/li&gt;
&lt;li&gt;Google keep&lt;/li&gt;
&lt;li&gt;Standard Notes&lt;/li&gt;
&lt;li&gt;Workflowy&lt;/li&gt;
&lt;li&gt;Bear&lt;/li&gt;
&lt;li&gt;todo.txt&lt;/li&gt;
&lt;li&gt;plain text markdown files&lt;/li&gt;
&lt;li&gt;Omni notes&lt;/li&gt;
&lt;li&gt;Apple Notes&lt;/li&gt;
&lt;li&gt;Obsidian&lt;/li&gt;
&lt;li&gt;Notion&lt;/li&gt;
&lt;li&gt;Roam Research&lt;/li&gt;
&lt;li&gt;Athens Resarch&lt;/li&gt;
&lt;li&gt;Coda&lt;/li&gt;
&lt;li&gt;Mem.ai (currently trying out)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&#39;ve also built and sold a now defunct note taking app called &lt;a href=&quot;https://github.com/Collateapp/CollateNotes&quot;&gt;Collate Notes&lt;/a&gt; as well as a VS Code plugin called &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=patricklee.vsnotes&quot;&gt;VSNotes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I can&#39;t settle on anything! My notes, tasks, etc are scattered across various services and no one service seems to be able to keep my attention for long. I keep looking for that note taking panacea that will organize my life and help me become more productive, however everything I try always seems to come up short in some way, shape or form.&lt;/p&gt;
&lt;p&gt;Notion is a favorite of mine, it had really great flexibility... but too much flexibility. It functioned great for writing nice looking documents, but failed at jotting down small tidbits quickly. I felt like I spent too much time making documents look nice instead of actually using the tool.&lt;/p&gt;
&lt;p&gt;Roam Research was really nice. It introduced me to &lt;a href=&quot;https://en.wikipedia.org/wiki/Zettelkasten&quot;&gt;Zettelkasten&lt;/a&gt; which is a neat concept. However I dropped it because Roam was expensive and lacked polish. In it&#39;s stead I tried Athens Research and Obsidian, both were pretty meh.&lt;/p&gt;
&lt;p&gt;Plain text note taking is all the rage with minimalists. I&#39;m a big fan of markdown for documentation (this blog is written in markdown). For notes, it was okay. Interoperability between services usually sucks. Pasting raw markdown into a Google doc will just result in a bunch of markdown formatting in a google doc, so that doesn&#39;t work. Syncing data is also a bigger pain with plain text. Do you use Git? A service like dropbox? Then on mobile your tool needs to work with these services.&lt;/p&gt;
&lt;p&gt;It&#39;s a nightmare!&lt;/p&gt;
&lt;h2&gt;I have no idea what I want&lt;/h2&gt;
&lt;p&gt;Do I want a writing tool?
Do I want a way to manage tasks?
Do I want a way to be reminded of things?
Do I want a way to manage a knowledge base?
Do I need a bookmarking tool?
Will I ever look at these notes ever again?
How do I reconcile the Google Docs heavy world that my work org operates in?
Do I want a dashboard that I can keep up all day to jot down notes, see my meetings, etc?&lt;/p&gt;
&lt;p&gt;I would love having all these things in a single tool, but that&#39;s not feasible. Its basically an operating system at that point. The services that try end up sucking. The services that don&#39;t end up lacking. Damned if you do, damned if you don&#39;t.&lt;/p&gt;
&lt;h2&gt;I&#39;m so lazy&lt;/h2&gt;
&lt;p&gt;I would love to be able to just automate stuff too. Click a button in slack and a todo item pops up in my tool or bookmark this link and it shows up in my notes. Integrations are great, interoperability between services means that I can pipe data from this service into my online brain. However very rarely does it do what you actually want. APIs don&#39;t play nice, data isn&#39;t available, hell a lot of these services don&#39;t even have APIs. What is one to do?&lt;/p&gt;
&lt;p&gt;The promise of a 2nd brain, in the cloud, ready to be queried that offloads the work of thinking. Isn&#39;t that the dream? To be able to think a thought and have it appear in a personal knowledge base to be ingested and understood by a machine? Then spat back out to you at the appropriate time and place? Barring having a hyper intelligent machine, what is one to do?&lt;/p&gt;
&lt;h2&gt;I think I need to designate scopes&lt;/h2&gt;
&lt;p&gt;I need to pick several tools and keep them in their lanes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Calendar: Google Calendar&lt;/li&gt;
&lt;li&gt;Reminders: Apple Reminders&lt;/li&gt;
&lt;li&gt;Jotting down ideas: Whatever is nearby?&lt;/li&gt;
&lt;li&gt;Writing: Google Docs / Markdown (depends on context)&lt;/li&gt;
&lt;li&gt;Bookmarking: Raindrop.io&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I think leveraging a tool like raindrop.io will help me keep all these various notes organized in a central location... at least until I get bored of maintaining it...&lt;/p&gt;
&lt;p&gt;Update(Feb 7, 2023): I&#39;ve written down how &lt;a href=&quot;https://patricklee.nyc/blog/how-i-use-obsidian&quot;&gt;I&#39;m currently using Obsidian&lt;/a&gt;&lt;/p&gt;
</description>
      <pubDate>Fri, 20 May 2022 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/note-taking-hell/</guid>
    </item>
    <item>
      <title>Striving for dispassionateness</title>
      <link>https://patricklee.nyc/blog/striving-for-dispassionateness/</link>
      <description>&lt;h2&gt;Striving for dispassionateness&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Not influenced by strong feelings or emotions; impartial&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://www.thefreedictionary.com/dispassionateness#:~:text=dispassionateness-,noun,%2C%20nonpartisanship%2C%20objectiveness%2C%20objectivity.&quot;&gt;Definition&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As I continue on my leadership journey managing the Growth engineering team at Noom, one aspect of my personality I&#39;ve been trying to work on is detachment. I have a mantra &amp;quot;Strive for dispassionateness&amp;quot; that I plastered on top of my personal goals to remind me to continue to detach myself from emotions. Dispassionateness or detachment as I&#39;ve defined it is the process of removing emotion from the decision making process to reduce the impact of bias and to try to make the best decisions possible.&lt;/p&gt;
&lt;p&gt;My coworker Nikhil, the VP of Growth at Noom is my model for dispassionateness. I&#39;ve worked with him for four years now and in this time I&#39;ve had a glimpse into how he handles making difficult decisions and accepting hard feedback. He does it with thoughtfulness, without ego, and kindness. Its quite impressive to see.&lt;/p&gt;
&lt;p&gt;I&#39;m an emotional person, I feel strong emotions which can bias my decision making process. This personality trait has hurt me in the past. I&#39;ve been in situations where I have a hard time forming sentences, breathing gets difficult, vision blurs. Getting overwhelmed by emotions is truly an awful experience. The adrenaline pumps as the fight or flight response kicks in, paralyzing your mind in indecision, and impairing your ability to think. I&#39;m a conflict-adverse introvert. I hate conflict, but as a people manager and leader there is no avoiding conflict sometimes. You will eventually get pulled into it, especially in a fast moving organization with many different people with their own biases, goals, and opinions.&lt;/p&gt;
&lt;p&gt;Disconnecting yourself from emotions isn&#39;t burying your emotions. Its a process of introspection and learning what your current emotional state is, and either working to return to my baseline state, or removing myself from the situation. A few things that I&#39;ve learned:&lt;/p&gt;
&lt;h2&gt;Understanding what affects my mood&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;If I&#39;m hungry or if I didn&#39;t get enough sleep, I&#39;ll often become irritable.&lt;/li&gt;
&lt;li&gt;When I exercise regularly in the mornings, I set myself up to be in a better head space.&lt;/li&gt;
&lt;li&gt;I burn out if I don&#39;t take vacations often or there are other compounding stressors. How close to burnout is important for me to keep tabs on. The closer I am, the more erratic my behavior will be and the less passionate I will be about work.&lt;/li&gt;
&lt;li&gt;As it gets closer to the end of the day, I get tired and can more easily get irritable.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Understanding when to stop and take a breather&lt;/h2&gt;
&lt;p&gt;Sometimes people send me a message or email that spike my blood pressure. I&#39;ve found that if something triggers me, taking a step back to think about it or let it bake helps a lot. I&#39;ve found a lot of success putting something down, then picking it up again the next morning when I&#39;m fresh and in a better head space. The scope of problems tend to be smaller the farther you get from it and initial reactions are usually overblown.&lt;/p&gt;
&lt;h2&gt;Understanding when to dig in&lt;/h2&gt;
&lt;p&gt;Speaking of initial reactions, one of my flaws is overreacting based on my initial reaction. Its easy to do so, but generally taking some time to investigate and dig in before gauging the severity of it is beneficial and something I actively work on. Its very easy to experience something, scream &amp;quot;WHAT?&amp;quot;, go on a tear and make things works. It takes discipline and detachment to stop, investigate, and ask questions, then thoughtfully determine the impact and next steps.&lt;/p&gt;
&lt;h2&gt;Understanding when to let things fall by the wayside.&lt;/h2&gt;
&lt;p&gt;If you&#39;re doing a good job, people are going to want you to do more. Knowing when to let things fall by the wayside (which is different from letting things slip through the cracks) is an invaluable skill.&lt;/p&gt;
</description>
      <pubDate>Mon, 21 Mar 2022 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/striving-for-dispassionateness/</guid>
    </item>
    <item>
      <title>Goodbye iterm2</title>
      <link>https://patricklee.nyc/blog/goodbye-iterm2/</link>
      <description>&lt;p&gt;I&#39;ve used iTerm 2 for a few years now but came to the realization that I don&#39;t actually use any of its features. Mac&#39;s built in terminal is more than enough for my needs. See ya later iTerm 2 and thanks for being rock solid all these years.&lt;/p&gt;
</description>
      <pubDate>Fri, 07 Jan 2022 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/goodbye-iterm2/</guid>
    </item>
    <item>
      <title>An ode to my linter</title>
      <link>https://patricklee.nyc/blog/an-ode-to-my-linter/</link>
      <description>&lt;pre&gt;&lt;code&gt;Oh my dearest linter,
adding squiggly lines under my mistake.
Gently teaching me why I&#39;m wrong.
How do I fix it?
Some help would be nice.
You autocorrected it! Thank you twice!

The documentation is right at hand:
&amp;quot;you idiot, don&#39;t add an ampersand!&amp;quot;
But I think you might be wrong,
my dear linter this is an edge case!
Well then I&#39;ll just have to add
a little comment to disable that
tiny check on line 35.
I&#39;m sorry my linter,
you&#39;ll have to abide.

&lt;/code&gt;&lt;/pre&gt;
</description>
      <pubDate>Thu, 30 Dec 2021 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/an-ode-to-my-linter/</guid>
    </item>
    <item>
      <title>Dotfiles</title>
      <link>https://patricklee.nyc/blog/dotfiles/</link>
      <description>&lt;p&gt;Finally got my &lt;a href=&quot;https://github.com/patleeman/dotfiles&quot;&gt;dotfiles&lt;/a&gt; set up. Now I can have a consistent environment across both Mac and Linux. Really only using it for managing initial environment setup scripts and to manage my terminal environment. Will continue to evolve it as I need to but glad to have built out the basic scaffolding.&lt;/p&gt;
</description>
      <pubDate>Wed, 29 Dec 2021 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/dotfiles/</guid>
    </item>
    <item>
      <title>My walking desk setup</title>
      <link>https://patricklee.nyc/blog/my-walking-desk-setup/</link>
      <description>&lt;p&gt;Over the course of 2020 and 2021 I&#39;ve become increasingly sedentary with lockdown and full remote work. Having gone from commuting into the office 1-2 times a week down to zero meant I had less opportunity to walk. Along with the birth of my son and having less time and energy to exercise I needed to find a way to integrate more walking into my routine. If I could figure out how to exercise while working then I would have more time to spend on more interesting things, a win-win situation!&lt;/p&gt;
&lt;p&gt;I&#39;ve seen treadmill desks before and was motivated after seeing one of my coworkers on one during a meeting. So I decided to pick up a treadmill and give it a shot.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://patricklee.nyc/public/blog/20211228_my_walking_desk_setup.md/1.png&quot; alt=&quot;The full walking desk setup&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This is my humble treadmill desk.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;The treadmill&lt;/h2&gt;
&lt;p&gt;There are a lot of treadmills on the market of varying quality. I knew that I didn&#39;t need a high end treadmill since I was only going to walk on it. Space is an issue, so I wanted something that could fold away if I had company and needed to use my office as a guest room. Finally I wanted to make sure the product had a warranty and a presence in the US in case something happened with the product. There are plenty of dodgy looking walking treadmills on Amazon and I just didn&#39;t want to take the chance of getting a piece of junk.&lt;/p&gt;
&lt;p&gt;This pretty much narrowed my choices down to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://treadly.co/order-treadly-2&quot;&gt;Treadly 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.lifespanfitness.com/products/tr1200-dt3-under-desk-treadmill?_pos=4&amp;amp;_psq=tr1200&amp;amp;_ss=e&amp;amp;_v=1.0&quot;&gt;LifeSpan TR1200&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While the LifeSpan TR1200 was a more solid choice, I decided to go with the smaller, sleeker and most importantly cheaper Treadly 2. My impressions of the treadly so far after about a month of usage:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Its heavier than I had expected. The build quality is good, it feels rugged and pretty solid.&lt;/li&gt;
&lt;li&gt;I didn&#39;t get the one with the bluetooth and I kinda wish I spent the extra money and gotten it. Since I&#39;m stationary at a desk, my Apple watch doesn&#39;t record the steps properly and being able to sync Apple Health to the Treadly would have been nice. It&#39;s no big deal though. You can upgrade to the pro version but it requires paying the difference and shipping back the existing treadmill.&lt;/li&gt;
&lt;li&gt;A pile of black rubber accumulates at the back of the treadmill after a walk. I think it&#39;s rubber off the bottom of my shoes getting rubbed off, at least I hope it is. It would not be great if this was the belt disintegrating, but I don&#39;t see any wear on it so far.&lt;/li&gt;
&lt;li&gt;The hand rail is covered by my desk so it&#39;s functionally useless, I just use the included remote to start and stop the treadmill. The handrail feels pretty solid though and it&#39;s folding mechanism is pretty solid.&lt;/li&gt;
&lt;li&gt;It has a bluetooth speaker but I don&#39;t have a need for it.&lt;/li&gt;
&lt;li&gt;The speed increments are in MPH and I&#39;ve found my comfortable walking speed is about 2.1 MPH. I don&#39;t know how accurate speed or step counter are but that doesn&#39;t really matter all that much.&lt;/li&gt;
&lt;li&gt;I only use the manual mode since I want the treadmill to set the pace and all I have to do is keep up. The Treadly 2 has an automatic mode that adjusts the speed based on where on the treadmill you&#39;re walking. Further up and it speeds up, further back and it slows down.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Overall I&#39;m pretty happy with this treadmill!&lt;/p&gt;
&lt;h2&gt;The setup&lt;/h2&gt;
&lt;p&gt;I have a standing desk which I had planned on using as my treadmill desk. The plan was to set up the treadmill in the morning then move it out of the way when I was finished so I could sit/stand the rest of the day. I tried this a few days and realized that I needed to have a dedicated setup for the treadmill desk and that it had to live somewhere semi-permanently. Having to set up the treadmill attributed some friction to actually using it which meant I was less likely to use it.&lt;/p&gt;
&lt;p&gt;So I cleared some space in my office, purchased a relatively cheap &lt;a href=&quot;https://www.amazon.com/dp/B093GLT2QY?psc=1&amp;amp;ref=ppx_yo2_dt_b_product_details&quot;&gt;Tangkula adjustable standing desk&lt;/a&gt; off of Amazon and repurposed some extra peripherals I had laying around. I also purchased a Logitech C920x webcam for this setup so I could take video calls while on the treadmill desk.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://patricklee.nyc/public/blog/20211228_my_walking_desk_setup.md/2.png&quot; alt=&quot;The desk setup&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;On the desk: Split Keyboard, Apple Trackpad, wrist rests, Logitech C920x, LG 34&amp;quot; Ultrawide monitor, Ergotron monitor arm, Treadly 2 remote&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When everything came, I realized that the standing desk needed to raised over the treadmill so it could slide underneath the desk setup. This is important because this cheap standing desk is relatively shallow and I needed to be centered in the middle of the treadmill so the desk had to be slid back. To solve this problem, I just bought some cheap &lt;a href=&quot;https://www.amazon.com/dp/B08QVJMWTD?psc=1&amp;amp;ref=ppx_yo2_dt_b_product_details&quot;&gt;6&amp;quot; bed risers&lt;/a&gt; which gave the desk enough height so it could clear the treadmill.&lt;/p&gt;
&lt;p&gt;I also have a small fan that blows me while I&#39;m walking since I get pretty warm after walking a while. The fan helps a lot.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://patricklee.nyc/public/blog/20211228_my_walking_desk_setup.md/3.png&quot; alt=&quot;Treadmill and cooling fan&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The desk is raised over the treadmill with the bed risers and the fan helps keep me cool while I walk.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Using it&lt;/h2&gt;
&lt;p&gt;My goal is 10,000 steps per day and I&#39;ve found that I&#39;m able to complete that in about three hours at a leisurely 2.1 MPH pace. The first few weeks I was pretty tired and didn&#39;t walk every day. It does take a period of acclimation to go from mostly sedentary to walking the equivalent of 2-3 miles a day so I wasn&#39;t kicking myself for not hitting my goal. Ultimately I want to build a long lasting healthy habit so I&#39;m taking it slow and working up to my goal.&lt;/p&gt;
&lt;p&gt;Some of my impressions after several weeks of daily usage:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I find that walking doesn&#39;t impede with my flow state. I&#39;m able to write code or documents just fine while walking. I&#39;m writing this blog post while walking. The constant pace and repetitiveness of it isn&#39;t distracting so it&#39;s quite easy to forget I&#39;m on a treadmill after a while.&lt;/li&gt;
&lt;li&gt;I usually spend about 2 hours on the treadmill in the mornings. More if I have meetings and need to stop walking so I can interact in the meeting. Ideally I&#39;d block off time for walking in the mornings and is something I will be exploring. I&#39;ve had a few times where my mornings were jam packed with meetings which caused me to miss my walk. Once I get going its hard to switch gears and move to the treadmill in the afternoons.&lt;/li&gt;
&lt;li&gt;Walking can be distracting in meetings. For meetings I need to be highly engaged I usually stop the treadmill but stay standing. For low engagement meetings I&#39;ll keep walking. Walking and talking leaves me breathless so I usually need to stop if I enter a discussion. This should be less of a problem as I acclimate and get healthier.&lt;/li&gt;
&lt;li&gt;I&#39;m constantly drinking water while walking, no spills yet! Haven&#39;t tried drinking hot coffee yet, though I might just skip that.&lt;/li&gt;
&lt;li&gt;I keep a pair of shorts, socks and my walking shoes next to the treadmill so I have no excuses to not walk.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I&#39;m really enjoying my walking desk. I&#39;m getting in physical activity where I&#39;d otherwise be sitting at my desk. My work is getting done and I&#39;m able to optimize my time outside work for other things I enjoy doing (like hanging out with my family)!&lt;/p&gt;
&lt;p&gt;My key takeaways from this project:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If I expect myself to use this walking desk there needs to be almost no barriers to me hopping at any time.&lt;/li&gt;
&lt;li&gt;Creating a comfortable setup (keyboard, trackpad, monitor, etc) that is very similar to my desk setup is important. If I tried to work off my laptop instead of with external monitors and peripherals like I normally do I think I would be way less motivated to hop over to the standing desk.&lt;/li&gt;
&lt;li&gt;Walking is great!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&#39;ve been considering a walking desk, I&#39;d highly recommend trying it out. Just make sure you have the space to dedicate to it. You can always pick up a cheap used treadmill and rig up a desk setup.&lt;/p&gt;
</description>
      <pubDate>Tue, 28 Dec 2021 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/my-walking-desk-setup/</guid>
    </item>
    <item>
      <title>Lessons learned from dabbling in the stock market</title>
      <link>https://patricklee.nyc/blog/lessons-learned-from-dabbling-in-the-stock-market/</link>
      <description>&lt;p&gt;I&#39;ve dabbled in investing in the past but over the last two years I&#39;ve really gotten involved heavily with managing my portfolio. I&#39;m still a complete amateur but I did pick up some very valuable lessons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I&#39;ve started to attach probabilities to events way more than I used to. This has the benefit of helping me think about potential events more objectively.&lt;/li&gt;
&lt;li&gt;There is a zen to riding the highs and lows of the market. It takes confidence in a long term game plan, diversification, and some good ole detachment in order to psychologically bear the swings.&lt;/li&gt;
&lt;li&gt;I learned not to go into a trade without an exit plan (still working on actualizing this one).&lt;/li&gt;
&lt;li&gt;The more you risk, the more you could potentially be rewarded.&lt;/li&gt;
&lt;li&gt;You could also lose everything in one bad trade. Don&#39;t put all your eggs in one basket.&lt;/li&gt;
&lt;li&gt;Leverage is a powerful and dangerous tool. Use it with extreme caution.&lt;/li&gt;
&lt;li&gt;A stock&#39;s price usually reached an equilibrium until some catalyst occurs. The same could be said about life, usually we reach some steady state until a catalyzing life event occurs.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TODO: explore how to introduce catalysts in a more consistent manner.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Companies rise and fall on a regular basis. What seems like a juggernaut one year may implode the next. Same for companies that seem to be worthless can be turned around and brought back from the grave.&lt;/li&gt;
&lt;/ul&gt;
</description>
      <pubDate>Mon, 27 Dec 2021 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/lessons-learned-from-dabbling-in-the-stock-market/</guid>
    </item>
    <item>
      <title>I should have learned more bash sooner</title>
      <link>https://patricklee.nyc/blog/i-should-have-learned-more-bash-sooner/</link>
      <description>&lt;p&gt;Bash tools are super powerful once you get a hang of using it. This whole blog is pretty much &lt;a href=&quot;https://github.com/patleeman/patricklee.nyc/&quot;&gt;a bunch of scripts and Pandoc&lt;/a&gt;. Its pretty cool what you can build once you get over the learning curve.&lt;/p&gt;
&lt;p&gt;I&#39;m a few years into my career now and I&#39;ve only really used shell scripts when working with CI. I&#39;ve never felt totally comfortable with it, maybe it&#39;s because it feels like casting spells by uttering some obscure incantations? I mean look at one of the lines I put together to sort an array for this blog:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;IFS=$&#39;\n&#39; SORTED_POSTS=( $(for j in &amp;quot;${POSTS[@]}&amp;quot;; do echo $j; done | sort -t &amp;quot;;&amp;quot; -k 1 -nr) )
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What does all this mean?
&lt;code&gt;IFS=$&#39;\n&#39;&lt;/code&gt; Hackily set the internal separator to newline so it stops breaking my strings up by spaces
&lt;code&gt;$(for j in &amp;quot;${POSTS[@]}&amp;quot;; do echo $j; done | sort -t &amp;quot;;&amp;quot; -k 1 -nr)&lt;/code&gt; Loop through the $POSTS array (not shown) and sort by the first column delineated by ;
&lt;code&gt;SORTED_POSTS=( ... )&lt;/code&gt; Create an array from the output of the previous command&lt;/p&gt;
&lt;p&gt;Hell, this probably isn&#39;t even the right way to do what I wanted it to do, but it works for my use case. What&#39;s really cool though is just how powerful and terse it is. The difficulty lies in getting started with it.&lt;/p&gt;
&lt;p&gt;Some of the Pros and Cons I&#39;ve encountered so far:&lt;/p&gt;
&lt;p&gt;Pros&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Portable between many different systems&lt;/li&gt;
&lt;li&gt;Plenty of information available online&lt;/li&gt;
&lt;li&gt;Very powerful and terse&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cons&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Learning curve is steep&lt;/li&gt;
&lt;li&gt;Lots of different ways to do X but somebody on the internet will tell you you&#39;re wrong&lt;/li&gt;
&lt;li&gt;Readability is not very good. If you want to share scripts with a team, you might want to choose something like Python.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So if I were to advise my slightly younger self:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Take a few days and learn how to write bash scripts.&lt;/li&gt;
&lt;li&gt;Read up on the basics of bash scripting.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://learnxinyminutes.com/docs/bash/&quot;&gt;Learn X in Y seconds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://mywiki.wooledge.org/BashGuide&quot;&gt;Bash Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Try writing some scripts to automate things (like setting up your &lt;a href=&quot;https://github.com/patleeman/dotfiles&quot;&gt;dotfiles repo&lt;/a&gt; sooner)&lt;/li&gt;
&lt;li&gt;If you find yourself reaching to some programming language to do something, try doing it in bash first.&lt;/li&gt;
&lt;li&gt;Don&#39;t bother with anything complicated interactively. Create a script file and execute it if its anything more than a one liner.&lt;/li&gt;
&lt;/ul&gt;
</description>
      <pubDate>Sun, 26 Dec 2021 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/i-should-have-learned-more-bash-sooner/</guid>
    </item>
    <item>
      <title>2018 Reading List and Look Back</title>
      <link>https://patricklee.nyc/blog/2018-reading-list-and-look-back/</link>
      <description>&lt;h2&gt;Changes in 2018&lt;/h2&gt;
&lt;p&gt;Last year I left Penguin Random House in April to work at Noom. I’m normally a utility reader and don’t do much reading for entertainment. During my entire 2.5 years at Penguin Random House, I think read at most a handful of books.&lt;/p&gt;
&lt;p&gt;The culture at Noom really embraces reading and encourages it, so this year I got some recommendations from my colleagues and began reading. This list is all business-y books that I have annotated with some thoughts. For the most part, they were all useful in their own way and once internalized, have helped me be more thoughtful and analytical.&lt;/p&gt;
&lt;h2&gt;Patrick’s 2018 Reading List&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The Goal - Eliyahu M. Goldratt&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Phoenix Project - Gene Kim, Kevin Behr, George Spafford&lt;/p&gt;
&lt;p&gt;The Phoenix Project is based on The Goal and references it often. Both weren’t particularly well written but they do give an interesting look at how manufacturing principals can be applied to modern office style work. An interesting way to think about how to structure teams and organize work.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The High Growth Handbook - Elad Gil&lt;/p&gt;
&lt;p&gt;Quite a comprehensive look into what it takes to build and grow startups. A lot of good information for startup newbies like me. I wasn’t too into the interviews but I can see myself going back and re-reading this every so often.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Powerful - Patty McCord &lt;strong&gt;*Recommended&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A look into how Netflix does things. I am still reading it but it’s quite a good read. Structured more as a guide for how to run a company the Netflix way than a tell all.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Power of Habit - Charles Duhigg &lt;strong&gt;*Recommended&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Interesting book on the psychology of habits, how to change them and how to re-wire our reward mechanisms. Not sure if I’ll try to apply any of the concepts to myself but it’s good information to internalize.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Clean Code - Robert C. Martin &lt;strong&gt;*Recommended&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The only software development book I read this year. Classic advice for writing maintainable code.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ReWork - Jason Fried and David Hansson&lt;/p&gt;
&lt;p&gt;A compilation of what seem like blog posts. A lot of advice on various things. I wasn’t too impressed by it, but it’s a quick read.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
      <pubDate>Tue, 01 Jan 2019 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/2018-reading-list-and-look-back/</guid>
    </item>
    <item>
      <title>Health and Fitness</title>
      <link>https://patricklee.nyc/blog/health-and-fitness/</link>
      <description>&lt;p&gt;I&#39;ve been on quite the fitness journey these last few months. Here&#39;s my story.&lt;/p&gt;
&lt;h2&gt;How it started&lt;/h2&gt;
&lt;p&gt;I didn’t grow up athletic. I didn’t play any sports, exercise, or spend much time outdoors as a kid. I enjoyed indoor activities like video games, legos and computers. When I got into my 20s, I got into cycling and rode with friends for fun and as a way to commute to work. It was hobby first with beneficial exercise as a side effects.&lt;/p&gt;
&lt;p&gt;Eventually I stopped cycling. I began eating more and more junk food and started gaining weight. My attention wasn’t on my health and over time the negatives began to manifest. I got fat, which caused back pain when I would sit for hours on end at work. My poor posture also exasperated any issues, and compounded any back pain. At night I would be listless, staying up late and waking up early for work. Overall the effect was just generally feeling crappy, lethargic, and moody. It was subtle, not huge changes to how I felt, which was the most insidious part. Getting unhealthy was a long drawn out process that became a normal part of my life.&lt;/p&gt;
&lt;h2&gt;Inspiration&lt;/h2&gt;
&lt;p&gt;I realized the benefits of being fit far outweighed the startup and maintenance cost of getting the habit in place. I was partly inspired by Wes Bos and Scott Tolinski in &lt;a href=&quot;https://syntax.fm/show/084/fitness-for-developers&quot;&gt;an episode of their developer focused podcast, Syntax&lt;/a&gt; where they discuss the benefits of working out and living a healthier lifestyle. At the same time, I also began to realize that there was a relationship between obesity and the impact it could potentially have on career opportunities in the future.&lt;/p&gt;
&lt;p&gt;I realized that being overweight can be a negative signal in the professional world. There is a negatively skewed bias against overweight individuals in society where people associate poor self control, discipline, and other negative traits with obesity while subconsciously associating positive traits to fitter individuals. This led me to a theory which I call the “No Fat CEOs” theory (which is completely unsubstantiated and not backed up by any facts) where corporations are more frequently led by individuals who are not overweight. Being overweight and unhealthy in my opinion is a liability to my career and I wanted to turn my fitness from a liability to an asset (or at the very least have no effect).&lt;/p&gt;
&lt;p&gt;As I slid into my 30s, I began noticing aches and pains and a general lethargy as I gained weight. Frankly, I felt like garbage. Walking up stairs would get me winded, bending over wasn’t easy. My body felt and looked like crap. The impact of being overweight on both my health and my psyche compounded the more overweight I became. It was easy to get stuck in a loop where I ate crap, felt like crap and looked like crap. I needed to break out the cycle.&lt;/p&gt;
&lt;h2&gt;Getting help&lt;/h2&gt;
&lt;p&gt;I had never set foot in a gym before and for a newbie like me, it can be quite a scary experience. I had no idea what exercises to do, how to do them and even where to start. I had learned recently that if you’re not an expert in something, the fastest and easiest way to obtain knowledge is to get help. So I hired a personal trainer and started going to a training session once a week.&lt;/p&gt;
&lt;p&gt;My trainer talked to me about my fitness goals, created a program for me, taught me the exercises, and has kept me accountable. She helped me overcome my fear of going to the gym. Once I was comfortable, I set a goal of going to the gym at least 3 times a week. I made time during my week and treat going to the gym as a top priority in life.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Since undertaking this fitness journey, I’ve noticed numerous benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I haven’t lost weight but I have lost fat and gained a lot of muscle.&lt;/li&gt;
&lt;li&gt;My back doesn’t hurt any more.&lt;/li&gt;
&lt;li&gt;I sleep better at night. Im going to bed earlier, sleep well, and wake up feeling rested.&lt;/li&gt;
&lt;li&gt;I noticed I’m more productive at work, I feel more focused.&lt;/li&gt;
&lt;li&gt;My posture is much better.&lt;/li&gt;
&lt;li&gt;Overall I feel strong and healthy.&lt;/li&gt;
&lt;li&gt;The feeling of accomplishment after a good session at the gym is itself a great reward and motivator.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There is a startup and maintenance cost to investing in my fitness and health, but I’ve already started collecting the dividends.&lt;/p&gt;
&lt;video height=&quot;300&quot; controls=&quot;&quot;&gt;
    &lt;source src=&quot;https://patricklee.nyc/public/blog/20181229_health_and_fitness.md/lift.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;Deadlift 1 rep max at 300lbs with a goal of 400lbs by the end of 2019.&lt;/p&gt;
</description>
      <pubDate>Sat, 29 Dec 2018 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/health-and-fitness/</guid>
    </item>
    <item>
      <title>Things to keep in mind while writing a VS Code extension.</title>
      <link>https://patricklee.nyc/blog/things-to-keep-in-mind-while-writing-a-vs-code-extension/</link>
      <description>&lt;p&gt;This article was originally posted on &lt;a href=&quot;https://medium.com/patrickleenyc/things-to-keep-in-mind-while-writing-a-vs-code-extension-9f2a3369b799&quot;&gt;medium&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;VS Code&lt;/a&gt; is a great editor platform. I tried my hand at creating an extension
and although the documentation is fairly complete and thorough. I still
ran into some issues. I’m documenting them here for other extension
authors.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://miro.medium.com/max/604/1*mUhuk-TkDPdDBcE2vep5BA.png&quot; alt=&quot;https://miro.medium.com/max/604/1*mUhuk-TkDPdDBcE2vep5BA.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;VS Code functionality takes the form of commands in the command palette.&lt;/p&gt;
&lt;h2&gt;Promises&lt;/h2&gt;
&lt;p&gt;If you’re used to the ES6 Promise style then VS Code’s promise style may
throw you off. Here is the newer style way to handle errors in promises
by chaining a &lt;code&gt;catch&lt;/code&gt; method after a &lt;code&gt;then&lt;/code&gt; method:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ES6 PromisedoPromise().then(val =&amp;gt; {  handleValue(val)}).catch(err =&amp;gt; {  handleError(err)})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;VS Code’s Thenable style promise &lt;code&gt;then&lt;/code&gt; method takes two params.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Success handler&lt;/li&gt;
&lt;li&gt;Error handler&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;// Thenable style promisesdoPromise().then(  val =&amp;gt; { handleValue(val) },   err =&amp;gt; { handleError(err) })
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Make sure to handle these errors correctly or you’re going to have a bad time.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Microsoft/vscode/issues/11693?source=post_page-----9f2a3369b799----------------------&quot;&gt;WARNING: Promise with no error callback:3 · Issue #11693 · Microsoft/vscodeVSCode Version: 1.4.0 OS Version: 10.10.5 I&#39;m developing an extension where I&#39;m using Promises (bluebird in this case)…github.com&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Settings&lt;/h2&gt;
&lt;p&gt;It wasn’t immediately clear how to add settings to my extension. Turns
out, I was looking for the wrong word. Settings are actually call
configurations and are located within contributions. &lt;a href=&quot;https://code.visualstudio.com/docs/extensionAPI/extension-points#_contributesconfiguration&quot;&gt;Here is a direct link to the documentation.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To add a setting to your extension, you need to add a key to your extension’s package.json file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;contributes&amp;quot;: {    &amp;quot;configuration&amp;quot;: ...}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This configuration section takes a JSON schema that describes what your
setting should be. Basically what data type it takes, a default value
and a description.&lt;/p&gt;
&lt;p&gt;It also wasn’t immediately clear how to implement a setting that takes an array of objects. You need to utilize the &lt;code&gt;items&lt;/code&gt; key to describe nested values. Here is an example from my extension VSNotes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Activation Events&lt;/h2&gt;
&lt;p&gt;If you have multiple commands you will need to make sure to include them in the &lt;code&gt;activationEvents&lt;/code&gt; portion of your package.json. This tells vscode to execute the activate function in extension.js.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;activationEvents&amp;quot;: [    &amp;quot;onCommand:extension.newNote&amp;quot;,    &amp;quot;onCommand:extension.listNotes&amp;quot;,    &amp;quot;onCommand:extension.setupNotes&amp;quot;,    &amp;quot;onCommand:extension.openNoteFolder&amp;quot;],&amp;quot;commands&amp;quot;: [    {        &amp;quot;command&amp;quot;: &amp;quot;extension.newNote&amp;quot;,        &amp;quot;title&amp;quot;: &amp;quot;VSNotes: New Note&amp;quot;    },    {        &amp;quot;command&amp;quot;: &amp;quot;extension.listNotes&amp;quot;,        &amp;quot;title&amp;quot;: &amp;quot;VSNotes: List recent notes&amp;quot;    },    {        &amp;quot;command&amp;quot;: &amp;quot;extension.setupNotes&amp;quot;,        &amp;quot;title&amp;quot;: &amp;quot;VSNotes: Run setup&amp;quot;    },    {        &amp;quot;command&amp;quot;: &amp;quot;extension.openNoteFolder&amp;quot;,        &amp;quot;title&amp;quot;: &amp;quot;VSNotes: Open Note Folder&amp;quot;    }],
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It may not be necessary to put all your commands into the activation event depending on how you architect your application. This could be a
potential issue if commands fail to show up.&lt;/p&gt;
&lt;h2&gt;Complex commands&lt;/h2&gt;
&lt;p&gt;I have no idea &lt;a href=&quot;https://code.visualstudio.com/docs/extensionAPI/vscode-api-commands&quot;&gt;what most of these do or why they are separate from the regular API&lt;/a&gt;. Could be because they are helper functions? Anyways, I used one to open a folder &lt;code&gt;vscode.openFolder&lt;/code&gt; and it took a bit of time to figure out how to actually open a folder. If some functionality you need isn’t in the &lt;a href=&quot;https://code.visualstudio.com/docs/extensionAPI/vscode-api&quot;&gt;regular namespace API&lt;/a&gt; check the &lt;a href=&quot;https://code.visualstudio.com/docs/extensionAPI/vscode-api-commands&quot;&gt;complex commands&lt;/a&gt; first.&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;Overall it was really painless to write a &lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;VS Code&lt;/a&gt; extension. The &lt;a href=&quot;https://code.visualstudio.com/docs/extensions/yocode&quot;&gt;Yeoman scaffolding&lt;/a&gt; they provide really speeds up development time and makes the whole process much easier. &lt;a href=&quot;https://code.visualstudio.com/docs/extensions/publish-extension&quot;&gt;Publishing is well documented and easy with the provided CLI tool&lt;/a&gt;. Overall a pleasant experience.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/patleeman/VSNotes&quot;&gt;Check out the extension I wrote: VSNotes&lt;/a&gt;. It’s a quick way to set a note folder and create markdown notes right
from VS Code. It’s quick and painless and lets you leverage VS Code’s
extensions for your note taking workflow. &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=patricklee.vsnotes&quot;&gt;Grab it from the marketplace&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
</description>
      <pubDate>Tue, 07 Nov 2017 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/things-to-keep-in-mind-while-writing-a-vs-code-extension/</guid>
    </item>
    <item>
      <title>A Website’s Life</title>
      <link>https://patricklee.nyc/blog/a-website-s-life/</link>
      <description>&lt;p&gt;Imagine your job is to run a website.&lt;/p&gt;
&lt;p&gt;You build it, get it running, promote it and people start using it. Things are going well! After this initial rush you settle down into maintenance and growth mode. There is no more mad scramble to add new features or scale the site. Users like your content and slowly tell their friends. Things are growing, albeit slowly.&lt;/p&gt;
&lt;p&gt;First you add some site analytics because you want to see who’s doing what on your site. Great, now you have a bit of insight into user behavior. You hear that buying ads on Facebook is effective to drive traffic, so you set that up and install their tracking code on your site. Easy peasy! You spend a couple bucks here and there, a/b test some things and do a couple of small test ad-buys. It turns out that its pretty difficult to get users to click on your Facebook ads, so you try Twitter, Pinterest, Instagram, and Google Adwords, to test things out. Some things work but you’re seeing sporadic results. Meanwhile, your marketing manager is complaining that the site has too many tags and that you need to add a tag manager. Your site’s header looks like somebody fired a shotgun of bad code at it, so you listen and install a tag manager. Awesome, that made things a bit neater and now you can easily install tags with the click of a mouse!&lt;/p&gt;
&lt;p&gt;The internet has been buzzing about exit intent and how its the new hotness. You &lt;em&gt;need&lt;/em&gt; to capitalize it to retain users! It’s so easy to sign up for another AdTech company and install their JavaScript snippet in your tag manager, so there’s not even a second thought. Now when a user tries to do anything on your site, it will show them a popup modal and ask them to sign up for their email list. If they just want access to your content, they’ll have to click on a snarky cancel message. Haha! “No, you don’t want awesome content?”, they’ll &lt;em&gt;love&lt;/em&gt; that! Oh yeah, while you were installing exit intent popups, it turns out that email lists are the best way of contacting your users according to an article you read in Fast Company. So you sign up for Mail Chimp and begin cranking out emails. They say it doesn’t matter what its about, just that its on a consistent schedule. Let’s get that content flowing!&lt;/p&gt;
&lt;p&gt;People love your content and sometimes post about it on social media. Awesome! New marketing channels! So you create a Facebook page, a Twitter account, a Pinterest board, an Instagram account, a Snapchat account and whatever else the kids are dooting on these days. Well it turns out managing five social media accounts is a lot of work! Good thing there’s a SAAS out there to solve your problem, so you sign up for one and start dooting to your users. Oh, in the mean time, wouldn’t it be cool for people to be able to doot to links to your content to their friends? So you add some social media links to your site so they can easily share content! &lt;em&gt;Brilliant&lt;/em&gt;!&lt;/p&gt;
&lt;p&gt;Your boss comes by and wants to create more of a community feeling to your site, so you add a comments section with the leading comment section SAAS provider out there. It’s better than installing your own comment section because now users can sign up with Facebook or Twitter! Except they inject ads onto your site unless you pay them, so you pony up the monthly fee and pay them to host comments. Users begin commenting! Sweet!&lt;/p&gt;
&lt;p&gt;Uh oh, people begin commenting on random pages that the site is really slow and doesn’t load well on mobile! Well crap, what can we do about that? Well, there’s this thing called Google Accelerated Mobile Pages that you heard about on CNET, let’s try that out. So your developer makes your site AMP enabled and you begin serving content via Google AMP. Now when users search for content on Google, they get a cached version of your site. Uh oh, but it also means they’re sharing mangled URLs on social media now. Well, we’ll deal with this later, we have more pressing matters right now.&lt;/p&gt;
&lt;p&gt;Turns out you left some ads running on an obscure ad network and you racked up a couple thousand dollars in charges. Well that sucks, things must have gotten lost in the shuffle when you were testing ad platforms. You turn it off and go through each ad network to check for running ads. After ensuring no new ad campaigns are running, time to solve some other problems. Your last email campaign had an abysmal open rate, so you’ll need to troubleshoot that, but first you need to schedule some doots on social media. You start troubleshooting your email campaigns and it turns out your emails are going straight to the spam folder. Probably because people don’t like getting multiple emails per week from your site, explains the high unsubscribe rate too. You don’t understand, people are really engaged with your content! They’re commenting and sharing links… right?&lt;/p&gt;
&lt;p&gt;Well…&lt;/p&gt;
&lt;p&gt;The handy social sharing links you installed have only been clicked a handful of times. The fancy comments section is full of unrelated and low effort comments. Nobody seems to be talking to each other, just using it as a place to air their grievances about the slow load times and the incessant nagging exit intent modal. They still love your content, however it’s getting more and more difficult to reach it.&lt;/p&gt;
&lt;p&gt;The site experience is starting to get bad, the console starts spitting out JavaScript errors because some of the SAAS services you installed went out of business. Browser updates begin breaking your site functionality (or so your developer tells you, it’s actually terribly written code). Things are beginning to grind to a halt so you do what any sane person does, decide to throw it all away and start fresh with a newly redesigned website.&lt;/p&gt;
&lt;p&gt;You hire a top tier web agency to build the site (priced accordingly). They come highly recommended by the team in your sister company that just went through this process. They agile their way into a beautifully designed work of art, complete with full bleed high resolution images, quirky and cool widgets hidden in off-grid locations, carousels for days and a revamped homepage with megabytes on megabytes of images. &lt;strong&gt;It’s beautiful!&lt;/strong&gt; The work is complete and they hand the site over to you and your team.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Imagine your job is to run this website…&lt;/em&gt;&lt;/p&gt;
</description>
      <pubDate>Wed, 30 Aug 2017 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/a-website-s-life/</guid>
    </item>
    <item>
      <title>Lessons learned from starting a business while working full time.</title>
      <link>https://patricklee.nyc/blog/lessons-learned-from-starting-a-business-while-working-full-time/</link>
      <description>&lt;p&gt;I started working on &lt;a href=&quot;http://collatenotes.com/&quot;&gt;Collate&lt;/a&gt; in December of 2016. I was dissatisfied with the note taking apps on the market and wanted a tool that would work for my needs. I had been toying with the idea and finally started writing code over the Christmas holiday. I had a basic prototype built with Electron, bootstrap and jQuery by February, then rebuilt it with Electron, Vue.js and Bulma from scratch because the code base was terrible. Today, Collate is profitable, has a couple hundred users, was featured on &lt;a href=&quot;http://lifehacker.com/collate-is-a-privacy-focused-evernote-style-notes-app-1794500652&quot;&gt;Lifehacker&lt;/a&gt; and is doing well by my standards. Here are some hard learned lessons from the last 8 months of working on Collate while maintaining a full time job:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Have a tight scope — I made the mistake of saying yes to everything and pretty soon Collate began heading in a direction I wasn’t happy with. Users will ask for features, it’s only natural. It’s extremely easy to bloat the scope of your project if you say yes to everything. Having an extremely tight scope of what your project does and provides is essential to focus the small amount of time you have to devote to the project. I’m working on the next iteration of Collate and it will be extremely pared down.&lt;/li&gt;
&lt;li&gt;Use what you know — Use technology you know like the back of your hand. This advice is given a lot and for good reason. If you need to spend time learning a new piece of tech, it’s time away from making your product more stable. I use Wordpress in my day job, so it’s only natural I use it for my product’s site. It’s not sexy but it works.&lt;/li&gt;
&lt;li&gt;If you have to learn new tech, experiment and choose what works for you — Other times you might not know how to use the right technology for the job. In these cases experiment and see what works best for your needs. I went with Vue.js for the second iteration of Collate because I was working on a project at work that utilized it. Using it in both places helped both projects immensely.&lt;/li&gt;
&lt;li&gt;Charge money — This is one thing I’m glad I got right from the start thanks to advice from &lt;a href=&quot;https://www.indiehackers.com/&quot;&gt;Indie Hackers&lt;/a&gt; and other startup founders. Charge money from the get-go and get customers comfortable paying for your product. Collate was profitable the second week out of release. The money gives you a cushion to experiment and grow the business. Since I’m working full time, all profits go back into the project to pay for things like servers, lawyers, and third party services I may use.&lt;/li&gt;
&lt;li&gt;It’s okay to not respond to emails — Customer service is a very time consuming task. I made the mistake of replying to each and every email in the beginning, usually with long explanations of what I was doing and my plans. With limited time, choose your service requests carefully and try to minimize time spent on it. It doesn’t mean you don’t care, you’re just prioritizing. I got to a point where I would dread opening up my inbox, after I stopped responding to everything, things got a lot more manageable.&lt;/li&gt;
&lt;li&gt;Get your legal ducks in a row — If you’re going to collect money for your project, spend a little up front as soon as you can afford to and get all your legal stuff squared away. I started my corporate entity (Collate, LLC) through a corporate filing company in my state. Opened a bank account with the same bank I use for my personal accounts. Then, got my End User License Agreement and Privacy Policy looked at by an attorney I found on &lt;a href=&quot;https://www.upcounsel.com/rf/pQ3CZlfu&quot;&gt;Upcounsel&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Think about marketing — You don’t have to be a marketing wiz but consider it while building out the product. At the very minimum, start early by building a email list of people interested in your product. You don’t have to constantly market to your list but its useful to have people to notify when you have something to announce.&lt;/li&gt;
&lt;li&gt;Pace yourself — I wish I had learned this lesson sooner. I worked on Collate furiously for the first six months, pumping out feature after feature and release after release. I was putting in close to 40 hours a week on nights and weekends working on Collate after work for a while. I got so burnt out that I had to step away from the project and try working on something else (and even not working on anything!). I’m back on it now, but working on it at a much slower pace. Take the time to decompress each day, get exercise and make sure to sleep.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Side projects while working full time are a lot of work but also very rewarding. The best part for me was building something from scratch that I’m passionate about building, something that I don’t get at my day job. It’s also pretty great to build something and then watch other people get excited about it.&lt;/p&gt;
</description>
      <pubDate>Sat, 19 Aug 2017 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/lessons-learned-from-starting-a-business-while-working-full-time/</guid>
    </item>
    <item>
      <title>From Community College to Columbia</title>
      <link>https://patricklee.nyc/blog/from-community-college-to-columbia/</link>
      <description>&lt;p&gt;I dropped out of college at twenty. The next few years were spent at various jobs until I ended up as a legal assistant at a law firm. The firm was filled with fax machines, typewriters, and massive paper files. What was the norm in 1988 was still the norm in the legal industry at the time. It was a slow moving beast, mired in paper and yesterday’s technology. I wanted to work with modern technology and be part of the future but there was no future for an aimless college dropout. I couldn’t see a way forward, so I went back.&lt;/p&gt;
&lt;h3&gt;The Borough of Manhattan Community College&lt;/h3&gt;
&lt;p&gt;Community college was an eye-opening experience. On one hand you had the highly motivated students, usually older, who had experienced life first hand. Many had full time jobs, kids, and experience working low wage jobs. Most of the ones I met worked in retail or dead end jobs, and college for them was a ticket out of their daily struggle and into a comfortable future. On the other hand, you had the unmotivated students, usually younger and straight out of high school. Most treated it as an extension of high school, 13th and 14th grade, as a way to defer working for a little bit. While I could sympathize with them, I fell into the former group of students. I was motivated, but I lacked a clear picture of where I wanted to be. My idea of dreaming big was a degree from the local four year college and a modest job doing something better than what I had been doing at the law firm. At this point, I was doing well in school, working my way through a business management degree, content with my potential future. Who knew that taking a mandatory speech class, and randomly choosing a time slot that worked well with my schedule would land me with a professor that would change my life?&lt;/p&gt;
&lt;p&gt;My Speech 101 professor, Dr. Poster, is a long time teacher and administrator at the Borough of Manhattan Community College (BMCC). She has a reputation of being a tough teacher, who expects a lot from her students and will hold them to a high standard. While plenty of her colleagues passed students who handed in sub par work, she held firm and expected quality work. She has an uncanny ability to see the best in her students, and to push them hard to realize their potential. Which is what she did with me. She brought me into her office one day and asked me about my plans for the future, what I wanted to do with my life, and where I saw myself going after I finished at BMCC. I gave her the rough layout of my college and career goals. Then she dropped a bomb on me.&lt;/p&gt;
&lt;p&gt;“Why don’t you apply to Columbia?”&lt;/p&gt;
&lt;p&gt;I had never even given Columbia serious consideration. That seemed way out of my reach, me, a college dropout in a no-name community college. I wasn’t a savant, I hadn’t done anything truly worthwhile, what chance did I have? She convinced me that it was worth trying and helped connect me to some people who could help with the application process. To my amazement, I got in.&lt;/p&gt;
&lt;h3&gt;Columbia University&lt;/h3&gt;
&lt;p&gt;Walking through the gates on 116th street and Broadway the first time was surreal. Stepping onto the Columbia grounds gives you the feeling that you’ve been transported miles away from New York City. I walked through rows of trees lining the main entrance which drew me into the center of campus. To the left were the stairs leading to Low Library, and to the right grassy fields and cleanly trimmed hedges leading to Butler Library. I can only describe the feeling as a sort of reverence, standing in this place where many generations of students have come and gone. A sort of… temple to the religion of academia. I had lived in New York City my entire life and had never known there was such a place.&lt;/p&gt;
&lt;p&gt;My first semester there, I took a “relatively light” load of four classes while still working part time. Very quickly, I realized that four classes was &lt;strong&gt;not&lt;/strong&gt; a light load and I had to quit my job. If I was going to pass my classes, showing up and doing homework was not enough. I was under water my first week of classes, drowning under the crushing weight of the volume, frequency, and difficulty of the work. It turns out that community college had not adequately prepared me for the rigors of real academia. Classes were much harder, especially since I was majoring in Economics-Mathematics, a major which combined the two disciplines and was similar to completing 80% of both degrees. To survive in this tough academic environment, you enter a sort of perpetual fight or flight mode. Fear had a lot to do with the stress. Fear of failing a class and extending my stay another semester with the associated costs. Fear of failing out of the school, leaving with significant debt without a degree to show for it. Fear that now that I had reached for the stars, I would fail and come crashing back to the ground. All these fears would be my main motivator and subsequently the reason I was able to graduate on time.&lt;/p&gt;
&lt;p&gt;I’d best describe the time between when a semester begins and when it ends as a long slow grind. You’re grinding out work, studying, reading, writing and problem sets. Once you complete a task, work begins on the next one, over and over until it’s time to sleep. In community college the bar is set a lot lower, mostly because the bar of students is a lot lower. Teachers expected average work and students presented a wide range of quality. At Columbia, I noticed that the range of quality was a lot smaller, and the quality of work was a lot higher. This meant that in order to be an average student at Columbia, I needed to work harder than I’d ever worked at BMCC. I had friends who were top students at BMCC, who were accepted to Columbia at the same time as I was. They echoed similar sentiments about the intensity of the work. I had thought of myself as an average student at best, and here were people I had considered harder working and smarter than myself struggling to get by.&lt;/p&gt;
&lt;p&gt;There was an aura of stress surrounding the student body. As my time at Columbia progressed, I noticed I started showing it as well. I don’t know if this was an experience unique to Columbia, top tier schools, or just college in general but I do know that during my time at BMCC I had never experienced that dreadful fear of failing a class. At BMCC the worst that could happen was that I would get a C. At Columbia the worst was failing a class and throwing away thousands of dollars as a result. On the flip side, however, I’ve never seen as many hard-working people in one place in my entire life. The maturity and discipline it took for these students to buckle down and study was inspirational for me. It helped to be surrounded by these hard-working students. I fed off the energy of my fellow students. I found it refreshing to be surrounded by people who were motivated especially coming from an environment where a fraction of your grade was determined by your attendance.&lt;/p&gt;
&lt;p&gt;I noticed the disparity between the students the most during group assignments. Once at BMCC, I worked with a group to produce a final report which would make up a large portion of my grade. One of our group members disappeared part way through the semester and did not respond to any of our emails. Left in charge of her portion we had to split her work. On the final day of class, when we were slated to hand in our report, she showed up with a crumpled print-out with a paragraph which was supposed to represent her portion, fully expecting us incorporate it with our work. Baffled, we had to turn her down and let her know that her work was unacceptable. In comparison, at Columbia, I worked with a group to present a report in which we all agreed to go the extra mile and create a video showcasing our findings. All members of the group were active, engaged, and contributed beyond their fair share of work. Though this is only anecdotal evidence, I found comparisons between idiosyncratic differences in the student bodies different enough to be startling.&lt;/p&gt;
&lt;p&gt;However, the student body was not without its flaws. Though racially diverse, the students at Columbia mostly came from the same privileged socioeconomic background. I found the school’s population to be homogenous. I was used to interacting with students with working class backgrounds from New York City. The difference was quite stark, and I found myself having a difficult time forming friendships with my peers. I naturally gravitated towards older, “unconventional” students, who were also returning to college, mostly military veterans. I didn’t have much time to socialize though. I had a carefully planned course schedule to adhere to if I was going to graduate on time. I stuck my nose in my books and worked harder than I had ever worked in my life.&lt;/p&gt;
&lt;h3&gt;Post Columbia&lt;/h3&gt;
&lt;p&gt;I graduated. It surprised me much more than it should have. In hindsight it wasn’t all just studying and stress, there were plenty of good times along with the bad. I met a lot of great people during my time, many who have gone on to do some impressive things. I had worked my way through two and a half years and landed an internship which eventually turned into a job. From there, I transitioned to my current role as a Data Analyst at Penguin Random House, the largest book publisher in the US. Without my education from Columbia, data analytics would be a complete mystery to me. Putting in the hours and studying outside of work isn’t a chore as it would have been prior to going back to school. An example of that is that since graduating, I’ve been able to teach myself programming. I had attempted to do so in the past but had never pushed through the tedious parts, always getting stuck. Also, thanks to the fundamental math and economic education I received, I find working with large data sets much easier.&lt;/p&gt;
&lt;p&gt;Looking back at it now, I can appreciate the rigor and the intensity of the work. Columbia helped push my boundaries and helped me realize what I’m capable of doing. Just three years prior, I matriculated from BMCC, content with a future that was just slightly better than the one I left. However, I would never have even thought to reach so high had Dr. Poster not seen something in me and pushed me to apply. It’s truly amazing what an effect one person can have on the trajectory of another person’s life and I’m grateful to her for what she’s done for me. She made me promise that I would never remove BMCC from my resume, to show others what students from a community college could achieve. I leave it on there for her, and to remind myself of my roots.&lt;/p&gt;
</description>
      <pubDate>Mon, 12 Dec 2016 00:00:00 +0000</pubDate>
      <dc:creator>Patrick Lee</dc:creator>
      <guid>https://patricklee.nyc/blog/from-community-college-to-columbia/</guid>
    </item>
  </channel>
</rss>